# Set up a firewall with UFW on Ubuntu and Debian

> Protect your Linux server with UFW: deny by default, allow SSH first, open ports and ranges, allow by source IP, rate-limit SSH, delete rules and handle IPv6.

Difficulty: Beginner\
Tested on: Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, Debian 12, Debian 13

UFW (Uncomplicated Firewall) is a front end for the Linux firewall that makes common rules one-line commands. This guide sets up a deny-by-default firewall on Ubuntu 24.04/26.04 or Debian 12/13 and covers the rules you will need later. Replace `198.51.100.7` with your own IP address.

## Before you start

- Log in over SSH with a sudo user, and keep the web console ready if your service page shows one.
- List the services you run and their ports: `sudo ss -tulpn`.

## Step 1: Install UFW

UFW is preinstalled on Ubuntu. On Debian:

```bash
sudo apt install ufw
```

## Step 2: Set defaults and allow SSH first

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
```

`OpenSSH` is an application profile for port 22. If SSH runs on another port, allow that port instead, for example `sudo ufw allow 2222/tcp`.

> **Warning**
>
> Always allow SSH before you enable UFW. Enabling a deny-by-default firewall without an SSH rule cuts your connection.

## Step 3: Allow your services

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

More examples:

| Goal | Command |
|---|---|
| One port | `sudo ufw allow 8080/tcp` |
| A port range | `sudo ufw allow 30000:30100/udp` |
| Only from one address | `sudo ufw allow from 198.51.100.7 to any port 5432 proto tcp` |
| From a whole network | `sudo ufw allow from 198.51.100.0/24 to any port 3306 proto tcp` |
| By application profile | `sudo ufw allow "Nginx Full"` (see `sudo ufw app list`) |
| Deny explicitly | `sudo ufw deny from 203.0.113.50` |

Keep databases and admin panels closed to the internet, or open them only to your own addresses.

## Step 4: Enable and check

```bash
sudo ufw enable
sudo ufw status verbose
```

**Verify:** the status shows `Status: active`, `Default: deny (incoming), allow (outgoing)` and your rules, each for IPv4 and `(v6)`. Open a new SSH session to confirm you still get in.

## Step 5: Rate-limit SSH

Replace the plain SSH rule with a limited one, which denies an address that opens six or more connections within 30 seconds:

```bash
sudo ufw limit OpenSSH
sudo ufw delete allow OpenSSH
```

## Managing rules

List rules with numbers and delete by number:

```bash
sudo ufw status numbered
sudo ufw delete 3
```

Insert a rule at a position (rules are evaluated in order):

```bash
sudo ufw insert 1 deny from 203.0.113.50
```

Preview what a command would do without applying it, using `--dry-run`, for example `sudo ufw --dry-run enable`.

## Logging

```bash
sudo ufw logging low
```

Blocked packets are logged with the prefix `[UFW BLOCK]`; read them with `sudo journalctl -k | grep UFW` or in `/var/log/ufw.log` where rsyslog is installed.

## IPv6

Check that `/etc/default/ufw` contains `IPV6=yes`. If you change it, reload with `sudo ufw reload`. Rules then cover both protocols.

## Docker and UFW

Docker publishes container ports with its own rules, which bypass UFW. A container started with `-p 8080:80` is reachable from the internet even if UFW does not allow 8080. Publish ports on `127.0.0.1` only (for example `-p 127.0.0.1:8080:80`) and expose them through a reverse proxy on the host. See [install Docker on Ubuntu](/guides/install-docker-ubuntu).

## Troubleshooting

**SSH froze right after `ufw enable`.** SSH was not allowed. Use the console: `sudo ufw allow OpenSSH`. See [locked out after a firewall change](/guides/locked-out-after-firewall-change).

**A port is open in UFW but still unreachable.** The service listens on `127.0.0.1` only, or it is not running. Check `sudo ss -tulpn`. See [ports and port forwarding](/guides/ports-and-port-forwarding).

**Outgoing mail on port 25 fails although UFW allows outgoing traffic.** Outbound port 25 is closed by default on HyperDC VPS. For services bought for a term of 3 months or longer, it is opened on request when you open a support ticket. Until then, send mail through a relay on port 587.

**Start over.** `sudo ufw reset` disables UFW and deletes all rules (it backs up the old ones). Add your SSH rule again before enabling.

## Next steps

- More control: [nftables firewall](/guides/nftables-firewall).
- Block repeated attempts: [Fail2ban and CrowdSec](/guides/fail2ban-crowdsec).

## Frequently asked questions

### Is UFW installed by default?

On Ubuntu, yes, but it is inactive until you enable it. On Debian, install it with sudo apt install ufw.

### Does UFW protect IPv6?

Yes, when IPV6=yes is set in /etc/default/ufw, which is the default. Each rule you add then applies to IPv4 and IPv6.

### Why are my Docker containers reachable despite UFW?

Docker publishes container ports with its own firewall rules, which are evaluated before UFW's. Publish ports only on 127.0.0.1 and put a reverse proxy in front, or configure Docker's firewall integration as its documentation describes.

### What does ufw limit do?

It allows a port but denies an address that opens six or more connections within 30 seconds. It suits SSH and slows down password guessing.

### Can I use UFW and nftables rules at the same time?

UFW writes its rules through the system's netfilter framework itself. Do not maintain separate nftables or firewalld rules alongside it; choose one tool.

---

Source: <https://hyperdc.com/guides/networking/ufw-firewall>\
Updated: 2026-10-09
