In an earlier post, I describe how I have set up my OpenBSD firewall to retrieve multiple public IPs from my ISP (legally – I pay for 5) and map some of those to internal IPs (1:1 NAT or “binat”). One of the downsides of my solution was that I needed one ethernet interface per public IP, as the ISP identifies DHCP clients by their MAC addresses. So, the firewall would need more than 2 ethernet interfaces, which is not an easy requirement for small form-factor firewalls such as Mini-ITX.
One solution to to overcome this with only two ethernet ports in the firewall is to put a managed switch that supports VLAN tagging between the firewall and the xDSL router. I bought an HP Procurve 1810G-8 which does the job perfectly.
My firewall has now only two interfaces, one is “internal”, connected to my home network (unmanaged) switch, and one is “external”, connected to the HP (managed) switch. The external interface is transporting three different VLANs from the firewall to the switch. The VLANs show up just like normal ethernet interfaces on the firewall, so I basically just needed to rename “em1” to “vlanXXX”, “em2” to “vlanYYY”, etc. in a couple of configuration files.
By default, the VLAN interfaces inherit the MAC address of their parent interface. This is not good for my setup, as the DHCP server would see only one client and thus leasing only one IP address. The solution is to use the ifconfig command to set the MAC addresses to unique values. However, the parent interface will drop the received ethernet frame as it does not know anything about the MAC address on the logical VLAN interface. Solution: create a bridge interface and put the parent interface into the bridge. This is the OpenBSD way to put an interface into “promiscuous” mode where it will receive packets with any MAC address, and then this setup will work. I crudely put these bridge creation commands into /etc/rc script before it calls the /etc/netstart, so that the vlan interfaces work when dhclients are started.
A better solution to this “unique-MAC-address-per-VLAN-interface” problem would be to write some new code into OpenBSD network stack so that the parent interface would check its VLAN interfaces’ MAC addresses as well and no promiscuous mode would be needed in this use case. Chances of this being accepted into OpenBSD code base are so slim (nobody knows me and its probably somehow insecure) that I don’t bother to think about any more than this. If you have commit rights and extra time, please go ahead.
Finally, three ports of the switch are connected to the VDSL router, forwarding untagged ethernet frames towards the ISP. From the ISP and DHCP viewpoint, it looks just like three different machines connected to a subscribers modem. And I continue to have my own firewall which does whatever I want it to do.