Firewall configuration
The firewall configuration located in /etc/config/firewall.
Requirements
firewalland its dependencies (pre-installed)iptables(pre-installed)iptables-mod-conntrack(pre-installed)iptables-mod-nat(pre-installed)iptables-mod-?(optional), see netfilter.
- The whole UCI firewall is not required. It exists to make your life simpler. This wiki page is being written and kept up-to-date for you, to help you configure the UCI firewall as quickly and as easily as possible. We refer to it throughout the wiki.
- There is no LuCI-firewall, it is simply a module to configure
/etc/config/firewallfrom the WebUI. - the UCI firewall is a set of scripts, it is all based on netfilter. In case questions pop up, please look it up.
- You can finds the firewall package here:
firewall. In case questions pop up, please look it up.
The UCI firewall configuration consists of several zones covering one ore more interfaces. Allowed traffic flow between the zones is controlled by forwardings. Each zone may include multiple rules and redirects.
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 |
|---|---|---|---|---|
syn_flood | boolean | no | 1 | Enable SYN flood protection |
drop_invalid | boolean | no | 1 | Drop packets not matching any active connection |
disable_ipv6 | boolean | no | 0 | Disables IPv6 firewall rules if set to 1 (Firewall v2 and later) |
input | string | no | DROP | Default policy (ACCEPT, REJECT, DROP) for the INPUT chain |
forward | string | no | DROP | Default policy (ACCEPT, REJECT, DROP) for the FORWARD chain |
output | string | no | DROP | Default policy (ACCEPT, REJECT, DROP) for the OUTPUT chain |
Zones
A zone section groups one 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.
The options below are defined within zone sections:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
name | zone name | yes | (none) | Unique zone name |
network | list | no | (none) | List of interfaces attached to this zone, if ommitted, the value of name is used by default |
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 (see Note on connection tracking) |
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. |
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 |
mtu_fix | | | 0 | zone sections in 8.09.2+) |
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.
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. |
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. |
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 | Disables NAT reflection for this redirect if set to 0 - 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. Example 3/hour. |
limit_burst | integer | no | 5 | Maximum initial number of packets to match; this number gets recharged by one every time the limit specified above is not reached, up to this number. |
extra | string | no | (none) | Extra arguments to pass to iptables, this is mainly useful to specify additional match options, like -m policy --dir in for IPsec. |
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. Like redirects the rules are tied to the given source zone and match incoming traffic occuring there.
Valid options for this section are:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
src | zone name | yes | (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 originating from the given source port or port range on the client host if tcp or udp is specified as protocol |
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. |
dest | zone name | no | (none) | Specifies the traffic destination zone, must refer to one of the defined zone names. If specified, the rule applies to forwarded traffic else it is treated as input rule. |
dest_ip | ip address | no | (none) | Match incoming traffic directed to the specified destination ip address |
dest_port | port or range | no | (none) | Match incoming traffic directed at the given destination port or port range on this host if tcp or udp is specified as protocol |
target | string | yes | DROP | Firewall action (ACCEPT, REJECT, DROP) for matched traffic |
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. Example 3/hour. |
limit_burst | integer | no | 5 | Maximum initial number of packets to match; this number gets recharged by one every time the limit specified above is not reached, up to this number. |
extra | string | no | (none) | Extra arguments to pass to iptables, this is mainly useful to specify additional match options, like -m policy --dir in for IPsec. |
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 |
|---|---|---|---|---|
path | file name | yes | /etc/firewall.user | Specifies a shell script to execute on boot or firewall restarts |
Included scripts may contain arbitary commands, for example advanced iptables rules or tc commands required for traffic shaping.
When writing custom iptables rules remember to use -I (insert) instead of -A (append) to ensure that the created rules appear before the generic ones.
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).
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.
Forwarding ports (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_ip 192.168.1.10
This other example forwards one arbitrary port that you define to an box running ssh beind openwer firewall in a more secure manner because it is not using default port 22.
config 'redirect'
option 'name' 'ssh'
option 'src' 'wan'
option 'proto' 'tcpudp'
option 'src_dport' '5555'
option 'dest_ip' '192.168.1.100'
option 'dest_port' '22'
option 'target' 'DNAT'
option 'dest' 'lan'
Source NAT (SNAT)
Source NAT changes an outgoing packet outgoing packet destined for the system so that is looks as though the 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 a it to access a few services my manually 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 to appear on the internet with the system's public WAN ip address.
True destination port forwarding
Most users won't want this. It's usage is similar to SNAT, but as the the destination IP address isn't changed, machines on the destination network need to be aware that they'll receive and answer requests from a public IP address that isn't necessarily theirs. Port forwarding in this fashion is typically used for load balancing.
config redirect
option src wan
option src_dport 80
option dest lan
option dest_port 80
option proto tcp
Block access to a specific host
The following rule blocks all connection attempts to the specified host address.
config rule
option src lan
option dest wan
option dest_ip 123.45.67.89
option target REJECT
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.
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 extra '-m time --weekdays Mon,Tue,Wed,Thu,Fri --timestart 21:00 --timestop 09:00'
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
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
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 OpenWrt 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
Simple DMZ rule
The following rule redirects all WAN ports for all protocols to the internal host 192.168.1.2.
config redirect option src wan option proto all option dest_ip 192.168.1.2
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
Forwarding IPv6 tunnel traffic
This example is for IPv6 tunnels only, and does not apply to native dual-stack interfaces.
This example only applies to the firewall v2 package and later (only in Trunk, not yet in Backfire).
|
From my experience all you need to do is just add the interface name of your ipv6 tunnel to the wan zone of your firewall. This worked for me Remove the information below if this is the correct way to proceed. |
| Caveat: The above will only work if the tunnel is bringing IPv6 connectivity to the router itself. If you use the tunnel to route a prefix into your lan as well, you will additionally need to allow Inter-Zone Forwarding from wan to lan (not enabled by default). Creating a separate firewall zone (as described below) is a cleaner solution, though. |
IPv6 packets are by default not forwarded from lan to your wan6 interface and vice versa. Make sure to add net.ipv6.conf.all.forwarding=1 in /etc/sysctl.conf to enable it permanently. Assuming your tunnel interface is called henet, add the following sections to /etc/config/firewall to create a new zone wan6, covering henet and allowing forwarding betweeen wan6 and lan in both directions:
config zone option name wan6 option network henet option family ipv6 option input ACCEPT option output ACCEPT option forward REJECT config forwarding option dest lan option src wan6 config forwarding option dest wan6 option src lan
The family option ensures that the zone and all associated entries (rule, forwarding and redirect sections) are only added to ip6tables but not iptables.
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 that 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 form UCI's and its documentation can be found in netfilter.
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.
Hotplug hooks (8.09.2+)
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 informations about the event are 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 frewall 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 hypothetical 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 actually harm if the firewall is "attacked" with many simultanous connection attempts, the resulting "backfire" of icmp responses can clog up all available upload and make the connection unusable (DoS).
When connection attempts are droppped 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.
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)
Note 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 .
How to delete a rule
If you made a mistake you can delete a rule this way.
First, issue this command to find the index of the rule:
# iptables -L -t raw --line-numbers
Now to delete, e.g. the third rule from chain OUTPUT, execute:
# iptables -t raw -D OUTPUT 3
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.
In order to see the rules as they're executed, run the fw command with the FW_TRACE
environment variable set to 1 (one):
# FW_TRACE=1 fw reload
To direct the output to a file for later inspection, use the command below:
# FW_TRACE=1 fw reload 2>/tmp/iptables.log
doc/uci/firewall.txt · Last modified: 2012/01/17 20:50 by jow