In computing, a DMZ (demilitarized zone) is a method for separating untrusted traffic from a trusted network. One of the most common implementations of this would be for supporting a publicly accessible server (such as web) on a local internet connection. The server sits in the DMZ and can be accessed from the Internet, but it cannot access the trusted network.
OpenWRT probably needs no introduction, the brilliant open source and community driven Linux based embedded router stack. I run it on my Netgear WNDR3800.
I have an ODRIOD-U3 (little ARM box) running Fedora, which runs a web server. This is what I want to make publicly available in my DMZ.
So, how to create a DMZ in OpenWRT? Some commercial routers have a single button “make a DMZ” and everything is handled behind the scenes for you. Not so with OpenWRT; it’s powerful, transparent, and only does what you tell it to, so we have to create it manually.
My router has a bunch of physical interfaces:
- eth0 (switch)
- eth1 (ethernet)
- wlan0 (wireless card)
- wlan1 (5GHz wireless card)
The eth1 device maps to the physical WAN port on the back of the router. It’s important to note that the physical interfaces may differ from router to router, depending on the chipsets.
The switch (eth0) includes a number of ports, including the four physical ones on the back of the router, a fifth one that’s not used, as well as one that connects to the CPU.
The switch supports VLANs (virtual LANs), and by default OpenWRT puts all of those ports into VLAN 1. This means that physical connections in those four ports at the back are on the same virtual switch and are able to communicate with each other. You can imagine that if I changed the VLAN of one of those ports to VLAN 10, that the device plugged into that port would no-longer be able to communicate with other devices on the switch. This is the basis for our DMZ.
That VLAN 1 actually creates a new interface on the router:
- eth0.1 (VLAN 1)
The configuration of the switch (including the mapping of ports to VLANs) is available under the switch menu, Network -> Switch.
Note: The port numbers on the switch in OpenWRT do not necessarily map in the right direction to the back of the router. In my case, port 0 on the switch is port 4 on the back of the router.
Creating a new VLAN
The first thing we want to do is create VLAN 10 and then assign one of the ports to that VLAN, removing it from VLAN 1.
- Browse to Network -> Switch
- Click Add to make a new VLAN entry
- Set this new entry’s VLAN ID to 10
- In the VLAN 1 row, change Port 0 to off
- In the VLAN 10 row, change Port 0 to untagged
- In the VLAN 10 row, change CPU port to tagged
Setting VLAN to untagged tells the switch to add the appropriate VLAN tag to each ethernet frame as the traffic exits that port. The setting tagged means that the switch should expect that traffic leaving the port has already been tagged, perhaps by the operating system running on the device which is attached to the port.
Port 0 (port 4 on the back of the router) is now in VLAN 10, while the remaining three ports are in VLAN 1 and so it is now isolated from the others. The CPU is also in VLAN 10, else we would not be able to pass any traffic to port 0.
That new VLAN 10 creates a new interface on the router:
- eth0.10 (VLAN 10)
In OpenWRT you create virtual network interfaces which map to physical devices on the router. These are available under the Network -> Interfaces menu.
For example, my router has:
- LAN (for my internal local area network)
- WAN (for the external Internet connection)
One or more physical devices are attached to these zones, for example in my case:
- LAN (bridges VLAN 1 eth0.1, wlan1 and wlan0 together)
- WAN (eth1)
The LAN bridge creates a new interface on the router:
- br-lan (bridged LAN)
Creating a new interface
Once we have created our new VLAN, we want to create a new a interface for the DMZ. In the same way that the VLAN 1 device, eth0.1, is attached to the LAN interface, we will attach VLAN 10 device, eth0.10, to our new DMZ interface.
- Browse to Network -> Interfaces
- Click Add New Interface to make a new DMZ zone
- Set the name of the new interface to DMZ
- Leave the protocol of the new interface to static
- Ensure bridge over multiple interfaces remains unchecked
- For the interface, select only VLAN Interface: “eth0.10”
- Click Submit
You should be presented with a new configuration screen for this interface.
- Set IPv4 address to something in a new range different to LAN, e.g. if your LAN is 192.168.1.1 then set DMZ to 192.168.0.1
- Leave the rest of the settings blank, you do not need to set routes, or IPv6 if you don’t want to
- Click on the Advanced Settings tab
- Ensure Bring up on boot is ticked
- If you don’t want IPv6, untick Use builtin IPv6-management
- Click on the Physical Settings tab, should already be set to eth0.10
- Click on the Firewall Settings tab
- Under Create / Assign firewall-zone select unspecified -or- create and type dmz
- Click Save and Apply
- If you want to run DHCP on your DMZ, then under DHCP Server click Setup DHCP Server button, leave default settings
We now have a new interface or zone called for the DMZ that’s set to use out DMZ VLAN. It has a new firewall policy assigned to it, dmz, which we now need to configure.
Now we need to configure the firewall to do a few things:
- Allow the DMZ to talk to the WAN zone, so that devices can access the Internet
- Allow the LAN zone to talk to the DMZ, but not the other way around
- Add some traffic rules opening ports 53 and 67, so that devices from the DMZ can access DNS and DHCP services on the router’s DMZ IP address
- Finally, forward the HTTP port (80) from external internet WAN interface onto a device in the DMZ
Let’s do zone settings first.
- Browse to Network -> Firewall
- Under the Zones section on General Settings page, edit the dmz zone
- Leave the name set to dmz
- Set input to reject, so that we drop all incoming packets by default
- Leave output as accept, although you could set this to reject by default but you’ll require specific outgoing rules as required (like for Yum updates)
- Leave Masquerading and MSS clamping disabled
- Under Covered networks ensure that only dmz is selected
- Under the section Inter-Zone Forwarding, ensure Allow forward to destination zones is set only to WAN
- ensure Allow forward from source zones is set only to LAN
- Click Advanced Settings tab
- If you don’t want IPv6, you can set Restrict to address family to IPv4 only
- Tick Enable logging on this zone, so that we can see what’s happening
Now let’s do port forwards.
- Click on the Port Forwards tab
- Under New port forward section, give a name, such as dmz-http
- Set Protocol to TCP
- Set External zone to WAN
- Set External port to 80
- Set Internal zone to DMZ
- Set Internal IP address to your DMZ server, e.g. 192.168.0.100
- Set Internal port to 80
- Click Add when you’re happy
- Repeat for HTTPS port 443 if you want to run a secure server
Finally, let’s finish with traffic rules.
- Click on the Traffic Rules tab
- Under Open ports on router, set a name like dhcp-dns
- Under Protocol, select UDP
- Under Port, set 53
- Click Add
- Find your new rule in the list and click edit
- Set Destination address to your router’s DMZ IP address
- Repeat for DHCP port 67 UDP if you want to use router’s DHCP server, but don’t set the destination address as DHCP is broadcast
If you want to be able to ping the router from the DMZ clients, do this.
- Set a name like ping-dmz
- Set protocol to Other
- Click Add
- In the new configuration page, set Protocol to ICMP
- Set Match ICMP type to echo reply
- Set Source zone to dmz
- Leave Destination zone to Device (input)
- Set Destination address to your router’s DMZ IP address
- Click Save
Checking the logs
Remember we told the router to log the DMZ? Well now we can monitor the firewall rules by browsing to Status -> Kernel Log. Here you should be able to see any rejects that are happening, which is useful to work out why something isn’t happening as you expect on the DMZ.
For example, disable the dmz-ping rule and then try to ping the router from your DMZ server. Refresh the Kernel Log and you should see entries appear.
Plug in a device, see if it gets an IP address. Try to ping 126.96.36.199 (Google DNS server), then try to ping google.com.
Set up a web server on your DMZ box, or use netcat to listen on port 80. Get your external IP address from the router, or Google “my ip”. Now get a friend to browse to your IP and see if you see your web server.