You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by "David P. Caldwell" <da...@code.davidpcaldwell.com> on 2017/01/19 15:38:40 UTC

Can Tomcat act as an HTTPS proxy?

I'm trying to forward HTTPS requests through a Tomcat HTTP (or HTTPS)
server to a backend HTTPS server.

The requests are initiated by a Java HTTP client (java.net.URLConnection-based).

So I have:

backend HTTPS server (which works)
Tomcat server running HTTP and HTTPS connectors
Java HTTPUrlConnection, using Tomcat HTTP connector as a proxy

The Java client can successfully:

* use the backend HTTPS server directly
* use the Tomcat HTTP connector
* use the Tomcat HTTPS connector

For my scenario, I think using the HTTP connector to proxy is correct,
though I've also tried using the HTTPS connector.

I'm not an expert on SSL or HTTPS. The HTTPS connector doesn't work,
but my understanding is that using it doesn't make sense; the trust
relationship is end-to-end, so you'd use ordinary HTTP to proxy in
between. It ends up with an unexpected EOF from server or something.

Assuming the HTTP connector is the right one to use, here's my
problem: Tomcat returns a 400 Bad Request when I attempt to request an
https: URL via an ordinary HTTP request to the HTTP connector.

Conceptually, it seems like this ought to be fine, to me, but as I
said, my understanding of the concepts is a bit murky, so I might be
wrong.

Am I on the right track? If so, is there something configurable that
will allow those requests to be forwarded rather than rejected?

-- David P. Caldwell
http://www.davidpcaldwell.com/

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Can Tomcat act as an HTTPS proxy?

Posted by "David P. Caldwell" <da...@code.davidpcaldwell.com>.
On Thu, Jan 19, 2017 at 7:15 PM, Daniel Savard <da...@gmail.com> wrote:
> 2017-01-19 12:21 GMT-05:00 David P. Caldwell <da...@code.davidpcaldwell.com>
> :
>
>> Chris,
>>
>> Good questions, I'll try to clarify.
>>
>> 1. The backend server serves files via HTTPS. (I control this, and may
>> switch it to HTTP; see below.)
>>
>> 2. The proxy server has an HTTPS connector like this (but under my
>> initial solution I wasn't thinking I should use it).
>> (...)
>>
>> -- David.
>>
>
>
> You just need a web application doing this job. There are many, here is a
> link to a short list: https://wiki.apache.org/tomcat/ServletProxy

Yeah, I realized after I described what I was doing that it's somewhat
misleading. Part of the mock is implemented in the middle server; it's
not just a passthrough. It really implements most of the behavior,
delegating a portion of it to the back end.

Possibly if I adopted url-pattern rules that were complex enough I
could separate that part out.

Thanks for the suggestion.

-- David.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Can Tomcat act as an HTTPS proxy?

Posted by Daniel Savard <da...@gmail.com>.
2017-01-19 12:21 GMT-05:00 David P. Caldwell <da...@code.davidpcaldwell.com>
:

> Chris,
>
> Good questions, I'll try to clarify.
>
> 1. The backend server serves files via HTTPS. (I control this, and may
> switch it to HTTP; see below.)
>
> 2. The proxy server has an HTTPS connector like this (but under my
> initial solution I wasn't thinking I should use it).
> (...)
>
> -- David.
>


You just need a web application doing this job. There are many, here is a
link to a short list: https://wiki.apache.org/tomcat/ServletProxy

We have Noodle embedded into another product in production at my shop and
it is working fine so far.

Regards,
-----------------
Daniel Savard

Re: Can Tomcat act as an HTTPS proxy?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

David,

On 1/19/17 12:21 PM, David P. Caldwell wrote:
> 1. The backend server serves files via HTTPS. (I control this, and
> may switch it to HTTP; see below.)

Ok.

> 2. The proxy server has an HTTPS connector like this (but under my 
> initial solution I wasn't thinking I should use it).
> 
> I can connect to this HTTPS connector with my client (as long as I 
> disable the various SSL security checks, given that this is a 
> self-signed certficate).

Let's Encrypt?

> 3. The proxy server also has an HTTP connector, the one that is
> the default when using the embedded API. It changes the port number
> on it to an open ephemeral port, changes the base directory to a
> temporary directory, adds a context and configures servlets and so
> forth (it's part of a framework, so it's generalized; in the case
> I'm working on, it's adding a single servlet that basically
> forwards requests to the backend).
> 
> 4. The purpose of all this rigamarole is mocking.

Oh. That can make a lot of my questions go away. One more before I
spend any real time droning on and on:

Is this only for unit testing, and so security, trust, etc. are all
moot points?

> I'd like to get rid of some or all of that parameterization, to 
> simplify my production code, so I decided to see whether I could 
> build an HTTPS mock of the environment.

This sounds like an excellent idea. Simpler production code is
*always* better.

> The purpose of the middle proxy server is essentially to remove
> the need to also parameterize server names and stuff. (The client
> code requests real production URLs, but because they are proxied
> through the middle tier, the middle tier can forward the requests
> to the mock server.)
> 
> So I think what I want to do is have that middle tier's HTTP
> connector pass HTTPS requests from the client through to the
> backend HTTPS server.

This is what is confusing to me. You have only two choices for
connectors: HTTP or HTTPS. You can't have the HTTPS connector use the
HTTP connector. At least not on the same server.

You either want this:

client --- HTTP --> proxy --- HTTP --> origin

or this

client --- HTTP --> proxy --- HTTPS --> origin

or this

client --- HTTPS --> proxy --- HTTP --> origin

or this

client --- HTTPS --> proxy --- HTTPS --> origin

Pick which one you want to use. Then, on the proxy, only enable the
protocol that the client needs as a Connector. For the outgoing
connection (to the origin server), there is no Connector. There is
only the proxy-as-client, which will connect to whatever protocol is
being used on the origin server.

But... if you are just trying to "mock" the backend server... doesn't
that mean that there *is no backend server* when the mocking takes place
?

> For what it's worth, with some additional research, it looks like 
> what's happening is that the various mechanisms I am attempting to
> use to "proxy" (tunnel) these requests are using a CONNECT request
> to Tomcat, which is returning a 400. I think. I haven't been able
> to catch it in the act.

Tomcat doesn't yet support the CONNECT protocol. There is a patch in a
BZ issue somewhere that I haven't yet tested (this is something I'm
actually interested in making work in Tomcat). So if your client is
intending to use HTTP CONNECT then you are out of luck.

If you want to use Tomcat as a reverse-proxy, then I believe there is
a servlet for that, but I've never used it.

> However, for my situation, explaining it to you suggests a
> different solution -- since I have my Tomcat "middle" server with
> an HTTPS connector, and that is working, I am also going to
> experiment with using HTTPS to communicate with the middle, and
> then switch the back end to HTTP. I'm not sure that'll help
> (because I'm not sure how I can implement the "direct all HTTPS
> requests to this host/port" without the Java client attempting to
> establish a tunnel) but I'll explore it.

Only you can decide what make the most sense to you, but my experience
with connecting to arbitrary backend services is that connection
information isn't that tough to "parameterize"... a URL plus an
SSLSocketFactory can get the job done in most cases.

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBCAAGBQJYgn/qAAoJEBzwKT+lPKRYx60P/ikPqpzWx2zHui7UKt+VOS/8
eeape8b+Jngamkp7f4/3avaia3AI48Vbrk2Y5EVGzgVzz6YDgSh/Q4eI+h9FwWGr
ZpqWcN8s/WOyJWCrfxQyKkZMbZaDPmC5a5XvUbgJ6GA2v2vcJ0iGhYqEoaTf3oKw
CvdWbuT8NHltccFymJCvRXLXCZTBSwBFXQFPC2PyGXzPuxhUzwapDqjWYoORGN/N
X50lRTp5byzchLkk1wWJPNX+t8zNXWi9Xt+uK20yTJgpv+yJ54+x4xqzZvpVtta1
kEV7GsPnv3PYxFmMvA9y3B1SQ0aJopY24eiURVOlSaZwJ+at6wyBS9CwzPAadHte
RTkdo2OJUO3wvw2UpGnikp+2ksiGAWGY+8VBTOWWmBB4yRUsMkvDM+5GTggXhcCf
N1qD4l1ZqkAuqkUM2gmYQgPyVubvkVR0L6ovtQ1eXsPJ5C5DOnVyMK196Qp/EP7Y
VTUYw4jZKGExojUg5Wsxh2lx2njUr5qIMwaNdfFTjfgL+UvwkiWUJrn6oOo/uC+H
TjPAfDxGBXlNXG2ijHi4uM2qpzQQTyJ8lo2AClbfE2J+3Gh+Vxr0ujfezniP6RHW
4qpK+p29kbjRgN4zNFZGEDnqyzeDj9aiaE6VmuuqaHJM77hh5/ybO3n/sG7Fy7Gx
HV+abq9HzY209oidPc0r
=3YBI
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Can Tomcat act as an HTTPS proxy?

Posted by "David P. Caldwell" <da...@code.davidpcaldwell.com>.
Chris,

Good questions, I'll try to clarify.

1. The backend server serves files via HTTPS. (I control this, and may
switch it to HTTP; see below.)

2. The proxy server has an HTTPS connector like this (but under my
initial solution I wasn't thinking I should use it).

var _https = new Packages.org.apache.catalina.connector.Connector();
var hport = (p.https.port) ? p.https.port : getOpenPort();
_https.setPort(hport);
_https.setSecure(true);
_https.setScheme("https");
_https.setAttribute("keyAlias", "tomcat");
_https.setAttribute("keystorePass", "inonit");
_https.setAttribute("keystoreFile", file.toString());
_https.setAttribute("clientAuth", "false");
_https.setAttribute("sslProtocol", "TLS");
_https.setAttribute("SSLEnabled", "true");
tomcat.getService().addConnector(_https);

I can connect to this HTTPS connector with my client (as long as I
disable the various SSL security checks, given that this is a
self-signed certficate).

3. The proxy server also has an HTTP connector, the one that is the
default when using the embedded API. It changes the port number on it
to an open ephemeral port, changes the base directory to a temporary
directory, adds a context and configures servlets and so forth (it's
part of a framework, so it's generalized; in the case I'm working on,
it's adding a single servlet that basically forwards requests to the
backend).

4. The purpose of all this rigamarole is mocking. The production
third-party environment uses HTTPS, and I do not control it. I've
built a fine HTTP mock of the production environment. But as you can
imagine, when developing my production code (clients that use the
production server), a bunch of parameterization creeps in. Basically
"protocol" gets passed all over the place, lots of configuration files
get pre-processed, and so forth, so that the code works in the mocked
HTTP-only environment as well as in real life. I'd like to get rid of
some or all of that parameterization, to simplify my production code,
so I decided to see whether I could build an HTTPS mock of the
environment. The purpose of the middle proxy server is essentially to
remove the need to also parameterize server names and stuff. (The
client code requests real production URLs, but because they are
proxied through the middle tier, the middle tier can forward the
requests to the mock server.)

So I think what I want to do is have that middle tier's HTTP connector
pass HTTPS requests from the client through to the backend HTTPS
server.

For what it's worth, with some additional research, it looks like
what's happening is that the various mechanisms I am attempting to use
to "proxy" (tunnel) these requests are using a CONNECT request to
Tomcat, which is returning a 400. I think. I haven't been able to
catch it in the act.

However, for my situation, explaining it to you suggests a different
solution -- since I have my Tomcat "middle" server with an HTTPS
connector, and that is working, I am also going to experiment with
using HTTPS to communicate with the middle, and then switch the back
end to HTTP. I'm not sure that'll help (because I'm not sure how I can
implement the "direct all HTTPS requests to this host/port" without
the Java client attempting to establish a tunnel) but I'll explore it.

-- David.



On Thu, Jan 19, 2017 at 11:42 AM, Christopher Schultz
<ch...@christopherschultz.net> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> David,
>
> On 1/19/17 10:38 AM, David P. Caldwell wrote:
>> I'm trying to forward HTTPS requests through a Tomcat HTTP (or
>> HTTPS) server to a backend HTTPS server.
>>
>> The requests are initiated by a Java HTTP client
>> (java.net.URLConnection-based).
>>
>> So I have:
>>
>> backend HTTPS server (which works) Tomcat server running HTTP and
>> HTTPS connectors Java HTTPUrlConnection, using Tomcat HTTP
>> connector as a proxy
>>
>> The Java client can successfully:
>>
>> * use the backend HTTPS server directly * use the Tomcat HTTP
>> connector * use the Tomcat HTTPS connector
>>
>> For my scenario, I think using the HTTP connector to proxy is
>> correct, though I've also tried using the HTTPS connector.
>>
>> I'm not an expert on SSL or HTTPS. The HTTPS connector doesn't
>> work, but my understanding is that using it doesn't make sense; the
>> trust relationship is end-to-end, so you'd use ordinary HTTP to
>> proxy in between. It ends up with an unexpected EOF from server or
>> something.
>>
>> Assuming the HTTP connector is the right one to use, here's my
>> problem: Tomcat returns a 400 Bad Request when I attempt to request
>> an https: URL via an ordinary HTTP request to the HTTP connector.
>>
>> Conceptually, it seems like this ought to be fine, to me, but as I
>> said, my understanding of the concepts is a bit murky, so I might
>> be wrong.
>>
>> Am I on the right track? If so, is there something configurable
>> that will allow those requests to be forwarded rather than
>> rejected?
>
> So you've got this?
>
> client -- HTTP --> Tomcat proxy -- HTTPS --> backend server
>
> ?
>
> Or this?
>
> client -- HTTPS --> Tomcat proxy -- HTTP --> backend server
>
> ?
>
> Please post as much of your configuration (<Connector>, proxy) as you ca
> n.
>
> Also, what is the purpose of the HTTPS wherever it is being used? It
> is for privacy or for authentication (or both)?
>
> - -chris
> -----BEGIN PGP SIGNATURE-----
> Comment: GPGTools - http://gpgtools.org
> Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
>
> iQIcBAEBCAAGBQJYgOyLAAoJEBzwKT+lPKRYcJ0P/jxtmltsNpilxkYnbTFopTFl
> 87GqViuIQOXdi/2EzP9jJhdieBv7XwIAI81hJ4qWCdUhANtxNoPeaytZPR2+E6hT
> 4zUC0x4ez4E9S2lUkhk7XcSr/0+hAM0rLd1TChJi0+tweZjWyaeCAbbdLHhjPb+e
> SRAs4Tz2qs0Y7i3qu3nV6VWt5u2eBEspogFHT8FXjXLYx/VPQOR9/60mnEDsaEek
> gC4Xqh5vMABd7Tcyslp0kfKrFEKjAgoej2cQ+p96faITV7X9ji0z35uvSwNErfD0
> iIruVVUfe8MSBRR8jwpLor6ORAL3dZ0FmKegxjAOJ897eIv3hO6rS2JqmT3Ju1Ez
> dczMIIJA7c92xk4UINlMrTRit8MXJoOuJSR778pRS/j8WirNGw1y66U2U8Z3KZeM
> 4tDKpIwwXx2HX0Mrag/m3UB5Y59UNX/5TVJQr+2GhcvIHOXK1cWUmFOdZtbwD5Xc
> a7HpZDuMNSrxZjzrfWg18EMl2IfGLWllW6Qs73e+VO3cC8tlbQzjO0RQowl2e867
> twZO8zXvGVrxtJcezaq1dRzPQDVRIVbedBAxNuN20JkdaWMcxGkBjsIiw99Vp4V7
> XgX+5+6ZeLAFHhVyoAVFumL4Rr585PzloiZLQcOUGosqqreVh4L2Yp5YRfgOojOU
> EPPtfY44QI4Jq3SwTLCr
> =938w
> -----END PGP SIGNATURE-----
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Can Tomcat act as an HTTPS proxy?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

David,

On 1/19/17 10:38 AM, David P. Caldwell wrote:
> I'm trying to forward HTTPS requests through a Tomcat HTTP (or
> HTTPS) server to a backend HTTPS server.
> 
> The requests are initiated by a Java HTTP client
> (java.net.URLConnection-based).
> 
> So I have:
> 
> backend HTTPS server (which works) Tomcat server running HTTP and
> HTTPS connectors Java HTTPUrlConnection, using Tomcat HTTP
> connector as a proxy
> 
> The Java client can successfully:
> 
> * use the backend HTTPS server directly * use the Tomcat HTTP
> connector * use the Tomcat HTTPS connector
> 
> For my scenario, I think using the HTTP connector to proxy is
> correct, though I've also tried using the HTTPS connector.
> 
> I'm not an expert on SSL or HTTPS. The HTTPS connector doesn't
> work, but my understanding is that using it doesn't make sense; the
> trust relationship is end-to-end, so you'd use ordinary HTTP to
> proxy in between. It ends up with an unexpected EOF from server or
> something.
> 
> Assuming the HTTP connector is the right one to use, here's my 
> problem: Tomcat returns a 400 Bad Request when I attempt to request
> an https: URL via an ordinary HTTP request to the HTTP connector.
> 
> Conceptually, it seems like this ought to be fine, to me, but as I 
> said, my understanding of the concepts is a bit murky, so I might
> be wrong.
> 
> Am I on the right track? If so, is there something configurable
> that will allow those requests to be forwarded rather than
> rejected?

So you've got this?

client -- HTTP --> Tomcat proxy -- HTTPS --> backend server

?

Or this?

client -- HTTPS --> Tomcat proxy -- HTTP --> backend server

?

Please post as much of your configuration (<Connector>, proxy) as you ca
n.

Also, what is the purpose of the HTTPS wherever it is being used? It
is for privacy or for authentication (or both)?

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBCAAGBQJYgOyLAAoJEBzwKT+lPKRYcJ0P/jxtmltsNpilxkYnbTFopTFl
87GqViuIQOXdi/2EzP9jJhdieBv7XwIAI81hJ4qWCdUhANtxNoPeaytZPR2+E6hT
4zUC0x4ez4E9S2lUkhk7XcSr/0+hAM0rLd1TChJi0+tweZjWyaeCAbbdLHhjPb+e
SRAs4Tz2qs0Y7i3qu3nV6VWt5u2eBEspogFHT8FXjXLYx/VPQOR9/60mnEDsaEek
gC4Xqh5vMABd7Tcyslp0kfKrFEKjAgoej2cQ+p96faITV7X9ji0z35uvSwNErfD0
iIruVVUfe8MSBRR8jwpLor6ORAL3dZ0FmKegxjAOJ897eIv3hO6rS2JqmT3Ju1Ez
dczMIIJA7c92xk4UINlMrTRit8MXJoOuJSR778pRS/j8WirNGw1y66U2U8Z3KZeM
4tDKpIwwXx2HX0Mrag/m3UB5Y59UNX/5TVJQr+2GhcvIHOXK1cWUmFOdZtbwD5Xc
a7HpZDuMNSrxZjzrfWg18EMl2IfGLWllW6Qs73e+VO3cC8tlbQzjO0RQowl2e867
twZO8zXvGVrxtJcezaq1dRzPQDVRIVbedBAxNuN20JkdaWMcxGkBjsIiw99Vp4V7
XgX+5+6ZeLAFHhVyoAVFumL4Rr585PzloiZLQcOUGosqqreVh4L2Yp5YRfgOojOU
EPPtfY44QI4Jq3SwTLCr
=938w
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Can Tomcat act as an HTTPS proxy?

Posted by "David P. Caldwell" <da...@code.davidpcaldwell.com>.
One clarification: when I wrote:

"is there something configurable that
will allow those requests to be forwarded rather than rejected?"

... what I really meant was, is there a way for the request to reach
my servlet (which handles all requests), basically. I already have a
server-side implementation that can make the request of the backend
server and return the response to the front end.

On Thu, Jan 19, 2017 at 10:38 AM, David P. Caldwell
<da...@code.davidpcaldwell.com> wrote:
> I'm trying to forward HTTPS requests through a Tomcat HTTP (or HTTPS)
> server to a backend HTTPS server.
>
> The requests are initiated by a Java HTTP client (java.net.URLConnection-based).
>
> So I have:
>
> backend HTTPS server (which works)
> Tomcat server running HTTP and HTTPS connectors
> Java HTTPUrlConnection, using Tomcat HTTP connector as a proxy
>
> The Java client can successfully:
>
> * use the backend HTTPS server directly
> * use the Tomcat HTTP connector
> * use the Tomcat HTTPS connector
>
> For my scenario, I think using the HTTP connector to proxy is correct,
> though I've also tried using the HTTPS connector.
>
> I'm not an expert on SSL or HTTPS. The HTTPS connector doesn't work,
> but my understanding is that using it doesn't make sense; the trust
> relationship is end-to-end, so you'd use ordinary HTTP to proxy in
> between. It ends up with an unexpected EOF from server or something.
>
> Assuming the HTTP connector is the right one to use, here's my
> problem: Tomcat returns a 400 Bad Request when I attempt to request an
> https: URL via an ordinary HTTP request to the HTTP connector.
>
> Conceptually, it seems like this ought to be fine, to me, but as I
> said, my understanding of the concepts is a bit murky, so I might be
> wrong.
>
> Am I on the right track? If so, is there something configurable that
> will allow those requests to be forwarded rather than rejected?
>
> -- David P. Caldwell
> http://www.davidpcaldwell.com/

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org