info_i_25x25.png See important information about Ubiquiti Devices and KRACK Vulnerability in this article. We will update this document as more information becomes available.

EdgeRouter - Zone-Policy CLI Example

Overview


Readers will learn how to create a zone-based firewall.

EdgeOS supports both ACL-based and zone-based firewalls, but currently the zone-based firewall is only configurable from the CLI. For a good article on the difference between ACL-based and zone-based firewalls, see: ACL vs. Zones

There are three networks:

  1. WAN - 172.16.10.0/24, 2001:0DB8:0:9999::0/64
  2. LAN - 192.168.100.0/24, 2001:0DB8:0:AAAA::0/64
  3. DMZ - 192.168.200.0/24, 2001:0DB8:0:BBBB::0/64

This specific example is for a router on a stick, but you can readily adapt this example for the number of NICs (Network Interface Cards) you have.

Logical Network Diagram 

  • Internet – 192.168.200.100 – tcp/80
  • Internet – 192.168.200.100 – tcp/443
  • Internet – 192.168.200.100 – tcp/25
  • Internet – 192.168.200.100 – tcp/53
  • EdgeOS acts as DHCP, DNS forwarder, NAT, router, firewall.
  • 192.168.200.200/2001:0DB8:0:BBBB::200 is an internal/external DNS, web, and mail (SMTP/IMAP) server.
  • 192.168.100.10/2001:0DB8:0:AAAA::10 is the administrator’s console, which can SSH to EdgeOS.
  • LAN and DMZ hosts have basic outbound access: web, FTP, SSH.
  • LAN can access DMZ resources.
  • DMZ cannot access LAN resources.
  • Inbound WAN connects to DMZ host.

 

 

Physical Network Diagram

The EdgeOS interface is assigned the .1/:1 address of their respective networks. Here are the VLAN assignments of the ports:

  • WAN - VLAN 10
  • LAN - VLAN 20
  • DMZ - VLAN 30

The configuration will look like this:

interfaces {
 ethernet eth0 {
 vif 10 {
 address 172.16.10.1/24
 address 2001:db8:0:9999::1/64
 }
 vif 20 {
 address 192.168.100.1/24
 address 2001:db8:0:AAAA::1/64
 }
 vif 30 {
 address 192.168.200.1/24
 address 2001:db8:0:BBBB::1/64
 }
 }
}

 

Basics of Zones

  • Each interface is assigned to a zone. The interface can be physical or virtual, such as tunnels (VPN, PPTP, GRE, etc.) and are treated exactly the same.
  • Traffic flows from zone A to zone B. I refer to this flow as a zone-pair-direction. For example, A->B and B->A are two zone-pair-directions.
  • Rulesets are created per zone-pair-direction.
  • I name rulesets to indicate which zone-pair-direction they represent (examples: ZoneA-ZoneB and ZoneB-ZoneA; LAN-DMZ and DMZ-LAN). In EdgeOS you must have unique ruleset names. In the event of overlap, I add a -6 to the end of IPv6 rulesets (example: LAN-DMZ and LAN-DMZ-6). This allows for auto-completion and uniqueness.
  • In this example we have four zones:
    • LAN
    • WAN
    • DMZ
    • Local
  • Note: The Local zone is the firewall itself.
  • If your computer is on the LAN and you need to SSH into your EdgeOS box, then you need a rule to allow it in the LAN-Local ruleset. If you want to access a webpage from your EdgeOS box, then you need a rule to allow it in the Local-LAN ruleset.
  • It is good to name the rules consistently. As the number of rules you have grows and the more consistency you have, the easier your life will be.
Rule 1 - State Established, Related
Rule 2 - State Invalid
Rule 100 - ICMP
Rule 200 - Web
Rule 300 - FTP
Rule 400 - NTP
Rule 500 - SMTP
Rule 600 - DNS
Rule 700 - DHCP
Rule 800 - SSH
Rule 900 - IMAPS
default-action drop
enable-default-log

Default Action and Logging

Zones and rulesets both have a default-action statement. When using zone-policies, the default action is set by the zone-policy statement and is represented by rule 10000.

It is good practice to log both accepted and denied traffic. It can save you from significant headaches when you try to troubleshoot a connectivity issue. Usingenable-default-log will log traffic hitting the default-action.

By default, iptables does not allow traffic for established sessions to return, so you must explicitly allow this. I do this by adding two rules to the beginning of every ruleset. Rule 1 allows established and related state packets through, and rule 2 drops and logs invalid state packets. I place the established/related rule at the top because the vast majority of traffic on a network is established and the invalid rule prevents invalid state packets from mistakenly being matched against other rules. Having the most matched rule listed first reduces CPU load in high-volume environments.

Important Note:You do not want to add logging to the established state rule as you will be logging both the inbound and outbound packets for each session instead of just the initiation of the session. Your logs will be massive in a very short period of time.

In EdgeOS you must have the interfaces created before you can apply them to the zone, and you must create the rulesets before you can apply them to a zone-policy.

  1. Create and configure the interfaces.
  2. Build out the rulesets for each zone-pair-direction; each ruleset should include at least the three state rules.
  3. Set up the zone-policies.

Zones do not allow for a default action of accept; the default action is either drop or reject. It is important to remember this because if you apply an interface to a zone and commit, any active connections will be dropped. Specifically, if you: 

  • are SSH’ed into EdgeOS
  • add Local or the interface you are connecting through to a zone
  • do not have rulesets in place to allow SSH and established sessions

then you will not be able to connect.

The following are the rules that were created for this example (which may not be complete), both in IPv4 and IPv6. If there is no IP specified, then the source/destination address is not explicit. 

  1. WAN – DMZ:192.168.200.200 – tcp/80
  2. WAN – DMZ:192.168.200.200 – tcp/443
  3. WAN – DMZ:192.168.200.200 – tcp/25
  4. WAN – DMZ:192.168.200.200 – tcp/53
  5. WAN – DMZ:2001:0DB8:0:BBBB::200 – tcp/80
  6. WAN – DMZ:2001:0DB8:0:BBBB::200 – tcp/443
  7. WAN – DMZ:2001:0DB8:0:BBBB::200 – tcp/25
  8. WAN – DMZ:2001:0DB8:0:BBBB::200 – tcp/53
  1. DMZ - Local - tcp/53
  2. DMZ - Local - tcp/123
  3. DMZ - Local - udp/67,68
  1. LAN - Local - tcp/53
  2. LAN - Local - tcp/123
  3. LAN - Local - udp/67,68
  4. LAN:192.168.100.10 - Local - tcp/22
  5. LAN:2001:0DB8:0:AAAA::10 - Local - tcp/22
  1. LAN - WAN - tcp/80
  2. LAN - WAN - tcp/443
  3. LAN - WAN - tcp/22
  4. LAN - WAN - tcp/20,21
  1. DMZ - WAN - tcp/80
  2. DMZ - WAN - tcp/443
  3. DMZ - WAN - tcp/22
  4. DMZ - WAN - tcp/20,21
  5. DMZ - WAN - tcp/53
  6. DMZ - WAN - udp/53
  1. Local - WAN - tcp/80
  2. Local - WAN - tcp/443
  3. Local - WAN - tcp/20,21
  4. Local - WAN - tcp/53
  5. Local - WAN - udp/53
  6. Local - WAN - udp/123
  1. Local - DMZ - tcp/25
  2. Local - DMZ - tcp/67,68
  3. Local - DMZ - tcp/53
  4. Local - DMZ - udp/53
  1. Local - LAN - tcp/67,68
  1. LAN - DMZ - tcp/80
  2. LAN - DMZ - tcp/443
  3. LAN - DMZ - tcp/993
  4. LAN:2001:0DB8:0:AAAA::10 - DMZ:2001:0DB8:0:BBBB::200 - tcp/22
  5. LAN:192.168.100.10 - DMZ:192.168.200.200 - tcp/22

Zone Rulesets

Since we have four zones, we need to set up the following rulesets:

  1. LAN-WAN
  2. LAN-Local
  3. LAN-DMZ
  4. WAN-LAN
  5. WAN-Local
  6. WAN-DMZ
  7. Local-LAN
  8. Local-WAN
  9. Local-DMZ
  10. DMZ-LAN
  11. DMZ-WAN
  12. DMZ-Local

Even if the two zones will never communicate, it is a good idea to create the zone-pair-direction rulesets and enable default logging. This will allow you to log attempts to access the networks. Without it, you will never see the connection attempts.

This is an example showing the configuration of the default-action, the default-log, and two base rules.

name wan-lan {
 default-action drop
 enable-default-log
 rule 1 {
 action accept
 state {
 established enable
 related enable
 }
 }
 rule 2 {
 action drop
 log enable
 state {
 invalid enable
 }
 }
}

Here is an example of an IPv6 DMZ-WAN ruleset.

ipv6-name dmz-wan-6 {
 default-action drop
 enable-default-log
 rule 1 {
 action accept
 state {
 established enable
 related enable
 }
 }
 rule 2 {
 action drop
 log enable
 state {
 invalid enable
 }
 rule 100 {
 action accept
 log enable
 protocol ipv6-icmp
 }
 rule 200 {
 action accept
 destination {
 port 80,443
 }
 log enable
 protocol tcp
 }
 rule 300 {
 action accept
 destination {
 port 20,21
 }
 log enable
 protocol tcp
 }
 rule 500 {
 action accept
 destination {
 port 25
 }
 log enable
 protocol tcp
 source {
 address 2001:db8:0:BBBB::200
 }
 }
 rule 600 {
 action accept
 destination {
 port 53
 }
 log enable
 protocol tcp_udp
 source {
 address 2001:db8:0:BBBB::200
 }
 }
 rule 800 {
 action accept
 destination {
 port 22
 }
 log enable
 protocol tcp
 }
}

Creating Zone Policy

Once you have all of your rulesets built, then you need to create your zone-policy.
Start by setting the interface and default action for each zone.

set zone-policy zone dmz default-action drop
set zone-policy zone dmz interface eth0.30

In this case, we are setting the IPv6 ruleset that represents traffic sourced from the LAN and destined for the DMZ. Because the zone-policy firewall syntax is a little awkward, I keep it straight by thinking of it backwards.

set zone-policy zone dmz from lan firewall ipv6-name lan-dmz-6


The DMZ-LAN policy is LAN-DMZ. You can get a rhythm to it when you build out a bunch at one time.
In the end, you will end up with something like this config: ZonesExampleConfigBoot. I took out everything but the firewall, interfaces, and zone-policy sections. It is long enough as-is.

Note:This example is incomplete. 

IPv6 Tunnel

If you are using an IPv6 tunnel from HE.net or somewhere else, the basis is the same except that you have two WAN interfaces, one for IPv4 and one for IPv6.
You have five zones instead of just four, and you configure your IPv6 ruleset between your tunnel interface and your LAN/DMZ zones instead of to the WAN.

LAN, WAN, DMZ, Local, and TUN (tunnel) IPv6 pairs are:

  1. LAN-TUN
  2. LAN-Local
  3. LAN-DMZ
  4. TUN-LAN
  5. TUN-Local
  6. TUN-DMZ
  7. Local-LAN
  8. Local-TUN
  9. Local-DMZ
  10. DMZ-LAN
  11. DMZ-TUN
  12. DMZ-Local

Note:None go to WAN since WAN does not have an IPv6 address on it.


You have to add a couple of rules to your WAN-Local ruleset to allow protocol 41 in.

Here is an example:

rule 400 {
 action accept
 destination {
 address 172.16.10.1
 }
 log enable
 protocol 41
 source {
 address ip.of.tunnel.broker
 }
}

Note: the UPNP2 service, when enabled, will still work with a zone-based firewall.

Related Articles