Write Better Firewall Rules in OPNsense using Aliases

A firewall alias is a powerful feature which should not be overlooked

Write Better Firewall Rules in OPNsense using Aliases Photo by BRRT from Pixabay

Introduction

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.

Add New Firewall Alias

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.

Add New Firewall Alias

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.

Add New Firewall Alias

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)
  • 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, hostnames, and FQDNs separated by commas in an alias such as:

  • 192.168.1.10, 192.168.1.11, myserver1, google.com

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 the AND operation. This is because 1 AND 1 = 1 and 1 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 since 0 AND 1 = 0 and 0 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.

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.

Firewall Rule Using Alias

Minimizing the Number of Firewall Rules

I mentioned in the Introduction 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:

Firewall Rule Before Alias

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:

Firewall Rule After Alias

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!