Engineering in practice
Deploying on Debian without fear
13 October 2026 · 8 min read
The Baseline: Treating Infrastructure as Predictable Code
When setting up a new production Debian 12 server, manual configuration through terminal history is an anti-pattern. If you set up a server by memory, you will inevitably forget a step: omitting a firewall rule, leaving SSH password login enabled, or misconfiguring timezone synchronizations.
Deploying on Debian without fear requires a deterministic, idempotent hardening baseline. Here is the exact blueprint codified inside debian-bootstrap.
1. Privileged User Separation: Stop Using Root
The moment a virtual private server (VPS) boots, create an unprivileged operational account with sudo permissions and install your authorized public SSH keys:
# Create deploy user
adduser --gecos "" deploy
usermod -aG sudo deploy
# Copy authorized SSH keys from root
mkdir -p /home/deploy/.ssh
cp /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys
chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys
2. Hardening SSH Without Getting Locked Out
Edit /etc/ssh/sshd_config.d/hardening.conf (or /etc/ssh/sshd_config) to enforce key-only authentication:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
X11Forwarding no
MaxAuthTries 4
The Critical Safety Step: Before restarting or reloading the SSH daemon, always validate the configuration syntax:
sudo sshd -t
If sshd -t outputs any errors, fix them before reloading! Never close your existing active SSH terminal session until you have successfully tested a new SSH connection in a separate terminal window.
3. Restrictive Firewall (UFW) with Default-Deny
Configure Uncomplicated Firewall (UFW) with a default-deny policy, explicitly allowing only required ports:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw --force enable
4. Intrusion Prevention & Unattended Security Updates
Brute-force automated bots scan internet IP ranges continuously. Mitigate this with two essential packages:
sudo apt update && sudo apt install -y fail2ban unattended-upgrades
# Enable automatic critical security patches
sudo dpkg-reconfigure -plow unattended-upgrades
# Start and enable fail2ban
sudo systemctl enable --now fail2ban
5. Virtual Memory (Swap) & Clock Synchronization
Even on servers with adequate RAM, having 2GB to 4GB of swap space acts as a vital safety buffer against unexpected memory spikes, preventing the Linux kernel OOM killer from abruptly terminating your database or API processes:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# Tune kernel swappiness to favor physical RAM
sudo sysctl vm.swappiness=10
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.d/99-swap.conf
Finally, ensure precise clock synchronization using systemd-timesyncd:
sudo timedatectl set-ntp true
sudo timedatectl set-timezone UTC
With these automated steps in place, any new Debian instance can be transformed from a raw virtual machine into an audited, secure production platform in under five minutes.