I've been using the Elasticsearch Python API to do some basic operation on a cluster (like creating an index or listing them). Everything worked fine but I decided to activate SSL authentification on the cluster and my scripts aren't working anymore.
I have the following errors :
Certificate did not match expected hostname: X.X.X.X. Certificate: {'subject': ((('commonName', 'X.X.X.X'),),), 'subjectAltName': [('DNS', 'X.X.X.X')]} GET https://X.X.X.X:9201/ [status:N/A request:0.009s] Traceback (most recent call last): File "/home/esadm/env/lib/python3.7/site-packages/urllib3/connectionpool.py", line 672, in urlopen
chunked=chunked, File "/home/esadm/env/lib/python3.7/site-packages/urllib3/connectionpool.py", line 376, in _make_request
self._validate_conn(conn) File "/home/esadm/env/lib/python3.7/site-packages/urllib3/connectionpool.py", line 994, in _validate_conn
conn.connect() File "/home/esadm/env/lib/python3.7/site-packages/urllib3/connection.py", line 386, in connect
_match_hostname(cert, self.assert_hostname or server_hostname) File "/home/esadm/env/lib/python3.7/site-packages/urllib3/connection.py", line 396, in _match_hostname
match_hostname(cert, asserted_hostname) File "/home/esadm/env/lib/python3.7/ssl.py", line 338, in match_hostname
% (hostname, dnsnames[0])) ssl.SSLCertVerificationError: ("hostname 'X.X.X.X' doesn't match 'X.X.X.X'",)
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "/home/esadm/env/lib/python3.7/site-packages/elasticsearch/connection/http_urllib3.py", line 233, in perform_request
method, url, body, retries=Retry(False), headers=request_headers, **kw File "/home/esadm/env/lib/python3.7/site-packages/urllib3/connectionpool.py", line 720, in urlopen
method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2] File "/home/esadm/env/lib/python3.7/site-packages/urllib3/util/retry.py", line 376, in increment
raise six.reraise(type(error), error, _stacktrace) File "/home/esadm/env/lib/python3.7/site-packages/urllib3/packages/six.py", line 734, in reraise
raise value.with_traceback(tb) File "/home/esadm/env/lib/python3.7/site-packages/urllib3/connectionpool.py", line 672, in urlopen
chunked=chunked, File "/home/esadm/env/lib/python3.7/site-packages/urllib3/connectionpool.py", line 376, in _make_request
self._validate_conn(conn) File "/home/esadm/env/lib/python3.7/site-packages/urllib3/connectionpool.py", line 994, in _validate_conn
conn.connect() File "/home/esadm/env/lib/python3.7/site-packages/urllib3/connection.py", line 386, in connect
_match_hostname(cert, self.assert_hostname or server_hostname) File "/home/esadm/env/lib/python3.7/site-packages/urllib3/connection.py", line 396, in _match_hostname
match_hostname(cert, asserted_hostname) File "/home/esadm/env/lib/python3.7/ssl.py", line 338, in match_hostname
% (hostname, dnsnames[0])) urllib3.exceptions.SSLError: ("hostname 'X.X.X.X' doesn't match 'X.X.X.X'",)
The thing I don't understand is that this message doesn't make any sense :
"hostname 'X.X.X.X' doesn't match 'X.X.X.X'"
Because the two adresses matches, they are exactly the same !
I've followed the docs and my configuration of the instance Elasticsearch looks like this :
Elasticsearch([get_ip_address()],
http_auth=('elastic', 'pass'),
use_ssl=True,
verify_certs=True,
port=get_instance_port(),
ca_certs='ca.crt',
client_cert='pvln0047.crt',
client_key='pvln0047.key'
)
Thanks for your help
Problem solved, the issue was in the constructor :
Elasticsearch([get_ip_address()],
http_auth=('elastic', 'pass'),
use_ssl=True,
verify_certs=True,
port=get_instance_port(),
ca_certs='ca.crt',
client_cert='pvln0047.crt',
client_key='pvln0047.key'
)
Instead of mentioning the ip address I needed to mention the DNS name, I also changed the arguments by using context object just to follow the original docs.
context = create_default_context(cafile="ca.crt")
context.load_cert_chain(certfile="pvln0047.crt", keyfile="pvln0047.key")
context.verify_mode = CERT_REQUIRED
Elasticsearch(['dns_name'],
http_auth=('elastic', 'pass'),
scheme="https",
port=get_instance_port(),
ssl_context=context
)
This is how I generated the certificates :
bin/elasticsearch-certutil cert ca --pem --in /tmp/instance.yml --out /home/user/certs.zip
And this is my instance.yml file :
instances:
- name: 'dns_name'
dns: [ 'dns_name' ]
Hope, it will help someone !
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With