-----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-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org