Securing tomcat7 - Disabling RC4 does not work - ssl

I'm trying to secure my tomcat 7 setup. I have currently two problems here comes my first one:
I use basically the default configuration, I just extended the ssl configuration to get an A rating on SSL Labs.
My problem is that I want to disable RC4 since it is insecure, so I added the cipher suites which I trust (well it is the list of Mozilla) it ends with !aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK which means AFIK that those algorithm should not been used. But RC4 is still used here is my full configuration (without comments):
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
URIEncoding="UTF-8"
redirectPort="8443" />
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" SSLHonorCipherOrder="true"
SSLDisableCompression="true" SSLCipherSuite="ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK"
SSLCertificateChainFile="/root/ca.crt"
SSLCACertificatePath="/etc/ssl/certs"
keystoreFile="/path/to/keystore" keystorePass="pwd" />
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
If you know what I'm doing wrong please inform me.

You've formatted your cipher suite list as if you were using APR / OpenSSL, but are still configured to use the NIO connector, which will rely on Java to do the connection, and as such needs that format for the cipher list. Put your preferred suites into a comma delimited list (no classes of suites, only explicit configurations), restart, and see if that doesn't resolve it for you.
Oracle Java 8 cipher names can be found here: http://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html
You can use this connector:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" SSLHonorCipherOrder="true"
SSLDisableCompression="true" ciphers="TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA"
keystoreFile="/path/to/keystore" keystorePass="pwd" />

Related

Why is Tomcat 9 serving same SSL certificate for two different domains that are configured separately?

I have one Linux server where I run three different websites
Server.xml looks like the following
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="443" />
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="1000" SSLEnabled="true" defaultSSLHostConfigName="sub1.domain1.info">
<SSLHostConfig hostName="sub1.domain1.info">
<Certificate certificateFile="conf/app1/cert.pem" certificateKeyFile="conf/app1/privkey.pem" certificateChainFile="conf/app1/chain.pem"
type="RSA" />
</SSLHostConfig>
<SSLHostConfig hostName="www.domain2.com/">
<Certificate certificateFile="conf/app2/cert.pem" certificateKeyFile="conf/app2/privkey.pem" certificateChainFile="conf/app2/chain.pem"
type="RSA" />
</SSLHostConfig>
<SSLHostConfig hostName="domain3.ac.in">
<Certificate certificateFile="conf/app3/cert.pem" certificateKeyFile="conf/app3/privkey.pem" certificateChainFile="conf/app3/chain.pem"
type="RSA" />
</SSLHostConfig>
<SSLHostConfig hostName="*.domain3.ac.in">
<Certificate certificateFile="conf/app2/cert.pem" certificateKeyFile="conf/app2/privkey.pem" certificateChainFile="conf/app2/chain.pem"
type="RSA" />
</SSLHostConfig>
</Connector>
<Host name="sub1.domain1.info" appBase="/home/applocation" unpackWARs="false" deployXML="false">
<Alias>sub1.domain1.info</Alias>
<Context path="" reloadable="true" docBase="/home/applocation" debug="1"/>
<Context docBase="/home/filepath" path="/pattern"/>
</Host>
<Host name="domain2.com" appBase="/home/app2path" unpackWARs="false" deployXML="false">
<Alias>www.domain2.com</Alias>
<Context path="" reloadable="true" docBase="/home/app2path" debug="1"/>
</Host>
<Host name="domain3.ac.in" appBase="/home/app3path" unpackWARs="false" deployXML="false">
<Alias>www.domain3.ac.in</Alias>
<Context path="" reloadable="true" docBase="/home/app3path" debug="1"/>
</Host>
Certificates generated using certbot
certbot certonly --standalone -d domainName
For some reason, when domain2.com is loaded on the browser, it says certificate is not valid. When I check details of the certificate, it carried the details of sub1.domain1.info's certificate (issued to sub1.domain1.info).
I am confused because, it worked for domain3.ac.in
Certificates were first generated for sub1.domain1.com followed by domain3.ac.in and at last www.domain2.com (at least 3 times generated for this domain now).
One thing I noted is that I get one warning while generating certificate for www.domain2.com that says something like "this might not work" but got generated anyway.
Also I am new to SSL with Tomcat, so please suggest any other necessary changes also.

Tomcat 8.5 multiple domains using multiple certificate stores

We had a working setup using multiple domains sharing a certificate. But now the setup is changed to use different certificates for the the different domains.
<server>
<!-- other non-changed stuff -->
<Service name="Catalina">
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="443" />
<Connector
port="443"
clientAuth="false"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="200"
enableLookups="false"
SSLEnabled="true"
scheme="https"
secure="true"
defaultSSLHostConfigName="stuff.company.com">
<SSLHostConfig hostName="stuff.company.com">
<Certificate
certificateKeyAlias="stuff"
certificateKeystoreType="JKS"
certificateKeystoreFile="/conf/certs/stuff.company.com.jks"
certificateKeystorePassword="[redacted]"
certificateKeyPassword="[redacted]"
type="RSA"
/>
</SSLHostConfig>
<SSLHostConfig hostName="things.company2.com">
<Certificate
certificateKeystoreFile="conf/certs/things.company2.com.jks"
certificateKeystorePassword="[redacted]"
certificateKeyPassword="[redacted]"
type="RSA"
/>
</SSLHostConfig>
</Connector>
<Engine>
<Host name="stuff.company.com" appBase="webapps/stuff-company-com">
<Context path="" cookies="false" docBase=""/>
<alias>stuff.company.com</alias>
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="stuff.company.com_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
<Host name="things.company2.com" appBase="webapps/things-company2-com">
<Context path="" cookies="false" docBase=""/>
<alias>things.company2.com</alias>
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="things.company2.com_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
Notes:
Does not seems matter if there is a / or not before conf in certificateKeystoreFile.
Between the config of the Connector with the information and the Host parts there are things
like Realm and Engine. These are not changed since the the previous working setup.
No changes was made in the section between now and the previously working setup.
If we relax the rules. The hosts are reachable over http. But not reachable at all over https
Version of Tomcat is 8.5.53 (latest available at the time of writing)
Windows Server 2012 is the OS
We changed clientAuth (deprecated) to certificateVerification (current way of doing things) which prevents all problems that can emerge from "If this SSLHostConfig element is not explicitly defined, it will be created", that has been discussed elsewhere on Stack Overflow.
Lessons learned are probably to first make sure everything is ported to the new way of doing things. In this case the new way of setting up a Connector. And after that proceed with whatever feature should be implemented.

How to redirect HTTP traffic to HTTPS while using Virtual Hosting in Tomcat

I need to configure my Tomcat 9 server to redirect http to https traffic.
I have tried:
Using a connector for the http port and having a redirectPort attribute pointing to the secure connector.
Including a security-constraint link at the bottom of the web.xml, which works for other Tomcat servers that are not using Virtual Hosting
Connector
<Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="443" />
<Connector
port="443"
protocol="org.apache.coyote.http11.Http11AprProtocol"
secure="true"
scheme="https"
maxThreads="200"
SSLEnabled="true"
maxSpareThreads="75"
maxHttpHeaderSize="8192"
acceptCount="100"
enableLookups="false"
disableUploadTimeout="true"
defaultSSLHostConfigName="example1.com">
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig hostName="example1.com">
<Certificate
certificateKeystoreFile="www_example1_com.jks"
certificateKeystorePassword="…” />
</SSLHostConfig>
<SSLHostConfig hostName="example2.com">
<Certificate
certificateKeystoreFile="www_example2_com.jks"
certificateKeystorePassword="…” />
</SSLHostConfig>
</Connector>
Security Constraint
<security-constraint>
<web-resource-collection>
<web-resource-name>Entire Application</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
Host configuration in server.xml
<!-- example1.com -->
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
<!-- example2.com -->
<Host name="example2.com" appBase="website-webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="website-logs"
prefix="website_access_log."
suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
https://example2.com - Works
https://www.example2.com - Works
www.example2.com - Does not Work
example2.com - Does not work
Port 80 was not open to outside traffic on my server, so the redirect could never happen. The http traffic was not getting to the server.
This was resolved by adding an inbound rule that allowed requests to reach port 80.

SSL Installation Issues for 2 Web-servers in 1 Domain

I have domain and 2 web-servers running on it with different port:
1) https://intellirehab.usim.edu.my (APACHE)
2) http://intellirehab.usim.edu.my:8081 (TOMCAT)
I have the SSL certificates for both of them; server.crt (for APACHE) and server.jks (for TOMCAT). I'm done the configuration part on APACHE server and 'HTTPS' just work fine for me. BUT, I'm trying to configure TOMCAT server to use SSL connection and it doesn't work. I am attempting to follow the instructions for setting up SSL in Tomcat 7 still doesn't work.
This is my server.xml file:
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
-->
<!--APR library loader. Documentation at /docs/apr.html -->
<!--<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> REMOVE IT IF USE KEYSTORE-->
<!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
<Listener className="org.apache.catalina.core.JasperListener" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" maxHttpHeaderSize="1048576" maxThreads="1000" scheme="https" secure="true" SSLEnabled="true" keystoreFile="conf/server.jks" keystorePass="*******" clientAuth="false" sslProtocol="TLS"
/>
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="intellirehab.usim.edu.my">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" />
</Realm>
<Host name="intellirehab.usim.edu.my" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
I've solve this problem by configuring SSL in 8081 connector and remove the 8443 connector. Thanks!

Authentication Required in localhost:8080 after starting the apache-tomcat server

I am using apache-tomcat-6.0.41 on Windows 7.After starting the server I am not able to see tomcat page but a windows asking for username and password prompts up.
I have also modified the tomcat-users.xml file as follows:-
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="manager"/>
<user username="admin" password="admin" roles="manager" />`
</tomcat-users>
My server.xml file also has the realm required as follows:-
?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
</Host>
</Engine>
</Service>
</Server>
Can anyone suggest the solution of this problem?
Please update the server port to a different port number such as 8050 apart from the default port 8080. I also faced the same issue and was able to resolve it by changing the port number.
This seems like you are switching to new page where you are using port 8080, but your tomcat is not actually started or not working on port 8080. Try changing port of tomcat instead of 8080 and check whether other service is not using 8080 port.