[
https://issues.apache.org/jira/browse/CASSANDRA-21750?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Arad Yaron updated CASSANDRA-21750:
-----------------------------------
Description:
cqlsh never sets {{server_hostname}} in the SSL options it passes to the Python
driver. The driver adds SNI only when {{check_hostname}} is enabled, and cqlsh
never enables it, so the TLS ClientHello carries no {{server_name}} extension.
TLS-aware middleboxes (WAFs, SNI-routing proxies, load balancers) may reset or
misroute such connections, even though the host was given on the command line.
cqlsh also exposes only {{validate = true|false}}, with no way to request a
host name check.
*Proposed change* (PR: https://github.com/apache/cassandra/pull/5237, commit
81f2ca9f99, against trunk)
* Send SNI with the target host whenever TLS is on, at every validation level,
except for IP literals (RFC 6066).
* Add {{ssl_mode}} ({{disable | require | verify-ca | verify-identity}}) via
{{--ssl-mode}}, the {{SSL_MODE}} environment variable, or {{[ssl] ssl_mode}} in
cqlshrc, in that order of precedence.
* {{verify-identity}} turns on host name checking.
* When {{ssl_mode}} is unset, {{validate}} keeps today's mapping: true or unset
-> verify-ca, false -> require.
* {{disable}} while SSL is enabled is an error, and an invalid value is
rejected.
* Settings stay an {{ssl_options}} dict rather than an {{SSLContext}}, so the
connection reused via {{self.conn.ssl_options}} keeps working.
*Testing*
* 12 new tests in {{pylib/cqlshlib/test/test_sslhandling.py}} pass. They cover
each mode, the {{validate}} fallback, precedence, IPv4/IPv6 hosts and the error
cases.
* {{pycodestyle --ignore E501,E402,E731,W503}} (per {{pylib/README.asc}}) is
clean.
* Real {{bin/cqlsh}} against a local TLS server that records the SNI of each
handshake:
** trunk, host {{localhost}}: SNI {{None}}
** this patch, {{validate = false}}, host {{localhost}}: SNI {{'localhost'}}
* Docs ({{cqlsh.adoc}}) and {{conf/cqlshrc.sample}} are updated.
*How to reproduce the missing SNI*
Run {{cqlsh --ssl <host> <port>}} against any TLS endpoint that logs the SNI it
receives (or capture the ClientHello). On trunk, no {{server_name}} is sent.
was:
cqlsh never sets {{server_hostname}} in the SSL options it passes to the Python
driver. The driver adds SNI only when {{check_hostname}} is enabled, and cqlsh
never enables it, so the TLS ClientHello carries no {{server_name}} extension.
TLS-aware middleboxes (WAFs, SNI-routing proxies, load balancers) may reset or
misroute such connections, even though the host was given on the command line.
cqlsh also exposes only {{validate = true|false}}, with no way to request a
host name check.
*Proposed change* (PR: https://github.com/apache/cassandra/pull/5237)
* Send SNI with the target host at every validation level, except for IP
literals (RFC 6066).
* Add {{ssl_mode}} ({{disable | require | verify-ca | verify-identity}}) via
{{--ssl-mode}}, the {{SSL_MODE}} environment variable, or {{[ssl] ssl_mode}} in
cqlshrc, in that order of precedence.
* When {{ssl_mode}} is unset, {{validate}} keeps today's mapping: true or unset
-> verify-ca, false -> require.
* {{disable}} while SSL is enabled is an error.
* Settings stay an {{ssl_options}} dict rather than an {{SSLContext}}, so the
connection reused via {{self.conn.ssl_options}} keeps working.
*Testing*
12 new tests in {{pylib/cqlshlib/test/test_sslhandling.py}}. Docs
({{cqlsh.adoc}}) and {{conf/cqlshrc.sample}} are updated.
*How to reproduce the missing SNI*
{noformat}
cqlsh --ssl <host> 9142
# capture the handshake in parallel:
tshark -i any -Y 'tls.handshake.type == 1' -T fields -e
tls.handshake.extensions_server_name
{noformat}
Stock cqlsh prints an empty server name. With the patch it prints {{<host>}}.
> cqlsh: send TLS SNI and add ssl_mode
> ------------------------------------
>
> Key: CASSANDRA-21750
> URL: https://issues.apache.org/jira/browse/CASSANDRA-21750
> Project: Apache Cassandra
> Issue Type: Improvement
> Components: Tool/cqlsh
> Reporter: Arad Yaron
> Priority: Normal
>
> cqlsh never sets {{server_hostname}} in the SSL options it passes to the
> Python driver. The driver adds SNI only when {{check_hostname}} is enabled,
> and cqlsh never enables it, so the TLS ClientHello carries no {{server_name}}
> extension. TLS-aware middleboxes (WAFs, SNI-routing proxies, load balancers)
> may reset or misroute such connections, even though the host was given on the
> command line.
> cqlsh also exposes only {{validate = true|false}}, with no way to request a
> host name check.
> *Proposed change* (PR: https://github.com/apache/cassandra/pull/5237, commit
> 81f2ca9f99, against trunk)
> * Send SNI with the target host whenever TLS is on, at every validation
> level, except for IP literals (RFC 6066).
> * Add {{ssl_mode}} ({{disable | require | verify-ca | verify-identity}}) via
> {{--ssl-mode}}, the {{SSL_MODE}} environment variable, or {{[ssl] ssl_mode}}
> in cqlshrc, in that order of precedence.
> * {{verify-identity}} turns on host name checking.
> * When {{ssl_mode}} is unset, {{validate}} keeps today's mapping: true or
> unset -> verify-ca, false -> require.
> * {{disable}} while SSL is enabled is an error, and an invalid value is
> rejected.
> * Settings stay an {{ssl_options}} dict rather than an {{SSLContext}}, so the
> connection reused via {{self.conn.ssl_options}} keeps working.
> *Testing*
> * 12 new tests in {{pylib/cqlshlib/test/test_sslhandling.py}} pass. They
> cover each mode, the {{validate}} fallback, precedence, IPv4/IPv6 hosts and
> the error cases.
> * {{pycodestyle --ignore E501,E402,E731,W503}} (per {{pylib/README.asc}}) is
> clean.
> * Real {{bin/cqlsh}} against a local TLS server that records the SNI of each
> handshake:
> ** trunk, host {{localhost}}: SNI {{None}}
> ** this patch, {{validate = false}}, host {{localhost}}: SNI {{'localhost'}}
> * Docs ({{cqlsh.adoc}}) and {{conf/cqlshrc.sample}} are updated.
> *How to reproduce the missing SNI*
> Run {{cqlsh --ssl <host> <port>}} against any TLS endpoint that logs the SNI
> it receives (or capture the ClientHello). On trunk, no {{server_name}} is
> sent.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]