Firewall in EdgeRouter
Lars Jönsson 2021-03-07
Information about the applied firewall in EdgeRouter X.
Overview
The firewall is based on iptables in Linux. The EdgeRouter X has a framework around iptables that comes from Vyatta. The framework simplifies the usage of iptables, but of course also limits what can be done. Here is some info from the VyOS Platform Blog:
In 2011 Ubiquiti Networks launched their EdgeMax line of products. EdgeOS™ is the essential part of the product line and is a fork of Vyatta Core 6.3 that exclusively runs on Cavium backed hardware produced by Ubiquiti Networks (EdgeRouter Lite, PoE, Pro) Since then they migrated to Debian 7 and replaced quagga with proprietary ZebOS™
Iptables
Iptables consists of multiple chains, like PREROUTING, FORWARD etc. Each chain has multiple tables, like nat, filter etc. The chains are connected according to the following figure:
Packets that are just forwarded from one network interface to another, goes through the chains PREROUTING, FORWARD and POSTROUTING. Packets destined to any Linux process, passes PREROUTING and INPUT. Packets originating from a Linux process passes OUTPUT and POSTROUTING.
Iptables in EdgeRouter X
The Firewall/NAT settings in the EdgeRouter GUI affects the iptables. The four tabs Port Forwarding, Firewall Polices, NAT and Firewall/NAT Groups updates different parts of the chains and tables.
The EdgeRouter add many chains that use used to simplify for the GUI to add its rules to iptables. The name of the chains include specific keywords. Most of them are self-explanatory, but some are not:
- VYATTA: Vyatta specific (Standard) rules
- UBNT: Ubiquiti specific rules
- CT: Connection Tracking
- PFOR: Port Forwarding
- FW: Forward
Each ruleset in the Firewall Polices tab will be added as its own
chain in iptables. The rulset is connected to an interface with a
specific direction. When the direction is in, an entry for that
interface will be added to the VYATTA_FW_IN_HOOK
chain, with the
ruleset chain as target. Direction out will be added to the
VYATTA_FW_OUT_HOOK
chain and local to the VYATTA_FW_LOCAL_HOOK
chain. The rulset can have multiple interfaces connected to it and
then each interface will added as its own entry in one of the "hooks"
depending on the direction.
The port forwarding rules setup in the Port Forwarding tab, will
end up in the UBNT_PFOR_DNAT_HOOK
, UBNT_PFOR_DNAT_RULES
,
UBNT_PFOR_FW_HOOK
and UBNT_PFOR_FW_RULES
chains.
Adding source and destination NAT rules in the NAT tab will end up
in some of the _SNAT_
and _DNAT_
chains.
Groups added in the Firewall/NAT Groups tab will become IP sets which are described in the IP set chapter.
Content of tables
PREROUTING chain
Raw table
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
35M 12G VYATTA_CT_PREROUTING_HOOK all -- any any anywhere anywhere
35M 12G NAT_CONNTRACK all -- any any anywhere anywhere
0 0 PFOR_CONNTRACK all -- any any anywhere anywhere
212 30735 FW_CONNTRACK all -- any any anywhere anywhere
175 21895 CT all -- any any anywhere anywhere NOTRACK
Chain VYATTA_CT_PREROUTING_HOOK (1 references)
pkts bytes target prot opt in out source destination
35M 12G RETURN all -- any any anywhere anywhere
Chain NAT_CONNTRACK (2 references)
pkts bytes target prot opt in out source destination
38M 12G ACCEPT all -- any any anywhere anywhere
Chain PFOR_CONNTRACK (2 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- any any anywhere anywhere
Chain FW_CONNTRACK (2 references)
pkts bytes target prot opt in out source destination
59 15001 ACCEPT all -- any any anywhere anywhere
Mangle table
Chain PREROUTING (policy ACCEPT 35M packets, 12G bytes)
pkts bytes target prot opt in out source destination
35M 12G VYATTA_FW_IN_HOOK all -- any any anywhere anywhere
Chain VYATTA_FW_IN_HOOK (1 references)
pkts bytes target prot opt in out source destination
NAT table
Chain PREROUTING (policy ACCEPT 77406 packets, 14M bytes)
pkts bytes target prot opt in out source destination
2743K 458M MINIUPNPD all -- any any anywhere anywhere
2743K 458M UBNT_PFOR_DNAT_HOOK all -- any any anywhere anywhere
2685K 455M VYATTA_PRE_DNAT_HOOK all -- any any anywhere anywhere
2685K 455M UBNT_SUSPEND_DNAT_HOOK all -- any any anywhere anywhere
2685K 455M VYATTA_DNAT all -- any any anywhere anywhere
Chain MINIUPNPD (1 references)
pkts bytes target prot opt in out source destination
Chain UBNT_PFOR_DNAT_HOOK (1 references)
pkts bytes target prot opt in out source destination
Chain VYATTA_PRE_DNAT_HOOK (1 references)
pkts bytes target prot opt in out source destination
2685K 455M RETURN all -- any any anywhere anywhere
Chain UBNT_SUSPEND_DNAT_HOOK (1 references)
pkts bytes target prot opt in out source destination
Chain VYATTA_DNAT (1 references)
pkts bytes target prot opt in out source destination
FORWARD chain
Mangle table
Chain FORWARD (policy ACCEPT 29M packets, 11G bytes)
pkts bytes target prot opt in out source destination
Filter table
Chain FORWARD (policy ACCEPT 755K packets, 311M bytes)
pkts bytes target prot opt in out source destination
29M 11G UBNT_PFOR_FW_HOOK all -- any any anywhere anywhere
28M 11G VYATTA_FW_IN_HOOK all -- any any anywhere anywhere
28M 11G VYATTA_FW_OUT_HOOK all -- any any anywhere anywhere
Chain UBNT_PFOR_FW_HOOK (1 references)
pkts bytes target prot opt in out source destination
Chain UBNT_PFOR_FW_RULES (1 references)
pkts bytes target prot opt in out source destination
Chain VYATTA_FW_IN_HOOK (1 references)
pkts bytes target prot opt in out source destination
Chain VYATTA_FW_OUT_HOOK (1 references)
pkts bytes target prot opt in out source destination
POSTROUTING chain
Mangle table
Chain POSTROUTING (policy ACCEPT 34M packets, 12G bytes)
pkts bytes target prot opt in out source destination
34M 12G VYATTA_FW_OUT_HOOK all -- any any anywhere anywhere
Chain VYATTA_FW_OUT_HOOK (1 references)
pkts bytes target prot opt in out source destination
NAT table
Chain POSTROUTING (policy ACCEPT 2481 packets, 146K bytes)
pkts bytes target prot opt in out source destination
1336K 183M UBNT_VPN_IPSEC_SNAT_HOOK all -- any any anywhere anywhere
1336K 183M MINIUPNPD-POSTROUTING all -- any any anywhere anywhere
1336K 183M UBNT_PFOR_SNAT_HOOK all -- any any anywhere anywhere
1324K 182M VYATTA_PRE_SNAT_HOOK all -- any any anywhere anywhere
1324K 182M VYATTA_SNAT all -- any any anywhere anywhere
Chain UBNT_VPN_IPSEC_SNAT_HOOK (1 references)
pkts bytes target prot opt in out source destination
Chain MINIUPNPD-POSTROUTING (1 references)
pkts bytes target prot opt in out source destination
Chain UBNT_PFOR_SNAT_HOOK (1 references)
pkts bytes target prot opt in out source destination
Chain VYATTA_PRE_SNAT_HOOK (1 references)
pkts bytes target prot opt in out source destination
1324K 182M RETURN all -- any any anywhere anywhere
Chain VYATTA_SNAT (1 references)
pkts bytes target prot opt in out source destination
The NAT Masquerade rule ends up in VYATTA_SNAT
.
Chain VYATTA_SNAT (1 references)
pkts bytes target prot opt in out source destination
1265K 178M MASQUERADE all -- any eth0 anywhere anywhere /* NAT-5010 */
INPUT chain
Mangle table
Chain INPUT (policy ACCEPT 5631K packets, 702M bytes)
pkts bytes target prot opt in out source destination
NAT table
Chain INPUT (policy ACCEPT 19949 packets, 2464K bytes)
pkts bytes target prot opt in out source destination
Filter table
Chain INPUT (policy ACCEPT 115K packets, 15M bytes)
pkts bytes target prot opt in out source destination
5632K 702M VYATTA_FW_LOCAL_HOOK all -- any any anywhere anywhere
Chain VYATTA_FW_LOCAL_HOOK (1 references)
pkts bytes target prot opt in out source destination
OUTPUT chain
Raw table
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
3105K 440M VYATTA_CT_OUTPUT_HOOK all -- any any anywhere anywhere
3105K 440M NAT_CONNTRACK all -- any any anywhere anywhere
0 0 PFOR_CONNTRACK all -- any any anywhere anywhere
0 0 FW_CONNTRACK all -- any any anywhere anywhere
0 0 CT all -- any any anywhere anywhere NOTRACK
Chain VYATTA_CT_OUTPUT_HOOK (1 references)
pkts bytes target prot opt in out source destination
3105K 440M RETURN all -- any any anywhere anywhere
Chain NAT_CONNTRACK (2 references)
pkts bytes target prot opt in out source destination
38M 12G ACCEPT all -- any any anywhere anywhere
Chain PFOR_CONNTRACK (2 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- any any anywhere anywhere
Chain FW_CONNTRACK (2 references)
pkts bytes target prot opt in out source destination
59 15001 ACCEPT all -- any any anywhere anywhere
Mangle table
Chain OUTPUT (policy ACCEPT 3115K packets, 441M bytes)
pkts bytes target prot opt in out source destination
NAT table
Chain OUTPUT (policy ACCEPT 13398 packets, 940K bytes)
pkts bytes target prot opt in out source destination
Filter table
Chain OUTPUT (policy ACCEPT 109K packets, 14M bytes)
pkts bytes target prot opt in out source destination
Standard firewall rules
During initial configuration of the EdgeRouter X, the firewall is configured. The two rulesets WAN_IN and WAN_LOCAL are added.
The rules prevents connections to be initiated from the WAN (Internet), but allows inbound traffic to connections initiated from the LAN and the Linux Services. The LAN has full access to the Linux Service. The VLANs in the figure can be ignored. They are used internally by the EdgeRouter to be able to separate subnets. In this case, eth0 is the WAN interface and the LAN subnet is available on interface eth1 through eth4.
NAT Masquerade will also be enabled, during initial configuration, to ensure that all packets sent to the WAN are masqueraded.
When the rulsets are set up in EdgeRouter X, they will be automatically be added to the filter tables of FORWARD and INPUT chains. Enabling of NAT Masquerade will add rules to the nat table of the POSTROUTING chain.
FORWARD/filter
Every rulset the has direction in or out, will end up in the filter table of the FORWARD chain. The firewall ruleset WAN_IN is added to the VYATTA_FW_IN_HOOK chain. The rules protect the LAN.
Chain VYATTA_FW_IN_HOOK (1 references)
pkts bytes target prot opt in out source destination
13M 7076M WAN_IN all -- eth0 any anywhere anywhere
Chain WAN_IN (1 references)
pkts bytes target prot opt in out source destination
13M 7076M RETURN all -- any any anywhere anywhere /* WAN_IN-10 */ state RELATED,ESTABLISHED
0 0 DROP all -- any any anywhere anywhere /* WAN_IN-20 */ state INVALID
0 0 DROP all -- any any anywhere anywhere /* WAN_IN-10000 default-action drop */
INPUT/filter
The rulesets that have direction local, are added to the filter table of the INPUT chain. The firewall ruleset WAN_LOCAL is added to the VYATTA_FW_LOCAL_HOOK chain. The rules protect the Local Process.
Chain VYATTA_FW_LOCAL_HOOK (1 references)
pkts bytes target prot opt in out source destination
816K 111M WAN_LOCAL all -- eth0 any anywhere anywhere
Chain WAN_LOCAL (1 references)
pkts bytes target prot opt in out source destination
517K 89M RETURN all -- any any anywhere anywhere /* WAN_LOCAL-10 */ state RELATED,ESTABLISHED
6906 523K DROP all -- any any anywhere anywhere /* WAN_LOCAL-20 */ state INVALID
292K 22M DROP all -- any any anywhere anywhere /* WAN_LOCAL-10000 default-action drop */
POSTROUTING/nat
The NAT Masquerade rule is added to the VYATTA_SNAT
chain. All
packets sent on interface eth0
will be masqueraded.
Chain VYATTA_SNAT (1 references)
pkts bytes target prot opt in out source destination
1265K 178M MASQUERADE all -- any eth0 anywhere anywhere /* NAT-5010 */
IP set
The Linux command line tool ipset is used to set up, maintain and inspect so called IP sets in the Linux kernel. Depending on the type of the set, an IP set may store IP(v4/v6) addresses, (TCP/UDP) port numbers, IP and MAC address pairs, IP address and port number pairs, etc.
Iptables matches and targets referring to sets create references, which protect the given sets in the kernel. A set cannot be destroyed while there is a single reference pointing to it.
IP sets used by iptables
IP sets can be added in the EdgeRouter GUI. In addition, IP sets are generated internally and they named according to the following convention:
TypeProtocol_Interface
Type: ADDR or NET depending if it a single address or a subnet
Protocol: v4 for IPv4 adresses
Interface: Name of the interface, i.e. eth0 or switch0.3618
An example of an internally generated IP set:
name: ADDRv4_eth0
value: Public IPv4 address of the EdgeRouter on the WAN/Internet
Manipulate and view tables
The Linux command iptables
is used for manipulating the content of
the tables to view the current content.
The content of each table in the chains can be viewed by using:
iptables -v -t <table> -L <chain>
--verbose -v verbose mode
--table -t table table to manipulate (default: `filter')
--list -L [chain [rulenum]]
List the rules in a chain or all chains
Another command for listing the iptables rules:
iptables -nvL |cut -f -9|column -t| sed 's/^Chain/\n&/g'|sed '/^Chain/ s/[ \t]\{1,\}/ /g'|sed '/^[0-9]/ s/[ \t]\{1,\}/ /10g'
To get the listing in XML format, use:
iptables-save | iptables-xml
Create a script dump-iptables
with the following content and run it
on the EdgeRouter:
#!/bin/bash
filename="iptables-`hostname`-`date +%Y%m%d-%H%M`.txt"
echo "================================================================================" > $filename
echo " $filename" >> $filename
echo "================================================================================" >> $filename
echo >> $filename
echo "--------------------------------------------------------------------------------" >> $filename
echo " filter" >> $filename
echo "--------------------------------------------------------------------------------" >> $filename
sudo iptables -vL -n -t filter >> $filename
echo >> $filename
echo "--------------------------------------------------------------------------------" >> $filename
echo " nat" >> $filename
echo "--------------------------------------------------------------------------------" >> $filename
sudo iptables -vL -n -t nat >> $filename
echo >> $filename
echo "--------------------------------------------------------------------------------" >> $filename
echo " mangle" >> $filename
echo "--------------------------------------------------------------------------------" >> $filename
sudo iptables -vL -n -t mangle >> $filename
echo >> $filename
echo "--------------------------------------------------------------------------------" >> $filename
echo " raw" >> $filename
echo "--------------------------------------------------------------------------------" >> $filename
sudo iptables -vL -n -t raw >> $filename