1

I want to redirect HTTP requests to my website to HTTPS when the client browser supports it. My web server is lighttpd.

a3nm
  • 8,978
  • 5
  • 28
  • 36

2 Answers2

1

This is how I did it manually, using the Upgrade-Insecure-Requests header. I'm sharing it because I didn't find documentation about this with lighttpd, but it seems to work.

In the lighttpd configuration for the domain, add the following:

$HTTP["host"] =~ "^example\.com$" {
        $HTTP["scheme"] == "http" {
                $REQUEST_HEADER["Upgrade-Insecure-Requests"] == "1" {
                        # Follows https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade-Insecure-Requests
                        # Adding the header only works if mod_setenv is loaded before mod_redirect in the server config!
                        # (See https://redmine.lighttpd.net/issues/1895)
                        setenv.add-response-header = (
                            "Vary" => "Upgrade-Insecure-Requests" 
                          )
                        url.redirect-code = 307
                        url.redirect = ("/(.*)" => "https://example.com/$1")
                }
        }
        # ... any extra configuration for domain example.com ...
}

And restart lighttpd for the change to take effect.

Note: this requires mod_setenv and mod_redirect to be loaded, and assumes that no other headers need to be sent as part of the redirect response.

a3nm
  • 8,978
  • 5
  • 28
  • 36
  • Or use ```url.redirect = (".*" => "https://%0$0")``` instead and make it independent of the domain name. – mesr Jul 30 '22 at 02:04
  • I agree something like this would be better, but unfortunately I just tested and it does not work, I get `Location: https:///` – a3nm Jul 30 '22 at 21:29
  • True, my mistake. The ```%0``` refers to regex match in the enclosing pattern-matching block (the ```=~``` operator). For example this will redirect all hosts to HTTPS: ```$HTTP["host"] =~ ".*" { url.redirect = (".*" => "https://%0$0") }```. It may need fine-tuning to work in particular situations. See https://stackoverflow.com/questions/38556625/what-is-0-and-0-in-lighttpd-configuration and https://wiki.archlinux.org/title/lighttpd#Redirect_http_requests_to_https. – mesr Jul 31 '22 at 12:00
  • Thanks for explaining. Somehow %0 does not seem to work, and %1 also didn't work even when adding parentheses around the domain name in `$HTTP["host"] =~ "^example\.com$" {`, I'm not sure why. – a3nm Aug 01 '22 at 15:39
  • I can't seem to find good documentation on this. It could be that the inner ```$HTTP["scheme"] == "http"``` block shadows the outer ```$HTTP["host"] =~ "^example\.com$"```. Maybe inverting them would work? – mesr Aug 01 '22 at 15:47
1

The official source for lighttpd documentation has had the following wiki page since 2007: https://wiki.lighttpd.net/HowToRedirectHttpToHttps

In modern versions of lighttpd:

server.modules += ("mod_redirect")

$HTTP["scheme"] == "http" {
    url.redirect = ("" => "https://${url.authority}${url.path}${qsa}")
    url.redirect-code = 308
}
gstrauss
  • 171
  • 1
  • Interesting, thanks! That said I prefer to only do this when the `Upgrade-Insecure-Requests` header is there. – a3nm Jun 16 '23 at 08:33