X-Forwarded-For header addition or header extension
Hi, I'm using HAproxy 1.4.8 on RHEL5 (fully up-to-date). I'm using the 'option forwardfor' In certain circumstances, the client has already got an X-Forwarded-For header in the request. HAproxy in this instance adds a second X-Forwarded-For header rather than extending the existing header. This causes a problem on our Tomcat backend because the RemoteIP valve (part of Tomcat) that is used appears to examine only the first header. 1. Is there some way to get HAproxy to extend the existing X-Forwarded-For header rather than adding a new one 2. Does the stunnel patch do the same thing or does it extend the existing X-Forwarded-For header? Thanks, -- Best Regards, Brett Delle Grazie
Re: X-Forwarded-For header addition or header extension
On Dec 10, 2010, at 6:42 AM, Brett Delle Grazie wrote: Hi, I'm using HAproxy 1.4.8 on RHEL5 (fully up-to-date). I'm using the 'option forwardfor' In certain circumstances, the client has already got an X-Forwarded-For header in the request. HAproxy in this instance adds a second X-Forwarded-For header rather than extending the existing header. This causes a problem on our Tomcat backend because the RemoteIP valve (part of Tomcat) that is used appears to examine only the first header. 1. Is there some way to get HAproxy to extend the existing X-Forwarded-For header rather than adding a new one 2. Does the stunnel patch do the same thing or does it extend the existing X-Forwarded-For header? It sounds like this is an issue with the RemoteIP valve. (I haven't looked at its code yet.) According to the HTTP spec, headers that allow multiple values can be specified as either a comma-separated list or multiple separate headers: Multiple message-header fields with the same field-name MAY be present in a message if and only if the entire field-value for that header field is defined as a comma-separated list [i.e., #(values)]. It MUST be possible to combine the multiple header fields into one field-name: field-value pair, without changing the semantics of the message, by appending each subsequent field-value to the first, each separated by a comma. The order in which header fields with the same field-name are received is therefore significant to the interpretation of the combined field value, and thus a proxy MUST NOT change the order of these field values when a message is forwarded. That is, the following are semantically equivalent according to the HTTP spec: X-Forwarded-For: 192.168.100.123 X-Forwarded-For: 127.0.0.1 and X-Forwarded-For: 192.168.100.123, 127.0.0.1 In fact, proxies and caches may make these changes in-flight. If you don't need the client's existing X-Forwarded-For information and can't wait for a Tomcat fix, you can always do a `reqidel ^X-Forwarded-Proto:.*' in your haproxy config. Then the only XFF header you will get in Tomcat will be from haproxy. (This may cause issues if you're using stunnel, though.)
Re: X-Forwarded-For header addition or header extension
Jim, Thanks, I've raised the issue with tomcat users and they recommended to create a bugzilla entry, which I will do. I will also point them to this mailing list for the definition. I'm using stunnel so the second suggestion won't work. The most simple and obvious solution is to use a different header that won't be used elsewhere - but that's a work-around. Thanks for your help. On 10 December 2010 13:30, Jim Riggs freebsd-li...@christianserving.orgwrote: On Dec 10, 2010, at 6:42 AM, Brett Delle Grazie wrote: Hi, I'm using HAproxy 1.4.8 on RHEL5 (fully up-to-date). I'm using the 'option forwardfor' In certain circumstances, the client has already got an X-Forwarded-For header in the request. HAproxy in this instance adds a second X-Forwarded-For header rather than extending the existing header. This causes a problem on our Tomcat backend because the RemoteIP valve (part of Tomcat) that is used appears to examine only the first header. 1. Is there some way to get HAproxy to extend the existing X-Forwarded-For header rather than adding a new one 2. Does the stunnel patch do the same thing or does it extend the existing X-Forwarded-For header? It sounds like this is an issue with the RemoteIP valve. (I haven't looked at its code yet.) According to the HTTP spec, headers that allow multiple values can be specified as either a comma-separated list or multiple separate headers: Multiple message-header fields with the same field-name MAY be present in a message if and only if the entire field-value for that header field is defined as a comma-separated list [i.e., #(values)]. It MUST be possible to combine the multiple header fields into one field-name: field-value pair, without changing the semantics of the message, by appending each subsequent field-value to the first, each separated by a comma. The order in which header fields with the same field-name are received is therefore significant to the interpretation of the combined field value, and thus a proxy MUST NOT change the order of these field values when a message is forwarded. That is, the following are semantically equivalent according to the HTTP spec: X-Forwarded-For: 192.168.100.123 X-Forwarded-For: 127.0.0.1 and X-Forwarded-For: 192.168.100.123, 127.0.0.1 In fact, proxies and caches may make these changes in-flight. If you don't need the client's existing X-Forwarded-For information and can't wait for a Tomcat fix, you can always do a `reqidel ^X-Forwarded-Proto:.*' in your haproxy config. Then the only XFF header you will get in Tomcat will be from haproxy. (This may cause issues if you're using stunnel, though.) __ This email has been scanned by the MessageLabs Email Security System. For more information please visit http://www.messagelabs.com/email __ -- Best Regards, Brett Delle Grazie
Re: HAProxy Cookie/Host Forwarding
Well, it's not that it doesn't work but we have approximately 1200 domains (that we actively develop on) and it doesn't seem very logical to hardcode each domain in. I was wondering if there was a workaround for the lines below so instead of using example.com:80 using a variable such as $HOST:80 (whichever host the end user is attempting to connect to). backend production modehttp option forwardfor balance source option httpclose server prod1 example.com:80 http://example.com/ On Fri, Dec 10, 2010 at 10:18 AM, Bryan Talbot btal...@aeriagames.comwrote: I do something similar using a config that is pretty much like what you've shown. What doesn't work about the config you've shown? -Bryan On Fri, Dec 10, 2010 at 9:05 AM, Anthony Saenz antho...@consumertrack.com wrote: Hi, Don't mean to bug but did anyone get a chance to possibly look at this and provide some assistance or does anyone know of alternative means to get this to work with cookie information? Thanks. On 12/8/10 3:43 PM, Anthony Saenz wrote: Hey, I was wondering if anyone could be of any assistance? I'm trying to use HAProxy to forward based on cookie and host. As it stands, I want HAProxy to see if a cookie is set and if it is, forward to a development server and if it isn't just push out to production. The main issue being, we have multiple production servers and a few thousand domains, so hard coding everything doesn't seem very efficient. Is there a way to have HAProxy forward the production request based on the host the person is attempting to initially connect to without it being static in the configuration file? Here's what I have so far... global daemon defaults mode http timeout connect 1 # default 10 second time out if a backend is not found timeout client 30 timeout server 30 maxconn 6 retries 3 frontend read_cookies bind:80 acl is_servermagic hdr_reg(Cookie) dev_magic=.* use_backend development if is_servermagic default_backend production backend development modehttp option forwardfor balance source option httpclose server dev1 192.168.1.100:80 backend production modehttp option forwardfor balance source option httpclose server prod1 example.com:80
Re: HAProxy Cookie/Host Forwarding
I thought you said you have multiple servers but thousands of domains. In that case, just list the servers by IP address and the proxy will pass the Host header value as supplied by the client. You should probably avoid using names resolved using DNS anyway so that a DNS hickup doesn't effectively disable your proxy. backend production modehttp option forwardfor balance source option httpclose server prod1 10.10.10.11:80 http://example.com/ server prod2 10.10.10.12:80 http://example.com/ server prod3 10.10.10.13:80 http://example.com/ On Fri, Dec 10, 2010 at 10:25 AM, Anthony Saenz antho...@consumertrack.comwrote: Well, it's not that it doesn't work but we have approximately 1200 domains (that we actively develop on) and it doesn't seem very logical to hardcode each domain in. I was wondering if there was a workaround for the lines below so instead of using example.com:80 using a variable such as $HOST:80 (whichever host the end user is attempting to connect to). backend production modehttp option forwardfor balance source option httpclose server prod1 example.com:80 http://example.com/ On Fri, Dec 10, 2010 at 10:18 AM, Bryan Talbot btal...@aeriagames.comwrote: I do something similar using a config that is pretty much like what you've shown. What doesn't work about the config you've shown? -Bryan On Fri, Dec 10, 2010 at 9:05 AM, Anthony Saenz antho...@consumertrack.com wrote: Hi, Don't mean to bug but did anyone get a chance to possibly look at this and provide some assistance or does anyone know of alternative means to get this to work with cookie information? Thanks. On 12/8/10 3:43 PM, Anthony Saenz wrote: Hey, I was wondering if anyone could be of any assistance? I'm trying to use HAProxy to forward based on cookie and host. As it stands, I want HAProxy to see if a cookie is set and if it is, forward to a development server and if it isn't just push out to production. The main issue being, we have multiple production servers and a few thousand domains, so hard coding everything doesn't seem very efficient. Is there a way to have HAProxy forward the production request based on the host the person is attempting to initially connect to without it being static in the configuration file? Here's what I have so far... global daemon defaults mode http timeout connect 1 # default 10 second time out if a backend is not found timeout client 30 timeout server 30 maxconn 6 retries 3 frontend read_cookies bind:80 acl is_servermagic hdr_reg(Cookie) dev_magic=.* use_backend development if is_servermagic default_backend production backend development modehttp option forwardfor balance source option httpclose server dev1 192.168.1.100:80 backend production modehttp option forwardfor balance source option httpclose server prod1 example.com:80