Haproxy https redirect loop if backends down

haproxy

This haproxy config terminates ssl for 2 sites (foo and bar) and load balances both sites to their own backend cluster. It also redirects http requests to https.

That works fine. Only, if the backend is down, it gets into a redirect loop for both sites. Eg: https://foo.example.com -> https://foo.example.com.

If I remove the redirect. It serves the sites over http and https and when the backends are down, it serves the 503 page as I would expect.

I want to redirect http to https. So, why is there a redirect loop?

global
    log 127.0.0.1   local0 debug
    maxconn 1024
    chroot /var/haproxy
    uid 604
    gid 604
    daemon
    pidfile /var/run/haproxy.pid

defaults
    log     global
    mode    http
    option  httplog
    option  dontlognull
    option  http-server-close
    option  redispatch
    retries 3
    maxconn 2000
    errorfile 503 /etc/haproxy/503.http

frontend http
    bind *:80
    redirect scheme https code 301 if !{ ssl_fc }

frontend https
    bind *:443 ssl crt /etc/ssl/example.com.pem

    option forwardfor
    reqadd X-Forwarded-Proto:\ https
    http-response set-header Strict-Transport-Security "max-age=31536000;"

    acl project_foo hdr(host) -i foo.example.com
    acl project_bar hdr(host) -i bar.example.com

    use_backend cluster_foo if project_foo
    use_backend cluster_bar if project_bar

backend cluster_foo
    server foo-1 foo-1.example.com:80 check

backend cluster_bar
    server bar-1 bar-1.example.com:80 check

“`

Best Answer

haproxy and nginx were on the same server while testing. foo-1.example.com listens on port 80 on a dedicated IP but haproxy listens on *:80

making haproxy listen on a dedicated IP fixed this. So, the config above is just fine. I took the time to re-test everything because I did stip down the config to have a reasonable reproducible setup