Skip to content

Instantly share code, notes, and snippets.

@dblueman
Last active December 4, 2025 08:55
Show Gist options
  • Select an option

  • Save dblueman/e8556d11a7b16a5026df78b79661a7a9 to your computer and use it in GitHub Desktop.

Select an option

Save dblueman/e8556d11a7b16a5026df78b79661a7a9 to your computer and use it in GitHub Desktop.
Raspberry Pi secure server setup guide

Bootloader factory reset (optional)

  1. Connect microSD card or NVMe drive to laptop
  2. Install Raspberry Pi Imager from https://www.raspberrypi.com/software/ or Linux repos
  3. Select CHOOSE OS > Misc utility images > Bootloader (Pi x family) > SD Card Boot

or if booted to OS from https://github.com/raspberrypi/rpi-eeprom/tree/master/firmware-2712/default (RPi5) or firmware-2711 for RPi4

wget path/pieeprom.bin
rpi-eeprom-update -df pieeprom.bin

Deploy OS image (from laptop/desktop)

  1. Connect microSD card or M.2 drive
  2. Install Raspberry Pi Imager from https://www.raspberrypi.com/software/ or Linux repos
  3. Select CHOOSE OS > Other general-purpose OS > Ubuntu > Ubuntu Server 24.04.x LTS (64-bit)
  4. Select EDIT SETTINGS
    1. Under GENERAL, set hostname, username, password
    2. Under SERVICES, enable SSH with password authentication

Setup Pi for first use

  1. Activate daily package updates and proxy, creating /etc/apt/apt.conf.d/90local
# Acquire::http::Proxy "http://10.20.30.40";
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "1";
APT::Periodic::Unattended-Upgrade "1";
Unattended-Upgrade::Allowed-Origins {
        "${distro_id}:${distro_codename}";
        "${distro_id}:${distro_codename}-security";
        "${distro_id}ESMApps:${distro_codename}-apps-security";
        "${distro_id}ESM:${distro_codename}-infra-security";
        "${distro_id}:${distro_codename}-updates";
        "${distro_id}:${distro_codename}-backports";
};
Unattended-Upgrade::MailOnlyOnError "false";
Unattended-Upgrade::MinimalSteps "false";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-WithUsers "false";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";
  1. Config ethernet addressing, editing /etc/systemd/network/eth0.network
[Match]
Name=eth0

[Network]
DHCP=yes
# Address=192.168.1.20/24
# Gateway=192.168.1.1
# DNS=1.0.0.1 1.1.1.1
  1. Enable systemd networking for the above to be effective
systemctl enable systemd-networkd
  1. Update OS, remove baggage and install useful packages (needed later)
apt -y upgrade
apt purge --auto-remove alsa-utils avahi-daemon cloud-init cloud-initramfs-copymods cloud-initramfs-dyn-netconf git landscape-common lvm2 lxd-agent-loader lxd-installer mdadm modemmanager motd-news-config multipath-tools netplan.io open-iscsi open-vm-tools polkitd pollinate python3-apport rsyslog snapd sosreport udisks2 wpasupplicant
apt install debfoster iptables-persistent net-tools
debfoster
  1. Add other users
useradd -m -G sudo -s /bin/bash daniel
passed daniel

Security hardening

  1. Disable wireless interfaces and GPU, editing /boot/firmware/config.txt
# dtparam=audio=on
# dtoverlay=vc4-kms-v3d
dtparam=cooling_fan=on

[pi4]
dtoverlay=disable-bt
dtoverlay=disable-wifi

[pi5]
dtoverlay=disable-bt-pi5
dtoverlay=disable-wifi-pi5
dtparam=pciex1_gen=3
  1. Configure NTP, editing /etc/systemd/timesyncd.conf
[Time]
FallbackNTP=time.cloudflare.com
  1. Enable login timeout, editing /etc/environment
TMOUT=3600
  1. Disable redundant automatic update shutdown inhibition service
systemctl disable unattended-upgrades.service
  1. Setup application firewall (adjust as neeeded), creating /etc/iptables/rules.v4 and /etc/iptables/rules.v6
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -m hashlimit --hashlimit-name ratelimit --hashlimit-mode srcip --hashlimit-above 3/second --hashlimit-burst 3 --hashlimit-htable-expire 30000 -j DROP
-A INPUT -p tcp -m multiport --dports 22 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -j ACCEPT
COMMIT
  1. Prevent latency and starvation under network load, creating /etc/sysctl.d/90-local.conf
net.core.default_qdisc=cake
net.ipv4.tcp_congestion_control=bbr
net.ipv4.tcp_slow_start_after_idle=0
net.ipv4.tcp_ecn=1
  1. Cross-check listening network services
netstat -lnutp

Verification

  1. Check automatic updates are enabled
systemctl status apt-daily.timer apt-daily-upgrade.timer
  1. Check there is no package corruption or binary modification (hacked)
apt install debsums
debsums -c
  1. Check storage speed is expected (adjust to mmcblk0 as needed)
dd if=/dev/mmcblk0 of=/dev/null bs=8M count=10 iflag=fullblock,direct
  1. Check NTP is synchronised
timedatectl timesync-status
  1. Check automatic updates work, see older logs in /var/log/unattended-upgrades/
unattended-upgrades --debug
  1. Check stability under load
apt intall stress-ng
stress-ng --vm -1 --vm-bytes 88% --vm-keep --verify --thermalstat 30 --timeout 24h
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment