The purpose of this tutorial is to walk you through the process of making an installation of Raspbian Stretch Lite more secure. Which you can then create your own image from to use as a baseline setup for future Raspberry Pi projects.
This tutorial assumes that you already know how to flash a microSD card with Raspbian. It also assumes that you are already somewhat familiar with setting up and using a Raspberry Pi.
- User Setup
- System Settings
- Configure a Static Ethernet IP Address
The first thing we will do to improve the security of our setup is to add a new user account with SUDO privileges, remove the default user (pi) account and home directory (/home/pi), and change the root user password.
Add a New User Account with SUDO Privileges
Raspbian has a default user account named pi that has SUDO (super user) privileges. We want to logon to this account and create a new account with SUDO privileges. Once we create the new account we will remove the pi account. Go ahead and logon to Raspbian using the standard credentials. Currently as of 11/4/2017, Username: pi, Password: raspberry
Issue the following command to add a new user:
sudo adduser USERNAME
I am going to use themaster as my username. A little reference to Doctor Who. This isn’t actually what I will use in the real world (sorry hackers). I just needed something for training purposes and for some reason this is the first thing that came to my mind. In my future Raspberry Pi tutorials you will see this theme re-emerge as I plan to use these setup instructions as my baseline setup for future tutorials.
You will be prompted for information about the user. It’s not necessary to include anything here. You can skip the questions by pressing enter. Then type “y” at the end to confirm the information is accurate.
We will now want to change the password of the newly created account:
sudo passwd themaster
We will now add the user to the sudo group. This will allow themaster to have super user privileges.
sudo usermod -a -G sudo themaster
Delete the Default “pi” Account
It is now time to say goodbye to the pi account. Logout by typing exit and pressing Enter. You should now be back at a logon screen.
Logon with the newly created account.
We now want to make sure that our new user account has sudo permissions. The easiest way to test this is to issue the following command. Only users who have sudo permissions are allowed to issue this command.
If successful, this will load the sudoers file. To exit the file, simply press Ctrl + X at the same time.
We will now issue the command to delete the pi account.
sudo deluser pi
We will also need to ensure the pi account home directory is also deleted.
sudo rm -r /home/pi
Change the “root” Account Password
sudo passwd root
We will now run the raspi-config program to make the following changes.
- Resize the filesystem to take advantage of the entire microSD card.
- Decrease the amount of memory being dedicated to the GPU.
- Change the hostname.
- Change the locale and timezone.
- Enable SSH for remote administration.
Some of these options will require a reboot before the changes will take effect. You can reboot when prompted or wait until we have completed all of the steps. I prefer to complete as many steps as I can before I have to reboot. I will let you know when I reboot.
Starting with the second option, 2 – Hostname, we will change the default hostname from raspberrypi to baseline. Since we’re going to use this to get future projects off the ground faster, when I flash a new microSD card with this image, I will already know what the hostname is. We’ll talk about it more in the new project setup tasks section, but when I do start a new project, I would change this hostname to reflect the project I am working on.
Example 1: In my next article I am writing about how you can use the Raspberry Pi as a web server. I used my IRGos test website to write the tutorial. So for the hostname I used irgos.
Example 2: In the past I have experimented with using a Raspberry Pi Zero as a car dashcam. For that project I used the hostname dashcam.
Next we will expand the filesystem. Select 7 – Advanced Options then A1 – Expand Filesystem. This will ensure that Raspbian has access to the entire available space of the microSD card.
From within 7 – Advanced Options, select A3 – Memory Split. On my projects where I don’t utilize a graphical user interface (GUI), I take this option all the way down to 16 megabytes (MB).
We will now change the locale. Select option 4 – Localisation Options. Then select I1 – Change Locale. Since I am in the United States I will use en_US.UTF-8 UTF-8. Select en_US.UTF-8 again to use it as the default locale for the system.
You will be taken back to the main menu. We need to go back into option 4 – Localisation Options. Then select Change Timezone. Select US then your timezone.
The settings will apply and you will again be taken back to the main menu.
To get into the system we will enable SSH. Select 5 – Interfacing Options. Then select P2 – SSH.
Once you have enabled SSH you can exit out of raspi-config. You will be prompted to reboot. Go ahead and allow the Pi to reboot at this time.
Configure a Static Ethernet IP Address
Static IP Assignment via MAC Address
In my opinion, the best option for configuring a static IP address is to have your router apply the IP address based on the MAC address of the device. I utilize this option on my network. Why?
Scenario 1: If I have my Pi connected to the switch that I have in the demilitarized zone (DMZ) it will receive one IP address. If I need to take the Pi offline and move it back onto my private network I can do so without logging back into the Pi to change the static IP address or turn off static IP addressing. It will then receive an IP address for my private network.
Scenario 2: I have a couple of Pi boards that I use for testing of miscellaneous projects. Using router based addressing allows me to print the IP address that I know the router will assign to those Pi boards.
In both of the above scenarios: 1.) The need for me to logon to the Pi to see what IP address has been assigned, 2.) The need to connect the Pi to a monitor to check the IP address, and 3.) The need to connect into my router’s console to see what IP address it assigned have all been eliminated.
Every router is different so you will have to read through your router’s manual in order to determine how to do this. However, I can tell you how I do it on my TP-LINK (TL-WDR4300) and Century Link (Actiontec C1000A) routers.
First, we need to determine your MAC address:
Look for the ether address in your Ethernet adapter information. If you are using a Pi with built-in Ethernet it should be listed as eth0. It will look something like this: r8:74:er:e9:4c:9e (invalid MAC address, by the way, but this is what they look like).
On my TP-LINK router, after I logon I click on DHCP then Address Reservation. I then click on Add New and supply the MAC Address of the Pi and the IP address that I would like to have reserved for the Pi. One thing to note here, the Pi will display it’s MAC address to you with colons. In my experience, you have to use hyphens instead of the colons when reserving an address on this TP-LINK router.
Once you save you will have to allow the router to reboot before the changes occur. You will then also have to reboot the Pi, but only after the router has fully rebooted.
On my CenturyLink router, after I logon I click on the Advanced Setup button. Then the DHCP Reservation link on the sidebar. Enter your MAC address into Step 4. Then in Step 5 you will select an IP address to associate with the MAC address. Click on Apply in Step 6. Allow the router to reboot.
Static IP Assignment via the dhcpcd.conf File
If you don’t have the option to use your router to assign a static IP address, you will have to do it manually via the dhcpcd.conf file.
We will use a program called nano (a text editor) to edit the dhcpcd.conf file which is located in the /etc directory.
sudo nano /etc/dhcpcd.conf
Look for the section in the file that provides an example static IP configuration. I like to put mine below the example, leaving the example in case I need to reference it in the future.
interface eth0 static ip_address=192.168.1.87/24 static routers=192.168.1.1 static domain_name_servers=192.168.1.1 188.8.131.52
The last IP address in static domain_name_servers, 184.108.40.206, is for Google’s public DNS servers. You do not have to add it.
Save and exit the file.
Now is a good time to go ahead and reboot.
Connect to the Pi via SSH and SFTP
Once you have PuTTY installed. From the main screen you should be on the Session settings. In the Host Name (or IP address) field, enter your Pi’s IP address. Port should remain 22. Connection type should remain SSH. In the Saved Sessions field, enter a name for the connection. I usually use the Pi’s hostname. Click on Save. You can then click on the Open button to connect.
Once you have FileZilla installed. We will open the Site Manager and create a new connection. In the Host field, enter your Pi’s IP address. Leave the Port field blank, but be sure to select SFTP – SSH File Transfer Protocol from the Protocol drop-down.
For the Logon Type select Normal and supply the username and password. Click on Connect.
Now that we are able to connect into the Pi without actually having to sit in front of it, this makes administration a little easier. However, it also makes the system more vulnerable. We have made the system more secure by making a new user for system administration, deleting the old default account (pi), and changing the password for the root account. Unfortunately, it’s not enough. Though, in the times we live in, there is never enough security! The most secure computer is one that is not turned on! But what fun is that?
We can increase security further by enabling two-factor authentication. The type of two-factor that we are going to implement on our Pi uses two keys. A private key and a public key.
The Raspberry Pi website has instructions for generating keys via ssh-keygen. I prefer to use the PuTTY Key Generator. The Raspberry Pi website instructions do not instruct you to add a passphrase. I disagree with that. I think you should.
Another option for two-factor is Google Authenticator. Digital Ocean has instructions for setting this up. I really wanted to use this option because I think it’s fantastic. However, all of the programs I use for connecting to and managing my Pi are much friendlier to certificate based authentication.
During the installation of PuTTY, PuTTY Key Generator should have also been installed. On Windows, it should be on the Start Menu. I can usually get to it by searching for it on Windows through Cortana search. If not, it’s located at: C:\Program Files (x86)\PuTTY\puttygen.exe
From the main screen, in the Actions section, click on Generate.
You will see an instruction at the top to move your mouse cursor over the blank space.
Once a key has been generated you will see the new public key, a fingerprint and comment.
Make sure to add a key passphrase!
Save the public and private keys. I keep these in a cloud storage account so that if I am mobile and need to logon to a server I can easily retrieve the key file.
Return to the SSH connection you have established with your Pi:
The above command will create a hidden directory named .ssh
We now need to get the public key that we created via PuTTY Generator into that newly created folder in a file named authorized_keys.
Access the .ssh directory:
Create the authorized_keys file:
You should now be able to copy and paste the public key that was generated by PuTTY Key Generator into this file.
Save and exit the file using Ctrl + X.
We now need to change the permissions of the authorized_keys file:
chmod 644 authorized_keys
We now need to edit the sshd_config file located at /etc/ssh/sshd_config (this will require sudo privileges):
sudo nano /etc/ssh/sshd_config
In the file, change all of the following options to NO:
Once you have changed those options to No, save and exit the file using Ctrl + X.
Restart the SSH server:
sudo service ssh reload
We now need to go back into PuTTY and modify our connection.
Click on the connection within PuTTY and select Load.
From the Category sidebar, expand SSH and select Auth. At the bottom of the list of options you will see Private key file for authentication. Click on Browse and select your private key file.
Return to the Session options screen. Click on Save to save the new authentication method.
Upon re-connecting to the server you will be prompted for the user that you would like to logon as and the passphrase for that user’s private key.
We will also need to update our connection settings within FileZilla.
Access the Site Manager. Change the Logon Type from Normal to Key file. A username will still need to be supplied, but you will now authenticate off of the private key file that you specify. Upon reconnection you will get another pop-up to enter the passphrase.
This only changes how you logon to the server. As you are performing administration tasks on the Pi, when you are prompted for your password, you will still supply the actual account password.
Install a Firewall
A firewall may be overkill for your project. However, if it’s going to be publicly accessible, it’s a must.
The instructions below were taken from the Raspberry Pi website.
The Firewall we are going to install is called UncomplicatedFirewall or UFW. It is incredibly easy to setup and use.
sudo apt-get install ufw
For the projects you will be implementing on your Pi, you will need to find out which port they require to be open. We’ll go ahead and allow port 22 through since we will need SSH access.
You can specify the port number:
sudo ufw allow 22
You can specify the protocol by name:
sudo ufw allow ssh
The next command will enable the firewall:
sudo ufw enable
I do agree with the Raspberry Pi website’s instruction of limiting SSH login attempts. By issuing the following command, if more than 6 login attempts occur within 30 seconds, the attempt will be denied:
sudo ufw limit ssh/tcp
As suggested by the Raspberry Pi website we will also install the fail2ban program for additional security.
sudo apt-get install fail2ban
There are just a couple of configuration changes we need to make for fail2ban to work properly.
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
You can view the configuration by opening the configuration file:
sudo nano /etc/fail2ban/jail.local
You will want to check for and install any available updates from time to time. At least once per month.
The following command will update your install of Raspbian as close to the downloadable image file as possible.
sudo apt-get dist-upgrade
The next section talks about creating a backup image of your microSD card. Don’t forget to make a new one after you have applied system updates in the future.
microSD Card Backup
Now that you have got your Pi setup with a good baseline set of security standards, now would be a good time to make a backup of it. With this backup you can quickly get a project off the ground. All you will have to do is change the hostname so that it doesn’t conflict with another system on the network and make sure it’s got its own IP address.
Making a backup is easy. I will walk you through how I do it on Windows using a program called Win32 Disk Imager.
First, you’ll want to shutdown the Pi:
Remove the microSD card and connect it into your Windows desktop.
Next, right click on your desktop or inside of a folder then select New > Text Document.
Before pressing Enter… Let’s give it a new filename.
I recommend something like: baseline_32GB_2017_11_12.img
baseline: Because this is our baseline image.
32GB: Because this is the size of the microSD card that I am backing up. Unfortunately, using this method, you will only be able to write the image back out to a microSD card that is the same size or larger.
Additionally, this is going to create a rather large .IMG file. Make sure you have enough space on your hard drive to create the .IMG file. A 32GB microSD card could result in an .IMG file that is close to 32GBs. We can use a program such as 7Zip to compress it after it has been created. Just know you’re still going to need to write the image to the same size card or larger.
Date: The date, so I will know when I made this backup IMG file.
To do this, open Win32 Disk Imager.
Allow it to make changes to the system.
Select the image file that you just created.
Ensure that your microSD card is selected in the Device drop-down.
Then click on Read.
This will read the contents of the microSD card and write them to the .IMG file.
Utilizing backups like this will allow you more flexibility in experimenting. If you get your Pi setup perfectly, but you would like to try something, make a backup before you make the change. If the change doesn’t work out, you can easily restore to the previous setup. Exactly where you left off. If the experiment does work, make a new backup!
New Project Tasks
When you are ready to start a new project and you have flashed your microSD card, there are a few things you will want to make sure that you do after your Pi is up and running.
If you are using the same Pi for all of your projects, no need to worry about getting a new IP address.
However, if you’re using a different Pi, and you have hard coded a static IP address into dhcpcd.conf, make sure you change this to avoid IP address conflict issues. Your router may simply assign another IP address to your Pi if the one you have in your dhcpcd.conf file is currently in use. This isn’t guaranteed.
In our backup image, the hostname is basline. I recommend changing this to more accurately describe the project you are working on.
Project Specific User Accounts
I do recommend creating separate accounts for your projects. For example, I am already working on my next blog post. In that post I am writing about how to use the Raspberry Pi as a web server. I take this baseline setup, but add on to it. I add another user account for the website that I am going to be hosting. The reason for this is because I do not want to host a website out of an account that has sudo privileges. If your project is going to be publicly accessible and doesn’t require sudo privileges, I would highly recommend this. Just make sure to generate public/private keys for this new user as well.
Post Publish Additions:
Check Boot Partition Size
Added on 5/27/2018
It came to my attention as I started working on a new Raspberry Pi project that I didn’t have it documented how to check to see if your image is already expanded to the entire microSD card. The utility you can use to check this is lsblk (list block devices). For me, the following is what I saw after I had just burned my 8 GB image onto a new 32 GB microSD card:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
mmcblk0 179:0 0 29.7G 0 disk
mmcblk0p1 179:1 0 41.8M 0 part /boot
mmcblk0p2 179:2 0 7.8G 0 part /
Looking at the last line I could tell that my image was not expanded to the entire microSD card.
To expand the boot partition to the entire microSD card, I used the raspi-config utility. Navigate to Advanced Options then select Expand Filesystem. raspi-config will do it for you. After rebooting lsblk should display something similar to the following:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
mmcblk0 179:0 0 29.7G 0 disk
mmcblk0p1 179:1 0 41.8M 0 part /boot
mmcblk0p2 179:2 0 29.7G 0 part /