TL;DR - option forwardfor
and http-request set-header X-Real-IP %[src]
are not working.
My setup is slightly complicated. I have a homeserver, with HAProxy installed and some docker containers. My homeserver is, then, connected to a VPS via WireGuard which also has HAProxy installed. HAProxy on homeserver forwards the docker containers with an SSL certificate to the VPS. The VPS, then, just does TLS pass through to the clients.
The issue is, if I do not use option forwardfor
in either of the 2 HAProxy configurations, I get the internal IP address of the docker container (172.XX.XX.1). If I add option forwardfor
on the homeserver’s HAProxy config, I get the internal IP of the WireGuard of the home server (10.0.0.2). And if I add option forwardfor
to the HAProxy config of the VPS as well, I get the internal IP of the WireGuard tunnel (10.0.0.1). And as far as I know, http-request set-header X-Real-IP %[src]
has no impact. I have also tried using send-proxy
and send-proxy-v2
, but then the whole setup stops working.
HAProxy config on home server:
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20>
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
listen rp
bind *:443 ssl crt /path/to/cert.pem
acl service1 hdr_sub(host) -i service1.domain.me
acl service2 hdr_sub(host) -i service2.domain.me
use_backend service1_backend if service1
use_backend service2_backend if service2
backend service1_backend
server service1_server 127.0.0.1:8080
backend service2_backend
# option forwardfor
# http-request set-header X-Real-IP %[src]
server service2_server 127.0.0.1:9090
HAProxy config on VPS:
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
tune.ssl.default-dh-param 4096
defaults
log global
mode tcp
# option forwardfor
timeout connect 5000
timeout client 50000
timeout server 50000
listen http
bind *:80
mode tcp
server default 10.0.0.2:80
listen https
bind *:443 alpn h2,http/1.1
mode tcp
# option forwardfor header X-Real-IP
# http-request set-header X-Real-IP %[src]
server main 10.0.0.2:443
I have to resort to this because I am behind CGNAT, and want TLS pass through on the VPS for privacy.
What am I doing wrong?
If you’re forwarding between haproxy instances, use proxy-protocol instead of forwardfor header forwarding.
Why are you running two HAProxy instances? You should be able to forward the traffic on your VPS to your homeserver with a firewall rule.
If that’s not an option, this should still be doable using the
X-Forwarded-For
header. Instead of setting it to single value, you need to append to it:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For#syntax
You don’t need haproxy on the vps at all, unless I’m misunderstanding you. Just route the traffic using iptables hooks in your wireguard config. This is exactly how I manage my email server and it’s entirely transparent.
Acronyms, initialisms, abbreviations, contractions, and other phrases which expand to something larger, that I’ve seen in this thread:
Fewer Letters More Letters DNS Domain Name Service/System HTTP Hypertext Transfer Protocol, the Web IP Internet Protocol NAT Network Address Translation VPS Virtual Private Server (opposed to shared hosting)
[Thread #140 for this sub, first seen 16th Sep 2023, 12:55] [FAQ] [Full list] [Contact] [Source code]