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.
Sandeep Sidhu · Founder, AlertKick
Debian 13 (trixie) is a strong server base because it does little by default. A minimal install has a small attack surface. The trade-off: 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. This version includes the Debian-specific commands and gotchas that make copy-pasting Ubuntu guides 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
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
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: Ubuntu ships unattended-upgrades preinstalled and enabled. Debian minimal installs often do not. 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.
Frequently asked questions
- Is Debian 13 secure by default?
- A minimal Debian 13 install is a small attack surface, but several protections Ubuntu users assume are present are opt-in on Debian. sudo may not be installed, no firewall front-end ships by default, and unattended-upgrades is frequently absent on minimal installs. The phrase secure by default refers to the package set, not to an internet-facing box with no packet policy.
- Why is sudo missing on my Debian 13 server?
- A minimal Debian install often has no sudo package and everything is done as root. If you set a root password during installation, the installer does not add your user to the sudo group either. Install sudo, create a deploy user, add it to the sudo group, and verify with sudo -v from that user before continuing - check with groups deploy rather than assuming.
- How do I harden SSH on Debian 13?
- Create a drop-in file under /etc/ssh/sshd_config.d/ setting PermitRootLogin no, PasswordAuthentication no, KbdInteractiveAuthentication no, MaxAuthTries 3, LoginGraceTime 20, and AllowUsers for your deploy user, then run sshd -t and reload the ssh service. Debian 13's OpenSSH honours sshd_config.d drop-ins, which survive package upgrades that touch the main config. Verify key-based login from a second terminal before disconnecting.
- Does Debian 13 have a firewall enabled by default?
- No. Unlike Ubuntu, Debian ships no firewall front-end, so a fresh box is wide open at the packet-filter level. The simplest path is to install ufw with default deny incoming, default allow outgoing, and explicit rules for OpenSSH and only the ports the server serves; alternatively, nftables is Debian's default backend and a hand-written /etc/nftables.conf is entirely reasonable. Note that published Docker container ports bypass ufw.
- Are automatic security updates enabled on Debian 13?
- Frequently not on minimal installs, whereas Ubuntu preinstalls and enables them. Install unattended-upgrades and run dpkg-reconfigure -plow unattended-upgrades, answering Yes. Confirm the Debian-Security origin is active in /etc/apt/apt.conf.d/50unattended-upgrades and check /var/run/reboot-required after kernel updates, because automatic patching that never reboots is only half applied.
- What should I do after completing the hardening checklist?
- The checklist 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 nobody wrote. Debian's stability sharpens the problem because servers run for years and nobody re-audits a box that never complains. The fix is watching the controls rather than re-running the list: AlertKick's eBPF agent runs on Debian and streams logins, changes to sshd_config and authorized_keys, new listening ports, and odd processes off-host, with a free tier that needs no card.