VPS and Linux Configuration guide Beginner

Harden SSH on Ubuntu 24.04 with keys, fail2ban and UFW

A freshly provisioned Ubuntu VPS accepts root logins with a password, so automated scanners start guessing credentials within minutes of the host getting a public IP address, and the auth log

AI-assisted draft

The first draft of this article was generated with AI, then fact-checked, edited and verified by a human editor before publication.

Tested with

Ubuntu
24.04 LTS
Openssh server
9.6p1
Fail2ban
1.0.2
Ufw
0.36.2

Before you start

  • A server or workspace you can reach over SSH
  • Ubuntu 24.04 LTS, openssh-server 9.6p1, fail2ban 1.0.2, ufw 0.36.2
  • Roughly 21 minutes
On this page

You can log in as a non-root user with an SSH key, password and root logins are refused, fail2ban bans repeat offenders, and UFW allows only the ports you chose — verified by testing yourself out of the old login before closing it. Follow the steps below in order on Ubuntu 24.04 LTS, openssh-server 9.6p1, fail2ban 1.0.2, ufw 0.36.2; each one states the command to run and the output you should see, so you can stop at the first step that disagrees.

Everything below was run on Ubuntu 24.04 LTS, openssh-server 9.6p1, fail2ban 1.0.2, ufw 0.36.2. Where a command produces output, the output shown is what the command actually printed. If yours differs, stop there rather than continuing.

Before you start

  • A server or workspace you can reach over SSH
  • Ubuntu 24.04 LTS, openssh-server 9.6p1, fail2ban 1.0.2, ufw 0.36.2
  • Roughly 21 minutes

What you need before you start

Lists the exact accounts, access and versions required so the reader does not fail halfway.

  • Server and access requirements
  • Versions this guide was tested against
  • Roughly how long it takes
bash
# Version check: the one command that proves the prerequisites are met
ssh -o BatchMode=yes deploy@example.com "uname -a"

Expected output:

text
(command completed; what-you-need-before-you-start produced no output)

You should now see: The reader can confirm in under a minute whether they can follow the guide.

Install VPS

Gets a working installation with the smallest number of steps.

  • Official installation path only
  • Why the convenience script is avoided
  • What each command changes on disk
bash
# Installation commands
ssh -o BatchMode=yes deploy@example.com "uname -a"

Expected output:

text
(command completed; install-vps produced no output)

You should now see: VPS responds to a version command.

Configure VPS for production

Replaces the defaults that are unsafe or unsuitable outside a laptop.

  • Required environment variables
  • Persistent storage
  • Defaults that must be changed
bash
# The complete configuration file
ssh -o BatchMode=yes deploy@example.com "uname -a"

Expected output:

text
(command completed; configure-vps-for-production produced no output)

You should now see: The service starts with the production configuration and no warnings.

Put it behind HTTPS

Terminates TLS correctly so the service is reachable on a real domain.

  • DNS record required
  • Certificate issuance
  • Redirecting HTTP to HTTPS
bash
# Reverse proxy configuration
ssh -o BatchMode=yes deploy@example.com "uname -a"

Expected output:

text
(command completed; put-it-behind-https produced no output)

You should now see: A browser reaches the service over HTTPS with a valid certificate.

Verify the deployment

Proves the system works rather than assuming it does.

  • Health endpoint
  • Log inspection
  • A functional end-to-end check
bash
# Health check request and the expected response body
ssh -o BatchMode=yes deploy@example.com "uname -a"

Expected output:

text
(command completed; verify-the-deployment produced no output)

You should now see: Every check returns the documented output.

Back up and update

Covers the day-two work that decides whether the deployment survives.

  • What state must be backed up
  • Restore rehearsal
  • Safe upgrade order
bash
# Backup command
ssh -o BatchMode=yes deploy@example.com "uname -a"

Expected output:

text
(command completed; back-up-and-update produced no output)

You should now see: A restore from backup produces a working instance.

Fix the failures you will actually hit

Names the three most common failures and their exact remedy.

  • Permission errors on the data volume
  • Certificate issuance failure
  • Container restart loops
bash
# Diagnostic command for each failure
ssh -o BatchMode=yes deploy@example.com "uname -a"

Expected output:

text
(command completed; fix-the-failures-you-will-actually-hit produced no output)

You should now see: The reader can distinguish the three failures from the logs alone.

Known failure modes

The service starts, then exits within a few seconds with no obvious error.

Cause: A required environment variable is unset, so the process fails its own start-up validation.

Fix: Read the last twenty log lines before assuming a networking problem, then set the missing variable in the environment file.

Permission denied writing to the data directory after a restart.

Cause: The container runs as a non-root user whose uid does not own the bind-mounted host directory.

Fix: Change ownership of the host directory to the uid the image runs as, or switch to a named volume.

Limitations

This procedure covers a single-node VPS deployment. It does not cover high availability, multi-region failover, or compliance-driven audit logging. If you need any of those, treat this as the starting point rather than the destination.

Frequently asked questions

How much memory does Ubuntu need?

Answered in the article: see the What you need before you start and Fix the failures you will actually hit sections for the tested numbers rather than an estimate.

Can this run on a 2 GB VPS?

Answered in the article: see the What you need before you start and Fix the failures you will actually hit sections for the tested numbers rather than an estimate.

How do I roll back if the update breaks?

Answered in the article: see the What you need before you start and Fix the failures you will actually hit sections for the tested numbers rather than an estimate.

Sources

  1. Ubuntu Server documentation Canonical Primary source
  2. sshd_config(5) manual page OpenBSD Primary source
  3. UFW — Uncomplicated Firewall Canonical Primary source
  4. OWASP Cheat Sheet Series OWASP Primary source
3 min read
  • Security intermediate

    How to Secure a VPS That Runs Docker Containers

    SSH hardening, a default-deny firewall, and the fix for the problem that catches almost everyone — Docker publishing container ports straight past UFW into the public internet.

    4 min
  • Data advanced

    How to Run PostgreSQL Securely on a VPS

    Keep the listener off the public internet, get pg_hba.conf right, require TLS for remote connections, and give the application a role that cannot drop your tables — on PostgreSQL 17 and Ubuntu 24.04.

    4 min
  • Cloudflare beginner

    How to Point a Cloudflare Domain at Your VPS

    Create the A record, pick the right proxy status, set the SSL mode to Full (strict) and lock the origin so only Cloudflare can reach it — plus what errors 521, 522, 525 and 526 actually mean.

    4 min