• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Tomcat 9 - Setting up SSL

 
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have searched a lot on how to best setup SSL with Tomcat 9 in a future-proof manner given that the documentation mentions a lot of  deprecated elements which are only supported for backward compatibility

Quoting documentation, As of Tomcat 8.5, the majority of the SSL configuration attributes in the Connector are deprecated. If specified, they will be used to configure a SSLHostConfig and Certificate for the defaultSSLHostConfigName. Note that if an explicit SSLHostConfig element also exists for the defaultSSLHostConfigName then that will be treated as a configuration error. It is expected that Tomcat 10 will drop support for the SSL configuration attributes in the Connector.

For instance, I have seen a working Tomcat 9 configuration with the following SSL connector. keystore.jks is a PKCS12 keystore created using Java keytool.  keytool -v -list -keystore keystore.jks with the provided password is able to open and list the contents.



I attempted to convert this to a Tomcat 9 syntax using this



But this throws an error which I can't figure out, the file is there and the password is correct.



Yes, I also updated the systemd tomcat.service to add AmbientCapabilities=CAP_NET_BIND_SERVICE to allow non-root tomcat user to bind to port 443

What am I missing?

Thanks
 
Marshal
Posts: 4509
572
VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Maybe this document will help: Apache Tomcat 9: SSL/TLS Configuration How-To

I avoid having to deal with this by using Apache HTTPd or NGINX as a security gateway to terminate TLS, and then proxy the non-TLS traffic to the backend servers using HTTP.

In addition, when you use HTTPd or NGINX to front-end your application, you can also perform some lightweight WAF (Web Application Firewall) functionality and check for required headers and supported values, ensure security tokens are present and resource paths are valid, block some types of denial-of-service attacks, etc. before passing requests to the backend.  Also, if you have a number of backend servers, you can use the reverse proxies to load-balance your traffic.
 
Ivan Javanik
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That's a good suggestion but I would prefer to terminate SSL in Tomcat.

All the solutions I've seen for SSL in Tomcat use Connector attributes and not the new SSLConfig and Certificate elements. I'm just looking for a solution that uses them as a learning experience.

Any other ideas?
 
Ron McLeod
Marshal
Posts: 4509
572
VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I gave it a quick try using the key and X.509 certificate files directly (no keystore) and got it work using the configuration below.  I didn't out any effort into putting files in the normal locations or making sure that everything in configuration file is correct/complete - I just focused on the PKI parts.  Also, I ran tomcat in a container rather than on the bare OS and use port 8443 instead of 443 - unlikely that would make any difference.

Hopefully you can use that as a reference to get things figured-out in your environment.

Reply back on this thread if you think I might be able to help.


server.xml

podman run -it --rm --name tomcat
   --security-opt label=disable
   -v /opt/server.xml:/usr/local/tomcat/conf/server.xml
   -v /opt/pki:/opt/pki
   -p 8443:8443
   tomcat:9-jdk11
   
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /opt/java/openjdk
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
09-Mar-2023 02:35:22.140 WARNING [main] org.apache.tomcat.util.digester.SetPropertiesRule.begin Match [Server/Service/Connector/SSLHostConfig/Certificate] failed to set property [caCertificateFile] to [/opt/pki/alpha-wildcard-intermediate.pem]
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name:   Apache Tomcat/9.0.73
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Feb 27 2023 15:33:40 UTC
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 9.0.73.0
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            5.4.17-2136.306.1.3.el8uek.x86_64
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /opt/java/openjdk
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           11.0.18+10
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Eclipse Adoptium
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /usr/local/tomcat
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/local/tomcat
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util=ALL-UNNAMED
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util.concurrent=ALL-UNNAMED
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded Apache Tomcat Native library [1.2.36] using APR version [1.7.0].
INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [true].
INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
INFO [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 3.0.2 15 Mar 2022]
INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-openssl-apr-8443"]
INFO [main] org.apache.tomcat.util.net.AbstractEndpoint.logCertificate Connector [https-openssl-apr-8443], TLS virtual host [*.example.net], certificate type [UNDEFINED] configured from [/root/.keystore] using alias [tomcat] and with trust store [null]
INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [1226] milliseconds
INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/9.0.73]
INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["https-openssl-apr-8443"]
INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [93] milliseconds


 
Ivan Javanik
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My certs are in a PKCS12 key store not a PEM. Does that matter?
 
Ron McLeod
Marshal
Posts: 4509
572
VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ivan Javanik wrote:My certs are in a PKCS12 key store not a PEM. Does that matter?


Yeah - PKCS12 is a password-protected archive which will contain the private key and the certificate(s), so the configuration would need to change.

It should be something like this:
 
Ivan Javanik
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, then we are back to where we started, I get that same error, What's more confusing is that the documentation lists certificateFile as an attribute of the Certificate element, not SSLHostConfig

Any other ideas? Thanks



 
Ron McLeod
Marshal
Posts: 4509
572
VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please post the entire Connector section of the server.xml file so I can see what your config is like.
 
Ron McLeod
Marshal
Posts: 4509
572
VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I just tried using a PKCS#12 keystore - works as expected.



Here's how I created the keystore:
 
Saloon Keeper
Posts: 27797
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I've struggled with SSL in Tomcat for many years now and my ultimate conclusion is that it simply is not worth setting up SSL in Tomcat in almost all cases.

Here's why:

Imprimus: The cert files for Tomcat are not in the popular format. Not all certificate providers can give you those files in the form that you need and converting certs intended for standard services like Apache is a royal pain.

Secundus: Tomcat can only listen on the Internet standard HTTP and HTTPS ports (80 and 443) if you run it as a privileged user. This is a security threat to the entire OS.

I think I had a third primary objection, but senility has wiped it from my mind at the moment.

So I always run my SSL channels to a reverse proxy server such as Apache or Nginx and pipeline from there to Tomcat.

Doing that gives me several advantages:

1. It's a lot easier to set up SSL to Apache and Nginx.

2. The proxy servers can safely listen on ports 80 and 443 on behalf of Tomcat.

3. The proxy servers allow me a consolidated entry for all my webapps, both JEE and non-Jee

4. It's fairly easy to set up the link from the proxy server to Tomcat using mod_jk or mod_proxy or their equivalents. And in my case, I have a master configuration that Puppet uses to ensure that my mirrored and load-balanced front-ends all pipe to the various Tomcat-based backend servers (as well as the stuff that's not Tomcat-based)

The setup and overhead for a reverse proxy server is negligible. The benefits are considerable. And Tomcat is "future-proofed" because the proxy Connectors have been pretty stable for a long time.
 
Ivan Javanik
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ron McLeod wrote:Please post the entire Connector section of the server.xml file so I can see what your config is like.



Here you go. The keystore is generated using the keytool command keystore -importkeystore -deststoretype pkcs12

Any idea why this is not working?  Does it matter that you created the keystore using openssl and not keytool?


 
Ron McLeod
Marshal
Posts: 4509
572
VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here are my suggestions:
  - remove any unnecessary configuration attributes (including clientAuth will break things)
  - rename your keystore to keystore.p12 to reflect that it is PKCS#12 (something might infer that it is JKS based on the current name)

 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic