Write Better Firewall Rules in OPNsense using Aliases
Table of Contents
When you first learned to write firewall rules in OPNsense, you may have simply used the pre-defined aliases for the network interfaces/ports and IP addresses such as “LAN net”, “LAN interface”, “HTTP”, “HTTPS”, etc. You may not have even realized you were using aliases since they do not appear in the list on the “Aliases” page. Using the predefined aliases is not only convenient but helps make your rules easier to understand (imagine having a large number of rules and seeing only IP/network addresses).
As you begin growing and segregating your network you may find that maintaining your rules becomes more difficult especially if you are using IP addresses in your rules for all the devices with static addresses. You may even forget the purpose of some of your rules if you do not enter good descriptions for your rules. Not only that, there are cases where you may end up with several nearly identical rules because you cannot enter more than one IP/network address/port, etc. into a single rule.
There is a better way – firewall rule aliases! An alias allows you to group one or more IP address(es), network address(es), port(s), and hostname(s) and use them in rules. You may then write rules that are easier to read, understand, and maintain. Aliases may help reduce the overall number of rules that you need to write because you may use a single alias containing multiple items. I personally have consolidated several rules into a single rule once I started making better use of aliases.
One nice touch with aliases is when you are viewing your firewall rules for each interface, you will see a tooltip when hovering over the alias. The tooltip will show the contents of the alias along with the description you entered. That is very convenient because you do not have to go to the “Aliases” page if you cannot remember what is in a particular alias.
Creating an Alias
To demonstrate how to create an alias, I will use a host alias as an example. Go to the “Firewall > Aliases” page. You will notice there are 4 pre-defined aliases in the list by default. Click on the “+” button highlighted in the screenshot below.
Enter the “Name” of your alias. Choose the “Type” from the dropdown. There are several types of aliases to choose from (see more details in Types of Aliases). The “Content” will depend on the type of alias you choose. In the example below, for the “Host(s)” alias, you may enter IP addresses or hostnames. You may even include another alias (see Nesting Firewall Rule Aliases). Finally, you may want to include a useful “Description” that will help you know the purpose or details of the alias – especially if it is difficult to determine simply from the alias name.
After you click “Save”, you will notice your new alias in the list. You will also see a notification stating you need to apply the changes in order to use the alias in your firewall rules. Simply click the “Apply” button when you are finished.
Types of Aliases
There are a number of parameters for which aliases may be defined. I will detail each one so you may see the versatility of aliases and have a greater understanding where they may be utilized.
Host(s)
The “Host(s)” alias type allows you to enter IP addresses, local hostnames, or fully qualified domain names (FQDN). If you find yourself referring to IP addresses frequently in your rules, you could make it a host alias and use that alias in your rules. Since the firewall rules only allow IP or network addresses, you must use an alias to use hostnames or FQDNs in your rules.
Host aliases also allow exclusions using the “!” symbol. This is not unfamiliar to users to who write code since the exclamation point is often use to mean “not”. If you have !192.168.1.10, for instance, it means exclude (or “not”) 192.168.1.10. I have discovered that you may only use exclusions on IP addresses. An error will be displayed if you try to save a host alias with an exclusion on a hostname/FQDN.
Valid examples for host aliases:
- IP address: 192.168.1.10 or !192.168.1.10 (IPv6 addresses are allowed too)
- IP address range: 192.168.1.10-192.168.1.15
- Local hostname (without the domain name): myserver or !myserver
- FQDN: google.com or !google.com
You may enter multiple values of any combination of IP addresses, IP address ranges, local hostnames, and FQDNs separated by commas in an alias such as:
- 192.168.1.10, 192.168.1.11, 192.168.1.15-192.168.1.20, myserver1, google.com
Warning
I have had issues in the past using local hostnames in aliases. They would work fine initially, but after some time I would notice I could not access something allowed by the firewall rules. I would check the contents of the alias under “Firewall > Diagnostics > Aliases” to find that the IP address of the hostname was blank (perhaps it failed to resolve or refresh the IP address for whatever reason).
There is the possibility this issue has been fixed at some point, but I personally generally stick to using IP addresses in my aliases for increased reliability (even though I would prefer to use hostnames for some of the aliases). If you are experiencing similar issues, simply use the IP address instead – but that does require using static DHCP mappings, which is something I make use of for any device where I want to limit access to various parts of my network.
Network(s)
The “Network(s)” alias allow you to enter the IP address range for networks in CIDR format. The CIDR notation is a way to define a subnet mask by using the number of bits that should be set to 1. The rest are set to 0. In the example of 192.168.1.0/24, the “/24” is the CIDR notation portion of the network address which is equivalent to the subnet mask of 255.255.255.0 (each of the 4 octets are 8 bits and for “/24” 3 octets of 8 bits are set to 1). Exclusions are allowed for network aliases like with host aliases.
Valid examples for network aliases:
- 192.168.1.0/24 or !192.168.1.0/24 (IPv6 addresses are allowed too)
You may enter multiple networks:
- 192.168.1.0/24, 192.168.2.0/24
Further explanation of CIDR if you are curious: If you have 24 bits that are set to 1 and the rest 0, the subnet mask is 255.255.255.0 (8 bits with a value of 1 is 255, which is 2^8-1 since you count 0 as one of the 256 values). When that mask and the IP address have the
AND
operation applied to them, it leaves the network address behind. If the IP address of a device in the network is 192.168.1.10, it will become 192.168.1.0 after theAND
operation. This is because1 AND 1 = 1
and1 AND 0 = 0
so the 1 bits of the subnet mask do not change the bit value of the IP address. However, 0 bits in the subnet mask will change the value of the IP address since0 AND 1 = 0
and0 AND 0 = 0
. That is why the last octet of the IP address is set to 0 with “/24” to obtain the network address. The “255” value of the subnet mask is essentially “keep the octet the same value” while anything less than 255 will change the the value of the octet in order to determine the network address range.
Port(s)
The “Port(s)” alias allows you to specify port numbers. You may enter a number between 0 and 65,535. To specify a range of continuous ports, use a colon between the port numbers.
Valid examples for port aliases:
- Port: 8080
- Port range: 8000:8080
You may enter multiple ports including port ranges:
- 22, 8000:8080
URL (IPs)
The “URL (IPs)” alias is used for a list of IP addresses that are hosted on a website. The OPNsense documentation does not mention the “URL (IPs)” alias type. When comparing “URL (IPs)” to “URL Table (IPs)”, it seems the main difference is the “Refresh Frequency”. I assume the “URL (IPs)” is used for static lists of IP addresses. This assumption seems to be confirmed by a user on the OPNsense forum.
If you need to make an update to the list, I do not know if you would have to recreate it, update the alias to force a refresh, or clear out the state of the alias for it to pull the update. If you feel the list could change even rarely, you might as well use the “URL Table (IPs)” alias type. It does not hurt to refresh a file that rarely changes since it will pick up any new changes without you needing to be concerned with updates.
Valid example for a URL alias:
You may enter multiple URLs:
URL Table (IPs)
The “URL Table (IPs)” alias is used for a list of IP addresses like the “URL (IPs)” alias. I imagine most users will want to use this URL alias type the most since it can be periodically refreshed, which is useful for blocklists since hostile IPs can change over time. The amount of days and hours between refreshes can be specified for URL table aliases.
Valid example for a URL table alias:
You may enter multiple URLs:
GeoIP
The “GeoIP” alias is used when you wish to block IP/network addresses from other countries. Because of services hosted on the cloud and tunneling network connections through VPNs, Tor, or SSH, it is easy bypass GeoIP blocks. However, it still can be useful since there still may be malicious traffic coming from hostile networks hosted in other countries you may deem as hostile. Perhaps it may block random attacks from unsophisticated attackers or from compromised machines in other countries.
To set up “GeoIP” aliases, you must sign up for MaxMind’s GeoIP service to obtain the GeoIP address ranges needed to fully configure the GeoIP alias. See the OPNsense documentation for details on how to set it up properly.
Network Group
The “Network Group” alias is useful for grouping other alias types except for the “Port(s)” and “External (Advanced)” alias types. This alias type only allows compatible aliases to be grouped. The main benefit for using a “Network Group” alias is the fact it prevents you from grouping incompatible aliases. Perhaps that could prevent some issues from occurring.
Valid example for a network group alias:
- hostalias1, hostalias2, urlalias (chosen from the dropdown)
MAC Address
The “MAC Address” alias allows you to use MAC addresses in aliases. The OPNsense documentation warns that MAC addresses can be spoofed so if you are concerned with the possibility of a malicious user spoofing MAC addresses to gain access to whatever resource your firewall rules allow then you may not want to use this alias type.
Valid example for a MAC address alias:
- 3f:cf:3f:1f:7f:bf
You may enter multiple MAC addresses:
- 3f:cf:3f:1f:7f:bf, 3e:ce:3e:1e:7e:be
External (Advanced)
The “External (Advanced)” alias type is used when you want an external process to manage the value of an alias in a firewall. This would be useful if you want to dynamically change the value of an alias. External aliases are considered an advanced feature so more than likely you will not need to use this type of alias unless you are trying to do something very sophisticated. I do not have any personal experience with this type of alias, but I can see it being useful in a very advanced firewall environment where a process triggers an update to the alias. Since OPNsense has a firewall API, there are likely better ways to update/manage firewall rules from an external process.
Dynamic IPv6 Host
This alias type is a more recent addition (at the time of this page update), and it is a very welcome addition for IPv6 support. Even though it is possible for everyone on the planet to have their own static IPv6 addresses, not all ISPs are assigning static IPv6 addresses to residential customers. Some ISPs may treat IPv6 similar to IPv4 and dynamically change the IPv6 prefixes (the first portion of the IPv6 address). Because IPv6 internal IPv6 addresses are essentially assigned by the ISP via DHCPv6 (if you have multiple networks, you may be able to assign different prefixes to each interface/network if your ISP allows prefix delegation), if the IPv6 address changes none of your IPv6 firewall rules that contain IPv6 addresses will work properly since they will be referencing the old IPv6 addresses.
To remedy that issue, the dynamic IPv6 host alias allows you to only include the second half of the IPv6 address so that first half of the IPv6 can be updated automatically if your ISP assigns you a new IPv6 address. This feature is very important if you do not have static IPv6 addresses assigned to you by your ISP.
In order to create a new dynamic IPv6 alias, you will need to enter the second half of the IPv6 address in the “Content” box. You must always begin the IPv6 address with ::
(2 colons). Also, you must select the appropriate interface to monitor for changes because each interface in your network can have a different IPv6 prefix (using “Track interface” in the “IPv6 Configuration Type” option). You can only chose one interface per dynamic IPv6 alias, but you can enter multiple IPv6 addresses if they are on the same interface/network. You will have to create additional aliases for other interfaces if you need them.
Examples of a dynamic IPv6 host alias using the LAN as the interface (you can chose any interface that is appropriate):
- ::1000:1000:1000:1
- ::1
Multiple addresses can be entered:
- ::1000:1000:1000:1, ::1000:1000:1000:2
IPv6 addresses an omit leading zeros and if an entire segment is all zeroes which is why in the example above, you can simply use ::1
instead of ::0000:0000:0000:0001
. You can read up on the various shorthand forms of IPv6 addresses if you are curious.
Nesting Firewall Rule Aliases
For all of the alias types, you may nest aliases inside of aliases. This may be useful if you wish to group several aliases together. For instance, if you have an alias for “server1” and “server2”, you could create a third alias called “myservers” which contains both “server1” and “server2”. By doing this, you could use the “server1” and “server2” aliases in their own specific firewall rules but then have broader firewall rule(s) which apply to both servers.
Deleting a Firewall Alias
If you attempt to delete an alias that is nested within another alias and/or is currently in use by a firewall rule, you will receive an error. This prevents you from breaking any of your firewall rules.
Firewall Rule Example
Now that you have a better understanding of the values that may be entered for various types of aliases, it is time to use them in your firewall rules.
Highlighted below is an example rule where the “MyServer” host alias is being used as the destination. For illustration purposes, you may assume the server exists in another network such as the DMZ. The example is showing the creation of a LAN rule to allow access from devices in the LAN network to the server in the DMZ network.
Minimizing the Number of Firewall Rules
I mentioned earlier that I was able to minimize having several nearly identical firewall rules. To illustrate that point, I will list some example rules without aliases and then a single rule that has an alias which functions exactly the same as the rules without aliases.
Before using an alias there are 2 rules allowing HTTPS access to 2 servers in the DMZ network. Since you can only enter one IP address at a time in the rules without an alias, you would need one rule for each server:
If you use an alias call “MyServers”, for instance, which has both IP addresses of the servers, you only need to create one rule with the “MyServers” alias as the “Destination” to allow HTTPS access to both servers in the DMZ:
As you can see, aliases allow you to reduce the number of rules you need to create and at the same time make the rule easier to comprehend (especially if you use more descriptive names than my example). In the example above, you can essentially read across the row: “Allow the LAN network to access My Servers using HTTPS”. I usually include a sentence in my description which is a human readable version of the rule so when I reviewing/tweaking my rules, I understand the purpose of them. Most rules are straightforward, but it can be helpful to include details that are not easily expressed or determined from glancing at the rule page since there is not enough space to show every value you have set in your rules.
Conclusion
A firewall alias is a simple yet very powerful concept that should not be overlooked if you wish to master writing firewall rules. You can likely live without them if you are only writing a few basic rules. However, as your learning grows and you begin tightening down access on your network, you may find your rule list increasing in number and complexity since you are writing more granular rules to limit access. To reduce complexity and the number of rules you need to create, making use of aliases is essential. I hope this information will help you see the potential value of using aliases in your firewall rules!