No KYC. Anonymous signup, paid in Monero & 20+ coins. Tbps DDoS included. Deploy in minutes.
Tutorials

How to Harden a Fresh VPS (Firewall, SSH Keys, WireGuard)

A practical first-hour checklist: key-only SSH, firewall, fail2ban, auto-updates and a WireGuard tunnel.

9 min read

A brand-new VPS is exposed to automated attacks within minutes of going online — bots scan the whole IPv4 space constantly, probing for default credentials and open services. This checklist walks through the essential hardening steps for a fresh ServPrivacy VPS: key-only SSH, a firewall, fail2ban, automatic updates, a private WireGuard tunnel, and basic monitoring. Commands assume Debian/Ubuntu; adapt the package manager for other distros.

Do these in order, and keep your current SSH session open while you test changes in a second terminal. That way a mistake in the firewall or SSH config never locks you out.

1. Update first

Start from a fully patched system so you are not hardening on top of known holes.

  • apt update && apt full-upgrade -y
  • reboot if a new kernel was installed.

2. Create a non-root user

Working and logging in as root is a needless risk. Make an admin user with sudo and use it for everything.

  • adduser alex
  • usermod -aG sudo alex

3. SSH key-only auth, disable root login

Passwords get brute-forced; keys do not. Generate a key on your own machine, not the server:

  • ssh-keygen -t ed25519 -C "you@example"
  • ssh-copy-id alex@your-server-ip

Confirm you can log in with the key, then lock down /etc/ssh/sshd_config:

  • PermitRootLogin no
  • PasswordAuthentication no
  • PubkeyAuthentication yes
  • KbdInteractiveAuthentication no

Optionally change the port and restrict who may log in:

  • Port 2222 — cuts most opportunistic scanner noise (security through obscurity, not a real control).
  • AllowUsers alex — nobody else may authenticate.

Apply and test in a new terminal before closing the old one:

  • systemctl restart ssh
  • ssh -p 2222 alex@your-server-ip
Never set PasswordAuthentication no until you have verified key login works. If you change the SSH port, remember to allow the new port in the firewall before restarting.

4. Firewall: UFW or nftables

Default-deny inbound, allow only what you serve. UFW is the friendliest front-end:

  • ufw default deny incoming
  • ufw default allow outgoing
  • ufw allow 2222/tcp — your SSH port (do this first!).
  • ufw allow 80,443/tcp — only if you run a web server.
  • ufw enable

Check the result with ufw status verbose. If you prefer the modern native stack, write rules directly in /etc/nftables.conf with a default-drop input chain and systemctl enable --now nftables. Either way, the principle is identical: deny everything inbound, then open the few ports you actually use.

5. fail2ban

fail2ban watches logs and temporarily bans IPs that rack up failed logins, blunting brute-force and scanner traffic.

  • apt install fail2ban -y
  • Copy the defaults: cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
  • In jail.local, enable the [sshd] jail, set your custom port = 2222, and tune bantime / maxretry.
  • systemctl enable --now fail2ban
  • Inspect with fail2ban-client status sshd.

6. Automatic security updates

Unpatched software is the most common way a server falls. Automate the security channel:

  • apt install unattended-upgrades -y
  • dpkg-reconfigure -plow unattended-upgrades

This applies security patches on its own. For reboots after kernel updates, either schedule them or review periodically — if you run LUKS full-disk encryption, remember an unattended reboot will pause for unlock (see the full-disk encryption guide).

7. A basic WireGuard tunnel

WireGuard gives you a fast, modern private network — keep admin services (databases, dashboards, internal APIs) off the public internet and reachable only through the tunnel.

  • apt install wireguard -y
  • Generate keys: wg genkey | tee privatekey | wg pubkey > publickey

Create /etc/wireguard/wg0.conf on the server:

  • [Interface]Address = 10.0.0.1/24, ListenPort = 51820, PrivateKey = <server-private-key>
  • [Peer]PublicKey = <client-public-key>, AllowedIPs = 10.0.0.2/32

Open the port and bring the interface up:

  • ufw allow 51820/udp
  • systemctl enable --now wg-quick@wg0
  • Verify with wg show.

Configure the matching client peer on your laptop and, once the tunnel is up, bind sensitive services to the 10.0.0.0/24 interface instead of 0.0.0.0 so they are invisible from the outside.

8. Monitoring and logs

You cannot respond to what you cannot see. Establish a baseline of visibility:

  • journalctl -u ssh --since today — review authentication activity.
  • last and lastb — successful and failed login history.
  • ss -tulpn — list every listening port; close anything you do not recognise.
  • Install a lightweight live view: apt install htop.
  • Consider auditd for syscall-level logging, or a remote log target so records survive a compromise.
Pair host hardening with the always-on Tbps-class DDoS protection included on every plan — the firewall stops what reaches your services, the network edge absorbs the floods. See DDoS protection explained.

Wrap-up

None of these steps are exotic, and together they put a fresh box far ahead of the default. For workloads that handle sensitive data, layer on full-disk encryption and pick a privacy-friendly jurisdiction — the reasoning is in why offshore. Need more horsepower than a VPS? The same checklist applies to a dedicated server.

Key takeaways

  • Patch first, then create a sudo user and stop logging in as root.
  • Move SSH to key-only auth, disable password and root login, and verify key access before locking it down.
  • Run a default-deny firewall (UFW or nftables) and add fail2ban to blunt brute-force scanners.
  • Enable unattended security upgrades so patches apply without you.
  • Use WireGuard to keep admin services off the public internet, and keep eyes on logs and listening ports.