0

This question already has an answer here:

I'm running version HA-Proxy version 1.8.12-1ppa1~bionic 2018/06/27 on Ubuntu.

I'm trying to load balance requests to load.mysite.com to two different windows servers with IIS. The servers also have other website running on IIS with the same ports. We use host name binding to arrive on the correct website.

This is my HAProxy cfg:

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

        # Default ciphers to use on SSL-enabled listening sockets.
        ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
        ssl-default-bind-options no-sslv3

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        option forwardfor
        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

# Stats
listen stats
        bind *:9999
        stats enable
        stats hide-version
        stats uri /stats
        stats auth admin:***

# Http In - forward to https
frontend http-in
        bind *:80
        redirect scheme https if !{ ssl_fc }

# Https in
frontend https-in
        bind *:443 ssl crt /etc/ssl/mysite.com/mysite.com.pem
        acl host_mysitePlatform hdr(host) -i load.mysite.com
        use_backend mysitePlatform_cluster if host_mysitePlatform

backend mysitePlatform_cluster
        balance roundrobin
        http-request set-header Host node1.mysite.com if { srv_id 1 }
        http-request set-header Host node2.mysite.com if { srv_id 2 }
#       http-send-name-header Host
        server mysite1Server node1.mysite.com:443 check ssl verify none
        server mySite2Server node2.mysite.com:443 check ssl verify none

This configuration is not working. IIS returns a 404 because it does not know to which site it should bind.

It works for backend server node1.mysite.com when I remove if { srv_id 1 }. But then of course it only works for one server.

So it looks like the condition if { srv_id ? } is always false.

I could just fix it by using the same host name bindings on both IIS servers (e.g. www.mysite.com) but we have some constraints that prevent us from doing that.

Also, initially we want the backends to be https because we need code changes to disable https and we want to do those after go live of the load balancer. In a later stage all our backends will be on port 80.

I commented http-send-name-header Host because this also didn't work. Only http-request set-header Host <hostName> works for me.

So my question is, how do I get srv_id to work? I also tried with creating an acl first that for example checks if srv_id = 1 but that is also always false. Perhaps if I could log the actual value of srv_id when load balancing to a server, then I could change my if statement to the correct value.

marked as duplicate by Michael - sqlbot, womble Jul 8 '18 at 2:13

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • I would expect HAProxy to log a warning that the ACL would never match when loading this configuration, because srv_id is only defined during response processing. It returns the server that provided the response. http-request is valid in the backend section, but processing happens before the server is selected. – Michael - sqlbot Jul 7 '18 at 16:39
  • http-send-name-header should send the name of the server, as configured, e.g. mysite1Server. – Michael - sqlbot Jul 7 '18 at 16:42
  • @Michael-sqlbot that fixed it for me, I changed the backend server config to server node1.mysite.com node1.mysite.com:443 check ssl verify none, uncommented the http-send-name-header and removed the set-header lines and it worked. I am considering removing this question because it has already been answered here serverfault.com/questions/876871/… – Rubanov Jul 7 '18 at 18:25
0

Srv_id probably works as it should: when you receive a response.

"Returns an integer containing the server's id when processing the response. While it's almost only used with ACLs, it may be used for logging or debugging."

Try SNI:

server mysite1Server node1.mysite.com:443 check ssl verify none sni node1.mysite.com
server mySite2Server node2.mysite.com:443 check ssl verify none sni node2.mysite.com
  • @gerard-h-pile Unfortunately that doesn't work : parsing [/etc/haproxy/haproxy.cfg:64] : 'server mysite1Server' : error detected while parsing sni expression : unknown fetch method 'node1.mysite.com' – Rubanov Jul 7 '18 at 18:14
0

I was able to fix it by changing my backend configuration to this

backend mysitePlatform_cluster
    balance roundrobin
    http-send-name-header Host
    server node1.mysite.com node1.mysite.com:443 check ssl verify none
    server node2.mysite.com node2.mysite.com:443 check ssl verify none

Now the host name (in HAproxy this is the server name) is passed to the IIS server and IIS binds to the correct website.

Not the answer you're looking for? Browse other questions tagged or ask your own question.