← All 45 books Ubuntu server hardening, one step per page Get the full edition · £10
One step per page

Ubuntu server hardening, one step per page

The twenty-four steps that take a fresh Ubuntu VPS from default to defensible, without locking yourself out.


Steve Hodgkiss 8 steps

A diagram of the mechanism, the classic mistake, and one thing to go try, on a test session first. That's a page.

Ubuntu server hardening, one step per page

The twenty-four steps that take a fresh Ubuntu VPS from default to defensible, without locking yourself out.


Set in Space Grotesk, Inter and JetBrains Mono (SIL Open Font License).

Commands and settings checked against the Ubuntu Server documentation (firewall, OpenSSH server, AppArmor, automatic updates, user management), the Ubuntu 24.04 LTS manual pages for sshd_config(5), ufw(8) and ufw-framework(8), the official fail2ban documentation, and the Ubuntu security notices. The CIS Ubuntu Linux Benchmark is cited as a reference standard for configuration practice, not quoted. Written and tested against Ubuntu 24.04 LTS; commands may differ on other releases.

General guidance only, for your own servers. You are responsible for changes you make to a production machine: rehearse every step on a test session first. Not professional security advice.

Your purchase is for personal use only. You do not have redistribution rights: please do not share, resell, or republish this book or its pages.

© 2026 Steve Hodgkiss. All rights reserved. Personal use only; no redistribution rights.

Edition 1.0 · stevehodgkiss.net

Contents

Contents


Part 1 · Before you touch anything4
Snapshot before you change anything5
The test-session rule6
Part 2 · Access7
SSH keys, not passwords8
Turn off root login and passwords: the safe order9
Part 3 · The perimeter10
Enable the firewall the safe way11
fail2ban: the guard that counts knocks12
Part 4 · Inside
Least privilege: sudo, not root13
Part 5 · When something happens
Backups: 3-2-1 for servers14
Part 1 of 5
Habits that make the rest safe
1

Before you touch anything

The moves that cost nothing and save everything: snapshots before changes, a test session instead of a live experiment, updates as a habit, one server one job, and knowing what your logs look like on a normal day.


In this part
  1. 01Snapshot before you change anything
  2. 02The test-session rule

Take a snapshot of the whole machine before every risky change. A mistake becomes a five-minute restore instead of a rebuild.

Ubuntu hardening · No. 01
Before you touch anything

Snapshot before you change anything

A mistake becomes a restore, not a rebuild

A PICTURE OF THE WHOLE MACHINE BEFORE THE CHANGE. A MISTAKE BECOMES A RESTORE.you, about to change sshdthe changeone config editlocked outSNAPSHOT, TAKEN BEFORErestore: the machine as it was,five minutes before the editno snapshot: the fix is a rebuild, an IP redeploy, and a long nightyour provider calls it a snapshot, image, or backup: same idea, whole disk

Before every risky change, freeze the whole machine. A snapshot is the disk at a moment in time: any mistake becomes a five-minute restore.

Without one, a lockout means rebuilding the server, a new IP, and moving your app by hand.

Snapshot, change, test, delete. Under ten minutes on most providers.

The seatbelt you wear while changing the locks.

TRY IT THIS WEEK

Snapshot your server in the provider panel, note its name, make one change from this book, test it, then delete the snapshot.

Every step in this book gets rehearsed on a throwaway machine first. Production is not the place to learn a command for the first time.

Ubuntu hardening · No. 02
Before you touch anything

The test-session rule

Learn it on a machine you can delete

REHEARSE ON A THROWAWAY MACHINE. PRODUCTION IS NOT WHERE YOU LEARN A COMMAND.the step, run somewhere cheap firstufw enablea throwaway VMbreaks: you delete it,nothing lostnow you knowthe exact stepsthe same command, learnedon production, with your appon it, and your users in itthe lockout youcould have had for freean hour on a disposable VM buys the exact commands, in the exact order

Spin up the cheapest disposable Ubuntu 24.04 VM and rehearse each step there first.

The mistake is a first attempt on the box your app lives on. The famous lockouts are nearly all first attempts.

After one rehearsal you paste exact commands in the exact order, already knowing what each prints.

Burn the test VM so production never burns.

TRY IT THIS WEEK

Create a one-dollar disposable Ubuntu 24.04 VM, rehearse one step from this book, then destroy it. You practised recovery, not just read it.

Part 2 of 5
Who gets in, and how
2

Access

The front door: keys instead of passwords, root login and password auth switched off in the safe order, config edits that are tested before they are applied, and a second factor on the control panel.


In this part
  1. 01SSH keys, not passwords
  2. 02Turn off root login and passwords: the safe order

A key pair replaces the password with two files: a public key that acts as the lock on the server, and a private key that stays on your laptop. Nothing guessable is ever sent.

Ubuntu hardening · No. 03
Access

SSH keys, not passwords

A lock and key, not a sticky note

A KEY PAIR NOBODY CAN GUESS. A PASSWORD IS A STICKY NOTE EVERYONE CAN TRY.password authSummer2024!guessable, reusable,typed on every loginkey pair authpublic key: the lock,copied to the serverprivate key: the key,never leaves your laptopfitsnothing to guess: the bot gets three numbers it will never landthe private key is a file; protect it with a passphrase and never copy it around

ssh-keygen -t ed25519 makes the pair; ssh-copy-id installs the public half on the server.

The password alternative is exactly what the bots grind at: every password ever typed can be guessed.

After the switch, logins are instant and the guessing simply fails. Ubuntu recommends ed25519: shorter, faster, as strong.

Give the server a lock. Keep the only key in your pocket.

TRY IT THIS WEEK

On your laptop: ssh-keygen -t ed25519, then ssh-copy-id you@your-server. Log in from a NEW terminal: no password prompt means the key works.

Once the key works, turn off the doors you no longer need: root login first, then password authentication. The order is the safety, and the old session stays open until the new one is proven.

Ubuntu hardening · No. 04
Access

Turn off root login and passwords: the safe order

Key in, root off, passwords off, session held

KEY IN FIRST. THEN ROOT OFF. THEN PASSWORDS OFF. OLD SESSION STAYS OPEN.1key login workstested in a fresh terminal2PermitRootLogin noroot cannot SSH at all3PasswordAuthentication noplus KbdInteractiveAuthentication4restart, new loginold session open throughoutreversed order: passwords off before the key works = locked out at step onethe classic sequence that strands you: trust the order

Ubuntu limits root to keys already, but say it: PermitRootLogin no, then PasswordAuthentication no.

The reverse is the lockout: passwords off before proving the key, or logging out before testing a fresh login.

Prove the key twice, edit, sshd -t, restart, log in from a new terminal. Then close the old session.

TRY IT THIS WEEK

On the test VM: prove key login in a second terminal, add both settings, sudo sshd -t, restart ssh, then log in from a third. Production after the rehearsal passes.

Part 3 of 5
Doors, and who watches them
3

The perimeter

What the internet is allowed to reach: a default-deny firewall enabled the safe way, only the ports your app needs, a guard that counts failed knocks, slower guessing, and the cloud firewall closed too.


In this part
  1. 01Enable the firewall the safe way
  2. 02fail2ban: the guard that counts knocks

ufw, Ubuntu's firewall, ships installed but switched off. Allow OpenSSH first, then run ufw enable. From then on, incoming traffic is denied unless you named the door, and your session survives the switch.

Ubuntu hardening · No. 05
The perimeter

Enable the firewall the safe way

Allow SSH first, then flip the switch

ALLOW SSH FIRST, THEN ENABLE. THE REVERSE IS LINUX'S MOST FAMOUS SELF-LOCKOUT.THE WRONG ORDERufw enableSSH notallowed yetyour own session, cutTHE SAFE ORDERufw allow OpenSSHufw enablesession survives: the door was named firstafter enable: default deny incomingport 22? on the list: in.port 5432? not on it: deniedthe check:sudo ufw status verboseufw ships installed but OFF; enabling is one command, in the right order

Without a firewall, every listening service is reachable from anywhere. ufw enable turns on default deny: incoming is refused unless a rule names it.

The famous mistake is enable before allow. Enable slams every door at once, including the one you are standing in.

Two commands in the right order, then sudo ufw status verbose to read the policy. Rules survive reboots.

Name the door you are standing in, then close all the others.

TRY IT THIS WEEK

On the test VM: sudo ufw allow OpenSSH, then sudo ufw enable, answer y. Your session survives, and status verbose reads default deny.

fail2ban reads the login log, counts failed attempts from each address, and bans anyone who fails too many times in a row, by writing a firewall rule that rejects them.

Ubuntu hardening · No. 06
The perimeter

fail2ban: the guard that counts knocks

Too many failed knocks, the door stops answering

A GUARD WHO COUNTS FAILED KNOCKS PER VISITOR AND BANS THE REPEAT OFFENDERS.the guesserfailed knocks,same addressfail2ban watchesauth.log, countingfailures per IP5BANNED10 minutes by defaultyou log infirst try, nevercountedthe check:fail2ban-client status sshdconfigure it in /etc/fail2ban/jail.local: never edit jail.conf

The bots never stop; fail2ban makes them expensive. The sshd jail is on by default: five failures in ten minutes earns a ten minute ban.

Editing jail.conf is the mistake: a package update overwrites it. Yours belong in jail.local.

fail2ban-client status sshd shows the guard on duty: failed, banned, current list.

TRY IT THIS WEEK

Install fail2ban on the test VM, run fail2ban-client status sshd, then add ignoreip for your own address in /etc/fail2ban/jail.local so you can never ban yourself.

Work as your own user and borrow root power with sudo, one command at a time. Root all day means every typo and every exploit runs with every key on the ring.

Ubuntu hardening · No. 07
Inside

Least privilege: sudo, not root

Borrow the big key, one command at a time

A KEYRING WITH ONLY THE NEEDED KEYS. ROOT ALL DAY IS EVERY KEY ON ONE RING.running as root: every key,always in your handyour user: one key,borrowed via sudosudo systemctl restart appyour one key unlocksthe root key, for onecommand, then hands it backa typo as your user fails harmlessly;the same typo as root edits the whole machine

Ubuntu disables the root password and gives your user sudo. The design: commands run powerless, sudo promotes exactly one when needed.

sudo su - and staying root means every typo runs with every key on the ring.

Log in as you, sudo the one command, return. The CIS standard calls it least privilege.

TRY IT THIS WEEK

If a second person helps: sudo adduser sam, sudo usermod -aG sudo sam, sam runs sudo -l. No -a with -G wipes groups: check with groups sam.

Three copies of anything you cannot lose, on two different media, with one offsite. For a server: the live copy, a provider snapshot, and database dumps pulled off the provider entirely. Then restore one, to prove the chain works.

Ubuntu hardening · No. 08
When something happens

Backups: 3-2-1 for servers

Three copies, two media, one offsite, tested

THREE COPIES, TWO MEDIA, ONE OFFSITE. THEN PROVE IT BY RESTORING.1. the live copyit is NOT a backup2. provider snapshotsame provider, samebuilding: half a backup3. the offsite copydatabase dumps and datapulled OFF the provideryour laptopor object storagethe step everyone skips:restore one, on the test VMa backup you have neverrestored is a hope, not a backupautomation beats memory: a nightly dump cron plus a weekly offsite pull you can read about in a log

Hardening narrows the odds; backups cap the loss. The rule of thumb: three copies, two media, one offsite, so no single failure takes them all.

The provider snapshot alone is the trap: a compromised panel or billing surprise takes both copies together.

Nightly dumps pulled off the provider, and a monthly restore rehearsed on the test VM.

TRY IT THIS WEEK

Add a nightly database-dump cron on the server, scp the latest dump to your laptop, and restore it into the test VM. If the app runs there, the chain is real.

Index

Index


Backups: 3-2-1 for servers14
Enable the firewall the safe way11
fail2ban: the guard that counts knocks12
Least privilege: sudo, not root13
Snapshot before you change anything5
SSH keys, not passwords8
The test-session rule6
Turn off root login and passwords: the safe order9