Installing the operating system is only the beginning. A secure Ubuntu Server must be configured for its workload, network exposure, data, and operating model. Hardening involves tradeoffs; untested changes can lock out administrators or stop applications.
Keep console access or an existing SSH session while changing SSH and firewall settings. Confirm a new session works before closing the current one.
1. Update and verify the support lifecycle
sudo apt update
sudo apt full-upgrade
sudo reboot
Use a supported Ubuntu LTS release where appropriate. Track kernel updates, reboot requirements, and security notices. Add third-party repositories only after assessing their source, signing keys, and maintenance plan.
2. Create individual administrator accounts
sudo adduser deploy
sudo usermod -aG sudo deploy
id deploy
Ubuntu disables direct password login for root by default and uses sudo for controlled elevation. Separate accounts improve accountability.
3. Use SSH keys before disabling passwords
ssh-keygen -t ed25519
ssh-copy-id deploy@server
ssh deploy@server
After testing key access, use an SSH configuration drop-in:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
sudo sshd -t
sudo systemctl reload ssh
Disable passwords only when every administrator has working keys and a recovery path. Protect private keys with passphrases and device controls.
4. Allow only required network traffic
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
sudo ufw status verbose
Adapt these rules to the workload. Internal databases should normally be restricted to private networks or explicit source ranges.
5. Reduce attack surface
systemctl list-unit-files --state=enabled
ss -lntup
sudo apt autoremove
Disable unused services, remove unnecessary packages, and assign ownership for every listening port. Understand dependencies before changing unfamiliar services.
6. Configure monitored security updates
sudo apt install unattended-upgrades
sudo dpkg-reconfigure unattended-upgrades
Automation reduces exposure, but monitor failures and reboot requirements. Test important updates in staging for critical systems.
7. Keep AppArmor enabled
sudo aa-status
systemctl status apparmor
AppArmor confines applications with profiles. Diagnose denials and refine a profile rather than disabling the protection globally.
8. Protect files, secrets, and data
- Apply least privilege to configuration files and private keys.
- Keep secrets out of repositories and shell history.
- Encrypt sensitive data and backups.
- Separate application identities from administrators.
- Define ownership for upload, log, and cache directories.
9. Configure logs, time, and monitoring
timedatectl status
journalctl -p warning..alert -b
last
lastb
Accurate time is essential for investigations. Monitor failed logins, account changes, service failures, disk capacity, load, and certificate expiry. Important systems should forward logs to separate storage.
10. Back up and rehearse recovery
Back up data, configuration, required keys, and recovery instructions. Keep at least one copy isolated from production credentials, verify checksums, and perform regular restore exercises.
11. Validate after hardening
- Expected users can log in with their keys.
- Only required ports are reachable from approved networks.
- Applications, scheduled jobs, queues, and backups still work.
- Updates, log rotation, alerts, and reboots are controlled.
- Changes and rollback steps are documented.
Hardening is continuous
An initial checklist does not replace vulnerability management, periodic review, and incident response. Define a suitable baseline, test it automatically, and update it as workloads and threats change.




No comments yet. Be the first to share your thoughts.