{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreigmn2gtx5nb3ky3rficw67xqaoxn3df3esllug7c2at3eooj7rwta",
"uri": "at://did:plc:25rdn5elo5izoxrmtis34zuk/app.bsky.feed.post/3mpne3ck4rlu2"
},
"path": "/wadethomastt/how-to-secure-a-vps-the-complete-ubuntu-hardening-guide-40ee",
"publishedAt": "2026-07-02T05:26:20.000Z",
"site": "https://dev.to",
"tags": [
"linux",
"security",
"devops",
"tutorial"
],
"textContent": "The moment a VPS gets a public IP, it's already being scanned. Automated bots start hammering the default root account with password guesses within minutes of the server going online — before you've even finished your first `apt update`.\n\nThis guide walks through the baseline hardening I run on every fresh Ubuntu server before deploying anything to it: creating a proper user account, locking down root, setting up a firewall, quieting bot noise on SSH, and auto-banning repeat offenders.\n\nPrefer to follow along on video?\n\n## 1. Stop Using the Root User\n\nEvery Linux server in the world ships with an account named `root`. That's the problem — hackers already know the username, so they only need to guess the password or find one exploit to get full control. A custom username forces an attacker to guess two unknowns instead of one.\n\nA few other reasons to move off root:\n\n * **No safety net.** Root executes destructive commands instantly, no confirmation. Run `rm -rf /` as root and it's gone. A standard user needs `sudo`, which at least forces a pause and a password prompt.\n * **Bots target root specifically.** The moment a VPS goes online, automated bots start brute-forcing the root account with thousands of password guesses per minute. Disable root login and that entire attack surface disappears.\n * **No accountability.** If more than one person has server access, a shared root login makes it impossible to tell who did what. Individual sudo accounts get logged to `/var/log/auth.log`, so every command is tied to a specific user.\n\n\n\n### Create a sudo user\n\n\n adduser your_username\n usermod -aG sudo your_username\n\n\n`-aG` breaks down into two flags: `-G` adds the user to the group that follows (`sudo`), and `-a` (append) makes sure the user is _added_ to that group rather than having all their other group memberships wiped out. Together, `-aG` says: add this user to `sudo`, keep everything else as-is.\n\nVerify it worked:\n\n\n\n groups your_username\n\n\n### Lock down root\n\nLog out of root and back in as your new sudo user first, then:\n\n\n\n # Lock the root password\n sudo passwd -l root\n\n # Disable root login over SSH\n sudo nano /etc/ssh/sshd_config\n # set: PermitRootLogin no\n sudo systemctl restart sshd\n\n # Confirm root is locked\n sudo passwd -S root\n\n\n## 2. Set Up a Firewall (UFW)\n\nA firewall closes off everything you're not explicitly using. On a fresh VPS, that means:\n\n * Blocking brute-force attempts on ports you don't need exposed\n * Keeping internal-only services (databases, admin tools) off the public internet\n * Restricting sensitive ports like SSH to specific IPs, if needed\n * Dropping unexpected traffic, which softens basic DoS attempts\n * Closing the door on any hidden vulnerability in something you're running\n\n\n\nUbuntu ships with UFW (Uncomplicated Firewall), which blocks all incoming traffic by default and only opens what you explicitly allow:\n\n\n\n # Allow SSH first so you don't lock yourself out\n sudo ufw allow OpenSSH\n # or: sudo ufw allow 22/tcp\n\n # Allow web traffic if you're hosting a site\n sudo ufw allow http\n sudo ufw allow https\n\n # Turn it on\n sudo ufw enable\n\n # Check status\n sudo ufw status verbose\n\n\n## 3. Change the Default SSH Port\n\nWithin minutes of going live, bots start hammering port 22 — not targeted attacks, just scripts sweeping the internet for the default SSH port. Moving to something non-standard, like 2222, makes those scanners skip right past you.\n\n\n\n sudo nano /etc/ssh/sshd_config\n # uncomment #Port 22 and change it:\n # Port 2222\n\n sudo ufw allow 2222/tcp\n sudo ufw reload\n sudo systemctl restart sshd\n\n\nWorth being honest about this one: security researchers call this \"security through obscurity,\" and on its own it's a weak measure — it doesn't make the server harder to break into. What it does do is keep your auth logs from being flooded with bot noise, which makes real suspicious activity much easier to spot. Pair it with SSH keys, disabled password auth, and Fail2Ban for actual hardening.\n\n## 4. Install Fail2Ban\n\nFail2Ban watches your logs for repeated failed login attempts and temporarily bans the offending IP at the firewall level.\n\n**Why it's worth running:**\n\n * Free, open-source, and quick to set up\n * Highly configurable — ban duration, whitelisted IPs, which services to watch\n * Bans happen at the firewall, so malicious traffic doesn't eat server resources\n * Can integrate with notifications for real-time alerts\n\n\n\n**Where it falls short:**\n\n * Reactive, not preventive — it only acts after a set number of failed attempts have already happened\n * Can lock out legitimate users who fat-finger a password a few times in a row\n * Weak against distributed attacks, since it bans by IP and botnets rotate through thousands of them\n * Vulnerable to IP spoofing\n * Can conflict with Docker's iptables rules on a Docker host, causing bans to fail or hit the wrong container\n\n\n\n**Install it:**\n\n\n\n sudo apt update\n sudo apt install fail2ban -y\n sudo systemctl start fail2ban\n sudo systemctl enable fail2ban\n\n\n(The `-y` flag auto-confirms every prompt during install — only use it once you're already certain about the package.)\n\n## Wrap-Up\n\nNone of these steps make a server unbreakable on their own — a sudo user, a firewall, an obscure SSH port, and Fail2Ban are each individually beatable. Stacked together, they cut off the low-effort, automated attacks that hit every public IP within minutes of going live, and they keep your logs clean enough that you'd actually notice something that isn't normal.\n\nIf you found this useful, the video above walks through each step live. Let me know in the comments if you run into anything setting this up on your own box.",
"title": "How to Secure a VPS: The Complete Ubuntu Hardening Guide"
}