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?
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.