Linux Server Security is the current field-guide cluster.Linux • Security • Self-hosting • Practical tools
Secure Remote Access

How to Harden SSH on Ubuntu 24.04 Without Locking Yourself Out

SSH hardening should be staged, not rushed. The safe pattern is to keep your current session open, add a second verified login path, test configuration syntax, and only then disable weaker access.

This guide is written as a cautious production checklist. It does not require exploit testing, but it does require discipline: do not close your existing SSH session while changing authentication, firewall, or service settings.

Verification and safety note

This page is a source-checked SSH hardening checklist, not a claim that the commands were run against your production server. SSH and firewall changes can lock you out, so the guide favors staged changes, syntax checks, official documentation, and rollback paths over one-shot hardening scripts.

Before applying it, confirm your Ubuntu/OpenSSH version, provider console access, and a second working login path. Treat every command that changes SSH, users, firewall, or service state as a maintenance-window action.

Before you change anything

Open a second terminal and confirm you can log in independently. If you are connected to a VPS, also confirm you have provider console or rescue access before touching SSH settings.

Minimum safety checks:

If any of those are missing, fix that first.

Step 1: Create or confirm a non-root sudo user

Use a non-root admin user for daily access. Root login should not be the normal path.

Run these on Ubuntu 24.04 as root or with sudo, replacing adminuser with your real admin username:

adduser adminuser
usermod -aG sudo adminuser

If the user already exists, confirm group membership instead:

id adminuser

The user should belong to the sudo group before you rely on that account for administration.

Step 2: Add SSH key authentication before disabling passwords

Do not disable password login until key login works from a fresh terminal.

From your local machine, copy your public key:

ssh-copy-id adminuser@SERVER_ADDRESS

Or manually place the public key in:

/home/adminuser/.ssh/authorized_keys

Then test a fresh login:

ssh adminuser@SERVER_ADDRESS

If this fails, stop. Do not edit password settings yet.

Step 3: Put SSH hardening in a drop-in file

On Ubuntu, OpenSSH server configuration can be changed in the main file or through included drop-in files. Ubuntu’s OpenSSH documentation notes that /etc/ssh/sshd_config includes /etc/ssh/sshd_config.d/*.conf, so a local drop-in is often cleaner than editing the whole file.

Create a local hardening file:

sudo nano /etc/ssh/sshd_config.d/99-local-hardening.conf

Start with conservative settings:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
X11Forwarding no

These settings assume key login already works. If key login has not been verified, do not apply them.

Step 4: Test SSH configuration before restarting

Always test syntax before reloading or restarting SSH.

sudo sshd -t

No output usually means the syntax check passed. If there is an error, fix it before restarting anything.

Then reload SSH:

sudo systemctl reload ssh

On Ubuntu, the service is commonly named ssh. On Ubuntu 24.04 systems using socket activation, you may also see ssh.socket involved. Confirm what your server is using before changing automation around it:

systemctl status ssh --no-pager
systemctl status ssh.socket --no-pager

Step 5: Test a new login before closing the old one

Keep your original SSH session open. In a new terminal, try logging in again:

ssh adminuser@SERVER_ADDRESS

Then confirm sudo works:

sudo -v

Only close the old session after the new session works.

Step 6: Limit where SSH is reachable

SSH key login is good. Private reachability is better.

For small servers, consider one of these patterns:

If using UFW, be careful. Allow your safe SSH path before enabling or tightening the firewall:

sudo ufw allow OpenSSH
sudo ufw status verbose

If SSH should only be reached over a private interface, test that path first and document exactly what is allowed.

Step 7: Keep a rollback path

Before hardening, save the current effective configuration and the file you changed.

sudo cp /etc/ssh/sshd_config /root/sshd_config.backup.$(date +%F)

If you used a drop-in file and need to revert from console access, move it away and reload SSH:

sudo mv /etc/ssh/sshd_config.d/99-local-hardening.conf /root/99-local-hardening.conf.disabled
sudo systemctl reload ssh

Do not rely on memory during a lockout. Write the rollback path down before changing access.

A safer minimum baseline

A reasonable first SSH baseline is:

That baseline is not exotic. It is just careful.

Common lockout causes

Disabling passwords before testing keys

This is the classic mistake. A public key in the wrong user’s home directory will not save you after password login is disabled.

Restarting SSH after a syntax error

Run sudo sshd -t before reloads. Syntax checks are cheap; lockouts are expensive.

Enabling UFW before allowing the active SSH path

A firewall can lock you out even if SSH itself is configured correctly.

Closing the only working session

Keep the old session open until a new one works.

Sources

Before you apply this on a production server

Keep your current SSH session open, test each change in a second terminal, and confirm your VPS provider console or rescue mode works before touching firewall or SSH settings.

Use read-only checks such as sshd -t, systemctl status ssh --no-pager, systemctl status ssh.socket --no-pager, and ufw status verbose before and after changes. Do not close the working session until key-based login, SSH reload, and firewall status have all been checked.

Bottom line

SSH hardening is not about one clever setting. It is about changing access without losing access.

Keep a working session open, verify key login, test syntax, reload carefully, and only then remove weaker paths.