Set up a new VPS: the essential secure steps
Bring up a fresh Ubuntu/Debian VPS safely: create a sudo user, log in with an SSH key, harden sshd, enable the UFW firewall, and disable ping.
On this page
When you first get a VPS, do three things before anything else: create a normal user with sudo (stop using root), switch from password to SSH-key login, and turn on a firewall. This guide walks each step with copy-paste commands.
Throughout, replace <username> with the user you want and <server-ip> with your
VPS IP. The example IPs (203.0.113.x) are placeholders.
Create a sudo user
Log in as root first (with the password your provider sent):
ssh root@<server-ip>Update packages, create the new user, and add it to the sudo group:
apt update && apt upgrade -y
adduser <username>
usermod -aG sudo <username>Log out, log back in as the new user, and confirm sudo works:
ssh <username>@<server-ip>
sudo -vNo error means you're good. Create the SSH key folder for this user:
mkdir ~/.ssh && chmod 700 ~/.sshLog in with an SSH key
Generate the key on your local machine (not on the VPS).
If you already have an SSH key for another VPS (e.g. id_ed25519), do NOT run the
default command and hit Enter through the prompts - it overwrites the old key and
you lose access to that other VPS. Give the new key its own name with -f.
If this is your first VPS:
ssh-keygen -t ed25519 -C "[email protected]"If you already have another key, name this one (example VPS "vps2"):
# Windows (PowerShell)
ssh-keygen -t ed25519 -C "[email protected]" -f $env:USERPROFILE\.ssh\id_ed25519_vps2
# macOS / Linux
ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519_vps2Push the public key to the VPS (use the right .pub name if you renamed it):
# Windows (PowerShell)
scp $env:USERPROFILE/.ssh/id_ed25519.pub <username>@<server-ip>:~/.ssh/authorized_keys
# macOS
scp ~/.ssh/id_ed25519.pub <username>@<server-ip>:~/.ssh/authorized_keys
# Linux
ssh-copy-id <username>@<server-ip>If the key isn't the default name, SSH won't pick it up automatically. Add it to
~/.ssh/config (on Windows that's C:\Users\<username>\.ssh\config, with no .txt
extension):
# VPS using the default key
Host vps1
HostName <server-ip-1>
User <username>
IdentityFile ~/.ssh/id_ed25519
# VPS using a named key
Host vps2
HostName <server-ip-2>
User <username>
IdentityFile ~/.ssh/id_ed25519_vps2Now just ssh vps1 or ssh vps2 - no need to remember IPs or key paths.
Harden SSH
Open the sshd config:
sudo nano /etc/ssh/sshd_configSet these three lines to disable IPv6 (one less attack surface), disable password login, and disable root login:
AddressFamily inet
PasswordAuthentication no
PermitRootLogin noIf an included .conf file exists, empty it so it can't override your settings:
sudo nano /etc/ssh/sshd_config.d/*.confRestart SSH (some distros use sshd instead of ssh):
sudo systemctl restart sshLog out and try again: make sure root login and password login are both refused.
Enable the UFW firewall
Install UFW, allow SSH/HTTP/HTTPS, then enable it:
sudo apt install ufw
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
sudo ufw statusDisable ping (ICMP echo), then reboot
To stop the server answering pings, open the rules file:
sudo nano /etc/ufw/before.rulesAdd this line right under the # ok icmp codes for INPUT block:
-A ufw-before-input -p icmp --icmp-type echo-request -j DROPFinally reboot and log back in once the server is up:
sudo rebootTroubleshooting
| Symptom | Fix |
|---|---|
| Still prompted for a password after pushing the key | The key has a non-default name - add IdentityFile to ~/.ssh/config, or use ssh -i <key-path> |
| Restart says the service isn't found | Try sudo systemctl restart sshd |
| Turned off PasswordAuthentication before pushing a key | Use your provider's web console to get in and fix it |