Raspberry Pi 4
Introduction
Let's start
Chicken or the egg
SSH, set up your client
Static IP, WiFi, BT and IPv6
Updating & upgrading
Hostname and SSH
raspi-config
What's my temperature?
Housekeeping

Log2Ram
Securing SSH with FIDO2
Bluetooth
USB WiFi
Go
Docker / Docker Compose
 

Introduction

There is an infinite amount of information on the web about installing and configuring a Raspberry Pi 4 Model B. And this was exactly my problem to find the right information here. There are certainly many options that lead to the goal. This is just my way doing the configuartion.

Let's start

The Raspberry Pi (RPi) will later be operated without a display and keyboard. Therefore the Raspberry Pi OS Lite (Bullseye) 64-bit image is used. I used the version from 2022-01-28. After downloading the ZIP file, it can be transferred to the SD card with e.g. ApplePi-Baker v2.

SSH will later be used to connect to the RPi. But SSH is turned off for security reasons. SSH can be enabled by placing a file named ssh, without any extension, onto the boot partition of the SD card [Source].

Chicken or the egg

After switching on, it may take about 30 seconds before we can access the RPi. But how we can connect to the RPi if we do not know the IP address? The RPi use DHCP for requesting an IP address. Perhaps you can get the DHCP info from your router if you are in a home network. Furthermore I found examples for nmap how to get the IP information. But I think that nmap is a very bad idea if you are in an enterprise network. Note: The Avahi daemon (mDNS) is started by default at the RPi and the default hostname is raspberrypi.

If you are using Linux or Mac OS X try to use the following command in a terminal:

  • ping raspberrypi.local

In case of Windows try to use the following commands in a dos box:

  • ping raspberrypi.local
  • ping raspberrypi.
  • ping raspberrypi

Yes, there is a dot at the end of the line for the second ping. Hopefully you have now the IP address of your RPi. We can now use this address to connect to the RPi by SSH.

SSH, set up your client

Here I make it easy for myself with the description. Please take a look in the original Raspberry Pi documentation under Passwordless SSH Access.

Btw, the default user is pi and the default password is raspberry. Assuming you are using Windows with PuTTY, the first connections will look like:

The first thing to do is change the password with the following command:

  • passwd

Next I will set a static IP address, and disable WiFi, Bluetooth and IPv6.

Static IP, WiFi, BT and IPv6

How to configure a static IP address can be find here. In general some changes must be done in /etc/dhcpcd.conf. Here I will use nano for the editor. Therefor the following command is used:

  • sudo nano /etc/dhcpcd.conf

The next lines are just an example. They need to be changed according to your infrastructure:

interface eth0
static ip_address=192.168.0.4/24
static routers=192.168.0.254
static domain_name_servers=192.168.0.254 8.8.8.8

Next WiFi and Bluetooth will be disabled. Therefore some lines must be added to the /boot/config.txt. Here the following command is used:

  • sudo nano /boot/config.txt

The following lines must be added [Source]:

dtoverlay=pi3-disable-wifi
dtoverlay=pi3-disable-bt

And for disabling IPv6 the content of /etc/modprobe.d/ipv6.conf must be changed. Therefore type:

  • sudo nano /etc/modprobe.d/ipv6.conf

And add the following lines [Source]:

alias net-pf-10 off
alias ipv6 off
options ipv6 disable_ipv6=1
blacklist ipv6

After these changes make a reboot with:

  • sudo reboot

After the reboot, PuTTY will lose the connection. Be in mind that you must use your new IP address for the next PuTTY session.

Updating & upgrading

This is easy again. Please take a look in the original Raspberry Pi documentation. Open a new PuTTY session and type:

  • sudo apt update
  • sudo apt -y full-upgrade
  • sudo reboot

This can take a while. But at the end the software is up to date.

Hostname and SSH

I want to change the hostname raspberrypi. But after changing the hostname, a new SSH key should be created too. For this procedure I found a description here. But unfortunately the hostname command does not work in my case. Therefore I changed the procedure a little bit. I want to use pi4 for the new hostname. The following commands are now required:

  • sudo raspi-config nonint do_hostname "pi4"
  • sudo reboot
  • sudo rm /etc/ssh/ssh_host_*
  • sudo dpkg-reconfigure openssh-server
  • sudo reboot

The next step is to change some settings like localisation with raspi-config.

raspi-config

raspi-config will be described by the original Raspberry Pi documentation here. But instead of using the GUI, you can change the settings from the command line too. I will change the Boot Options to B2, Localisation to Europe/Berlin, Memory Split to 16 and expand the filesystem. Therefore the following commands are needed:

  • sudo timedatectl set-timezone Europe/Berlin
  • sudo raspi-config nonint do_wifi_country DE
  • sudo raspi-config nonint do_boot_behaviour B2
  • sudo raspi-config nonint do_memory_split 16
  • sudo raspi-config --expand-rootfs
  • sudo reboot

I found additional information on this on the following page. For security, I have put the overview of the raspi-config command line options here again.

What's my temperature?

Perhaps it is interesting to monitor the temperature of the RPi. A description of this can be found on the following page. But in short, use the following commands:

  • cd
  • nano my-pi-temp.sh

And copy the following lines:

#!/bin/bash
# Script: my-pi-temp.sh
# Purpose: Display the ARM CPU and GPU temperature of Raspberry Pi 2/3
# Author: Vivek Gite www.cyberciti.biz under GPL v2.x+
# -------------------------------------------------------
cpu=$(</sys/class/thermal/thermal_zone0/temp)
echo "$(date) @ $(hostname)"
echo "-------------------------------------------"
echo "GPU => $(vcgencmd measure_temp)"
echo "CPU => $((cpu/1000))'C"

Now we must set the permission for the new file too:

  • chmod +x my-pi-temp.sh

And now we can use the new script with the following command:

  • ./my-pi-temp.sh

Housekeeping

From time to time you should check for updates and upgrade your system like described here. In short, use the following commands:

  • sudo apt update
  • sudo apt full-upgrade
  • sudo apt clean

The official documentation for the Raspberry Pi can be find here.




Log2Ram

Log2Ram can be used to extend the sd card lifetime of a Raspberry Pi. To avoid writing too many times log data, Log2Ram will be used. More information can be find here and here. To make it short again:

  • sudo apt-get install git
  • cd /home/pi
  • git clone https://github.com/azlux/log2ram.git
  • cd log2ram
  • chmod +x install.sh
  • sudo ./install.sh
  • sudo nano /etc/log2ram.conf
  • sudo reboot

Securing SSH with FIDO2

Here I use a security key from Yubico for which there is also a description available. I will use the Non-discoverable keys here. For the creation of the key, however, a few prerequisites must still be met. The libfido2 library and a corresponding version of OpenSSH are required here.

Under macOS I assume that Homebrew is available. Here the following commands are used in the terminal to update libfido2 and OpenSSH:

  • brew install libfido2
  • brew install openssh

On Linux, a Debian Edition, SSH was available in a version greater than 8.2 and therefore no update was necessary here. However, if your SSH version is lower than 8.2, an update is required. It may also be necessary to update libfido2 as well.

Under Windows, here Win10 21H2, SSH was available in version 8.1 and therefore an update was required. I used the update from GitHub, it was the version v8.9.1.0p1-Beta and here specifically the "OpenSSH-Win64.zip" file. I had also tested it with the msi file, but this didn't work for me. So I unpacked the zip file in my tools directory and then added the new OpenSSH path to the system path and not to the user path.

If the version of SSH is greater than or equal to 8.2, a key protected with FIDO2 can now be generated. It is helpful for later use if a comment is also given for the key in order to be able to better distinguish between the keys later. In the example here I use a "blue" and "black" key and want to use it to secure the SSH access to a Raspberry Pi.

It doesn't matter now whether macOS, Linux or Windows is used. The commands for generating and transferring the keys are the same in the terminal. For the example I use the Windows Terminal here.

After connecting the Yubikey use the following command to generate the "blue" key:

  • ssh-keygen -t ed25519-sk -C "blue"

There are two windows here. Once an info that you want to log in as openssh with ssh. And second, the info that ssh will display the brand and model of the key. Then you will be prompted to tap on the key. Furthermore, you have to specify the complete path of the key and the key name.

For the "blue" key I used the following input: C:\Users\win10/.ssh/pi_sk_blue_key

The display in the terminal looked like this:

The "black" key is generated accordingly. The following 4 files have now been created in the .ssh directory:

Next, the public keys have to be transferred to the Raspberry Pi.

Oops, I should have used macOS or Linux as an example and not Windows. I just noticed that there is no ssh-copy-id command in Windows :o(

Normally the following command can be used to copy the public key to the remote server:

  • ssh-copy-id -i public-key user@host

But not here under Windows. It doesn't matter, we'll get that resolved now too.

Log in to the Raspberry Pi, with user and password, and use the following commands:

  • cd
  • mkdir .ssh
  • cd .ssh
  • touch authorized_keys
  • chmod 600 authorized_keys

Next, the public keys from Windows must now be copied to authorized_keys on the Raspberry Pi. To do this, the authorized_keys file is opened with nano on the Raspberry Pi:

  • nano authorized_keys

We now have a window with a SSH connection where nano is open.

Now the file pi_sk_blue_key.pub is opened in the editor on the Windows computer. The content is copied to the clipboard. Select the nano window and past the content of the clipboard. This has now copied the content of the pi_sk_blue_key.pub file from the Windows computer to the authorized_keys file on the Raspberry Pi.

Now the same process has to be repeated for the pi_sk_black.pub file. The authorized_keys file should now contain the additional two lines, both starting with sk-ssh-ed25519 and ending with blue and black respectively.

The authorized_keys file can now be saved and closed. Log out to close the SSH session.

Now we can try to login by SSH without a password, protected by FIDO2. The syntax for the login looks like:

  • ssh -i public-key user@host

In the example here, the user is pi and the host is 192.168.1.60. A login with the blue key looks like this:

  • ssh -i C:\Users\win10\.ssh\pi_sk_blue_key pi@192.168.1.60

After executing this command you will be prompted to connect the corresponding key if this is not already the case. If the key is already connected, you will be prompted to tap. If the wrong key is connected, you will also get a corresponding message.

And here is the command for the black key:

  • ssh -i C:\Users\win10\.ssh\pi_sk_black_key pi@192.168.1.60

You can simplify the login a bit with a config file. Information such as public-key file, user and host are stored in the file. The config file is a text file with the simple name config. The file is in the .ssh directory where the keys are also stored.

In our example, the config file has the following content:

A login with the blue key can now be done with the following command:

  • ssh pi_blue

And for the black key:

  • ssh pi_black

But why two keys in this example?

You cannot backup a key. If a backup is needed, one more key must always be used as a backup. If you ever lose a key, you can identify it by the comment in the authorized_keys file and delete it.

Blue and black, Matrix?

No, here I am using a blue yubico Security Key NFC and a black YubiKey 5 NFC. In both cases the key with the USB-A Interface was used.

Bluetooth

I thought that the drivers for Bluetooth are easy to install. But it turned out to be a bigger puzzle. I wanted to use the following Bluetooth dongle here, TBW-106UB. The first steps were easy and looked like this:

  • sudo apt-get update
  • sudo apt-get upgrade
  • sudo apt-get autoremove
  • sudo apt-get install bluetooth bluez blueman
  • /etc/init.d/bluetooth status

Unfortunately, there was the following errors when querying the status:

pi4 bluetoothd[1019]: profiles/sap/server.c:sap_server_register() Sap driver initialization failed.
pi4 bluetoothd[1019]: sap-server: Operation not permitted (1)
pi4 bluetoothd[1019]: Failed to set privacy: Rejected (0x0b)

To fix the problem with the sap server, line with ExecStart of the file:

/etc/systemd/system/bluetooth.target.wants/bluetooth.service

file must be changed as follows:

ExecStart=/usr/libexec/bluetooth/bluetoothd --noplugin=sap

Here "--noplugin=sap" was added. But after a reboot there was still an error when querying the status:

pi4 bluetoothd[1019]: Failed to set privacy: Rejected (0x0b)

In order to solve this problem as well, the file:

/lib/systemd/system/bthelper@.service

must be changed as follows:

[Unit]
Description=Raspberry Pi bluetooth helper
Requires=hciuart.service bluetooth.service
After=hciuart.service bluetooth.service
Before=

[Service]
Type=oneshot
ExecStartPre=/bin/sleep 2
ExecStart=/usr/bin/bthelper %I
RemainAfterExit=yes

This is just a summary of the informations that are available here, here and here.

USB WiFi

The Aircrack-ng tool, for example, is available for the security analysis of your own WLAN network. However, a WiFi adapter and a driver that supports the monitor mode are required here. But not every adapter supports monitor mode, or runs on the RPi without a corresponding driver.

I found a very good source for USB WiFi Adapter Information for Linux here. With the information there I was able to install the drivers for RTL8812AU, RTL8821AU and RTL8812BU without any problems. A detailed description of the installation can be found on the corresponding pages.

But here is the quick run for the RTL8812AU driver:

  • sudo apt update && sudo apt upgrade
  • sudo apt install -y raspberrypi-kernel-headers bc build-essential dkms git
  • mkdir -p ~/src
  • cd ~/src
  • git clone https://github.com/morrownr/8812au-20210629.git
  • cd ~/src/8812au-20210629
  • ./ARM64_RPI.sh
  • sudo ./install-driver.sh NoPrompt
  • sudo reboot

And here is the quick run for the RTL8821AU driver:

  • sudo apt update && sudo apt upgrade
  • sudo apt install -y raspberrypi-kernel-headers bc build-essential dkms git
  • mkdir -p ~/src
  • cd ~/src
  • git clone https://github.com/morrownr/8821au-20210708
  • cd ~/src/8821au-20210708
  • ./ARM64_RPI.sh
  • sudo ./install-driver.sh NoPrompt
  • sudo reboot

And here is the quick run for the RTL8812BU driver:

  • sudo apt update && sudo apt upgrade
  • sudo apt install -y raspberrypi-kernel-headers bc build-essential dkms git
  • mkdir -p ~/src
  • cd ~/src
  • git clone https://github.com/morrownr/88x2bu-20210702
  • cd ~/src/88x2bu-20210702
  • ./ARM64_RPI.sh
  • sudo ./install-driver.sh NoPrompt
  • sudo reboot

And here is the quick run for the RTL8188EUS driver:

  • sudo apt update && sudo apt upgrade
  • sudo apt install -y raspberrypi-kernel-headers bc build-essential libelf-dev dkms git
  • mkdir -p ~/src
  • cd ~/src
  • sudo rmmod r8188eu.ko
  • git clone https://github.com/aircrack-ng/rtl8188eus.git
  • cd rtl8188eus
  • sudo -i
  • echo "blacklist r8188eu" >> "/etc/modprobe.d/realtek.conf"
  • exit
  • sudo reboot
  • cd ~/src/rtl8188eus
  • sudo make
  • sudo make install
  • sudo reboot

The following adapters should then run with these drivers:

It looks like the following adapters are already supported directly out of the box:

Btw, the monitor mode can be enabled with the following commands for e.g. wlan0:

  • sudo airmon-ng check kill
  • sudo ip link set wlan0 down
  • sudo iw dev wlan0 set type monitor
  • sudo ip link set wlan0 up

Go

Go is required for some applications. For example, Go can be installed using the following commands:

  • sudo apt update && sudo apt upgrade
  • sudo apt install golang

Depending on the distribution you use, you may get an older version of Go this way. At the time when I create the description here, version 1.18.1 was the most current version. I will now show you another way to install Go:

  • mkdir ~/src && cd ~/src
  • wget https://go.dev/dl/go1.18.1.linux-arm64.tar.gz
  • sudo tar -C /usr/local -xzf go1.18.1.linux-arm64.tar.gz
  • rm go1.18.1.linux-arm64.tar.gz
  • cd

Next, the following lines must be added to the end of your profile:

PATH=$PATH:/usr/local/go/bin
GOPATH=$HOME/go

Use the following command and add the 2 lines at the end:

  • nano ~/.profile

After that, the changes can be applied to the system with the following command:

  • source ~/.profile

If everything has been implemented correctly, the version of Go can now be queried with the following command:

  • go version

Docker / Docker Compose

The real reason for my Raspberry Pi and why I have created the description for the Raspberry Pi here is that I would like to take a closer look at Docker. That is why there is also a description of how to install Docker on the RPi.

  • cd /home/pi
  • curl -fsSL get.docker.com -o get-docker.sh
  • sh get-docker.sh
  • sudo usermod -aG docker pi
  • sudo reboot

To verify that Docker is installed and running type:

  • docker version
  • docker info

You should see now some information about versions and other things. Another test is the Docker hello-world:

  • docker run hello-world

If everything is installed correctly, the message "Hello from Docker!" should appear. If Docker has now been installed correctly, the "Docker Compose" tool can be installed. The following commands are used for this purpose:

  • sudo apt-get install -y python3-pip
  • sudo pip3 install docker-compose

To verify that Docker Compose is installed type:

  • docker-compose version

If you see some version information now, Docker and Docker Compose have been installed correctly.