Pass src ip with HAProxy and MS ADFS

Hi

For the time being we are running MS ADFS with the configuration shown below - and that works like a charm… unfortunately there’s now need for the src ip to be shown to the ADFS servers - preferly as “X-MS-Forwarded-Client-IP”

I guess that would be possible if running in http-mode, but has anyone done this with ADFS?

global
log /dev/log local0
log /dev/log local1 notice
maxconn 6000
tune.ssl.default-dh-param 2048
daemon
chroot /var/lib/haproxy
uid 0
gid 0
ssl-default-server-options force-tlsv12 no-tls-tickets
ssl-default-server-ciphers ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
ssl-default-bind-options force-tlsv12 no-tls-tickets
ssl-default-bind-ciphers ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS

defaults
log global
option tcplog
option dontlognull
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms

frontend ADFSFrontend
bind 10.0.1.100:443 interface eth0
mode tcp
default_backend ADFSBackend

backend ADFSBackend
mode tcp
balance roundrobin
server adfs01 10.0.1.101:443 check
server adfs02 10.0.1.102:443 check

backend Stats
listen stats
bind :9000
mode http
stats enable
stats hide-version
stats refresh 10s
stats show-desc ADFS
stats show-legends
stats realm HAProxyADFS\ Statistics
stats auth stats:stats
stats uri /Stats

Best regards
'Adder

Hi Adder,

I’ve seen HAProxy in HTTP mode load-balancing ADFS services.
You must import your certificate into HAProxy, turn on ssl on the frontend and ssl on the server line and add an http rule which looks like:
http-request set-header X-MS-Forwarded-Client-IP %[src]

Hi Baptiste

Do you have an configuration example on it? I do have some problems getting this to work in http-mode due the SNI part of ADFS

best regards
'Adder

Hi

The config I have tried is as follows:

global
log 127.0.0.1:514 local0 info
maxconn 6000
tune.ssl.default-dh-param 2048
daemon
chroot /var/lib/haproxy
uid 99
gid 99
ssl-default-server-options force-tlsv12 no-tls-tickets
ssl-default-server-ciphers ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
ssl-default-bind-options force-tlsv12 no-tls-tickets
ssl-default-bind-ciphers ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS

defaults
log global
option tcplog
option httplog
option dontlognull
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms

frontend ADFSFrontend
bind 10.0.1.160:443 ssl crt /etc/haproxy/wildcard.cert.pem
mode http
http-request set-header X-MS-Forwarded-Client-IP %[src]
default_backend ADFSBackend

backend ADFSBackend
mode http
balance roundrobin
option httpchk GET /adfs/ls/IdpInitiatedSignon.aspx HTTP/1.0\r\n
option httpclose
option forwardfor header X-Client
http-check expect string Sign\ in
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
server adfssrv01 10.0.1.101:443 ssl verify none sni ssl_fc_sni inter 3s rise 2 fall 3
server adfssrv02 10.0.1.102:443 ssl verify none sni ssl_fc_sni inter 3s rise 2 fall 3

And I can see the login page, but when signing in it fails, and in the log I see:

ADFSFrontend~ ADFSBackend/adfssrv02 0/0/1/6/7 401 344 - - ---- 1/1/0/0/0 0/0 “GET /adfs/Proxy/webapplicationproxy/store?api-version=1 HTTP/1.1”
ADFSFrontend~ ADFSBackend/adfssrv01 0/0/1/6/7 401 344 - - ---- 1/1/0/0/0 0/0 “GET /adfs/Proxy/webapplicationproxy/store?api-version=1 HTTP/1.1”
ADFSFrontend~ ADFSBackend/adfssrv02 0/0/1/6/7 401 344 - - ---- 1/1/0/0/0 0/0 “GET /adfs/Proxy/webapplicationproxy/store?api-version=1 HTTP/1.1”
ADFSFrontend~ ADFSBackend/adfssrv01 0/0/1/6/7 401 344 - - ---- 1/1/0/0/0 0/0 “GET /adfs/Proxy/webapplicationproxy/store?api-version=1 HTTP/1.1”
ADFSFrontend/1: SSL handshake failure

Regards
'Adder

Hi BlackAdderDK,

I normally avoid offloading the SSL for ADFS at all costs… However, I’ll have a go at helping. Can I confirm that it is 100% the same certificate used on the backend WAP servers(not just for the same domains)?

I assume you have provided the full chain in the cert file?

Hi Aaron

I fully understand your comment about avoiding SSL offloading, and have done the same so far with a setup running in tcp-mode

But there’s a supplier of some 2-factor software that needs the src address and/or and specific http-header.

Regarding the certificate, yes it is the same certificate used (a star certificate, key and cert only)

’ Adder

SSL is not offloaded in @BlackAdderDK config, since HAProxy would do SSL on the server side too.
We call this “SSL bridging” or “re-encryption” deployment layout.

Hi Baptiste

Yes, you are completely correct - my comment is in general, that if I can avoid breaking the tunnel from client to end-point I will try to.

I figured out my problem, and got all up and running - first of all the httpclose (and http-server-close) did break the communication with the ADFS server.

Furthermore I tried to change the httpchk to a GET on /adfs/probe… and If I do in eg. firefox I will get an 200… but Haproxy got an 503… but When returning to /adfs/ls/IdpInitiatedSignon.aspx, and changing the following “http-check expect status 200” - all started to function as expected.

Thanks for you time

Best regards
'Adder

That makes perfect sense! Sorry that I missed it… You were getting a 401 so I should have figured it was the auth…

Hi,

I have the same exact problem. Can you please give me some extra details regarding your solution?
What do yo use instead the “httpclose” option?

Thanks,
László