Https to https://www

Hello,

On my DNS provider I redirect http to https. It works well.
In the server, I use letsencrypt with a certificate over the domain with www and all requests with https and www work very well also.

My question is I want to add a redirection for requests from https://domain.com to https://www.domain.com.

I was searching quite a time in the forum with questions like this redirection-with-https/1693/3 and trying several configurations for the proxy but nothing works.

Can you please help me?
Many thanks in advance.

This is the content of haproxy.cfg

global
    maxconn 256
    lua-load /usr/local/etc/haproxy/acme-http01-webroot.lua
    chroot /jail
    ssl-default-bind-ciphers AES256+EECDH:AES256+EDH:!aNULL;
    tune.ssl.default-dh-param 4096

defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    option forwardfor
    option http-server-close
    stats enable
    stats uri /stats
    stats realm Haproxy\ Statistics

frontend http
    bind *:80
    mode http
    acl url_acme_http01 path_beg /.well-known/acme-challenge/
    http-request use-service lua.acme-http01 if METH_GET url_acme_http01
    redirect scheme https code 301 if !{ ssl_fc }

frontend ft_ssl_vip
    bind *:443 ssl crt /usr/local/etc/haproxy/certs/ no-sslv3 no-tls-tickets no-tlsv10 no-tlsv11

    rspadd Strict-Transport-Security:\ max-age=15768000

    # www server redirect from subdomain [www]
    acl www_match_acl      hdr_end(host) -i www.mydomain.com
    use_backend apptest_server if www_match_acl

backend apptest_server
    server apptest_server XXX.XXX.XXX.XXX:XXXX check
    http-request add-header X-Forwarded-Proto https if { ssl_fc }

Hi,

Well, you don’t really have anything in your frontend currently that would actually redirect requests from https://domain.com to https://www.domain.com. Your current acl www_match_acl only checks if www.domain.com is already being used.
In order to have the redirect working I would replace your frontend config (starting with the acl) with this:

acl no_www_acl ssl_fc_sni -i domain.com
http-request redirect location https://www.domain.com%[capture.req.uri] code 302 if no_www_acl
use_backend apptest_server if !no_www_acl

So, if https://domain.com was requested, then redirect to https://www.domain.com (keeping any additional path or query string elements, if present). Send to apptest_server otherwise.

This config only works with browsers supporting SNI, but pretty much everything these days does. Alternatively you could write the acl like this (note the exact match):
acl no_www_acl hdr(host) -i domain.com

Thank you so much @kkoppel.

It didn’t work. I am certainly doing something wrong. I replaced acl section as you suggested and the resulting config (below) still does not work. Do you have any idea? Do I need to keep the acl www_match_acl so people connecting directly to www can access or with your snippet this is not necessary anymore?

Thank you so much again.

global
    maxconn 256
    lua-load /usr/local/etc/haproxy/acme-http01-webroot.lua
    chroot /jail
    ssl-default-bind-ciphers AES256+EECDH:AES256+EDH:!aNULL;
    tune.ssl.default-dh-param 4096

defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    option forwardfor
    option http-server-close
    stats enable
    stats uri /stats
    stats realm Haproxy\ Statistics

frontend http
    bind *:80
    mode http
    acl url_acme_http01 path_beg /.well-known/acme-challenge/
    http-request use-service lua.acme-http01 if METH_GET url_acme_http01
    redirect scheme https code 301 if !{ ssl_fc }

frontend ft_ssl_vip
    bind *:443 ssl crt /usr/local/etc/haproxy/certs/ no-sslv3 no-tls-tickets no-tlsv10 no-tlsv11

    rspadd Strict-Transport-Security:\ max-age=15768000
    
    acl no_www_acl ssl_fc_sni -i domain.com
    http-request redirect location https://www.domain.com%[capture.req.uri] code 302 if no_www_acl
    use_backend apptest_server if !no_www_acl

backend apptest_server
    server apptest_server XXX.XXX.XXX.XXX:XXXX check
    http-request add-header X-Forwarded-Proto https if { ssl_fc }

The old acl www_match_acl is not needed anymore.
You should also make your haproxy log somewhere by adding something like this to the global section:

log /dev/log local0

and these to the defaults section:

log global
option httplog

Then you should be able to see logs appearing in your syslog, provided it is configured to write local0 logs somewhere.

Could you describe what exactly happens when you try to access https://domain.com? Is the domain.com DNS name even resolving to the same IP as www.domain.com? :slight_smile:
Does accessing https://www.domain.com still work?

Hello kkoppel,

I realized I didn’t answer.
First of all thank you for your feedback, you pointed me in the right direction.

If this can help others, my problem was that I had a “URL redirection” in the DNS that permanently redirected @ to https://www.domain.com. Changing this for a A record instead that pointed to the hosting machine, and configuring the redirection with haproxy instead was the solution.

Thanks again kkoppel,
Best