Debian System Installation and Initial Server Configuration Guide
This guide walks you through installing the latest stable Debian release (currently Debian 13 “Trixie”) and performing essential post-installation hardening and configuration steps for a production server. The instructions assume you’re setting up a headless server (no desktop environment).
All commands are written assuming you’re running as root or using sudo. Commands that require elevated privileges are prefixed with #.
1. Preparation Before Installation
- Download the netinst ISO (recommended for servers) from: https://www.debian.org/distrib/netinst
- Current stable (as of February 2026): Debian 13.3 “trixie” SHA256 checksums and signatures are available on the download page — always verify.
- Prepare bootable media:
- USB drive ≥ 2 GB
- Tools: Rufus (Windows), dd (Linux/macOS), balenaEtcher, etc.
- Server hardware requirements (minimal realistic setup in 2026):
- CPU: x86-64 (amd64) – most modern servers
- RAM: ≥ 2 GB (4–8 GB recommended)
- Disk: ≥ 20 GB (SSD strongly preferred)
2. Booting the Installer
- Insert USB / mount ISO and boot from it
- Select Graphical install or Install (text mode is fine for servers)
- Choose language → location → keyboard layout
3. Important Installation Choices (Server-Focused)
| Step | Recommended Choice for Server | Notes |
|---|---|---|
| Hostname | e.g. srv-lax-01 | Use lowercase, no spaces |
| Domain name | e.g. example.local or leave blank | Real domain only if you control DNS |
| Root password | Strong, 20+ characters | You’ll rarely log in directly as root later |
| New user account | Create one (e.g. admin) | We’ll lock root login later |
| Partition disks | Guided – use entire disk → All files in one partition | Simpler & sufficient for most servers |
| LVM | Yes (default) | Enables easy future resize |
| Software selection | Uncheck Debian desktop environment Check SSH server Check standard system utilities | Minimal + SSH is ideal |
| GRUB boot loader | Yes, install to /dev/sda (or your main disk) | Usually correct for single-disk servers |
After installation finishes, reboot and remove installation media.
4. First Login & Immediate Post-Install Tasks
# Log in as the non-root user you created (or root if you didn't create one)
# Update package lists and upgrade everything
sudo apt update
sudo apt upgrade -y
# Install basic useful tools right away
sudo apt install -y vim htop curl wget git unzip tree tmux fail2ban \
apt-listchanges needrestart dnsutils net-tools lsof
# Optional but very common on servers
sudo apt install -y chrony # better time sync than systemd-timesyncd in many cases
5. Secure SSH (Critical Step)
Edit /etc/ssh/sshd_config (use sudo vim or sudo nano):
# Change these lines (uncomment if needed):
Port 2222 # ← change from 22 (recommended)
PermitRootLogin no # ← disable root login
PasswordAuthentication no # ← only keys after setup
PubkeyAuthentication yes
MaxAuthTries 4
LoginGraceTime 30
After editing:
# Restart SSH
sudo systemctl restart ssh
# If you're connected via SSH, **open a second terminal** and test new port + key login first!
6. Set Up SSH Key Authentication (Recommended)
On your local machine (laptop/desktop):
ssh-keygen -t ed25519 -C "yourname@workstation" -f ~/.ssh/debian_srv
# Press Enter for no passphrase (or set strong one)
Copy public key to server:
# From your local machine
ssh-copy-id -i ~/.ssh/debian_srv.pub -p 2222 admin@your-server-ip
Then test:
ssh -i ~/.ssh/debian_srv -p 2222 admin@your-server-ip
Once key works → you can safely disable password auth in sshd_config.
7. Firewall – Use nftables (Modern Default in Debian 13)
# Install and enable
sudo apt install nftables
sudo systemctl enable nftables
# Basic strict server ruleset
cat << 'EOF' | sudo tee /etc/nftables.conf
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
ct state invalid drop
iif "lo" accept
tcp dport 2222 accept comment "SSH"
# Add other ports here, e.g.:
# tcp dport { 80, 443 } accept comment "Web"
# udp dport 123 accept comment "NTP" (if not using chrony)
icmp type echo-request limit rate 5/second accept
icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate 5/second accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
EOF
# Apply and check
sudo nft -f /etc/nftables.conf
sudo nft list ruleset
8. Additional Hardening Steps (Quick Wins)
# Disable unused services (example)
sudo systemctl disable --now bluetooth cups
# Better umask for root & users
echo "UMASK=027" | sudo tee -a /etc/login.defs
# Install and configure automatic security updates
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
# Enable automatic reboots after kernel updates (optional but useful)
sudo sed -i 's|^//Unattended-Upgrade::Automatic-Reboot "false";|Unattended-Upgrade::Automatic-Reboot "true";|' \
/etc/apt/apt.conf.d/50unattended-upgrades
9. Final Checks & Useful Aliases
# Quick system status
sudo systemctl --failed
needrestart -r a
# Helpful aliases (add to ~/.bashrc)
cat << 'EOF' >> ~/.bashrc
alias up='sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y'
alias dfh='df -hT | grep -v tmpfs'
alias mem='free -h'
alias ports='sudo ss -tulnp'
EOF
source ~/.bashrc
Summary – Recommended Order of Operations
- Minimal + SSH install
- Full system update
- SSH hardening → key-only + non-standard port
- nftables firewall
- unattended-upgrades
- fail2ban + basic monitoring tools
- Backup strategy (you still need one!)
Your server should now be reasonably secure for internet exposure — but always monitor logs, keep updated, and consider tools like logwatch, prometheus/node_exporter, or cockpit depending on your needs.