Securing your Ghost blog admin site

In the previous post we set up a Ghost blog on Debian 6 behind an Apache web server. We also configured the Forever npm module to keep the blog up and running continuously. Today we will secure the admin interface to the ghost blog.

Ghost's admin interface is hosted under the http://{yourblog}/ghost url of your blog and does not run over https by default. As we will be logging in and submitting our admin password we need to secure this.

Rather than run the complete blog over https I have decided to only secure the /ghost domain. We'll use a simple url rewrite technique in Apache to achieve this.

Create and install your SSL certificates

Our first step is to create the SSL certificates that will be used in order to secure the site. Create the directory that will store the keys:

> su
> ***********
> mkdir -p /etc/apache2/ssl/apericore.com

As I'm currently only planning to use https for the admin functions of the blog I'll create a self signed certificate rather than purchasing from a Certificate Authority. So lets ensure we have the required dependencies and go ahead and create the certificate using OpenSSL:

> apt-get update
> apt-get upgrade
> apt-get install openssl
> openssl req -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apericore.com/apache.pem -keyout /etc/apache2/ssl/apericore.com/apache.key

Answer all the questions, remembering to use your domain name for the Common Name, and as we have specified -nodes you will not be asked to provide a passphrase. We now have the self-signed certificate that will expire after 365 days (-days) and server key ready to be installed in our Apache Web Server.

Configure your Apache Virtual Host for SSL

Ensure Apache has the ssl module enabled:

> a2enmod ssl

Update /etc/apache2/ports.conf to listen on port 443 by adding the following:

<IfModule mod_ssl.c>
    Listen 443
</IfModule>

<IfModule mod_gnutls.c>
    Listen 443
</IfModule>

Now edit the virtual host configuration for your site under /etc/apache2/sites-available to add the SSL virtual host listening on port 443:

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerAdmin admin@apericore.com
    ServerName blog.apericore.com
    ServerAlias blog.apericore.org
    DocumentRoot /var/www/ghost/blog.apericore/htdocs/

    # LogFiles
    ErrorLog /var/www/ghost/blog.apericore/logs/error.log
    CustomLog /var/www/ghost/blog.apericore/logs/access.log combined

    ProxyRequests Off
    ProxyPass / http://127.0.0.1:2368/
    ProxyPassReverse / http://127.0.0.1:2368/
    ProxyPreserveHost On
    <Proxy *>
        Order deny,allow
        Allow from 127.0.0.1
    </Proxy>
    
    # SSL Configuration
    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/apericore.com/apache.pem
    SSLCertificateKeyFile /etc/apache2/ssl/apericore.com/apache.key
</VirtualHost>
</IfModule>

Restart Apache and you now have your site optionally available on https:

> /etc/init.d/apache2 restart

You can check the config by launching your site with the https protocol rather than http, for example https://blog.apericore.com. N.B with most browsers you will get a warning message when you try to launch the https site as the certificate is self signed and not trusted. As we are only using this for our own admin purposes we can accept this warning and proceed. Obviously if we were doing this to be used by the public we'd want to get a signed certificate from an appropriate authority.

Forcing your Ghost Admin site to use https

Now that we have Apache configured for SSL we will force all traffic to /ghost to be run over https by using the mod_rewrite module. Enable the module:

> a2enmod rewrite

Now update you virtual host configuration file under /etc/apache2/sites-available to redirect any traffic to http://yourblog/ghost to https://yourblog/ghost by adding the following to your non SSL (*:80) virtual host:

#
# Rewrite rules
#
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/?ghost/(.*) https://%{SERVER_NAME}/ghost/$1 [R,L]

This directive uses a rewrite rule to ensure anything under /ghost will have its url rewritten to be https. Again restart Apache to allow the changes to take affect:

> /etc/init.d/apache2 restart

You can now test to ensure that trying to access http://blog.apericore.com/ghost will force you to https://blog.apericore.com/ghost for a SSL connection. Whereas you can still access http://blog.apericore.com without being forced to use https.

Conclusion

We now have a fully functioning and secure Ghost admin site for our company blog.