Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

virtual host force https and redirect www to non-www, but no other subdomains

This is essentially the same question as htaccess force https and redirect www to non-www, but no other subdomains (i.e., I want to configure Apache to redirect all non-HTTPS and/or "www" URLs to HTTPS non-www URLs), but I want to configure Apache via a Virtual Host rather than an .htaccess file (since I read that avoiding .htaccess has some benefits).

I was able to get the following answer to work when using an .htaccess file: https://stackoverflow.com/a/34333450/1468130 But it did not work when I tried transferring that answer's configuration to my Virtual Hosts configuration; "https://www.domain.com" never redirected to "https://domain.com".

I read up on the differences between .htaccess and Virtual Host .conf files, and found this http://tltech.com/info/rewriterule-in-htaccess-vs-httpd-conf/ and this: https://www.digitalocean.com/community/questions/can-you-use-virtual-host-config-conf-to-redirect-www-domain-to-non-www?answer=15129 which seemed to hint that I could just wrap the configuration in a <Directory> block and it would work. Unfortunately, it doesn't ("https://www.domain.com" is still never redirected to "https://domain.com"), so I'm wondering if the Internet knew what I was doing wrong:

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

        ServerAdmin [email protected]
        DocumentRoot /var/www/domain.com/

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        <Directory /var/www/domain.com/>
                RewriteEngine On

                # match any URL with www and rewrite it to https without the www
                RewriteCond %{HTTP_HOST} ^(www\.)(.*) [NC]
                RewriteRule (.*) https://%2%{REQUEST_URI} [L,R=301]

                # match urls that are non https (without the www)
                RewriteCond %{HTTPS} off
                RewriteCond %{HTTP_HOST} !^(www\.)(.*) [NC]
                RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
        </Directory>
</VirtualHost>

I've also tried configuring <VirtualHost *:443> as Dusan Bajic suggested in the comments, but that has no effect either; https://www.domain.com still won't redirect to https://domain.com:

<VirtualHost *:443>
        ServerName domain.com
        ServerAlias www.domain.com

        ServerAdmin [email protected]
        DocumentRoot /var/www/domain.com/

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        SSLCertificateFile /etc/letsencrypt/live/domain.com/cert.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/domain.com/privkey.pem
        Include /etc/letsencrypt/options-ssl-apache.conf
        SSLCertificateChainFile /etc/letsencrypt/live/domain.com/chain.pem

        <Directory /var/www/domain.com/>
                RewriteEngine On

                # match any URL with www and rewrite it to https without the www
                RewriteCond %{HTTP_HOST} ^(www\.)(.*) [NC]
                RewriteRule (.*) https://%2%{REQUEST_URI} [L,R=301]
        </Directory>
</VirtualHost>

Also per the comments, I have tried the above *:443 configuration paired with a *:80 configuration with the <Directory> block changed to only redirect HTTP to HTTPS. But when I do that, "www" never gets removed.

<Directory /var/www/paradoxmayhem.com/>
        RewriteEngine On

        RewriteCond %{SERVER_NAME} =www.paradoxmayhem.com [OR]
        RewriteCond %{SERVER_NAME} =paradoxmayhem.com
        RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
</Directory>
like image 732
Jackson Avatar asked Mar 12 '23 05:03

Jackson


1 Answers

Got it! Apparently, when I used letsencrypt (certbot) to configure SSL, it automatically created another virtual host file (at /etc/apache2/sites-enabled/domain.com-le-ssl.conf), which has its own definition for the domain.com *:443 Virtual Host, and seems to have taken precedence over any of the *:443 configuration I tried to set up before. I added the following code to the -le-ssl.conf file, and now my redirects finally work in all the cases I desired, using 100% Apache Virtual Host configuration:

<Directory /var/www/domain.com/>
        RewriteEngine On

        # match any URL with www and rewrite it to https without the www
        RewriteCond %{HTTP_HOST} ^(www\.)(.*) [NC]
        RewriteRule (.*) https://%2%{REQUEST_URI} [L,R=301]
</Directory>
like image 129
Jackson Avatar answered Apr 06 '23 09:04

Jackson