Ubuntu Server Hardening Checklist

2026-03-26 5 min read securityubuntu

Ubuntu Server is a common base for self-hosted apps, home labs, and small production workloads because it is well-documented and broadly supported. That also means it is one of the most common targets for casual scanning and opportunistic abuse. Hardening an Ubuntu server does not require turning it into an unusable bunker, but it does require reducing obvious risk and maintaining the system consistently.

The best hardening checklist is practical. It focuses on defaults that lower exposure, improve recoverability, and reduce the chance that one small mistake becomes a bigger compromise.

Start with updates. An unpatched server is the easiest way to lose before anything interesting happens. Apply security updates promptly, enable unattended upgrades where appropriate, and keep the kernel, SSH stack, and internet-facing services current. Updating is not glamorous, but it closes many common holes.

Next, reduce what is installed and exposed. Every unnecessary package, open port, and background service is extra attack surface. Minimal systems are easier to secure and easier to understand. If a server is meant to run a reverse proxy and a few containers, it probably does not need random development packages, unused daemons, or legacy compatibility services.

User and privilege hygiene are just as important. Create a non-root administrative user and use sudo instead of direct root login. Review which accounts exist on the system and remove or disable anything that should not be there. Least privilege is not a buzzword here; it is basic damage control.

A strong Ubuntu hardening baseline typically includes:

  • apply security updates regularly
  • disable direct root SSH login
  • require SSH keys instead of passwords where possible
  • enable a host firewall such as UFW
  • remove or disable unused services
  • review user accounts and sudo access
  • monitor authentication and system logs

SSH usually deserves immediate attention because it is the first target on most public servers. Disable password authentication if you can rely on key-based access. Restrict which users may log in. Change defaults only when it serves a real security or operational purpose, not because obscurity feels satisfying. For a deeper pass on keys, login restrictions, and rate limiting, see the SSH hardening guide.

The commands that do most of the work

Most of this checklist takes a few minutes on a fresh Ubuntu 24.04 LTS server. Patch first and turn on automatic security updates:

sudo apt update && sudo apt upgrade -y
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

Then lock down SSH. Add a drop-in file such as /etc/ssh/sshd_config.d/99-hardening.conf with:

PermitRootLogin no
PasswordAuthentication no
AllowUsers deploy

Apply it with sudo systemctl restart ssh, then confirm you can still log in from a second terminal before closing your working session. One gotcha catches almost everyone here: Ubuntu cloud images since 22.04 ship their own drop-in, typically /etc/ssh/sshd_config.d/50-cloud-init.conf, which can quietly override PasswordAuthentication set in the main config. Verify the effective settings with sudo sshd -T | grep -i passwordauthentication rather than trusting the file you edited.

Finish with the firewall:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Note that Docker publishes ports by writing iptables rules directly, so a container started with -p 8080:8080 is reachable even when UFW says otherwise. Bind internal containers to 127.0.0.1 or use a Docker-aware firewall setup if that matters for your host.

Firewalling should be explicit. UFW is easy to use and good enough for many Ubuntu servers. Allow only the ports that are required, such as 22 for SSH or 80 and 443 for a reverse proxy. Do not leave services reachable just because they are convenient during setup. If a database should be private, keep it private at the host level as well as at the application level.

Logging and visibility matter because you cannot respond to what you never notice. Review authentication logs, system logs, and service logs. A tool like Fail2ban can act on those logs automatically, banning IPs that hammer your SSH port instead of leaving them to fill auth.log. If the server matters, forward logs or at least ensure local retention is sensible. Hardening is not only about prevention; it is also about detection and response.

Filesystem and secret handling deserve attention too. Protect configuration files with appropriate permissions. Avoid storing sensitive tokens in world-readable files or shell history. Back up configurations and keys securely — backups are part of security, and the 3-2-1 strategy gives you a practical framework for doing this right. If you use Docker on the host, remember that container misconfiguration can undermine host security assumptions.

For internet-facing systems, kernel and network protections may also be worth reviewing, but avoid cargo-cult tuning. Not every sysctl recommendation on the internet is helpful for every workload. Prefer Ubuntu’s documentation, established hardening guidance, and changes you understand.

Another underrated step is documenting your baseline. Write down which ports should be open, which services are expected to run, who has administrative access, and how updates are handled. This turns hardening from a one-time cleanup into a maintainable standard.

Hardening is never finished. New packages get installed, temporary firewall rules linger, and old accounts remain longer than intended. A checklist works best when it is revisited after major changes, not only on the day the server is first provisioned.

It is also smart to review scheduled tasks and automation. Old scripts, forgotten cron jobs, and backup jobs running as overly privileged users can quietly create risk. A hardened server is not only one with fewer open ports; it is one where background behavior is understood.

If you want a sensible order of operations, keep it simple: patch the system, remove unnecessary components, lock down SSH, enable the firewall, limit privileges, and review logs. Those basic steps prevent a surprising number of real-world problems. Ubuntu gives you solid building blocks; security comes from how consistently you use them.

This article is for general information only and should not be treated as professional advice.

Related transmissions
ubuntu
How to Build a Privacy-First AI Workflow on Ubuntu
A practical guide to building a privacy-first AI workflow on Ubuntu using local...
backup
Restic Backup Self-Hosted Guide
A practical Restic guide for self-hosted environments, covering repositories,...
security
How to Secure a Self-Hosted AI Stack on Ubuntu
A practical baseline security guide for small self-hosted AI deployments on...
Newsletter

Stay in the signal

Practical guides on self-hosted AI, SEO, and open-source tools — no noise, no spam.

Follow via RSS →

Email signups open soon.