
Most VPS break-ins still start the same way: someone guesses (or reuses) an SSH password. This SSH key setup guide tutorial walks you through moving a hosting VPS to key-based access. It also includes a back-out plan so you don’t lock yourself out mid-change.
The steps below assume Ubuntu 24.04/26.04 LTS or Debian 12/13 on a VPS or dedicated server. Even if you run a control panel like cPanel/WHM, SSH still sits underneath it. The panel won’t secure port 22 for you.
What you’ll build (and what you’ll avoid)
- Key-based SSH for your admin user (ed25519), with correct file permissions.
- Safer sshd defaults: no root login, no password auth (after verification), and limited attack surface.
- A “don’t get locked out” workflow: keep an active session open, validate config before reload, and test from a second terminal.
- Optional extras: 2FA for SSH, port allowance checks, and basic brute-force protection.
Prerequisites checklist (do this first)
Run these checks before you touch SSH settings. They’re the difference between a smooth change and a late-night console recovery.
- You can currently SSH into the server with root or a sudo-capable user.
- You have console access from your provider (web console / rescue / KVM) as an emergency fallback.
- Your firewall allows SSH from your IP. If you use UFW, confirm port 22 is open.
Quick diagnostics
# On the server
whoami
sudo -v
sudo ss -lntp | grep ':22'
If you use UFW:
sudo ufw status verbose
If you suspect firewall issues, use the targeted fix list in UFW firewall troubleshooting tutorial (2026).
Pick the right hosting plan for SSH hardening work
SSH hardening is easier with steady uptime and predictable networking. For production, start with a VPS that gives you full root access and a clean OS image.
HostMyCode’s HostMyCode VPS fits if you want to manage the stack yourself. If you want help with baseline security and maintenance, use managed VPS hosting.
Step 1: Create (or choose) a non-root admin user
If you already have a sudo user, skip ahead. Otherwise, create one and grant sudo access.
# As root
adduser admin
usermod -aG sudo admin
On Debian, the sudo group is usually sudo. On some RHEL-family systems it’s wheel. This tutorial focuses on Ubuntu/Debian hosting boxes.
Step 2: Generate an ed25519 SSH key on your local machine
Generate the key pair on your laptop/desktop, not on the server. Use ed25519 unless you have a specific legacy requirement.
# On your local machine
ssh-keygen -t ed25519 -a 64 -C "admin@yourdomain" -f ~/.ssh/hostmycode-admin-ed25519
-a 64increases KDF rounds for better passphrase resistance.- Use a passphrase. It keeps a stolen laptop from becoming a stolen server.
Step 3: Install the public key on the server (the safe way)
If you have ssh-copy-id, use it. It usually sets the directory and permissions correctly.
# On your local machine
ssh-copy-id -i ~/.ssh/hostmycode-admin-ed25519.pub admin@SERVER_IP
If ssh-copy-id isn’t available, install the key manually:
# On the server (as admin or root)
mkdir -p /home/admin/.ssh
chmod 700 /home/admin/.ssh
nano /home/admin/.ssh/authorized_keys
chmod 600 /home/admin/.ssh/authorized_keys
chown -R admin:admin /home/admin/.ssh
Paste the contents of your .pub file into authorized_keys as a single line.
Step 4: Verify key login before changing sshd settings
Open a second terminal and test key login now. Keep your original SSH session open as your safety line.
# On your local machine
ssh -i ~/.ssh/hostmycode-admin-ed25519 admin@SERVER_IP
If this fails, stop here. Fix the key installation before you change any sshd settings.
Step 5: Harden sshd config (without breaking access)
On Ubuntu/Debian, the main config is usually /etc/ssh/sshd_config. Overrides often live in /etc/ssh/sshd_config.d/*.conf.
In 2026, it’s normal to put hardening in a drop-in file. That way, OS updates are less likely to overwrite your changes.
Create a drop-in file
sudo mkdir -p /etc/ssh/sshd_config.d
sudo nano /etc/ssh/sshd_config.d/10-hostmycode-hardening.conf
Recommended baseline config for a hosting VPS
# /etc/ssh/sshd_config.d/10-hostmycode-hardening.conf
Protocol 2
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding no
AllowTcpForwarding no
PermitTunnel no
MaxAuthTries 3
LoginGraceTime 20
ClientAliveInterval 300
ClientAliveCountMax 2
# Limit who can SSH
AllowUsers admin
Why these settings:
PermitRootLogin noremoves the most targeted username on the internet.PasswordAuthentication noshuts down password guessing entirely.AllowUsersprevents random system users from authenticating via SSH.AllowTcpForwarding noreduces the chance SSH gets used as a tunnel for abuse. If you need port forwarding for a specific workflow, change it tolocalinstead ofyes.
Validate the config before restarting SSH
This is where most lockouts happen. A small typo plus a reload can cut off access.
Don’t skip the check:
sudo sshd -t
No output means the syntax is valid. If you see an error, fix it before you touch the service.
Reload (not reboot) the SSH service
sudo systemctl reload ssh
Then test a fresh login from another terminal:
ssh -i ~/.ssh/hostmycode-admin-ed25519 admin@SERVER_IP
Step 6: Add a “break-glass” access method (recommended)
On hosting servers, you want a controlled emergency path. Don’t rely on “hope” or memory.
Two practical options:
- Provider console access (best). Keep it enabled and test it occasionally.
- A second key stored in a password manager (good). Add it to
authorized_keysand lock it down with restrictions.
Restrict an emergency key
You can prefix a key line in authorized_keys with restrictions. Example:
from="203.0.113.10",no-agent-forwarding,no-port-forwarding,no-X11-forwarding ssh-ed25519 AAAAC3... breakglass@laptop
If that key ever leaks, it’s much harder to reuse from somewhere else.
Step 7: Tighten network exposure (simple firewall rules)
If your office or home IP is stable, limit SSH to that source IP. Keys handle authentication. IP filtering cuts log noise and blocks drive-by probing.
UFW example: allow SSH only from your IP
# Replace with your real IP
MYIP="203.0.113.10"
sudo ufw allow from $MYIP to any port 22 proto tcp
sudo ufw deny 22/tcp
sudo ufw status numbered
Important: add the allow rule first, then the deny. Reversing that order can block you immediately.
Step 8 (optional): Add SSH 2FA with Google Authenticator / TOTP
Keys already provide strong security. 2FA helps when multiple admins need access and you want one more gate.
It also helps if someone insists on using an unprotected key.
On Ubuntu/Debian, install the PAM module:
sudo apt update
sudo apt install -y libpam-google-authenticator
Run setup for your admin user:
sudo -u admin google-authenticator
Then enable it in PAM. Edit /etc/pam.d/sshd and add near the top:
auth required pam_google_authenticator.so nullok
Now in /etc/ssh/sshd_config.d/10-hostmycode-hardening.conf, set:
KbdInteractiveAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Validate and reload:
sudo sshd -t
sudo systemctl reload ssh
Test from a new terminal. You should authenticate with your key, then be prompted for the TOTP code.
Common lockout causes (and fast fixes)
If you hit “Permission denied (publickey),” it’s usually something simple and fixable.
1) Wrong permissions on .ssh or authorized_keys
sudo chmod 700 /home/admin/.ssh
sudo chmod 600 /home/admin/.ssh/authorized_keys
sudo chown -R admin:admin /home/admin/.ssh
2) You edited the wrong sshd file
Drop-ins can override the main file. Some setups also include drop-ins from the main file.
Check what sshd is actually using:
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|pubkeyauthentication|allowusers'
3) Firewall blocks your IP
Check from the server side:
sudo ufw status verbose
sudo iptables -S | sed -n '1,80p'
If you can’t reach port 22 at all, use your provider console. Then adjust the firewall rules there.
Make SSH changes safer on a hosting server
A hosting VPS isn’t a lab box. Sites, mail, and SSL renewals all assume the server stays reachable.
Use a workflow that keeps the blast radius small:
- Keep at least one privileged session open until the change is verified.
- Run
sshd -tbefore any reload/restart. - Prefer
systemctl reload sshso active sessions stay up. - Write down the “break-glass” path in your team notes.
If you’re moving toward a stricter admin model (multiple users, audited access), pair this with SSH Access Control Tutorial (2026).
Pair SSH hardening with basic monitoring and alerts
Once password logins are disabled, most SSH “attacks” become background noise. You still want visibility.
Watch for misconfigured clients, repeated failures, or unexpected login times.
Follow VPS log monitoring tutorial (2026) to add actionable alerts without burning CPU.
Don’t stop at SSH: add backups before you need them
SSH hardening protects access. Backups protect recovery.
For hosting servers, a sane baseline is nightly encrypted offsite backups plus regular restore tests.
If you want a proven workflow, use VPS Backup Automation Tutorial (2026) for Restic automation. For broader planning, use VPS Disaster Recovery Tutorial (2026).
Summary: a safe SSH hardening runbook you can repeat
- Create a non-root sudo user.
- Generate an ed25519 key with a passphrase.
- Install the public key and test login.
- Add an sshd drop-in: disable root login, then disable passwords.
- Validate with
sshd -t, reload, and test again. - Restrict port 22 with firewall rules where practical.
- Add monitoring and backups so “secure” also means “recoverable.”
If you’re setting this up for client sites or a reseller stack, run the process on a clean VPS first. Then standardize it.
For production hosting, choose managed VPS hosting if you want help keeping the security baseline consistent over time. Or start with a self-managed HostMyCode VPS and apply this runbook during provisioning.
If you’re moving sites onto a new server, set up SSH keys and hardening on day one—before you point production traffic at it. HostMyCode offers VPS hosting for hands-on admins and managed VPS hosting when you want the same security outcomes without owning every patch and config detail.
FAQ
Should you disable SSH password login immediately?
Not until you’ve confirmed key login works from a second terminal. Install the key, test it, then disable passwords.
Is ed25519 better than RSA for SSH in 2026?
For most admins, yes. ed25519 keys are smaller, fast, and widely supported on current OpenSSH. Use RSA only for older constraints.
What’s the safest way to edit sshd settings on a remote VPS?
Use an sshd_config.d drop-in, run sshd -t, and reload SSH. Keep one privileged SSH session open until you confirm a new login works.
Do you need to change the SSH port?
No. Keys plus disabling passwords solves the real problem. If you want less log noise, restrict SSH by IP instead of moving ports.
How do you verify which SSH options are active?
Run sudo sshd -T and grep for the settings you care about (root login, password auth, allowed users). That output reflects the effective configuration.