Firewall Configuration

The firewall configuration located in /etc/config/firewall.

Overview

OpenWrt relies on netfilter for packet filtering, NAT and mangling. The UCI Firewall provides a configuration interface that abstracts from the iptables system to provide a simplified configuration model that is fit for most regular purposes while enabling the user to supply needed iptables rules on their own when needed.

UCI Firewall maps two or more Interfaces together into Zones that are used to describe default rules for a given interface, forwarding rules between interfaces and extra rules. In the config file, default rules come first but they are the last to take effect. The netfilter system is a chained processing filter where packets pass through various rules. The first rule that matches is executed, often leading to another rule-chain until a packet hits either ACCEPT or DROP/REJECT. Such an outcome is final, therefore the default rules take effect last and the most specific rule takes effect first. Zones are also used to configure masquerading also known as NAT (network-address-translation) as well as port forwarding rules, which are more generally known as redirects.

Zones must always be mapped onto one or more Interfaces which ultimately map onto physical devices; therefore zones cannot be used to specify networks (subnets) and the generated iptables rules operate on interfaces exclusively. The difference is that interfaces can be used to reach destinations not part of their own subnet, when their subnet contains another gateway. Usually however, forwarding is done between lan and wan interfaces, with the router serving as edge gateway to the internet. The default configuration of UCI Firewall provides for such a common setup.

Requirements

  • firewall (or firewall3) and its dependencies (pre-installed)

  • iptables (pre-installed)

  • iptables-mod-? (optional) - depends on what speial feature is required

Sections

Below is an overview of the section types that may be defined in the firewall configuration. A minimal firewall configuration for a router usually consists of one defaults section, at least two zones (lan and wan) and one forwarding to allow traffic from lan to wan.

Defaults

The defaults section declares global firewall settings which do not belong to specific zones. The following options are defined within this section:

Name Type Required Default Description

input

string

no

REJECT

Set policy for the INPUT chain of the filter table.

output

string

no

REJECT

Set policy for the OUTPUT chain of the filter table.

forward

string

no

REJECT

Set policy for the FORWARD chain of the filter table.

drop_invalid

boolean

no

0

Drop invalid packets (e.g. not matching any active connection).

synflood_protect

boolean

no

0

Enable SYN flood protection.

synflood_rate

string

no

25

Set rate limit (packets/second) for SYN packets above which the traffic is considered a flood.

synflood_burst

string

no

50

Set burst limit for SYN packets above which the traffic is considered a flood if it exceeds the allowed rate.

tcp_syncookies

boolean

no

1

Enable the use of SYN cookies.

tcp_ecn

boolean

no

0

tcp_westwood

boolean

no

0

tcp_window_scaling

boolean

no

1

Enable TCP window scaling.

accept_redirects

boolean

no

0

accept_source_route

boolean

no

0

custom_chains

boolean

no

1

disable_ipv6

boolean

no

0

Disable IPv6 firewall rules.

Zones

A zone section groups one or more interfaces and serves as a source or destination for forwardings, rules and redirects. Masquerading (NAT) of outgoing traffic is controlled on a per-zone basis. Note that masquerading is defined on the outgoing interface.

  • INPUT rules for a zone describe what happens to traffic trying to reach the router itself through an interface in that zone.

  • OUTPUT rules for a zone describe what happens to traffic originating from the router itself going through an interface in that zone.

  • FORWARD rules for a zone describe what happens to traffic passing between different interfaces in that zone.

The options below are defined within zone sections:

Name Type Required Default Description

name

zone name

yes

(none)

Unique zone name. 11 characters is the maximum working firewall zone name length.

network

list

no

(none)

List of interfaces attached to this zone. If omitted and neither extra* options, subnets or devices are given, the value of name is used by default. Alias interfaces defined in the network config cannot be used as valid standalone networks.

masq

boolean

no

0

Specifies whether outgoing zone traffic should be masqueraded - this is typically enabled on the wan zone

masq_src

list of subnets

no

0.0.0.0/0

Limit masquerading to the given source subnets. Negation is possible by prefixing the subnet with !. multiple subnets are allowed.

masq_dest

list of subnets

no

0.0.0.0/0

Limit masquerading to the given destination subnets. Negation is possible by prefixing the subnet with !. multiple subnets are allowed.

conntrack

boolean

no

1 if masquerading is used, 0 otherwise

Force connection tracking for this zone

mtu_fix

boolean

no

0

Enable MSS clamping for outgoing zone traffic

input

string

no

DROP

Default policy (ACCEPT, REJECT, DROP) for incoming zone traffic

forward

string

no

DROP

Default policy (ACCEPT, REJECT, DROP) for forwarded zone traffic

output

string

no

DROP

Default policy (ACCEPT, REJECT, DROP) for outgoing zone traffic

family

string

no

any

Protocol family (ipv4, ipv6 or any) to generate iptables rules for

log

boolean

no

0

Create log rules for rejected and dropped traffic in this zone

log_limit

string

no

10/minute

Limits the amount of log messages per interval

device

list

no

(none)

List of raw network device names attached to this zone, e.g. ppp+ to match any PPP interface

subnet

list

no

(none)

List of IP subnets attached to this zone

extra

string

no

(none)

Extra arguments passed directly to iptables. Note that these options are passed to both source and destination classification rules, therfore direction-specific options like --dport should not be used here - in this case the extra_src and extra_dest options should be used instead

extra_src

string

no

Value of 'extra'

Extra arguments passed directly to iptables for source classification rules

extra_dest

string

no

Value of 'extra'

Extra arguments passed directly to iptables for destination classification rules

Forwardings

The forwarding sections control the traffic flow between zones and may enable MSS clamping for specific directions. Only one direction is covered by a forwarding rule. To allow bidirectional traffic flows between two zones, two forwardings are required, with src and dest reversed in each.

Below is a listing of allowed option within forwardings:

Name Type Required Default Description

src

zone name

yes

(none)

Specifies the traffic source zone. Must refer to one of the defined zone names

dest

zone name

yes

(none)

Specifies the traffic destination zone. Must refer to one of the defined zone names

family

string

no

any

Protocol family (ipv4, ipv6 or any) to generate iptables rules for

The iptables rules generated for this section rely on the state match which needs connection tracking to work. At least one of the src or dest zones needs to have connection tracking enabled through either the masq or the conntrack option.

Redirects

Port forwardings (DNAT) are defined by redirect sections. All incoming traffic on the specified source zone which matches the given rules will be directed to the specified internal host.

Redirects are also commonly known as "port forwarding", and "virtual servers".

Port ranges are specified as start:stop, for instance 6666:6670. This is similar to the iptables syntax.

The options below are valid for redirects:

Name Type Required Default Description

src

zone name

yes for DNAT target

(none)

Specifies the traffic source zone. Must refer to one of the defined zone names. For typical port forwards this usually is wan

src_ip

ip address

no

(none)

Match incoming traffic from the specified source ip address

src_dip

ip address

yes for SNAT target

(none)

For DNAT, match incoming traffic directed at the given destination ip address. For SNAT rewrite the source address to the given address.

src_mac

mac address

no

(none)

Match incoming traffic from the specified mac address

src_port

port or range

no

(none)

Match incoming traffic originating from the given source port or port range on the client host

src_dport

port or range

no

(none)

For DNAT, match incoming traffic directed at the given destination port or port range on this host. For SNAT rewrite the source ports to the given value.

proto

protocol name or number

yes

tcpudp

Match incoming traffic using the given protocol

dest

zone name

yes for SNAT target

(none)

Specifies the traffic destination zone. Must refer to one of the defined zone names.

dest_ip

ip address

yes for DNAT target

(none)

For DNAT, redirect matched incoming traffic to the specified internal host. For SNAT, match traffic directed at the given address. For DNAT if the dest_ip value matches the local ip addresses of the router, as shown in the ifconfig, then the rule is translated in a DNAT + input accept rule. Otherwise it is a DNAT + forward rule

dest_port

port or range

no

(none)

For DNAT, redirect matched incoming traffic to the given port on the internal host. For SNAT, match traffic directed at the given ports. Only a single port or range can be specified, not disparate ports as with Rules (below)

ipset

string

no

(none)

If specified, match traffic against the given ipset. The match can be inverted by prefixing the value with an exclamation mark

mark

string

no

(none)

If specified, match traffic against the given firewall mark, e.g. 0xFF to match mark 255 or 0x0/0x1 to match any even mark value. The match can be inverted by prefixing the value with an exclamation mark, e.g. !0x10 to match all but mark #16.

start_date

date (yyyy-mm-dd)

no

(always)

If specifed, only match traffic after the given date (inclusive).

stop_date

date (yyyy-mm-dd)

no

(always)

If specified, only match traffic before the given date (inclusive).

start_time

time (hh:mm:ss)

no

(always)

If specified, only match traffic after the given time of day (inclusive).

stop_time

time (hh:mm:ss)

no

(always)

If specified, only match traffic before the given time of day (inclusive).

weekdays

list of weekdays

no

(always)

If specified, only match traffic during the given week days, e.g. sun mon thu fri to only match on sundays, mondays, thursdays and fridays. The list can be inverted by prefixing it with an exclamation mark, e.g. ! sat sun to always match but on saturdays and sundays.

monthdays

list of dates

no

(always)

If specified, only match traffic during the given days of the month, e.g. 2 5 30 to only match on every 2nd, 5th and 30rd day of the month. The list can be inverted by prefixing it with an exclamation mark, e.g. ! 31 to always match but on the 31st of the month.

utc_time

boolean

no

0

Treat all given time values as UTC time instead of local time.

target

string

no

DNAT

NAT target (DNAT or SNAT) to use when generating the rule

family

string

no

any

Protocol family (ipv4, ipv6 or any) to generate iptables rules for.

reflection

boolean

no

1

Activate NAT reflection for this redirect - applicable to DNAT targets.

reflection_src

string

no

internal

The source address to use for NAT-reflected packets if reflection is 1. This can be internal or external, specifying which interface’s address to use. Applicable to DNAT targets.

limit

string

no

(none)

Maximum average matching rate; specified as a number, with an optional /second, /minute, /hour or /day suffix. Examples: 3/second, 3/sec or 3/s.

limit_burst

integer

no

5

Maximum initial number of packets to match, allowing a short-term average above limit

extra

string

no

(none)

Extra arguments to pass to iptables. Useful mainly to specify additional match options, such as -m policy %%--%%dir in for IPsec.

enabled

string

no

1 or yes

Enable the redirect rule or not.

Rules

Sections of the type rule can be used to define basic accept or reject rules to allow or restrict access to specific ports or hosts.

The rules are defined as follows: * If src and dest are given, the rule matches forwarded traffic * If only src is given, the rule matches incoming traffic * If only dest is given, the rule matches outgoing traffic * If neither src nor dest are given, the rule defaults to an outgoing traffic rule

Port ranges are specified as start:stop, for instance 6666:6670. This is similar to the iptables syntax.

Valid options for this section are:

Name Type Required Default Description

src

zone name

no

(none)

Specifies the traffic source zone. Must refer to one of the defined zone names

src_ip

ip address

no

(none)

Match incoming traffic from the specified source ip address

src_mac

mac address

no

(none)

Match incoming traffic from the specified mac address

src_port

port or range

no

(none)

Match incoming traffic from the specified source port or port range, if relevant proto is specified. Multiple ports can be specified like 80 443 465

proto

protocol name or number

no

tcpudp

Match incoming traffic using the given protocol. Can be one of tcp, udp, tcpudp, udplite, icmp, esp, ah, sctp, or all or it can be a numeric value. A protocol name from /etc/protocols is also allowed. The number 0 is equivalent to all.

icmp_type

list of type names or numbers

no

any

For protocol icmp select specific icmp types to match. Values can be either exact icmp type numbers or type names (see below).

dest

zone name

no

(none)

Specifies the traffic destination zone. Must refer to one of the defined zone names, or * for any zone. If specified, the rule applies to forwarded traffic; otherwise, it is treated as input rule.

dest_ip

ip address

no

(none)

Match incoming traffic directed to the specified destination ip address. With no dest zone, this is treated as an input rule!

dest_port

port or range

no

(none)

Match incoming traffic directed at the given destination port or port range, if relevant proto is specified. Multiple ports can be specified like 80 443 465

ipset

string

no

(none)

If specified, match traffic against the given ipset. The match can be inverted by prefixing the value with an exclamation mark

mark

mark/mask

no

(none)

If specified, match traffic against the given firewall mark, e.g. 0xFF to match mark 255 or 0x0/0x1 to match any even mark value. The match can be inverted by prefixing the value with an exclamation mark, e.g. !0x10 to match all but mark #16.

start_date

date (yyyy-mm-dd)

no

(always)

If specifed, only match traffic after the given date (inclusive).

stop_date

date (yyyy-mm-dd)

no

(always)

If specified, only match traffic before the given date (inclusive).

start_time

time (hh:mm:ss)

no

(always)

If specified, only match traffic after the given time of day (inclusive).

stop_time

time (hh:mm:ss)

no

(always)

If specified, only match traffic before the given time of day (inclusive).

weekdays

list of weekdays

no

(always)

If specified, only match traffic during the given week days, e.g. sun mon thu fri to only match on sundays, mondays, thursdays and fridays. The list can be inverted by prefixing it with an exclamation mark, e.g. ! sat sun to always match but on saturdays and sundays.

monthdays

list of dates

no

(always)

If specified, only match traffic during the given days of the month, e.g. 2 5 30 to only match on every 2nd, 5th and 30rd day of the month. The list can be inverted by prefixing it with an exclamation mark, e.g. ! 31 to always match but on the 31st of the month.

utc_time

boolean

no

0

Treat all given time values as UTC time instead of local time.

target

string

yes

DROP

Firewall action (ACCEPT, REJECT, DROP, MARK, NOTRACK) for matched traffic

set_mark

mark/mask

yes for target MARK

(none)

Zeroes out the bits given by mask and ORs value into the packet mark. If mask is omitted, 0xFFFFFFFF is assumed

set_xmark

:::

:::

:::

Zeroes out the bits given by mask and XORs value into the packet mark. If mask is omitted, 0xFFFFFFFF is assumed

family

string

no

any

Protocol family (ipv4, ipv6 or any) to generate iptables rules for.

limit

string

no

(none)

Maximum average matching rate; specified as a number, with an optional /second, /minute, /hour or /day suffix. Examples: 3/minute, 3/min or 3/m.

limit_burst

integer

no

5

Maximum initial number of packets to match, allowing a short-term average above limit

extra

string

no

(none)

Extra arguments to pass to iptables. Useful mainly to specify additional match options, such as -m policy %%--%%dir in for IPsec.

enabled

boolean

no

yes

Enable or disable rule.

Available icmp type names for icmp_type:

address-mask-reply host-redirect pong time-exceeded

address-mask-request

host-unknown

port-unreachable

timestamp-reply

any

host-unreachable

precedence-cutoff

timestamp-request

communication-prohibited

ip-header-bad

protocol-unreachable

TOS-host-redirect

destination-unreachable

network-prohibited

redirect

TOS-host-unreachable

echo-reply

network-redirect

required-option-missing

TOS-network-redirect

echo-request

network-unknown

router-advertisement

TOS-network-unreachable

fragmentation-needed

network-unreachable

router-solicitation

ttl-exceeded

host-precedence-violation

parameter-problem

source-quench

ttl-zero-during-reassembly

host-prohibited

ping

source-route-failed

ttl-zero-during-transit

Includes

It is possible to include custom firewall scripts by specifying one or more include sections in the firewall configuration.

There is only one possible parameter for includes:

Name Type Required Default Description

enabled

boolean

no

1

Allows to disable the corresponding include without having to delete the section

type

string

no

script

Specifies the type of the include, can be script for traditional shell script includes or restore for plain files in iptables-restore format

path

file name

yes

/etc/firewall.user

Specifies a shell script to execute on boot or firewall restarts

family

string

no

any

Specifies the address family (ipv4, ipv6 or any) for which the include is called

reload

boolean

no

0

Specifies whether the include should be called on reload - this is only needed if the include injects rules into internal chains

Includes of type script may contain arbitary commands, for example advanced iptables rules or tc commands required for traffic shaping.

Since custom iptables rules are meant to be more specific than the generic ones, you must make sure to use -I (insert) instead of -A (append) so that the rules appear before the default rules.

IP Sets

The UCI firewall version 3 supports referencing or creating ipsets to simplify matching of huge address or port lists without the need for creating one rule per item to match,

The following options are defined for ipsets:

Name Type Required Default Description

enabled

boolean

no

1

Allows to disable the declaration fo the ipset without the need to delete the section

external

string

no

(none)

If the external option is set to a name, the firewall will simply reference an already existing ipset pointed to by the name. If the external option is unset, the firewall will create the ipset on start and destroy it on stop

name

string

yes if external is unset \\ no if external is set

(none) if external is unset \\ value of external if external is set

Specifies the firewall internal name of the ipset which is used to reference the set in rules or redirects

family

string

no

ipv4

Protocol family (ipv4 or ipv6) to create ipset for. Only applicable to storage types hash and list, the bitmap type implies ipv4.

storage

string

no

varies

Specifies the storage method (bitmap, hash or list) used by the ipset, the default varies depending on the used datatypes (see match option below). In most cases the storage method can be automatically inferred from the datatype combination but in some cases multiple choices are possible (e.g. bitmap:ip vs. hash:ip).

match

list of direction/type tuples

yes

(none)

Specifies the matched data types (ip, port, mac, net or set) and their direction (src or dest). The direction is joined with the datatype by an underscore to form a tuple, e.g. src_port to match source ports or dest_net to match destination CIDR ranges.

iprange

IP range

yes for storage type bitmap with datatype ip

(none)

Specifies the IP range to cover, see ipset. Only applicable to the hash storage type.

portrange

Port range

yes for storage type bitmap with datatype port

(none)

Specifies the port range to cover, see ipset. Only applicable to the hash storage type.

netmask

integer

no

32

If specified, network addresses will be stored in the set instead of IP host addresses. Value must be between 1 and 32, see ipset. Only applicable to the bitmap storage type with match ip or the hash storage type with match ip.

maxelem

integer

no

65536

Limits the number of items that can be added to the set, only applicable to the hash and list storage types.

hashsize

integer

no

1024

Specifies the initial hash size of the set, only applicable to the hash storage type.

timeout

integer

no

0

Specifies the default timeout for entries added to the set. A value of 0 means no timeout.

Possible Storage / Match Combinations

The table below outlines the possible combinations of storage methods and matched datatypes as well as the usable IP address family. The order of the datatype matches is significant.

Family Storage Match Notes

ipv4

bitmap

ip

Requries iprange option

ipv4

bitmap

ip mac

Requires iprange option

ipv4

bitmap

port

Requires portrange option

any

hash

ip

-

any

hash

net

-

any

hash

ip port

-

any

hash

net port

-

any

hash

ip port ip

-

any

hash

ip port net

-

-

list

set

Meta type to create a set-of-sets

IPv6 notes

As described above, the option family is used for distinguishing between IPv4, IPv6 and both protocols. However the family is inferred automatically if IPv6 addresses are used, the following is automatically treated as an IPv6 only rule.

config rule
	option src wan
	option src_ip fdca:f00:ba3::/64
	option target ACCEPT

Similar, such a rule is detected as IPv4 only.

config rule
	option src wan
	option dest_ip 88.77.66.55
	option target REJECT

Rules without IP addresses are automatically added to iptables and ip6tables, unless overridden by the family option. Redirect rules (portforwards) are always IPv4 (for now) since there is no IPv6 DNAT support (yet).

Examples

Opening ports

The default configuration accepts all LAN traffic, but blocks all incoming WAN traffic on ports not currently used for connections or NAT. To open a port for a service, add a rule section:

config rule
	option src              wan
	option dest_port        22
	option target           ACCEPT
	option proto            tcp

This example enables machines on the internet to use SSH to access your router.

Opening ports for selected subnet/host

If you want to permit access to one host or subnet you should describe src_ip field:

config rule
	option src              wan
	option src_ip           '12.34.56.64/28'
	option dest_port        22
	option target           ACCEPT
	option proto            tcp

This example enables ssh access to the host from the entire 12.34.56.64/28 subnet.

Port forwarding for IPv4 (Destination NAT/DNAT)

This example forwards http (but not HTTPS) traffic to the webserver running on 192.168.1.10:

config redirect
	option src       wan
	option src_dport 80
	option proto     tcp
	option dest      lan
	option dest_ip   192.168.1.10

This other example forwards one arbitrary port that you define to a box running ssh.

config redirect
	option src       wan
	option src_dport 5555
	option proto     tcp
	option dest      lan
	option dest_ip   192.168.1.100
	option dest_port 22

Stateful firewall without NAT

If your LAN is running with public IP addresses, then you definitely don’t want NAT (masquerading). But you may still want to run a stateful firewall on the router, so that machines on the LAN are not reachable from the Internet.

To do this, just add the conntrack option to the WAN zone:

config zone
	option name             wan
	list   network          'wan'
	list   network          'wan6'
	option input            REJECT
	option output           ACCEPT
	option forward          REJECT
	option masq             0
	option mtu_fix          1
	option conntrack        1

DNAT/SNAT redirects and forwarding combination

Given a couple of redirect (DNAT and SNAT, like to redirect the traffic from an host to and from a specific ip address) such as:

config redirect
	option name     'icmp DNAT'
	option src      'wan'
	option src_dip   '1.2.3.4'
	option proto    'icmp'
	option dest     'dmz'
	option dest_ip  '192.168.1.79'
	option target   'DNAT'

config redirect
	option name     'icmp SNAT'
	option src      'dmz'
	option src_ip   '192.168.1.79'
	option src_dip  '1.2.3.4'
	option proto    'icmp'
	option dest     'wan'
	option target   'SNAT'

Someone could ask "Ok, the packet source or destination is changed, but still has to be forwarded towards the right network interface to reach the endpoint". So the administrator of the device could wonder of adding additional forwarding rules but no, it is not needed. The forwarding rules are added by the firewall appliance itself.

The same applies to the masquerading, the rules are applied before the global masquerading (if a masquerading is set), therefore they will not be overridden (at least the SNAT) by the masquerading mechanism.

Port accept for IPv6

To open port 80 so that a local webserver at 2001:db8:42::1337 can be reached from the Internet:

config rule
	option src       wan
	option proto     tcp
	option dest      lan
	option dest_ip   2001:db8:42::1337
	option dest_port 80
	option family    ipv6
	option target    ACCEPT

To open SSH access to all IPv6 hosts in the local network:

config rule
	option src       wan
	option proto     tcp
	option dest      lan
	option dest_port 22
	option family    ipv6
	option target    ACCEPT

To open all TCP/UDP port between 1024 and 65535 towards the local IPv6 network:

config rule
	option src       wan
	option proto     tcpudp
	option dest      lan
	option dest_port 1024:65535
	option family    ipv6
	option target    ACCEPT

Source NAT (SNAT)

Source NAT changes an outgoing packet so that it looks as though the OpenWrt system is the source of the packet.

Define source NAT for UDP and TCP traffic directed to port 123 originating from the host with the IP address 10.55.34.85. The source address is rewritten to 63.240.161.99:

config redirect
	option src              lan
	option dest             wan
	option src_ip           10.55.34.85
	option src_dip          63.240.161.99
	option dest_port        123
	option target           SNAT

When used alone, Source NAT is used to restrict a computer’s access to the internet, but allow it to access a few services by forwarding what appear to be a few local services, e.g. NTP, to the internet. While DNAT hides the local network from the internet, SNAT hides the internet from the local network.

Source NAT and destination NAT are combined and used dynamically in IP masquerading to make computers with private (192.168.x.x, etc.) IP address appear on the internet with the OpenWrt router’s public WAN ip address.

Block access to the Internet using MAC

The following rule blocks all connection attempts from the client to the Internet.

config rule
	option src              lan
	option dest             wan
	option src_mac          00:00:00:00:00:00
	option target           REJECT

Block access to the Internet for specific IP on certain times

The following rule blocks all connection attempts to the internet from 192.168.1.27 on weekdays between 21:00pm and 09:00am (times are specified in UTC unless the --kerneltz switch is used).

The package iptables-mod-ipopt must be installed to provide xt_time.
config rule
	option src              lan
	option dest             wan
	option src_ip           192.168.1.27
	option proto            all
	option start_time       21:00
	option stop_time        09:00
	option weekdays         'mon tue wed thu fri'
	option target           REJECT

Restricted forwarding rule

The example below creates a forward rule rejecting traffic from lan to wan on the ports 1000-1100.

config rule
	option src              lan
	option dest             wan
	option dest_port        1000-1100
	option proto            tcpudp
	option target           REJECT

Simple output rule

The example below creates an output rule which prevents the router from pinging the address 8.8.8.8.

config rule
	option dest             wan
	option dest_ip          8.8.8.8
	option proto            icmp
	option target           REJECT

Transparent proxy rule (same host)

The rule below redirects all outgoing HTTP traffic from lan through a proxy server listening at port 3128 on the router itself.

config redirect
	option src              lan
	option proto            tcp
	option src_dport        80
	option dest_port        3128
	option dest_ip          192.168.1.1

Transparent proxy rule (external)

The following rule redirects all outgoing HTTP traffic from lan through an external proxy at 192.168.1.100 listening on port 3128. It assumes the lan address to be 192.168.1.1 - this is needed to masquerade redirected traffic towards the proxy.

config redirect
	option src              lan
	option proto            tcp
	option src_ip           !192.168.1.100
	option src_dport        80
	option dest_ip          192.168.1.100
	option dest_port        3128
	option target           DNAT

config redirect
	option dest             lan
	option proto            tcp
	option src_dip          192.168.1.1
	option dest_ip          192.168.1.100
	option dest_port        3128
	option target           SNAT

IPSec passthrough

This example enables proper forwarding of IPSec traffic through the wan.

# AH protocol
config rule
	option src              wan
	option dest             lan
	option proto            ah
	option target           ACCEPT

# ESP protocol
config rule
	option src              wan
	option dest             lan
	option proto            esp
	option target           ACCEPT

For some configurations you also have to open port 500/UDP.

# ISAKMP protocol
config rule
	option src              wan
	option dest             lan
	option proto            udp
	option src_port         500
	option dest_port        500
	option target           ACCEPT

Zone declaration for semi non-UCI interfaces, manually listed in the network config, and forwardings

Scenario: having one or more vpn tunnels using openvpn, with the need of defining a zone to forward the traffic between the vpn interfaces and the lan.

First list the interfaces in /etc/config/network, for example in the following way: (be careful on the limits of interface naming in terms of name length.

config interface 'tun0'
	option ifname 'tun0'
	option proto 'none'

config interface 'tun1'
	option ifname 'tun1'
	option proto 'none'

Then create the zone in /etc/config/firewall, for example one zone for all the vpn interfaces.

config zone
	option name             vpn_tunnel
	list   network          'tun0'
	list   network          'tun1'
	option input            ACCEPT
#the traffic towards the router from the interface will be accepted
#(as for the lan communications)
	option output           ACCEPT
#the traffic from the router to the interface will be accepted
	option forward          REJECT
#traffic from this zone to other zones is normally rejected

Then we want to communicate with the "lan" zone, therefore we need forwardings in both ways (from lan to wan and viceversa)

config forwarding
	option src              lan
	option dest             vpn_tunnel
#if a packet from lan wants to go to the vpn_tunnel zone
#let it pass

config forwarding
	option src              vpn_tunnel
	option dest             lan
#if a packet from vpn_tunnel wants to go to the lan zone
#let it pass

This will create a lot of "automatic" iptables rules (because automatic scripting is not as efficient as raw iptable commands in /etc/firewall.user) but those rules will be more clear in the luci webinterface and also more readable for less expert users.

In general remember that forwardings are relying how routing rules are defined, and afterwards which zones are defined on which interfaces.

Zone declaration for non-UCI interfaces

This example declares a zone which maches any Linux network device whose name begins with "ppp".

config zone
	option name             example
	option input            ACCEPT
	option output           ACCEPT
	option forward          REJECT
	option device           'ppp+'

Zone declaration for a specific subnet and protocol

This example declares a zone which maches any TCP stream in the 10.21.0.0/16 subnet.

config zone
	option name             example
	option input            ACCEPT
	option output           ACCEPT
	option forward          REJECT
	option subnet           '10.21.0.0/16'
	option extra            '-p tcp'

Zone declaration for a specific protocol and port

This example declares a zone which maches any TCP stream from and to port 22.

config zone
	option name             example
	option input            ACCEPT
	option output           ACCEPT
	option forward          REJECT
	option extra_src        '-p tcp --sport 22'
	option extra_dest       '-p tcp --dport 22'

Manual iptables rules

Traditional iptables rules, in the standard iptables unix command form, can be specified in an external file and included in the firewall config file. It is possible to include multiple files this way.

config include
	option path /etc/firewall.user

config include
	option path /etc/firewall.vpn

The syntax for the includes is Linux standard, and therefore different from UCI’s.

Firewall management

After a configuration change, firewall rules are rebuilt by executing /etc/init.d/firewall restart; calling /etc/init.d/firewall stop will flush all rules and set the policies to ACCEPT on all standard chains. To manually start the firewall, call /etc/init.d/firewall start.

The firewall can be permananently disabled by executing /etc/init.d/firewall disable. Note that disable does not flush the rules, so it might be required to issue a stop before. Use enable to activate the firewall again.

Temporarily disable firewall

Run /etc/init.d/firewall stop to flush all rules and set the policies to ACCEPT. To restart the firewall, run /etc/init.d/firewall start.

Hotplug hooks

In addition to includes it is possible to let the firewall execute hotplug handlers when interfaces are added to a zone or removed from it. This is useful to create rules for interfaces with dynamic ip configurations (dhcp, pppoe) on the fly.

Each time an interface is added or removed from a zone, all scripts in the /etc/hotplug.d/firewall/ directory are executed. Scripts must be named in the form NN-name with NN being a numeric index between 00 and 99. The name can be freely choosen.

Once a handler script is invoked, the information about the event is passed through the environment. The table below lists defined variables and their meaning.

Variable Description

ACTION

Type of the event: add if an interface was added, remove if it was removed

ZONE

Name of the firewall zone the interface was added to

INTERFACE

OpenWrt name of the interface, for example "lan" or "wan" - corresponds to the interfaces defined in /etc/config/network

DEVICE

The physical interface involved, for example "eth0" or "ppp0"

Implications of DROP vs. REJECT

The decision whether to drop or to reject traffic should be done on a case-by-case basis. Many people see dropping traffic as a security advantage over rejecting it because it exposes less information to a potential attacker. While dropping slightly increases security, it can also complicate the debugging of network issues or cause unwanted side-effects on client programs.

If traffic is rejected, the router will respond with an ICMP error message ("destination port unreachable") causing the connection attempt to fail immediately. This also means that for each connection attempt a certain amount of response traffic is generated. This can cause harm if the firewall is "attacked" with many simultaneous connection attempts; the resulting "backfire" of ICMP responses can clog up all available bandwidth and make the connection unusable (DoS).

When connection attempts are dropped the client is not aware of the blocking and will continue to re-transmit its packets until the connection eventually times out. Depending on the way the client software is implemented, this could result in frozen or hanging programs that need to wait until a timeout occurs before they’re able to continue.

Also there is an interesting article which that claims dropping connections doesnt make you any safer - Drop versus Reject

DROP

  • less information is exposed

  • less attack surface

  • client software may not cope well with it (hangs until connection times out)

  • may complicate network debugging (where was traffic dropped and why)

REJECT

  • may expose information (like the ip at which traffic was actually blocked)

  • client software can recover faster from rejected connection attempts

  • network debugging easier (routing and firewall issues clearly distinguishable)

Notes on connection tracking

NOTRACK

By default, the firewall will disable connection tracking for a zone if no masquerading is enabled. This is achieved by generating NOTRACK firewall rules matching all traffic passing via interfaces referenced by the firewall zone. The purpose of NOTRACK is to speed up routing and save memory by circumventing resource intensive connection tracking in cases where it is not needed. You can check if connection tracking is disabled by issuing iptables -t raw -vnL, it will list all rules, check for NOTRACK target.

NOTRACK will render certain ipables extensions unusable, for example the MASQUERADE target or the state match will not work!

If connection tracking is required, for example by custom rules in /etc/firewall.user, the conntrack option must be enabled in the corresponding zone to disable NOTRACK. It should appear as option 'conntrack 1 ' in the right zone in /etc/config/firewall. For further information see http://security.maruhn.com/iptables-tutorial/x4772.html .

Debug generated rule set

It is possible to observe the iptables commands generated by the firewall program, this is useful to track down iptables errors during firewall restarts or to verify the outcome of certain uci rules.

You can enable debug mode using the -d switch:

# fw3 -d reload 2>/tmp/iptables.log

Furthermore it is also possible to print the to-be generated ruleset using the print command in conjunction with the -4 and -6 switches:

# fw3 -4 print > /tmp/ipv4.rules
# fw3 -6 print > /tmp/ipv6.rules

Packet flow

INPUT (destined to router)

Table Chain Type Description

raw

PREROUTING

system

:::

notrack

internal

Internal chain for NOTRACK rules

mangle

PREROUTING

system

:::

fwmark

internal

Internal chain for MARK rules

nat

PREROUTING

system

:::

delegate_prerouting

internal

Internal chain to hold toplevel prerouting rules, dispatches traffic to the corresponding zonenameprerouting chains

:::

prerouting_rule

user

Container chain for custom user prerouting rules (firewall.user)

:::

zonenameprerouting

internal

Per-zone container chains for DNAT (port forwarding) rules

:::

preroutingnamerule

user

Per-zone container chains for custom user prerouting rules (firewall.user)

mangle

INPUT

system

filter

INPUT

system

:::

delegate_input

internal

Internal chain to hold toplevel input rules, dispatches traffic to the corresponding zonenameinput chains

:::

input_rule

user

Container chain for custom user input rules (firewall.user)

:::

syn_flood

internal

Internal chain to match and drop syn flood attempts

:::

zonenameinput

internal

Per-zone container chains for input rules

:::

inputnamerule

user

Per-zone container chains for custom user input rules (firewall.user)

OUTPUT (originating from router)

Table Chain Type Description

raw

OUTPUT

system

mangle

OUTPUT

system

nat

OUTPUT

system

filter

OUTPUT

system

:::

delegate_output

internal

Internal chain to hold toplevel output rules, dispatches traffic to the corresponding zonenameoutput chains

:::

output_rule

user

Container chain for custom user output rules (firewall.user)

:::

zonenameoutput

internal

Per-zone container chains for output rules

:::

outputnamerule

user

Per-zone container chains for custom user output rules (firewall.user)

mangle

POSTROUTING

system

nat

POSTROUTING

system

:::

delegate_postrouting

internal

Internal chain to hold toplevel postrouting rules, dispatches traffic to the corresponding zonenamepostrouting chains

:::

postrouting_rule

user

Container chain for custom user postrouting rules (firewall.user)

:::

zonenamepostrouting

internal

Per-zone container chains for postrouting rules (masq, snat)

:::

postroutingnamerule

user

Per-zone container chains for custom user postrouting rules (firewall.user)

FORWARD (relayed through router)

Table Chain Type Description

raw

PREROUTING

system

:::

notrack

internal

Internal chain for NOTRACK rules

mangle

PREROUTING

system

:::

fwmark

internal

Internal chain for MARK rules

nat

PREROUTING

system

:::

delegate_prerouting

internal

Internal chain to hold toplevel prerouting rules, dispatches traffic to the corresponding zonenameprerouting chains

:::

prerouting_rule

user

Container chain for custom user prerouting rules (firewall.user)

:::

zonenameprerouting

internal

Per-zone container chains for DNAT (port forwarding) rules

:::

preroutingnamerule

user

Per-zone container chains for custom user prerouting rules (firewall.user)

mangle

FORWARD

system

:::

mssfix

internal

Internal chain to hold for TCPMSS rules (mtu_fix)

filter

FORWARD

system

:::

delegate_forward

internal

Internal chain to hold toplevel forward rules, dispatches traffic to the corresponding zonenameforward chains

:::

forwarding_rule

user

Container chain for custom user forward rules (firewall.user)

:::

zonenameforward

internal

Per-zone container chains for output rules

:::

forwardingnamerule

user

Per-zone container chains for custom user forward rules (firewall.user)

mangle

POSTROUTING

system

nat

POSTROUTING

system

:::

delegate_postrouting

internal

Internal chain to hold toplevel postrouting rules, dispatches traffic to the corresponding zonenamepostrouting chains

:::

postrouting_rule

user

Container chain for custom user postrouting rules (firewall.user)

:::

zonenamepostrouting

internal

Per-zone container chains for postrouting rules (masq, snat)

:::

postroutingnamerule

user

Per-zone container chains for custom user postrouting rules (firewall.user)