Skip to content
LinkState
Go back

It is only a lab is not a security model

Introduction to Containerlab and Corporate Networks

Overview of Containerlab

Containerlab is a lightweight orchestration tool that builds multi‑node lab topologies using Docker, Podman, or containerd runtimes. It defines nodes, links, and management networks in a declarative YAML file (clab.yaml). Each node runs as a container with its own network namespace; inter‑node connectivity is provided by Linux bridges, VLAN‑aware bridges, or MACVLAN interfaces that Containerlab creates on the host. Network engineers frequently use it to validate routing protocols, SD‑WAN overlays, or security policies before pushing changes to production.

Corporate Access VLANs and Network Segmentation

In many enterprises the access VLAN is the Layer‑2 domain that connects end‑user devices (laptops, IP phones, wireless APs) to the distribution layer. By design, an access VLAN should carry only traffic that originates from or is destined for the devices attached to that VLAN, with segmentation enforced at the distribution/core layers (e.g., via VLAN ACLs, port‑based ACLs, or IEEE 802.1X).

A common myth is:

“You can treat a Containerlab fabric as just another host and plug it into a corporate access VLAN without any additional segmentation design.”

This assumes lab traffic will be indistinguishable from ordinary user traffic and that existing port‑level controls will contain it. We test this assumption against container‑based networking realities, policy evaluation order, and ownership boundaries.


Containerlab Architecture and Network Integration

Containerlab Fabric Design and Configuration

Containerlab creates three primary network constructs for each lab:

  1. Management network – a Docker bridge (clab-mgmt) that provides SSH/HTTP access to all nodes.
  2. Point‑to‑point links – Linux veth pairs placed in the appropriate container namespaces, optionally tagged with VLAN IDs via bridge vlan commands.
  3. Shared networks – optional Docker networks (bridge, macvlan, ipvlan) that multiple nodes can attach to, often used to simulate a common LAN segment.

A minimal clab.yaml for a two‑router lab:

name: clab-access-vlan
topology:
  nodes:
    r1:
      kind: linux
      image: alpine:3.19
      exec:
        - ip link set lo up
        - ip addr add 10.0.0.1/24 dev lo
    r2:
      kind: linux
      image: alpine:3.19
      exec:
        - ip link set lo up
        - ip addr add 10.0.0.2/24 dev lo
  links:
    - endpoints: ["r1:eth1", "r2:eth1"]
      # No VLAN tagging – raw L2

When deployed, Containerlab creates a veth pair (veth-r1-eth1<->veth-r2-eth1) and moves each end into the respective container’s network namespace. No VLAN tagging occurs unless explicitly configured.

Integrating Containerlab with Corporate Access VLANs

To attach the lab to an existing corporate access VLAN (e.g., VLAN 20, ID 20, subnet 10.1.20.0/24), engineers often add a host‑side VLAN subinterface and bridge it into a Containerlab node’s interface. Example steps on the host (physical NIC eno1):

# 1. Create VLAN subinterface on the host
sudo ip link add link eno1 name eno1.20 type vlan id 20
sudo ip link set dev eno1.20 up

# 2. Assign an IP (optional for management)
sudo ip addr add 10.1.20.10/24 dev eno1.20

# 3. Create a Linux bridge for the lab
sudo ip link add name br-clab type bridge
sudo ip link set dev br-clab up

# 4. Attach the VLAN subinterface to the bridge
sudo ip link set dev eno1.20 master br-clab

Corresponding clab.yaml snippet:

topology:
  nodes:
    r1:
      kind: linux
      image: alpine:3.19
      net:
        - ipv4_address: 10.1.20.11/24   # placed in br-clab

By default, Containerlab creates its own Docker bridge for each net entry unless an external bridge is referenced via the bridge key (requires the containerlab plugin or manual docker network connect). Without that explicit binding, the node will not be on VLAN 20; it will be isolated in a private Docker bridge, and the host‑side VLAN subinterface will remain unused.

Thus, the myth that “plugging in” is enough fails unless the engineer explicitly couples the Containerlab‑created interfaces to the corporate VLAN bridge.


Security Implications of Containerlab in Corporate Networks

Policy Leakage and Lateral Reach

Policy leakage occurs when traffic that should be confined to the lab traverses corporate policy boundaries because the enforcement point sees the traffic as originating from a trusted host or VLAN.

Scenario:

Because the source IP of the scan is 10.1.20.11 (an address within the trusted access VLAN), the switch’s ACL allows the packets, and the traffic reaches the data‑center without inspection. The lab has effectively leaked policy: the segmentation intended to keep user traffic separate from critical assets is bypassed.

Lateral reach is amplified when the lab uses overlapping IP address space with corporate networks. If the lab inadvertently uses the same subnet as a production VLAN (e.g., both use 10.1.20.0/24), ARP replies from lab nodes can corrupt the corporate MAC‑to‑IP mapping, causing traffic intended for production hosts to be delivered to lab containers—a classic ARP spoofing scenario that exists even without malicious intent.

Ambiguous Ownership and Management

When a Containerlab fabric is tethered to an access VLAN, several administrative boundaries blur:

BoundaryTraditional OwnerContainerlab OwnerPotential Conflict
Physical switch portNetwork Ops (port‑security, 802.1X)Lab engineer (who plugs the cable)Unauthorized MAC‑based bypass if port‑security is disabled for “lab” ports
VLAN IDNetEng (VLAN policy, pruning)Lab engineer (who chooses VLAN ID)VLAN hopping if the lab uses a VLAN not permitted on the trunk
IP address spaceIPAM team (DHCP, static assignments)Lab engineer (static IPs in clab.yaml)Duplicate IP → ARP conflicts, blackholing
Host firewallServer team (iptables/nftables)Lab engineer (privileged containers can modify host netns)Container escape leading to host‑level rule changes
Logging & monitoringSIEM team (NetFlow, sFlow)Lab engineer (may disable logging for speed)Loss of visibility into lab‑generated traffic

Because Containerlab runs containers with privileged capabilities by default (e.g., NET_ADMIN, SYS_MODULE) to manipulate interfaces, a compromised container can alter the host’s networking stack, potentially disabling or re‑configuring the very VLAN bridge that provides the supposed segmentation. This creates a policy ownership ambiguity: who is responsible for ensuring that the host‑side bridge remains in the intended state?


Troubleshooting Common Issues in Containerlab‑Corporate Network Integration

Identifying and Resolving Policy Conflicts

  1. Verify Layer‑2 attachment

    # On host: show bridge FDB entries for the VLAN subinterface
    sudo bridge fdb show dev eno1.20

    Look for MAC addresses of lab nodes. If absent, the lab is not bridged to the VLAN.

  2. Check for IP overlap

    # List all IPv4 addresses assigned to interfaces in br-clab
    sudo ip -4 addr show dev br-clab

    Compare against the corporate IPAM database (e.g., ipam show subnet 10.1.20.0/24).

  3. Inspect switch port ACLs
    On a Cisco Nexus/IOS‑XR switch:

    show access-lists | include VLAN20_IN

    Ensure the ACL does not contain overly permissive permit ip any any entries that would allow lab‑sourced traffic to bypass segmentation.

  4. Detect ARP anomalies

    sudo arp -an | grep 10.1.20.0/24

    Duplicate MACs for the same IP indicate a conflict.

Debugging Network Connectivity and Segmentation Issues


Code and CLI Examples for Secure Containerlab Deployment

Configuring Containerlab with VLAN Segmentation

The following clab.yaml demonstrates a secure attachment to VLAN 20 using an explicit external bridge and enforcing IP address uniqueness via an ipam plugin (illustrative; replace with your actual IPAM integration).

name: clab-secure-access
topology:
  kinds:
    linux:
      image: alpine:3.19
      plugin: bridge          # pulls in the bridge plugin to connect to host bridge
  nodes:
    r1:
      kind: linux
      mgmt_ipv4: 10.1.20.30/24   # optional mgmt IP in the same VLAN
      net:
        - ipv4_address: 10.1.20.31/24
          bridge: br-clab          # forces use of external bridge
    r2:
      kind: linux
      mgmt_ipv4: 10.1.20.31/24
      net:
        - ipv4_address: 10.1.20.32/24
          bridge: br-clab
  links:
    - endpoints: ["r1:eth1", "r2:eth1"]
      # No VLAN tagging on the link; VLAN is handled by the bridge

Host‑side preparation (run once):

# Create the VLAN subinterface
sudo ip link add link eno1 name eno1.20 type vlan id 20
sudo ip link set dev eno1.20 up

# Create the bridge that will hold the VLAN and lab interfaces
sudo ip link add name br-clab type bridge
sudo ip link set dev br-clab up

# Attach the VLAN subinterface to the bridge
sudo ip link set dev eno1.20 master br-clab

# (Optional) Enable VLAN filtering on the bridge to prevent VLAN hopping
sudo bridge vlan add dev br-clab vid 20 pvid untagged self
sudo bridge vlan del dev br-clab vid 1   # remove default VLAN 1

Implementing Network Policies and Access Controls

Assuming corporate policy is enforced by an nftables firewall on the distribution layer, add a rule that explicitly denies traffic sourced from the lab’s subnet unless it matches an approved service list.

# nftables snippet (place in /etc/nftables.conf)
table ip filter {
    chain forward {
        type filter hook forward priority 0; policy drop;

        # Allow legitimate user traffic from access VLAN to data center (HTTPS/HTTP)
        ip saddr 10.1.20.0/24 ip daddr 10.100.0.0/16 tcp dport { 443, 80 } accept

        # Explicitly block any other traffic from the lab subnet
        ip saddr 10.1.20.0/24 drop
    }
}

If the lab needs to reach a specific internal service (e.g., a monitoring endpoint at 10.100.10.5:9100), add an exception:

        ip saddr 10.1.20.0/24 ip daddr 10.100.10.5/32 tcp dport 9100 accept

Validation test:

# From r1 container, try to reach a prohibited port
docker exec -it clab-secure-access-r1-1 nc -zv 10.100.0.5 22
# Expected: connection timed out (blocked by nftables)

# From r1 container, try to reach allowed monitoring port
docker exec -it clab-secure-access-r1-1 nc -zv 10.100.10.5 9100
# Expected: connection succeeded

Scaling Limitations and Considerations for Containerlab in Corporate Environments

Performance and Resource Constraints

Mitigation:

Scalability and High Availability in Large‑Scale Deployments

Containerlab itself is stateless; the YAML file defines the desired state. For high


Share this post on:

Previous Post
Semantic Snapshots for Reliable Post-Change Proof
Next Post
The healthy namespace that fooled the investigation