Basisconfiguratie van Raspberry Pi OS Lite (Bookworm) voor gebruik in een homelab. Geschreven voor headless server-scenario's zonder desktop. Onderdeel van de pixelkeep homelab setup.
Gebruikte Pi's in dit homelab:
rpi-dns01 192.168.20.11 Pi-hole + Unbound primary
rpi-dns02 192.168.20.12 Pi-hole + Unbound secondary
rpi-ha 192.168.20.20 Home Assistant OS
Deze guide geldt voor Raspberry Pi OS Lite Bookworm (Debian 12). Veel informatie die je online vindt is gebaseerd op oudere versies (Bullseye, Buster) en werkt niet meer — met name de netwerkconfiguratie en headless setup zijn ingrijpend veranderd.
Als je gewend bent aan oudere Pi OS versies, zijn dit de belangrijkste wijzigingen:
Onderdeel Oud (Bullseye en eerder) Nieuw (Bookworm)
--------- ----------------------- ----------------
Netwerkconfiguratie /etc/dhcpcd.conf nmcli / NetworkManager
Headless WiFi setup wpa_supplicant.conf in /boot Raspberry Pi Imager (verplicht)
Headless SSH setup leeg ssh bestand in /boot Raspberry Pi Imager
Default gebruiker pi / raspberry Geen standaard — zelf instellen
Static IP dhcpcd.conf aanpassen nmcli commando's
- Wat er veranderd is in Bookworm
- Image schrijven en headless configureren
- Eerste verbinding via SSH
- Systeem bijwerken
- Hostname instellen
- Gebruiker aanmaken en beveiligen
- SSH hardening
- Statisch IP instellen via nmcli
- Aanbevolen: DHCP reservering via UniFi
- Tijdzone instellen
- Automatische beveiligingsupdates
- Fail2Ban
- Firewall — UFW
- Git
- Validatie checklist
- Bronnen
Gebruik Raspberry Pi Imager (v1.8 of nieuwer) om het image te schrijven én te pre-configureren. De oude methode van wpa_supplicant.conf en een leeg ssh bestand in de boot-partitie werkt niet meer in Bookworm.
Download Raspberry Pi Imager: https://www.raspberrypi.com/software/
Stap 1 — OS kiezen
Raspberry Pi OS Lite (64-bit) → voor Pi 4, Pi 5, Pi Zero 2W
Raspberry Pi OS Lite (32-bit) → voor Pi 2B, Pi 3B, Pi Zero W
Kies de Bookworm versie. De nieuwste images zijn soms Trixie (Debian 13) — Trixie-gebaseerde images (december 2025) hebben WiFi-problemen bij headless setup. Gebruik de Bookworm (Legacy) versie voor betrouwbare headless installatie.
Stap 2 — OS Customisation instellen (verplicht voor headless)
Klik op het tandwiel-icoon of kies Edit Settings na het selecteren van het OS.
Tab: General
Hostname: rpi-dns01 (aanpassen per Pi)
Username: <jouw gebruikersnaam> (niet 'pi' gebruiken)
Password: <sterk wachtwoord>
WiFi SSID: pixelkeep-iot (of ethernet — dan leeg laten)
WiFi password: <wachtwoord>
Locale: Europe/Amsterdam
Keyboard layout: nl
Tab: Services
Enable SSH: Aan
Allow public-key authentication only: Aan (aanbevolen)
SSH public key: plak hier je ~/.ssh/id_ed25519.pub
Tab: Options
Eject media when finished: Aan
Stap 3 — Schrijf het image
Klik Write en bevestig. Imager schrijft het image en configureert alles via firstrun.sh op de boot-partitie.
SSH key aanmaken (als je die nog niet hebt):
ssh-keygen -t ed25519 -C "pixelkeep-homelab"
cat ~/.ssh/id_ed25519.pub
# kopieer de output naar het Imager SSH key veld
Zoek het IP-adres van de Pi na de eerste boot. Kijk in het UniFi dashboard onder Clients, of gebruik nmap:
nmap -p 22 --open 192.168.20.0/24
Verbind via SSH:
ssh <gebruikersnaam>@192.168.20.XX
Als je een SSH key hebt geconfigureerd in Imager logt je direct in zonder wachtwoord.
Voeg de host toe aan je ~/.ssh/config voor gemakkelijke toegang:
Host rpi-dns01
HostName 192.168.20.11
User <gebruikersnaam>
IdentityFile ~/.ssh/id_ed25519
Daarna verbinden met:
ssh rpi-dns01
Direct na de eerste verbinding:
sudo apt update && sudo apt full-upgrade -y
sudo apt autoremove -y
sudo reboot
Na de reboot opnieuw verbinden en de versie controleren:
cat /etc/os-release
uname -r
Als je de hostname niet via Imager hebt ingesteld, of wil wijzigen:
sudo hostnamectl set-hostname rpi-dns01
sudo nano /etc/hosts
Pas de regel aan met 127.0.1.1:
127.0.1.1 rpi-dns01
Controleer:
hostname
hostnamectl status
In Bookworm bestaat de pi gebruiker standaard niet meer. Als je tijdens het flashen via Imager al een gebruiker hebt aangemaakt, sla dan de aanmaakinstructies over.
Nieuwe gebruiker aanmaken (als nog niet gedaan):
sudo adduser <gebruikersnaam>
sudo usermod -aG sudo <gebruikersnaam>
Uitloggen en inloggen als de nieuwe gebruiker om te testen:
exit
ssh <gebruikersnaam>@192.168.20.XX
Sudo wachtwoord verplichten:
Standaard hoeft een sudo-gebruiker geen wachtwoord in te typen. Voor een server is dat ongewenst.
sudo nano /etc/sudoers.d/010_<gebruikersnaam>-nopasswd
Als het bestand bestaat met NOPASSWD: ALL, vervang dat door:
<gebruikersnaam> ALL=(ALL) PASSWD: ALL
Of maak een nieuw bestand aan:
echo "<gebruikersnaam> ALL=(ALL) PASSWD: ALL" | sudo tee /etc/sudoers.d/010-passwd
SSH public key toevoegen (als niet via Imager gedaan):
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "ssh-ed25519 AAAA..." >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
sudo nano /etc/ssh/sshd_config
Controleer en stel in:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
X11Forwarding no
MaxAuthTries 3
LoginGraceTime 20
Herstart SSH:
sudo systemctl restart ssh
Test de verbinding in een nieuw terminalvenster voordat je het huidige sluit. Als de verbinding werkt, is de configuratie correct.
ssh rpi-dns01
Sluit het huidige terminalvenster pas af als de nieuwe verbinding succesvol is. Bij een fout in de configuratie kun je anders jezelf buitensluiten.
Optioneel — SSH poort wijzigen:
Het wijzigen van de standaard SSH poort (22) verlaagt de hoeveelheid automatische scanpogingen in de logs. In een netwerk zonder directe internetblootstelling (zoals dit homelab) heeft het beperkte beveiligingswaarde, maar het is nette praktijk.
Port 2222 # of een andere ongebruikte poort boven 1024
Vergeet daarna niet de UFW firewall regel aan te passen (zie Firewall sectie) en je ~/.ssh/config bij te werken:
Host rpi-dns01
HostName 192.168.20.11
User <gebruikersnaam>
Port 2222
IdentityFile ~/.ssh/id_ed25519
In Bookworm gebruikt Raspberry Pi OS NetworkManager in plaats van dhcpcd. Gebruik nmcli voor netwerkconfiguratie. Het bestand /etc/dhcpcd.conf bestaat niet meer.
Aanbevolen aanpak: DHCP reservering via de UniFi router (zie volgende sectie). Dat is betrouwbaarder dan een statisch IP op de Pi zelf instellen.
Als je toch een statisch IP direct op de Pi wil instellen:
Bekijk eerst de actieve verbindingen:
nmcli device status
nmcli connection show
Noteer de naam van de actieve verbinding, bijvoorbeeld Wired connection 1 of eth0.
Stel een statisch IP in (vervang waarden naar jouw situatie):
sudo nmcli connection modify "Wired connection 1" \
ipv4.method manual \
ipv4.addresses 192.168.20.11/24 \
ipv4.gateway 192.168.20.1 \
ipv4.dns "192.168.20.11 192.168.20.12"
Activeer de gewijzigde verbinding:
sudo nmcli connection up "Wired connection 1"
Controleer het resultaat:
ip addr show eth0
ip route
nmcli device show eth0 | grep IP4
Als de verbindingsnaam spaties bevat (zoals
Wired connection 1), zet die dan tussen aanhalingstekens.
Terug naar DHCP:
sudo nmcli connection modify "Wired connection 1" \
ipv4.method auto \
ipv4.addresses "" \
ipv4.gateway "" \
ipv4.dns ""
sudo nmcli connection up "Wired connection 1"
De meest betrouwbare manier om een Pi altijd hetzelfde IP te geven is een DHCP reservering in de UniFi router op basis van het MAC-adres. Dat werkt ongeacht welk OS op de Pi staat en verandert niet bij een herinstallatie.
Zoek het MAC-adres van de Pi:
ip link show eth0 | grep ether
# voorbeeld: dc:a6:32:xx:xx:xx
Maak de reservering aan in UniFi:
UniFi Network > Clients > [Pi in de lijst] > Settings
Fixed IP Address: 192.168.20.11
Sla op
Of via:
UniFi Network > Settings > Networks > [Servers VLAN] > DHCP
DHCP Reservations > Create > MAC + IP invullen
Na het instellen van de reservering: laat de Pi DHCP gebruiken (geen statisch IP op de Pi zelf nodig). De Pi krijgt altijd hetzelfde IP via de router.
Als niet via Imager ingesteld:
sudo timedatectl set-timezone Europe/Amsterdam
timedatectl status
Controleer ook of NTP gesynchroniseerd is:
timedatectl show | grep NTPSynchronized
Verwacht: NTPSynchronized=yes
unattended-upgrades downloadt en installeert automatisch beveiligingsupdates op de achtergrond.
Installeer:
sudo apt install unattended-upgrades apt-listchanges -y
Configureer:
sudo dpkg-reconfigure --priority=low unattended-upgrades
# kies 'Yes'
Controleer de configuratie:
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
De standaard configuratie installeert alleen beveiligingsupdates. Dat is de juiste keuze voor een server. De relevante regels:
Unattended-Upgrade::Origins-Pattern {
"origin=Debian,codename=${distro_codename},label=Debian-Security";
"origin=Raspbian,codename=${distro_codename},label=Raspbian";
};
Optioneel — stel in dat de Pi automatisch herstart bij kernel updates (buiten werktijd):
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
Stel de update-frequentie in:
sudo nano /etc/apt/apt.conf.d/20auto-upgrades
Controleer of het bestand de volgende regels bevat (anders aanvullen):
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "7";
Test de configuratie:
sudo unattended-upgrade --dry-run --debug
Controleer de logbestanden na de eerste automatische run:
sudo cat /var/log/unattended-upgrades/unattended-upgrades.log
Fail2Ban monitort logbestanden en blokkeert automatisch IP-adressen die te veel mislukte inlogpogingen doen. Zinvol zelfs in een intern netwerk — beschermt ook tegen apparaten die gecompromitteerd zijn op het IoT VLAN.
Installeer:
sudo apt install fail2ban -y
Maak een lokale configuratie aan (overschrijf nooit jail.conf direct — die wordt overschreven bij updates):
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
Aanbevolen instellingen:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
backend = systemd
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
Als je SSH poort hebt gewijzigd:
[sshd]
enabled = true
port = 2222
logpath = %(sshd_log)s
Start en controleer Fail2Ban:
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd
Bekijk gebande IPs:
sudo fail2ban-client status sshd | grep "Banned IP"
UFW (Uncomplicated Firewall) is een frontend voor iptables en eenvoudig te beheren via de commandoregel.
In dit homelab is de primaire beveiliging de UniFi zone-based firewall. UFW op de Pi is een extra verdedigingslaag — host-based firewall. Bij een correct geconfigureerd netwerk bereiken ongewenste verbindingen de Pi al niet. UFW beschermt ook als een apparaat op hetzelfde VLAN gecompromitteerd raakt.
Installeer:
sudo apt install ufw -y
Basisregels instellen (stel dit in vóór je UFW activeert):
SSH toestaan (vervang 22 door jouw poort als je die hebt gewijzigd):
sudo ufw allow 22/tcp
Pi-hole DNS (alleen voor Pi's met Pi-hole):
sudo ufw allow 53/tcp
sudo ufw allow 53/udp
Webinterface Pi-hole (alleen vanuit Servers en Management VLAN):
sudo ufw allow from 192.168.20.0/24 to any port 80 proto tcp
sudo ufw allow from 192.168.10.0/24 to any port 80 proto tcp
Alle overige inbound verkeer weigeren:
sudo ufw default deny incoming
sudo ufw default allow outgoing
UFW inschakelen:
sudo ufw enable
Zorg dat je SSH allow-regel correct is ingesteld vóór je UFW activeert, anders sluit je jezelf buitenaf.
Status controleren:
sudo ufw status verbose
sudo ufw status numbered
Regel verwijderen via nummer:
sudo ufw status numbered
sudo ufw delete <nummer>
Firewall herladen na wijzigingen:
sudo ufw reload
Veelgebruikte poorten:
Poort Protocol Dienst
----- -------- ------
22 TCP SSH
53 TCP/UDP DNS
80 TCP HTTP (Pi-hole web UI)
443 TCP HTTPS
8123 TCP Home Assistant
5335 UDP Unbound (localhost only, geen externe regel nodig)
Git is voorgeïnstalleerd in Raspberry Pi OS Lite. Controleer de versie:
git --version
Als niet aanwezig:
sudo apt install git -y
Koppel Git aan je GitHub account:
git config --global user.name "jouw-github-gebruikersnaam"
git config --global user.email "jouw-email@example.com"
git config --global init.defaultBranch main
Controleer de configuratie:
git config --list
SSH key toevoegen aan GitHub (voor push toegang):
Gebruik dezelfde SSH key die je voor de Pi hebt aangemaakt:
cat ~/.ssh/id_ed25519.pub
Voeg de public key toe in GitHub onder:
GitHub > Settings > SSH and GPG keys > New SSH key
Test de verbinding:
ssh -T git@github.com
# verwacht: Hi <username>! You've successfully authenticated...
Kloon een repository:
git clone git@github.com:thedotxyz/pihole-unbound.git
Basiscommando's:
git status # status van de lokale repo
git pull # haal wijzigingen op van remote
git add . # stage alle wijzigingen
git commit -m "beschrijving" # commit met bericht
git push # push naar remote
git log --oneline -10 # laatste 10 commits
Doorloop na de basisinstallatie:
[ ] SSH verbinding werkt met key (niet met wachtwoord)
[ ] Root login via SSH is geblokkeerd
ssh root@192.168.20.11 → moet falen
[ ] Sudo vereist wachtwoord
sudo ls → moet wachtwoord vragen
[ ] Correct IP toegewezen
ip addr show eth0
[ ] DNS werkt
dig google.com @192.168.20.11 (op Pi-hole Pi's)
dig google.com (op andere Pi's)
[ ] Tijdzone correct
timedatectl status
[ ] NTP gesynchroniseerd
timedatectl show | grep NTPSynchronized
[ ] Unattended-upgrades actief
systemctl status unattended-upgrades
[ ] Fail2Ban actief
sudo fail2ban-client status
[ ] UFW actief met correcte regels
sudo ufw status verbose
[ ] Systeem volledig bijgewerkt
sudo apt list --upgradable
- Raspberry Pi OS documentatie: https://www.raspberrypi.com/documentation/computers/os.html
- Raspberry Pi Imager: https://www.raspberrypi.com/software/
- NetworkManager / nmcli op Bookworm: https://www.jeffgeerling.com/blog/2024/set-static-ip-address-nmtui-on-raspberry-pi-os-12-bookworm
- Unattended-upgrades: https://wiki.debian.org/UnattendedUpgrades
- Fail2Ban documentatie: https://github.com/fail2ban/fail2ban
- UFW documentatie: https://help.ubuntu.com/community/UFW
- Pi-hole + Unbound repo: https://github.com/thedotxyz/pihole-unbound
- Homelab network repo: https://github.com/thedotxyz/homelab-network