Skip to content

/commands/ufw/ufw-block-ip-address

ufw block an IP address: sudo ufw insert 1 deny from 203.0.113.7

The commands on this page have not been executed by our verification runner yet.updated
tool
ufw
versions
ufw 0.36
os
linux

sudo ufw insert 1 deny from 203.0.113.7 blocks all incoming traffic from that address by placing the rule before every other rule. Position matters: ufw applies the first rule that matches, and ufw deny from ... alone appends the rule after your existing allow rules, where it never fires for ports you have opened. sudo ufw prepend deny from ADDRESS has the same effect and also handles IPv6 correctly.

bash
sudo ufw insert 1 deny from 203.0.113.7               # block one IPv4 address
sudo ufw prepend deny from 203.0.113.7                # same, top of the IPv4 rules
sudo ufw prepend deny from 2001:db8::7                # top of the IPv6 rules
sudo ufw insert 1 deny from 198.51.100.0/24           # a whole network
sudo ufw insert 1 deny from 203.0.113.7 to any port 22 proto tcp   # only SSH
sudo ufw status numbered                              # check the order

Variants

CommandEffect
ufw deny from ADDRAppend a deny rule; blocks only traffic no earlier rule accepted.
ufw insert 1 deny from ADDRPut the rule first so it overrides every allow.
ufw prepend deny from ADDRPut it before all rules of the same IP version.
ufw reject from ADDRRefuse with an error instead of dropping silently.
ufw deny from ADDR to any port 443 proto tcpBlock one service for that source only.
ufw deny out to ADDRStop this machine from connecting to ADDR.
ufw delete deny from ADDRRemove the block by repeating the rule after delete.

Check the order

bash
sudo ufw status numbered

The deny rule should be [ 1] (or the first (v6) rule for an IPv6 address). If it sits below an ALLOW IN Anywhere line for the same port, it has no effect on that port. Delete it with sudo ufw delete NUMBER and insert it again at the top; numbers change after each delete, so list again before deleting a second rule.

Pitfalls

  • Docker published ports. Containers published with -p are reached through the FORWARD path and Docker's own iptables chains, so ufw rules on INPUT do not apply to them. Docker documents the DOCKER-USER chain for this case.
  • Many addresses. One ufw rule per address becomes slow and hard to read. For large blocklists, use an ipset referenced from /etc/ufw/before.rules, or a tool built for it such as fail2ban.
  • Already established connections. ufw allows packets of connections already established through its connection tracking rules; an attacker connected before the rule may keep the open session until it ends.
  • Empty ruleset. insert 1 needs an existing rule at that position; with no rules at all ufw answers ERROR: Invalid position '1'. Use ufw deny from ADDR or prepend in that case.
  • Root required. Without sudo ufw stops with You need to be root to run this script.

Confirm it works

sudo ufw status verbose shows the rule as DENY IN from the address. With logging on (sudo ufw logging on), blocked packets from it appear in the kernel log or /var/log/ufw.log with the [UFW BLOCK] prefix. For the plain iptables way, see iptables block an IP address.

FAQ

Why does ufw deny from IP not block anything?

ufw evaluates rules in order and the first match wins. ufw deny appends the rule, so an earlier allow rule (for example 22/tcp from Anywhere) still accepts the traffic. Insert the deny at position 1 or use prepend.

What is the difference between deny and reject?

deny drops the packets silently, so the sender waits for a timeout. reject sends an error back, so the client fails immediately. Use deny for hostile sources and reject when you want legitimate clients to notice quickly.

Does ufw insert 1 work for IPv6 addresses?

Not when IPv4 rules exist. ufw lists IPv4 rules first, and inserting an IPv6 rule at a position held by an IPv4 rule fails with ERROR: Invalid position '1'. Use ufw prepend deny from ADDRESS, which puts the rule before all rules of its own IP version.

Sources