Intro

A RaspberryPi isn’t the most powerful computer around, nor is it equipped to perform server-grade mission-critical tasks. But a lot of people use it as their home-grown server, some have multiple units or clusters of them, and some companies even offer RaspberryPi data centers.

I’m a tinkerer. This means I make mistakes, I ruin one of my servers, and — more often than not — I re-install it from scratch because I don’t know how to fix it. Then I do it all over again. Setting up a base system that I can build on has become a somewhat mundane task. This post documents just that: my endeavor to create a secured minimum system from which I can build a RaspberryPi server.

Disclaimer

I am by no means an expert in server installation or maintenance. I do this for fun, and sometimes I get lazy and cut corners. Please don’t treat this as a you-must-do-this guide, but more of a this-is-what-I-did and I’d like to share it with you. If you spot any mistakes, please let me know and I’ll do my best to address it immediately.

Operating System Selection

The objective of this build is to prepare a minimum system that is reasonably secured and can be used as a base system from which we can build a RaspberryPi-based server. Note the keywords: minimum and server. We won’t need to have a desktop environment, let alone Minecraft. Let’s leave all unnecessary things out of the build.

To achieve the objective, I chose MinibianPi. It’s a stripped-down version of Raspbian which is quite up-to-date, and even supports Pi 2. I think it’s a great place to start.

Installing MinibianPi

Write the image to an SD card (there are instructions for Windows users, Mac users, and Linux users).

Login as root (password is raspberry), either directly or via SSH using Terminal if you’re on a Mac or PuTTY if you’re a Windows user. The image has SSH enabled by default.

Install raspi-config. We could just re-partition the SD card ourselves, but I would personally try to not mess with partitions.

apt-get install raspi-config -y

Run raspi-config, and then expand filesystem. We have to do this now to avoid running out of disk space when we start installing other stuff.

Reboot

Creating New User With Administrative Privileges

I believe this is one of the most important things to do, because the default ‘pi’ user on the Raspbian image is vulnerable enough if exposed to the internet, let alone having a system with a known root password.

First we need to update our repositories. I found out the hard way that if we do this any later, some installations just won’t work.

apt-get update

Next, we need to install sudo so that we can grant administrative privileges to non-root users.

apt-get install sudo

Alright, with that done, let’s add the new user.

adduser USERNAME

We have to set a password for this new user, but all other fields can be left blank.

To grant administrative privileges, we can add USERNAME to the sudo group.

adduser USERNAME sudo

With that done, we can reboot and login as USERNAME.

Securing The Operating System

Regenerating Unique Host Keys

The very first thing we need to do is regenerate the unique host keys.

sudo rm /etc/ssh/ssh_host_* && sudo dpkg-reconfigure openssh-server

Next we need to verify that the keys have indeed changed and make sure we’re still able to login. If you’ve been doing all this via SSH, try to login using another Terminal or PuTTY session. If you’re using PuTTY, you should see a warning and getting past it is simple. If you’re using Terminal or a Linux machine, you need to remove the host key from your known hosts file. Here’s how you do it if you previously logged in using the Pi’s IP address:

ssh-keygen -R 192.168.1.111

If that doesn’t work, and you’re okay with resetting your entire known hosts file, just delete it:

cd
rm .ssh/known_hosts
ssh ras.mydomain.com

Setting Up Key Pair Authentication for SSH

Next, we should prefer key pair authentication for SSH than the default password authentication. As long as we don’t lose our private key, that is. If you’re a Mac or Linux user, follow along. If you’re stuck with Windows, like I am, here‘s a good article about setting up key pair authentication using PuTTY.

On your own terminal (not on the Pi), do this to create your private and public key pair:

ssh-keygen

Follow the on-screen instructions to create the SSH keys on your computer. To use key pair authentication without a passphrase, press Enter when prompted for a passphrase. After completing this, 2 files will be created in the directory ~/.ssh (or /home/USERNAME/.ssh). The file id_rsa is your private key, and id_rsa.pub is your public key. Now, we need to upload the public key to the Pi. Let’s use SCP for this:

scp ~/.ssh/id_rsa.pub USERNAME@192.168.1.2:

Change 192.168.1.2 to your Pi’s reserved IP address.

Then, using the Pi’s console, on the Pi’s home directory, let’s create the .ssh directory:

mkdir .ssh

Next, move and rename the id_rsa.pub file to the .ssh directory and change permissions to secure it:

After that’s done, our Pi will be able to authenticate us using our public key. To try this out, logout from your Pi and try to login again. Instead of the usual SSH login prompt, you will be prompted to enter your passphrase if you have one. If you didn’t set a passphrase, you’ll be logged in immediately.

Disabling Password Authentication and Root Login

When we’re able to log in using key pair authentication, we should disable password authentication. While we’re at it, let’s disable root login as well:

Edit the file /etc/ssh/sshd_config

sudo nano /etc/ssh/sshd_config

Set ‘PasswordAuthentication’ value to ‘no’.

Set ‘PermitRootLogin’ value to ‘no’.

Restart SSH service.

sudo service ssh restart

Test by logging in without your private key, the attempt should be rejected.

Installing Iptables and Setting Up Basic Firewall Rules

To protect against attackers who take advantage of open ports, we should install iptables and set our default firewall rules. For now, we’ll just block everything except localhost, network pings, and SSH on port 22.

All good! We just need to make sure those rules get loaded on every reboot. To do that, we’ll need to create a script:

sudo nano /etc/network/if-pre-up.d/firewall

Put the following code in the file:

#!/bin/sh
/sbin/iptables-restore < /etc/iptables.firewall.rules

Save, exit, nano, and make the file executable by root and not accessible by anyone else.

sudo chmod 700 /etc/network/if-pre-up.d/firewall

Test by rebooting and checking iptables right after you’re able to login again.

After confirming that the firewall is automatically restored on boot, let’s make the system logger divert all iptables-related rules to a different log file. This will come in handy when we need to analyze the logs, saving us the time to sort out the firewall log from other log entries. First, let’s create a new file:

After doing this you should have all log messages having the prefix [NETFILTER] stored in /var/log/netfilter.log.

NOTE: This build will eventually evolve into a server, which means we will need some more ports opened for our services to be able to function properly. When you have your services up and running locally but can’t access it from your network, just remember to check your iptables settings and make sure it’s not blocking your service port.

Installing fail2ban

The last item in our security checklist is installing a piece of software called fail2ban. It will monitor our log files for failed login attempts. After an IP address has exceeded the maximum number of authentication attempts, it will be blocked at the network level and the event will be logged in /var/log/fail2ban.log. To install it, issue the following command:

sudo apt-get install fail2ban -y

Getting The System Up-to-Date

Now the system is relatively secure and almost ready, but before we proceed with actually building the server, let’s upgrade everything first.

Update all installed software packages:

sudo apt-get upgrade -y && sudo apt-get dist-upgrade -y

Update the Pi’s firmware while we’re at it

sudo apt-get install rpi-update -y
sudo rpi-update

That’s it, now we have a secured minimum system ready to build. What servers can we build from this starting point? That depends on your imagination. Enjoy!

References and Further Reading

These articles are a good read if you’re into setting up your own RaspberryPi-based server. I believe they use the standard Raspbian Wheezy image for their tutorials, but most of the commands will run just fine.