In part 1 we covered the basics of setting up the ERL for one WAN interface and one LAN interface with a basic firewall on the WAN interface. But isolating our internal networks against bad actors on the outside is one of the most important functions of a router, so let’s explore a more robust firewall configuration.
ACL vs. Zone Based Firewall
The default firewall setup on the ERL (and the only one supported via the web client) allows defining firewalls as sets of ACL rules on a per-interface and per-direction basis. But the ERL also supports zone-based firewalls, which work by dividing your network into zones and matching rules based on source and destination zones. For a pretty thorough comparison of ACL versus zone-based firewall, I suggest going here. The basic idea behind a zone-based firewall is as follows:
- You define zones for your network. A common set of zones might be WAN, LAN, and DMZ.
- You assign one or more interfaces to each zone.
- You set up rules which match based on source and destination zones.
While an ACL firewall can be easier to set up for simple networks such as the one in this example, a zone-based firewall is conceptually simpler (in my opinion at least) and less susceptible to the sorts of mistakes that can open up your network to the outside.
Setting Up a Zone Based Firewall
The approach I’ve taken is based on this article, and I recommend reading it before proceeding. The link to the example configuration file in that article is broken however, luckily someone was kind enough to post a copy here.
Let’s convert the firewall we created in part 1 to a roughly equivalent zone-based firewall. In the end the result will in fact be much more robust than the ACL firewall.
Define Zones and Allowed Connections
The first step is to determine what our zones are and what connections will be permited for each pair of source and destination zones.
In this simple setup we have a WAN zone for the connection to the internet and a LAN zone for our internal LAN. We also need to define one more zone, named local, for connections to the router itself (DHCP, DNS, ssh, etc.).
Three zones gives us six
<source>,<destination> zone pairs. A reasonable
initial set of rules for traffic to allow between the zones is:
- WAN to LAN: Allow only traffic for established connections.
- WAN to local: Allow only traffic for established connections.
- LAN to WAN: Drop invalid state packets, allow all other traffic.
- LAN to local: Allow traffic for established connections. Also allow new ICMP, DHCP, DNS, ssh, and HTTP/HTTPS connections.
- local to WAN: Drop invalid state packets, allow all other traffic.
- local to LAN: Drop invalid state packets, allow all other traffic.
Create Firewall Rulesets
Now we need to translate the list of permissible traffic into firewall rules.
The article linked to above suggests defining two sets of rules for every
<source>,<destination> pair, using the naming convention
<source>-<destination> for IPv4 and
<source>-<destination>-6 for IPv6. I
generally follow this suggestion, but it results in quite a few identical
rulesets, as you can see from the list above. Therefore I define a few
“standard” rulesets for these rather than having redundant rules. Let’s write
these rulesets first.
The most basic of these is what I call the allow established, drop invalid ruleset. For performance reasons these rules form the basis of all rulesets, but often they are the only rules needed. The following commands in the CLI will create this ruleset for IPv4.
We need an equivalent rule for IPv6, but here we need to additionally allow ICMP connections.
The other repeated case we have is the allow all connections ruleset. To save
some typing we can start off by making a copy of the
rulesets, then simply change the default action to
accept and disable logging
for the default rule.
Repeat these steps to create a
We have only one ruleset left to create now, for connections from the LAN to the router. For IPv4 this looks like:
This should be done for IPv6 as well. Keep in mind that
already includes a rule for ICMP.
Set Up Zones
Now that we have our rulesets, we need to tell the router about our zones, which
interfaces belong to each zone, and which rulesets to apply for traffic
originating from other zones. This information goes in the
of the configuration, with one
zone stanza for each zone of our network.
Let’s start by creating a local zone.
Each zone has a default action, which must be either drop or reject.
Next specify which interface(s) are in this zone. Normally this would be a
interface <iface> command, but the local zone is a bit different:
Now we must create
from <zone> stanzas to specify which rulesets to apply for
traffic from the specified zone to the local zone.
Repeat this procedure for the LAN and WAN zones.
Delete Existing WAN Rules
If you’ve been following along you will already have some ACL rules applied to the WAN interface. It’s time to delete those.
Now it’s time to cross your fingers and commit the load of changes we just made. If you’ve made any mistakes the CLI will let you know, and you can correct them and commit again. Don’t forget to save your changes and back them up once everything is working!
Setting up a zone-based firewall on the EdgeRouter is a bit of work, but for me the conceptual simplicity and inherent protection against mistakes make it worthwhile.
In part 3 we’ll talk about setting up VLANs.