A new VPS is exposed to the public internet from the moment it boots. Within minutes, automated bots begin probing port 22 with credential-stuffing attacks. The good news: a handful of well-understood steps will eliminate the vast majority of that risk. This guide walks through hardening a fresh Linux server (Ubuntu/Debian assumed; commands map closely to other distros) the same way a professional would on day one.
If you are still choosing where to run your workload, Skyline provisions cloud servers and VPS inside Saudi Arabia, which keeps your data under PDPL/NCA data-residency rules and puts a local Arabic-speaking support team a message away.
Before you begin
You need:
- A new VPS with a public IP and the initial
rootcredentials (or a default sudo user) from your provider. - An SSH client on your machine. On Linux/macOS this is built in; on Windows use the OpenSSH client or PowerShell.
- An SSH key pair. If you don't have one, generate it locally:
ssh-keygen -t ed25519 -C "you@example.com"
ed25519 keys are short, fast, and stronger than legacy 2048-bit RSA. Press Enter to accept the default path (~/.ssh/id_ed25519) and set a passphrase.
Step 1 — Update the system first
Log in and bring all packages current before anything else, so you start from a patched baseline:
ssh root@your_server_ip
apt update && apt upgrade -y
Step 2 — Create a non-root sudo user
Operating as root daily is dangerous: a single typo can be catastrophic, and root is the first account every attacker targets. Create a dedicated administrative user instead:
adduser deploy
usermod -aG sudo deploy
Now copy your SSH public key to the new user so you can log in as them:
rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy/
If you provisioned with password login, use ssh-copy-id deploy@your_server_ip from your local machine instead. Open a second terminal and confirm you can log in as deploy and run sudo whoami (it should print root) before you touch anything else. Never close your working session until the new access is verified.
Step 3 — Harden the SSH daemon
This is the single highest-impact change. Edit the SSH config:
sudo nano /etc/ssh/sshd_config
Set the following directives (uncomment or add them):
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
MaxAuthTries 3
X11Forwarding no
| Directive | Effect |
|---|---|
PermitRootLogin no |
Blocks direct root login over SSH |
PasswordAuthentication no |
Forces key-only auth, defeating brute force |
MaxAuthTries 3 |
Drops the connection after 3 failed attempts |
Apply the change by reloading the service:
sudo systemctl reload ssh
Test in a new terminal before logging out. Confirm key login still works and that a password attempt is rejected. If something is wrong, your existing session is still open to fix it.
Optional: change the SSH port
Moving SSH off port 22 (for example to 2222) won't stop a determined attacker but dramatically cuts log noise from automated scanners. Set Port 2222 in sshd_config, allow it in the firewall (next step) before reloading, and connect with ssh -p 2222 deploy@your_server_ip.
Step 4 — Configure the firewall with UFW
UFW (Uncomplicated Firewall) is a friendly front end to iptables. By default, deny everything inbound and permit only what you need:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
If you run a web server, open HTTP and HTTPS too:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Critical: allow your SSH port before enabling the firewall, or you will lock yourself out. If you changed the port, use
sudo ufw allow 2222/tcpinstead ofOpenSSH.
Enable and verify:
sudo ufw enable
sudo ufw status verbose
Step 5 — Install Fail2ban
Fail2ban watches your logs and temporarily bans IPs that show malicious patterns, such as repeated failed logins:
sudo apt install fail2ban -y
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Edit jail.local and, under [sshd], ensure the jail is enabled with sensible limits:
[sshd]
enabled = true
maxretry = 3
bantime = 1h
findtime = 10m
Restart and check the jail:
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
Step 6 — Enable automatic security updates
Unpatched software is the most common breach vector. On Ubuntu/Debian, enable unattended security upgrades:
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades
This applies security patches automatically while leaving feature upgrades under your control.
Hardening checklist
- [x] System fully updated
- [x] Non-root sudo user created and verified
- [x] Root SSH login disabled
- [x] Password authentication disabled (key-only)
- [x] UFW firewall enabled with a default-deny policy
- [x] Fail2ban running on the SSH jail
- [x] Automatic security updates enabled
What to do next
This baseline blocks the overwhelming majority of opportunistic attacks. From here, consider per-application hardening (a reverse proxy, TLS via Let's Encrypt, database bind-to-localhost), centralized logging, and regular off-server backups. If your server also handles email, our business email hosting keeps mail off the box and properly authenticated with SPF, DKIM, and DMARC.
For more guides on running servers in the Kingdom, browse our VPS and cloud servers hub.
Ready to deploy on in-Kingdom infrastructure with transparent pricing and local support? Create your Skyline Cloud account and spin up a hardened VPS in minutes.
Comments
0 total · 0 threads