User Tools

Site Tools


docs:guide-user:firewall:firewall_configuration

Firewall Configuration in OpenWrt

OpenWrt's firewall management application fw3 has three provisioning mechanisms

  1. UCI Configuration Files
  2. uci utility
  3. LuCI

Most of the information in this section will focus on the configuration files and content. The UCI and LuCI interfaces are user abstractions ultimately modifiying the configuration files.

Firewall Managment through UCI Configuration Files

See UCI System for an overview of the UCI configuration files. The main firewall configuration file is /etc/config/firewall. This can be editted to modify the firewall settings.

:!: save the current firewall to a backup file. If your changes cause loss-of-connectivity to the router you will need to access it in failsafe mode and restore the backup to /etc/config/firewall.

Once the settings are changed (and double-checked!), use /etc/init.d/firewall restart to reload the firewall rules. This is a simple shell script calling fw3 reload. It will print diagnostics to the console as it parses the new firewall configuration. Check for errors!

:!: Any line using # in the first character is not parsed. This is useful for comments to explain a section, or to quickly comment out a section.

The capabilities provided by netfilter are large and continually growing. The UCI firewall configuration in /etc/config/firewall covers a reasonable subset of netfilter rules but not all of them. In order to support more functionality an includes section was added to the UCI firewall configuration to load a file containing native iptable directives. It is processed as a shell script so really any shell command can be added to it but the focus is working with the netfilter subsystem by adding iptables commands. See fw3 Configuration Examples for usage.

:!: The iptables commands can be cryptic and cause unexpected results. Whenever possible, use the fw3 firewall UCI config. There are some scenarios where iptable commands are required. See Netfilter in OpenWrt for more information.

Configuration File 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. (The forwarding section is not strictly required when there are no more than two zones as the rule can then be set as the 'global default' for that zone.)

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.
forward string no REJECT Set policy for the FORWARD chain of the filter table.
output string no REJECT Set policy for the OUTPUT chain of the filter table.
drop_invalid boolean no 0 Drop invalid packets (e.g. not matching any active connection).
syn_flood boolean no 0 Enable SYN flood protection (obsoleted by synflood_protect setting).
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 FIXME
tcp_window_scaling boolean no 1 Enable TCP window scaling.
accept_redirects boolean no 0 FIXME
accept_source_route boolean no 0 FIXME
custom_chains boolean no 1 FIXME
disable_ipv6 boolean no 0 Disable IPv6 firewall rules.
flow_offloading boolean no 0 Enable software flow offloading for connections. (decrease cpu load / increase routing throughput)
flow_offloading_hw boolean no 0 Enable hardware flow offloading for connections. (depends on flow_offloading and hw capability)
tcp_reject_code reject_code no FIXME FIXME
any_reject_code reject_code no FIXME FIXME
auto-helper bool no FIXME FIXME

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 nor 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. Use list syntax .
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.
masq_allow_invalid boolean no 0 Do not add DROP INVALID rules, if masquerading is used. The DROP rules are supposed to prevent NAT leakage (see commit in firewall3).
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 The protocol family (ipv4, ipv6 or any) these iptables rules are for.
log int no 0 Bit field to enable logging in the filter and/or mangle tables, bit 0 = filter, bit 1 = mangle. (Since r6397-7cc9914aae)
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.
custom-chains bool no FIXME FIXME
enabled bool no yes if set to 0, zone is disabled
auto_helper bool no FIXME FIXME
helper cthelper no FIXME FIXME

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
name forward name no (none) Unique forwarding name.
src zone name yes (none) Specifies the traffic source zone. Must refer to one of the defined zone names. For typical port forwards this usually is 'wan'.
dest zone name yes (none) Specifies the traffic destination zone. Must refer to one of the defined zone names
mtu_fix boolean no 0 Enable MSS clamping for traffic flowing from the source zone to the destination zone (Deprecated and moved to zone sections in 8.09.2+)
family string no any Protocol family (ipv4, ipv6 or any) to generate iptables rules for.
enabled bool no yes if set to 0, forward is disabled

:!: 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 throught the masq option.

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.

In fw3, the src and dest are tied to the target:

  • 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
name string no (none) Name of rule
src zone name yes (:!: optional since Firewall v2, version 58 and above) (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' 1.
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, representing one of these protocols or a different one. 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' 1.
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. You can specify the direction as 'setname src' or 'setname dest'.
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.
device string no FIXME FIXME
direction direction no FIXME FIXME direction_out
set_helper cthelper no FIXME FIXME
helper cthelper no FIXME FIXME

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

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
name string no string Name of redirect
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. For DNAT target on Attitude Adjustment, NAT reflection works only if this is equal to lan.
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.
enabled string no 1 or yes Enable the redirect rule or not.
helper cthelper no FIXME FIXME

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.

:!: If the rule existings in iptables it wil not be re-added. A standard iptables -I or -A will add a duplicate rule.

The standard include config is this. The /etc/firewall.user is empty initially.

config include
	option path '/etc/firewall.user'

Source NAT (SNAT)

FIXME list of options but need to find how to use to document this

snats.c:23:	FW3_OPT("enabled",             bool,      snat,     enabled),
snats.c:25:	FW3_OPT("name",                string,    snat,     name),
snats.c:26:	FW3_OPT("family",              family,    snat,     family),
snats.c:28:	FW3_OPT("src",                 device,    snat,     src),
snats.c:29:	FW3_OPT("device",              string,    snat,     device),
snats.c:31:	FW3_OPT("ipset",               setmatch,  snat,     ipset),
snats.c:33:	FW3_LIST("proto",              protocol,  snat,     proto),
snats.c:35:	FW3_OPT("src_ip",              network,   snat,     ip_src),
snats.c:36:	FW3_OPT("src_port",            port,      snat,     port_src),
snats.c:38:	FW3_OPT("snat_ip",             network,   snat,     ip_snat),
snats.c:39:	FW3_OPT("snat_port",           port,      snat,     port_snat),
snats.c:41:	FW3_OPT("dest_ip",             network,   snat,     ip_dest),
snats.c:42:	FW3_OPT("dest_port",           port,      snat,     port_dest),
snats.c:44:	FW3_OPT("extra",               string,    snat,     extra),
snats.c:46:	FW3_OPT("limit",               limit,     snat,     limit),
snats.c:47:	FW3_OPT("limit_burst",         int,       snat,     limit.burst),
snats.c:49:	FW3_OPT("connlimit_ports",     bool,      snat,     connlimit_ports),
snats.c:51:	FW3_OPT("utc_time",            bool,      snat,     time.utc),
snats.c:52:	FW3_OPT("start_date",          date,      snat,     time.datestart),
snats.c:53:	FW3_OPT("stop_date",           date,      snat,     time.datestop),
snats.c:54:	FW3_OPT("start_time",          time,      snat,     time.timestart),
snats.c:55:	FW3_OPT("stop_time",           time,      snat,     time.timestop),
snats.c:56:	FW3_OPT("weekdays",            weekdays,  snat,     time.weekdays),
snats.c:57:	FW3_OPT("monthdays",           monthdays, snat,     time.monthdays),
snats.c:59:	FW3_OPT("mark",                mark,      snat,     mark),
snats.c:61:	FW3_OPT("target",              target,    snat,     target),

IP Sets

fw3 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. When using ipsets matching on multiple elements, e.g. hash:ip,port, specify the packet fields to match on in quotes or comma-separated (i.e. “match dest_ip dest_port”).
iprange IP range yes for storage type bitmap with datatype ip (none) Specifies the IP range to cover, see ipset(8). 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(8). 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(8). 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.
entry setentry no FIXME FIXME
loadfile string no FIXME FIXME

:!: This needs the kmod-ipt-ipset kernel module installed.

ipsets 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, e.g.

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

… is automatically treated as IPv6 only rule.

Similar, such a rule:

config rule
        option src wan
        option dest_ip 88.77.66.55
        option target REJECT

… is detected as IPv4 only.

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).

Firewall Management through the ''uci'' utility

The uci utility (base package) is a low-level abstraction to the configuration files. It can accessed on the device remotely through SSH.

Use uci show firewall to display the firewall content as a set of arrays mapping to the Configuration File Sections:

  • defaults
  • zone
  • forwarding
  • rule
  • redirect
  • include

For example, this rule rejects all traffic forwarded from the WAN-side to the LAN-side of the router.

firewall.@rule[22]=rule
firewall.@rule[22].src='wan'
firewall.@rule[22].dest='lan'
firewall.@rule[22].proto='tcp udp icmp'
firewall.@rule[22].target='REJECT'
firewall.@rule[22].name='REJECT-ALL-WAN-LAN'

This is presumed to create the final rules (each 'proto' creates a rule) in the WANLAN forward chain. These rules cause all packets from the WAN to be rejected, so desired traffic (e.g. icmp) needs to have rules prior to this.

The uci utility is useful to view the firewall configuration but not to do any meaningful modifications for the following reasons:

  • Essentially prior knowledge of where a firewall rule needs to go into the rule array in order make it work. If the rule above were at index=1 not much would work.
  • The utility does not recognized content of /etc/firewall.user.
  • The 'uci commit' operation is necessary to save the changes but still

needs '/etc/init.d/firewall restart' to reload new tables.

Firewall Management through LuCI

LuCI is a good mechanism to view and modify the firewall configuration. It is located under Network → Firewall and maps closely to the configuration file sections. It takes a little longer to modify the firewall configuration but has a higher level of organization than the config files.

Make changes and reload using Save & Apply button.

:!: LuCI will remove all '#' lines from '/etc/config/firewall'!

docs/guide-user/firewall/firewall_configuration.txt · Last modified: 2018/09/16 12:49 by bobafetthotmail