Wrangling HTTP and HTTPS versions of the same Apache virtual host

March 11, 2021

I recently tweeted:

It has been '0' days since I have been bitten by the fact that in Apache you usually have separate configurations for the HTTP and the HTTPS version of a site even if you want them the same, so you can change the wrong one when testing and be confused when a fix doesn't work.

(This was part of discovering how not to use RewriteRule in a reverse proxy.)

We have a bunch of named virtual hosts that we have set up for people; many although not all of them are reverse proxies to user run web servers. Increasingly people ask for (and we provide) both a HTTP and a HTTPS version of the site. The most natural and least complicated way to do this is to have a big Apache configuration file with all of our named vhosts and to repeat the configuration for a host between the HTTP and HTTPS versions.

This tends to look something like:

<VirtualHost 128.100.X.XX:80>
  ServerName ahost.cs.<etc>

  [all of ahost's configuration]
</VirtualHost>

<VirtualHost 128.100.X.XX:443>
  ServerName ahost.cs.<etc>
  SSLEngine on
  [TLS certificate settings]

  [all of ahost's configuration]
</VirtualHost>

When you do this and you have some RewriteRule settings or something complex that you're trying to fix, it's possible to accidentally change the HTTPS version of the site but not the HTTP version and then test against the HTTP version. Or vice versa. This is made easier when the site's configuration is big enough to push the other version of the site off your editor screen.

One answer is that we're shooting both ourselves and other people in the foot by even having a meaningful HTTP site here. If people ask for a HTTPS site, we should default to making their HTTP site redirect everything to the HTTPS one (and probably the HTTPS one should set a HSTS header). This would make the mistake impossible to commit, because the only site with real configuration would be the HTTPS one.

Failing that, what I would like is some way to have the same block apply to both the HTTP and HTTPS virtual host. In my imagination, it would look something like:

<VirtualHost 128.100.X.XX:80 128.100.X.XX:443>
  ServerName ahost.cs.<etc>

  <IfPort :443>
    SSLEngine on
    [TLS certificate settings]
  </IfPort>

  [all of ahost's configuration]
</VirtualHost>

(Apache 2.4 has an <If> directive, but my understanding is that it takes effect too late to do this.)

One possible answer is to put the vhost's real configuration in a separate file that is Include'd in both. Unfortunately I don't think this scales for us; we don't like splitting things up this way in general, and we have enough virtual hosts where the HTTP and HTTPS versions are different that they would be exceptions in this scheme in one way or another. We'd prefer to keep everything in one file where it's at least readily visible all at once.

Another possible answer is mod_macro (first brought to my attention by @ch2500). Unfortunately as far as I can see this involves adding an extra configuration block for each such virtual host (for the <Macro> definition), and makes the actual HTTP and HTTPS <VirtualHost> blocks more magical and harder to read. I'm not all that enthused and my co-workers would almost certainly reject this as too much magic even if I proposed it.

(Some but not all of our virtual hosts could be done with a common <Macro> template, but that would create even more magic.)


Comments on this page:

By Brian at 2021-03-12 13:36:48:

The solution to this is to either use Include, as you mentioned, or to make the HTTP site do nothing but redirect to HTTPS. Once it has been determined that a site should use HTTPS, what reason is there to keep HTTP around? Many would consider that a security issue.

Once you get into using macros and other complicated things, I think you end up making something more complicated than it needs to be when a simpler solution already exists.

Written on 11 March 2021.
« What OpenSSH sshd logs when a session disconnects (on Linux)
Prometheus and the case of the stuck metrics »

Page tools: View Source, View Normal.
Search:
Login: Password:

Last modified: Thu Mar 11 23:24:38 2021
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.