I have a Tomcat 8.5 server running on an Amazon Linux EC2 Linux instance. Tomcat is running on port 8443, with IPTables remapping 443 to it.
I've changed the "sslProtocol" clause of the connector to specify TLS 1.2 protocol. And the change doesn't work: it 's still accepting TLS 1.0 and 1.1 as well as 1.2. Anybody know what the problem could be?
The Connector looks like this (sensitive information redacted):
<Connector port="8443" proxyPort="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,text/json,application/x-javascript,application/javascript,application/json"
maxThreads="1000" socket.appReadBufSize="1024" socket.appWriteBufSize="1024" bufferSize="1024" SSLEnabled="true" scheme="https" secure="true"
keystoreFile="/etc/tomcat8/dev.REDACTED.net.ks" keyAlias="REDACTED" ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA"
clientAuth="false" sslProtocol="TLSv1.2" />
(previously, the "sslProtocol" clause was 'sslProtocol="TLS"')
The same "sslProtocol" clause works just fine in the connector tag of a Tomcat 7 server running on a customer's AS/400, restricting it to TLS 1.2.
From the documentation for Connector (formatting simplified because doing HTML on Stack is too hard)
and for SSLHostConfig (ditto)
In other words, this is the value passed to
SSLContext.getInstance()
. Since you don't identify your Java, I'll use context names for the current Oracle LTS version, 11 (emphasis added):And the implementation of that context in the SunJSSE provider enables TLSv1 (which means 1.0), TLSv1.1, and TLSv1.2 -- in other words, it means "maximum 1.2". In older versions of Java it also enabled SSLv3, but that was removed as insecure after the POODLE attack a few years ago. (I love saying "POODLE attack", it just sounds so silly. :-)
The attribute that selectively controls the list of enabled protocols is
protocols
in SSLHostConfig -- mentioned (briefly) in the quote above -- or equivalently but spelled differentlysslEnabledProtocols
in Connector. In older versions (before 8.5 'merged' the configurations) it wasSSLProtocol
in Connector only when using OpenSSL/APR.AS/400 is almost certainly using IBM Java rather than Sun-now-Oracle-now-OpenJDK. IBM licensed the source from Sun way back when, and guarantees compatibility with the Java specification defined by Sun -- which explicitly excluded, and still does, the cryptoproviders. IBM has its own cryptoproviders which are different from (though functionally very similar to) the Sun/Oracle/Open ones, so to know what it does for particular SSLContext's you need to find the IBM documentation on the (or some) IBM website, which I always find unnavigable. It may implement TLSv1.2 as "minimum 1.2".
PS: do you really have both RSA and ECC certs in your keystore? If not, much of that huge value you use for ciphers is useless, wasted clutter. Plus no sane client anywhere wants to use static-ECDH (or static-DH either) ciphersuites. Do you understand the very important difference between ECDH and ECDHE in TLS terminology?
The correct answer came in over the weekend, from the Tomcat Users list, straight from two of the developers: