You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by bu...@apache.org on 2017/02/21 23:31:03 UTC

[Bug 60762] New: Enhancement: Add support for runtime SNI changes in tomcat-embed

https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

            Bug ID: 60762
           Summary: Enhancement: Add support for runtime SNI changes in
                    tomcat-embed
           Product: Tomcat 8
           Version: 8.5.x-trunk
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Connectors
          Assignee: dev@tomcat.apache.org
          Reporter: jesse@dreamtsoft.com
  Target Milestone: ----

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.

Thanks!
Jesse

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #20 from Mahesh <ma...@gmail.com> ---
Sure. I could find some ways myself. Posting them here for anyone who comes
across this.

There is now a solution to this starting with Tomcat v8.5.24.

They introduced 2 methods named:

reloadSslHostConfig(String hostName) - to reload a specific host
reloadSslHostConfigs() - reload all

They can be called in various ways:

 1. Using jmx
 2. Using manager service
 3. By making custom protocol - I found this way during my research

Details of way 1 and way 2 are easily available online.

Details of how to go about using way 3:

 1. Make a class extending the protocol of your choice for eg.
Http11NioProtocol
 2. Override the required methods and just call super in them to keep default
behavior 
 3. Make a thread in this class to call reloadSslHostConfigs method time to
time
 4. Package this class in a jar and put that jar in tomcat's lib folder
 5. Edit protocol in connector in server.xml to use this custom defined
protocol 

Find sample code below:

Main protocol class:

        package com.myown.connector;

        import java.io.File;
        import java.io.InputStream;
        import java.lang.reflect.Field;
        import java.net.URL;
        import java.net.URLConnection;
        import java.nio.file.StandardCopyOption;
        import java.util.ArrayList;
        import java.util.List;
        import java.util.concurrent.ConcurrentMap;

        import javax.management.MalformedObjectNameException;
        import javax.management.ObjectName;
        import javax.net.ssl.SSLSessionContext;

        import org.apache.coyote.http11.Http11NioProtocol;
        import org.apache.juli.logging.Log;
        import org.apache.juli.logging.LogFactory;
        import org.apache.tomcat.util.modeler.Registry;
        import org.apache.tomcat.util.net.AbstractEndpoint;
        import org.apache.tomcat.util.net.AbstractJsseEndpoint;
        import org.apache.tomcat.util.net.GetSslConfig;
        import org.apache.tomcat.util.net.SSLContext;
        import org.apache.tomcat.util.net.SSLHostConfig;
        import org.apache.tomcat.util.net.SSLHostConfigCertificate;
        import org.apache.tomcat.util.net.SSLImplementation;
        import org.apache.tomcat.util.net.SSLUtil;

        public class ReloadProtocol extends Http11NioProtocol {

                private static final Log log =
LogFactory.getLog(Http12ProtocolSSL.class);

                public ReloadProtocol() {
                        super();
                        RefreshSslConfigThread refresher = new 
                      RefreshSslConfigThread(this.getEndpoint(), this);
                        refresher.start();
                }

                @Override
                public void setKeystorePass(String s) {
                        super.setKeystorePass(s);
                }

                @Override
                public void setKeyPass(String s) {
                        super.setKeyPass(s);
                }

                @Override
                public void setTruststorePass(String p) {
                        super.setTruststorePass(p);
                }

                class RefreshSslConfigThread extends Thread {

                        AbstractJsseEndpoint<?> abstractJsseEndpoint = null;
                        Http11NioProtocol protocol = null;

                        public RefreshSslConfigThread(AbstractJsseEndpoint<?>
abstractJsseEndpoint, Http11NioProtocol protocol) {
                                this.abstractJsseEndpoint =
abstractJsseEndpoint;
                                this.protocol = protocol;
                        }

                        public void run() {
                                int timeBetweenRefreshesInt = 1000000; // time
in milli-seconds
                                while (true) {
                                        try {
                                abstractJsseEndpoint.reloadSslHostConfigs();
                                                       
System.out.println("Config Updated");
                                        } catch (Exception e) {
                                                System.out.println("Problem
while reloading.");
                                        }
                                        try {
                                               
Thread.sleep(timeBetweenRefreshesInt);
                                        } catch (InterruptedException e) {
                                                System.out.println("Error while
sleeping");
                                        }
                                }
                        }
           }
    }



Connector in server.xml should mention this as the protocol:

    <Connector protocol="com.myown.connector.ReloadProtocol"
     ..........


Hope this helps.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #14 from Mark Thomas <ma...@apache.org> ---
Catalina:type=ThreadPool,name="http-nio-8080"

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

Mahesh <ma...@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mahesh.ratta95@gmail.com

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #6 from Mark Thomas <ma...@apache.org> ---
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.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

Jesse <je...@dreamtsoft.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jesse@dreamtsoft.com

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

Mark Thomas <ma...@apache.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dmikusa@gopivotal.com

--- Comment #7 from Mark Thomas <ma...@apache.org> ---
*** Bug 55770 has been marked as a duplicate of this bug. ***

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

Mark Thomas <ma...@apache.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #8 from Mark Thomas <ma...@apache.org> ---
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.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #19 from Mark Thomas <ma...@apache.org> ---
The Tomcat community does not use Bugzilla as a user support forum. Questions
relating to the usage of Apache Tomcat are very unlikely to receive an answer
here and should be directed to the Apache Tomcat users mailing list.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

Ralf Hauser <ha...@acm.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hauser@acm.org

--- Comment #4 from Ralf Hauser <ha...@acm.org> ---
Might be useful to implement letsencrypt - see also

http://people.apache.org/~schultz/ApacheCon NA 2017/Let's Encrypt Apache
Tomcat.pdf

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #10 from Mark Thomas <ma...@apache.org> ---
Off the top of my head (I can check later if this doesn't work) you should be
able to do this via JMX.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #18 from Mahesh <ma...@gmail.com> ---
I guess I found the method.

It's reloadSslHostConfig's 2 variants.

But how do I call it ?

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #5 from Jesse <je...@dreamtsoft.com> ---
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.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #2 from Jesse <je...@dreamtsoft.com> ---
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.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #11 from Jesse <je...@dreamtsoft.com> ---
I'd rather not use JMX, I'm not totally familiar with JMX but wouldn't that
require me to enable JMX on a port in our application?

If I can use JMX directly via the embedded tomcat without doing any tcp port
type access then that would work.

For now I have been able to remove my implementation of methods in NioEndpoint
in favor of using the ones you have, but I still have my own extension classes
so I can get access to them.

Thanks,
Jesse

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #13 from Jesse <je...@dreamtsoft.com> ---
I was able to see many tomcat mbeans using:

ManagementFactory.getPlatformMBeanServer().queryNames(new
ObjectName("Tomcat:*"), null)

However I don't see any that look like they'd represent an endpoint in that
list.

I also looked for "Catalina:*" but none were found.

Given that I am running this in the same JVM as the Tomcat instance that I want
to manage, if I could find an ObjectName that represents the AbstractEndpoint,
could I actually get access to the AbstractEndpoint that I want to invoke the
add/removeSslHostConfig methods on?  It seems like the JMX interfaces are all
for string/serialized communications and I need to pass the SSLHostConfig
object that I've created.

Thanks!

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #3 from Mark Thomas <ma...@apache.org> ---
For anyone looking at implementing this, the following thread will be useful:
http://markmail.org/thread/ox3h7oaqgef3qqyk

The short version is removing an SSLHostConfig for APR/native is going to be 
tricky.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #16 from Mark Thomas <ma...@apache.org> ---
Please move this to the users list.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #17 from Mahesh <ma...@gmail.com> ---
Hello,

I was facing this exact bug and glad it is resolved.

But I'm not sure how to proceed with this (really new to configuring tomcat).

I've configured everything in server.xml and 2 way handshaking works. But how
do I periodically call the method added to solve this bug ?

Also I'm not sure which method was actually added. How do I find the code
commit related to this bug ? I tried to find it in github repo but with no
success.

Any help will be really appreciated.

Thanks.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #15 from Jesse <je...@dreamtsoft.com> ---
That gives an InstanceNotFoundException, I can't find any Catalina:* objects.

Even if that did return an object, could I gain direct access to the
AbstractEndpoint instance that I want to call the methods against?

Thanks!

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #1 from Christopher Schultz <ch...@christopherschultz.net> ---
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.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #12 from Christopher Schultz <ch...@christopherschultz.net> ---
(In reply to Jesse from comment #11)
> I'd rather not use JMX, I'm not totally familiar with JMX but wouldn't that
> require me to enable JMX on a port in our application?

You can use JMX within the same JVM just via an API interface. No need to
expose any ports or anything like that.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 60762] Enhancement: Add support for runtime SNI changes in tomcat-embed

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60762

--- Comment #9 from Jesse <je...@dreamtsoft.com> ---
Hi Mark,

Thanks for your work on this, I see the methods on AbstractEndpoint and I think
they are exactly what I need and should allow me to remove my custom
implementation.

The only thing holding me back at this point is that I don't know how to get
access to the AbstractEndpoint from our application.  We have an instance of
Tomcat and can get a Connector using the getConnector method, from there I can
get the ProtocolHandler but that does not offer any way to get the endpoint.  I
could probably safely cast ProtocolHandler to AbstractProtocol where there is a
getEndpoint method, but that method is protected.

Is there an appropriate way for me to get access to the new public methods on
AbstractEndpoint?

Thanks again!
Jesse

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org