How do I permanently redirect www.subdomain to subdomain when using Wildcard SSL

August 29, 2015 15.3k views
Apache

I've setup a staging server for client viewing using a URL structure of subdomain.domain.tld (e.g.: client-abc.my-staging-site.com, client-xyz.my-staging-site.com, or whatever.my-staging-site.com).

  • subdomain = "client site name"
  • domain.tld = "my staging domain with top-level-domain."

Please note that I've already installed a Wildcard SSL.

Thus far, I can get www, none-www, and none-ssl (i.e., http) to redirect to none-www with ssl (i.e., https) within my apache vhost file (see below).

I.E., I have the following URLs redirecting successfully to https://subdomain.domain.tld/…

Which is accomplished via this apache vhost file, subdomain.domain.tld.conf:

<VirtualHost *:80>
    # vhost domain with www in front of subdomain
    ServerName www.subdomain.domain.tld

    # permanent redirect www to none-www and http to https
    # must have a second <VirtualHost *:80> set up
    # change https to http if there is no SSL certificate
    # this is faster than .htaccess;
    Redirect permanent / https://subdomain.domain.tld/
</VirtualHost>

<VirtualHost *:80>
    # vhost domain without www in front of subdomain
    ServerName subdomain.domain.tld

    # rewrite rules enabled
    RewriteEngine On

    # redirect http to https
    # comment out if there is no SSL certificate
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [QSA,R=301,L]

    #…all other normal config stuff goes here…

</VirtualHost>

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        # vhost domain
        ServerName subdomain.domain.tld

        #…all other normal config stuff goes here; including ssl stuff…

    </VirtualHost>
</IfModule>

However I can not get the following to redirect to https://subdomain.domain.tld/…

I've tried using rewrite rules in both the vhost conf file and .htaccess file, e.g.,…

# rewrite rules
RewriteEngine On

# remove the www on sub-domains; however because the ssl is called before the rewrite rules
# the browser will complain; if using a wildcard ssl, only the first sub-domain level 
# is supported the workaround could be to add every virtual host name in the Subject Alternative 
# Name (SAN) extension, the major problem being that the certificate will need to be reissued 
# whenever a new virtual server is added; nonetheless, if the end-user accepts the security 
# risk and proceeds, the url will be rewriting to the none-www which is secure
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.*)$ [NC]
RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [QSA,R=301,L]

Please also note, for some reason, when accepting the browser warning for security risk the browser retains the URL of https://www.subdomain.domain.tld/ (not good) and displays the files from the very first vhost on the server (also not good). If I can't redirect, at least help me figure out how to disable this odd result.

Any suggestions would be welcome. Thanks in advance.

2 comments
  • I also tried this…

    I replaced the RewriteCond in the vhost conf file from this (within the <VirtualHost *:443> section):

    RewriteCond %{HTTP_HOST} ^(?:www\.)?(.*)$ [NC]
    

    To this:

    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    

    And it seems to be working now…can someone confirm that this is valid through duplication?

    Here's a copy of a vhost conf file:

    <VirtualHost *:80>
    
        # vhost domain with www in front of subdomain
        ServerName www.subdomain.domain.tld
    
        # permanent redirect www to none-www and http to https
        # must have a second <VirtualHost *:80> set up
        # change https to http if there is no SSL certificate
        # this is faster than .htaccess;
        Redirect permanent / https://subdomain.domain.tld/
    
    </VirtualHost>
    
    <VirtualHost *:80>
    
        # vhost domain without www in front of subdomain
        ServerName subdomain.domain.tld
    
        # server admin email
        ServerAdmin hostmaster@domain.tld
    
        # vhost folder
        DocumentRoot "/var/www/subdomain"
    
        # vhost folder permissions
        <Directory "/var/www/subdomain">
            Options Indexes FollowSymLinks MultiViews
            AllowOverride all
            Order allow,deny
            Allow from all
        </Directory>
    
        # vhost error logging; on Ubuntu APACHE_LOG_DIR = /var/log/apache2
        ErrorLog ${APACHE_LOG_DIR}/subdomain.domain.tld-error.log
        CustomLog ${APACHE_LOG_DIR}/subdomain.domain.tld-access.log combined
    
        # vhost environment variables
        SetEnv DB_NAME "subdomain"
        SetEnv DB_USER "subdomain"
        SetEnv DB_PASS "random_pass"
        SetEnv DB_HOST "localhost"
        SetEnv DB_PRET "wp_"
    
        # compression rules
        SetOutputFilter DEFLATE
        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|ico|png)$ \ no-gzip dont-vary
        SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ \no-gzip dont-vary
        SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary
    
        # broswer compressing adjustments
        BrowserMatch ^Mozilla/4 gzip-only-text/html
        BrowserMatch ^Mozilla/4\.0[678] no-gzip
        BrowserMatch \bMSIE !no-gzip !gzip-only-text/htmld
    
        # rewrite rules enabled
        RewriteEngine On
    
        # redirect www to none-www
        RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
        RewriteRule ^(.*)$ http://%1%{REQUEST_URI} [QSA,R=301,L]
    
        # redirect http to https
        # comment out if there is not SSL certificate
        RewriteCond %{HTTPS} off
        RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [QSA,R=301,L]
    
     </VirtualHost>
    
    <IfModule mod_ssl.c>
        <VirtualHost *:443>
    
            # vhost domain without www in front of subdomain
            ServerName subdomain.domain.tld
    
            # server admin email
            ServerAdmin hostmaster@domain.tld
    
            # vhost folder
            DocumentRoot "/var/www/subdomain"
    
            # vhost folder permissions
            <Directory "/var/www/subdomain">
                Options Indexes FollowSymLinks MultiViews
                AllowOverride all
                Order allow,deny
                Allow from all
            </Directory>
    
            # vhost error logging; on Ubuntu APACHE_LOG_DIR = /var/log/apache2
            ErrorLog ${APACHE_LOG_DIR}/subdomain.domain.tld-ssl-error.log
            CustomLog ${APACHE_LOG_DIR}/subdomain.domain.tld-ssl-access.log combined
    
            # vhost environment variables
            SetEnv DB_NAME "subdomain"
            SetEnv DB_USER "subdomain"
            SetEnv DB_PASS "random_pass"
            SetEnv DB_HOST "localhost"
            SetEnv DB_PRET "wp_"
    
            # compression rules
            SetOutputFilter DEFLATE
            SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|ico|png)$ \ no-gzip dont-vary
            SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ \no-gzip dont-vary
            SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary
    
            # broswer compressing adjustments
            BrowserMatch ^Mozilla/4 gzip-only-text/html
            BrowserMatch ^Mozilla/4\.0[678] no-gzip
            BrowserMatch \bMSIE !no-gzip !gzip-only-text/htmld
    
            # rewrite rules enabled
            RewriteEngine On
    
            # remove the www on sub-domains; however because the ssl is called before the rewrite rules
            # the browser will complain; if using a wildcard ssl, only the first sub-domain level 
            # is supported the workaround could be to add every virtual host name in the Subject Alternative 
            # Name (SAN) extension, the major problem being that the certificate will need to be reissued 
            # whenever a new virtual server is added; nonetheless, if the end-user accepts the security 
            # risk and proceeds, the url will be rewriting to the none-www which is secure
            RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
            RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [QSA,R=301,L]
    
            # enable/disable ssl for this virtual host
            SSLEngine on
    
            # ssl certificate files + bundle file; comment out if using self-signed certificate; see next section
            SSLCertificateKeyFile   /etc/ssl/certs/domain.key
            SSLCertificateFile      /etc/ssl/certs/domain.crt
            SSLCertificateChainFile /etc/ssl/certs/domain.ca-bundle
    
            # self-signed (snakeoil) certificate files; comment out if using a third-party certificate; see previous
            #SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
            #SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
    
            # SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
            <FilesMatch \.(cgi|shtml|phtml|php)$>
                SSLOptions +StdEnvVars
            </FilesMatch>
            <Directory /usr/lib/cgi-bin>
                SSLOptions +StdEnvVars
            </Directory>
    
            # SSL Protocol Adjustments:
            BrowserMatch \"MSIE [2-6]\" \\
            nokeepalive ssl-unclean-shutdown \\
            downgrade-1.0 force-response-1.0
    
            # MSIE 7 and newer should be able to use keepalive
            BrowserMatch \"MSIE [17-9]\" ssl-unclean-shutdown
    
        </VirtualHost>
    </IfModule>
    # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
    

    Thanks.

  • Hello,

    Yes that is the proper way to handle the rewrite rule.

1 Answer

If the virtualhost with the redirect is not being called when you use www.subdomain.domain.tld you may want to add a ServerAlias directive under the ServerName for that virtualhost.

ServerAlias www.subdomain.domain.tld

Since all traffic that matches that Virtualhost is redirected to the correct place this should solve the problem as it will be the first VirtualHost that will match based on the requested name.

Have another answer? Share your knowledge.