I'm starting to use haproxy to balance across nginx servers (in order to load balance the rails instances behind those nginxen). I want to 301 redirect all names that aren't the www name to the www name (and all http -> https). So I write this, which doesn't quite work. What actually happens is that http -> https, but all the names on https return 200 rather than 301 for all but www.staging.example.com. In addition, I was hoping to 301, say http://staging.example.com/ directly to https://www.staging.example.com/, but instead it just 301's to https://staging.example.com/

frontend www-http
    bind 1.2.3.4:80

    acl redirect_canonical req_ssl_sni -i staging.example.com
    acl redirect_canonical req_ssl_sni -i myname.example.com
    http-request  redirect  code 301  location  https://www.staging.example.com%[capture.req.uri]  if\
 redirect_canonical

    http-request  redirect  code 301  scheme https  if !{ ssl_fc }

    reqadd X-Forwarded-Proto:\ http
    default_backend railswebapp-backend

frontend www-https
    bind 1.2.3.4:443 ssl crt /etc/haproxy/ssl/

    # Test URI to see if its a letsencrypt request.                                                      
    acl letsencrypt-acl path_beg /.well-known/acme-challenge/
    use_backend letsencrypt-backend if letsencrypt-acl

    acl redirect_canonical req_ssl_sni -i staging.example.com
    acl redirect_canonical req_ssl_sni -i myname.example.com
    http-request  redirect  code 301  location  https://www.staging.example.com%[capture.req.uri]  if\
 redirect_canonical

    reqadd X-Forwarded-Proto:\ https
    default_backend railswebapp-backend

Any pointers on what I'm doing wrong?

Update

The corrected block is this:

frontend www-http
    bind 1.2.3.4:80

    acl redirect_canonical hdr(host) -i staging.example.com
    acl redirect_canonical hdr(host) -i myname.example.com
    http-request  redirect  code 301  location  https://www.staging.example.com%[capture.req.uri]  if\
 redirect_canonical

    http-request  redirect  code 301  scheme https  if !{ ssl_fc }

    reqadd X-Forwarded-Proto:\ http
    default_backend railswebapp-backend

frontend www-https
    bind 1.2.3.4:443 ssl crt /etc/haproxy/ssl/

    # Test URI to see if its a letsencrypt request.                                                      
    acl letsencrypt-acl path_beg /.well-known/acme-challenge/
    use_backend letsencrypt-backend if letsencrypt-acl

    acl redirect_canonical ssl_fc_sni -i staging.example.com
    acl redirect_canonical ssl_fc_sni -i myname.example.com
    http-request  redirect  code 301  location  https://www.staging.example.com%[capture.req.uri]  if\
 redirect_canonical

    reqadd X-Forwarded-Proto:\ https
    default_backend railswebapp-backend

0 Answers