VLANs in Linux

Suffice to say I’m migrating a bunch of virtual systems from systems with two Ethernet ports to one with a single Ethernet port.  Pick an excuse, any excuse (lower power, faster CPU, cheaper to use, etc.) – that’s probably why.

The problem I have now is how do I segregate traffic from the public facing side to that of where the storage/LDAP/DNS/servers live?  The answer is VLANS.

Not being a network person (but having a bit of time to look into the problem) I knew I needed a few things, a managed switch being one of the key parts.  In this case it’s being provided by a ZyXEL 16-port switch.  It’s not much, but it gives me the capability of setting up VLANs.

The public VLAN in this case is just the connection to the ISP’s router and a few other devices that are on that subnet we get from them.  The internal devices have to be able to talk to each other.  This is easy enough to simulate using the switch and a collection of Raspberry Pis running Raspbian (any Linux should do, these directions will be Debian-based so should work for any of the variants with minimal changes).

In our example here, the public network is and the internal network is

First we set up the switch.  There’s three ports that I’ll work with – one for the public network, one for the servers, one for the internal network.  The ports for the public network aren’t changed.  This allows any current traffic to other devices on the public network (NAT devices for example) to continue running uninterrupted.

Next is the internal server ports.  In this case, they do need to be modified so that connections into the switch get tagged with our VLAN.  Tagging has to do with inserting a VLAN tag into the Ethernet packet (see Wikipedia for more on what this looks like).  Tagging can come from one of two locations – the system itself, or from the switch.  In the case of systems on the internal network, we don’t want to have the individual systems to do the tagging as otherwise we’d have to modify every system on that subnet and make sure that every new device has tagging enabled. So instead it gets turned on at the switch.  

Lastly we have our server that needs to straddle both VLANs.  It needs to signify which VLAN gets what traffic – remember that VLANs happen at the Ethernet layer and not IP, so it doesn’t care about subnets.  There’s two VLANs that go to this port, and on this server we’ll have the server do the tagging rather than the switch.

In this example, port 1 goes to the public network, port 15 is the server, and port 16 goes on to the internal VLAN.  On the switch, there’s two VLANs – the default one that exists on every managed switch, and what we’ll call VLAN 100 to represent the  There’s no requirement there be a connection between the VLAN number and anything else, and there’s a limit of 4094 VLANs that can be created since the VID is 12 bits long and the first and last VIDs are reserved.

Port 1 and all the other ports have no changes.

Port 16 with the internal VLAN is set to be untagged on VID 100.  We’ll also set the PVID for this port to be 100.  Any traffic that comes into the switch from this port will get tagged to be on VLAN 100.  Any traffic that leaves the switch via that port gets the VID removed.  For security purposes, you can exclude traffic from the default VLAN for that port.

Here’s how port 16 looks with a PVID of 100. Any traffic that comes into the switch from this port will be assumed to be on VLAN 100.

Port 15 on our server gets put onto both the public and internal VLANs.  For VLAN 0, there’s no change.  Any traffic that comes into the switch without a VLAN tag gets put onto the default VLAN (the public one).  For VLAN 100, we set it as Tagged, meaning that the server will tell the switch if there’s another VLAN to send traffic to.  The switch will add or remove tags as necessary before sending the packet out the respective ports.

Tagged (port 15) and untagged (port 16)
Tagged (port 15) and untagged (port 16)

On the server, there’s no change to eth0.  Traffic that goes out that interface goes to the default VLAN and gets sent to the public network.  For the internal VLAN, we need to create a new device, eth0.100.  We’re still using the physical eth0 device but by adding the .100 at the end it makes sure that when packets go out that device it has VLAN 100 associated with it.  You may need to install the vlan package on Ubuntu/Debian before you can get this to work, but otherwise you can treat it just like any other Ethernet device under Linux.  In Debian, you can just add this into /etc/network/interfaces then raise the interface using ifup eth0.100.

auto eth0.100
iface eth0.100 inet static
     vlan-raw-device eth0

Background Links: