DB-유

ufw Basics on Ubuntu

· linux, ubuntu, firewall

I like iptables, but I've mistyped one rule on a remote server and spent the next half hour on the provider's web console. That's why I use ufw on most Ubuntu boxes. It turns everyday firewall work into one-liners and still writes real iptables rules underneath. On 16.04 it's installed but disabled.

These are the handful of commands I use on nearly every server. Ubuntu 14.04 or 16.04, sudo access, and mind the order below so you don't lock yourself out.

1. Check the state and set defaults

Before enabling anything, look at the status and set the default policies. Denying incoming and allowing outgoing is the right starting point for almost every server.

sudo ufw status verbose
sudo ufw default deny incoming
sudo ufw default allow outgoing

These defaults are recorded in /etc/default/ufw and /etc/ufw/user.rules; you rarely need to touch those files directly.

2. Allow SSH before enabling the firewall

Everybody skips this once and regrets it. Add a rule for SSH first. ufw understands service names from /etc/services, so ssh and 22/tcp are equivalent:

sudo ufw allow ssh

If sshd listens on a non-standard port, name the port explicitly:

sudo ufw allow 2222/tcp

I use limit instead of allow for SSH on anything public. instead of allow for SSH. It permits connections but blocks a source IP that opens more than six connections in thirty seconds, which takes the edge off brute-force attempts:

sudo ufw limit ssh

3. Enable it

sudo ufw enable

You will be warned that the command may disrupt existing SSH connections. Because the SSH rule is already in place, it will not. ufw is now active and will start at boot via its systemd unit.

4. Open what your services need

For a web server:

sudo ufw allow http
sudo ufw allow https

ufw also ships application profiles in /etc/ufw/applications.d/. Packages such as nginx and Apache register their own, so you can write:

sudo ufw app list
sudo ufw allow 'Nginx Full'

To restrict a service to a single source, for example MySQL from an application server only:

sudo ufw allow from 10.0.0.5 to any port 3306 proto tcp

Whole subnets work too:

sudo ufw allow from 10.0.0.0/24 to any port 5432 proto tcp

5. Deleting and reordering rules

List rules with numbers so you can refer to them precisely:

sudo ufw status numbered
sudo ufw delete 3

You can also delete by repeating the original rule with delete in front:

sudo ufw delete allow http

Rules are evaluated in order, and deny rules for specific hosts should come before broad allow rules. Use insert to place a rule at a given position:

sudo ufw insert 1 deny from 198.51.100.7

6. Logging

ufw logs to /var/log/ufw.log (and to the kernel log) once you enable it:

sudo ufw logging low

low logs blocked packets only, which is what I want most of the time. medium and high add allowed packets and rate-limit information and get noisy quickly.

Check what's really in effect

sudo ufw status verbose

You should see Status: active, the default policies, and each rule with its action and source. To see the underlying iptables rules ufw generated:

sudo iptables -L ufw-user-input -n

From another machine, nc -zv 203.0.113.30 3306 should time out or be refused unless that machine is in an allowed source range.

Gotchas

  • ERROR: Could not find a profile matching 'Nginx Full'. The application profile only exists after the nginx package is installed. Use sudo ufw allow 80,443/tcp instead.
  • Enabled ufw and lost the SSH session. You skipped the SSH rule. From the provider console run sudo ufw allow ssh, or sudo ufw disable to start over.
  • Docker containers reachable despite ufw rules. Docker inserts its own iptables rules that bypass the ufw chains. Either bind published ports to 127.0.0.1 in the container's port mapping, or set "iptables": false in /etc/docker/daemon.json and manage the rules yourself.
  • IPv6 rules missing. Check that IPV6=yes is set in /etc/default/ufw, then run sudo ufw disable && sudo ufw enable so the v6 rules are generated.

ufw won't replace iptables for complicated setups, but for a single server it's plenty. For anything fancier you can still drop raw rules into /etc/ufw/before.rules.