# How to secure a new VPS with UFW and fail2ban

> First hardening steps for a new Ubuntu VPS. Install updates, add a sudo user, set UFW rules, block SSH brute force with fail2ban and enable auto updates.

A fresh VPS is reachable from the whole internet from the first minute. Automated scanners will find it and try to log in long before you install anything useful. The steps below take about 15 minutes on Ubuntu 24.04 and close the most common doors: outdated packages, password guessing and services listening on ports you did not mean to open.

You need root SSH access to the server. See [how to connect via SSH](https://datapasa.com/wiki/server-management/connect-via-ssh).

## Step 1. Install updates

```bash
apt update && apt upgrade -y
```

If the upgrade installed a new kernel, the system shows a message that a restart is required. Reboot once with `reboot` and connect again.

## Step 2. Create a sudo user

Working as root all the time makes every typo dangerous. Create a regular user with sudo rights, here called `admin`:

```bash
adduser admin
usermod -aG sudo admin
```

`adduser` asks for a password and some optional details you can skip with Enter. The password is used for `sudo`, not for SSH, once you switch to keys.

Copy root's authorized keys to the new user if you already use key login:

```bash
rsync --archive --chown=admin:admin ~/.ssh /home/admin
```

If you do not have a key yet, set one up now with [the SSH keys guide](https://datapasa.com/wiki/server-management/set-up-ssh-keys). Then, in a new terminal, check that you can log in and use sudo:

```bash
ssh admin@YOUR_SERVER_IP
sudo whoami
```

The second command must print `root`.

## Step 3. Configure the UFW firewall

UFW (Uncomplicated Firewall) ships with Ubuntu. By default it blocks all incoming connections and allows all outgoing ones once enabled. The only rule you must add **before** enabling it is SSH, otherwise you cut off your own connection.

```bash
sudo ufw allow OpenSSH
sudo ufw enable
```

`OpenSSH` is an application profile that opens port 22. List the profiles available on your system with `sudo ufw app list`.

Open other ports only for the services you actually run. For a web server:

```bash
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
```

Check the result:

```bash
sudo ufw status verbose
```

Useful commands for later:

| Task | Command |
|---|---|
| List rules with numbers | `sudo ufw status numbered` |
| Delete a rule by number | `sudo ufw delete 3` |
| Allow a port only from your IP | `sudo ufw allow from YOUR_HOME_IP to any port 22 proto tcp` |
| Rate limit SSH connections | `sudo ufw limit OpenSSH` |

> **Docker ignores UFW.** If you run Docker, ports you publish with `-p` bypass UFW rules. See [how to install Docker](https://datapasa.com/wiki/server-management/install-docker-on-ubuntu) for how to publish ports safely.

> **Locked out?.** If a firewall rule blocks SSH, open the browser console in [VMmanager](https://datapasa.com/wiki/server-management/manage-server-in-vmmanager) and run `ufw disable` there.

## Step 4. Block brute force attempts with fail2ban

fail2ban watches logs for repeated failed logins and bans the source IP for a while. Install it:

```bash
sudo apt install -y fail2ban
```

On Ubuntu 24.04 the package already enables a jail for SSH in `/etc/fail2ban/jail.d/defaults-debian.conf`, reading from the systemd journal. To adjust how strict it is, put your own values in `/etc/fail2ban/jail.local` instead of editing the shipped files, which updates may replace:

```bash
sudo nano /etc/fail2ban/jail.local
```

```ini
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1

[sshd]
enabled = true
```

This bans an IP for one hour after 5 failures within 10 minutes. Add your home IP to `ignoreip`, separated by a space, if it is static, so you never ban yourself.

Restart the service and check the SSH jail:

```bash
sudo systemctl enable fail2ban
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
```

The output shows the number of failed attempts and currently banned IPs. On a public server the list usually fills up within hours. To unban an address:

```bash
sudo fail2ban-client set sshd unbanip 203.0.113.10
```

Key only login already makes password guessing useless. fail2ban still helps by cutting down the noise in your logs and the load from scanners.

## Step 5. Turn on automatic security updates

Ubuntu Server installs `unattended-upgrades` by default. Make sure it is present and active:

```bash
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
```

Answer **Yes**. This writes `/etc/apt/apt.conf.d/20auto-upgrades` with:

```ini
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
```

By default only security updates are installed, once a day. Some updates, such as a new kernel, need a reboot to take effect. If you want the server to reboot on its own at a quiet hour, open `/etc/apt/apt.conf.d/50unattended-upgrades` and set:

```ini
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";
```

Test the configuration without changing anything:

```bash
sudo unattended-upgrade -v --dry-run
```

## Checklist

- Packages updated and server rebooted if needed
- Sudo user created and tested
- SSH keys in place, password login disabled
- UFW enabled with only the ports you need
- fail2ban running with the `sshd` jail
- Automatic security updates enabled

## Summary

These steps do not make a server bulletproof, but they stop the automated attacks that hit every VPS on the internet. Keep the list of open ports short, update the software you install yourself, and review `sudo ufw status` whenever you add a new service.
