In Kubernetes, I've created a Service that exposes ports 9200 and 9300. This service gets applied to an AWS ELB which creates listeners for those ports. The full DNS name for the ELB is ct-es.ct-es.svc.clsuter.local. The pods for their respective containers execute successfully but X-pack and PKI authentication is where I'm running into problems.
When I try to execute a curl request shown below, I get a 401 error in the response:
You have security enabled in Elasticsearch with 2 security realms (native and PKI) so you need to send some client credentials in your request. You need to send either
a username and password combination for a user that exists in the native realm , with -uusername:password
a client certificate by specifying --cert and --key , see the curl man page at curl - How To Use
I've looked at PKI realm documentation and it hasn't helped. I'd like authentication to happen using PKI because that removes the hassle of maintaining passwords.
I tried providing a client certificate and the key but still keep getting the same result. My questions are:
The clients have their dns name as :1-2-3-4.es.pod.cluster.local (which is also reflected in their certificate SubjectName. The clients are behind a load balancer whose dns name is es.es.svc.cluster.local (also reflected in the certificate SubjectName). Could this be the cause of missing auth token?)
Also, as a follow-up to my previous response. I changed the password for the elastic user using the elastic-setup-passwords script and tried using the new password in the curl request. It now gives me this error:
That's in the error response, not the request.
Those are the authentication headers that are supported by your configuration of that Elasticsearch node.
Bearer realm="security"
That's support for an OAuth2 Bearer access token
Basic realm="security" charset="UTF-8"
That's support for Basic Authentication (username + password)
If you fail to provide any authentication credentials the response will include HTTP response headers that are used to provide feedback to your user agent which HTTP authentication methods would be supported by the server.
No.
HTTP client authentication doesn't do reverse DNS lookups on the client address. The subject name in a client certificate is used for identity but it doesn't need to match any DNS names.
Have you setup a PKI realm on your client node?
It wasn't included in the elasticsearch.yml of your original post.
Please provide details. How did you do this?
At a guess it looks like you provided the wrong password, but there are other possible causes. The elasticsearch logs can help work out the cause.
I'm making this curl request from one of the client nodes. curl--cert /usr/share/elasticsearch/config/elasticsearch.crt--key /usr/share/elasticsearch/config/elasticsearch.key --cacert /usr/share/elasticsearch/config/ca.crt https://ct-es.ct-es.svc.cluster.local:9200/cluster/health?pretty
The PKI realm has been setup on both client and master nodes. If you take a closer look at my original post, you'll see I've mentioned that the elasticsearch.yml is from the client node. The master nodes have a similar looking YAML config with the exception that the node.master value is set to true.
Sorry, that was my fault. The bottom of your file wasn't visible without scrolling and I missed it.
It looks like you've missed enabling client authentication on the http interface. You need to set xpack.security.http.ssl.client_authentication to optional or required. You've set xpack.ssl.client_authentication, but the http interface does not rely on that default setting.
Thank you for the suggestion. So, I made that change you recommended and noticed something in the elasticsearch logs. Something about an empty certificate chain. I was able to remediate that by changing the xpack.security.http.ssl.certificate_authorities setting to point to the location (instead of an array inside the [ ] parenthesis).
Now, I'm getting this error:
{
"error" : {
"root_cause" : [
{
"type" : "security_exception",
"reason" : "action [cluster:monitor/health] is unauthorized for user [1-2-3-4.ct-es.pod.cluster.local]"
}
],
"type" : "security_exception",
"reason" : "action [cluster:monitor/health] is unauthorized for user [1-2-3-4.ct-es.pod.cluster.local]"
},
"status" : 403
}
I understand this is related to role-mapping, however, I don't know how to work around that. These elasticsearch nodes are running on kubernetes pods which get their certificate dynamically during the bootstrapping process. The config files are mapped using Kubernetes ConfigMap. I'm not sure how to add the PKI_DN for all the nodes in role_mapping.yaml. Does the role mapping yaml file interpret a wildcard CN as shown below:
role_mapping.yml:
client_node:
-"CN=*.pod.cluster.local,O=My Organization, L=My City, ST=My State, C=My Country"
Alternatively if you ensure that only these clients will ever get a certificate that is signed by the CA that is configured as your CA for the http layer
xpack.security.http.ssl.certificate_authorities:
you could possibly use the role mapping API to set a rule to match the realm name
Apache, Apache Lucene, Apache Hadoop, Hadoop, HDFS and the yellow elephant
logo are trademarks of the
Apache Software Foundation
in the United States and/or other countries.