Category: SysAdmin


DRY in Apache HTTP & HTTPS VirtualHosts

On a number of occasions I have needed to make a site available via both HTTP and HTTPS which can result in creating two almost identical VirtualHost stanzas. The HTTPS stanza usually ends up being a copy & paste of the HTTP stanza with the SSL certificate stuff tacked on to the end. This means you generally end up with a file that is something like the following:

# file: /etc/apache2/sites-available/site.example.com.conf

<VirtualHost *:80>
    ServerName    site.example.com
    ServerAdmin   webmaster@example.com
    DocumentRoot  /var/www/site
    ErrorLog      /var/log/apache2/site-error_log
    CustomLog     /var/log/apache2/site-access_log  vhost_combined

    # ... some rewrite rules, ACLs, etc ...
</VirtualHost>

<VirtualHost *:443>
    ServerName    site.example.com
    ServerAdmin   webmaster@example.com
    DocumentRoot  /var/www/site
    ErrorLog      /var/log/apache2/site-error_log
    CustomLog     /var/log/apache2/site-access_log  vhost_combined

    # ... duplicate rewrite rules, ACLs, etc ...

    SSLEngine  On
    SSLCertificateFile     ssl/crt/wc.example.com.crt
    SSLCertificateKeyFile  ssl/key/wc.example.com.key
</VirtualHost>

This method tends to break the "don't repeat yourself" (DRY) principle and can lead to inconsistencies if you make a typo, or forget to make changes to both stanzas. One method I have found to overcome this is to make use of the Include directive.

The first step is to take all of the configuration settings that are common to both the HTTP and HTTPS stanzas and place them in a new file:

# file: /etc/apache2/sites-include/site.example.com.conf

ServerName    site.example.com
ServerAdmin   webmaster@example.com
DocumentRoot  /var/www/site
ErrorLog      /var/log/apache2/site-error_log
CustomLog     /var/log/apache2/site-access_log  vhost_combined

# ... some rewrite rules, ACLs, etc ...

Note: I generally use Debian systems which have the convention of storing VirtualHost configuration files in /etc/apache2/sites-available, so I like to keep these common setting files in /etc/apache2/sites-include.

You can then Include this common setting file in both of your VirtualHost stanzas:

# file: /etc/apache2/sites-available/site.example.com.conf

<VirtualHost *:80>
    Include  sites-include/site.example.com.conf
</VirtualHost>

<VirtualHost *:443>
    Include  sites-include/site.example.com.conf

    SSLEngine  On
    SSLCertificateFile     ssl/crt/wc.example.com.crt
    SSLCertificateKeyFile  ssl/key/wc.example.com.key
</VirtualHost>

Using this method you only need to make changes in one location (sites-include/site.example.com.conf) and they will be applied to both HTTP and HTTPS.

You can also do something similar if you use the same wildcard SSL certificate in a number of different VirtualHost files. First move the common SSL settings into a new file:

# file: /etc/apache2/ssl/site.example.com.conf

SSLEngine  On
SSLCertificateFile     ssl/crt/wc.example.com.crt
SSLCertificateKeyFile  ssl/key/wc.example.com.key

Then Include the SSL settings file in your HTTPS VirtualHost stanza:

# file: /etc/apache2/sites-available/site.example.com.conf

<VirtualHost *:80>
    Include  sites-include/site.example.com.conf
</VirtualHost>

<VirtualHost *:443>
    Include  sites-include/site.example.com.conf
    Include  ssl/wc.example.com.conf
</VirtualHost>

This can be particularly useful if you have a number of extra SSL settings that need to be configured.

Environment Variables of a Running Process

When creating init scripts or trying to debug services on Linux it can be handy to know what the environment variables are for a running process. It turns out that you can retrieve these variables from /proc (along with lots of other rather useful information). The environment variables are located in /proc/$PID/environ where $PID is the ID of the process we are interested in.

cat can be used to print out the environment variables, but the entries are separated by null characters which makes them a bit difficult to read. To view the entries in a slightly more legible form we can pipe the output through tr to replace the null characters with new line characters:

cat /proc/$PID/environ | tr '\000' '\n'

References: