[GUIDE] Raspberry Pi 3 server setup

So I have previously done a tutorial on setting up an email server on a Raspberry Pi 2.

This post is not going to contain the email server element (yet). What it is going to detail is setting up a Raspberry Pi 3 which I received for Xmas as a headless server.

This is also an exercise for me to learn Markdown which I am using to compose these posts.

Regards

Ro55mo

Table of contents

  1. Prepare image and boot
  2. Connect via SSH
  3. Set static IP and hostname
  4. Create a new user
  5. Update and upgrade
  6. Remove default user
  7. Configure SSH ports
  8. Configure firewall (iptables)
  9. Setup SSH keys
  10. Autoupdate script

Prepare image and boot

Download the image file of Raspbian from this link.

Once this is done, extract the image file and wirte it to your MicroSD card via a USB adapter. If you are using Windows, Win32 Disk Imager is a suitable tool.

If you are using Linux you will likely already have a suitable GUI utility installed on your machine. If not you can always use dd.

At the time of writing I am using the new PIXEL version of Raspbian. This update of Raspbian now has SSH closed by default on boot.

To enable SSH, we need to do is to put a file called ssh in the /boot/ directory. This can just be an empty text file.

Once complete, eject the MicroSD card from the PC and then remove the USB adapter. Take the MicroSD card from the adapter and place it in your Raspberry Pi.

Insert an ethernet cable into the Raspberry Pi ethernet port and then insert the other end of the cable into your router / modem, assuming it has a suitable ethernet port or into a switch.

Now attach the power cable to your Raspberry Pi and it will boot.

Connect via SSH

So now we have a Raspberry Pi connected to your network but without any monitor, mouse or keyboard connected to it. So we are going to connect via SSH if you are on Linux or PuTTY if you are on Windows.

In order to do this we need to find the new devices IP address. This assumes that a device on your network, probably your modem / router is configured to hand out dynamic IPs via DHCP.

One way to do this is to login to your modem / router and find that page that lists all devices on your network. Another way is a quick scan of your subnet with nmap.

nmap -p 1-1024 192.168.0.0/24

The above command will scan the first 1024 ports of each IP in the range 192.168.0.0 with a 24 bit mask.

And lo. The desired information is returned.

Nmap scan report for 192.168.0.35
Host is up (0.0036s latency)
Not shown: 1023 closed ports
PORT STATE SERVICE
22/tcp open ssh

Now we can connect from the terminal with the command with the default password.

ssh -p 22 [email protected]

The first thing to do is enter the following command

sudo raspi-config

And then run through the presented options. Most importantly the ones to expand the file system to fill the whole MicroSD card, disable the desktop environment and set the time. We don't need to change the default password as we will delete the user "pi" later on in any case.

When you are done with the raspi-config tool select < Finish > and then reboot the Raspberry Pi. After a few seconds you will be able to login again as we did before.

Set a static IP and hostname

Enter the following command to edit the interfaces file.

sudo nano /etc/network/interfaces

Edit the file so it resembles the following where 192.168.0.7 is the static IP you want your Raspberry Pi to have and your default gateway is 192.168.0.1

auto lo
iface lo inet loopback

auto eth0
allow-hotplug eth0
iface eth0 inet static
address 192.168.0.7
netmask 255.255.255.0
gateway 192.168.0.1

auto eth0:0
allow-hotplug eth0:0

allow-hotplug wlan0
iface wlan0 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

allow-hotplug wlan1
iface wlan1 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

Enter the following command to edit the hostname file.

sudo nano /etc/hostname

Delete the existing entry and give your raspberrypi a new name.

I am using the name “Oort” as this Raspberry Pi will form the basis of a personal cloud storage device. Exit and save the file.

Enter the following command to edit the hosts file.

sudo nano /etc/hosts

It should like this when you are done.

127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters

127.0.1.1       Oort

Exit and save the file.

Remember to update the hosts file on your own PC.

I personally want to disable the Wi-Fi and Bluetooth that come on the Raspberry Pi 3 as I won't be using them.

Enter the following command to edit the driver blacklist file.

sudo nano /etc/modprobe.d/raspi-blacklist.conf

Enter the text below and then exit, saving the file as you go.

#wifi
blacklist brcmfmac
blacklist brcmutil
#bt
blacklist btbcm
blacklist hci_uart

Now reboot the Raspberry Pi with the following command.

sudo shutdown -r now

#Create a new user

The point of the next few sections is to secure the Raspberry Pi.

Connect via SSH on the new IP address.

ssh -p 22 pi@Oort

This command assumes the user you want to create is called ‘voyager’.

sudo adduser voyager

You should be prompted for a user password and additional details.

Enter the following command to add the user to the sudo’ers file so it can perform administrative commands.

sudo adduser voyager sudo

Enter the command.

logout

Update and upgrade

Login with the new user.

ssh -p 22 voyager@Oort

Enter the following commands one at a time.

sudo apt-get update

sudo apt-get upgrade

The commands should execute successfully. This also proves that the new user can perform administrative actions.

This process seems to take a lot longer with the new PIXEL version of Raspbian. Be patient.

Remove default user

Enter the following command.

sudo userdel -r pi

You can verify the "pi" user account is gone with the following command.

awk -F: '/\/home/ {printf "%s:%s\n",$1,$3}' /etc/passwd

Configure SSH ports

Enter the following command.

sudo nano /etc/ssh/ssh_config

Uncomment and edit the line containing “Port”. Change the number 22 to something between 49152 and 65535. Exit and save the file. Let's assume we choose port 65000.

Enter the following command.

sudo nano /etc/ssh/sshd_config

Edit the line containing “Port” to the same number you chose above. Exit and save the file.

These numbers can be different if you want, I just have them the same for the sake of convenience.

The first file controls the SSH port your Raspberry Pi communicates out on. The second file controls the port that you connect to your Pi on from your own client computer.

Reboot your Raspberry Pi with the command.

sudo shutdown -r now

Once it has been rebooted you should be able to connect with the following command.

ssh -p 65000 voyager@Oort

Configure firewall (iptables)

Enter the following command to elevate to root.

sudo su

nano /etc/iptables.firewall.rules

Paste in the following text.

*filter

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

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

#  Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

#  Allow SSH connections
#  The -dport number should be the same port number you set in sshd_config
-A INPUT -p tcp -m state --state NEW --dport 65000 -j ACCEPT

# Ping from inside to outside
-A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
-A INPUT -p icmp --icmp-type echo-reply -j ACCEPT

# Ping from outside to inside
-A INPUT -p icmp --icmp-type echo-request -j ACCEPT
-A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT

#  Log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

#  Drop all other inbound - default deny unless explicitly allowed policy
-A INPUT -j DROP
-A FORWARD -j DROP

COMMIT

Make sure you change the SSH connection port to the same number you choose in the sshd_config file. Failure to do so will mean we will lose connection to the Raspberry Pi after a reboot.

Activate the rules with the following command.

iptables-restore < /etc/iptables.firewall.rules

And check with the following command.

iptables -L

Now we have to create a method to reload the rules after a reboot.

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

Paste in the text below.

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

Quit and save the file.

Enter the following command to make the script executable.

chmod +x /etc/network/if-pre-up.d/firewall

Now reboot the Raspberry Pi.

shutdown -r now

Reconnect to the Raspberry Pi on the new port you entered in the sshd_config file and allowed access to in the iptables config file.

ssh -p 65000 voyager@Oort

When you setup other services on the Raspberry Pi you will of course have to edit the "iptables.firewall.rules" file and reload the rules.

Setup SSH keys

To make SSH access to the Raspberry Pi secure we will setup SSH keys and then disable password login.

On your client PC open a terminal and type

ssh-keygen -t rsa

You will be prompted to enter a passphrase but you don't have to. Just hit the return / enter key twice.

The key pair will be placed at /home/username/.ssh/id_rsa.pub The private key located at /home/username/.ssh/id_rsa

Now we need to copy the public key to the Raspberry Pi.

Open /home/username/.ssh/id_rsa.pub with a text editor. Copy the contents.

Login to the Raspberry Pi

Navigate to /home/voyager/

Enter the commands

mkdir .ssh

cd .ssh

nano authorized_keys

Paste in the contents of /home/username/.ssh/id_rsa.pub

Close and save the file.

Logout of the Raspberry Pi.

Now log back into the Raspberry Pi with

ssh -p 65000 voyager@Oort

You should be logged in with being prompted for a password.

Edit the following file.

sudo nano /etc/ssh/sshd_config

Change the following section.

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

Exit and save the file.

Enter the following command.

sudo shutdown -r now

After a minute log back into the Raspberry Pi with the command.

ssh -p 65000 voyager@Oort

To verify this as working download an SSH client to your phone, turn on the phones Wi-Fi so you are on the same local network as the Raspberry Pi and then try and SSH to it. Remeber to use the Raspberry Pis IP address in this case. You should be denied access.

Congratulations. You have installed, updated and somewhat hardened your Raspberry Pi. It is now safe(ish) to expose to the Internet.

Autoupdate script

Now I totally understand if you don’t want to do this section as it could break the system at a later date but as it is only my information on the Pi I am happy to do this.

On the Pi at the command line elevate yourself to root and move to /root with

sudo su

cd /root

Create the script

nano autoupdate

and paste in the following text

#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
apt-get update
apt-get upgrade -y
apt-get autoremove -y

Exit and save the file.

Make the script executable with

chmod +x autoupdate

and now add it to the crontab file by entering the following command

crontab -e

And adding the last line of this example.

# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command
30 1 * * 1 sh /root/autoupdate

Now at 01:30 every Monday your Pi will autoupdate itself.

You can verify this as working by checking

/var/log/dpkg.log