301 redirect over https doesn't include HSTS header (HAProxy 2.1)

All the redirects need to happen in a second proxy layer (in this case, the frontend redirects listening on 127.0.0.1:8081 - so make sure that port is free or use a different one). This also requires another backend, which is needsredirect here that is needed to divert the traffic to the new frontend.

The original frontend http-in must not contain any redirect rules (just the HSTS settings) and must make sure that request that still need to be redirected go through backend needsredirect to frontend redirects.

It should look like this then (untested):

frontend http-in
    bind *:80
    bind *:443 ssl crt /certs/example.net.pem alpn h2,http/1.1

    # default headers
    http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    http-response set-header X-Frame-Options "SAMEORIGIN"
    http-response set-header X-XSS-Protection "1; mode=block"
    http-response set-header X-Content-Type-Options "nosniff"

    # route subdomains to backends
    acl is_main  hdr(host) -i example.net
    acl is_www   hdr(host) -i www.example.net

    use_backend needsredirect  if !{ ssl_fc }
    use_backend needsredirect  if is_main
    use_backend www   if is_www

backend needsredirect
    server localredirects 127.0.0.1:8081

frontend redirects
    bind 127.0.0.1:8081
    
    # redirect non-www to www
    acl has_www hdr_beg(host) -i www.
    http-request redirect prefix https://www.%[hdr(host)] code 301 if !{ has_www }

    # redirect all HTTP traffic to HTTPS
    http-request redirect scheme https code 301 if !{ ssl_fc }

backend www
    server main main:9200 check
2 Likes