haproxyproxy-protocol

How to strip Proxy protocol with HAproxy?


Consider the following situation:

                                      Internet
                                         ||
                                         ||
                                  .------''------.
                                  | HTTPS (:443) |
                                  '------..------'
                                         ||
                 .-----------------------'|
                 |                       \/
                 |           3rd party HAproxy service
                 |                       ||
                 |                       ||
             optional        .-----------''-----------.
               route         | PROXY Protocol (:5443) |
                 |           '-----------..-----------'
                 |                       ||                                 ________
      ___________|_______________________||________________________________| SERVER |____
     |           |                       \/                                              |
     |           |                 local HAproxy                                         |
     |           |                       ||                                              |
     |           |                       ||                                              |
     |           |                .------''------.                                       |
     |           |                | HTTPS (:443) |                                       |
     |           |                '------..------'                                       |
     |           |                       ||                                              |
     |           |                       ||                                              |
     |           |                       \/                                              |
     |           '---------------> local webserver                                       |
     |___________________________________________________________________________________|

The backend server has both HAproxy and Apache httpd locally running on port 5443 and 443 respectively.

My local webserver does not support the PROXY protocol. So I want HAproxy to catch the PROXY Protocol from the 3rd party service, and pass the data to the local webserver in either HTTPS or simply a TCP pass-through.

In the case of HTTPS I suppose it should manipulate the HTTP packets using the correct SSL-certificate to add the original sender IP in the X-Forwarded-For HTTP headers (which should be provided by the PROXY protocol).

However, the documentation of HAproxy is awful if you are new to HAproxy, and I could not find examples that explain how to do this. I know it has to be possible since HAproxy is listed as "Proxy-protocol ready software", but how?


Solution

  • Yes, you need to use the accept-proxy keyword after bind in the frontend declaration. It will also be good to read about the related send-proxy keyword which is used in the given "3rd party HAproxy service".

    The PROXY Protocol can be stripped back to its original state using the following HAproxy configuration:

    frontend app-proxy
      bind *:5443 accept-proxy
      mode tcp
      option tcplog
      default_backend app-httpd
    backend app-httpd
      mode tcp
      server app1 127.0.0.1:443 check
    

    This will accept a PROXY Protocol on port 5443, strip it, and send the TCP data to 443.

    If you would like to manipulate the HTTP packets in the SSL-encrypted TCP data, you would need to have access to the correct SSL certificates (which your webserver should have access to already). This is what you'll likely want to do.

    frontend app-proxy
      bind *:5443 accept-proxy ssl crt /path/to/certnkey-file.pem
      mode http
      option httplog
      default_backend app-httpd
    backend app-httpd
      mode http
      server app1 127.0.0.1:443 check ssl verify none
    

    The advantage of the latter approach is that the original client data is preserved while passing through the proxies, so that you know what the original IP of your visitor is. Which is kind of the whole idea of using PROXY Protocol in the first place! HAproxy will automatically update the X-Forwarded-For header with the correct IP-address which was transferred using the PROXY Protocol.