Debian 13 server hardening checklist: minimal install to defensible
A copy-pasteable hardening checklist for Debian 13 (trixie): sudo and SSH lockdown, nftables/ufw, unattended-upgrades, sysctl settings, and auditd - with the Debian-specific gotchas that Ubuntu guides skip.
The AlertKick team
Debian 13 (trixie) makes a wonderful server precisely because it does so little on its own - a minimal install is a small attack surface by default. The flip side: several protections Ubuntu users assume are “just there” are opt-in on Debian. This checklist covers the same ground as our Ubuntu 24.04 hardening guide - the reasoning behind each control lives there - but with the Debian-specific commands and the gotchas that make copy-pasting Ubuntu guides onto Debian quietly fail. (Distro-neutral version with a verify command per step: the Linux server security checklist.)
1. Sudo first - it may not even be installed
A minimal Debian install often has no sudo and everything done as root. Fix that before anything else:
apt update && apt install -y sudo
adduser deploy
usermod -aG sudo deploy
# verify: log in as deploy, run `sudo -v` - THEN continue
Debian gotcha: if you set a root password during install, the installer doesn’t add your user to sudo. Check with groups deploy rather than assuming.
2. SSH: keys only, root locked out
# workstation: ssh-keygen -t ed25519 && ssh-copy-id deploy@server
sudo tee /etc/ssh/sshd_config.d/90-hardening.conf > /dev/null <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
MaxAuthTries 3
LoginGraceTime 20
AllowUsers deploy
EOF
sudo sshd -t && sudo systemctl reload ssh
Same rule as everywhere: verify key login from a second terminal before disconnecting. Debian 13’s OpenSSH honours sshd_config.d/ drop-ins, which survive package upgrades that touch the main config. The reasoning on why keys-only ends the brute-force game applies unchanged.
3. Firewall: nothing is preinstalled - choose and enable one
Unlike Ubuntu, Debian ships no firewall front-end by default; a fresh box is wide open at the packet-filter level. Simplest path, same semantics as the Ubuntu guide:
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 443/tcp # only what this server serves
sudo ufw enable && sudo ufw status verbose
If you prefer staying native, nftables is Debian’s default backend and a hand-written /etc/nftables.conf is entirely reasonable - but write something. “Debian is secure by default” refers to the package set, not to an internet-facing box with no packet policy. The Docker caveat applies here too: published container ports bypass ufw.
4. Security updates: install the machinery, don’t assume it
sudo apt update && sudo apt upgrade -y
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades # answer Yes
Debian gotcha: on Ubuntu this is preinstalled and on; on Debian minimal installs it frequently isn’t. Confirm the security origin is active in /etc/apt/apt.conf.d/50unattended-upgrades (the Debian-Security origin is enabled in the default template) and check /var/run/reboot-required after kernel updates - automatic patching that never reboots is only half applied.
5. Kernel settings
The sysctl block from the Ubuntu guide, step 6 applies to Debian 13 verbatim - redirects, source routing, syncookies, kptr_restrict, dmesg_restrict, and Yama ptrace scoping. One Debian note: Yama is compiled into Debian kernels, but confirm after applying:
sudo sysctl kernel.yama.ptrace_scope # expect 1 after applying the block
6. auditd and the day-two problem
sudo apt install -y auditd
sudo systemctl enable --now auditd
And the same closing truth as every hardening list: this page describes a moment, and the box starts drifting from it immediately - a config rewritten by an upgrade, a port opened by a deploy, a cron entry you didn’t write. Debian’s stability actually sharpens the problem: boxes run for years, and nobody re-audits a server that never complains.
The fix is watching the controls, not re-running the checklist: AlertKick’s eBPF agent runs on Debian the same as everywhere - logins, file changes to sshd_config and authorized_keys, new listening ports, odd processes - streamed off-host, triaged, and quiet until something genuinely drifts. Install takes about a minute, and the free tier needs no card.
Debian gives you the smallest starting surface of any mainstream distro. Add the watcher, and keep it that way.