Latest / Linux Server Admin with Fexingo: Sysadmin, Bash, and Server Engineering / Linux Server VLAN Tagging with systemd-networkd
Transcript
- Lucas: Alright, let's talk about VLAN tagging on Linux servers — specifically how to set it up with systemd-networkd. Luna: Because the old ways — vconfig, ifcfg scripts — are showing their age. Lucas: Exactly. If you're running a modern distro like Debian 12 or Ubuntu 24.04, systemd-networkd is likely the default network manager, and it handles VLANs in a much cleaner way. Luna: What's the practical use case? Who's actually doing this? Lucas: Think about a multi-tenant web host with a single 10-gigabit NIC. You want to isolate customer traffic into separate broadcast domains — without buying a separate physical interface for each tenant. That's exactly what 802.1Q VLANs are for. Luna: Right, so you tag each packet with a VLAN ID between 1 and 4094, and the switch sorts it out. Lucas: Exactly. And on the server side, you create a virtual interface per VLAN. The old way was using the `vconfig` command or writing ifcfg-vlan files. But with systemd-networkd, it's all declarative — you drop a couple of files in /etc/systemd/network/. Luna: Let's do a concrete example. Suppose I have physical interface enp1s0 and I want VLAN 100 for customer A and VLAN 200 for customer B. Lucas: Good. First, make sure the physical interface itself is configured. You create a.network file for enp1s0 — say, 10-enp1s0.network — with just the basics: match on the interface name, and maybe you want to keep the physical interface itself without an IP if it's just acting as a parent. Luna: So no Address= line on the parent. Just link up. Lucas: Correct. Then you create two.netdev files — one per VLAN. For VLAN 100, you'd create a file like 20-vlan100.netdev. The content is minimal: name=vlan100, kind=vlan. Then a section with Id=100 and link=enp1s0. Luna: And that's it? systemd-networkd creates the virtual interface? Lucas: It creates it on boot, yeah. But you also need a.network file for each VLAN to assign an IP. So you'd create 30-vlan100.network with name=vlan100 and Address=192.168.100.1/24. Luna: So the pattern is: one.netdev to define the VLAN device, and one.network to assign the IP. That's per VLAN. Lucas: Exactly. And you can actually combine the.netdev and.network into one file if you use the section inside the.network file — but I prefer keeping them separate for clarity. Luna: What about the switch side? It has to be configured for trunk mode, right? Lucas: Right. The switch port connected to the server must be in trunk mode and allow VLANs 100 and 200. Otherwise, packets get dropped. That's the other half of the equation. Luna: Let's talk about verification. How do you know it's working? Lucas: First, `networkctl list` will show both vlan100 and vlan200 as 'routable' if they have IPs. Second, `ip -d link show vlan100` will show the VLAN ID. And ping tests between the server and a client on the same VLAN should just work. Luna: I've seen cases where the VLAN interface comes up but traffic doesn't flow — usually it's MTU mismatch or the switch not tagging correctly. Lucas: MTU is a good call. If the physical interface has an MTU of 1500, the VLAN interface inherits that, but the 4-byte VLAN tag pushes the frame to 1504 bytes. Some switches or endpoints might not handle that — you might need to set the physical interface to MTU 1504 or higher. Luna: Or use jumbo frames end to end, but that's another topic. Lucas: Yeah, we'll save that for a future episode. Another common gotcha: systemd-networkd won't create the VLAN interface if the parent interface isn't up. So make sure enp1s0 is actually link-up before relying on the VLAN. Luna: I've also had issues where NetworkManager was still managing the physical interface, and it interfered. You have to either disable NetworkManager for that interface or use nmcli to create the VLANs. Lucas: Right — if you're running NetworkManager alongside systemd-networkd, you can tell NM to ignore the interface with a configuration in /etc/NetworkManager/conf.d/. But the cleanest approach is to use systemd-networkd exclusively. Luna: Let's talk about a more advanced scenario: what about VLAN stacking, or Q-in-Q? Lucas: systemd-networkd supports that too. You can create a VLAN on top of another VLAN. The.netdev file would have kind=vlan and the parent link would be the first VLAN interface. But that's niche — most of us will only need single tagging. Luna: Fair. And what about bridge interfaces? Can you attach VLANs to a bridge? Lucas: Absolutely. That's common in virtualization. You create a bridge, then create VLAN interfaces with the bridge as parent, or you use the bridge's VLAN filtering feature. systemd-networkd handles that with the section. Luna: I think the big takeaway here is that systemd-networkd makes VLAN configuration transparent and version-controllable. You can store those.netdev and.network files in your dotfiles or Ansible repo. Lucas: Exactly — it's infrastructure as code. No more SSHing into a server and running ad-hoc vconfig commands that get lost on reboot. Luna: One last tip: always test with a trunk port and a known working client before cutting over. I've burned an afternoon debugging a typo in a.network file. Lucas: Yeah, I've been there. Use `networkctl reload` after changing files, then `networkctl status vlan100` to check for errors. And check the journal with `journalctl -u systemd-networkd`. Luna: Honestly, if this episode saved you from one late-night debug session, that's probably worth the price of a coffee. Lucas: That's actually a good point. If today's tech conversation gave you something usable, there's a link: buy me a coffee dot com slash fexingo. Keeps the show ad-free and covers the server costs. Luna: No pressure — just if it made your day easier. But yeah, every little bit helps. Lucas: So, to wrap up: VLAN tagging with systemd-networkd is clean, declarative, and reliable. Pair it with a properly trunked switch port and you can segment your network without extra hardware. Luna: And remember to test with `ping` and `tcpdump` — because the network isn't real until the packets actually flow. Lucas: Good note. Next time we'll talk about bonding — combining multiple physical interfaces into one logical link for redundancy or throughput. See you then.