You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by Gary Gregory <ga...@gmail.com> on 2017/05/09 07:21:55 UTC

Best way to use one SSLContext for different origin servers in a proxy

Hi All,

We have a nice example in HttpCore for an HTTP reverse proxy here:

https://hc.apache.org/httpcomponents-core-4.4.x/httpcore-nio/examples/org/apache/http/examples/nio/NHttpReverseProxy.java

I've taken this example and morphed into a different beast. I am wondering
how I can let each origin server client have its own SSLContext in order
for me to given them different TrustStrategy implementations.

In our example, we set things up like this:

        final IOEventDispatch *connectingEventDispatch *= new
DefaultHttpClientIODispatch(
                clientHandler, ConnectionConfig.DEFAULT);

        final IOEventDispatch listeningEventDispatch = new
DefaultHttpServerIODispatch(
                serviceHandler, ConnectionConfig.DEFAULT);

        Thread t = new Thread(new Runnable() {

            public void run() {
                try {
                    connectingIOReactor.execute(*connectingEventDispatch*);
                } catch (InterruptedIOException ex) {
                    System.err.println("Interrupted");
                } catch (IOException ex) {
                    ex.printStackTrace();
                } finally {
                    try {
                        listeningIOReactor.shutdown();
                    } catch (IOException ex2) {
                        ex2.printStackTrace();
                    }
                }
            }

        });
        t.start();


In my case I build the connectingEventDispatch with our lower-level APIs in
order to pass in the SSLContext like this:

ConnectionConfig clientConnectionConfig = ConnectionConfig.DEFAULT;
IOEventDispatch *connectingEventDispatch *=
    clientSslContext == null ?
    new DefaultHttpClientIODispatch(clientHandler, clientConnectionConfig)
:
    new DefaultHttpClientIODispatch(clientHandler, *clientSslContext*,
clientConnectionConfig);

But this SSLContext is used for ALL origin servers (a.k.a. target hosts)

Do I need to build a connectingEventDispatch for each SSLContext I need and
then execute each like the above:

connectingIOReactor.execute(connectingEventDispatch);

Each execute in its own thread?

Or is there a cleaner, more HttpCore way to do this?

Thank you!
Gary

-- 
E-Mail: garydgregory@gmail.com | ggregory@apache.org
Java Persistence with Hibernate, Second Edition
<https://www.amazon.com/gp/product/1617290459/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1617290459&linkCode=as2&tag=garygregory-20&linkId=cadb800f39946ec62ea2b1af9fe6a2b8>

<http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1617290459>
JUnit in Action, Second Edition
<https://www.amazon.com/gp/product/1935182021/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1935182021&linkCode=as2&tag=garygregory-20&linkId=31ecd1f6b6d1eaf8886ac902a24de418%22>

<http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1935182021>
Spring Batch in Action
<https://www.amazon.com/gp/product/1935182951/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1935182951&linkCode=%7B%7BlinkCode%7D%7D&tag=garygregory-20&linkId=%7B%7Blink_id%7D%7D%22%3ESpring+Batch+in+Action>
<http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1935182951>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

Re: Best way to use one SSLContext for different origin servers in a proxy

Posted by Gary Gregory <ga...@gmail.com>.
Thank you the pointer. I am experimenting based on your idea.

Gary

On Tue, May 9, 2017 at 2:04 AM, Oleg Kalnichevski <ol...@apache.org> wrote:

> On Tue, 2017-05-09 at 01:39 -0700, Gary Gregory wrote:
> > On May 9, 2017 1:00 AM, "Oleg Kalnichevski" <ol...@apache.org> wrote:
> >
> > On Tue, 2017-05-09 at 00:21 -0700, Gary Gregory wrote:
> > > Hi All,
> > >
> > > We have a nice example in HttpCore for an HTTP reverse proxy here:
> > >
> > > https://hc.apache.org/httpcomponents-core-4.4.x/httpcore-nio/exampl
> > > es
> > > /org/apache/http/examples/nio/NHttpReverseProxy.java
> > >
> > > I've taken this example and morphed into a different beast. I am
> > > wondering
> > > how I can let each origin server client have its own SSLContext in
> > > order
> > > for me to given them different TrustStrategy implementations.
> > >
> > > In our example, we set things up like this:
> > >
> > >         final IOEventDispatch *connectingEventDispatch *= new
> > > DefaultHttpClientIODispatch(
> > >                 clientHandler, ConnectionConfig.DEFAULT);
> > >
> > >         final IOEventDispatch listeningEventDispatch = new
> > > DefaultHttpServerIODispatch(
> > >                 serviceHandler, ConnectionConfig.DEFAULT);
> > >
> > >         Thread t = new Thread(new Runnable() {
> > >
> > >             public void run() {
> > >                 try {
> > >                     connectingIOReactor.execute(*connectingEventDis
> > > pa
> > > tch*);
> > >                 } catch (InterruptedIOException ex) {
> > >                     System.err.println("Interrupted");
> > >                 } catch (IOException ex) {
> > >                     ex.printStackTrace();
> > >                 } finally {
> > >                     try {
> > >                         listeningIOReactor.shutdown();
> > >                     } catch (IOException ex2) {
> > >                         ex2.printStackTrace();
> > >                     }
> > >                 }
> > >             }
> > >
> > >         });
> > >         t.start();
> > >
> > >
> > > In my case I build the connectingEventDispatch with our lower-level
> > > APIs in
> > > order to pass in the SSLContext like this:
> > >
> > > ConnectionConfig clientConnectionConfig = ConnectionConfig.DEFAULT;
> > > IOEventDispatch *connectingEventDispatch *=
> > >     clientSslContext == null ?
> > >     new DefaultHttpClientIODispatch(clientHandler,
> > > clientConnectionConfig)
> > > :
> > >     new DefaultHttpClientIODispatch(clientHandler,
> > > *clientSslContext*,
> > > clientConnectionConfig);
> > >
> > > But this SSLContext is used for ALL origin servers (a.k.a. target
> > > hosts)
> > >
> > > Do I need to build a connectingEventDispatch for each SSLContext I
> > > need and
> > > then execute each like the above:
> > >
> > > connectingIOReactor.execute(connectingEventDispatch);
> > >
> > > Each execute in its own thread?
> > >
> > > Or is there a cleaner, more HttpCore way to do this?
> > >
> >
> > I suppose the IOEventDispatch#onConnect would be the right place to
> > implement TLS upgrade. One can employ various strategies here, for
> > instance, passing some sort of config object as an attachment to the
> > session request and building SSL context for the session based on
> > that
> > config.
> >
> >
> > Hi Oleg,
> >
> > I am not talking about upgrading connections, even though that would
> > be
> > nice but a separate topic. I
> >
> > I know at startup whether I need SSL or not for each origin server
> > and
> > which TrustStrategy for origin server. I am wondering how to install
> > a TS
> > for each given origin server.
>
>
> I am not sure I understand the problem you are having. One would set up
> trust material when upgrading to SSL/TLS, wound not one?
>
> ---
>
> class MyIODispatch extends AbstractIODispatch<DefaultNHttpClientConnection>
> {
>
>     @Override
>     protected DefaultNHttpClientConnection createConnection(final
> IOSession session) {
>
>         InetSocketAddress remoteAddress = (InetSocketAddress)
> session.getRemoteAddress();
>         if ("secure-origin".equalsIgnoreCase(remoteAddress.getHostName()))
> {
>
>             SSLContext sslContext = SSLContextBuilder.create()
>                     .loadTrustMaterial(new TrustStrategy() {
>                         @Override
>                         public boolean isTrusted(X509Certificate[] chain,
> String authType) throws CertificateException {
>                             return true;
>                         }
>                     })
>                     .build();
>             SSLIOSession sslioSession = new SSLIOSession(session,
> SSLMode.CLIENT, sslContext, null);
>             session.setAttribute(SSLIOSession.SESSION_KEY, sslioSession);
>         }
>         return new DefaultNHttpClientConnection(session, 8 * 1024);
>     }
> }
> ---
>
> Oleg
>
> >
> > It is still a little too early for me to port my app to 5.0 as I am
> > still
> > flushing out features. I certainly plan on doing that and helping
> > with 5.0
> > as much as I can.
> >
> > Gary
> >
> >
> > Oleg
> >
> > PS: I hope that TLS upgrade APIs in 5.0 are much nicer.
> >
> >
> > > Thank you!
> > > Gary
> > >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
> > For additional commands, e-mail: dev-help@hc.apache.org
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
> For additional commands, e-mail: dev-help@hc.apache.org
>
>


-- 
E-Mail: garydgregory@gmail.com | ggregory@apache.org
Java Persistence with Hibernate, Second Edition
<https://www.amazon.com/gp/product/1617290459/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1617290459&linkCode=as2&tag=garygregory-20&linkId=cadb800f39946ec62ea2b1af9fe6a2b8>

<http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1617290459>
JUnit in Action, Second Edition
<https://www.amazon.com/gp/product/1935182021/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1935182021&linkCode=as2&tag=garygregory-20&linkId=31ecd1f6b6d1eaf8886ac902a24de418%22>

<http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1935182021>
Spring Batch in Action
<https://www.amazon.com/gp/product/1935182951/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1935182951&linkCode=%7B%7BlinkCode%7D%7D&tag=garygregory-20&linkId=%7B%7Blink_id%7D%7D%22%3ESpring+Batch+in+Action>
<http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1935182951>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

Re: Best way to use one SSLContext for different origin servers in a proxy

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Tue, 2017-05-09 at 01:39 -0700, Gary Gregory wrote:
> On May 9, 2017 1:00 AM, "Oleg Kalnichevski" <ol...@apache.org> wrote:
> 
> On Tue, 2017-05-09 at 00:21 -0700, Gary Gregory wrote:
> > Hi All,
> > 
> > We have a nice example in HttpCore for an HTTP reverse proxy here:
> > 
> > https://hc.apache.org/httpcomponents-core-4.4.x/httpcore-nio/exampl
> > es
> > /org/apache/http/examples/nio/NHttpReverseProxy.java
> > 
> > I've taken this example and morphed into a different beast. I am
> > wondering
> > how I can let each origin server client have its own SSLContext in
> > order
> > for me to given them different TrustStrategy implementations.
> > 
> > In our example, we set things up like this:
> > 
> >         final IOEventDispatch *connectingEventDispatch *= new
> > DefaultHttpClientIODispatch(
> >                 clientHandler, ConnectionConfig.DEFAULT);
> > 
> >         final IOEventDispatch listeningEventDispatch = new
> > DefaultHttpServerIODispatch(
> >                 serviceHandler, ConnectionConfig.DEFAULT);
> > 
> >         Thread t = new Thread(new Runnable() {
> > 
> >             public void run() {
> >                 try {
> >                     connectingIOReactor.execute(*connectingEventDis
> > pa
> > tch*);
> >                 } catch (InterruptedIOException ex) {
> >                     System.err.println("Interrupted");
> >                 } catch (IOException ex) {
> >                     ex.printStackTrace();
> >                 } finally {
> >                     try {
> >                         listeningIOReactor.shutdown();
> >                     } catch (IOException ex2) {
> >                         ex2.printStackTrace();
> >                     }
> >                 }
> >             }
> > 
> >         });
> >         t.start();
> > 
> > 
> > In my case I build the connectingEventDispatch with our lower-level
> > APIs in
> > order to pass in the SSLContext like this:
> > 
> > ConnectionConfig clientConnectionConfig = ConnectionConfig.DEFAULT;
> > IOEventDispatch *connectingEventDispatch *=
> >     clientSslContext == null ?
> >     new DefaultHttpClientIODispatch(clientHandler,
> > clientConnectionConfig)
> > :
> >     new DefaultHttpClientIODispatch(clientHandler,
> > *clientSslContext*,
> > clientConnectionConfig);
> > 
> > But this SSLContext is used for ALL origin servers (a.k.a. target
> > hosts)
> > 
> > Do I need to build a connectingEventDispatch for each SSLContext I
> > need and
> > then execute each like the above:
> > 
> > connectingIOReactor.execute(connectingEventDispatch);
> > 
> > Each execute in its own thread?
> > 
> > Or is there a cleaner, more HttpCore way to do this?
> > 
> 
> I suppose the IOEventDispatch#onConnect would be the right place to
> implement TLS upgrade. One can employ various strategies here, for
> instance, passing some sort of config object as an attachment to the
> session request and building SSL context for the session based on
> that
> config.
> 
> 
> Hi Oleg,
> 
> I am not talking about upgrading connections, even though that would
> be
> nice but a separate topic. I
> 
> I know at startup whether I need SSL or not for each origin server
> and
> which TrustStrategy for origin server. I am wondering how to install
> a TS
> for each given origin server.


I am not sure I understand the problem you are having. One would set up
trust material when upgrading to SSL/TLS, wound not one?

---

class MyIODispatch extends AbstractIODispatch<DefaultNHttpClientConnection> {

    @Override
    protected DefaultNHttpClientConnection createConnection(final IOSession session) {

        InetSocketAddress remoteAddress = (InetSocketAddress) session.getRemoteAddress();
        if ("secure-origin".equalsIgnoreCase(remoteAddress.getHostName())) {

            SSLContext sslContext = SSLContextBuilder.create()
                    .loadTrustMaterial(new TrustStrategy() {
                        @Override
                        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                            return true;
                        }
                    })
                    .build();
            SSLIOSession sslioSession = new SSLIOSession(session, SSLMode.CLIENT, sslContext, null);
            session.setAttribute(SSLIOSession.SESSION_KEY, sslioSession);
        }
        return new DefaultNHttpClientConnection(session, 8 * 1024);
    }
}
---

Oleg

> 
> It is still a little too early for me to port my app to 5.0 as I am
> still
> flushing out features. I certainly plan on doing that and helping
> with 5.0
> as much as I can.
> 
> Gary
> 
> 
> Oleg
> 
> PS: I hope that TLS upgrade APIs in 5.0 are much nicer.
> 
> 
> > Thank you!
> > Gary
> > 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
> For additional commands, e-mail: dev-help@hc.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Best way to use one SSLContext for different origin servers in a proxy

Posted by Gary Gregory <ga...@gmail.com>.
On May 9, 2017 1:00 AM, "Oleg Kalnichevski" <ol...@apache.org> wrote:

On Tue, 2017-05-09 at 00:21 -0700, Gary Gregory wrote:
> Hi All,
>
> We have a nice example in HttpCore for an HTTP reverse proxy here:
>
> https://hc.apache.org/httpcomponents-core-4.4.x/httpcore-nio/examples
> /org/apache/http/examples/nio/NHttpReverseProxy.java
>
> I've taken this example and morphed into a different beast. I am
> wondering
> how I can let each origin server client have its own SSLContext in
> order
> for me to given them different TrustStrategy implementations.
>
> In our example, we set things up like this:
>
>         final IOEventDispatch *connectingEventDispatch *= new
> DefaultHttpClientIODispatch(
>                 clientHandler, ConnectionConfig.DEFAULT);
>
>         final IOEventDispatch listeningEventDispatch = new
> DefaultHttpServerIODispatch(
>                 serviceHandler, ConnectionConfig.DEFAULT);
>
>         Thread t = new Thread(new Runnable() {
>
>             public void run() {
>                 try {
>                     connectingIOReactor.execute(*connectingEventDispa
> tch*);
>                 } catch (InterruptedIOException ex) {
>                     System.err.println("Interrupted");
>                 } catch (IOException ex) {
>                     ex.printStackTrace();
>                 } finally {
>                     try {
>                         listeningIOReactor.shutdown();
>                     } catch (IOException ex2) {
>                         ex2.printStackTrace();
>                     }
>                 }
>             }
>
>         });
>         t.start();
>
>
> In my case I build the connectingEventDispatch with our lower-level
> APIs in
> order to pass in the SSLContext like this:
>
> ConnectionConfig clientConnectionConfig = ConnectionConfig.DEFAULT;
> IOEventDispatch *connectingEventDispatch *=
>     clientSslContext == null ?
>     new DefaultHttpClientIODispatch(clientHandler,
> clientConnectionConfig)
> :
>     new DefaultHttpClientIODispatch(clientHandler,
> *clientSslContext*,
> clientConnectionConfig);
>
> But this SSLContext is used for ALL origin servers (a.k.a. target
> hosts)
>
> Do I need to build a connectingEventDispatch for each SSLContext I
> need and
> then execute each like the above:
>
> connectingIOReactor.execute(connectingEventDispatch);
>
> Each execute in its own thread?
>
> Or is there a cleaner, more HttpCore way to do this?
>

I suppose the IOEventDispatch#onConnect would be the right place to
implement TLS upgrade. One can employ various strategies here, for
instance, passing some sort of config object as an attachment to the
session request and building SSL context for the session based on that
config.


Hi Oleg,

I am not talking about upgrading connections, even though that would be
nice but a separate topic. I

I know at startup whether I need SSL or not for each origin server and
which TrustStrategy for origin server. I am wondering how to install a TS
for each given origin server.

It is still a little too early for me to port my app to 5.0 as I am still
flushing out features. I certainly plan on doing that and helping with 5.0
as much as I can.

Gary


Oleg

PS: I hope that TLS upgrade APIs in 5.0 are much nicer.


> Thank you!
> Gary
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org

Re: Best way to use one SSLContext for different origin servers in a proxy

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Tue, 2017-05-09 at 00:21 -0700, Gary Gregory wrote:
> Hi All,
> 
> We have a nice example in HttpCore for an HTTP reverse proxy here:
> 
> https://hc.apache.org/httpcomponents-core-4.4.x/httpcore-nio/examples
> /org/apache/http/examples/nio/NHttpReverseProxy.java
> 
> I've taken this example and morphed into a different beast. I am
> wondering
> how I can let each origin server client have its own SSLContext in
> order
> for me to given them different TrustStrategy implementations.
> 
> In our example, we set things up like this:
> 
>         final IOEventDispatch *connectingEventDispatch *= new
> DefaultHttpClientIODispatch(
>                 clientHandler, ConnectionConfig.DEFAULT);
> 
>         final IOEventDispatch listeningEventDispatch = new
> DefaultHttpServerIODispatch(
>                 serviceHandler, ConnectionConfig.DEFAULT);
> 
>         Thread t = new Thread(new Runnable() {
> 
>             public void run() {
>                 try {
>                     connectingIOReactor.execute(*connectingEventDispa
> tch*);
>                 } catch (InterruptedIOException ex) {
>                     System.err.println("Interrupted");
>                 } catch (IOException ex) {
>                     ex.printStackTrace();
>                 } finally {
>                     try {
>                         listeningIOReactor.shutdown();
>                     } catch (IOException ex2) {
>                         ex2.printStackTrace();
>                     }
>                 }
>             }
> 
>         });
>         t.start();
> 
> 
> In my case I build the connectingEventDispatch with our lower-level
> APIs in
> order to pass in the SSLContext like this:
> 
> ConnectionConfig clientConnectionConfig = ConnectionConfig.DEFAULT;
> IOEventDispatch *connectingEventDispatch *=
>     clientSslContext == null ?
>     new DefaultHttpClientIODispatch(clientHandler,
> clientConnectionConfig)
> :
>     new DefaultHttpClientIODispatch(clientHandler,
> *clientSslContext*,
> clientConnectionConfig);
> 
> But this SSLContext is used for ALL origin servers (a.k.a. target
> hosts)
> 
> Do I need to build a connectingEventDispatch for each SSLContext I
> need and
> then execute each like the above:
> 
> connectingIOReactor.execute(connectingEventDispatch);
> 
> Each execute in its own thread?
> 
> Or is there a cleaner, more HttpCore way to do this?
> 

I suppose the IOEventDispatch#onConnect would be the right place to
implement TLS upgrade. One can employ various strategies here, for
instance, passing some sort of config object as an attachment to the
session request and building SSL context for the session based on that
config.

Oleg

PS: I hope that TLS upgrade APIs in 5.0 are much nicer. 


> Thank you!
> Gary
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org