Updated October 28, 2026
These steps apply to a fresh Ubuntu 24.04, Debian 12, AlmaLinux 9 or Rocky Linux 9 install. Managed servers arrive with all of this done; on unmanaged servers, do it before you deploy anything. Commands show Ubuntu/Debian first, then the RHEL-family equivalent.
1. Update everything
apt update && apt full-upgrade -y # Ubuntu / Debian
dnf upgrade --refresh -y # AlmaLinux / Rocky
reboot # if the kernel was updated 2. Create your own user
adduser deploy
usermod -aG sudo deploy # Ubuntu / Debian
usermod -aG wheel deploy # AlmaLinux / Rocky 3. Install your SSH key, then turn off passwords
From your workstation:
ssh-copy-id deploy@SERVER_IP Log in as the new user in a second terminal to prove the key works. Then create /etc/ssh/sshd_config.d/10-hardening.conf:
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
MaxAuthTries 3 sshd -t && systemctl reload ssh # the unit is "sshd" on AlmaLinux / Rocky Keep your original session open until you have confirmed a fresh login still works.
4. Firewall: deny by default
# Ubuntu / Debian
ufw default deny incoming
ufw default allow outgoing
ufw allow OpenSSH
ufw allow 80,443/tcp
ufw enable
# AlmaLinux / Rocky
firewall-cmd --permanent --add-service=ssh --add-service=http --add-service=https
firewall-cmd --reload 5. Automatic security updates
apt install -y unattended-upgrades && dpkg-reconfigure -plow unattended-upgrades # Ubuntu / Debian
dnf install -y dnf-automatic && systemctl enable --now dnf-automatic-install.timer # AlmaLinux / Rocky On RHEL-family systems, set upgrade_type = security in /etc/dnf/automatic.conf if you
only want security updates applied automatically.
6. Block repeated login attempts
apt install -y fail2ban # Ubuntu / Debian
dnf install -y epel-release && dnf install -y fail2ban # AlmaLinux / Rocky
systemctl enable --now fail2ban 7. Time, hostname and swap
timedatectl set-timezone UTC
timedatectl set-ntp true
hostnamectl set-hostname web1.example.com Servers with plenty of RAM still benefit from a small swap file (2–4 GB) so the kernel can page out idle memory instead of invoking the out-of-memory killer at the first spike.
8. Write down what you did
Keep the steps in a script or an Ansible playbook so the next server is identical. Then move on to the hardening checklist and backups.