Closed mark-bb closed 8 months ago
can you share your full cqlshrc ?
it should be working if it's defined in the certfile
as a workaround you can use validate=false
in cqlshrc
The server certificate hostname checking was turned off in fact previously, at least in 5.1. The way cqlsh worked with certificates resembled the one used by Cassandra at the moment - there are no visible attempts to set the server_name
ssl option like above and ssl_context.check_hostname
.
https://docs.python.org/3/library/ssl.html#ssl.SSLContext.check_hostname
The PROTOCOL_TLS_CLIENT protocol enables hostname checking by default. With other protocols, hostname checking must be enabled explicitly.
According to the citation above this means, that hostname verification was not used previously, when cqlsh used PROTOCOL_TLS
or PROTOCOL_TLS_CLIENTv1_2
protocols.
Now I see, that ssl_context.check_hostname
is used explicitly based on client's validate
option setting in cqlshrc, which is actually not fully correct. We may require the server cert verification, but not its hostname validation. But there is no distinct client option for hostname validation, and your rule "to verify cert and validate its hostname" or "not verify cert and not validate hostname" looks ok.
But, if you set ssl_context.check_hostname = True
, you must use server_name
ssl_option equal to one of the certificate SAN DNS names.
If you don't do this, then it works with [connection].hostname = IP
in cqlshrc and the same IP specified in the SAN IP only.
as a workaround you can use validate=false in cqlshrc
This is really a workaround, but it turns off the server cert verification as well. It may be inappropriate in some real cases, of course.
as a workaround you can use validate=false in cqlshrc
This is really a workaround, but it turns off the server cert verification as well. It may be inappropriate in some real cases, of course.
o.k. so if we introduce a new check_hostname
parameter to cqlsh, it would solve the issue you are having ? and you can disable the hostname checks ?
look at the driver code:
def _wrap_socket_from_context(self):
ssl_options = self.ssl_options or {}
# PYTHON-1186: set the server_hostname only if the SSLContext has
# check_hostname enabled and it is not already provided by the EndPoint ssl options
if (self.ssl_context.check_hostname and
'server_hostname' not in ssl_options):
ssl_options = ssl_options.copy()
ssl_options['server_hostname'] = self.endpoint.address
self._socket = self.ssl_context.wrap_socket(self._socket, **ssl_options)
seems like it would work only for ip addresses, and not for DNS names (they were lost) so it's a bit driver bug as well
so to sum it up:
1) I think we should do the suggestion you proposed at the beginning - we should need to use the ssl_options
since driver doesn't handle it correctly (yet)
2) plus add option to control the check_hostname
on it's own
o.k. so if we introduce a new check_hostname parameter to cqlsh, it would solve the issue you are having ? and you can disable the hostname checks ?
No, it doesn't resolve my goal - to have an ability to verify certificate and validate its hostname correctly.
Use case: I don't want to allow use of certificate issued for server1 on server2.
The handy feature (not existing in Cassandra, afaik) you suggest may really help, when I have, say, hundreds servers in a cluster, and I don't want to issue distinct certs for each of them.
I issue a server certificate without SAN DNS at all and use this new check_hostname=false
with verify=true
. I still have an ability to verify this cert without checking its non-existing DNS name there. The current workaround for this scenario is only setting verify=false
which disables my cert verification.
seems like it would work only for ip addresses, and not for DNS names (they were lost) so it's a bit driver bug as well
Yes, I see. Seems, that this is why the workaround I suggested initially needed.
@fruch I've created another issue on the proposed check_hostname
cqlshrc property discussed here. https://github.com/scylladb/scylla-cqlsh/issues/77
Currently we get the following error running cqlsh with such a server certificate and
hostname=dbserver[.fqdn]
in the[connection]
section of thecqlshrc
file.The workaround is to add the last line after the 1-st one in the
/opt/scylladb/share/cassandra/libexec/cqlsh.py
file.