0

On our dev server we have multiple sites for multiple developers running via vhosts in Apache 2.4.6. We are on CentOS 7.

We want to redirect all http://www.site.ext.dev-username.commondomain.ext to https://www.site.ext.dev-username.commondomain.ext. Here, dev-username and site.ext can change depending on dev site and user.

We have previously used something like this:

<VirtualHost *:80>
    ServerName www.site.ext.dev-username.commondomain.ext
    Redirect permanent / https://www.site.ext.dev-username.commondomain.ext/
</VirtualHost>

But is it possible to match any (or at least wildcard) ServerName and redirect accordingly, i.e. with a backreference to a regex? Maybe with a DirectoryMatch or something instead of the vhost?

I have noticed this in the documentation (for directory and location matching), which is sadly not compatible with my version of Apache:

From 2.4.8 onwards, named groups and backreferences are captured and written to the environment with the corresponding name prefixed with "MATCH_" and in upper case. This allows elements of URLs to be referenced from within expressions and modules like mod_rewrite. In order to prevent confusion, numbered (unnamed) backreferences are ignored. Use named groups instead.

Leonard Challis
  • 23
  • 3
  • 12
  • 26
  • Possible duplicate of [Redirect, Change URLs or Redirect HTTP to HTTPS in Apache - Everything You Ever Wanted to Know About Mod\_Rewrite Rules but Were Afraid to Ask](https://serverfault.com/questions/214512/redirect-change-urls-or-redirect-http-to-https-in-apache-everything-you-ever) – Gerald Schneider Mar 04 '19 at 12:04
  • I don't think it is. – Leonard Challis Mar 04 '19 at 12:18
  • 2
    I agree - this question is about how the `ServerName` and `ServerAlias` directive works in apache, rather than how mod_rewrite works. – Jenny D Mar 04 '19 at 15:50

2 Answers2

1

With the backreferences only enabled in 2.4.8 (and me being on an earlier version) I figured an alternative solution which isn't pure apache config but works for me and may help others.

I added a new vhost config, like so:

<VirtualHost *:80>
  ServerName 000_default_http.commondomain.ext
  ServerAdmin technical@commondomain.ext

  DirectoryIndex index.html index.php
  DocumentRoot /var/www/html/000_default_http/
  <Directory /var/www/html/000_default_http/>
    AllowOverride All
    Require all granted
  </Directory>

  CustomLog "|/usr/sbin/rotatelogs -l /var/log/httpd/000_default_http%Y%m%d_web.log 86400" combined env=!image
  CustomLog "|/usr/sbin/rotatelogs -l /var/log/httpd/000_default_http%Y%m%d_image.log 86400" combined env=image
  ErrorLog "|/usr/sbin/rotatelogs -l /var/log/httpd/000_default_http%Y%m%d_error.log 86400"
</VirtualHost>

Here, ServerName doesn't matter. Because we give it a filename of 000_default_http.conf it will be taken as the default vhost. What we do need to do is make sure all our vhost configs specify:

<VirtualHost *:443>

Then, whenever we visit any site at http:// it will use the above config. I then added the following to index.php in /var/www/html/000_default_http/:

<?php
if ($_SERVER['SERVER_PORT'] == '80') {
    header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
    exit;
}

And made sure any directories were caught also, by adding a .htaccess file also:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]

So now, any url, complete with path and query string, will be redirected from http to https.

Note that if you decided you did want an explicit HTTP site (or several) alongside the HTTPS ones, that's fine. Just make sure your 000_default_http.conf comes first alphabetically out of the configs with the *:80 virtual host. If Apache matches the ServerName on these configs on port 80, it will use them, otherwise it will continue using the above vhost and redirect to the HTTPS couterpart.

Obviously you can switch out the PHP for any language of your choice. But this method allows me to not bother with a seperate .htaccess directive on all sites and/or muddying up every vhost config file for the developer configs.

That said, if someone can come up with a nicer approach that can be done solely in apache config I'd be very interested in hearing it.

Leonard Challis
  • 23
  • 3
  • 12
  • 26
1

I'm using following vhost:

<VirtualHost *:80>

    ServerName 'sub.domain.tld'

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

</VirtualHost>

This redirects every HTTP request to HTTPS with the exact path

r00tusr
  • 161
  • 1
  • 1
  • 5