Same server, different Apache virtual hosts, redirection does not work for one of them

apache-2.4redirectrewrite

On my server there are multiple virtual hosts configured. Two of them should have the following behaviour, so that in the end, it should always be redirected to https://www…..

for example, I put the following into the URL bar: domain1.tld

It redirects to www.domain1.tld -> redirects to -> https://www.domain1.tld

The setup looks like this…

<VirtualHost *:80>
        ServerName domain1.tld
        Redirect permanent / http://www.domain1.tld
</VirtualHost>

<VirtualHost *:80>
        ServerName www.domain1.tld

    ###### more settings ####

RewriteEngine on
RewriteCond %{SERVER_NAME} =www.domain1.tld
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>  

The other virtual host has exactly the same configuration:

<VirtualHost *:80>
        ServerName domain2.tld
        Redirect permanent / http://www.domain2.tld
</VirtualHost>

<VirtualHost *:80>
        ServerName www.domain2.tld

    #### more settings ####

RewriteEngine on
RewriteCond %{SERVER_NAME} =www.domain2.tld
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

But what happens here is very strange. When I enter www.domain2.tld into the URL bar, it will be redirected to https://www.domain2.tld successfully. But when I enter domain2.tld into the URL bar, it redirects to https://domain2.tld and I get the default "Did Not Connect: Potential Security Issue" page with the error message:

Error code: SSL_ERROR_BAD_CERT_DOMAIN

If I view the certificate, it show me the certificate from my 3rd domain configuration: subdomain1.domain1.tld. This virtual host can exists with both http and https, so the configuration looks slightly different. It has no redirection:

<VirtualHost *:80>
        ServerName subdomain1.domain1.tld

    ##### more settings ####

</VirtualHost>

But this should not be the problem. The problem is:

When I enter domain2.tld into the URL bar, Why does this domain not redirect to HTTPS properly and gets the certificate of the 3rd domain?

What is additionally to say:
domain2 is located at another domain provider (which points to my server IP), so the DNS setting looks slightly different (since the option were not the same as on my domain1 provider). Could this maybe a problem (on DNS level)?

Setup of domain1 (working):
domain1

For domain2, I can't make such settings. Instead the settings look like this:

*.domain2.tld A [IP OF MY SERVER]
ftp.domain2.tld A [IP OF MY SERVER]
domain2.tld A [IP OF MY SERVER]
mail.domain2.tld A [IP OF MY SERVER]

[UPDATE]
I also add here the SSH config of the virtual host for domain2.tld.

<IfModule mod_ssl.c>
<VirtualHost *:443>
        ServerName www.domain2.tld

    #### more settings ####

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

[UPDATE]
Just for testing, I disabled completely the domain2.tld.conf (that means the non-https site configuration) in /etc/apache2/sites-enabled (a2dissite). The behaviour should be now that only the https version works. I even restarted apache, but it's getting more confusing: The behaviour of the website is still the same. That means, when I enter www.domain2.tld into the URL bar, the site still redirects to https://www.domain2.tld. How is that possible?! Where does this redirection come from, because there is no more active rewrite condition for this? Only the site with the <VirtualHost *:443> condition is available. (And I cleaned the browser cache and data).

[UPDATE]
The confusion with this existing redirect was, that every browser somehow saves the redirect information (although they shouldn't), but I'm not able to reset this stupid behaviour by clearing the cache and data. I wonder how I can test server settings when the browser makes odd things all the time.
I also tried to narrow the problem down, but it seems the the RewriteRule and or RewriteCond of domain2.tld is not working at all. This is my current example of the domain2 config:

<VirtualHost *:80>
        ServerAdmin [myself]@gmail.com
        ServerName www.domain2.tld
        ServerAlias domain2.tld *.domain2.tld
        DocumentRoot /var/www/www.domain2.tld
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/www.domain2.tld/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/domain2/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn
        CustomLog "|/usr/bin/rotatelogs ${APACHE_LOG_DIR}/domain2/access-%Y-%m-%d.log 86400" combined
        #CustomLog ${APACHE_LOG_DIR}/access.log combined

    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>

RewriteEngine on
RewriteCond %{SERVER_NAME} =www.domain2.tld
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

If I try a complete different website als rewrite rule, it will be ignored. So there must be anything totally wrong here.

[UPDATE + SOLUTION]
Obviously all this confusion (and misconfigurations) happens, because all browsers I was using keep these stupid wrong redirects in cache I can't get rid of (at least in FF, it's still not working here, although I cleared everything). I will ask this as separate question.

The solution for both domains is Leo's answer and pretty simple:

<VirtualHost *:80>
        ServerName domain2.tld
        Redirect permanent / https://www.domain2.tld
</VirtualHost>

<VirtualHost *:80>
        ServerName www.domain2.tld
        Redirect permanent / https://www.domain2.tld
</VirtualHost>

I can confirm that this works, because I tested it with a complete virgin browser (and device) I never used before to invoke domain2.tld.
I tested it with an older Firefox on another device and it works there too.
Conclusion: The Firefox of my main machine is the only one which cannot handle the redirect. Not sure why. Ironically, this Firefox should be the one which should be able to handle this best, because I have a lot of anti-tracking configs and add-ons installed, so I get a "clean" Firefox at every startup. That's why I'm totally confused about this.

Best Answer

For what I can see, you are making a double redirect, by using a redirect + rewrite. It shouldn't be necessary to do it (and as you didn't post all the apache config files, including the ones on /etc/apache2/conf.d and sites-enabled or equivalent), you might also have a missing setting or something overwriting it regarding the SSL settings.

Try something like this for ex. domain1.tld.conf

<VirtualHost *:80>
        ServerName domain1.tld
        Redirect permanent / https://www.domain1.tld
</VirtualHost>

<VirtualHost *:80>
        ServerName www.domain1.tld
        Redirect permanent / https://www.domain1.tld
</VirtualHost>  

OR, you could even simplify it to a single VirtualHost and single file for testing using an Alias:

<VirtualHost *:80>
        ServerName domain1.tld
        ServerAlias www.domain1.tld
        Redirect permanent / https://www.domain1.tld
</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName www.domain1.tld


    ....

    SSLEngine On
    SSLCertificateFile /etc/letsencrypt/live/www.domain1.tld/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/www.domain1.tld/privkey.pem

    ...

</VirtualHost>
</IfModule>

Of course, for this to work, you must have a working HTTPS VirtualHost too, with a valid SSL certificate and the SSL and Headers modules enabled in Apache (a2enmod ssl, a2enmod headers). You should probably check this connecting directly to the HTTPS versions of the sites. If the HTTPS version is not working correctly, the redirects will fail.

Regarding your updated questions about the redirects still working after removing the configuration for the plain VirtualHost in port 80, you are probably suffering from a cache of your web browser or something like that. If you want to try the HTTPS site, and not the redirects, simply fill the URL with the whole protocol and subdomain https://www.domain1.tld, you can also use another browser (or private windows) to accomplish the cache override.

And you should always check the /var/log/apache2 log files, the access.log and error.log will be helpful in debugging the issues.

Related Topic