In this post, we'll perform some essential server hardening.

In subsequent posts, we'll install Ghost, secure the Ghost admin interface and install some free themes.

Hardening your server

When you first access your new Digital Ocean droplet there are a few steps you can complete in order to make it more secure.

Login as root

Login to your new droplet using the IP Address and root password from DigitalOcean's confirmation email:

ssh root@128.199.238.4

At the first login, it will ask you:

The authenticity of host '128.199.238.4 (128.199.238.4)' can't be established. 
ECDSA key fingerprint is 79:95:46:1a:ab:37:11:8e:86:54:36:38:bb:3c:fa:c0.
Are you sure you want to continue connecting (yes/no)?

Type "yes", press the enter key and then type your root password.

Change the root password

Change the root password to something strong:

passwd

Write it down and keep it in a safe place.

Create a new user

Now let's create a new user and grant them administrative (root) privileges. You can choose any name you like. I chose "homer":

adduser homer
adduser homer sudo 

Check for updates

You should also run the following commands to upgrade your installed packages:

sudo apt-get update
sudo apt-get upgrade

You can also check for broken dependencies:

sudo apt-get check

And, remove old dependencies (.deb files) for packages that are no longer installed on your system:

sudo apt-get autoclean

Note: Removing these files from /var/cache/apt/archives can reclaim a significant amount of diskspace.

Set the Timezone

To check your current timezone, enter the following command:

date

You should then see output like:

Thu Mar 21 18:02:49 MST 2012

To change timezones, enter the following command:

sudo dpkg-reconfigure tzdata

It will prompt you for a country/city combination. Then run the following command to sync the server's time:

sudo ntpdate pool.ntp.org

Note: Remember to restart cron as it won’t pick up the timezone change: sudo service cron restart

The easiest way to ensure that your server's time remains up to date is to install the Network Time Protocol daemon. To install it, enter the following command:

sudo apt-get install ntp

Open the NTP configuration file with a text editor. I used nano:

sudo nano /etc/ntp.conf

And, update the NTP configuration file so that it only uses local (I'm based in Sydney) NTP servers:

server 0.au.pool.ntp.org
server 1.au.pool.ntp.org
server 2.au.pool.ntp.org
server 3.au.pool.ntp.org

Now, restart NTP:

sudo service ntp restart

Configure SSH

SSH, or Secure Shell, is a protocol used to securely connect to remote systems. SSH works by connecting a client program to a ssh server. It is used to foil eavesdropping and spoofing of network traffic by encrypting all traffic during a session, both logins and data transfers.

In Ubuntu, the main ssh server (sshd) configuration file is located at /etc/ssh/sshd_config. Make sure you create a backup of the file before modifying it:

sudo cp /etc/ssh/sshd_config{,.bak}

Open it with a text editor. I used nano:

sudo nano /etc/ssh/sshd_config

There are a few things we want to change but we'll take it a step at a time:

Port 22

The port declaration specifies which port the sshd server will listen on for connections. By default, this is 22 however you can change this to any number between 1025 and 65536.

It is a good idea to change this to a non-standard port to help obscure your server from random port scans.

PermitRootLogin yes

Change this from yes to no to stop any future root logins via SSH. Remember, if you run into problems you can always login to your droplet via the "Console Access" button in the DigitalOcean control panel.

If you would like to limit the users who can login then add the following line to the bottom of the file:

AllowUsers homer

Make sure you replace "homer" with your new username. Save (^O), and exit (^X) nano. To check your changes, run the following command:

sudo sshd -t

If there are no syntax errors, it exits silently. Reload SSH, and it will implement the new settings:

sudo reload ssh

To test the new settings (don’t logout of your current session), open a new terminal window and login as your new user. Don't forget to include the new port number:

ssh -p 22000 homer@128.199.238.4

Your prompt should now say:

homer@robferguson:~$

From now on, you will only be logging in as the new admin user we created.

Key-based authentication

While it's helpful to be able to login to a remote system using passwords, it's a much better idea to use key-based authentication.

Generating SSH keys

SSH keys should be generated on the computer you wish to log in from. I'm logging in from my new MacBook Pro running OS X 10.9.2.

First, let's check and see if we already have a default identity:

ls -al ~/.ssh

Default identity files that use RSA encryption appear as an id_rsa and id_rsa.pub pair.

To create a default identity, enter the following command:

ssh-keygen -t rsa

Look at the file permissions:

-rw-------  1 homer  staff  1679  4 Apr 17:37 id_rsa
-rw-r--r--  1 homer  staff   416  4 Apr 17:37 id_rsa.pub
-rw-r--r--  1 homer  staff   395  4 Apr 13:57 known_hosts

The id_rsa file is readable and writable only by the owner. We should also protect it from being accidentally overwritten:

chmod 400 id_rsa

The id_rsa.pub file can be shared and has the appropriate permissions.

Now we're ready to copy your public key to the remote server:

ssh-copy-id '-p 22000 homer@128.199.238.4'

This will start a SSH session which will prompt you for your (homer's) password. After you enter your password, it will copy the default identities public key (id_rsa.pub) to the server accounts authorized_keys file.

To test the new settings, open a new terminal window and login as your new user. Don't forget to include the new port number:

ssh -p 22000 homer@128.199.238.4

Note: If your copy of OS X is missing ssh-copy-id you can use MacPorts to install it. Or you can grab a copy from GitHub:

sudo mkdir /usr/local/sbin
sudo curl https://raw.github.com/beautifulcode/ssh-copy-id-for-OSX/master/ssh-copy-id.sh -o /usr/local/sbin/ssh-copy-id
sudo chmod +x /usr/local/sbin/ssh-copy-id
sudo ln -s /usr/local/sbin/ssh-copy-id /usr/sbin/ssh-copy-id

Create a SSH config file

You can make things a little easier on yourself by setting up a SSH configuration file:

sudo nano ~/.ssh/config

Here's what mine looks like:

Host blog 
    HostName robferguson.org
    Port     22000
    User     homer

Now, I just need to enter the following command to connect to my new droplet:

ssh blog

Which is a lot fewer key strokes and much easier to remember.

Setup a firewall

UFW, or Uncomplicated Firewall, is a front-end to iptables that is installed by default in Ubuntu 12.04 LTS.

To check the status of UFW, enter the following command:

sudo ufw status

Right now, it should be inactive:

Status: inactive

By default, UFW’s will deny all incoming connections and allow all outgoing connections. We want to allow incoming connections to SSH (on port 22000), HTTP (on port 80) and HTTPS (on port 443) so we need to enter the following commands:

sudo ufw allow 22000
sudo ufw allow 80
sudo ufw allow 443

To enable UFW, enter the following command:

sudo ufw enable

Now, check the status of UFW:

sudo ufw status

When UFW is active, you'll get a listing of the current rules:

Status: active
To               Action      From
--               ------      ----
22000            ALLOW       Anywhere
80               ALLOW       Anywhere
443              ALLOW       Anywhere
22000            ALLOW       Anywhere (v6)
80               ALLOW       Anywhere (v6)
443              ALLOW       Anywhere (v6)

Install Fail2Ban

Fail2ban can help protect your droplet from malicious behaviour by scanning through log files and reacting to suspicious actions like repeated failed login attempts.

To install Fail2ban, enter the following command:

sudo apt-get install fail2ban

Make a local copy of the default fail2ban configuration file:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Open it with a text editor. I used nano:

sudo nano /etc/fail2ban/jail.local

There are a couple of things we want to change but we'll take it a step at a time:

[DEFAULT]
# "ignoreip" can be an IP address, a CIDR mask or a DNS host
ignoreip = 127.0.0.1/8 
bantime  = 600
maxretry = 3

Add your static IP address (not your local IP address) to the ignoreip line, making sure to separate each address with a space. Including your address will guarantee that you do not accidentally ban yourself from your own server.

Note: Ubuntu 12.04 LTS displays your static IP address when you login, just after Ubuntu's message of the day.

We also need to let Fail2ban know which port to monitor for SSH connections:

[ssh]
enabled  = true
port     = ssh
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 6

So, we need to change port = ssh to port = 22000.

Now we can restart Fail2Ban, and it will implement the new settings:

sudo service fail2ban restart

Install Logwatch

Logwatch is a log parser and analyser that can help protect your droplet from malicious behaviour by monitoring log files and creating reports about the activities taking place on your server.

To install Logwatch, enter the following command:

sudo apt-get install logwatch

Note: Logwatch will install Postfix if you do not have an SMTP service installed. If you are prompted to install Postfix, select the "Internet Site" configuration and enter your FQDN (e.g., robferguson.org).

Open the Logwatch configuration file with a text editor. I used nano:

sudo nano /usr/share/logwatch/default.conf/logwatch.conf

There are only a couple of things we need to change to get up and running:

Output = mail
Format = html
MailTo = homer@robferguson.org
MailFrom = logwatch@robferguson.org

These directives tell Logwatch to email you reports in HTML format. The MailTo and MailFrom directives must be valid email addresses.

To test your configuration, enter the following command:

sudo logwatch

Then check your email to make sure that Logwatch is working. Be sure to check your spam folder as the emails may be marked as spam.

Finally, we can update crontab:

sudo crontab -e

And, schedule Logwatch to run at 1 AM every day:

0 1 * * * /usr/sbin/logwatch

Note: If Logwatch appears to be running twice a day, check the /etc/cron.daily directory and remove the 00logwatch file.

What's next

In the next post, we'll install Ghost.

References: