Raspberry Pi

Guide for the initial, bare-bones setup of a Raspberry Pi.

The Raspberry Pi is a small, inexpensive, single-board computer system that retails for about $35 USD. It is one of the simplest and most cost-effective ways of powering digital infrastructure services for a small- to medium-sized group of comrades who need secure access to various telecommunications and coordination tools. You can think of a Raspberry Pi as a small-scale equivalent of your own private “cloud” service offering, replacing the need to create accounts with Google, Microsoft, or Apple, Inc.

Hardware setup

TK-TODO

Software setup

Operating System installation

Installing NOOBS

TK-TODO

See Raspberry Pi Foundation: Installing NOOBS for now.

Post-OS install checklist

The following tasks should be performed after every clean installation of the Operating System (such as NOOBS, Raspbian, etc).

  1. Provide the Raspberry Pi with Internet connectivity; this is usually as simple as connecting to a Wi-Fi network (if your model Pi has a built-in Wi-Fi card), plugging in an ethernet cable attached to a modem provided by your ISP into the Raspberry Pi’s physical network port (its NIC), or inserting an external Wi-Fi device and setting up Wi-Fi via the command line.
    1. Check for successful connectivity by attempting to contact a remote server, perhaps by invoking ping 1.1.1.1 or ping 8.8.8.8 or ping 9.9.9.9. The first is Cloudflare’s public DNS resolver, the next is Google’s public DNS resolver, and the latter is the non-profit group Quad 9’s public DNS resolver, which both respond to WAN-side pings. If you receive a response, you are connected.
    2. If you do not read a reply, check that the Raspberry Pi has obtained an IP address: ip addr | grep inet. You should see at least one IP address in a routable range (such as 192.168.XXX.XXX, where XXX is a number from 1 to 254).
    3. Next, check that your local DNS resolver is configured correctly, so that you can use addresses such as google.com instead of its numeric IP address. Inspect the contents of the plain-text file at /etc/resolv.conf on your local filesystem; if in doubt, replace its contents using the following command invocation:
      echo "nameserver 9.9.9.9" > /tmp/resolv.conf && sudo cp /tmp/resolv.conf /etc/resolv.conf # Use Quad 9, a security-conscious provider.
      
      1. Finally, some network configurations will confuse the resolvconf utility, which is responsible for updating the resolv.conf file, and your changes will be automatically overwritten. To disable this, append resolvconf=NO to your system’s /etc/resolvconf.conf file.
  2. Update the installed packages.
    • For a Debian-based system, this is usually accomplished using the sudo apt update and sudo apt upgrade commands performed in sequence.
    • For a RedHat-derived system, this is usually accomplished using the sudo yum update command.
  3. Update the device’s firmware and boot code. Raspbian-based Operating Systems (such as NOOBS) supply the rpi-update utility for this purpose. Invoke it with root privileges using the sudo rpi-update command.
  4. Reboot the Raspberry Pi to activate the new firmware:
    sudo shutdown -r now
    
  5. Configure locale and regional settings. Raspbian-based Operating Systems (such as NOOBS) supply the raspi-config utility for this purpose. Invoke it with root privileges using the sudo raspi-config command.
    1. First, update the raspi-config utility itself to make sure you have the latest version.
    2. Set the correct keyboard layout.
    3. Configure other Raspberry Pi system settings as desired. Recommendations:
      1. Change the default password. (By default, most Raspbian-derived OS installations create a pi user with the password set to raspberry, as documented by the Raspberry Pi Foundation. This should be changed to a strong pass phrase and stored securely by a trusted administrator.)
      2. Disable automatic login: Boot OptionsDesktop / CLIConsole (Text console, requiring user to login.)
      3. Disable the camera interface: Interfacing OptionsCameraNo
      4. Disable the Raspberry Pi’s VNC server: Interfacing OptionsVNCNo
      5. Disable the Raspberry Pi’s SPI interface: Interfacing OptionsSPINo
      6. Disable the I2C interface: Interfacing OptionsI2CNo
      7. Disable login over the serial interface: Interfacing OptionsSerialNo
      8. Disable the 1-Wire interface: Interfacing Options1-WireNo
      9. Disable the remote GPIO interface: Interfacing OptionsRemote GPIONo
  6. Tune the filesystem:
    1. Enable automatic filesystem integrity checking, for example by invoking the following command, making sure to replace root with the correct label of your filesystem:
      sudo tune2fs -i 1m "LABEL=root"
      

Consider following the above procedure with a security hardening guide relevant for your chosen Operation System. For example, as Raspbian is a Debian-derived OS, read the Securing Debian Manual and perform the hardening steps described there to further secure the Operating System itself.

Essential security tooling installation

Once the Operating System is installed, updated, and configured, you should consider taking extra security precautions. This section describes a non-exhaustive listing of additional steps to take to further secure your installation. As mentioned earlier, refer to the Securing Debian Manual for additional recommended security hardening steps.

dm-crypt

If you did not encrypt your hard drive(s) during the Operating System installation, you can (and should?) do so as soon as possible thereafter.

TK-TODO

Tor

Tor is an anonymizing overlay network known as a mix network (or "mixnet" for short). It sits in between your application(s) and your network connection, providing an extra layer of protection between your (self-hosted) services and the public Internet. Tor is useful for privacy-enhanced communication, cryptographic naming services (through its Onion service or “hidden service” features), and firewall traversing capabilities.

See the Tor page for a further treatment of using Tor as an infrastructure provider. The remainder of this section considers Tor in the specific context of a Raspberry Pi.

Install Tor on a Raspberry Pi 1 running Debian-based GNU/Linux

The Raspberry Pi 1 (all models) have an older, ARM CPU. You can confirm this by running uname -m at a command line. The output will be something like armv6l, indicating an older ARM chip. (Newer Raspberry Pi’s, the Raspberry Pi 2 and the Raspberry Pi 3, ship with a newer ARM chip, which report armv7l when queried with uname -m). This older version of the processor requires us to build Tor packages from source.

NOTE: You can also install Tor “the easy way” by doing sudo apt install tor, but this is unlikely to provide you with a stable, officially supported version of Tor. Installing Tor this way on a Raspberry Pi 1 will mean your Tor installation will lack critical security patches. If you do not want to follow these instructions, consider acquiring a Raspberry Pi 2 or a Raspberry Pi 3, instead.

The Tor Project maintains simple instructions for building Tor from source, which work nicely on a Raspberry Pi 1. Those instructions are duplicated here in our own voice, but refer to the primary source at the linked page for the most up-to-date information.

Install Tor on a Raspberry Pi 2 or 3 running Debian-based GNU/Linux

Installing Tor on a Raspberry Pi model 2 or 3 is usually as simple as sudo apt install tor, but be certain to check the version of Tor available in your Operating System distribution’s package repositories:

sudo apt update && apt show tor | grep -i version

Compare the version of Tor available from the command output above to the latest stable versions available from the Tor project.

Alternatively, and if the repositories are too far out of date, you can also build Tor from source yourself.

Secure Shell

Raspbian-derived systems automatically install OpenSSH. However, you should check the version (using ssh -V) and update if necessary (using sudo apt update && sudo apt install openssh-server), as well as harden the default installation to avoid known vulnerabilities.

See SSH for details.

Software installation

Once the Operating System is installed, updated, and configured, you can further customize your system by choosing purpose-specific software tools for your use case. Some examples:

  • Calibre – E-book management suite.
  • Git – Distributed version control system suite with client and server capabilities.
  • Lighttpd – Lightweight Web server software.
  • Radicale – Simple and extensible CalDAV and CardDAV server software.
  • rsync – Fast, powerful, and network-capable filesystem synchronization tool.

You can, of course, run any software you wish on your Pi. See the Awesome Selfhosted list for quality recommendations.

Post-software installation security considerations

After you have installed a given software package, consider performing the following steps to ensure the tool does not compromise you or your comrades.

Network security

Audit listening ports

TK-TODO

Remove identifying service information from banners and headers

Many network services provide details about their implementation to clients attempting to make use of those services. For instance, Web servers often identify themselves as a certain piece of software at a specific version. This information is useful to attackers and should therefore be limited or omitted.

For example, if you run the Lighttpd HTTP server, you could remove the HTTP Server header from its responses to clients with the following configuration line in your server’s /etc/lighttpd/lighttpd.conf file:

server.tag = ""

This limits the amount of information attackers can acquire about your infrastructure.

Different services will have different identifying details and will need to be configured in different ways.

By way of another example, Debian-based GNU/Linux distributions that ship with OpenSSH have an additional SSH configuration directive to remove Operating System information from the server’s SSH header. Consider adding the following to your server’s /etc/ssh/sshd_config file:

DebianBanner no

Be certain to check the specific service you are running for security hardening instructions before making that service available to a wider populace.

Host-based security precautions

Disable logging

Most of the time, activity logging is used for debugging and troubleshooting purposes, or as a collection engine for future analytics, typically in the service of surveillance capitalism. Therefore, unless you need to debug a problem, it is recommended that you disable the logging behavior of as many running services as possible, as much as possible. You can always re-enable logs for a short time during troubleshooting efforts if you need to.

Disable login logging

Out of the box, most Operating Systems maintain various logs of user logins (both successful and unsuccessful attempts), sometimes along with a remote IP address of the source destination. Consider removing the logs of successful logins, but retain the unsuccessful attempt logs so that you may monitor your system for brute force password guessing attacks.

A non-exhaustive list of the various successful login logs that you may wish to audit or nullify on your system include:

  • /var/log/lastlog – Most recent login times for each user, which can be viewed using the lastlog(1) command.
  • /var/log/utmp – List of current active login sessions, used by commands such as who(1).
  • /var/log/wtmp – Historical log of past successful logins, which can be viewed using the last(1) command. Be sure to check for the existence of /var/log/wtmp.1, /var/log/wtmp.2, etc., as well.

Meanwhile, a non-exhaustive list of the various unsuccessful login logs that you may wish to audit or nullify on your system include:

  • /var/log/btmp – Historical log of past unsuccessful logins, which can be viewed with the lastb(1) command.
  • /var/log/faillog – TK-TODO.

Replace the wtmp and lastlog files with a symbolic link to /dev/null in order to disable it:

sudo rm /var/log/wtmp* /var/log/lastlog # Remove all historical successful login logs.
sudo ln -s /dev/null /var/log/wtmp      # Put symbolic links in place of these files.
sudo ln -s /dev/null /var/log/lastlog

The utmp file cannot be removed on GNU/Linux kernels (it will be recreated on boot), but it can be protected by removing world-readable permissions from the file:

sudo chmod o-r /var/run/utmp # Disallow access to `who(1)` and similar functions for regular users.

See also §4.11.3 of the Securing Debian Manual for more information about login logging, or login.defs(5) in the manual.

Disable service logs

If you run a service that you cannot stop from logging, you may have a number of other options:

  • Configure the service to send its log to the special device file, /dev/null.
  • Make a symbolic link (“symlink”) from the original log file’s location to the /dev/null file:
    ln -s /dev/null /path/to/the/logfile.log
    
  • Utilize your system’s logrotate(8) facility to aggressively shred log files.
Shredding log files with logrotate

If you cannot create a situation where zero information is logged to disk, you can still clean up after the service’s daemon yourself by using your system’s built-in log rotation facility, which is likely the logrotate(8) utility. For each service you add that writes logs, create a file in the /etc/logrotate.d directory. That file should contain a logrotate configuration, similar to the following example:

# This is an example to show how you can use logrotate to eradicate a service's logfiles.
/path/to/server/log.txt {
        daily
        copytruncate
        rotate 0
        size 1
        shred
        missingok
        nomail
        postrotate
                shred --remove /path/to/server/log.txt.1
        endscript
}

Restrict process privileges with systemd

When writing systemd service units, consider including the following directives in the unit’s [Service] section to harden the service unit’s execution context:

# Harden the unit's execution context.
# See systemd.exec(5) for more details about these directives.

# Deny attempts to create writable and executable memory.
MemoryDenyWriteExecute=true

# Deny access to `execve()` to help prevent exploitation of potential privilege escalation vulnerabilities.
NoNewPrivileges=true

# Restrict access to physical storage media.
# With `PrivateDevices=true`, the process can only access data through mounted filesystems
# and not by accessing the block devices (under `/dev`) that make up the disk itself.
PrivateDevices=true

# Restrict access to network interfaces.
# This should only be enabled for services that should not have access to the network.
#PrivateNetwork=true

# Protects the `/tmp` directory by giving each process its own `/tmp` hierarchy.
PrivateTmp=true

# Re-map the process's own user namespace so it is disconnected from other processes's user namespace.
PrivateUsers=true

# Makes the `/sys/fs/cgroup` directory hierarchy read-only to all processes of the unit.
ProtectControlGroups=true

# Makes the `/home`, `/root` and `/run/user` directories inaccessible and appear empty to the unit's processes.
ProtectHome=true

# Disallows the process from making modifications to loaded kernel modules.
ProtectKernelModules=true

# Disallows the process from making changes to kernel variables (such as those set via `sysctl(8)`).
ProtectKernelTunables=true

# When set to `true`, this makes the `/usr` and `/boot` directories read-only.
# When set to `full`, this additionally makes the `/etc` directory hierarchy read-only, as well.
ProtectSystem=full

# Disallows the process from changing the default Linux kernel personality. See `personality(2)` for details.
LockPersonality=true

# Disallows the process from using sockets other than UNIX domain, IPv4, and IPv6 sockets.
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6

# Disallows the process from using kernal scheduling APIs to change the CPU scheduler's settings; see `sched(7)` for deatils.
RestrictRealtime=true