Ghost is a beautiful blogging platform built upon the exciting Node.js technology. Well, exciting only in the mind of stupid geeks that never escaped the cellar their parents locked them in. But cellar dwelling geeks are not today's topic. Technology blogs chasing advertisement clicking nuts even described Ghost as beautiful long before John O’Nolan - author of Ghost - wrote a single line of code.
Excuse me thus for being a bit sceptical, so please do stay away from technology blogs because one day, the parents of the authors will be sober up and find themselves in dire need of having a bottle of wine. That’s when they go down into the cellar and discover that their geek son hacked into their internet and pretends to understand what makes the world go round. This will get pretty ugly real fast.
A few breakfasts ago, Ghost was released to some idiots that supported the effort on Kickstarter because they just broke up with their girlfriend and suddenly had some money left at the end of the day. By chance there was none of those nice emails from any gentleman from Nigeria to give their bank data so at the end they gave it to another random stranger on the internet. The result is the same: the money is gone.
One of my next ramblings will expand on how much fun (or not) I have blogging with Ghost but by now the most burning issue on your mind must be how to get rid of your girlfriend and have some money left at the end of the day.
I hear your muffled moaning behind the cellar door! But since you are locked into the cellar you really only have an imaginary girlfriend and still have no money. Typically geeks having the wrong priorities. Sorry, I haven’t had my Orval yet today, so I am not in the mood to help some sore losers that have no money to pay for my beer.
Installing Ghost the secure way
You really want to protect your cat pictures and want to keep nasty people out of your nice and shiny new server. Ghost is still in beta and is build upon alpha software, so there will be bugs and security issues. How to keep this manageable until it is a mature platform?
I do not own a nice server since I have my priorities right so my money goes to beers. That’s why I decided to rent a 5 USD/month Linux server at DigitalOcean. They have some very nice hardware hosted in cellars that feels like home to the geeks locked in there. These are the smart ones that escaped the cellar of their parents.
John O’Nolan promised that the first beta version of Ghost would have a proper installation procedure but as usual this was wishful thinking or maybe I have to look up the meaning of the word “proper” again.
So next is my installation procedure. Boring, but It Just Works (™). Most of the installation procedures on the web end up as a procedure that is almost, but not quite, entirely unlike a proper installation procedure (thanks, Douglas Adams!).
Yes, I made some shortcuts, but you are probably too young to know the full story now. Please wait for a next post where I will delve deeper and tell you everything about chroots and the dangers that lies within.
Before you start another Mountain Dew
The following procedure will teach you on how to install Ghost, protected by Nginx (as a proxy) and ModSecurity. Your password and other secrets will be safe because we will use a SSL certificate.
First of all, running a server (droplet) at DigitalOcean is not for dweebs that think that one should not login as “root”. Droplets are for real men that hate “best practices” and acknowledge that one more beer will always make things right. Or on the contrary, things might not be all right, but a few more beers will no doubt make you accept the universe again.
For those refusing to work as “root”, just put “sudo” before every command. Note: I used Ubuntu 12.04 LTS as operating system.
Modify the root password
You will sign on to your droplet as root using the SSH protocol and a password. Make sure to modify the password the first time you sign-on to your droplet, since the original password was sent to you by email.
Use a very long and complex password since the entire internet and the NSA will be there to brute-force your choice. A long password is not the name of your imaginary girlfriend, but something like “Dude,thisisreallypainful!”.
After that you are asked to type in the new root password twice. Finally, your root user has a new password.
A better idea might be certificates but the problem is that I know you will be too lazy to protect the private key on your laptop with a strong password. Unfortunately, bad guys know how to get text files out of your laptop.
Do not forget the basics
Before doing anything else make it a habit to update the software and operating system of your droplet:
We need some more software:
Configure a non-standard port for SSH
Tons of script kiddies will try to use the standard port (22) of the SSH protocol to brute-force your password. Keep them out by modifying the standard port (here in the example port 6543):
The already installed
fail2ban software will protect against brute-forcing, no additional configuration is necessary.
Protect your droplet with a firewall
This is done by modifying the iptables configuration. First we will make certain that all local traffic is accepted.
Then allow all existing connections:
We will allow only connections to SSH (6543 or whatever you used in the earlier steps) and to the web server (80, 443):
Make those rules persistent using the package
After this, reboot the server and grab a cold beer:
Next, you will have to sign-in again using SSH, but don’t forget you have to use the newly configured port (6543 in our example)!
Request SSL certificates
Enabling SSL in the web-server protects the data travelling between browser and server (such as your password) against prying eyes.
It is possible to create your own certificates (self-signed) or buy them from a certificate authority (CA). Self-signed certificates will result in a security warning when users visit your site. However, SSL certificates from a CA cost real money, money that is better spent buying beers.
Luckily the nice guys from CACERT will create your SSL certificates for free. Unfortunately some browsers still display a security warning, but some accept the certificate. There is absolutely no reason to only consider paid SSL certificates “secure”. Anyway, if you want to get rid of the pop-up, direct your users to install the root certificate of CACERT.
You will need to create a private key, and generate a certificate signing request (CSR).
When ordering a certificate, you will need to copy the content of the
.csr file to a form at CACERT. In return they will give you a certificate. Copy this to a file, e.g.
As always, modify the
YOUR.DOMAIN.NAME to the real name of your blog (e.g.
First we need to install
Node.js. Download the latest
.tar.gz archive (in this case 0.10.21) from Nodejs.org.
Go for for a few more beers and:
Create a user to run Ghost and use a strong password (modify the
YOUR.DOMAIN.NAME to your real domain name, e.g.
Get the ghost source (at this moment only available to Kickstarter backers) and unzip the archive. Transfer your local file to the server in the
Now unzip the ghost files:
Make sure that
production is the default and that Ghost uses your real domain name (again, modify
YOUR.DOMAIN.NAME to your real domain):
We need to make certain that Ghost will start automatically after a reboot. Luckily I was able to steal someones script for this. Open the file in the editor:
Copy the following content (do not forget to change the name):
Save the script by
CTRL-O and leave the nano editor with
CTRL-X. Make the script executable with:
We use crontab to start this script after a reboot:
Paste the following line as last line (again, change
YOUR.DOMAIN.NAMEto your real domain):
Save the script. Exit the shell and you are root again. Create the logfile:
exit touch /var/log/nodelog.txt chown ghost.ghost /var/log/nodelog.txt
Install Nginx and ModSecurity
We will instal Nginx as front-end to Ghost and run it with special filtering software (ModSecurity). The goal is to protect our blog against all kinds of hacking activity. Unfortunately, this means compiling Nginx and ModSecurity. Repeat this step every time Nginx needs to be updated because of security issues!
First download and compile the latest ModSecurity (here version 2.7.5):
cd wget https://www.modsecurity.org/tarball/2.7.5/modsecurity-apache_2.7.5.tar.gz tar xzvf modsecurity-apache_2.7.5.tar.gz cd modsecurity-apache_2.7.5 ./configure --enable-standalone-module make make install
Next we create a user for nginx:
adduser --system --no-create-home --disabled-login --disabled-password --group nginx
Download and compile the latest version of Nginx (here version 1.5.6).:
cd wget http://nginx.org/download/nginx-1.5.6.tar.gz tar zxvf nginx-1.5.6.tar.gz cd nginx-1.5.6 ./configure --add-module=../modsecurity-apache_2.7.5/nginx/modsecurity --with-http_ssl_module --prefix=/opt/nginx --user=nginx --group=nginx --without-http_scgi_module --without-http_uwsgi_module --without-http_fastcgi_module --without-http_autoindex_module --with-http_spdy_module make make install
Create the following file (see references for where I stole this one):
Copy the following content to make Nginx autorun:
# nginx description "nginx http daemon" author "Philipp Klose <me@'thisdomain'.de>" start on (filesystem and net-device-up IFACE=lo) stop on runlevel [!2345] env DAEMON=/opt/nginx/sbin/nginx env PID=/opt/nginx/logs/nginx.pid expect fork respawn respawn limit 10 5 #oom never pre-start script $DAEMON -t if [ $? -ne 0 ] then exit $? fi end script exec $DAEMON
Copy the ModSecurity configuration file to the Nginx directory:
cp ~/modsecurity-apache_2.7.5/modsecurity.conf-recommended /opt/nginx/conf/modsecurity.conf
We need some more rules for ModSecurity:
cd /opt/nginx/conf/modsecurity.conf wget https://github.com/SpiderLabs/owasp-modsecurity-crs/tarball/master tar zxvf master --wildcards --no-anchored ‘*.conf’ --strip-components 2
We need to relax some ModSecurity rules to make it work:
sed -i '/981172/s/^/# /' modsecurity_crs_41_sql_injection_attacks.conf sed -i '/981245/s/^/# /' modsecurity_crs_41_sql_injection_attacks.conf sed -i '/981243/s/^/# /' modsecurity_crs_41_sql_injection_attacks.conf
Configure ModSecurity to filter Cross-Site-Scripting (XSS) and SQL Injection (SQLi) attacks:
sed -i 's/DetectionOnly/On' modsecurity.conf sed -i 's/13107200/100000000' modsecurity.conf
Open your editor to make some more modifications:
Add the following 3 lines to the end of the file:
SecDefaultAction "log,deny,phase:1" Include "modsecurity_crs_41_sql_injection_attacks.conf" Include "modsecurity_crs_41_xss_attacks.conf"
Save the file.
The only thing left is modifying the Nginx configuration file. Note that I had to disable ModSecurity for file-upload (I am investigating why):
Modify the content of the file to read (the number of worker_processes can be put to the number of CPUs):
Save the file. Do not forget to modify
YOUR.DOMAIN.NAME to your real domain name.
Now move the certificate and key to the Nginx configuration directory:
cd mv YOUR.DOMAIN.NAME.cer /opt/nginx/conf/ mv YOUR.DOMAIN.NAME.key /opt/nginx/conf/
Check the validity of the nginx.conf file and fix errors where necessary:
The output should look like:
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok nginx: configuration file /opt/nginx/conf/nginx.conf test is successful
There is nothing left to but reboot:
I will work on improvements:
- review file system permissions
- chrooted installation
- finetune modsecurity.conf
- finetune (better caching) nginx.conf
- switch to PM2 instead of using Forever
My first cat picture
Unfortunately my cat escaped when I was having some beers, so here is a picture of me drinking my first beer of the day.
I hope you enjoyed this blog, I certainly did. Looking forward to your first cat picture.
Why do you insult geeks?
Stupid geeks! I never intended to insult all geeks, I only stated that stupid geeks are the ones that never escaped the cellar where their parents locked them in.
Smart geeks are the ones that did manage to escape after marauding their parents wine cellar.
Why don’t locked up geeks drink the wine?
Because they only like Mountain Dew. See above.
What do you really think of Ghost?
Did you even read my blog? I told you that I will tell you all there is to know in due course in one of my next posts. At this moment I believe that Ghost will be the greatest platform for people without writing skills but having nice pictures of cats.
01 October 2013
New version Node.js, Ghost, SPDI support NGINX
26 September 2013
Some links I found useful while drinking lots of beers: