Hi Community.
When I adds accept-proxy to a bind configuration, it returns ssl handshake error. Without accept-proxy all is fine except I cannot get the original IP from the connecting client.
Let me introduce the arcitecture:
One frontend public server with HAProxy (Server A). This server is also a VPN server where the internal HAProxy server connects over VPN so Server A and Server B shares a dedicated network.
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-SHA3> #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
frontend http-in
bind *:80
mode http
option forwardfor
# Define hosts
use_backend nc-http-bk if { hdr(host) -i cloud.mydomain.tld }
redirect scheme https code 301 if { hdr(Host) -i www.mydomain.tld } !{ ssl_fc }
backend nc-http-bk
balance roundrobin
mode http
option forwardfor
#source 0.0.0.0 usesrc clientip
server node1 xxx.xxx.xxx.xxx:80 check send-proxy
frontend env_ssl_frontend
bind *:443
mode tcp
http-request redirect scheme https if ! { ssl_fc }
option tcplog
option tcp-check
tcp-request inspect-delay 10s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend bk-https-nc if { req_ssl_sni -i cloud.mydomain.tld }
use_backend bk-https-www if { req_ssl_sni -i www.mydomain.tld }
backend bk-https-nc
balance roundrobin
mode tcp
#source 0.0.0.0 usesrc clientip
option ssl-hello-chk
server main xxx.xxx.xxx.xxx:443 check send-proxy
#check fall 3 rise 2 send-proxy
backend bk-https-www
balance roundrobin
mode tcp
#source 0.0.0.0 usesrc clientip
option ssl-hello-chk
server main xxx.xxx.xxx.xxx:443 check send-proxy
Server B is internal and is used by all devices and clients on the internal network.
global
log /dev/log local0
log /dev/log local1 notice
stats socket /haproxy-admin.sock mode 660 level admin
stats timeout 30s
daemon
#ssl-default-bind-options ssl-min-ver TLSv1.2 prefer-server-ciphers
#ssl-default-bind-ciphers ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES256:ECDH+AES128:!aNULL:!SHA1:!AESCCM
#ssl-default-server-options ssl-min-ver TLSv1.3
#ssl-default-server-ciphers ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES256:ECDH+AES128:!aNULL:!SHA1:!AESCCM
defaults
maxconn 1000
mode http
log global
option http-server-close
option dontlognull # bind *:443 ssl crt .
timeout http-request 5s
timeout connect 30s
timeout client 4h # ddos protection
timeout server 4h # stick-table type ip size 100k expire 30s store conn_cur
#option forwardfor
frontend http-in
bind *:80
mode http
option forwardfor
# Define hosts
use_backend nc-http-bk if { hdr(host) -i cloud.mydomain.tld }
redirect scheme https code 301 if { hdr(Host) -i www.mydomain.tld } !{ ssl_fc }
# Internal trafic
frontend env_ssl_frontend
bind xxx.xxx.xxx.xxx:443
mode tcp
http-request redirect scheme https if ! { ssl_fc }
option tcplog
option tcp-check
tcp-request inspect-delay 10s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend bk-https-nc if { req_ssl_sni -i cloud.mydomain.tld }
use_backend bk-https-www if { req_ssl_sni -i www.mydomain.tld }
# From VPN tunnel (public)
frontend env_vpn_ssl
bind xxx.xxx.yyy.xxx:443
mode tcp
http-request redirect scheme https if ! { ssl_fc }
option tcplog
tcp-request inspect-delay 10s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend bk-https-nc if { req_ssl_sni -i cloud.mydomain.tld }
use_backend bk-https-www if { req_ssl_sni -i www.mydomain.tld }
backend nc-http-bk
balance roundrobin
mode http
option forwardfor
#source 0.0.0.0 usesrc clientip
server node1 xxx.xxx.xxx.xxx:8080 check send-proxy
backend bk-https-nc
balance roundrobin
mode tcp
#source 0.0.0.0 usesrc clientip
option ssl-hello-chk
server main xxx.xxx.xxx.xxx:4443 send-proxy
#check fall 3 rise 2 send-proxy
backend bk-https-www
balance roundrobin
mode tcp
#source 0.0.0.0 usesrc clientip
option ssl-hello-chk
server main xxx.xxx.xxx.xxx:4443 send-proxy
#check fall 3 rise 2 send-proxy
If I adds
frontend env_vpn_ssl
bind xxx.xxx.yyy.xxx:443 accept-proxy
Then I get an SSL Handshake error on my downstream endpoint. Without that one, all trafic is proxied without any other error, but the connecting IP in the webserver behind Server B, is recognised to be the VPN tunnel IP of Server A.
I have tested using send-proxy-v2 but same result. Any ideas?