A DMZ (demilitarized zone) is a segmented part of a network that is used to host all publicly accessible websites and services. The intention is to protect the internal network from external threats. It is an effective strategy to minimize public exposure of your critical assets as well as limit the damage caused when an intruder is able to penetrate your network.
While researching DMZ implementations when writing this how-to, I came across a nice write-up on implementing a basic DMZ using a single firewall as well as implementing a more advanced/secure DMZ using two firewalls (another good DMZ reference). The basic DMZ example is pretty much the approach that I took in my home network – partially due to inexperience when I was learning how to use OPNsense and partially due to minimizing expense on purchasing additional hardware. I am limiting the scope of this how-to to the basic DMZ example since I imagine many home network users will be using a single router/firewall to manage multiple logical/physical networks.
The basic DMZ implementation is a more budget friendly and easier to implement option due to requiring less hardware/software to purchase, configure, and maintain. However, the trade off is less security. By less security, I mean someone has to compromise your router/firewall box to the extent that they have full visibility into all your networks including the internal, private networks. If that type of compromise occurs, you already have big problems. Depending on the quality of your router/firewall, this may or may not be an easy task for an attacker. You are basically putting all of your eggs in one basket with this approach. For a home network user, I do not think this fact alone should sway you away from using a single router/firewall for your network. It is still a lot more secure than using a single network and exposing various ports on a server to the Internet using a standard consumer-grade router that receives little to no security updates.
The advanced DMZ implementation mitigates the issue of compromise of your internal, private networks more effectively since the attacker would have to compromise the second firewall or perhaps a device behind the second firewall before further penetration of your network could occur. The devices behind the second firewall would be practically invisible to the DMZ network especially if all traffic from the DMZ network is dropped between the DMZ and your internal network(s). (It is important to note that you can also drop traffic between the DMZ and your internal network(s) with the basic DMZ approach, but if your only router/firewall is compromised, the attacker is much more likely to snoop on traffic or attempt to compromise devices on your internal network since the attacker can see all of your configured networks, interfaces, devices, and firewall rules.).
Two Approaches of Implementing a Basic DMZ
There are at least two approaches you may consider when implementing a basic DMZ using a single router/firewall. I imagine there are other approaches, but I am limiting this discussion to two slightly different approaches. Each have their own pros and cons so you may choose based on your current hardware/budget.
If your OPNsense box has more than one Ethernet port, you may put network switches/devices on separate physical ports. The two physical ports can be configured to be on separate physical networks/subnets. Some benefits to this approach is that you do not need to know how to configure VLANs or have hardware that supports VLANs so the configuration is less complex. You may use multiple inexpensive unmanaged switches for each physical network you create. If you need to create more than a few networks, the second option of using VLANs is likely a better approach since it can be less costly and make more efficient use of the hardware (less hardware more fully utilized).
The second approach is utilizing VLANs which allows for creating one or more virtual networks. Your network switches need to have VLAN functionality in this approach and as well as wireless access points if you wish to have separate wireless networks. With VLANs, you can decide if you wish to use one or more physical interfaces. If you are only using one physical interface on your router, it is considered a “router on a stick” configuration. If you have additional interfaces, you may wish to utilize them either with link aggregation (LAG) or by dividing up the VLANs among the different interfaces. If you have several VLANs on a single interface, you may also want to consider using a higher bandwidth interface such as 10 Gbit in order to alleviate any potential bottlenecks without resorting to a LAG, and it also allows for faster data transfers if you have other devices on 2.5-10 Gbit connections.
Below are diagrams of the two approaches:
Physical Network Approach
By default, OPNsense will setup a WAN and LAN interface if it detects your network appliance has more than one Ethernet port. For simplicity, I am going to assume you already have the default interfaces configured. You will need to create an additional interface for the DMZ network. You will need to have a 3rd Ethernet port available in order to create another physical network. This physical network example uses 3 ports: 1 for the WAN, 1 for the LAN, and 1 for the DMZ network.
Assign DMZ Interface
To assign a new interface for the DMZ network, go to the “Interfaces > Assignments” page. At the bottom of the page you will see the “New interface” section.
Select the appropriate physical port from the dropdown box. In my example, I chose “igb2” which is the third Ethernet port since the numbering starts with zero. The interface “igb2” could be different for you depending on your hardware configuration. Enter a “Description” for the interface. This will show up in the left sidebar panel. Then click the “+” button to assign the interface.
Logical Network Approach
If you are implementing the logical/VLAN approach, there is an extra step you must take when assigning an interface. You must first create a VLAN interface before you can assign it.
Create VLAN Interface
To create a VLAN interface, go to the “Interfaces > Other Types > VLAN” page. Click the “Add” button to open the VLAN interface page.
Select the parent interface which you want to create the VLAN interface. This interface is the physical Ethernet port you want to use the VLAN. You may create multiple VLANs on the same parent/physical port. VLANs allow you to create many logical networks that exist on a single physical network. In my example, I used the “igb1” interface which is the second Ethernet port. For this logical network example, you only need 2 ports: 1 for the WAN and 1 for the LAN/DMZ networks. The LAN and DMZ networks will share the second port.
Please note that I am assuming that you already have the default WAN/LAN interface configured so the LAN should already be created on the “igb1” interface. The “igb1” interface could be different depending on your hardware Ethernet port assignments.
Enter a VLAN tag number. I typically like to use the same number as the subnet for the VLAN but you do not have to use that convention. In my example, I am using the 192.168.20.0 network for the DMZ so I chose “20” as the VLAN tag. You can choose a “VLAN priority” for the network traffic which may be useful if you have a congested network. It probably does not help much otherwise. Perhaps for a live streaming/VOIP application, it may be more important to use the VLAN priority. Enter a “Description” for the VLAN interface. This name will be visible when making the interface assignment so name it something useful. I like to name the VLAN the same as the assigned interface name so it is easier to match up VLANs to interfaces. It also makes the VLAN configuration appear more consistent throughout the web interface. Click “Save” to save the VLAN interface configuration.
Assign DMZ VLAN Interface
The assignment of the logical/VLAN interface is very similar to the physical interface except that you select your DMZ VLAN interface instead of the physical interface in the dropdown box.
Configure VLANs on the Network Switch
When you take the logical network/VLAN approach, you will need to configure VLANs on your network switch with the same VLAN ID/tag. In our example, the DMZ uses the VLAN ID/tag of 20. Due to the number of switches on the market and the differences on how to configure VLANs, I will not describe it in detail, but I wanted to mention that you must configure VLANs on your network switch for this approach to function properly. This is another reason why I mentioned that setting up two physical networks is less complex. You can use basic unmanaged switches for the physical networks, but for logical networks using VLANs, you must use VLAN-aware switches.
One important step with creating VLANs on your switch is to set the port on the switch where your router is connected to a tagged/trunk port so that it can carry all of the VLAN traffic. In OPNsense, you do not need to worry about setting the router port where the switch is connected to a tagged/trunk port since OPNsense knows how to do this properly with your VLAN interfaces.
Common Steps for Both Approaches
Once the DMZ interface has been assigned, the remaining steps are the same. A physical and logical interface is treated the same. Even the assignment of the interfaces is very similar, but I thought it was important to explain the step separately to provide a clear explanation for both approaches since the logical network/VLAN approach requires an extra step before assigning the interface. Not only is the rest of the interface creation the same, but the firewall rules are also the same for both approaches! The DMZ interface is referenced in the firewall rules the same way for a physical and a logical network.
Configure and Enable DMZ Interface
Once the DMZ interface is assigned, it will be listed under the “Interfaces” sidebar menu. Click on the “[DMZ]” interface to configure the interface.
Click the “Enable Interface” and “Prevent interface removal” checkboxes. The “Prevent interface removal” option prevents you from deleting the interface from the “Assignments” page. It can be a useful safeguard so you do not accidentally mess up network configuration in a very bad way. You may notice on the logical/VLAN interface that the device name is slightly different than the screenshot. It will show “igb2_vlan20” instead of “igb2” which is ok because that indicates a VLAN interface is being used instead of a physical interface. I did not want to bother with 2 different screenshots when the device name is the only slight difference. The “Description” should already be filled with “DMZ” since you added it when you assigned the interface. Next, select “Static IPv4” for the “IPv4 Configuration Type”. You may also enable IPv6 as well, but for simplicity, I am only showing IPv4.
If you scroll down farther on the same page, you should see the IPv4 configuration now that you have selected the “Static IPv4” configuration type.
Enter the IP address of the interface itself, which is 192.168.20.1 in this example. To indicate the range of network addresses on the interface, select “24” in the dropdown box to indicate this is /24 network with the address range of 192.168.20.0-192.168.20.255 (where the usable addresses are 192.168.20.1-192.168.20.254). Finally, click the “Save” button to save the interface changes. You will also need to click “Apply changes” button at the top of the page to activate the changes.
Enable DHCP on DMZ Interface
Many users will want to enable DHCP to assign addresses so it does not have to be done manually on each individual device on the network. Go to the “Services > DHCPv4 > [DMZ]” page to configure DHCP for the DMZ network.
Click the “Enable DHCP server on the DMZ interface” checkbox. Then enter “192.168.20.100” in the “from” box and “192.168.20.200” in the “to” box. You may choose different ranges. If you plan to have some static IP addresses, you should leave some room for those. You have to make sure your static IP addresses do not overlap the DHCP address range because IP address conflicts could occur. Also, do not start your range at “192.168.20.1” since that is the DMZ interface address and will act as the gateway IP address for devices on the DMZ network. Click the “Save” button to save and enable DHCP for the DMZ network.
Create Static DHCP Leases (Optional)
If you are running server(s) and hosting various services, you will likely want to use static IP addresses so that you can use port forwarding and add appropriate firewall rules. I prefer to use DHCP static mappings rather than go to each device and manually configure the IP address settings. It allows you to manage all static IP addresses from a centralized management interface. You can add a new static DHCP lease from the “Services > DHCPv4 > [DMZ]” page, but I prefer to go to the “Services > DHCPv4 > Leases” page. The reason I prefer the “Leases” page is that there is a “+” button you can use to add a new static DHCP lease and it will prepopulate the MAC address on the “Static DHCP Mapping” page. You have to go to the “Leases” page anyway to copy the MAC address (or go to the device itself to find the MAC address to type in) so it makes sense to add a new static lease from the “Leases” page. It is a handy shortcut you may use.
With that said, click on the “+” button for the device you want to create a static DHCP mapping.
The “Static DHCP Mapping” page will then open with the MAC address prepopulated.
Enter the “IP address” for the server/device and then the “Hostname” for the device. You may be much more creative with the hostname than my example. The hostname entered will actually override the hostname that is set on the system so keep that in mind. If you like the hostname configured on your server, just enter the same hostname so that you can refer your server from other devices on the network by the name you prefer. The fact that the hostname can be overridden can be helpful if there are devices on your network which do not seem to allow you to change their default hostname. If you are OCD or need to refer to the device easier than some randomly generated name, you can use static DHCP mappings to clean up those hostnames (but it also means they now will have a static IP address, which should not normally be an issue).
At this point you should now have 3 networks/interfaces: WAN, LAN, and DMZ. The last major step is to set up firewall rules so that the network traffic is properly isolated. There are a number of ways you may go about creating firewall rules and some of the rules will depend up on which services you are planning on hosting. Also, it depends on how strict you wish to be with your network traffic. I am going to explain a basic approach that you may want to use if you are creating a DMZ for the first time. This approach works well when you have several VLANs/networks because you do not have to manually add a new network IP address range to isolate each network every time you create a new VLAN/network.
The general idea is this: allow DNS traffic through the network interface/gateway, block any DNS traffic to internal/external networks, allow specific traffic to devices on other internal networks, and allow external network access (to the Internet) while blocking internal network access (to isolate local networks).
For the last “allow all other” rule, this is where you could get more strict than my example by allowing only specific types of traffic such as HTTP/HTTPS, etc. but if you access a lot of services on many different ports, it could take some time to determine everything you need to allow. For home networks, it is easier to start with allowing all ports and then tighten them down later once you determine which ports you really need to open.
The firewall rules should be ordered from the most specific rules to the most general rules since the rules are evaluated from the top to the bottom of the list. Once a rule is triggered for a given data packet, no further rules are processed for that packet. Depending on what you are allowing or blocking, the order is very important.
Below is a basic set of rules you may want to implement for the DMZ network which provides isolation between the DMZ and the LAN. The DMZ network cannot access anything in the LAN network so that protects you from attacks originating from the DMZ.
- Allow access to DNS server on DMZ network interface
- Block access to all other DNS servers
- Allow access to all external networks and block all internal networks for local network isolation
For the LAN network, you need to have a similar set of rules. For illustration purposes, I am going to assume you have a web server in your DMZ that you want clients in your LAN to access so the LAN will have an additional rule to allow network traffic to the web server. The idea is to limit access as much as possible so the only connection allowed to the DMZ from the LAN will be to the web server.
- Allow access to DNS server on LAN network interface
- Block access to all other DNS servers
- Allow access to web server in DMZ for HTTPS
- Allow access to all external networks and block all internal networks for local network isolation
To minimize repetition, I will only describe the DMZ rules except for the one LAN rule to access the DMZ web server since the rules are nearly identical. You simply change the interface in the firewall rules depending on which interface you are creating rules. So let us get started!
Allow access to DNS server on DMZ network interface
To allow access to your OPNsense Unbound DNS server, you need to allow port 53 on the “DMZ address”. You do not need to allow access to your router’s IP (of 192.168.1.1, for example) for DNS since each device is assigned the network interface as the gateway address via DHCP. The “DMZ address” in our example is 192.168.20.1, but you can use the built-in firewall alias of “DMZ address” to reference the interface without needing to specify the IP address.
|Destination Port||53 (DNS)|
|Description||Allow access to DNS server|
Block access to all other DNS servers
If you want to control access to DNS for DNS filtering/blocking, you will need to prevent rogue users or devices from using an alternate DNS server. This rule blocks all other DNS servers so only the local Unbound DNS server can be used (except if the DNS lookups are encrypted via DNS over HTTPS). There may be devices which have hardcoded Google DNS servers and if you block it, they will fail to resolve. To resolve that issue, you can redirect DNS to your local DNS server. Keep in mind it may not be possible to redirect/block every unwanted DNS request especially if encryption is being used, but every little bit of protection you can put in place is worth the effort since it adds more layers of defense that must be overcome by an adversary.
|Destination Port||53 (DNS)|
|Description||Block access to all other DNS servers|
Allow access to all external networks and block all internal networks for local network isolation
To isolate the DMZ network from the other internal networks, you need to block access to all other internal networks. The easiest way is to block all private IP address ranges using a firewall alias because if you add any new networks, you do not need to update your list of networks to block in your alias. This ensures that you do not forget to block any new networks that you create so it is a good safeguard for keep your network secure.
|Destination / Invert||checked|
|Destination||PrivateNetworks (alias with the private address ranges)|
|Description||Allow access to Internet and block access to all local networks|
For this rule you need to check the box for “Destination / Invert” because you want to “allow not local addresses” which means allow any other networks except for the local networks – essentially providing access to all external networks, which would be the Internet.
The “Destination” makes use of a firewall rule alias called “PrivateNetworks”. You will not see “PrivateNetworks” as an option in your rules until you first create the alias. Aliases are necessary when you want to specify multiple values in the same rule, and they are reusable. As a bonus, your rules will be easier to read and maintain since you can create fewer rules. Without aliases, you would have to create a separate rule with each individual value so this rule would have to be 3 rules instead of 1 rule.
To create an alias, go to the “Firewall > Aliases” page and click the “+” button in the bottom right corner of the alias list table. Enter a name such as “PrivateNetworks”. You will wan to pick “Network(s)” as the “Type”. Enter 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 as the networks. This includes the entire IPv4 private IP address ranges.
And now for the LAN rule…
Allow access to web server in DMZ for HTTPS for the LAN network
The following rule allows any device in the LAN network to access the web server in the DMZ with the IP address 192.168.20.10. I recommend creating an alias for your server if you plan to reference it in several rules. If you have multiple services hosted on the same server but on different ports, you can create an alias with multiple ports. You would then use the alias rather than a specific port number. Using the alias eliminates the need to create 3 separate rules for 3 different port numbers. The same approach can be taken if you have multiple web servers. You can put them all in the same rule using aliases.
|Description||Allow access to web server in DMZ network|
Now you should have a fully functioning DMZ network! Keep in mind that this configuration, while more secure than a flat, single LAN network, is still more vulnerable to an attack than a more advanced DMZ with 2 separate firewalls. However, for a more advanced home network with a secure platform like OPNsense which receives regular security updates, this DMZ approach should be adequate for most users’ home networking needs!