Debian – Redirect non-www to www on HTTPS not working

apache-2.4debianhttps

I'm trying to configure apache server so it redirects non-www to www and http to https. This is my configuration:

000-default.conf:

<VirtualHost *:80>
    ServerName www.example.com
    ServerAlias example.com

    # non-www to www
    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^www\. [NC]
    RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [END,R=301,L]

    DocumentRoot /var/www/...

    # to https
    RewriteCond %{SERVER_NAME} =example.com [OR]
    RewriteCond %{SERVER_NAME} =www.example.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
</VirtualHost>

000-default-le-ssl.conf:

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerName www.example.com
        ServerAlias example.com

        # non-www to www
        RewriteEngine On
        RewriteCond %{HTTP_HOST} (?!^www\.)^(.+)$
        RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L]

        DocumentRoot /var/www/...

        SSLCertificateFile /etc/letsencrypt/live/www.example.com/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privkey.pem
        Include /etc/letsencrypt/options-ssl-apache.conf
    </VirtualHost>
</IfModule>

Problem is that when I access https://example.com, it does not redirect and shows me an error instead, saying that the certificate's owner does not match hostname 'example.com'. Why isn't it redirecting from https:// to https://www.?

Best Answer

When you got the SSL certificate from Let's Encrypt, did you get it for only 'www.example.com'? Let's Encrypt clients, such as certbot, only provides certs for the explicit domain names you request.

The message you're seeing is that your browser is receving a SSL certificate for a domain that doesn't match.

Before the redirect is sent to your browser, with an SSL site, your browser must create a secure tunnel between itself and the server. As part of that process, the server sends a certificate, in this case,

SSLCertificateFile /etc/letsencrypt/live/www.example.com/fullchain.pem

If that certificate includes the domain name with which you're accessing the website, all to the good, your browser will continue, and the webserver will send you the redirect response. If it doesn't match, the browser assumes that someone is up to no good, and throws an error message instead.

The easiest thing to do, if my guess as to the problem is right, would be to request an additional domain with certbot of example.com and www.example.com. It'll likely say 'this cert already exists, do you want to expand' (or similar), say yes. In any case, make sure that new cert is configured to be served from Apache.

One note, you don't need to redirect twice from http to https and no www to www. Your :80 config can be much simplified to;

 RewriteEngine on
 RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L,QSA]

I tend to use the following, just because it's shorter:

 RewriteEngine on
 RewriteRule ^(.*)$ https://www.example.com$1 [R=301,L,QSA]
Related Topic