Ravindra BagaleCourses & study guides Track your progress

Labs · Cyber Security

Lab: Harden a Fresh Ubuntu Server: Updates, Key-Only SSH, a UFW Host Firewall and fail2ban

Intermediate45 minYour own Ubuntu Server 22.04/24.04 VM · ssh and ssh-keygen (built into Windows 10+, Mac, Linux) · ufw · fail2ban

Course: Cyber Security · Chapter 32: Linux and Network Hardening

Chapter 32 covers Linux and network hardening; this lab applies the four controls that would have stopped the break-in in Lab 31.

Chala mitrano! In Lab 31 an attacker guessed a password over SSH. Today we make sure that can never happen on our server: updates, keys instead of passwords, a firewall that allows only what we need, and fail2ban to block anyone who keeps trying. And we do it carefully, so we never lock ourselves out. Chala!

Suppose we are…

Suppose we are a Linux administrator at Myntra, and a new Ubuntu server has just been handed to us. Company policy says no server goes live until four controls are in place: latest updates, SSH with keys only, a host firewall, and automatic blocking of repeated failed logins. We practise the full checklist on our own Ubuntu VM.

Goal of this lab

By the end you will have:

  • All updates installed and automatic security updates on.
  • SSH that accepts only your key (passwords and root login refused), tested from a second session.
  • UFW allowing only SSH, and fail2ban watching SSH, with a test ban and unban.

What you need (all free)

  • Your own Ubuntu Server VM with a user that has sudo, reachable from your laptop (host-only 192.168.56.x or NAT with port forwarding). An Ubuntu EC2 free-tier instance also works.
  • The VM's IP and your username. About 45 minutes.

Safety and ethics

Harden only servers you own or manage. Keep your current SSH session open until a new session with your key works; this is how you avoid locking yourself out.

Part 1: updates

  1. Log in to the VM and update everything:

    sudo apt update && sudo apt upgrade -y
    sudo apt install -y unattended-upgrades
    

Part 2: key-only SSH

  1. On your laptop (not the server), create a key pair. Press Enter for the default path and set a passphrase:

    ssh-keygen -t ed25519 -C "laptop-key"
    
  2. Copy the public key to the server (replace user and IP). Mac/Linux:

    ssh-copy-id student@192.168.56.105
    

    Windows PowerShell:

    type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh student@192.168.56.105 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
    
  3. Test the key login in a new terminal: ssh student@192.168.56.105.

    What you should see: you are asked for the key's passphrase, not the server password, and you get a prompt.

  4. On the server, switch off passwords and root login with a drop-in file. The 10- prefix makes it load before Ubuntu's own 50-cloud-init.conf:

    printf "PasswordAuthentication no\nKbdInteractiveAuthentication no\nPermitRootLogin no\n" | sudo tee /etc/ssh/sshd_config.d/10-keys-only.conf
    sudo sshd -t && sudo systemctl restart ssh
    
  5. Keep the old session open. From the laptop, try a login that refuses to use keys:

    ssh -o PubkeyAuthentication=no student@192.168.56.105
    

    What you should see: Permission denied (publickey). Passwords are no longer accepted. A normal ssh student@... with your key still works.

Part 3: host firewall (UFW)

  1. Allow SSH before enabling the firewall, then enable it:

    sudo ufw allow OpenSSH
    sudo ufw default deny incoming
    sudo ufw enable
    sudo ufw status verbose
    

    What you should see: Status: active, Default: deny (incoming), allow (outgoing), and 22/tcp (OpenSSH) ALLOW IN Anywhere.

Part 4: fail2ban

  1. Install fail2ban and create a local jail file:

    sudo apt install -y fail2ban
    printf "[sshd]\nenabled = true\nbackend = systemd\nmaxretry = 5\nfindtime = 10m\nbantime = 1h\n" | sudo tee /etc/fail2ban/jail.local
    sudo systemctl restart fail2ban
    sudo fail2ban-client status sshd
    

    What you should see: Status for the jail: sshd with Currently failed: 0 and Currently banned: 0.

  2. Test a ban safely with a reserved documentation IP (not a real machine), then remove it:

    sudo fail2ban-client set sshd banip 203.0.113.9
    sudo fail2ban-client status sshd
    sudo fail2ban-client set sshd unbanip 203.0.113.9
    

    What you should see: Banned IP list: 203.0.113.9, then an empty list after unban.

  3. Write your hardening record: date, update status, SSH settings, UFW rules, fail2ban settings. Compare with the Lab 31 incident: which control would have stopped it?

Ravindra Bagale's Tip

Order matters: key works → then passwords off; SSH allowed → then firewall on. Do it the other way round and you are locked out. On a cloud server, also keep the AWS Security Group limited to your IP (Lab 4): two layers are better than one. Kram mahatvacha!

Common mistakes

Mistake What happens Fix
Turning off passwords before testing the key You are locked out Test the key in a new session first
ufw enable before ufw allow OpenSSH Your SSH session drops Allow SSH first
Editing /​etc/​fail2ban/​jail.​conf Updates overwrite it Put settings in jail.local
Restarting sshd without sshd -t A typo stops SSH from starting Always sudo sshd -t first
Banning your own IP while testing You cannot connect Test with 203.0.113.9; unban with unbanip

Self-check checklist

0 of 5 done

Try-at-home challenge

Your server will also run Nginx (Lab 7). Open web ports in UFW and prove that only SSH, HTTP and HTTPS are allowed.

Check your answer

Run sudo ufw allow "Nginx Full" (needs Nginx installed; otherwise sudo ufw allow 80,443/tcp). Then sudo ufw status numbered shows only OpenSSH and Nginx Full (or 80,443/tcp) rules, for IPv4 and IPv6. Everything else stays denied by the default incoming policy.

Samjla ka? Update, keys only, firewall, fail2ban, in the right order. Aata pudhe jaauya: Chapter 33 looks inside certificates and hashes.