Securing Your Raspberry Pi

5 October 2016

Raspberry Pi is a wonderful, low cost, device that's perfect for security and home automation projects. Unfortunately, Raspbian, the officially supported operating system for the Raspberry Pi, places an emphasis on usability and approachability over security. This certainly doesn't mean, however, that Raspbian is insecure. It just means that you're going to have to take some extra time and make some extra effort to secure your Raspberry pi device. This starts by hardening the installation and should also include the installation of a few additional packages that allow you to exercise more control and monitoring on your device.

User Accounts

Your first step in securing the Raspberry Pi should be to disable the default Pi account in Raspbian, since it utilizes the well known password 'raspberry.' Before disabling this account, however, you should create a new account on the system. You can use the useradd command to do this, with some extra flags to specify that a new home directory be created for the user. To do this log in as the Pi user and issue the command:

$ sudo /usr/sbin/useradd --groups sudo -m justin

Use your own username instead of my name as you like. This will create a new account, create a directory for the account (such as /home/justin) and add the new account to the sudo group so the user can use the sudo command. Once the new user account is created we need to set a password for the account. You can do this using the command:

$ sudo passwd justin

And you'll be prompted to set a new password on the account. Next you'll want to reset the root password to ensure it's something strong. To do this use the command:

$ sudo passwd root

And be sure to change your password to something really long. Finally, you'll want to disable the pi account. To do this use the command:

$ sudo passwd --lock pi

Now you can log out of the Pi account and log in with your new account and password. This will ensure that no one can log into your Pi without knowing the account and the password. Although you may think your Pi is relatively safe from unwanted attacks, by default Raspbian installs a remote access shell, SSH, that can be accessed from anywhere.

Securing SSH

Our next step to securing our Pi is to lock down SSH. To do this we're going to disable the ability for a remote user to log in as root and set up SSH so that only machines with an authorized SSH key can log in. To do this edit the SSH configuration file using vi, or another text editor, with the command:

$ sudo vi /etc/ssh/sshd_config

And be sure the following lines are set and uncommented - meaning that the lines are in the file and they aren't preceded with a hash tag symbol, which marks a line as a comment and ignores it for configuration purposes:

# Authentication:
LoginGraceTime 120
PermitRootLogin no
StrictModes yes

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile      %h/.ssh/authorized_keys

# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no

UsePAM no

The last line is very important since it will disable Pluggable Authentication Modules (PAM), or native Linux authentication, and only allow users to log in with a key. Next you'll want to generate an SSH key. You can do this with PuTTY on windows or with the ssh-keygen command on Linux. Create a .ssh directory in your users home directoyr and an authorized_keys file with the following commands, being sure to set the permissions properly (otherwise the key based authentication will fail):

$ mkdir ~/.ssh
$ chmod 0700 ~/.ssh
$ touch ~/.ssh/authorized_keys
$ chmod 0600 ~/.ssh/authorized_keys

Next you can use vi, or another text editor, to edit the authorized_keys file and paste in the public key you generated so you can log in. Be sure to restart SSH to ensure the changes take effect using the command:

$ sudo systemctl restart ssh

Firewall

Once you've locked down SSH you'll want to ensure that the iptables firewall is running on your Raspberry Pi. For additional good measure you can configure the firewall so that it logs a message whenever a firewall rule is activated and a connection is blocked. First make sure that iptables is installed using the command:

$ sudo apt-get install iptables iptables-persistent

Note that using the iptables firewall will require new kernel modules to be loaded. The easiest way to load them is to reboot your Pi. Once iptables is installed go ahead and check the current iptables rules with the command:

$ sudo /sbin/iptables -L

This will list the rules, which are probably empty. You can save these rules off to a text file and edit it using the command:

$ sudo /sbin/iptables-save > /etc/iptables/rules.v4

This is the file that iptables-persistent uses when your system boots or reboots to make sure that the firewall is still running. Once saved go ahead and edit the file so that it looks something like the following, altering whatever rules you need:

$ sudo cat /etc/iptables/rules.v4
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

# Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

# Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allows all outbound traffic
# You could modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

# Allows SSH connections 
# The --dport number is the same as in /etc/ssh/sshd_config
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

# log iptables denied calls (access via 'dmesg' command)
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

# Reject all other inbound - default deny unless explicitly allowed policy:
-A INPUT -j REJECT
-A FORWARD -j REJECT

COMMIT

Next check to ensure your iptables are working properly. This can be tricky because you might be remotely connected via SSH and if you've messed something up you don't want your connection to be severed. Thankfully, there is a command that will help you by applying rules and asking for confirmation that you can still connect. If you don't respond in a certain amount of time the program will assume you've gotten disconnected and it will roll back your changes. If you do respond it will apply your changes permanently. To accomplish this use the command:

$ sudo /usr/sbin/iptables-apply /etc/iptables/rules.v4

If everything works your changes will be applied and you can check them with the command:

$ sudo /sbin/iptables -L

Automated Updates

Next you're going to want to make sure your Pi applies updates automatically so that your system doesn't fall behind or fail to apply patches for security. You can do this by installing the package unattended-upgrades as described on the official Debian wiki at https://wiki.debian.org/UnattendedUpgrades.

Logwatch

Another handy tool to keep track of things on your Raspberry Pi is the logwatch package. Of course, you'll need to ensure that e-mail is working on your Pi, but the exim4 mail relay agent should work just fine. You can look at my article on setting up email relay on the Pi for more information.

Install logwatch using the command:

$ sudo apt-get install logwatch

Then adjust the configuration file at /usr/share/logwatch/default.conf/logwatch.conf to suit your needs. By default logwatch will e-mail the root account, so you probably want to set up some sort of relay. The easiest way to do this is to edit the /etc/aliases file to point to your e-mail address. To do this be sure that root forwards to your local account and that your local account points to a real e-mail address such as:

root: justin,root
justin: justin@madirish.net

Be sure to use the following command after you edit the /etc/aliases file to have the changes take effect:

$ sudo /usr/bin/newaliases

Now your Pi will send you e-mails each night reporting on the previous day's activities and alerts.