Certificate for <localhost> doesn't match any of the subject alternative names

I'm running Elasticsearch 7.01 on Ubuntu 18.04 LTS with SSL and security enabled.

I'm having trouble configuring the input section of a new Watcher event on a cluster that uses SSL certs that were generated by the bin/elasticsearch-certutil tool. When I trigger the watch, I get an error regarding a SAN problem with the cert: "Certificate for doesn't match any of the subject alternative names". (See below for .watcher-history output.)

My watch definition looks like this:

PUT _watcher/watch/cluster_health_yellow_watch
{
  "trigger": {
    "schedule": {
      "interval": "10s"
    }
  },
  "input": {
    "http": {
      "request": {
        "scheme": "https",
        "host": "localhost",
        "port": 9200,
        "path": "/_cluster/health",
        "auth": {
          "basic": {
            "username": "watcher",
            "password": "<redacted>"
          }
        }
      }
    }
  },
  "condition": {
    "compare": {
      "ctx.payload.status": {
        "eq": "yellow"
      }
    }
  },
  "actions": {
    "gmail_account": {
      "email": {
        "to": "<redacted>",
        "subject": "Cluster Status Warning",
        "body": "Cluster status is YELLOW"
      }
    }
  }
}

I originally had the xpack.http.ssl.truststore.path set to the elastic-certificates.p12 file and got the error. I also tried setting it to the elastic-stack-ca.p12 file, but had the same problem. (In both cases, I had xpack.http.ssl.truststore.secure_password defined to the corresponding password in my Elasticsearch keystore, and it doesn't appear to be an issue of reading the *.p12 files.)

xpack.http.ssl:
  truststore.path: /etc/elasticsearch/certs/elastic-certificates.p12
  truststore.type: PKCS12

In some systems, I can overcome this by disabling cert validation. However, I don't see an option for that in the https://www.elastic.co/guide/en/elastic-stack-overview/7.0/input-http.html docs.

Any help is greatly appreciated. Maybe I just can't see the forest through the trees right now. :slight_smile:

Here's my watcher history:

# query
GET .watcher-history*/_search
{
  "size": 1,
  "sort" : [
    { "result.execution_time" : "desc" }
  ]
}

# result
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 7,
    "successful" : 7,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 10000,
      "relation" : "gte"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : ".watcher-history-9-2019.06.14",
        "_type" : "_doc",
        "_id" : "cluster_health_yellow_watch_dc105626-8109-4242-b6a9-ee305f55d094-2019-06-14T18:59:22.039922Z",
        "_score" : null,
        "_source" : {
          "watch_id" : "cluster_health_yellow_watch",
          "node" : "IZ0_EXRbQXaiNzOHnTsn7Q",
          "state" : "failed",
          "user" : "<redacted>",
          "status" : {
            "state" : {
              "active" : true,
              "timestamp" : "2019-06-14T18:58:38.180Z"
            },
            "actions" : {
              "gmail_account" : {
                "ack" : {
                  "timestamp" : "2019-06-14T18:58:38.180Z",
                  "state" : "awaits_successful_execution"
                }
              }
            },
            "execution_state" : "failed",
            "version" : -1
          },
          "trigger_event" : {
            "type" : "schedule",
            "triggered_time" : "2019-06-14T18:59:22.039Z",
            "schedule" : {
              "scheduled_time" : "2019-06-14T18:59:22.019Z"
            }
          },
          "input" : {
            "http" : {
              "request" : {
                "scheme" : "https",
                "host" : "localhost",
                "port" : 9200,
                "method" : "get",
                "path" : "/_cluster/health",
                "params" : { },
                "headers" : { },
                "auth" : {
                  "basic" : {
                    "username" : "watcher",
                    "password" : "::es_redacted::"
                  }
                }
              }
            }
          },
          "condition" : {
            "compare" : {
              "ctx.payload.status" : {
                "eq" : "yellow"
              }
            }
          },
          "result" : {
            "execution_time" : "2019-06-14T18:59:22.039Z",
            "execution_duration" : 4,
            "input" : {
              "type" : "http",
              "status" : "failure",
              "error" : {
                "root_cause" : [
                  {
                    "type" : "s_s_l_peer_unverified_exception",
                    "reason" : "Certificate for <localhost> doesn't match any of the subject alternative names: []"
                  }
                ],
                "type" : "s_s_l_peer_unverified_exception",
                "reason" : "Certificate for <localhost> doesn't match any of the subject alternative names: []"
              },
              "http" : {
                "request" : {
                  "host" : "localhost",
                  "port" : 9200,
                  "scheme" : "https",
                  "method" : "get",
                  "path" : "/_cluster/health",
                  "auth" : {
                    "basic" : {
                      "username" : "watcher",
                      "password" : "::es_redacted::"
                    }
                  }
                }
              }
            },
            "actions" : [ ]
          },
          "messages" : [
            "failed to execute watch input"
          ]
        },
        "sort" : [
          1560538762039
        ]
      }
    ]
  }
}

Per the error you get, do you have "localhost" in the certificate as one dns entry for all nodes ? If you want to access an https server with localhost, then the certificate should include localhost as one subject alternative name inside the certificate

You could also try [xpack.http.ssl.verification_mode: "certificate"] (https://www.elastic.co/guide/en/elasticsearch/reference/current/notification-settings.html#ssl-notification-settings) but disabling even partially certificate verification is not the best course of actions if you can fix the certificate

Hope this helps

You can probably use the hosts fqdn instead of localhost.

Hooray! The verification_mode setting appears to have been the problem. (It defaults to a value of full.) My watch is working correctly now.

In summary, here is the configuration I used:

xpack.http.ssl:
  verification_mode: certificate
  truststore.path: /etc/elasticsearch/certs/elastic-certificates.p12
  truststore.type: PKCS12
# truststore.secure_password: <keystore>

xpack.notification.email.account:
    gmail_account:
        profile: gmail
        smtp:
            auth: true
            starttls.enable: true
            host: smtp.gmail.com
            port: 587
            user: <redacted>
#           secure_password: <keystore>

Thank you, @Julien!