Network Segmentation with VLANs on Linux

Virtual Local Area Networks (VLANs) provide logical network segmentation, allowing you to partition a single physical network into multiple isolated broadcast domains. This guide covers implementing 802.1Q VLAN tagging on Linux servers, configuring VLAN interfaces with ip-link, using Netplan for persistent configuration, implementing inter-VLAN routing, and securing communication between segments with firewall rules.

Table of Contents

System Requirements

VLAN support requires specific kernel features and network configuration:

  • Linux kernel with 8021q module (loaded or built-in)
  • Network interface capable of VLAN tagging
  • Root access for network configuration
  • Layer 2 switch supporting 802.1Q tagging (for multi-device networks)
  • Basic networking knowledge

Verify VLAN support:

lsmod | grep 8021q
modprobe 8021q
ip link show | grep vlan

802.1Q VLAN Basics

802.1Q is the standard protocol for VLAN tagging. It adds a 4-byte tag to Ethernet frames, allowing multiple VLANs over a single physical link.

Tag structure:

  • TPID (Tag Protocol Identifier): 0x8100
  • Priority Code Point (PCP): 3 bits (0-7)
  • Canonical Format Indicator (CFI): 1 bit
  • VLAN ID (VID): 12 bits (0-4094, usable 1-4094)

Example VLAN IDs:

VLAN 100: Management/Admin
VLAN 200: Production Services
VLAN 300: Development
VLAN 400: Guest Network
VLAN 500: Security Monitoring

Physical Setup

Configure the physical network infrastructure for VLAN support.

Network topology:

Switch (VLAN-capable)
  |
  +-- Server (eth0, tagged)
  |     |
  |     +-- eth0.100 (VLAN 100)
  |     +-- eth0.200 (VLAN 200)
  |     +-- eth0.300 (VLAN 300)
  |
  +-- Firewall
  +-- Access Point

Configure switch port as VLAN trunk:

Switch Configuration (example for Cisco-like):
interface GigabitEthernet1/0/1
  switchport mode trunk
  switchport trunk allowed vlan 100,200,300,400,500
  no shutdown

Set native VLAN on trunk:

switchport trunk native vlan 1

Configure access ports for specific VLANs:

interface GigabitEthernet1/0/2
  switchport mode access
  switchport access vlan 200
  no shutdown

Use ip-link commands to create and manage VLANs.

Verify physical interface:

ip link show eth0

Create a VLAN interface:

sudo ip link add link eth0 name eth0.100 type vlan id 100
sudo ip link add link eth0 name eth0.200 type vlan id 200
sudo ip link add link eth0 name eth0.300 type vlan id 300

Bring up VLAN interfaces:

sudo ip link set eth0.100 up
sudo ip link set eth0.200 up
sudo ip link set eth0.300 up

Assign IP addresses to VLAN interfaces:

# Management VLAN (VLAN 100)
sudo ip addr add 192.168.100.10/24 dev eth0.100

# Production VLAN (VLAN 200)
sudo ip addr add 192.168.200.10/24 dev eth0.200

# Development VLAN (VLAN 300)
sudo ip addr add 192.168.300.10/24 dev eth0.300

Verify VLAN configuration:

ip link show | grep vlan
ip addr show | grep vlan

View VLAN statistics:

cat /proc/net/vlan/eth0.100
cat /proc/net/vlan/config

Delete VLAN interfaces:

sudo ip link del eth0.100
sudo ip link del eth0.200

Netplan Configuration

Make VLAN configuration persistent using Netplan (Ubuntu/Debian).

Edit Netplan configuration:

sudo nano /etc/netplan/99-vlans.yaml

Create VLAN configuration:

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: no
      
  vlans:
    eth0.100:
      id: 100
      link: eth0
      addresses:
        - 192.168.100.10/24
      routes:
        - to: 0.0.0.0/0
          via: 192.168.100.1
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]
        
    eth0.200:
      id: 200
      link: eth0
      addresses:
        - 192.168.200.10/24
      gateway4: 192.168.200.1
      
    eth0.300:
      id: 300
      link: eth0
      addresses:
        - 192.168.300.10/24
      gateway4: 192.168.300.1

Apply configuration:

sudo netplan apply

Verify configuration:

sudo netplan try
ip addr show
ip route show

Make permanent:

sudo netplan apply

For complex multi-interface setup:

network:
  version: 2
  renderer: networkd
  
  ethernets:
    eth0:
      dhcp4: no
    eth1:
      dhcp4: no
      
  vlans:
    # VLAN 100 across eth0 and eth1
    eth0.100:
      id: 100
      link: eth0
      addresses:
        - 192.168.100.10/24
        
    eth1.100:
      id: 100
      link: eth1
      addresses:
        - 192.168.101.10/24
        
    # VLAN 200 across eth0 and eth1
    eth0.200:
      id: 200
      link: eth0
      addresses:
        - 192.168.200.10/24
        
    eth1.200:
      id: 200
      link: eth1
      addresses:
        - 192.168.201.10/24

NetworkManager Setup

Configure VLANs using NetworkManager (alternative to Netplan).

Create VLAN connection:

sudo nmcli connection add type vlan \
  con-name vlan100 \
  vlan.parent eth0 \
  vlan.id 100 \
  ipv4.addresses 192.168.100.10/24 \
  ipv4.gateway 192.168.100.1 \
  ipv4.method manual

Activate connection:

sudo nmcli connection up vlan100

Create additional VLANs:

sudo nmcli connection add type vlan \
  con-name vlan200 \
  vlan.parent eth0 \
  vlan.id 200 \
  ipv4.addresses 192.168.200.10/24 \
  ipv4.gateway 192.168.200.1 \
  ipv4.method manual

sudo nmcli connection add type vlan \
  con-name vlan300 \
  vlan.parent eth0 \
  vlan.id 300 \
  ipv4.addresses 192.168.300.10/24 \
  ipv4.gateway 192.168.300.1 \
  ipv4.method manual

List connections:

nmcli connection show

Show VLAN details:

nmcli connection show vlan100

Modify VLAN settings:

sudo nmcli connection modify vlan100 ipv4.addresses 192.168.100.20/24
sudo nmcli connection up vlan100

Delete VLAN:

sudo nmcli connection delete vlan100

Inter-VLAN Routing

Configure routing between VLANs for controlled inter-VLAN communication.

Enable IP forwarding:

sudo sysctl -w net.ipv4.ip_forward=1

Make permanent:

sudo nano /etc/sysctl.conf

Add:

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

Apply:

sudo sysctl -p

Configure routing between VLANs:

# Route from VLAN 100 to VLAN 200
sudo ip route add 192.168.200.0/24 via 192.168.100.1 dev eth0.100

# Route from VLAN 200 to VLAN 300
sudo ip route add 192.168.300.0/24 via 192.168.200.1 dev eth0.200

# Route from VLAN 300 to VLAN 100
sudo ip route add 192.168.100.0/24 via 192.168.300.1 dev eth0.300

Make routes persistent in Netplan:

vlans:
  eth0.100:
    id: 100
    link: eth0
    addresses:
      - 192.168.100.10/24
    routes:
      - to: 192.168.200.0/24
        via: 192.168.100.1
      - to: 192.168.300.0/24
        via: 192.168.100.1

Configure using a routing table:

# Create custom routing table
sudo nano /etc/iproute2/rt_tables

Add:

200 vlan200
300 vlan300

Create policy-based routing:

sudo ip rule add from 192.168.100.0/24 table vlan200
sudo ip route add 192.168.200.0/24 via 192.168.100.1 table vlan200

Verify routes:

ip route show
ip route show table vlan200

Firewall Rules

Secure inter-VLAN communication with firewall rules.

Create firewall rules to control VLAN traffic:

# Drop all inter-VLAN traffic by default
sudo iptables -I FORWARD -j DROP

# Allow VLAN 100 to VLAN 200 on specific ports
sudo iptables -I FORWARD -s 192.168.100.0/24 -d 192.168.200.0/24 -p tcp --dport 3306 -j ACCEPT

# Allow VLAN 200 to VLAN 300 on HTTP
sudo iptables -I FORWARD -s 192.168.200.0/24 -d 192.168.300.0/24 -p tcp --dport 80 -j ACCEPT

# Allow return traffic
sudo iptables -I FORWARD -s 192.168.200.0/24 -d 192.168.100.0/24 -m state --state ESTABLISHED -j ACCEPT

Make rules persistent:

sudo iptables-save > /etc/iptables/rules.v4

Using UFW:

sudo ufw default deny forward

# Allow MySQL from VLAN 100 to VLAN 200
sudo ufw allow in on eth0.100 from 192.168.100.0/24 to 192.168.200.0/24 port 3306

# Allow HTTP from VLAN 200 to VLAN 300
sudo ufw allow in on eth0.200 from 192.168.200.0/24 to 192.168.300.0/24 port 80

Create logging for VLAN traffic:

sudo iptables -I FORWARD -s 192.168.100.0/24 -d 192.168.200.0/24 -j LOG --log-prefix "VLAN100->200: "

View firewall logs:

sudo tail -f /var/log/syslog | grep "VLAN"

VLAN Management

Manage and monitor VLAN configurations.

View all VLAN interfaces:

sudo vlan show
ip -d link show type vlan

Show detailed VLAN information:

cat /proc/net/vlan/config
cat /proc/net/vlan/eth0.100

Monitor VLAN traffic:

# Real-time VLAN traffic
sudo iftop -i eth0.100

# VLAN statistics
ethtool -S eth0 | grep -i vlan

# Bandwidth usage per VLAN
vnstat -i eth0.100
vnstat -i eth0.200

Change VLAN priority (CoS):

# Set priority 5 for VLAN 100
sudo ip link set eth0.100 type vlan egress-qos-map 0:5

Configure VLAN MTU:

# Set jumbo frames for VLAN
sudo ip link set eth0.100 mtu 9000

Verify MTU:

ip link show eth0.100

Troubleshooting

Diagnose VLAN configuration issues.

Verify VLAN exists:

ip link show | grep -E "eth0\.[0-9]+"
grep -E "eth0\.[0-9]+" /proc/net/vlan/config

Check interface status:

ip link show eth0.100
ip addr show eth0.100

Test connectivity between VLANs:

# From VLAN 100 host
ping 192.168.200.1
ping 192.168.200.10

# Check routing
traceroute 192.168.200.10

Debug routing:

# Show all routes
ip route show
ip route show all

# Show routing table lookup
ip route show from 192.168.100.10

Monitor traffic on VLAN:

# Capture VLAN traffic
sudo tcpdump -i eth0.100 -n -A

# Show VLAN-tagged frames on physical interface
sudo tcpdump -i eth0 "vlan 100"

Check firewall rules:

sudo iptables -L FORWARD -n
sudo ufw status verbose

View kernel logs for VLAN issues:

dmesg | grep -i vlan
journalctl | grep -i vlan

Conclusion

VLANs provide powerful network segmentation capabilities on Linux servers without requiring additional hardware. By following this guide, you've implemented 802.1Q VLAN tagging, configured VLAN interfaces using both ip-link and persistent configuration tools, set up inter-VLAN routing for controlled communication, implemented firewall rules for security, and established monitoring for VLAN activity. Proper VLAN design isolates workloads, improves security, and simplifies network management. Whether protecting sensitive production systems or isolating untrusted networks, VLANs are an essential component of modern network security architecture.