Adds a section documenting how missing HTTP/HTTPS rules caused a site outage on tttpod, and updates the fleet reference table. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
193 lines
5.2 KiB
Markdown
193 lines
5.2 KiB
Markdown
---
|
|
title: "UFW Firewall Management"
|
|
domain: selfhosting
|
|
category: security
|
|
tags: [security, firewall, ufw, ubuntu, networking]
|
|
status: published
|
|
created: 2026-04-02
|
|
updated: 2026-04-03
|
|
---
|
|
|
|
# UFW Firewall Management
|
|
|
|
UFW (Uncomplicated Firewall) is the standard firewall tool on Ubuntu. It wraps iptables/nftables into something you can actually manage without losing your mind. This covers the syntax and patterns I use across the MajorsHouse fleet.
|
|
|
|
## The Short Answer
|
|
|
|
```bash
|
|
# Enable UFW
|
|
sudo ufw enable
|
|
|
|
# Allow a port
|
|
sudo ufw allow 80
|
|
|
|
# Block a specific IP
|
|
sudo ufw insert 1 deny from 203.0.113.50
|
|
|
|
# Check status
|
|
sudo ufw status numbered
|
|
```
|
|
|
|
## Basic Rules
|
|
|
|
### Allow by Port
|
|
|
|
```bash
|
|
# Allow HTTP and HTTPS
|
|
sudo ufw allow 80
|
|
sudo ufw allow 443
|
|
|
|
# Allow a port range
|
|
sudo ufw allow 6000:6010/tcp
|
|
|
|
# Allow a named application profile
|
|
sudo ufw allow 'Apache Full'
|
|
```
|
|
|
|
### Allow by Interface
|
|
|
|
Useful when you only want traffic on a specific network interface — this is how SSH is restricted to Tailscale across the fleet:
|
|
|
|
```bash
|
|
# Allow SSH only on the Tailscale interface
|
|
sudo ufw allow in on tailscale0 to any port 22
|
|
|
|
# Then deny SSH globally (evaluated after the allow above)
|
|
sudo ufw deny 22
|
|
```
|
|
|
|
Rule order matters. UFW evaluates rules top to bottom and stops at the first match.
|
|
|
|
### Allow by Source IP
|
|
|
|
```bash
|
|
# Allow a specific IP to access SSH
|
|
sudo ufw allow from 100.86.14.126 to any port 22
|
|
|
|
# Allow a subnet
|
|
sudo ufw allow from 192.168.50.0/24 to any port 22
|
|
```
|
|
|
|
## Blocking IPs
|
|
|
|
### Insert Rules at the Top
|
|
|
|
When blocking IPs, use `insert 1` to place the deny rule at the top of the chain. Otherwise it may never be evaluated because an earlier ALLOW rule matches first.
|
|
|
|
```bash
|
|
# Block a single IP
|
|
sudo ufw insert 1 deny from 203.0.113.50
|
|
|
|
# Block a subnet
|
|
sudo ufw insert 1 deny from 203.0.113.0/24
|
|
|
|
# Block an IP from a specific port only
|
|
sudo ufw insert 1 deny from 203.0.113.50 to any port 443
|
|
```
|
|
|
|
### Don't Accumulate Manual Blocks
|
|
|
|
Manual `ufw deny` rules pile up fast. On one of my servers, I found **30,142 manual DENY rules** — a 3 MB rules file that every packet had to traverse. Use Fail2ban for automated blocking instead. It manages bans with expiry and doesn't pollute your UFW rules.
|
|
|
|
If you inherit a server with thousands of manual blocks:
|
|
|
|
```bash
|
|
# Nuclear option — reset and re-add only the rules you need
|
|
sudo ufw --force reset
|
|
sudo ufw allow 'Apache Full'
|
|
sudo ufw allow in on tailscale0 to any port 22
|
|
sudo ufw deny 22
|
|
sudo ufw enable
|
|
```
|
|
|
|
## Managing Rules
|
|
|
|
### View Rules
|
|
|
|
```bash
|
|
# Simple view
|
|
sudo ufw status
|
|
|
|
# Numbered (needed for deletion and insert position)
|
|
sudo ufw status numbered
|
|
|
|
# Verbose (shows default policies and logging)
|
|
sudo ufw status verbose
|
|
```
|
|
|
|
### Delete Rules
|
|
|
|
```bash
|
|
# Delete by rule number
|
|
sudo ufw delete 3
|
|
|
|
# Delete by rule specification
|
|
sudo ufw delete allow 8080
|
|
```
|
|
|
|
### Default Policies
|
|
|
|
```bash
|
|
# Deny all incoming, allow all outgoing (recommended baseline)
|
|
sudo ufw default deny incoming
|
|
sudo ufw default allow outgoing
|
|
```
|
|
|
|
## Don't Forget Web Server Ports
|
|
|
|
If you're running a web server behind UFW, make sure ports 80 and 443 are explicitly allowed. This sounds obvious, but it's easy to miss — especially on servers where UFW was enabled after the web server was already running, or where a firewall reset dropped rules that were never persisted.
|
|
|
|
```bash
|
|
# Allow HTTP and HTTPS
|
|
sudo ufw allow 80
|
|
sudo ufw allow 443
|
|
|
|
# Or use an application profile
|
|
sudo ufw allow 'Apache Full'
|
|
```
|
|
|
|
If your site suddenly stops responding after enabling UFW or resetting rules, check `sudo ufw status numbered` first. Missing web ports is the most common cause.
|
|
|
|
## UFW with Fail2ban
|
|
|
|
On Ubuntu servers, Fail2ban and UFW operate at different layers. Fail2ban typically creates its own nftables table (`inet f2b-table`) at a higher priority than UFW's chains. This means:
|
|
|
|
- Fail2ban bans take effect **before** UFW rules are evaluated
|
|
- A banned IP is rejected even if UFW has an ALLOW rule for that port
|
|
- Add trusted IPs (your own, monitoring, etc.) to `ignoreip` in `/etc/fail2ban/jail.local` to prevent self-lockout
|
|
|
|
```ini
|
|
# /etc/fail2ban/jail.local
|
|
[DEFAULT]
|
|
ignoreip = 127.0.0.1/8 ::1 100.0.0.0/8
|
|
```
|
|
|
|
The `100.0.0.0/8` range covers all Tailscale IPs, which prevents banning fleet traffic.
|
|
|
|
## UFW Logging
|
|
|
|
```bash
|
|
# Enable logging (low/medium/high/full)
|
|
sudo ufw logging medium
|
|
```
|
|
|
|
Logs go to `/var/log/ufw.log`. Useful for seeing what's getting blocked, but `medium` or `low` is usually enough — `high` and `full` can be noisy.
|
|
|
|
## Fleet Reference
|
|
|
|
UFW is used on these MajorsHouse servers:
|
|
|
|
| Host | Key UFW Rules |
|
|
|---|---|
|
|
| majortoot | SSH on tailscale0, deny 22 globally |
|
|
| majorlinux | SSH on tailscale0, deny 22 globally |
|
|
| tttpod | SSH on tailscale0, deny 22 globally, Apache Full (added 2026-04-03) |
|
|
| teelia | SSH on tailscale0, deny 22 globally, Apache Full |
|
|
|
|
The Fedora servers (majorlab, majorhome, majormail, majordiscord) use iptables or firewalld instead.
|
|
|
|
## See Also
|
|
|
|
- [Linux Server Hardening Checklist](linux-server-hardening-checklist.md) — initial firewall setup as part of server provisioning
|
|
- [Fail2ban & UFW Rule Bloat Cleanup](../../05-troubleshooting/networking/fail2ban-ufw-rule-bloat-cleanup.md) — what happens when manual blocks get out of hand
|