Force https:// and www. with virtual host apache2

Solution 1:

This worked for me, you can test it on my domain if you like.

<VirtualHost *:80>
    ServerName freesoftwareservers.com
    ServerAlias *.freesoftwareservers.com
    Redirect / https://www.freesoftwareservers.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName freesoftwareservers.com
    ServerAlias *.freesoftwareservers.com

http://domain.com

http://www.domain.com

https://domain.com

I had issues re-implementing this, and found that if I deleted 000-default.conf symlink from /sites-enabled it worked. Not sure whats the deal, but I have 0 other DNS records on the DNS side and my Apache does all the redirecting and it works.

Solution 2:

You need three redirects to do what you want:

http://example.com to https://www.example.com

http://www.example.com to https://www.example.com

https://example.com to https://www.example.com

The first two are from port 80 plain HTTP so you have a VirtualHost for them. You can make a VirtualHost section apply to more than one hostname (www.example.com and example.com) by having a ServerAlias section:

# Redirect http://example.com and http://www.example.com to main site
<VirtualHost *:80>
  ServerName www.example.com
  ServerAlias example.com

  Redirect / https://www.example.com/
</VirtualHost >

Then, you need a VirtualHost for your https://example.com only. HTTPS uses port 443:

# Redirect https://example.com to main site
<VirtualHost *:443>
  ServerName example.com

  Redirect / https://www.example.com/
</VirtualHost >

Note: you'll need to set up your SSL settings there too, with a certificate that supports BOTH the domain with and without the "www.". Setting up your SSL settings is outside the scope of this question. (Added info: these can be two separate certificates if you like; it's becoming more common to have lots of separate certs now we have things like Let's Encrypt and SNI)

If you don't have an SSL certificate that supports your domain without the "www." then you won't be able to do the redirect from https://example.com. The redirect will only happen after the browser checks the certificate. The user would be presented with a mismatched certificate error.

Then, finally, you need your VirtualHost section for the "valid" site: HTTPS (port 443) on www.example.com:

# Main site
<VirtualHost *:443>
  ServerName www.example.com

  # Put all your configuration for this site here

</VirtualHost >

Once you have tested your redirects and you're happy they are working, you can make them permanent by specifying the 301 status in the redirect (change Redirect / https://www.example.com/ to Redirect 301 / https://www.example.com/ everywhere), and by enabling HSTS which forces users' browsers to remember the preference for HTTPS.

Solution 3:

To add to thomasrutter's answer, I still had a problem when I was doing what he suggested. Sometimes you may need to add in the SSL info to the https://example.com virtual host. For instance when you're using SNI to allow multiple ssl certificates per ipaddress.

With out it you may get the ssl_error_rx_record_too_long error, since the server will be returning plain text to the https request.

# Redirect https://example.com to main site
<VirtualHost *:443>
  ServerName example.com
  Redirect / https://www.example.com/

  #for Apache Old Style (Valid on Apache <= 2.4.8) - just add in whats needed for your version
  SSLEngine on
  SSLCertificateFile        "your certificate file.crt"
  SSLCertificateKeyFile     "your key file.key"
  SSLCertificateChainFile   "your chain file.crt"
</VirtualHost >