**''​Note No2''​**:​ Precompiled OpenWrt Images contain the OpenWrt-Firewall. The OpenWrt-Firewall already contains a couple of rules. For some obscure reasons, this pre-defined rules are not contained in the file **''/​etc/​config/​firewall''​** but are hard-coded in other files. http://​nbd.name/​gitweb.cgi?​p=firewall3.git;​a=summary Since the netfilter system is a chained processing filter, you need to know this pre-existing rules in order to successfully add own rules.

===== Overview =====

===== Overview =====

-

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 his own when needed.

+

OpenWrt relies on [[doc:​howto:​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 his 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 that are not covered by the first two. In the config file, default rules come //first// but they are the last to take effect. The iptables ([[doc:​howto:​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.

+

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 that are not covered by the first two. 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.

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.

It is not required to use UCI Firewall, but merely exists to make life easier for you. The WebUI ([[doc:​howto:​LuCI]]) may also be used to configure the UCI firewall. The firewall package may be found here: ''​[[https://​dev.openwrt.org/​browser/​trunk/​package/​network/​config/​firewall|firewall]]''​.

+

===== Sections =====

===== Sections =====

Line 52:

Line 45:

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

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

-

* OUTPUT rules for a zone describe what happens to traffic originating from the router itself.

+

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

* FORWARD rules for a zone describe what happens to traffic coming from that zone and passing to another zone.

* FORWARD rules for a zone describe what happens to traffic coming from that zone and passing to another zone.

Line 59:

Line 52:

^ Name ^ Type ^ Required ^ Default ^ Description ^

^ Name ^ Type ^ Required ^ Default ^ Description ^

| ''​name''​ | zone name | yes | //(none)// | Unique zone name |

| ''​name''​ | zone name | yes | //(none)// | Unique zone name |

-

| ''​network''​ | list | no | //(none)// | List of //​[[doc:​uci:​network#​interfaces|interfaces]]//​ attached to this zone. If omitted and neither extra* options, subnets or devices are given, the value of ''​name''​ is used by default |

+

| ''​network''​ | list | no | //(none)// | List of //​[[doc:​uci:​network#​interfaces|interfaces]]//​ attached to this zone. If omitted and neither extra* options, subnets or devices are given, the value of ''​name''​ is used by default. Use list syntax as explained in [[doc:​uci]]. ​|

| ''​subnet''​ | list | no | //(none)// | List of IP subnets attached to this zone. \\ :!: Only supported by the Firewall v2, version 58 and above |

+

| ''​subnet''​ | list | no | //(none)// | List of IP subnets attached to this zone. \\ :!: Only supported by the Firewall v2, version 58 and above, not supported by 12.09 default installation ​|

-

| ''​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. \\ :!: Only supported by the Firewall v2, version 58 and above |

+

| ''​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. \\ :!: Only supported by the Firewall v2, version 58 and above, not supported by 12.09 default installation ​|

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

//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//:​

The options below are valid for //​redirects//:​

Line 108:

Line 103:

| ''​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. |

| ''​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//​ |

| ''​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_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. |

| ''​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. |

| ''​ipset''​ | string | no | //(none)// | If specified, match traffic against the given //​[[#​ip.sets|ipset]]//​. The match can be inverted by prefixing the value with an exclamation mark |

| ''​ipset''​ | string | no | //(none)// | If specified, match traffic against the given //​[[#​ip.sets|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. |

| ''​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. |

| ''​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. |

| ''​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. |

:!: On Attitude Adjustment, for NAT reflection to work, you **must** specify ''​option dest lan''​ in the ''​redirect''​ section (even though we're using a ''​DNAT''​ target).

==== Rules ====

==== Rules ====

Line 139:

Line 137:

* If only ''​dest''​ is given, the rule matches //​outgoing//​ 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

* 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:

Valid options for this section are:

Line 153:

Line 153:

| ''​ipset''​ | string | no | //(none)// | If specified, match traffic against the given //​[[#​ip.sets|ipset]]//​. The match can be inverted by prefixing the value with an exclamation mark |

| ''​ipset''​ | string | no | //(none)// | If specified, match traffic against the given //​[[#​ip.sets|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. |

| ''​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. |

(with the exceptions mentioned above), then a device on the lan side of the

+

router 1 can communicate through the internet if it has the router 1 as

+

gateway, this because the packet flow between devices is managed by routing.

+

In our case the router 2 has no proper setup in terms of gateway,

+

as the default openwrt configuration expects that a wan connection

+

on the router 2 is provided.

+

+

Anyway suppose that on the router 1 we have the following rule:

+

<​code>​

+

config redirect

+

option target '​DNAT'​

+

option src '​wan'​

+

option dest '​lan'​

+

option proto '​tcp'​

+

option src_dip '​172.22.13.228'​

+

option src_dport '​2023'​

+

option dest_ip '​192.168.1.1'​

+

option dest_port '​23'​

+

option name '​Telnet to new Router' ​

+

</​code>​

+

This rule is redirecting the tcp packets on the port 2023 with destination the wan ip of the router 1

+

(172.22.13.228) towards the lan ip of the router 2.

+

The router 2 cannot reply to those packets because we didn't adjust its routing table,

+

that is we didn't specify that the gateway to reply to "​wan"​ sources is the router 1.

+

Indeed those redirected packets will have an source ip external from the (default) "​lan"​ zone 192.168.1.0/​24.

+

+

We can solve this activating the masquerading on the "​lan"​ zone on the router 1, in this way.

+

<​code>​

+

config zone

+

option name '​lan'​

+

option network '​lan'​

+

option input '​ACCEPT'​

+

option output '​ACCEPT'​

+

option forward '​REJECT'​

+

option masq '​1'​

+

</​code>​

+

This setup will provide the following effect (that is the effect intended by the masquerading):​ if a packet, belonging to a certain [[wp>​Virtual_circuit|connection]],​ is coming into the lan zone with a source ip belonging to another zone, keep track of the connection, taking note of the source ip of that connection, and modify the source ip with the ip of the router in the lan zone (that is: source_ip from a.b.c.d to 192.168.1.254). \\

+

Then deliver the packet to the intended destination (that is, 192.168.1.1,​ the router2). Afterwards, if a packet from 192.168.1.1 is coming back towards 192.168.1.254,​ belonging to the connection tracked before, changed back the destination ip (here is the second effect of the masquerading) with the source ip memorized before (that is, dest_ip from 192.168.1.254 to a.b.c.d ). In this way, for the point of view of the router 2, the router 2 just communicate with a device with an ip belonging to its "​lan"​ zone , and therefore the default routing is working without problem.

+

+

At least one side effect of this setup is that every device in the lan zone of the router 1 cannot see any "​wan"​ ip, and this could be not wanted for several reasons (one of which: if you setup a proper gateway, there is no need for this masquerading). But this was just a "​special case" to expose in brief how the masquerading works and how it could be applied to zones that usually don't use it. An improvement of "​masquerading only for a specific device in the zone" could be the following:

+

<​code>​

+

config zone

+

option name '​lan'​

+

option network '​lan'​

+

option input '​ACCEPT'​

+

option output '​ACCEPT'​

+

option forward '​REJECT'​

+

option masq '​1'​

+

option masq_dest '​192.168.1.1/​32'​

+

</​code>​

+

This provide the masquerading feature only if the packets are send towards the destination 192.168.1.1/​32 (this subnet should belong to the lan zone).

+

==== Port accept for IPv6 ====

+

+

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

+

+

<​code>​

+

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

+

</​code>​

+

+

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

+

+

<​code>​

+

config rule

+

option src wan

+

option proto tcp

+

option dest lan

+

option dest_port 22

+

option family ​ ipv6

+

option target ​ ACCEPT

+

</​code>​

+

+

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

for example in the following way: (be careful on the limits of interface naming in terms of name length, [[doc/​uci/​network|read more]])

+

<​code>​

+

config interface '​tun0'​

+

option ifname '​tun0'​

+

option proto '​none'​

+

+

config interface '​tun1'​

+

option ifname '​tun1'​

+

option proto '​none'​

+

</​code>​

+

+

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

+

<​code>​

+

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

+

</​code>​

+

+

Then we want to communicate with the "​lan"​ zone, therefore we need forwardings in both ways

+

(from lan to wan and viceversa)

+

<​code>​

+

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

+

</​code>​

+

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.

==== Zone declaration for non-UCI interfaces ====

==== Zone declaration for non-UCI interfaces ====

Line 481:

Line 665:

<​code>​

<​code>​

config zone

config zone

+

option name ​example

option input ACCEPT

option input ACCEPT

option output ​ ​ACCEPT

option output ​ ​ACCEPT

Line 495:

Line 680:

<​code>​

<​code>​

config zone

config zone

+

option name ​example

option input ACCEPT

option input ACCEPT

option output ​ ​ACCEPT

option output ​ ​ACCEPT

Line 511:

Line 697:

<​code>​

<​code>​

config zone

config zone

+

option name ​example

option input ACCEPT

option input ACCEPT

option output ​ ​ACCEPT

option output ​ ​ACCEPT

Line 549:

Line 736:

option dest lan

option dest lan

option src wan6

option src wan6

+

#you don't need the below as you can a firewall rule to open the port that you need

config forwarding

config forwarding

option dest wan6

option dest wan6

Line 606:

Line 793:

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.

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 - [[http://​www.chiark.greenend.org.uk/​~peterb/​network/​drop-vs-reject|Drop versus Reject]].

**DROP**

**DROP**

Line 619:

Line 808:

-

===== Note on connection tracking ​(NOTRACK) ​=====

+

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

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.

Line 627:

Line 818:

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''​.

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 .

For further information see http://​security.maruhn.com/​iptables-tutorial/​x4772.html .

+

+

==== nf_conntrack_skip_filter ====

+

+

Since [[https://​dev.openwrt.org/​changeset/​42048/​trunk/​package|r42048]],​ there is a new setting activated by default which causes the packets with the established state, completely bypass iptables filter table. This is to [[https://​dev.openwrt.org/​ticket/​17690#​comment:​6|help with network performance]] and unless you need all packets to be counted by iptables filter or have some specific rules which would apply to already established connections,​ you should leave it active. ​