OpenWrt’s firewall is a UCI-based abstraction over the underlying packet filtering engine. Since OpenWrt 22.03 the default implementation is firewall4 (fw4), which translates UCI config to nftables rules. Older releases used an iptables backend.
The configuration format (/etc/config/firewall) is identical for both the nftables (fw4) and iptables backends. Existing configs migrate without change.
/etc/config/firewall structure
The file contains five types of UCI sections:
| Section type | Purpose |
|---|
config defaults | Global policies and flags |
config zone | Named security zones (e.g. lan, wan) |
config forwarding | Zone-to-zone forwarding permissions |
config rule | Stateless traffic rules (allow/block/reject) |
config redirect | DNAT port forwarding and NAT rules |
Global defaults
config defaults
option synflood_protect 1
option input REJECT
option output ACCEPT
option forward REJECT
| Option | Description |
|---|
synflood_protect | Enable SYN flood protection |
input | Default policy for traffic destined to the router itself |
output | Default policy for traffic originating from the router |
forward | Default policy for traffic passing through the router |
disable_ipv6 | Set to 1 to suppress generation of IPv6 rules |
Valid policy values: ACCEPT, REJECT, DROP.
Zones
A zone is a named group of interfaces that share the same trust level and traffic policy.
config zone
option name lan
list network 'lan'
option input ACCEPT
option output ACCEPT
option forward ACCEPT
config zone
option name wan
list network 'wan'
list network 'wan6'
option input REJECT
option output ACCEPT
option forward REJECT
option masq 1
option mtu_fix 1
| Zone option | Description |
|---|
name | Zone identifier referenced by forwarding/rule/redirect sections |
network | One or more logical interface names (from /etc/config/network) |
input | Policy for traffic entering the router from this zone |
output | Policy for traffic leaving the router into this zone |
forward | Policy for traffic transiting through the router via this zone |
masq | Enable IPv4 masquerading (SNAT) — set on the WAN zone |
mtu_fix | Enable MSS clamping to fix MTU issues on PPPoE/tunnels |
extra_src | Raw nftables match expressions added to source matching |
Forwarding rules
Forwarding sections grant one zone permission to send traffic to another zone through the router. Without a forwarding entry, traffic between zones is blocked by the forward policy.
# Allow LAN to reach WAN (standard internet access)
config forwarding
option src lan
option dest wan
To allow traffic in both directions (e.g. for a VPN zone that should reach LAN):
config forwarding
option src vpn
option dest lan
config forwarding
option src lan
option dest vpn
Traffic rules
Traffic rules match packets and apply a target action. Rules are evaluated in order; the first match wins.
Example: allow SSH from WAN
config rule
option name Allow-SSH-WAN
option src wan
option dest_port 22
option proto tcp
option target ACCEPT
Example: block a specific host from reaching WAN
config rule
option name Block-Host
option src lan
option src_ip 192.168.1.100
option dest wan
option target REJECT
Example: block inbound traffic on a port range
config rule
option name Block-Port-Range
option src wan
option dest_port 6881:6889
option proto tcp
option target DROP
Traffic rule options
| Option | Description |
|---|
name | Human-readable rule name |
src | Source zone name (or * for any) |
src_ip | Match source IP/CIDR |
src_mac | Match source MAC address |
src_port | Match source port(s) or range |
dest | Destination zone name (omit for input rules) |
dest_ip | Match destination IP/CIDR |
dest_port | Match destination port(s) or range |
proto | Protocol: tcp, udp, icmp, all, etc. |
family | Address family: ipv4, ipv6, or any |
target | Action: ACCEPT, REJECT, DROP, NOTRACK |
enabled | Set to 0 to disable without deleting |
Port forwarding (DNAT redirects)
Redirect sections map an incoming WAN port to an internal LAN host.
Example: forward HTTP (port 80) to an internal web server
config redirect
option name Forward-HTTP
option src wan
option src_dport 80
option dest lan
option dest_ip 192.168.1.10
option dest_port 80
option proto tcp
option target DNAT
Example: forward a remapped SSH port
config redirect
option name Forward-SSH
option src wan
option src_dport 2222
option dest lan
option dest_ip 192.168.1.20
option dest_port 22
option proto tcp
option target DNAT
Redirect options
| Option | Description |
|---|
src | Incoming zone (usually wan) |
src_ip | Limit to a specific external source IP |
src_dport | Destination port(s) on the WAN side |
dest | Target zone (usually lan) |
dest_ip | Internal host IP address |
dest_port | Internal port (can differ from src_dport) |
proto | Protocol: tcp, udp, or tcp udp |
target | DNAT for port forwarding, SNAT for source NAT |
Managing the firewall
Reload after config changes
# Reload the firewall (fw4, nftables-based)
fw4 reload
# Or via the init script
/etc/init.d/firewall reload
Inspect the active ruleset
# Print the full generated nftables ruleset
fw4 print
# Show zone and rule summary
fw4 status
# Inspect raw nftables tables directly
nft list ruleset
Add a rule via UCI (no file editing)
# Add a port-forwarding redirect
uci add firewall redirect
uci set firewall.@redirect[-1].name='Forward-HTTPS'
uci set firewall.@redirect[-1].src='wan'
uci set firewall.@redirect[-1].src_dport='443'
uci set firewall.@redirect[-1].dest='lan'
uci set firewall.@redirect[-1].dest_ip='192.168.1.10'
uci set firewall.@redirect[-1].dest_port='443'
uci set firewall.@redirect[-1].proto='tcp'
uci set firewall.@redirect[-1].target='DNAT'
uci commit firewall
fw4 reload
Always test firewall changes over a local connection before committing. An incorrect rule can lock you out of SSH access. Keep a console session open or use the fw4 reload command’s built-in rollback support when testing remotely.
Custom nftables rules
For advanced use cases not covered by the UCI abstraction, place raw nftables include files in /etc/nftables.d/. Files matching *.nft are loaded by fw4 after generating the main ruleset.
# /etc/nftables.d/99-custom.nft
table inet fw4 {
chain forward {
# Drop all traffic from a specific subnet
ip saddr 10.0.99.0/24 drop
}
}