Search code examples
apachemod-rewrite

Apache Mod_Rewrite www to non-www Not Working


I am trying to do a Mod_Rewrite and get rid of all www. in the url. All my SSL certificates are non-www and I don't want to create SSL certs for www. subdomains. I just want to rewrite and redirect.

<VirtualHost *:80>
 ServerAdmin webmaster@localhost
 DocumentRoot /var/www/html
 ErrorLog ${APACHE_LOG_DIR}/error.log
 CustomLog ${APACHE_LOG_DIR}/access.log combined
 RewriteEngine on
 RewriteCond %{HTTPS} off
 RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI}
 RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
 RewriteRule ^ https://%1%{REQUEST_URI} [END,L,R=permanent]
</VirtualHost>
<Directory /var/www>
 Options Indexes FollowSymLinks
 AllowOverride All
 Require all granted
</Directory>

Followed by sudo systemctl restart apache2 but with testing, the www. is still persistent.


Solution

  • <VirtualHost *:80>
     ServerAdmin webmaster@localhost
     DocumentRoot /var/www/html
     ErrorLog ${APACHE_LOG_DIR}/error.log
     CustomLog ${APACHE_LOG_DIR}/access.log combined
     RewriteEngine on
     RewriteCond %{HTTPS} off
     RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI}
     RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
     RewriteRule ^ https://%1%{REQUEST_URI} [END,L,R=permanent]
    </VirtualHost>
    

    The rule you've posted is in the <VirtualHost *:80> container so it only applies to HTTP (non-HTTPS) traffic. However, it will never be processed anyway since you are redirecting to HTTPS on the "same host" in the immediately preceding rule. You need to reverse these two rules if you wish to prioritise the removal of the www subdomain (when accessing over HTTP). (Oridinarily, this would only need to be done in the <VirtualHost *:443> (HTTPS) container.)

    (However, if you wish to implement HSTS then the rules are already in the correct order. Although you are missing the flags argument from the first rule.)

    However, you are also missing the ServerName and ServerAlias directives from this vHost container so it's unclear whether the www subdomain would even resolve here (or what domain resolves here for that matter).

    For example:

     ServerName example.com
     ServerAlias www.example.com
    
     :
    
     RewriteEngine on
     RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
     RewriteRule ^ https://%1%{REQUEST_URI} [R=permanent,L]
     RewriteCond %{HTTPS} off
     RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    

    However, if you wish to redirect HTTPS traffic from www to non-www then you have no choice but to make sure the SSL cert covers the www subdomain as well (otherwise the request won't even reach your server). And the relevant rule to remove www would need to be repeated in the <VirtualHost *:443> (HTTPS) container.