| Both sides previous revision Previous revision Next revision | Previous revision Next revisionBoth sides next revision |
| docs:guide-user:firewall:firewall_configuration [2020/09/07 16:40] – formatting optimized vgaetera | docs:guide-user:firewall:firewall_configuration [2024/08/28 10:11] – [Rules] Added some clarification hints for src and dest IP addresses and added a real world example for inter zone traffic forwarding between interfaces. flygarn12 |
|---|
| ====== Firewall configuration /etc/config/firewall ====== | ====== Firewall configuration /etc/config/firewall ====== |
| OpenWrt's firewall management application [[docs:guide-user:firewall:overview|fw3]] has three provisioning mechanisms | OpenWrt's firewall management application [[docs:guide-user:firewall:overview|firewall]] is mainly configured through ''/etc/config/firewall''. |
| | |
| Configuration files: | |
| * ''/etc/firewall.user'' | |
| * ''/etc/config/firewall'' | |
| |
| Most of the information in this wiki will focus on the configuration files and content. | Most of the information in this wiki will focus on the configuration files and content. |
| * **The main firewall config file is ''/etc/config/firewall'', and this is edited to modify the firewall settings** | * **The main firewall config file is ''/etc/config/firewall'', and this is edited to modify the firewall settings** |
| * :!: //Create a backup of the firewall config __prior__ to making changes// | * :!: //Create a backup of the firewall config __prior__ to making changes// |
| * Should changes cause a loss-of-connectivity to the router, you will need to access it in [[docs:guide-user:troubleshooting:failsafe_and_factory_reset#failsafe_mode|Failsafe Mode]] to restore the backup | * Should changes cause a loss-of-connectivity to the router, you will need to access it in [[docs:guide-user:troubleshooting:failsafe_and_factory_reset#failsafe_mode|failsafe mode]] to restore the backup |
| * Once the settings are changed, //and __after__ double checking changes//, reload the firewall via ''/etc/init.d/firewall reload'' | * Once the settings are changed, //and __after__ double checking changes//, reload the firewall via ''/etc/init.d/firewall reload'' |
| * This is a simple shell script calling ''fw3 reload'', and will print diagnostics to the console as it parses the new firewall configuration. //Check for errors!// | * This is a simple shell script calling ''fw4 reload'', and 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** | * **Any line using ''#'' in the first character is not parsed** |
| * Comments are utilized to describe, explain, or quickly comment out, a section | * Comments are utilized to describe, explain, or quickly comment out, a section |
| * **The UCI firewall configuration in ''/etc/config/firewall'' covers a reasonable subset of [[docs:guide-user:firewall:netfilter_iptables:netfilter_openwrt|NetFilter]] rules, but not all of them** | * **OpenWrt 22.03 and later** ships with **firewall4** by default, which uses nftables as a backend. It accepts the same UCI configuration syntax as fw3. |
| * To provide more functionality, an ''[[firewall_configuration#includes|include]]'' section was added to the UCI firewall config that loads a file containing native iptables directives | * **The UCI firewall configuration in ''/etc/config/firewall'' covers a reasonable subset of [[docs:guide-user:firewall:netfilter_iptables:netfilter_openwrt|NetFilter]] rules, but not all of them** |
| * //This is processed as a shell script, allowing any shell command to be added to it, but the focus is working with the netfilter subsystem by adding iptables commands// | * To provide more functionality, ''[[firewall_configuration#includes_2203_and_later_with_fw4|include]]'' mechanisms are available. |
| * See [[docs:guide-user:firewall:fw3_configurations:fw3_config_examples|fw3 Configuration Examples]] for usage | * //You can either include a shell script with nftables commands, or include nftables snippets at different locations.// |
| * **Whenever possible, use the fw3 firewall UCI config** | * See [[docs:guide-user:firewall:fw3_configurations:fw3_config_examples|Firewall examples]] for usage (might be outdated!) |
| * There are some scenarios where ''[[http://www.netfilter.org|iptables]]'' commands are required | * **Whenever possible, use the firewall UCI config ''/etc/config/firewall''** |
| | * There are some scenarios where custom ''[[http://www.netfilter.org|nftables]]'' rules are required |
| * See [[docs:guide-user:firewall:netfilter_iptables:netfilter_openwrt|Netfilter in OpenWrt]] for more information | * See [[docs:guide-user:firewall:netfilter_iptables:netfilter_openwrt|Netfilter in OpenWrt]] for more information |
| |
| ==== Web interface ==== | ==== Web interface instructions ==== |
| [[docs:guide-user:luci:start|LuCI]] is a good mechanism to view and modify the firewall configuration. | [[docs:guide-user:luci:start|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 is located under **Network -> Firewall** and maps closely to the configuration file sections. |
| * :!: LuCI will remove all comment [''#''] lines from ''/etc/config/firewall''! | * :!: LuCI will remove all comment [''#''] lines from ''/etc/config/firewall''! |
| |
| ==== Command-line interface ==== | ==== Command-line instructions ==== |
| [[docs:guide-user:base-system:uci|UCI]] is a low-level abstraction to the configuration files and can be accessed remotely through [[docs:guide-quick-start:sshadministration|SSH]]. | [[docs:guide-user:base-system:uci|UCI]] is a low-level abstraction to the configuration files and can be accessed remotely through [[docs:guide-quick-start:sshadministration|SSH]]. |
| |
| |
| [[docs:guide-user:base-system:uci|UCI]] is useful to view the firewall configuration, but not to do any meaningful modifications for the following reasons: | [[docs:guide-user:base-system:uci|UCI]] is useful to view the firewall configuration, but not to do any meaningful modifications for the following reasons: |
| * Essential prior knowledge of where a firewall rule needs to go into the rule array in order to make it work (similar to ''iptables -I'') | * Essential prior knowledge of where a firewall rule needs to go into the rule array in order to make it work. |
| * ''uci'' does not recognize content within the ''/etc/firewall.user'' script. | * ''uci'' does not recognize content within the ''/etc/firewall.user'' script. |
| * ''uci commit'' is necessary to save the changes, but still needs ''/etc/init.d/firewall reload'' to reload new tables. | * ''uci commit'' is necessary to save the changes, but still needs ''/etc/init.d/firewall reload'' to reload new tables. |
| Below is an overview of the section types that may be defined in the firewall configuration. | 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''. | * 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.// | * //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 ==== | ==== Defaults ==== |
| option custom_chains '1' | option custom_chains '1' |
| option drop_invalid '1' | option drop_invalid '1' |
| option syn_flood '1' | |
| option synflood_burst '50' | |
| option synflood_protect '1' | option synflood_protect '1' |
| | option synflood_rate '25/s' |
| | option synflood_burst '50' |
| option tcp_ecn '1' | option tcp_ecn '1' |
| option tcp_syncookies '1' | option tcp_syncookies '1' |
| | ''syn_flood'' | boolean | no | ''0'' | Enable [[wp>SYN flood]] protection (obsoleted by ''synflood_protect'' setting). | | | ''syn_flood'' | boolean | no | ''0'' | Enable [[wp>SYN flood]] protection (obsoleted by ''synflood_protect'' setting). | |
| | ''synflood_protect'' | boolean | no | ''0'' | Enable [[wp>SYN flood]] protection. | | | ''synflood_protect'' | boolean | no | ''0'' | Enable [[wp>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_rate'' | string | no | ''25/s'' | 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. | | | ''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 [[wp>SYN cookies]]. | | | ''tcp_syncookies'' | boolean | no | ''1'' | Enable the use of [[wp>SYN cookies]]. | |
| | ''tcp_ecn'' | boolean | no | ''0'' | Enable/Disable [[wp>Explicit_Congestion_Notification|Explicit Congestion Notification]]. Implemented upstream in Linux Kernel. See [[https://github.com/torvalds/linux/blob/54dee406374ce8adb352c48e175176247cb8db7c/Documentation/networking/ip-sysctl.txt|ip-sysctl.txt]]. | | | ''tcp_ecn'' | integer | no | ''0'' | ''0'' Disable, ''1'' Enable, ''2'' Enable when requested for ingress (but disable for egress) [[wp>Explicit_Congestion_Notification|Explicit Congestion Notification]]. Affects only traffic originating from the router itself. Implemented upstream in Linux Kernel. See [[https://docs.kernel.org/networking/ip-sysctl.html|kernel docs]]. | |
| | ''tcp_window_scaling'' | boolean | no | ''1'' | Enable TCP window scaling. | | | ''tcp_window_scaling'' | boolean | no | ''1'' | Enable [[wp>TCP_window_scale_option|TCP window scaling]]. | |
| | ''accept_redirects'' | boolean | no | ''0'' | Accepts redirects. Implemented upstream in Linux Kernel. See [[https://github.com/torvalds/linux/blob/54dee406374ce8adb352c48e175176247cb8db7c/Documentation/networking/ip-sysctl.txt|ip-sysctl.txt]]. | | | ''accept_redirects'' | boolean | no | ''0'' | Accepts redirects. Implemented upstream in Linux Kernel. See [[https://docs.kernel.org/networking/ip-sysctl.html|kernel docs]]. | |
| | ''accept_source_route'' | boolean | no | ''0'' | Implemented upstream in Linux Kernel. See [[https://github.com/torvalds/linux/blob/54dee406374ce8adb352c48e175176247cb8db7c/Documentation/networking/ip-sysctl.txt|ip-sysctl.txt]]. | | | ''accept_source_route'' | boolean | no | ''0'' | Implemented upstream in Linux Kernel. See [[https://docs.kernel.org/networking/ip-sysctl.html|kernel docs]]. | |
| | ''custom_chains'' | boolean | no | ''1'' | Enable generation of custom rule chain hooks for user generated rules. User rules would be typically stored in firewall.user but some packages e.g. BCP38 also make use of these hooks. | | | ''custom_chains'' | boolean | no | ''1'' | Enable generation of custom rule chain hooks for user generated rules. User rules would be typically stored in firewall.user but some packages e.g. BCP38 also make use of these hooks. | |
| | ''disable_ipv6'' | boolean | no | ''0'' | Disable IPv6 firewall rules. | | | ''disable_ipv6'' | boolean | no | ''0'' | Disable IPv6 firewall rules. (not supported by fw4) | |
| | ''flow_offloading'' | boolean | no | ''0'' | Enable software flow offloading for connections. (decrease cpu load / increase routing throughput) | | | ''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) | | | ''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 | ''0'' | Defined in [[https://lxr.openwrt.org/source/firewall3/options.h#L92|firewall3/options.h]]. Seems to determine method of packet rejection; ([[wp>TCP_reset_attack|tcp reset, or drop]], vs [[wp>Internet_Control_Message_Protocol#Destination_unreachable|ICMP Destination Unreachable, or closed]]) | | | ''tcp_reject_code'' | reject_code | no | ''0'' | Defined in [[https://lxr.openwrt.org/source/firewall3/options.h#L92|firewall3/options.h]]. Seems to determine method of packet rejection; ([[wp>TCP_reset_attack|tcp reset, or drop]], vs [[wp>Internet_Control_Message_Protocol#Destination_unreachable|ICMP Destination Unreachable, or closed]]) | |
| | ''any_reject_code'' | reject_code | no | ''1'' | Defined in [[https://lxr.openwrt.org/source/firewall3/options.h#L92|firewall3/options.h]]. Seems to determine method of packet rejection; ([[wp>TCP_reset_attack|tcp reset, or drop]], vs [[wp>Internet_Control_Message_Protocol#Destination_unreachable|ICMP Destination Unreachable, or closed]])| | | ''any_reject_code'' | reject_code | no | ''1'' | Defined in [[https://lxr.openwrt.org/source/firewall3/options.h#L92|firewall3/options.h]]. Seems to determine method of packet rejection; ([[wp>TCP_reset_attack|tcp reset, or drop]], vs [[wp>Internet_Control_Message_Protocol#Destination_unreachable|ICMP Destination Unreachable, or closed]])| |
| | ''auto-helper'' | bool | no | ''1'' | Enable Conntrack helpers | | | ''auto_helper'' | bool | no | ''1'' | Enable Conntrack helpers | |
| | | ''auto_includes'' | bool | no | ''1'' | (fw4 only, 22.03 and later) Enable automatic nftables includes under ''/usr/share/nftables.d/'' | |
| ==== Includes ==== | |
| It is possible to include custom firewall scripts by specifying one or more ''include'' sections in the firewall configuration: | |
| | |
| <code bash> | |
| config include | |
| option path '/etc/firewall.user' | |
| </code> | |
| | |
| * The ''/etc/firewall.user'' script is empty by default. | |
| | |
| === Options === | |
| ^ 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 arbitrary 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 exists in iptables, it will not be re-added. A standard iptables ''-I'' or ''-A'' will add a duplicate rule. | |
| | |
| === Example === | |
| Here is an example of ''/etc/firewall.user'' script that allows to CloudFlare.com to access HTTP 80 and HTTPS 443 ports. | |
| Use if your uhttpd is hidden behind CF proxy. | |
| | |
| <code bash> | |
| # Replace the ips-v4 with v6 if needed | |
| for ip in `wget -qO- http://www.cloudflare.com/ips-v4`; do | |
| iptables -I INPUT -p tcp -m multiport --dports http,https -s $ip -j ACCEPT | |
| done | |
| </code> | |
| | |
| **NOTE:** The example uses HTTP to get the list of IPs. | |
| Using HTTP makes us vulnerable to MITM attacks. | |
| To use the more secure HTTPS and avoid MITM risks, we need to install ''ca-certs''. | |
| | |
| ==== Redirects ==== | |
| Port forwardings (DNAT) are defined by ''redirect'' sections. | |
| //Port Redirects are also commonly known as "port forwarding" or "virtual servers".// | |
| * All //incoming// traffic on the specified //source zone// which matches the given rules will be directed to the specified internal host. | |
| * Port ranges are specified as ''start:stop'', for instance ''6666:6670'' //(similar to the iptables syntax)//. | |
| | |
| === Destination NAT === | |
| <code bash> | |
| config redirect | |
| option name 'DNAT WAN to LAN for SSH' | |
| option src 'wan' | |
| option src_dport '19900' | |
| option dest 'lan' | |
| option dest_ip '192.168.1.1' | |
| option dest_port '22' | |
| option proto 'tcp' | |
| option target 'DNAT' | |
| </code> | |
| | |
| :!: If a src_dport is not included in the config section, packets matching the other config options, //on any port//, will be forwarded to the destination port specified in that config section. | |
| This could pose a security risk to the application running on the destination port the config section opens. | |
| One way to test for this issue, is to use // [[https://www.grc.com/default.htm|Gibson Research Corporation's]] // ShieldsUP! service, and probe the desired ports on your router. | |
| The response could be //open//, //closed//, or //stealth// (drop). | |
| In cases of open or closed ports, packets are reaching a destination host, and are sending ack/reply packets back. | |
| Whereas stealthed ports drop packets; from the perspective of the probing system (Gibson Research), that system cannot definitively know if those packets may, or may not be reaching the destination host. | |
| | |
| === Source NAT === | |
| Masquerade is the most common form of SNAT, changing the source of traffic to WAN to the router's public IP. | |
| SNAT can also be done manually: | |
| | |
| <code bash> | |
| config redirect | |
| option name 'SNAT DMZ 192.168.1.250 to WAN 1.2.3.4 for ICMP' | |
| option src 'dmz' | |
| option src_ip '192.168.1.250' | |
| option src_dip '1.2.3.4' | |
| option dest 'wan' | |
| option proto 'icmp' | |
| option target 'SNAT' | |
| </code> | |
| | |
| === Options === | |
| ^ 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 | no | //tcpudp// | Match incoming traffic using the given //protocol//. Can be one (or several when using list syntax) 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 | 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 | no | //(none)// | For //DNAT//, redirect matches incoming traffic to the specified internal host. For //SNAT//, it matches traffic directed at the given address. For //DNAT//, if the ''dest_ip'' is not specified, the rule is translated in a iptables/REDIRECT rule, otherwise it is a iptables/DNAT 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 //[[#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. | | |
| | ''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 | | |
| | |
| See also: [[https://git.openwrt.org/?p=project/firewall3.git;a=blob;f=snats.c;hb=HEAD#l22]] | |
| |
| ==== Zones ==== | ==== Zones ==== |
| </code> | </code> |
| |
| * **MASQUERADE** (NAT) of outgoing traffic (WAN) is controlled on a per-zone basis on the //outgoing// interface.\\ \\ | * **MASQUERADE** (NAT) of outgoing traffic (WAN) is controlled on a per-zone basis 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. | * **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. | * **OUTPUT** rules for a zone describe what happens to traffic originating from the router itself going through an interface in that zone. |
| ^ Name ^ Type ^ Required ^ Default ^ Description ^ | ^ Name ^ Type ^ Required ^ Default ^ Description ^ |
| | ''name'' | zone name | yes | //(none)// | Unique zone name. 11 characters is the maximum working firewall zone name length. | | | ''name'' | zone name | yes | //(none)// | Unique zone name. 11 characters is the maximum working firewall zone name length. | |
| | ''network'' | list | no | //(none)// | List of //[[docs:guide-user:base-system:basic-networking#interfaces|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 [[docs:guide-user:base-system:basic#appending_or_deleting_values_on_a_list_option| list syntax]] . | | | ''network'' | list | no | //(none)// | List of //[[docs:guide-user:network:network_configuration#section_interface|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 [[docs:guide-user:base-system:basic#appending_or_deleting_values_on_a_list_option| list syntax]]. | |
| | ''masq'' | boolean | no | ''0'' | Specifies whether //outgoing// zone traffic should be masqueraded. This is typically enabled on the //wan// zone. | | | ''masq'' | boolean | no | ''0'' | Specifies whether //outgoing// zone IPv4 traffic should be masqueraded. This is typically enabled on the //wan// zone. | |
| | | ''masq6'' | boolean | no | ''0'' | Specifies whether //outgoing// zone IPv6 traffic should be masqueraded. This is typically enabled on the //wan// zone. Available with fw4. Requires ''[[docs:guide-user:network:ipv6:configuration?s=sourcefilter#protocol_dhcpv6|sourcefilter=0]]'' for DHCPv6 interfaces with missing GUA prefix. | |
| | ''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_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_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. | |
| | ''forward'' | string | no | ''DROP'' | Default policy (''ACCEPT'', ''REJECT'', ''DROP'') for //forwarded// 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. | | | ''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. | | | ''family'' | string | no | //(auto)// | Specifies the address family (''ipv4'', ''ipv6'' or ''any'') for which the rules are generated. If unspecified, matches the address family of other options in this section and defaults to ''any''. | |
| | ''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'' | int | no | ''0'' | Bit field to enable logging in the filter and/or mangle tables, bit 0 = filter, bit 1 = mangle. | |
| | ''log_limit'' | string | no | ''10/minute'' | Limits the amount of log messages per interval. | | | ''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. | | | ''device'' | list | no | //(none)// | List of L3 network interface names attached to this zone, e.g. ''tun+'' or ''ppp+'' to match any TUN or PPP interface. This is specifically suitable for undeclared interfaces which lack built-in netifd support such as OpenVPN. Otherwise ''network'' is preferable and ''device'' should be avoided. | |
| | ''subnet'' | list | no | //(none)// | List of IP subnets attached to this zone. | | | ''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, therefor direction-specific options like ''%%--dport%%'' should not be used here - in this case the ''extra_src'' and ''extra_dest'' options should be used instead. | | | <del>''extra''</del> | <del>string</del> | <del>no</del> | <del>//(none)//</del> | <del>Extra arguments passed directly to iptables. Note that these options are passed to both source and destination classification rules, therefor direction-specific options like ''%%--dport%%'' should not be used here - in this case the ''extra_src'' and ''extra_dest'' options should be used instead.</del> | |
| | ''extra_src'' | string | no | //Value of ''extra''// | Extra arguments passed directly to iptables for source classification rules. | | | <del>''extra_src''</del> | <del>string</del> | <del>no</del> | <del>//Value of ''extra''//</del> | <del>Extra arguments passed directly to iptables for source classification rules.</del> | |
| | ''extra_dest'' | string | no | //Value of ''extra''// | Extra arguments passed directly to iptables for destination classification rules. | | | <del>''extra_dest''</del> | <del>string</del> | <del>no</del> | <del>//Value of ''extra''//</del> | <del>Extra arguments passed directly to iptables for destination classification rules.</del> | |
| | ''custom_chains'' | bool | no | ''1'' | Enable generation of custom rule chain hooks for user generated rules. Has no effect if disabled (0) in the ''defaults'' section (see above). | | | ''custom_chains'' | bool | no | ''1'' | Enable generation of custom rule chain hooks for user generated rules. Has no effect if disabled (0) in the ''defaults'' section (see above). | |
| | ''enabled'' | bool | no | yes | if set to ''0'', zone is disabled | | | ''enabled'' | bool | no | yes | if set to ''0'', zone is disabled | |
| |
| ==== Forwardings ==== | ==== Forwardings ==== |
| The ''forwarding'' sections control the traffic flow between //zones//, and may enable [[wp>Path_MTU_discovery#Problems_with_PMTUD|MSS clamping]] for specific directions. | The ''forwarding'' sections control the traffic flow between //zones//. |
| |
| <code bash> | <code bash> |
| </code> | </code> |
| |
| * 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. | * 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. |
| |
| === Options === | === Options === |
| ^ Name ^ Type ^ Required ^ Default ^ Description ^ | ^ Name ^ Type ^ Required ^ Default ^ Description ^ |
| | ''name'' | forward name | no | //(none)// | Unique forwarding name. | | | ''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'. | | | ''src'' | zone name | yes | //(none)// | Specifies the traffic //source zone//. Refers 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// | | | ''dest'' | zone name | yes | //(none)// | Specifies the traffic //destination zone//. Refers to one of the defined //zone names//. | |
| | <del>''mtu_fix''</del> | <del>boolean</del> | <del>no</del> | <del>''0''</del> | <del>Enable MSS clamping for traffic flowing from the //source zone// to the //destination zone//</del> (Deprecated and moved to ''zone'' sections in 8.09.2+) | | | ''family'' | string | no | ''any'' | Specifies the address family (''ipv4'', ''ipv6'' or ''any'') for which the rules are generated. | |
| | ''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. | |
| | ''enabled'' | bool | no | yes | if set to ''0'', forward is disabled | | | ''ipset'' | string | no | //(none)// | If specified, match traffic against the given //[[docs:guide-user:firewall:firewall_configuration#ip_sets|ipset]]//. The match can be inverted by prefixing the value with an exclamation mark. | |
| |
| :!: The //iptables// rules generated for this section rely on the //state match// which needs connection tracking to work. | :!: The 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 the ''masq'' option. | * At least one of the ''src'' or ''dest'' zones needs to have //connection tracking// enabled through the ''masq'' option. |
| |
| </code> | </code> |
| |
| * In [[docs:guide-user:firewall:fw3_configurations:start|fw3]], the ''src'' and ''dest'' are tied to the target: | Below example is based on a **inter zone forward case** (where zone forward is set to reject) where you have one firewall zone called ''lan'' with two interfaces. In one interface you have a server with IP address ''172.30.100.1'' and the other interface is the default lan interface with ''192.168.1.0/24'' IP range. This configuration case will allow IPv4 ''tcp'' traffic from all IP addresses in the default lan interface to specifically connect only to the server IP address and to the server port ''22''. |
| * If ''src'' and ''dest'' are given, the rule matches //forwarded// traffic | |
| * If only ''src'' is given, the rule matches //incoming// traffic | <code bash> |
| * If only ''dest'' is given, the rule matches //outgoing// traffic | config rule |
| * If neither ''src'' nor ''dest'' are given, the rule defaults to an //outgoing// traffic rule\\ \\ | option name 'forward ssh to server' |
| * Port ranges are specified as ''start:stop'', for instance ''6666:6670'' //(similar to the iptables syntax)//. | option family 'ipv4' |
| | option src 'lan' |
| | option src_ip '192.168.1.0/24' |
| | option dest 'lan' |
| | option dest_ip '172.30.100.1' |
| | option proto 'tcp' |
| | option dest_port '22' |
| | option target 'ACCEPT' |
| | |
| | </code> |
| | |
| | * In OpenWrt firewall, 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 |
| | * IP address for ''src_ip'' and ''dest_ip'' can be a specific IP address or use CIDR notations to define a complete interface group of IP addresses as a source or destination, for instance ''192.168.1.0/24''. |
| | * Port ranges are specified as ''start-stop'', for instance ''6666-6670''. |
| |
| === Options === | === Options === |
| ^ Name ^ Type ^ Required ^ Default ^ Description ^ | ^ Name ^ Type ^ Required ^ Default ^ Description ^ |
| | ''name'' | string | no | //(none)// | Name of rule | | | ''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'' | zone name | no | //(none)// | Specifies the traffic //source zone//. Refers to one of the defined //zone names//, or ''*'' for any zone. If omitted, the rule applies to //output// traffic. | |
| | ''src_ip'' | ip address | no | //(none)// | Match incoming traffic from the specified //source ip address// | | | ''src_ip'' | ip address | no | //(none)// | Match incoming traffic from the specified //source IP address//, CIDR notations can be used, see note above. | |
| | ''src_mac'' | mac address | no | //(none)// | Match incoming traffic from the specified //mac 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' [[https://forum.openwrt.org/viewtopic.php?pid=287271|1]]. | | | ''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' [[https://forum.openwrt.org/viewtopic.php?pid=287271|1]]. | |
| | ''proto'' | protocol name or number | no | ''tcpudp'' | Match incoming traffic using the given //protocol//. Can be one (or several when using list syntax) 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''. | | | ''proto'' | protocol name or number | no | ''tcp udp'' | Match incoming traffic using the given //protocol//. Can be one (or several when using list syntax) of ''tcp'', ''udp'', ''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). | | | ''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'' | zone name | no | //(none)// | Specifies the traffic //destination zone//. Refers 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_ip'' | ip address | no | //(none)// | Match incoming traffic directed to the specified //destination IP address//, CIDR notations can be used, see note above. 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' [[https://forum.openwrt.org/viewtopic.php?pid=287271|1]]. | | | ''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' [[https://forum.openwrt.org/viewtopic.php?pid=287271|1]]. | |
| | ''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. You can specify the direction as 'setname src' or 'setname dest'. The default if neither src nor dest are added is to assume src | | | ''ipset'' | string | no | //(none)// | If specified, match traffic against the given //[[docs:guide-user:firewall:firewall_configuration#ip_sets|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'. The default if neither src nor dest are added is to assume src | |
| | ''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. | |
| | ''start_date'' | date (''yyyy-mm-dd'') | no | //(always)// | If specifed, only match traffic after the given date (inclusive). | | | ''start_date'' | date (''yyyy-mm-dd'') | no | //(always)// | If specifed, only match traffic after the given date (inclusive). | |
| | ''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. | | | ''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. | | | ''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 | | | ''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_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 | | | ''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. | | | ''family'' | string | no | //(auto)// | Specifies the address family (''ipv4'', ''ipv6'' or ''any'') for which the rules are generated. If unspecified, matches the address family of other options in this section and defaults to ''any''. | |
| | ''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'' | 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'' | | | ''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. | | | <del>''extra''</del> | <del>string</del> | <del>no</del> | <del>//(none)//</del> | <del>Extra arguments to pass to iptables. Useful mainly to specify additional match options, such as ''%%-m policy --dir in%%'' for IPsec.</del> | |
| | ''enabled'' | boolean | no | yes | Enable or disable rule. | | | ''enabled'' | boolean | no | yes | Enable or disable rule. | |
| | ''device'' | string | no | FIXME | FIXME | | | ''device'' | string | no | FIXME | FIXME | |
| | ''helper'' | cthelper | no | FIXME | FIXME | | | ''helper'' | cthelper | no | FIXME | FIXME | |
| |
| === ICMP Name Types === | === ICMP name types === |
| | ''address-mask-reply'' | ''host-redirect'' | ''pong'' | ''time-exceeded'' | | | ''address-mask-reply'' | ''host-redirect'' | ''pong'' | ''time-exceeded'' | |
| | ''address-mask-request'' | ''host-unknown'' | ''port-unreachable'' | ''timestamp-reply'' | | | ''address-mask-request'' | ''host-unknown'' | ''port-unreachable'' | ''timestamp-reply'' | |
| | ''host-prohibited'' | ''ping'' | ''source-route-failed'' | ''ttl-zero-during-transit'' | | | ''host-prohibited'' | ''ping'' | ''source-route-failed'' | ''ttl-zero-during-transit'' | |
| |
| ===== Routing ===== | ==== Redirects ==== |
| ==== IP sets ==== | Port forwardings (DNAT) are defined by ''redirect'' sections. |
| fw3 supports referencing or creating [[http://ipset.netfilter.org/|ipsets]] to simplify matching of large address or port lists without the need for creating one rule per item to match. | //Port Redirects are also commonly known as "port forwarding" or "virtual servers".// |
| * :!: This needs the ''kmod-ipt-ipset'' kernel module installed. | * All //incoming// traffic on the specified //source zone// which matches the given rules will be directed to the specified internal host. |
| | * Port ranges are specified as ''start-stop'', for instance ''6666-6670''. |
| | |
| | === Destination NAT === |
| | See also: [[docs:guide-user:firewall:fw3_configurations:fw3_ipv6_examples#ipv6_port_forwarding|IPv6 port forwarding]] |
| | |
| | <code bash> |
| | config redirect |
| | option name 'DNAT WAN to LAN for SSH' |
| | option src 'wan' |
| | option src_dport '19900' |
| | option dest 'lan' |
| | option dest_ip '192.168.1.1' |
| | option dest_port '22' |
| | option proto 'tcp' |
| | option target 'DNAT' |
| | </code> |
| | |
| | :!: If a ''src_dport'' is not included in the config section, packets matching the other config options, //on any port//, will be forwarded to the destination port specified in that config section. |
| | This could pose a security risk to the application running on the destination port the config section opens. |
| | One way to test for this issue, is to use // [[https://www.grc.com/default.htm|Gibson Research Corporation's]] // ShieldsUP! service, and probe the desired ports on your router. |
| | The response could be //open//, //closed//, or //stealth// (drop). |
| | In cases of open or closed ports, packets are reaching a destination host, and are sending ack/reply packets back. |
| | Whereas stealthed ports drop packets; from the perspective of the probing system (Gibson Research), that system cannot definitively know if those packets may, or may not be reaching the destination host. |
| | |
| | === Source NAT === |
| | Masquerade is the most common form of SNAT, changing the source of traffic to WAN to the router's public IP. |
| | SNAT can also be done manually: |
| | |
| | <code bash> |
| | config redirect |
| | option name 'SNAT DMZ 192.168.1.250 to WAN 1.2.3.4 for ICMP' |
| | option src 'dmz' |
| | option src_ip '192.168.1.250' |
| | option src_dip '1.2.3.4' |
| | option dest 'wan' |
| | option proto 'icmp' |
| | option target 'SNAT' |
| | </code> |
| |
| === Options === | === Options === |
| | See also: [[https://git.openwrt.org/?p=project/firewall3.git;a=blob;f=snats.c;hb=HEAD#l22|List of SNAT options @ OpenWrt SNAPSHOT]] |
| | |
| | ^ 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//. Refers 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 | no | //tcp udp// | Match incoming traffic using the given //protocol//. Can be one (or several when using list syntax) of ''tcp'', ''udp'', ''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 | yes for ''SNAT'' target | //(none)// | Specifies the traffic //destination zone//. Refers to one of the defined //zone names//. Irrelevant for //DNAT// target. | |
| | | ''dest_ip'' | ip address | no | //(none)// | For //DNAT//, redirect matches incoming traffic to the specified internal host. For //SNAT//, it matches traffic directed at the given address. For //DNAT//, if the ''dest_ip'' is not specified, the rule is translated in a redirect rule, otherwise it is a //DNAT// 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 //[[docs:guide-user:firewall:firewall_configuration#ip_sets|ipset]]//. The match can be inverted by prefixing the value with an exclamation mark. Unsupported in firewall4. | |
| | | ''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 | //(auto)// | Specifies the address family (''ipv4'', ''ipv6'' or ''any'') for which the rules are generated. If unspecified, matches the address family of other options in this section and defaults to ''ipv4''. | |
| | | ''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. | |
| | | ''reflection_zone'' | list of zone names | no | //(none)// | List of zones for which reflection should be enabled. 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''. | |
| | | <del>''extra''</del> | <del>string</del> | <del>no</del> | <del>//(none)//</del> | <del>Extra arguments to pass to iptables. Useful mainly to specify additional match options, such as ''%%-m policy --dir in%%'' for IPsec.</del> | |
| | | ''enabled'' | string | no | ''1'' or ''yes'' | Enable the redirect rule or not. | |
| | | ''helper'' | cthelper | no | FIXME | FIXME | |
| | |
| | ==== IP sets ==== |
| | See also: [[docs:guide-user:firewall:fw3_configurations:fw3_config_ipset|IP set examples]] |
| | |
| | fw4 supports referencing or creating [[https://wiki.nftables.org/wiki-nftables/index.php/Sets|IP sets]] to simplify matching of large address or port lists without the need for creating one rule per item to match. fw4 [[commit>?p=project/firewall4.git;a=blob;f=root/usr/share/ucode/fw4.uc;h=47e86cd7dd2a0f87caeccde51710330199905fd3;hb=47e86cd7dd2a0f87caeccde51710330199905fd3#l3189|supports fewer options]] (see [[:docs:guide-user:firewall:firewall_configuration#options_fw4|below]]). |
| | |
| | === Options (fw3) === |
| ^ Name ^ Type ^ Required ^ Default ^ Description ^ | ^ Name ^ Type ^ Required ^ Default ^ Description ^ |
| | ''enabled'' | boolean | no | ''1'' | Allows to disable the declaration of the ipset without the need to delete the section. | | | ''enabled'' | boolean | no | ''1'' | Allows to disable the declaration of 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. | | | ''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. | | | ''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''. | | | ''family'' | string | no | ''ipv4'' | Specifies the address family (''ipv4'' or ''ipv6'') for which the IP set is created. 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''). | | | ''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''). :!: This is only required by fw3 and must be removed from the fw4 configuration. | |
| | ''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").| | | ''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 [[http://ipset.netfilter.org/ipset.man.html|ipset(8)]]. Only applicable to the ''hash'' storage type. | | | ''iprange'' | IP range | yes for storage type ''bitmap'' with datatype ''ip'' | //(none)// | Specifies the IP range to cover, see [[http://ipset.netfilter.org/ipset.man.html|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 [[http://ipset.netfilter.org/ipset.man.html|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 [[http://ipset.netfilter.org/ipset.man.html|ipset(8)]]. Only applicable to the ''hash'' storage type. | |
| | ''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. | | | ''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. | | | ''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. | | | ''timeout'' | integer | no | ''0'' | Specifies the default timeout for entries added to the set. A value of ''0'' means enabling the timeout capability flag on a set, but do not put the timeout to entries. | |
| | ''entry'' | setentry | no | FIXME | FIXME | | | ''entry'' | setentry | no | //(none)// | The IP address, CIDR, or MAC. Each list entry is a single CIDR, or IP etc when not using ranges or masks etc above. | |
| | ''loadfile'' | string | no | FIXME | FIXME | | | ''loadfile'' | string | no | //(none)// | A path URL on the openwrt filesystem to a file containing a list of CIDRs. | |
| |
| === Storage / Match Options === | === Options (fw4) === |
| | ^ Name ^ Type ^ Required ^ Default ^ Description ^ |
| | | ''enabled'' | boolean | no | ''1'' | Allows to disable the declaration of the ipset without the need to delete the section. | |
| | | ''comment'' | boolean | no | //(none)// | Seems like a bug: should be a string for user defined comment. | |
| | | ''name'' | string | yes | //(none)// | Specifies the firewall internal name of the ipset which is used to reference the set in rules or redirects. | |
| | | ''family'' | string | no | ''ipv4'' | Specifies the address family (''ipv4'' or ''ipv6'') for which the IP set is created. | |
| | | ''match'' | list of ipsettypes | 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. | |
| | | ''maxelem'' | integer | no | ''65536'' | Limits the number of items that can be added to the set. | |
| | | ''timeout'' | integer | no | ''0'' | Specifies the default timeout for entries added to the set. A value of ''0'' means enabling the timeout capability flag on a set, but do not put the timeout to entries. | |
| | | ''entry'' | List of ''entry'' | no | | The IP address, CIDR, or MAC. Each list entry is a single CIDR, or IP etc. | |
| | | ''loadfile'' | string | no | //(none)// | A path URL on the openwrt filesystem to a file containing a list of CIDRs. | |
| | |
| | === IP set types === |
| | ''prefix_suffix'' |
| | |
| | ^ Prefix, aka direction ^ Suffix aka datatype ^ Notes ^ |
| | | src_* | | Source matching of ''suffix'' | |
| | | dest_* | | Destination matching of ''suffix'' | |
| | | | _ip | IP addresses | |
| | | | _port | TCP/UDP ports | |
| | | | _mac | MAC addresses | |
| | | | _net | Subnets | |
| | | | _set | Unsupported in firewall4 | |
| | |
| | === Storage / Match options === |
| The order of datatype matches is significant | The order of datatype matches is significant |
| ^ Family ^ Storage ^ Match ^ Notes ^ | ^ Family ^ Storage ^ Match ^ Notes ^ |
| | - | ''list'' | ''set'' | Meta type to create a set-of-sets | | | - | ''list'' | ''set'' | Meta type to create a set-of-sets | |
| |
| ==== IPv6 ==== | ==== Includes (22.03 and later with fw4) ==== |
| As described above, the option ''family'' is used for distinguishing between IPv4, IPv6 and both protocols. | ''fw4'' has several ways to include custom firewall rules. |
| However the family is inferred automatically if IPv6 addresses are used: | In all cases, the custom rules need to be written in nftables-style. |
| | |
| | === Config include section with nftables snippets === |
| | One way is to include ''nftables'' snippets. |
| | There are several possible positions in the nftables structure. |
| | |
| | For example, to add custom logging to the ''input_wan'' chain: |
| |
| <code bash> | <code bash> |
| config rule | # /etc/config/firewall |
| option src 'wan' | config include |
| option src_ip 'fdca:f00:ba3::/64' | option type 'nftables' |
| option target 'ACCEPT' | option path '/etc/my_custom_firewall_rule.nft' |
| | option position 'chain-pre' |
| | option chain 'input_wan' |
| | |
| | # /etc/my_custom_firewall_rule.nft |
| | tcp dport 0-1023 log prefix "Inbound WAN connection attempt to low TCP port: " |
| </code> | </code> |
| |
| Similar, such a rule is detected as IPv4 only: | To add one or more custom chains: |
| |
| <code bash> | <code bash> |
| config rule | config include |
| option src 'wan' | option type 'nftables' |
| option dest_ip '88.77.66.55' | option path '/etc/my_custom_firewall_chain.nft' |
| option target 'REJECT' | option position 'table-post' |
| </code> | </code> |
| |
| * Rules without IP addresses are automatically added to iptables and ip6tables, //unless overridden by the family option//. | Supported options: |
| * Redirect rules (port forwards) are always IPv4 (for now) since there is [[https://bugs.openwrt.org/index.php?do=details&task_id=500|no IPv6 DNAT support]] (yet). | |
| | ^ 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, either ''script'' for compatibility with fw3 (shell script, see below) or ''nftables'' for nftables snippets | |
| | | ''path'' | file name | yes | - | Specifies the filename to include | |
| | | ''position'' | string | yes (if type is nftables) | ''table-post'' | Specifies the position at which the rules will be inserted (see below for allowed values) | |
| | | ''chain'' | string | yes (if position matches ''chain-*'') | - | Specifies the chain in which the rules will be inserted | |
| | |
| | The possible positions for nftables snippets are: |
| | |
| | ^ Position ^ Meaning ^ |
| | | ''ruleset-pre'' | At the very beginning, before the fw4 table definition | |
| | | ''ruleset-post'' | At the very end, after the fw4 table definition | |
| | | ''table-pre'' | At the beginning of the fw4 table, before any chain definition | |
| | | ''table-post'' | At the end of the fw4 table, after all chains definition | |
| | | ''chain-pre'' | At the beginning of $chain (defined in ''option chain''), before rules in this chain | |
| | | ''chain-post'' | At the end of $chain (defined in ''option chain''), after rules in this chain | |
| | |
| | Run ''fw4 print'' to understand the table / chain / rules structure. |
| | |
| | Note that ''-pre'' can also be written as ''-prepend'', and ''-post'' can also be written as ''-postpend'' or ''-append''. |
| | |
| | === Config include section with shell script === |
| | Custom rule inclusion through a shell script works similarly as fw3, but the script should use nftables. |
| | Option ''fw4_compatible'' is required when the path is ''/etc/firewall.user'' to indicate to fw4 that the script is compatible with nftables. |
| | |
| | <code bash> |
| | config include |
| | option enabled 1 |
| | option type 'script' |
| | option path '/etc/firewall.user' |
| | option fw4_compatible 1 |
| | </code> |
| | |
| | Options ''family'' and ''reload'' from fw3 are no longer supported with fw4. |
| | |
| | === Default drop-in includes === |
| | fw4 includes ''/etc/nftables.d/*.nft'' by default, at the beginning of the fw4 table (equivalent to the ''table-pre'' position) |
| | |
| | It means that custom chains can be created by adding a file ending in ''.nft'' in the ''/etc/nftables.d/'' directory. |
| | |
| | === Drop-in includes for package authors === |
| | For package authors that need custom firewall rules, it is possible to add nftables snippets in the following directories, depending on the desired position: |
| | |
| | ^ Path ^ Position ^ |
| | | ''/usr/share/nftables.d/ruleset-pre/*.nft'' | Included at the very beginning, before the fw4 table definition | |
| | | ''/usr/share/nftables.d/ruleset-post/*.nft'' | Included at the very end, after the fw4 table definition | |
| | | ''/usr/share/nftables.d/table-pre/*.nft'' | Included at the beginning of the fw4 table, before any chain definition | |
| | | ''/usr/share/nftables.d/table-post/*.nft'' | Included at the end of the fw4 table, after all chains definition | |
| | | ''/usr/share/nftables.d/chain-pre/${chain}/*.nft'' | Included at the beginning of ''${chain}'' (a valid fw4 chain name), before rules in this chain | |
| | | ''/usr/share/nftables.d/chain-post/${chain}/*.nft'' | Included at the end of ''${chain}'' (a valid fw4 chain name), after rules in this chain | |
| | |
| | Snippets need to be readable files and their name must end with ''.nft''. |
| | |
| | ==== Includes (21.02 and earlier with fw3) ==== |
| | It is possible to include custom firewall scripts by specifying one or more ''include'' sections in the firewall configuration: |
| | |
| | <code bash> |
| | config include |
| | option path '/etc/firewall.user' |
| | </code> |
| | |
| | The ''/etc/firewall.user'' script is empty by default. |
| | |
| | === Options === |
| | ^ 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 arbitrary commands, for example advanced nftables rules or tc commands required for traffic shaping. |
| |