77
votes

On my apache server I'd like to be able to redirect all incoming http requests to the equivalent https request. The catch is that I'd like to be able to do this for my default virtual host without specifying the ServerName and have the redirect work with whatever server name appeared in the request url. I'm hoping for something like this:

NameVirtualHost *:80
<VirtualHost *:80>
    RedirectPermanent / https://%{SERVER_NAME}/
    ...
</VirtualHost>

Is this possible using Redirect or will I have to resort to Rewrite?

4

4 Answers

112
votes

Try adding this in your vhost config:

RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
84
votes

Both works fine. But according to the Apache docs you should avoid using mod_rewrite for simple redirections, and use Redirect instead. So according to them, you should preferably do:

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

<VirtualHost *:443>
    ServerName www.example.com
    # ... SSL configuration goes here
</VirtualHost>

The first / after Redirect is the url, the second part is where it should be redirected.

You can also use it to redirect URLs to a subdomain: Redirect /one/ http://one.example.com/

38
votes

This is the complete way to omit unneeded redirects, too ;)

These rules are intended to be used in .htaccess files, as a RewriteRule in a *:80 VirtualHost entry needs no Conditions.

RewriteEngine on
RewriteCond %{HTTPS} off [OR] 
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R=301,L]

Eplanations:

RewriteEngine on

==> enable the engine at all

RewriteCond %{HTTPS} off [OR]

==> match on non-https connections, or (not setting [OR] would cause an implicit AND !)

RewriteCond %{HTTP:X-Forwarded-Proto} !https

==> match on forwarded connections (proxy, loadbalancer, etc.) without https

RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R=301,L]

==> if one of both Conditions match, do the rewrite of the whole URL, sending a 301 to have this 'learned' by the client (some do, some don't) and the L for the last rule.

0
votes

I have use mkcert to create infinites *.dev.net subdomains & localhost with valid HTTPS/SSL certs (Windows 10 XAMPP & Linux Debian 10 Apache2)

I create the certs on Windows with mkcert v1.4.0 (execute CMD as Administrator):

mkcert -install
mkcert localhost "*.dev.net"

This create in Windows 10 this files (I will install it first in Windows 10 XAMPP)

localhost+1.pem
localhost+1-key.pem

Overwrite the XAMPP default certs:

copy "localhost+1.pem" C:\xampp\apache\conf\ssl.crt\server.crt
copy "localhost+1-key.pem"  C:\xampp\apache\conf\ssl.key\server.key

Now, in Apache2 for Debian 10, activate SSL & vhost_alias

a2enmod vhosts_alias
a2enmod ssl
a2ensite default-ssl
systemctl restart apache2

For vhost_alias add this Apache2 config:

nano /etc/apache2/sites-available/999-vhosts_alias.conf

With this content:

<VirtualHost *:80>
   UseCanonicalName Off
   ServerAlias *.dev.net
   VirtualDocumentRoot "/var/www/html/%0/"
</VirtualHost>

Add the site:

a2ensite 999-vhosts_alias

Copy the certs to /root/mkcert by SSH and let overwrite the Debian ones:

systemctl stop apache2

mv /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/ssl/certs/ssl-cert-snakeoil.pem.bak
mv /etc/ssl/private/ssl-cert-snakeoil.key /etc/ssl/private/ssl-cert-snakeoil.key.bak

cp "localhost+1.pem" /etc/ssl/certs/ssl-cert-snakeoil.pem
cp "localhost+1-key.pem" /etc/ssl/private/ssl-cert-snakeoil.key

chown root:ssl-cert /etc/ssl/private/ssl-cert-snakeoil.key
chmod 640 /etc/ssl/private/ssl-cert-snakeoil.key

systemctl start apache2

Edit the SSL config

nano /etc/apache2/sites-enabled/default-ssl.conf

At the start edit the file with this content:

<IfModule mod_ssl.c>
    <VirtualHost *:443>

            UseCanonicalName Off
            ServerAlias *.dev.net
            ServerAdmin webmaster@localhost

            # DocumentRoot /var/www/html/
            VirtualDocumentRoot /var/www/html/%0/

...

Last restart:

systemctl restart apache2

NOTE: donĀ“t forget to create the folders for your subdomains in /var/www/html/

/var/www/html/subdomain1.dev.net
/var/www/html/subdomain2.dev.net
/var/www/html/subdomain3.dev.net