Bug 60762 - Enhancement: Add support for runtime SNI changes in tomcat-embed
Summary: Enhancement: Add support for runtime SNI changes in tomcat-embed
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: Connectors (show other bugs)
Version: 8.5.x-trunk
Hardware: All All
: P2 enhancement (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
: 55770 (view as bug list)
Depends on:
Reported: 2017-02-21 23:31 UTC by Jesse
Modified: 2017-11-23 18:51 UTC (History)
3 users (show)


Note You need to log in before you can comment on or make changes to this bug.
Description Jesse 2017-02-21 23:31:03 UTC
This is an enhancement request, I have put it against Tomcat 8 since that is the latest stable product, if this enhancement is more appropriate for the Tomcat 9 release please move it or let me know and I can re-submit it.

The request is to add public methods for adding/removing/updating SSLHostConfig objects within the AbstractEndpoint.sslHostConfigs map.  Ideally this would be exposed publicly via the Connector class.  I think this is specific to tomcat-embed since I don't believe that runtime changes such as this are possible elsewhere.

For our application I have exposed the functionality needed by extending the NioEndpoint class, this does not consider any of the other nio2/apr/bio connectors, as we only use nio it works for us.  I have tested and been running this way for a while now.

I have also extended the AbstractHttp11JsseProtocol and Connector classes so I can gain access to my implementation of NioEndpoint, this is just for convenience, I think these methods belong publicly exposed on the Connector class (similar to how addSslHostConfig/findSslHostConfigs methods are delegated from Connector all the way to AbstractEndpoint).

The methods I've added to my NioEndpoint implementation:

    // this behaves similar to a Map.put operation, only it is void
    public void addOrUpdateSSLHostConfig(SSLHostConfig config)

    public void removeSSLHostConfig(String sniHostName)

For the nio implementation I had to ensure the ssl contexts were released/created, not sure about how that would work for the other implementations.

Comment 1 Christopher Schultz 2017-02-22 04:15:52 UTC
If you call org.apache.tomcat.util.net.AbstractEndpoint.addSslHostConfig(SSLHostConfig) with a hostconfig object with a hostname matching an existing hostconfig, it will be replaced.

Is this not sufficient?

Note that the new SSLHostConfig has no effect unless you bounce the whole connector.
Comment 2 Jesse 2017-02-22 17:47:34 UTC
In version 8.5.9 that we are running it looks like that method calls putIfAbsent against the sslHostConfigs map, throwing an IllegalArgumentException if there is a duplicate SSLHostConfig object for the given key/hostname.  From what I can tell there is no existing public method in 8.5.9 to modify an existing SSLHostConfig once loaded, additionally the methods to do so properly with regard to ssl context release/create are protected.  Please correct me if my understanding of this is wrong.

Also, in the case where an SSL certificate or SSLHostConfig object needs to be removed for any reason, this method would not suffice with either behavior.

When you say that the new SSLHostConfig has no effect without bouncing the whole connector, is this in a newer tomcat version?  Or do you refer to the newly created SSLHostConfig object that we are creating and putting in the sslHostConfigs map?  In the latter case we definitely are seeing the newly created SSLHostConfig object taking effect and new requests to it's hostname are being served the corresponding certificate.
Comment 3 Mark Thomas 2017-03-06 22:08:07 UTC
For anyone looking at implementing this, the following thread will be useful:

The short version is removing an SSLHostConfig for APR/native is going to be  tricky.
Comment 4 Ralf Hauser 2017-07-21 07:41:10 UTC
Might be useful to implement letsencrypt - see also

http://people.apache.org/~schultz/ApacheCon NA 2017/Let's Encrypt Apache Tomcat.pdf
Comment 5 Jesse 2017-07-21 18:23:16 UTC
We have actually implemented letsencrypt in our application.  We allow users to configure new domains that our application will respond to over SSL, and we give them the option to provide their own certificate or the application can generate (and auto-renew) for them via letsencrypt.

I do agree that this request would align well with the needs of tomcat supporting letsencrypt, although my request is actually to provide the public methods so our application can control things as necessary to leverage letsencrypt or user provided certificates at runtime.  Those same methods could likely be used by more generic letsencrypt support as well.
Comment 6 Mark Thomas 2017-09-15 20:12:24 UTC
This has been implemented in 9.0.x for 9.0.0.M28 onwards.

I'll back-port it to 8.5.x once folks have had a chance to test it.
Comment 7 Mark Thomas 2017-11-23 15:10:40 UTC
*** Bug 55770 has been marked as a duplicate of this bug. ***
Comment 8 Mark Thomas 2017-11-23 18:51:28 UTC
This will be available in 8.5.24 onwards.

There are no plans at this time to back-port this to 8.0.x or 7.0.x.