20

I am trying to reconfigure my Apache Tomcat server to only use TLSv1. However, it is still falling back to SSLv3 using certain browsers.

I setup the <connector> tag with the following settings:

<Connector ...
       enableLookups="true" disableUploadTimeout="true"
       acceptCount="100"  maxThreads="200"
       scheme="https" secure="true" SSLEnabled="true"
       clientAuth="false" sslProtocol="TLS" ciphers="TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA" sslEnabledProtocols="TLSv1" />

Am I missing a configuration setting or have somethign present that I shouldn't have present?

rmiesen
  • 302
  • 1
  • 2
  • 6
  • What is the problem with v3? I thought that v1 had security issues. – mdpc Oct 16 '14 at 21:36
  • 8
    @mdpc POODLE affects SSLv3. – Gene Gotimer Oct 16 '14 at 21:38
  • 2
    Tomcat version ? JDK version ? In recent versions sslProtocol is TLS by default. – Xavier Lucas Oct 16 '14 at 21:57
  • 2
    rmeisen: The answers will vary depending on your Tomcat and Java versions, and if you are using JSSE verses AJP. The differences are as subtle as `sslProtocols=TLSv1` verses `sslProtocol="TLS"` (Notice that `s`?). Specifying your Tomcat & Java versions will save you from insanity. – Stefan Lasiewski Oct 17 '14 at 00:25

8 Answers8

13

Depending on the version of Tomcat 5 and Version 6 the SSLEnabled="true" might not work as it was added mid-release. To get past this you just need to edit the following: sslProtocols = TLS To: sslProtocols = "TLSv1,TLSv1.1,TLSv1.2"

Seems strange but even though it says TLS, it contains the SSL 3.

This fixed it on our Tomcat 5.5.20 and our Tomcat 6 instances. -Greg

I believe what you need to do is:

Jboss:

<Connector protocol="HTTP/1.1" SSLEnabled="true" 
       enableLookups="true" disableUploadTimeout="true"
       acceptCount="100"  maxThreads="200"
       scheme="https" secure="true" clientAuth="false" 
       keystoreFile="${jboss.server.home.dir}/conf/keystore.jks"
       keystorePass="rmi+ssl"
       sslProtocols = "TLSv1,TLSv1.1,TLSv1.2" />

Not sure on the cipher suite definition however sslprotocols should just be set to TLSv1,TLSv1.1,TLSv1.2

depending on your tomcat version it will differ, other potential solutions:

Tomcat 5 and 6

<Connector...
   enableLookups="true" disableUploadTimeout="true"
   acceptCount="100"  maxThreads="200" SSLEnabled="true" scheme="https" secure="true"
   clientAuth="false" sslEnabledProtocols = "TLSv1,TLSv1.1,TLSv1.2" />

**On RHEL5-based distros, the following applies to Tomcat 6 versions prior to Tomcat 6.0.38 **

Note that TLSv1.1,TLSv1.2 is supported by Java 7, not Java 6. Adding these directives to a server running Java 6 is harmless, but won't enable TLSv1.1 & TLSv1.2.

<Connector...
   enableLookups="true" disableUploadTimeout="true"
   acceptCount="100"  maxThreads="200" SSLEnabled="true" scheme="https" secure="true"
   clientAuth="false" sslProtocols = "TLSv1,TLSv1.1,TLSv1.2" />

Tomcat >=7

<Connector...
       enableLookups="true" disableUploadTimeout="true"
       acceptCount="100"  maxThreads="200" SSLEnabled="true" scheme="https" secure="true"
       clientAuth="false" sslProtocols = "TLSv1,TLSv1.1,TLSv1.2" />

Tomcat APR connectors

<Connector...
               maxThreads="200"
               enableLookups="true" disableUploadTimeout="true"
               acceptCount="100" scheme="https" secure="true"
               SSLEnabled="true" 
               SSLProtocol="TLSv1"
               SSLCertificateFile="${catalina.base}/conf/localhost.crt"
               SSLCertificateKeyFile="${catalina.base}/conf/localhost.key" />

the above is altered to cater to what your connector specifications were above. Source: https://access.redhat.com/solutions/1232233

Stefan Lasiewski
  • 22,949
  • 38
  • 129
  • 184
RCG
  • 784
  • 1
  • 6
  • 15
4

I have a similar use case, which is to enable Tomcat 7 to strictly use only TLSv1.2, not to fall back to earlier SSL protocols such as TLSv1.1 or SSLv3.

I am using: C:\apache-tomcat-7.0.64-64bit and C:\Java64\jdk1.8.0_60.

Following this instruction: https://tomcat.apache.org/tomcat-7.0-doc/security-howto.html. Tomcat is relatively simple to setup SSL support.

From many references I tested many combination, finally I found 1 which will enforce Tomcat 7 to accept TLSv1.2 only. 2 places needed to touch:

1) In C:\apache-tomcat-7.0.64-64bit\conf\server.xml

<Connector port="8443" 
 protocol="org.apache.coyote.http11.Http11Protocol"
 maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
 keystoreFile="ssl/.keystore" keystorePass="changeit"
 clientAuth="false" sslProtocol="SSL" sslEnabledProtocols="TLSv1.2" />

where

keystoreFile = local self-signed trust store

org.apache.coyote.http11.Http11Protocol = JSSE BIO implementation.

We don't use org.apache.coyote.http11.Http11AprProtocol, because it is powered by openssl. The underlying openssl will fall back to support earlier SSL protocols.

2) When start up Tomcat, enable the following environment parameters.

set JAVA_HOME=C:\Java64\jdk1.8.0_60
set PATH=%PATH%;C:\Java64\jdk1.8.0_60\bin
set CATALINA_HOME=C:\apache-tomcat-7.0.64-64bit
set JAVA_OPTS=-Djdk.tls.client.protocols="TLSv1.2" -Dsun.security.ssl.allowUnsafeRenegotiation=false -Dhttps.protocols="TLSv1.2"

JAVA_OPTS restriction is required, otherwise Tomcat (which is powered by Java8) will fall back to support earlier SSL protocols.

Start up Tomcat C:\apache-tomcat-7.0.64-64bit\bin\startup.bat

We can see JAVA_OPTS appears in Tomcat startup log.

Oct 16, 2015 4:10:17 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Djdk.tls.client.protocols=TLSv1.2
Oct 16, 2015 4:10:17 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Dsun.security.ssl.allowUnsafeRenegotiation=false
Oct 16, 2015 4:10:17 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Dhttps.protocols=TLSv1.2

Then, we can use openssl command to verify our setup. First connect localhost:8443 with TLSv1.1 protocol. Tomcat refuses to reply with Server certificate.

C:\OpenSSL-Win32\bin>openssl s_client -connect localhost:8443 -tls1_1
Loading 'screen' into random state - done
CONNECTED(000001C0)
5372:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:.\ssl\s3_pkt.c:362:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 5 bytes and written 0 bytes

Connect localhost:8443 with TLSv1.2 protocol, Tomcat replies ServerHello with certificate:

C:\OpenSSL-Win32\bin>openssl s_client -connect localhost:8443 -tls1_2
Loading 'screen' into random state - done
CONNECTED(000001C0)
depth=1 C = US, ST = Washington, L = Seattle, O = getaCert - www.getacert.com
verify error:num=19:self signed certificate in certificate chain
---
Certificate chain
0 s:/C=SG/ST=SG/L=Singapore/O=Xxxx/OU=Development/CN=Myself
   i:/C=US/ST=Washington/L=Seattle/O=getaCert - www.getacert.com
1 s:/C=US/ST=Washington/L=Seattle/O=getaCert - www.getacert.com
   i:/C=US/ST=Washington/L=Seattle/O=getaCert - www.getacert.com
---
Server certificate
-----BEGIN CERTIFICATE-----
(ignored)
-----END CERTIFICATE-----
subject=/C=SG/ST=SG/L=Singapore/O=Xxxx/OU=Development/CN=Myself
issuer=/C=US/ST=Washington/L=Seattle/O=getaCert - www.getacert.com
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 2367 bytes and written 443 bytes

This proves that Tomcat now strictly respond to TLSv1.2 request only.

Jenny D
  • 27,358
  • 21
  • 74
  • 110
oraclesoon
  • 141
  • 2
  • Very nice and thorough answer! Kudos! – Jenny D Oct 16 '15 at 10:34
  • I've found that `JAVA_OPTS=-Djdk.tls.client.protocols="TLSv1.2` is not necessary (Tomcat 8.0.29, Java 1.8.0_74). It's not mentioned here either: https://wiki.apache.org/tomcat/Security/POODLE – Paul Mar 01 '16 at 14:56
  • -Djdk.tls.client.protocols is relevant to Tomcat acting as a client to make requests from elsewhere ... it should only be relevant for that use case. – em_bo Jun 14 '21 at 19:15
2

Tomcat 7 documentation clearly states that the sslEnabledProtocols and sslProtocol options are suppported and that there is an overlap between them:
https://tomcat.apache.org/tomcat-7.0-doc/config/http.html

Gene M
  • 121
  • 1
0

In Tomcat 6.0.41, you will need to use the blocking connector since the NIO one is ignoring those settings.

http://wiki.apache.org/tomcat/Security/POODLE

http://mail-archives.apache.org/mod_mbox/tomcat-users/201410.mbox/%3C5440F1C6.3040205@apache.org%3E

Connector port="443" protocol="org.apache.coyote.http11.Http11Protocol" maxThreads="200" scheme="https" secure="true" SSLEnabled="true" clientAuth="false"
keystoreFile="tomcat.jks" keystorePass="changeit" sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2" />

0

In Tomcat 5.5 you should use undocumented parameter

protocols="TLSv1"

to restrict use of excatly this protocol version.

Mic
  • 1
  • 1
0

To disable SSL 3 (POODLE) in Jboss 4.0.3 SP1 (Tomcat 5.5 with java 1.5) in server.xml change your code like this.

<Connector port="443" address="${jboss.bind.address}" maxThreads="100" strategy="ms" maxHttpHeaderSize="8192" emptySessionPath="true" scheme="https" secure="true" clientAuth="false" keystoreFile="${jboss.server.home.dir}/conf/eCP.keystore" keystorePass="password" sslProtocol="TLS" protocols="TLSv1,TLSv1.1,TLSv1.2" />

Natarajan
  • 11
  • 2
0

for newer Tomcats use sslProtocols and sslEnabledProtocols combo like this:

<Connector port="8443" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" disableUploadTimeout="true" acceptCount="100" scheme="https" secure="true" clientAuth="false" sslProtocols="TLSv1,TLSv1.1,TLSv1.2" sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2" SSLEnabled="true" URIEncoding="UTF-8" keystorePass=""/>

andrej
  • 463
  • 4
  • 12
0

First of all, as @iviorel says, it's not sslProtocols, it's sslProtocol. (Why did his answer get downscore?)

JSSE
For me, on Tomcat 7 and Java 7, sslProtocol in the following configuration doesn't work:

<Connector SSLEnabled="true" clientAuth="false" 
keyAlias="keyalias" keystoreFile="keystore" keystorePass="changeit" 
maxThreads="150" port="443" protocol="org.apache.coyote.http11.Http11Protocol" 
scheme="https" secure="true" sslProtocol="TLSv1,TLSv1.1,TLSv1.2" />

It says:

SEVERE: Failed to initialize end point associated with ProtocolHandler ["http-bio-443"]
java.io.IOException: TLSv1,TLSv1.1,TLSv1.2 SSLContext not available
    at org.apache.tomcat.util.net.jsse.JSSESocketFactory.init(JSSESocketFactory.java:465)
    at org.apache.tomcat.util.net.jsse.JSSESocketFactory.createSocket(JSSESocketFactory.java:187)
    at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:398)
    at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:646)
    ...
Caused by: java.security.NoSuchAlgorithmException: TLSv1,TLSv1.1,TLSv1.2 SSLContext not available
    at sun.security.jca.GetInstance.getInstance(GetInstance.java:159)
    at javax.net.ssl.SSLContext.getInstance(SSLContext.java:156)
    at org.apache.tomcat.util.net.jsse.JSSESocketFactory.createSSLContext(JSSESocketFactory.java:478)
    at org.apache.tomcat.util.net.jsse.JSSESocketFactory.init(JSSESocketFactory.java:439)
    ... 19 more

But the following works just fine:

<Connector SSLEnabled="true" clientAuth="false" 
keyAlias="keyalias" keystoreFile="keystore" keystorePass="changeit" 
maxThreads="150" port="443" protocol="org.apache.coyote.http11.Http11Protocol" 
scheme="https" secure="true" sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2" />

APR
To disable SSL v3, and enable TLSv1 protocol:

SSLProtocol="TLSv1"

To enable TLSv1, TLSv1.1, TLSv1.2 protocols:

SSLProtocol="TLSv1+TLSv1.1+TLSv1.2"

Or:

SSLProtocol="all"

Note: the "TLSv1.1", "TLSv1.2" values require Tomcat Native 1.1.32 and a version of Tomcat that supports it.

Rad
  • 195
  • 3
  • 10