tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christopher Schultz <ch...@christopherschultz.net>
Subject Re: [OT] Forward TLS connection information from AWS ELB -> httpd -> Tomcat
Date Thu, 02 Oct 2014 20:06:16 GMT
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

All,

On 10/1/14 10:26 AM, Christopher Schultz wrote:
> I'm interested in using AWS ELB for SSL termination but allowing
> the client's TLS connection information to be forwarded all the
> way through the chain to Tomcat.
> 
> The setup looks like this:
> 
> ELB /\ /  \ /    \ w0    w1 /  \   / \ t0  t1 t0  t1
> 
> (t0 and t1 are repeated because otherwise the diagram would be
> even more difficult to read).
> 
> w0 and w1 are running Apache httpd, t0 and t1 are running Tomcat.
> The client's connection is TLS terminated at ELB and whether the 
> connections between ELB/wx/tx are encrypted should be immaterial.
> I'm using mod_jk from httpd -> Tomcat.
> 
> ELB provides the following HTTP headers to wx: X-Forwarded-For
> (client's IP) X-Forwarded-Port 	443 X-Forwarded-Proto 	https
> 
> Unfortunately, it looks like I can't get things like the cipher 
> default, etc. but I'm okay with that for the time being.
> 
> I'm wondering two things:
> 
> 1. How can I get Apache httpd to trust that the connection is
> encrypted? I want to be able to use "RequireSSL" for certain
> resources and have httpd trust that the connection coming from the
> ELB is in fact secure.
> 
> 2. How can I use that connection information to tell mod_jk that
> things are to be trusted as well?
> 
> For #2, I might just be able to use SetEnv to set 
> REMOTE_ADDR=X-Forwarded-For, but I'm not sure how to say "yes, this
> is encrypted". Should I set up a separate VirtualHost on a
> different (non-80) port that is configured only for ELB connections
> and then force SSL to "on" regardless of the actual incoming
> connections?
> 
> That would allow me to use port 80 for "regular" web traffic and
> not have to worry about proper checking to make sure that the
> connection was in fact coming from the ELB and not directly into
> the web server.

I have some information for those wanting to do this.

Here is a write-up someone did for how to get Apache to log things
appropriately when using AWS ELB:
http://knowledgevoid.com/blog/2012/01/13/logging-the-correct-ip-address-using-apache-2-2-x-and-amazons-elastic-load-balancer/

Here are the two configurations I was able to get working and a few
notes about them.

I would highly recommend that anyone using ELB set up an ELB-only
VirtualHost that only handles requests being proxied through the ELB.
This will protect you against some misconfigurations, etc. that might
allow remote users to get access to resources they should not, or be
able to forge certain parts of the request.

Something like this:

<VirtualHost *:81>
  (remaining configuration)
</VirtualHost>

Remember that you will have to "Listen 81" somewhere.

If you have httpd 2.4, then you have mod_remoteip out of the box.
That's nice:

    # Trust AWS ELB's X-Forwarded-For header
    # This will set REMOTE_ADDR to the client's real IP
    RemoteIPHeader X-Forwarded-For
    RemoteIPInternalProxy 10.0.0.0/8

    # Handle ELB requests; maintain client information
    SetEnvIf X-Forwarded-Proto "https" HTTPS=On
    SetEnvIf X-Forwarded-Port "(.*)" JK_LOCAL_PORT=$1

That last SetEnvIf is nearly entirely useless (because nobody really
cares about users' port numbers), but I put it in there for completeness.

Also, mod_remoteip will adjust the value of the REMOTE_ADDR
environment variable -- which is visible to CGI-style programs as well
as mod_jk/Tomcat/etc. but *it will not work in log files* if you use
"%h" as your remote-ip log format. You will have to use "%a" instead.
On AWS Linux, the httpd package comes with both "combined" and
"common" log formats defined using "%h" so you'll have to change those
to "%a".

If you have httpd 2.2. instead, you'll have to do things a bit
differently (unless you want to use the back-port of mod_remoteip for
httpd 2.2):

    # Handle ELB requests; maintain client information
    SetEnvIf X-Forwarded-Proto "https" HTTPS=On
    SetEnvIf X-Forwarded-For "(.*)" REMOTE_ADDR=$1 JK_REMOTE_ADDR=$1
    SetEnvIf X-Forwarded-Port "(.*)" JK_LOCAL_PORT=$1
    <Location "/">
      Order deny,allow
      Deny from all
      Allow from 10.0.0.0/8
    </Location>

If you want to log properly, I think the best thing to do is change
"%h" (or "%a") in your log formats to "%{X-Forwarded-For}i" or, if you
want to be super-correct, you want to do something like this:

    # The following line has been split over multiple lines.
    # httpd doesn't support this; it's for email readability only
    SetEnvIf X-Forwarded-For \
        "^.*?(\d{1,3}+\.\d{1,3}+\.\d{1,3}+\.\d{1,3}+)" \
        XFFCLIENTIP=$1
    LogFormat "... %{XFFCLIENTIP}e ..." format-name
    CustomLog access_log format-name

This won't get you the right client IP address in error.log, though.
I'm not exactly sure how to do that. Apparently, setting REMOTE_ADDR
is only useful for CGI-style interaction and has no effect on how
httpd does logging, etc.

It also seems that you cannot re-define a LogFormat. I tried
re-defining my "combined" log format in a VirtualHost and it did not
work. Using a different LogFormat nickname gave me better results.

Hope that helps,
- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: GPGTools - http://gpgtools.org

iQIcBAEBCAAGBQJULbA4AAoJEBzwKT+lPKRYjBsP/AqnX+rrn3JwJaHdPdnkRaHi
jMfoFLwwVa2zomXWkWTWyYwPz74ZGjGF7Vl06W8qIZXQOok6pSmORHa1LYxM5cy9
WMcaxeXX+83nLt9zugDzBJ6ti5MW0Q8DGaHwh7t0RpGIbE6edLzfEpKkQwT7w2lc
z4f4cyKjIOck6Ami0zKKpbTnmyQ0P2ejY8PfjhVoj6UCqR/7vWPHZB4NgZgaDJTc
MToGCQCbKgPQggr8qbgto9L0UQGfsY+jPyAl+49GE6AtPTIE70ChPe8BxM/Y+UpP
3ANk43CYkJtZaD8qVIpEreZzhUi3ujrmz6ty3n3BKY6R5WHP9A6loThdu61BFT6M
djnRaiPYGDt+r6Y0nXe30/q7rEm+zEMU/Uyn4Vhen0vE6d/F9Uqux8Euv6P0dKRz
symwOReQo1nJ7suBVNmJVkxtXucqHdO2yL88XEzNJpgjwQsm8/RPT0aFo4X/Eog2
uJXGum8SPEIztlpXPm0EsvLBVls0wQEY2Cf+c0GoN3Y69WbBuaVSRS3xmbxa268N
L2WVyhCv3OBIqWCaKejArBExQ7Ew5gnQ5/Rf2tVs4S0zjXU7zg4vLE00D2B1ooVd
z8iOrSeUznI6EIU8wyoZzlEau1BXMZ2ApWaBh3HfmCW0UuwMF7gCXCVs64GZ0C5E
eDtTMU+PaDQMyinzEbIH
=TReq
-----END PGP SIGNATURE-----

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


Mime
View raw message