Heartbeat TLS ServerName not being set correctly

When trying to monitor an SSL enabled endpoint it seems like Heartbeat is setting the ServerName to the IP address instead of the hostname. For setups where the certificate is only signed with the domain (and not all IP addresses) this causes verification to fail. For setups where different certificates are served depending on hostname (Kubernetes nginx-ingress being a popular example) it means that Heartbeat tries to verify the invalid fake certificate that is returned when no matching domains are found.

Looking through the code and docs I can't find a way to have the verified ServerName be the domain instead of the resolved IP address.

Example configuration:

- type: "tcp"
  name: "elastic.co"
  schedule: "@every 60s"
  hosts: ["tls://elastic.co:443"]
  ssl:
    enabled: true

Error message:

x509: cannot validate certificate for 151.101.194.217 because it doesn't contain any IP SANs"

Here is the section which is setting the ServerName

The host string which gets passed in actually ends up being the resolved IP address.

To confirm that this was the issue I hard coded it to "elastic.co" allows the certificate to be verified properly.

config.ServerName = "elastic.co"

I have reproduced this with the latest releases version (running from official Docker images) and also with the latest builds from the master branch.

Thanks so much @michael.russell. I've opened an issue here: https://github.com/elastic/beats/issues/17123

I hope to tackle this fairly soon, I think the fix should be relatively simple here.

1 Like