Haproxy, get original IP address for layer 4 (TCP)



  • I'm messing with TCP-based stuff. I just realized my service will be behind haproxy on production machines and therein lies the problem. How do I get the original ip address for connection? Since the traffic is being redirected, all I can get is "127.0.0.1" or wherever haproxy will be.

    It's easy with http, just stick it in the header. But what about pure TCP?

    The canonical answer is: use a special kernel patch and custom compile haproxy to use it. HA! On the crappy crippled VPS-es I'm given, I can hardly get firewall to work. No go.

    The things I've tried so far:

    • Since I control communication on the receiving side, how about haproxy should just stick the IP in the data flow and I'll parse it on other side? Answer: No option in haproxy

    • Ok, so how about I send some custom command, like haproxy sourceip and it sends me the data I want? Answer: No option

    • Ok, how about I hook up my custom script that gets called for each connection, that gets passed connection info, and I merge the data through that? Answer: no option.

    • Another option I missed: send-proxy command, that is a part of "PROXY" protocol. Answer: haproxy 1.5 minimum, see you in a few years (all I get are 1.3 and 1.4-s)

    Right now, I'm considering parsing the haproxy logs and extracting the ip-s from there. Or just giving up.

    Before that, any haproxy/linux guru here had a similar problem? Anything I'm missing?



  • This post is deleted!


  • Yeah, that shit doesn't fly with pure TCP, that's the issue.



  • Ok, I got it. send-proxy option is the solution. It's exactly what I need. It's pain in the ass that I'd have to recompile all my haproxies to 1.5+, but it's better than having a daemon digging through logs (ugh).

    For those interested, here's a quick rundown:

    • Need haproxy 1.5+

    • In your configuration, add send-proxy option

    backend bk_cartman
        mode tcp
        timeout server 1m
        timeout connect 5s
        server srv_cartman 127.0.0.1:12345 send-proxy
    
    • On the receiving end, as soon as connection is formed, you get something like this:
    proxy TCP4 192.168.1.1 192.168.1.2 52137 1034
    

    That's IP version, source/destination IP, source/destination port. Couldn't be simpler. I like it.


Log in to reply