Discussion:
Reverse proxy support in Tomcat
Jan Hlavatý
2017-07-18 12:09:43 UTC
Permalink
Hello,

I can't seem to figure out the proper setup for the situation where I
have multiple webhosts behind a reverse proxy server being forwarded to
Tomcat.

There can be only one proxyHost and proxyPort on a Connector but I have
multiple Hosts and Aliases.

How am I supposed to do that? Make multiple Connectors one per hostname,
on different local ports, sharing on Executor to avoid multiplying
threads, and have the proxy forward to different ports based on hostname?

Jan



---------------------------------------------------------------------
To unsubscribe, e-mail: users-***@tomcat.apache.org
For additional commands, e-mail: users-***@tomcat.apache.org
André Warnier (tomcat)
2017-07-18 12:29:29 UTC
Permalink
Hi.
Post by Jan Hlavatý
Hello,
I can't seem to figure out the proper setup for the situation where I
have multiple webhosts behind a reverse proxy server being forwarded to
Tomcat.
There can be only one proxyHost and proxyPort on a Connector but I have
multiple Hosts and Aliases.
How am I supposed to do that? Make multiple Connectors one per hostname,
on different local ports, sharing on Executor to avoid multiplying
threads, and have the proxy forward to different ports based on hostname?
No to all that. All you need is multiple <Host> entries in the tomcat server.xml config.
A single <Connector> (and port) will do for all. <Executor> is optional, and indeed
relates to optimising the usage of threads.

Other than that, I don't really know at what level to begin explaining why.
Let's try this :

In HTTP 1.1 and above, when a browser sends a request to a server, it adds a header line
to each request :
Host: some.server.com

The receiving HTTP server reads this header, and that is what tells it to which of it's
"hosts" this request is adressed.

If you have a front-end reverse proxy, and say 10 virtual hosts, then each of these
virtual host names is configured in the DNS to resolve to the IP address of your proxy.
So the front-end proxy receives all requests directed to any of these hosts.
It then belongs to the proxy, to forward all these requests to the single back-end Tomcat
server, and include the original "Host:" header in the requests that it proxies so.

The single Tomcat Connector will receive all these requests, and will dispatch them to
each individual <Host> in function of that same "Host:" header.

Clear ?



---------------------------------------------------------------------
To unsubscribe, e-mail: users-***@tomcat.apache.org
For additional commands, e-mail: users-***@tomcat.apache.org
Mark Thomas
2017-07-18 13:29:39 UTC
Permalink
Post by André Warnier (tomcat)
Hi.
Post by Jan Hlavatý
Hello,
I can't seem to figure out the proper setup for the situation where I
have multiple webhosts behind a reverse proxy server being forwarded to
Tomcat.
There can be only one proxyHost and proxyPort on a Connector but I have
multiple Hosts and Aliases.
How am I supposed to do that? Make multiple Connectors one per hostname,
on different local ports, sharing on Executor to avoid multiplying
threads, and have the proxy forward to different ports based on hostname?
No to all that. All you need is multiple <Host> entries in the tomcat server.xml config.
A single <Connector> (and port) will do for all. <Executor> is optional,
and indeed relates to optimising the usage of threads.
Other than that, I don't really know at what level to begin explaining why.
In HTTP 1.1 and above, when a browser sends a request to a server, it
Host: some.server.com
The receiving HTTP server reads this header, and that is what tells it
to which of it's "hosts" this request is adressed.
If you have a front-end reverse proxy, and say 10 virtual hosts, then
each of these virtual host names is configured in the DNS to resolve to
the IP address of your proxy.
So the front-end proxy receives all requests directed to any of these hosts.
It then belongs to the proxy, to forward all these requests to the
single back-end Tomcat server, and include the original "Host:" header
in the requests that it proxies so.
Note: Passing on the host header can require explicit configuration. In
the proxy. e.g. for httpd:

ProxyPreserveHost On
Post by André Warnier (tomcat)
The single Tomcat Connector will receive all these requests, and will
dispatch them to each individual <Host> in function of that same "Host:"
header.
Clear ?
One tip. Don't try and change the context path in the reverse proxy. It
creates all sorts of potential for things to go wrong. In httpd config
syntax:

ProxyPass /foo http://localhost:8080/foo

is good

ProxyPass /foo http://localhost:8080/bar

is likely to be a lot of work to get working correctly. In the past I
have spent days on-site with one customer getting one application to
work in this configuration because they didn't want to change the
back-end context path.

And finally, if the reverse proxy handles HTTP and HTTPS
and you are proxying to Tomcat over HTTP, use a separate Tomcat
connector for each of the HTTP and HTTPS traffic - it makes correct,
secure configuration a lot simpler.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-***@tomcat.apache.org
For additional commands, e-mail: users-***@tomcat.apache.org
Igal @ Lucee.org
2017-07-18 16:44:01 UTC
Permalink
Post by Mark Thomas
Note: Passing on the host header can require explicit configuration. In
ProxyPreserveHost On
The best tool that I found to set up reverse proxy is Tomcat's
RemoteIpFilter --
https://tomcat.apache.org/tomcat-8.5-doc/api/org/apache/catalina/filters/RemoteIpFilter.html
which I configure like so in the web descriptor:

|<filter> <filter-name>RemoteIpFilter</filter-name>
<filter-class>org.apache.catalina.filters.RemoteIpFilter</filter-class>
<init-param> <param-name>internalProxies</param-name>
<param-value>127\.0\.0\.1</param-value> </init-param> <init-param>
<param-name>remoteIpHeader</param-name>
<param-value>x-forwarded-for</param-value> </init-param> <init-param>
<param-name>remoteIpProxiesHeader</param-name>
<param-value>x-forwarded-by</param-value> </init-param> <init-param>
<param-name>protocolHeader</param-name>
<param-value>x-forwarded-proto</param-value> </init-param> </filter>
<filter-mapping> <filter-name>RemoteIpFilter</filter-name>
<url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher>
</filter-mapping>|


Then in the web server I pass the following headers from the web server
to Tomcat (example shows nginx as web server, but they all work the
same, the only difference is the variable names in the web server):


|proxy_set_header Host $host; ## CGI.HTTP_HOST|


See https://gist.github.com/isapir/8a70ed85b3a7a6e92908191f938d7a1a for
more.


Igal Sapir

Lucee Core Developer
Lucee.org <http://lucee.org/>

Christopher Schultz
2017-07-18 13:32:49 UTC
Permalink
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

André,
Post by André Warnier (tomcat)
Hi.
Post by Jan Hlavatý
Hello,
I can't seem to figure out the proper setup for the situation
where I have multiple webhosts behind a reverse proxy server
being forwarded to Tomcat.
There can be only one proxyHost and proxyPort on a Connector but
I have multiple Hosts and Aliases.
How am I supposed to do that? Make multiple Connectors one per
hostname, on different local ports, sharing on Executor to avoid
multiplying threads, and have the proxy forward to different
ports based on hostname?
No to all that. All you need is multiple <Host> entries in the
tomcat server.xml config. A single <Connector> (and port) will do
for all. <Executor> is optional, and indeed relates to optimising
the usage of threads.
Other than that, I don't really know at what level to begin
In HTTP 1.1 and above, when a browser sends a request to a server,
it adds a header line to each request : Host: some.server.com
The receiving HTTP server reads this header, and that is what tells
it to which of it's "hosts" this request is adressed.
If you have a front-end reverse proxy, and say 10 virtual hosts,
then each of these virtual host names is configured in the DNS to
resolve to the IP address of your proxy. So the front-end proxy
receives all requests directed to any of these hosts. It then
belongs to the proxy, to forward all these requests to the single
back-end Tomcat server, and include the original "Host:" header in
the requests that it proxies so.
The single Tomcat Connector will receive all these requests, and
will dispatch them to each individual <Host> in function of that
same "Host:" header.
+1

See point 5 in: https://tomcat.apache.org/tomcat-8.0-doc/proxy-howto.htm
l

Also see the list of bullet points under
https://tomcat.apache.org/connectors-doc/common_howto/proxy.html,
specifically this one:

"
* local name: getLocalName(). This is also equal to getServerName(),
unless a Host header is contained in the request. In this case the
server name is taken from that header.
"

So, basically, if you simply don't configure any proxyHost or
proxyPort at all, I think you'll get the behavior you desire.

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

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAlluDf4ACgkQHPApP6U8
pFiboQ/+Po/u6b4OwC0Nsel1sbN3TA8cIyrASDy4NmYjlNLw3DSTBMo38VVK1Rqm
+L4sLFBBdJ/01eH6ahEHmJGE9Cifg72i/ldsqFfrLD9kglSOa8Y4iJtRkMyq8qgr
ElkzLY+phBDNVk45ePQ0dSEW97i/HJI3/DSaRGLxmiI2a7FDSQEM7Y1E5ZEvQ1nQ
q+A0zrr0+yxJmKEjx1u0q1ehiAqcK1P3QpcSsBOGEIliDoalCdSMIZgYnl0ok9sR
LeKnc5+2Xz3QWwpRRPhUFb+2AXLe7MBG2YKwJxCJraRn+ets12MV5NrpNg0NHUOz
knlJL6auc2m1vaU1fOjN5tzS4O9pBmT/eM7f35gNz9A9ggmOcwOnyd9hZ7NZh20h
7vEkvBKMA0C+8aO2w4cICm+25b2Oy6ut5mGHCZz68MY2s8dfEGo614nFIdlQtklu
QmhlTCj4cw8kNdGZ9ayfvSOaLD3O/lz6azpLWGHP0qGUvtTB4TqMI3CqNtuDxwWO
vzU8jXKaTFxnCMphgpMxwLOxUlbEjOEfWJeIARasNKJswgHEHFEe9XGNyfMXP6zC
7RTACy5nvX6FWm0U0RtzXrF0zKbqTaeRtNoI+wmkhrsDbEuVqMPUoG/UhBP1NEmZ
QkHCEoJaAxmFU/qC5FIyU88sM8Y8rhiRqkhT6E8oNriv8VtT+Xw=
=vjQ7
-----END PGP SIGNATURE-----

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