Ideas to get X-Forwarded-For working for HTTPS/Node Balancer

I am currently using the Linode Lode Balancers service to distribute load across a few nodes. Each node runs an apache + pylons app. server instance, where apache acts as proxy for dynamic content and directly serves static content. I have HTTPS load balancing enabled via the TCP method.

Everything works great, except that I always get the IP of load balancer in X-Forwarded-For header.

I want to get the actual client IP coming through. Is there any way to make it happen other than running my own node balancer and terminating the https connection there?

Thanks!

Dwipal :?:

6 Replies

Disclaimer: I have no experience with Linode's load balancing service, but I suspect you'll have to roll your own for what you want to achieve.

If you want to inject the actual source IP as X-Forwarded-For header at the load balancer into an SSL stream then the only way I know is to terminate the SSL session at the load balancer. This is because the HTTP headers are part of the encrypted payload, you can't modify the payload without the SSL keys to decrypt it. I suspect Linode's balancer doesn't have a mechanism for offloading SSL keys to them (but it would be a neat feature).

The only other way is to not have a NAT-ing load balancer but one that operates in bridged mode, i.e. passes the IP packets with the source address set to be the actual source of the client. It's unlikely Linode support that mode as it's very difficult to set up from a networking/routing perspective if you want to be able to transparently load balance across multiple subnets/data centres.

@feanor:

If you want to inject the actual source IP as X-Forwarded-For header at the load balancer into an SSL stream then the only way I know is to terminate the SSL session at the load balancer.
Some load balancers do support other ways of forwarding the client's IP address, for example prefixing the encrypted packet with the IP. Obviously this requires special support in the backend web server.

@feanor:

It's unlikely Linode support that mode as it's very difficult to set up from a networking/routing perspective if you want to be able to transparently load balance across multiple subnets/data centres.
Well, Linode doesn't load balance across multiple networks – yet, anyway.

crazy idea to get origin IP in a TLS/SSL3 stream without terminating it.

As a new special load balancer type TLS/SSL:

  • replace the SNI TLS extension in the TLS Client Hello with the source IP address.

Why?

  • its not encrypted or protected beyond a TCP checksum

    • Apache and maybe other servers have visibility of it in a server variable (Apache SSLTLSSNI (undocumented) since 2.2.12 ~~[https://issues.apache.org/bugzilla/showbug.cgi?id=54292" target="blank">](https://issues.apache.org/bugzilla/show … i?id=54292">https://issues.apache.org/bugzilla/show_bug.cgi?id=54292]()
    • Its at the beginning of the conversation so its easy(er) to manipulate

    A bit of funky u32 firewall rules match the TLS Client Hello packet to push this to a nfqueue.

    A small bit of nfqueue code could insert a TLS extension SNI into the packet contain the text representational of the source IP address. The original SNI extension would be lost.

    Perhaps another extension could be chosen. After all there is 2^32 of them and ~18 are allocated. http://www.iana.org/assignments/tls-ext … values.xml">http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xml

    Crazy idea obviously but it could work. :)

    EDIT: won't work - Client Hello is part of the hash that is validated when Finished Handshake occurs.

next crazy idea. Use TCP OOB to send the origin IP. Isn't interfering for any TCP app that doesn't use OOB…..

Perhaps mod_rpaf for your Apache instances would be the solution in this scenario?

A quick update: NodeBalancers now support terminating HTTPS/SSL connections. They also append the X-Forwarded-For header while in HTTTP or HTTPS mode. There's more info here:

X-Forwarded-For Header

NodeBalancer SSL Configuration

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct