If you've just rented a VPS, you're probably eager to start installing your apps, website, or the project you've been preparing. But did you know that within minutes of your VPS going online, bots on the internet are already trying to break into it?
These bots work around the clock, scanning IP addresses across the entire internet, looking for open SSH ports, and then trying thousands of username and password combinations (brute force). If your VPS still uses the default setup, logging in as root with a password, sooner or later one of those attempts might just succeed.
The good news is that securing a VPS isn't as complicated as it sounds. With a few simple steps and about 15–20 minutes, your VPS will be far safer against the vast majority of automated attacks.
In this article, we'll walk through how to secure a new Linux VPS step by step, from creating a new user, logging in with an SSH key, disabling root and password logins, enabling the UFW firewall, and installing Fail2ban, to turning on automatic security updates. Let's get started!
Unlike your home computer, which sits behind a router, a VPS is connected directly to the internet with a public IP address. That means anyone on the internet can try to connect to your VPS at any time.
Try it yourself later: after your VPS has been running for a few hours, run the following command to see the failed login attempts:
Don't be surprised if the output contains dozens, or even hundreds, of login attempts from IP addresses you don't recognize. Those are bots trying their luck.
The default VPS setup from most providers is usually quite "relaxed" for the sake of convenience:
Root login is allowed: root is the user with full access. If this account is compromised, the attacker owns the entire server.
Password login is allowed: a password, no matter how strong, can still be guessed by brute force.
No firewall yet: every port opened by an application is immediately reachable from the internet.
No limit on login attempts: bots are free to try as many times as they like.
The steps in this article will close these gaps one by one.
A fresh VPS running Ubuntu 24.04 LTS or 26.04 LTS. The commands in this article are written for both versions. Other Debian-based distros are generally similar, but there may be small differences.
Your VPS IP address and root password (or other initial access) from your VPS provider.
A terminal on your local computer: Terminal on Mac/Linux, or PowerShell on Windows 10/11, which already includes OpenSSH.
Important: while following this tutorial, do not close your active SSH session until you've confirmed you can log in from a new session. If a configuration goes wrong, that old session is your lifeline. As a last resort, most VPS providers also offer a web console in their dashboard.
In the examples in this article, we'll use the IP address 203.0.113.10 and a new user named budi. Replace them with your own IP and username.
The first thing to do on a new VPS is update all packages. The operating system image from your VPS provider was often built weeks or months ago, so there may be security holes that have been patched since then.
Working as root every day is risky. One typo can break the system, and root is also the main target for bots. So we'll create a regular user that can run administrator commands through sudo.
Create a new user with the following command:
adduser budi
You'll be asked to set a password for this user, followed by some extra details like a full name, which you can skip by pressing Enter. Keep this password safe, because you'll use it every time you run sudo.
Next, add the user to the sudo group:
usermod -aG sudo budi
To make sure the new user has sudo access, switch to that user and run a simple command:
su - budisudo whoami
If the output is root, the user budi can now run commands as an administrator. Type exit to return to the root session.
This is the step that has the biggest impact on your VPS security. An SSH key is a pair of cryptographic keys: a private key stored on your computer, and a public key installed on the server. Only a computer holding that private key can log in.
Think of the difference like this: a password is like a PIN code that can be guessed, while an SSH key is like an extremely intricate physical key. Without holding the key, bots don't stand a chance.
This step is done on your local computer, not on the VPS. Open a new terminal and create an SSH key with the following command:
ssh-keygen -t ed25519 -C "budi-laptop"
Press Enter to save it to the default location (~/.ssh/id_ed25519). You'll also be asked to create a passphrase. We strongly recommend setting one, so your private key stays safe even if your laptop is stolen.
The Ed25519 algorithm is more modern and faster than RSA, and produces much shorter keys with excellent security. Almost every modern SSH server supports it.
Now copy the public key to the VPS for the user budi. On Mac/Linux, just use the following command:
If you get straight in without being asked for the user's password (only your SSH key passphrase, if you set one), congratulations! Your SSH key is set up correctly.
Now that your SSH key works, it's time to close the doors that get attacked most often: logging in as root and logging in with a password.
On newer Ubuntu versions, it's best not to edit the main /etc/ssh/sshd_config file directly, but to use an extra file in the /etc/ssh/sshd_config.d/ folder instead. Create a new file with the following command:
Save the file by pressing CTRL+X, then Y, and Enter.
Here's a quick explanation of each line:
PermitRootLogin no: root can't log in over SSH at all.
PasswordAuthentication no: password login is disabled, and only SSH keys are accepted.
KbdInteractiveAuthentication no: closes the interactive login method that could act as a "back door" for passwords.
PubkeyAuthentication yes: makes sure SSH key login stays enabled.
MaxAuthTries 3: the connection is dropped after 3 failed authentication attempts.
Why does the filename start with 00-? Many Ubuntu VPS images include a 50-cloud-init.conf file in the same folder that contains PasswordAuthentication yes. SSH uses the first value it reads, and the files in this folder are read in order by name. With the 00- prefix, our settings are read first and don't get overridden by that file.
Before applying it, check the configuration for typos:
sudo sshd -t
If no message appears, the configuration is valid. Then make sure the settings that are actually in effect match what you expect:
UFW (Uncomplicated Firewall) is Ubuntu's built-in firewall frontend, and as the name suggests, it's very easy to use. The principle is simple: deny all incoming connections, then open only the ports you actually need.
First, make sure UFW is installed:
sudo apt install ufw -y
Set the default policy: deny all incoming connections and allow all outgoing connections.
Then allow SSH. This step is mandatory before enabling UFW, otherwise you'll lock yourself out of your own VPS immediately.
sudo ufw allow OpenSSH
If your VPS will run a website, open the HTTP and HTTPS ports as well:
sudo ufw allow 80/tcpsudo ufw allow 443/tcp
After that, enable UFW with the following command, and type y when asked for confirmation:
sudo ufw enable
Check the firewall status to make sure the rules are active:
sudo ufw status verbose
The output should look roughly like this:
Status: activeLogging: on (low)Default: deny (incoming), allow (outgoing), disabled (routed)New profiles: skipTo Action From-- ------ ----22/tcp (OpenSSH) ALLOW IN Anywhere22/tcp (OpenSSH (v6)) ALLOW IN Anywhere (v6)
If the status is active and the SSH port is listed under ALLOW IN, the firewall is working correctly.
A note for Docker users: Docker manages its own firewall rules, so ports published by containers (for example -p 8080:80) can remain open to the internet even if they aren't allowed in UFW. If you run Docker, it's best to publish ports only on 127.0.0.1 and access them through a reverse proxy.
Even with password login disabled, bots will keep trying. That isn't dangerous, but it floods your logs and wastes server resources. This is where Fail2ban comes in.
Fail2ban watches the login logs and automatically blocks IP addresses that fail to log in too often within a certain time. Install Fail2ban with the following command:
sudo apt install fail2ban -y
On Ubuntu, the SSH jail is actually enabled by default. However, we'll create our own configuration so the rules are explicit and don't get overwritten when the package is updated. Create a jail.local file:
This means an IP address that fails to log in 5 times within 10 minutes will be banned for 1 hour. The backend = systemd option is used because newer Ubuntu versions record SSH logs in the systemd journal rather than in the /var/log/auth.log file.
Tip: if you have a static IP address (for example, your office IP), add it to the ignoreip line so you never get banned by accident, e.g. ignoreip = 127.0.0.1/8 ::1 198.51.100.25.
Enable Fail2ban and restart it so the new configuration is loaded:
To confirm that the SSH jail is working, use the following command:
sudo fail2ban-client status sshd
The output should look something like this:
Status for the jail: sshd|- Filter| |- Currently failed: 0| |- Total failed: 0| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd`- Actions |- Currently banned: 0 |- Total banned: 0 `- Banned IP list:
Leave your VPS running for a few hours, then run the command above again. Usually the Total failed and Total banned numbers will have started to grow, which is a sign that Fail2ban is busy keeping the bots out.
Total failed stays at 0? Compare it with the SSH log using sudo journalctl -u ssh --since "1 hour ago" | grep -i "invalid\|closed". If the log shows lots of login attempts but Fail2ban hasn't recorded any, the default filter probably doesn't recognize the process name used by newer OpenSSH versions (sshd-session). Create the file /etc/fail2ban/filter.d/sshd.local containing the two lines below, then restart Fail2ban:
[Init]journalmatch = _SYSTEMD_UNIT=ssh.service
If your own IP ever gets banned, unban it from the web console with the following command:
sudo fail2ban-client set sshd unbanip 198.51.100.25
New security vulnerabilities are discovered almost every week. To make sure your VPS always gets the latest patches without you logging in every day, enable unattended-upgrades, a feature that automatically installs security updates.
On Ubuntu, this package is usually already installed and enabled by default, but it doesn't hurt to make sure. Run the following commands:
Choose Yes when asked whether to automatically download and install stable updates.
To check that the configuration works, run a simulation with the following command:
sudo unattended-upgrade --dry-run --debug
If there are no errors, automatic security updates are ready to go. By default, unattended-upgrades only installs updates from the security repository, so the risk of an update breaking your apps is very small.
Changing the SSH port from 22 to another port (for example 2222) is not a replacement for the steps above, because more sophisticated bots can still find the new port. However, it's quite effective at reducing the "noise" of automated login attempts in your logs.
If you want to do it, follow the order carefully so you don't lock yourself out. First, open the new port in UFW:
sudo ufw allow 2222/tcp
Second, add the following line to the /etc/ssh/sshd_config.d/00-hardening.conf file:
Port 2222
Third, apply the change. Since Ubuntu 22.10, SSH is started through systemd socket activation, so simply restarting ssh won't move the port. Use the following commands instead:
From this article, we can conclude that securing a new Linux VPS is actually quite easy and doesn't require any complicated tools. The key lies in a few basic steps: using a regular user with sudo, logging in only with an SSH key, disabling root and password login, enabling the UFW firewall, installing Fail2ban, and letting security updates run automatically.
Of all these steps, disabling password login and switching to SSH keys has the biggest impact. With this step alone, almost every automated brute-force attack becomes useless.
Keep in mind that security isn't a one-time job. Make it a habit to check your logs now and then, keep an eye on Fail2ban's status, and only open the ports you actually need whenever you install a new application.
Once your VPS is secure, you can start installing applications with peace of mind. If your VPS has little RAM, don't forget to read how to configure swap memory in Linux. And if you'd like to deploy apps as easily as on Heroku, check out the tutorial on how to install CapRover.