You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Christopher Schultz <ch...@christopherschultz.net> on 2014/10/01 16:26:50 UTC

[OT] Forward TLS connection information from AWS ELB -> httpd -> Tomcat

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

All,

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.

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

iQIcBAEBCAAGBQJULA8qAAoJEBzwKT+lPKRYMf4P/2yONDv5rQFgHguhMeWv8BJs
jbv8bLOOK5Vf+r5idJgyEgOFEI4jbEKfGdhIvD5BasT4PZF65sn3AsOXQpav9GA4
kgomQHDipou3u5PFGi2d3xQQsDB9MjOTfAmmvQFNEnPxtisYQA+wNHGGxJDwyHIZ
tJkS4jP8mA3vxLaoCLoSiOi2MEGr2nbj5Xcfd75F2IXfci9QEhGEgsUxyFq+K+Vb
p+GVv4px55+zO9sLaIk6SiaNOGI3p86W+IX5spvoxO2Qxah+DVSoq9HRGryWd/Wn
O3ZwSGqCHYKsPI1xHECaN/58pAR7polyU5nEFmzWbxFhc31Q2hpDkZuyZ3SIY2u1
7lLY+Zx41nizjfjeYeIcMtZ4OBj0uHBSj5qzLehF7zItZoRqEhgv2b4yn8vJjIj0
GF4wpVqAqSWaIJ2F1C9ZjTnL9LhTJHZBurpt1JDSe7ALS/s4EoEQ/rbaz9kEUMNq
BBThIapN+VXCwaqsA7hQliCWRoGuP2kNFStsatgeaNaBZd5Cf8cg8iTSUcoDR4UW
Z4CHSi/4H6uD3wmcI6Jca7dfJEY+eNGM3zLsUF1hQPYP9MG6Fohy6h/UGGhlRehh
sXZ6bL0oVfGVxSM9gMCDQzB4ptb9zuqU5UgWjKEB50lbwXgMLUm7XP3/C/bY7Zgt
cXABRHoZSqoq2tPV1Lov
=g2oZ
-----END PGP SIGNATURE-----

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


Re: [OT] Forward TLS connection information from AWS ELB -> httpd -> Tomcat

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

Stefan,

On 10/1/14 5:33 PM, Stefan Mayr wrote:
> Hi Christopher,
> 
> Am 01.10.2014 20:40, schrieb Christopher Schultz:
>> -----BEGIN PGP SIGNED MESSAGE-----
> ...
>> 
>> I've been trying to get mod_remoteip to handle the client's IP
>> address for me -- especially for logging -- but I'm having some
>> difficulty and have asked a question over on the httpd users'
>> list about that.
> ...
> 
> mod_remoteip can do more for you (if you need it). Just for the
> purpose of logging the X-Forwarded-For-Header you could define a
> custom LogFormat and add request headers like
> \"%{X-Forwarded-For}i\" to it.

Yes, but I don't need mod_remoteip if all I want to do is log the
client's IP. What I was hoping to to us to use mode_remoteip to just
substitute the client's IP for everything. That doesn't seem to be
working for me at all.

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

iQIcBAEBCAAGBQJULHPeAAoJEBzwKT+lPKRY7T8P/iyLcWtf2V/COmPjPFiVQqnX
cmgDnzt8kzK4FX3fuERAjNLCK3l7ulhHHRn7hEScy3AFixF4sbFotYrAzaTdryiu
tJdx1KRpfN+faZoMZiwNo0zSXFOYeVim3Nn1ydI3MewU8D6cism//EAyHTp5owAu
ZJC7vMtEk7pxJkLI6ECJWx4u3ubpxeop3W4lePAzqC+1WecE0UtxRAC4KAzZq5Vr
e0xhE2c4WoNuoZcW3CvlhHhSZmnV+c86ROc/LqfaFAHlr8OnUcL7nJu1lCDR8aqr
YbMKpIMB7U/2YxEv0t4eFjKqHAtgRLfW9lrowLKQ04QJoXRvSYbFQrKsXypaTnk3
/0fnnKcFNFU+tgKwSM26nAXrMvd9RGflePTxaVnaBnKVGC6hJURltBcBtyhQD93j
pxdCap6FG6tn7rbWC0tgbNcdak4VYZOdcq9hY81a8Vebw7fEX1JfUF8NGUmBY5dg
KhFa79gkUlEnHUq+UQs7PvROFmP+/ylssXKRFnbNN7MauNQzn+nP3UbKM8WP+htB
Puct3J9Lh1e+tMPbnRPGWUyQr0HReHnp+TRM22Mv+wEPpKQP1ALRhBMuFnLiYKPm
4E3IaLLAGZTq7kIHLPSUBZU01+3pRANpZAXH05Qygd35gszuhlpjT0KqWa5B9Mw3
KcmWAgMrAYZQGSa/nwGC
=RNwv
-----END PGP SIGNATURE-----

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


Re: [OT] Forward TLS connection information from AWS ELB -> httpd -> Tomcat

Posted by Stefan Mayr <st...@mayr-stefan.de>.
Hi Christopher,

Am 01.10.2014 20:40, schrieb Christopher Schultz:
> -----BEGIN PGP SIGNED MESSAGE-----
...
>
> I've been trying to get mod_remoteip to handle the client's IP address
> for me -- especially for logging -- but I'm having some difficulty and
> have asked a question over on the httpd users' list about that.
...

mod_remoteip can do more for you (if you need it). Just for the purpose 
of logging the X-Forwarded-For-Header you could define a custom 
LogFormat and add request headers like \"%{X-Forwarded-For}i\" to it.

- Stefan

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


Re: [OT] Forward TLS connection information from AWS ELB -> httpd -> Tomcat

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

Stefan,

On 10/1/14 2:18 PM, Stefan Mayr wrote:
> Am 01.10.2014 19:18, schrieb Christopher Schultz:
>> -----BEGIN PGP SIGNED MESSAGE-----
> ...
>>>> What I'm mainly looking for is a way to say "the incoming 
>>>> connection (from ELB) is HTTP and I want to pretend that the 
>>>> connection is HTTPS".
>>> 
>>> Then the easier solution seems using ELB for SSL termination
>>> and using the X-Forwarded-Proto header, passing from apache to
>>> tomcat
>> 
>> Yes. Just looking for a way to say "oh, the connection is also 
>> encrypted".
> 
> If I remember correctly this needs only one line in Apache httpd
> to forward it to Tomcat
> 
> SetEnvIf X-Forwarded-Proto https HTTPS=on

This is where I have gotten so far, actually.

I've been trying to get mod_remoteip to handle the client's IP address
for me -- especially for logging -- but I'm having some difficulty and
have asked a question over on the httpd users' list about that.

> mod_jk should use this information and mark it as a secure
> connection for you. Then you can require a secure connection in
> your webapp web.xml or check it in httpd with the same environment
> variable:
> 
> Order Deny,Allow Deny from all Allow from env=HTTPS

I didn't know that you could do "Allow from env=HTTPS". I'll
definitely do that. I was also doing "Allow from 10.0.0.0/8" so that
only my ELB could access the VirtualHost I'm configuring.

> If the httpd is only a helper process to pass this information to
> Tomcat you can also use the Proxy-Valves: 
> http://tomcat.apache.org/tomcat-7.0-doc/config/valve.html#Proxies_Support
>
>  Something like this should serve your purpose: <Valve 
> className="org.apache.catalina.valves.RemoteIpValve" 
> protocolHeader="x-forwarded-proto" portHeader="x-forwarded-port" 
> />

I'd prefer to handle this at the httpd level if for no other reason
than logging.

> Together with transport-guarantee CONFIDENTIAL in your web.xml
> this would eliminate the need to configure anything on Apache httpd
> at all.

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

iQIcBAEBCAAGBQJULEqCAAoJEBzwKT+lPKRYKSUP/13RcT/81IevhKnZpWq8yj4A
eJeGk2FXG3dzziO/NQq5OGUYftDCjIeY/Iwu7r5JbdjncDO6R+SMyTEBQ09rXD8L
aQCVt+mXFPU4XOeNC292o+ju1FwUS8dyEj3nPOslIarM4jOTgFo5FoZnTO/ML8pg
ho9hIUZsIQb0Tf+YlSND8gMl3Lz/N0TQFTOALcub32gGJb7PztYhqj3lEttWkFL0
5Jg368WGL22aDP3VFXjNruOiLTDV0JQH9XOojMGBV5J/5logbqTvAQpVQew3KLHW
1M0xF4Hu99JyNUdRUa8LB8gmMKcVtTArVWpjb0aKV7tXr6/dszHT0PMfRRZNCII5
ObZB+8ZGOnV6YWXgefkwiERFwa2ibjRaup/D+R6GwY4aJjJ8bR+e9Zs2HzS3nPAA
3YP5zGYYFcAu2bkw3IPCTUYdM1PHJxNIVEQ/NaMR1rEltD3v1lFjkSgq5FDl/17c
oV9aUgCtIRyz5ZDVS8j4zjEak6+wEn7mJZ3BNU4S9wpkuKJgi/e7l/PfqbcFNwlF
RS0f2j6Z9JtYNtjlNjYdpMbnnwhN3LKOBBmXQ/77PVi0WMms5Yj1HDwZxFvQNfGx
xPu+ACMweviCdza7dm7aWTx+wBg8cx5SPwn9oONpQyn54ssJzw33wOobfNDtCkPG
GeMPjnzD3XHwjXAM6c61
=STcf
-----END PGP SIGNATURE-----

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


Re: [OT] Forward TLS connection information from AWS ELB -> httpd -> Tomcat

Posted by Stefan Mayr <st...@mayr-stefan.de>.
Am 01.10.2014 19:18, schrieb Christopher Schultz:
> -----BEGIN PGP SIGNED MESSAGE-----
...
>>> What I'm mainly looking for is a way to say "the incoming
>>> connection (from ELB) is HTTP and I want to pretend that the
>>> connection is HTTPS".
>>
>> Then the easier solution seems using ELB for SSL termination and
>> using the X-Forwarded-Proto header, passing from apache to tomcat
>
> Yes. Just looking for a way to say "oh, the connection is also encrypted".

If I remember correctly this needs only one line in Apache httpd to 
forward it to Tomcat

SetEnvIf X-Forwarded-Proto https HTTPS=on

mod_jk should use this information and mark it as a secure connection 
for you. Then you can require a secure connection in your webapp web.xml 
or check it in httpd with the same environment variable:

Order Deny,Allow
Deny from all
Allow from env=HTTPS

If the httpd is only a helper process to pass this information to Tomcat 
you can also use the Proxy-Valves: 
http://tomcat.apache.org/tomcat-7.0-doc/config/valve.html#Proxies_Support

Something like this should serve your purpose:
<Valve
  className="org.apache.catalina.valves.RemoteIpValve"
  protocolHeader="x-forwarded-proto"
  portHeader="x-forwarded-port"
/>

Togehter with transport-guarantee CONFIDENTIAL in your web.xml this 
would eliminate the need to configure anything on Apache httpd at all.

- Stefan

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


Re: [OT] Forward TLS connection information from AWS ELB -> httpd -> Tomcat

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

Frederik,

On 10/1/14 12:52 PM, Frederik Nosi wrote:
> Hi Christopher,
> 
> On 10/01/2014 06:05 PM, Christopher Schultz wrote:
>> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
>> 
>> Frederik,
>> 
>> On 10/1/14 11:15 AM, Frederik Nosi wrote:
>>> Hi Christopher, On 10/01/2014 04:26 PM, Christopher Schultz
>>> wrote: All,
>>> 
>>> 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.
>>> 
>>>> Maybe i'm missing something, but you can check that 
>>>> X-Forwarded-Proto header contains https? Seems a bit risky,
>>>> maybe additionally adding another check that the incomming
>>>> request comes from ELB's IP(s)?
>> Yes, I can check this. I can also ensure that the port is only 
>> accessible from the ELB. I'm less worried about this and more
>> worried about getting everything else working first. Protecting
>> the connection itself will not be a problem.
>> 
> 
> Maybe i didn't got your question right, what you're interested
> first, is letting know to tomcat that the client is using a secure
> connection? If so you can just pass a custom header from apache to
> tomcat, but this seems too easy :-)

No, I'm interested in convincing Apache httpd that the original
connection was encrypted. Basically, I want the equivalent of Tomcat's
secure="true" configuration option.

>>> 2. How can I use that connection information to tell mod_jk
>>> that things are to be trusted as well?
>>> 
>>>> Just pass a custom header. BTW Are you encrypting the w <--->
>>>> t connections as well? BTW I recall a setup i've made times
>>>> ago, where the SSL termination was on the apache webservers,
>>>> ex: LB (tcp) <---- https ---> apache httpd (SSL Termination
>>>> doing client certificate verification) / mod_jk <--- AJP --->
>>>> Tomcat I was able to send client's certificate information as
>>>> headers to tomcat. But not sure this is your situation.
>> I don't need to use client certificates, but being able to
>> support them would be nice.
>> 
>> AWS ELB seems to support TCP pass-through but you can't do it for
>> port 443. If you want to use port 443, you can either choose
>> "HTTPS/SSL" or "TCP/SSL". If you choose "HTTPS/SSL" then you have
>> to use either HTTP or HTTPS as the back-end protocol. For some
>> reason, choosing HTTPS causes endless stalling when trying to
>> make a connection.
> 
> I would get a tcpdump from the apache frontend, maybe you can get
> more info this way.

Yes, obviously I can do that. I was hoping that resorting to
packet-tracing would not be necessary.

>> Using TCP/SSL -> TCP/SSL (what I would call TCP pass-through)
>> ought to allow me to do SSL termination at the web server level,
>> accept client certificates, and have mod_ssk work without any
>> modification at all. I think in order to do this, I have to
>> configure Apache httpd to accept connections using the "proxy
>> protocol", and I'm not sure how to do that.
> 
> Hmm, didn't knowed about this protocol before. From some quick
> googling and reading, seems interesting, as at your endpoint the
> connection comes from ELBs'IP not from the client's IP, this
> protocol adds the missing info, real client ip.
> 
> http://blog.haproxy.com/haproxy/proxy-protocol/
> 
> So using this seems you need to add another piece to you'r
> infrastructure.
> 
>> 
>>> 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?
>>>> Maybe this can help: RewriteEngine on RewriteCond
>>>> %{HTTP:X-Forwarded-For} ^(.*)$ [NC] RewriteRule ^(.*)$ -
>>>> [env=JK_REMOTE_ADDR:%0] This way you send to tomcat as
>>>> REMOTE_ADDR  the contents of the X-Forwarded-For header
>> Why use mod_rewrite (slow) when you can use mod_setenvif (fast)?
>> 
>> SetEnvIf X-Forwarded-For "(.*)" JK_REMOTE_ADDR=$1
> 
> Indeed is better your way
> 
>> 
>> What I'm mainly looking for is a way to say "the incoming
>> connection (from ELB) is HTTP and I want to pretend that the
>> connection is HTTPS".
> 
> Then the easier solution seems using ELB for SSL termination and
> using the X-Forwarded-Proto header, passing from apache to tomcat

Yes. Just looking for a way to say "oh, the connection is also encrypted".

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

iQIcBAEBCAAGBQJULDdxAAoJEBzwKT+lPKRYybAP/2Avx29/ESZP581ZXLFd3AkV
ptTls68M2I1SPlqdr9hFzKD1Uy8BcFS8wnZy6Joe+wBhLL7wGQ3ccukrr6bTHi6X
aUsUCe+L+Ce8l24mtEhWgqaTN4Ia0yBzUkWY9/xxt0Fhs2y6/LxOHOS9tWmD9VF4
+z3doNQ4JNvBpxiamBBxv5OGkF3m4S3Mof504sC5Xigsk2Kcon559nxOjQ2qLyMz
7HGLjHTJITCqfxMXHWAOAflTKzYr1aTl9rbEUhX5wgyIzAnJvSJTfmo1UedjsPFc
YcjdOyr5qOMuGfQj1Dr+W+0JKd6/pdmyu1gZ7/c2SnvNRzd4RoS2G7FEaq12vL77
B8BRkjMxfZ5suh+t5o+Cq9E5IdbdNRdEefaw3yilP9/O2jgV4EPrsxy7lzFVFkQQ
Tyx1Uty07eFnxL9GXqGdPVYKPqvdoMH8xYZIAIcv+b6cChyzkotB0haAtd9q/7h8
3J+ejCNzotM0Oiah0II3EP86S7Mumd8P/Yy7AdYwt6KOCyOCGUSrawCf+LJgPEGZ
sojggwHZvfQmd2m2ttlJMiXD/85ktpOv5lZCYhOsBzlf1KTCjr7Gsm/JuaLhdA5N
JPucWuDe3xjIem2TIV3e1/KwvCTJfS4hu3nh3QQE/AjbeVPdYMI2OW/qymVBDYDl
Z3Cz/TfcpCfeTg03eE2x
=aeQy
-----END PGP SIGNATURE-----

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


Re: [OT] Forward TLS connection information from AWS ELB -> httpd -> Tomcat

Posted by Frederik Nosi <fr...@postecom.it>.
Hi Christopher,

On 10/01/2014 06:05 PM, Christopher Schultz wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> Frederik,
>
> On 10/1/14 11:15 AM, Frederik Nosi wrote:
>> Hi Christopher, On 10/01/2014 04:26 PM, Christopher Schultz wrote:
>> All,
>>
>> 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.
>>
>>> Maybe i'm missing something, but you can check that
>>> X-Forwarded-Proto header contains https? Seems a bit risky, maybe
>>> additionally adding another check that the incomming request
>>> comes from ELB's IP(s)?
> Yes, I can check this. I can also ensure that the port is only
> accessible from the ELB. I'm less worried about this and more worried
> about getting everything else working first. Protecting the connection
> itself will not be a problem.
>

Maybe i didn't got your question right, what you're interested first, is 
letting know to tomcat that the client is using a secure connection? If 
so you can just pass a custom header from apache to tomcat, but this 
seems too easy :-)

>> 2. How can I use that connection information to tell mod_jk that
>> things are to be trusted as well?
>>
>>> Just pass a custom header. BTW Are you encrypting the w <---> t
>>> connections as well? BTW I recall a setup i've made times ago,
>>> where the SSL termination was on the apache webservers, ex:
>>> LB (tcp) <---- https ---> apache httpd (SSL Termination doing
>>> client certificate verification) / mod_jk <--- AJP ---> Tomcat
>>> I was able to send client's certificate information as headers
>>> to tomcat. But not sure this is your situation.
> I don't need to use client certificates, but being able to support
> them would be nice.
>
> AWS ELB seems to support TCP pass-through but you can't do it for port
> 443. If you want to use port 443, you can either choose "HTTPS/SSL" or
> "TCP/SSL". If you choose "HTTPS/SSL" then you have to use either HTTP
> or HTTPS as the back-end protocol. For some reason, choosing HTTPS
> causes endless stalling when trying to make a connection.

I would get a tcpdump from the apache frontend, maybe you can get more 
info this way.

>
> Using TCP/SSL -> TCP/SSL (what I would call TCP pass-through) ought to
> allow me to do SSL termination at the web server level, accept client
> certificates, and have mod_ssk work without any modification at all. I
> think in order to do this, I have to configure Apache httpd to accept
> connections using the "proxy protocol", and I'm not sure how to do that.

Hmm, didn't knowed about this protocol before. From some quick googling 
and reading, seems interesting, as at your endpoint the connection comes 
from ELBs'IP not from the client's IP, this protocol adds the missing 
info, real client ip.

http://blog.haproxy.com/haproxy/proxy-protocol/

So using this seems you need to add another piece to you'r infrastructure.

>
>> 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?
>>> Maybe this can help:
>>> RewriteEngine on RewriteCond %{HTTP:X-Forwarded-For} ^(.*)$ [NC]
>>> RewriteRule ^(.*)$ - [env=JK_REMOTE_ADDR:%0]
>>> This way you send to tomcat as REMOTE_ADDR  the contents of the
>>> X-Forwarded-For header
> Why use mod_rewrite (slow) when you can use mod_setenvif (fast)?
>
> SetEnvIf X-Forwarded-For "(.*)" JK_REMOTE_ADDR=$1

Indeed is better your way

>
> What I'm mainly looking for is a way to say "the incoming connection
> (from ELB) is HTTP and I want to pretend that the connection is HTTPS".

Then the easier solution seems using ELB for SSL termination and using 
the X-Forwarded-Proto header, passing from apache to tomcat

[...]





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


Re: [OT] Forward TLS connection information from AWS ELB -> httpd -> Tomcat

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

Frederik,

On 10/1/14 11:15 AM, Frederik Nosi wrote:
> Hi Christopher, On 10/01/2014 04:26 PM, Christopher Schultz wrote: 
> All,
> 
> 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.
> 
>> Maybe i'm missing something, but you can check that
>> X-Forwarded-Proto header contains https? Seems a bit risky, maybe
>> additionally adding another check that the incomming request
>> comes from ELB's IP(s)?

Yes, I can check this. I can also ensure that the port is only
accessible from the ELB. I'm less worried about this and more worried
about getting everything else working first. Protecting the connection
itself will not be a problem.

> 2. How can I use that connection information to tell mod_jk that
> things are to be trusted as well?
> 
>> Just pass a custom header. BTW Are you encrypting the w <---> t 
>> connections as well? BTW I recall a setup i've made times ago,
>> where the SSL termination was on the apache webservers, ex:
> 
>> LB (tcp) <---- https ---> apache httpd (SSL Termination doing
>> client certificate verification) / mod_jk <--- AJP ---> Tomcat
> 
>> I was able to send client's certificate information as headers
>> to tomcat. But not sure this is your situation.

I don't need to use client certificates, but being able to support
them would be nice.

AWS ELB seems to support TCP pass-through but you can't do it for port
443. If you want to use port 443, you can either choose "HTTPS/SSL" or
"TCP/SSL". If you choose "HTTPS/SSL" then you have to use either HTTP
or HTTPS as the back-end protocol. For some reason, choosing HTTPS
causes endless stalling when trying to make a connection.

Using TCP/SSL -> TCP/SSL (what I would call TCP pass-through) ought to
allow me to do SSL termination at the web server level, accept client
certificates, and have mod_ssk work without any modification at all. I
think in order to do this, I have to configure Apache httpd to accept
connections using the "proxy protocol", and I'm not sure how to do that.

> 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?
>> Maybe this can help:
> 
>> RewriteEngine on RewriteCond %{HTTP:X-Forwarded-For} ^(.*)$ [NC] 
>> RewriteRule ^(.*)$ - [env=JK_REMOTE_ADDR:%0]
> 
>> This way you send to tomcat as REMOTE_ADDR  the contents of the 
>> X-Forwarded-For header

Why use mod_rewrite (slow) when you can use mod_setenvif (fast)?

SetEnvIf X-Forwarded-For "(.*)" JK_REMOTE_ADDR=$1

What I'm mainly looking for is a way to say "the incoming connection
(from ELB) is HTTP and I want to pretend that the connection is HTTPS".

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

iQIcBAEBCAAGBQJULCZeAAoJEBzwKT+lPKRYHQcP/1tdeiy0lWAHcQ2vG4HrpACy
ni5Ac17Z5gSeqQyol66/NiOPBnRM9NaZqLg6wpIps+8SaZuKnHir2IgnWXOBo7lQ
81aJokPIivwO74ang6lnfJJR2vYCYLn7eONI6+qqSWlk+Mw2CoLbsGoPxVeeBBe7
AE+2QZnzj9NtuhlGiIKvlPQXmJBs/VgBiEq23wFsikLisY0eHMkwGcYnuPZ9KYil
qHxxmfntPgMH+uhCcxwGHrXlLJLCCGZCFv3xQHkCKC5Ndb9mnGBY1b0IcplPwOvQ
zbRVHdJcewE36hHECE5r2Z4a44ThKMLPEz1wZVCJm5ljEZiyuVq181ukkotBdvT8
y3/WuHwzZV8z6mdCNGBoB/Y4RdXfyfwaIKFZwlM3OhBcPVD+jki82dE/7tLZ3mlZ
AUj5pBGuoePVV8hnrukLi+DM4sJ6CZ6zLq0OKX3MzfF8n8/kG7vr20ntTi7mjTDs
Suk3lLr2L+Y7LBOzeepbThGK3CtCMm3OGZisuN90Pf9yrnuxDRJigpPUSeKdO0uQ
rJMx9gqRWiBl2jbWO6bsF4Aqy4wGVA+zyG9oTWMWDegU3uXHVAZdVb/R1YRZ18Qk
wH826ul3NMaUUGmWS6rpGpKpFm8V4UZ+qtz8eaMkBet3YOzYLBqJQ4xj5Co2K+g+
ZNKUGsHHHFYdVK9HyKcL
=PcDT
-----END PGP SIGNATURE-----

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


Re: [OT] Forward TLS connection information from AWS ELB -> httpd -> Tomcat

Posted by Frederik Nosi <fr...@postecom.it>.
Hi Christopher,
On 10/01/2014 04:26 PM, Christopher Schultz wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> All,
>
> 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.

Maybe i'm missing something, but you can check that X-Forwarded-Proto 
header contains https? Seems a bit risky, maybe additionally adding 
another check that the incomming request comes from ELB's IP(s)?

> 2. How can I use that connection information to tell mod_jk that things
>     are to be trusted as well?

Just pass a custom header. BTW Are you encrypting the w <---> t 
connections as well? BTW I recall a setup i've made times ago, where the 
SSL termination was on the apache webservers, ex:

LB (tcp) <---- https ---> apache httpd (SSL Termination doing client 
certificate verification) / mod_jk <--- AJP ---> Tomcat

I was able to send client's certificate information as headers to 
tomcat. But not sure this is your situation.
> 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?
Maybe this can help:

RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-For} ^(.*)$ [NC]
RewriteRule ^(.*)$ - [env=JK_REMOTE_ADDR:%0]

This way you send to tomcat as REMOTE_ADDR  the contents of the 
X-Forwarded-For header

>
> 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.
>
> Thanks,
> - -chris
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1
> Comment: GPGTools - http://gpgtools.org
>
> iQIcBAEBCAAGBQJULA8qAAoJEBzwKT+lPKRYMf4P/2yONDv5rQFgHguhMeWv8BJs
> jbv8bLOOK5Vf+r5idJgyEgOFEI4jbEKfGdhIvD5BasT4PZF65sn3AsOXQpav9GA4
> kgomQHDipou3u5PFGi2d3xQQsDB9MjOTfAmmvQFNEnPxtisYQA+wNHGGxJDwyHIZ
> tJkS4jP8mA3vxLaoCLoSiOi2MEGr2nbj5Xcfd75F2IXfci9QEhGEgsUxyFq+K+Vb
> p+GVv4px55+zO9sLaIk6SiaNOGI3p86W+IX5spvoxO2Qxah+DVSoq9HRGryWd/Wn
> O3ZwSGqCHYKsPI1xHECaN/58pAR7polyU5nEFmzWbxFhc31Q2hpDkZuyZ3SIY2u1
> 7lLY+Zx41nizjfjeYeIcMtZ4OBj0uHBSj5qzLehF7zItZoRqEhgv2b4yn8vJjIj0
> GF4wpVqAqSWaIJ2F1C9ZjTnL9LhTJHZBurpt1JDSe7ALS/s4EoEQ/rbaz9kEUMNq
> BBThIapN+VXCwaqsA7hQliCWRoGuP2kNFStsatgeaNaBZd5Cf8cg8iTSUcoDR4UW
> Z4CHSi/4H6uD3wmcI6Jca7dfJEY+eNGM3zLsUF1hQPYP9MG6Fohy6h/UGGhlRehh
> sXZ6bL0oVfGVxSM9gMCDQzB4ptb9zuqU5UgWjKEB50lbwXgMLUm7XP3/C/bY7Zgt
> cXABRHoZSqoq2tPV1Lov
> =g2oZ
> -----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: [OT] Forward TLS connection information from AWS ELB -> httpd -> Tomcat

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----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