Network Namespaces & VRF - Virtual Network Isolation for Raspberry Pi
Introduction
Network namespaces and VRF (Virtual Routing and Forwarding) are powerful Linux kernel features that enable complete network isolation on a single device. They allow you to run multiple independent network stacks, each with its own routing tables, firewall rules, and network interfaces - all on one Raspberry Pi.
This technology enables sophisticated networking scenarios that were previously impossible without multiple physical devices:
- Multiple VPN Connections: Connect to different VPNs simultaneously without conflicts
- Network Segmentation: Isolate IoT devices, guest networks, and production services
- Testing Environments: Test network configurations without affecting your main network
- Multi-Tenant Systems: Run separate network environments for different users or services
- Container Networking: Foundation of Docker, Kubernetes, and LXC networking
- Security Isolation: Prevent network-based attacks from spreading between services
- Traffic Engineering: Route different applications through different network paths
This comprehensive guide covers:
- Network Namespaces: Create isolated network environments with separate interfaces and routing
- VRF (Virtual Routing and Forwarding): Multiple routing tables for traffic separation
- Virtual Ethernet (veth) Pairs: Connect namespaces and create virtual networks
- Network Bridges: Build complex virtual network topologies
- VPN Segmentation: Route different traffic through different VPN tunnels
- Container Integration: Understand Docker and Kubernetes networking fundamentals
- Practical Applications: Multi-VPN gateway, isolated test networks, secure IoT segments
- Performance Tuning: Optimize virtual networking for Raspberry Pi
Perfect for:
- Network Engineers: Advanced routing and traffic engineering
- Security Professionals: Network isolation and segmentation
- DevOps Engineers: Container networking and multi-environment setups
- VPN Users: Multiple simultaneous VPN connections with policy routing
- IoT Developers: Isolate untrusted devices on separate networks
- System Administrators: Complex network topology management
- Homelab Enthusiasts: Professional networking features on consumer hardware
Understanding Network Namespaces
What is a Network Namespace?
A network namespace is a Linux kernel feature that provides complete isolation of network resources. Each namespace has:
- Network interfaces: Separate set of physical and virtual interfaces
- IP addresses: Independent IP address assignments
- Routing tables: Isolated routing decisions
- Firewall rules: Separate iptables/nftables configurations
- Network statistics: Independent /proc/net entries
- Port bindings: Same port can be used in different namespaces
Default Network Namespace
| # Every Linux system starts with one default namespace
# All processes run in this namespace unless moved
# View current namespace
ip netns identify $$
# (empty output = default namespace)
# List all network namespaces
ip netns list
# (empty if no custom namespaces created)
# View interfaces in default namespace
ip link show
# View routing table
ip route show
# View firewall rules
sudo iptables -L -n
|
Network Namespace Architecture
| ┌─────────────────────────────────────────────────────────────┐
│ Physical Raspberry Pi │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Default Namespace │ │ Namespace "red" │ │
│ │ │ │ │ │
│ │ eth0: 192.168.1.10│ │ veth-red: 10.1.0.2│ │
│ │ wlan0: DHCP │ │ Routing: custom │ │
│ │ lo: 127.0.0.1 │ │ iptables: custom │ │
│ │ │ │ │ │
│ │ Routing: main │ │ ┌──────────────┐ │ │
│ │ iptables: main │ │ │Process A │ │ │
│ │ │ │ │(runs in red) │ │ │
│ │ ┌──────────────┐ │ │ └──────────────┘ │ │
│ │ │Default │ │ │ │ │
│ │ │processes │ │ └─────────────────────┘ │
│ │ └──────────────┘ │ │
│ └─────────────────────┘ ┌─────────────────────┐ │
│ │ Namespace "blue" │ │
│ │ │ │
│ │ veth-blue: 10.2.0.2│ │
│ │ Routing: custom │ │
│ │ iptables: custom │ │
│ │ │ │
│ │ ┌──────────────┐ │ │
│ │ │Process B │ │ │
│ │ │(runs in blue)│ │ │
│ │ └──────────────┘ │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
|
Creating and Managing Network Namespaces
Basic Namespace Operations
| # Create a network namespace
sudo ip netns add red
# List all namespaces
ip netns list
# Output: red
# Create multiple namespaces
sudo ip netns add blue
sudo ip netns add green
# View all namespaces
ip netns list
# Output:
# green
# blue
# red
# Delete a namespace
sudo ip netns delete green
# Execute command in namespace
sudo ip netns exec red ip addr show
# Shows only lo interface (loopback), down by default
# Start bash shell in namespace
sudo ip netns exec red bash
# Now you're inside the "red" namespace
# Exit with 'exit' command
|
Namespace Isolation Demonstration
| # Create test namespace
sudo ip netns add isolated
# Compare interface lists
echo "=== Default Namespace ==="
ip link show
echo "=== Isolated Namespace ==="
sudo ip netns exec isolated ip link show
# Only shows 'lo' (loopback), nothing else
# Try to ping from isolated namespace (will fail - no connectivity)
sudo ip netns exec isolated ping 8.8.8.8
# Error: Network is unreachable
# Bring up loopback in namespace
sudo ip netns exec isolated ip link set lo up
# Now can ping localhost
sudo ip netns exec isolated ping -c 3 127.0.0.1
# Works!
# But still no external connectivity
sudo ip netns exec isolated ping -c 1 8.8.8.8
# Error: Network is unreachable
|
Virtual Ethernet (veth) Pairs
veth pairs are virtual network cables - what goes in one end comes out the other.
Creating veth Pairs
| # Create a veth pair
sudo ip link add veth0 type veth peer name veth1
# Both ends are in default namespace initially
ip link show | grep veth
# veth0@veth1: ...
# veth1@veth0: ...
# Move one end to a namespace
sudo ip link set veth1 netns red
# Now veth1 only visible in 'red' namespace
ip link show | grep veth
# Only shows veth0
sudo ip netns exec red ip link show
# Shows both lo and veth1
|
Connecting Namespace to Default Network
| # Create namespace
sudo ip netns add red
# Create veth pair
sudo ip link add veth-red type veth peer name veth-red-br
# Move one end to namespace
sudo ip link set veth-red netns red
# Configure namespace side
sudo ip netns exec red ip addr add 10.1.0.2/24 dev veth-red
sudo ip netns exec red ip link set veth-red up
sudo ip netns exec red ip link set lo up
# Configure default namespace side
sudo ip addr add 10.1.0.1/24 dev veth-red-br
sudo ip link set veth-red-br up
# Test connectivity
ping -c 3 10.1.0.2
# Success!
# From namespace to default
sudo ip netns exec red ping -c 3 10.1.0.1
# Success!
|
Adding Internet Access to Namespace
| # Add default route in namespace
sudo ip netns exec red ip route add default via 10.1.0.1
# Enable IP forwarding on host
sudo sysctl -w net.ipv4.ip_forward=1
# Add NAT (masquerade) for namespace traffic
sudo iptables -t nat -A POSTROUTING -s 10.1.0.0/24 -o eth0 -j MASQUERADE
# Allow forwarding
sudo iptables -A FORWARD -i veth-red-br -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o veth-red-br -m state --state RELATED,ESTABLISHED -j ACCEPT
# Test internet from namespace
sudo ip netns exec red ping -c 3 8.8.8.8
# Success!
sudo ip netns exec red curl -s https://ifconfig.me
# Shows public IP
|
Network Bridges for Complex Topologies
Creating a Bridge
| # Create a bridge
sudo ip link add br0 type bridge
# Bring it up
sudo ip link set br0 up
# Assign IP to bridge
sudo ip addr add 10.10.0.1/24 dev br0
|
Connecting Multiple Namespaces via Bridge
| #!/bin/bash
# multi-namespace-bridge.sh
# Create bridge
sudo ip link add br-ns type bridge
sudo ip link set br-ns up
sudo ip addr add 10.100.0.1/24 dev br-ns
# Function to create and connect namespace
create_namespace() {
local NAME=$1
local IP=$2
# Create namespace
sudo ip netns add $NAME
# Create veth pair
sudo ip link add veth-$NAME type veth peer name veth-$NAME-br
# Move one end to namespace
sudo ip link set veth-$NAME netns $NAME
# Configure namespace side
sudo ip netns exec $NAME ip addr add $IP/24 dev veth-$NAME
sudo ip netns exec $NAME ip link set veth-$NAME up
sudo ip netns exec $NAME ip link set lo up
sudo ip netns exec $NAME ip route add default via 10.100.0.1
# Attach bridge side to bridge
sudo ip link set veth-$NAME-br master br-ns
sudo ip link set veth-$NAME-br up
echo "Created namespace: $NAME with IP $IP"
}
# Create multiple namespaces
create_namespace ns1 10.100.0.10
create_namespace ns2 10.100.0.20
create_namespace ns3 10.100.0.30
# Enable forwarding
sudo sysctl -w net.ipv4.ip_forward=1
# Add NAT for internet access
sudo iptables -t nat -A POSTROUTING -s 10.100.0.0/24 -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i br-ns -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o br-ns -m state --state RELATED,ESTABLISHED -j ACCEPT
echo "=== Testing connectivity ==="
# Test namespace to namespace
echo "ns1 -> ns2:"
sudo ip netns exec ns1 ping -c 2 10.100.0.20
echo "ns2 -> ns3:"
sudo ip netns exec ns2 ping -c 2 10.100.0.30
# Test internet access
echo "ns1 -> Internet:"
sudo ip netns exec ns1 ping -c 2 8.8.8.8
echo "Done! All namespaces connected via bridge."
|
VRF (Virtual Routing and Forwarding)
VRF provides multiple routing tables on a single interface, without full namespace isolation.
Understanding VRF vs Network Namespaces
| Feature |
Network Namespace |
VRF |
| Routing Tables |
Separate |
Separate |
| Network Interfaces |
Can be separate |
Shared |
| Firewall Rules |
Separate |
Shared |
| Process Isolation |
Full |
Partial |
| Performance |
Slight overhead |
Minimal overhead |
| Use Case |
Complete isolation |
Traffic separation |
| Complexity |
Higher |
Lower |
Creating VRF Devices
| # Load VRF kernel module (if not already loaded)
sudo modprobe vrf
# Create VRF device
sudo ip link add vrf-red type vrf table 10
sudo ip link set vrf-red up
# Create another VRF
sudo ip link add vrf-blue type vrf table 20
sudo ip link set vrf-blue up
# List VRF devices
ip link show type vrf
|
Assigning Interfaces to VRF
| # Create virtual interfaces for testing
sudo ip link add dummy-red type dummy
sudo ip link add dummy-blue type dummy
# Assign to VRF
sudo ip link set dummy-red master vrf-red
sudo ip link set dummy-blue master vrf-blue
# Configure IPs
sudo ip addr add 10.1.1.1/24 dev dummy-red
sudo ip addr add 10.2.2.1/24 dev dummy-blue
# Bring up
sudo ip link set dummy-red up
sudo ip link set dummy-blue up
# View routing tables
ip route show vrf vrf-red
ip route show vrf vrf-blue
ip route show table 10
ip route show table 20
|
Running Processes in VRF Context
| # Start process in specific VRF
sudo ip vrf exec vrf-red ping 8.8.8.8
# Run server in specific VRF
sudo ip vrf exec vrf-red python3 -m http.server 8080
# Run shell in VRF context
sudo ip vrf exec vrf-blue bash
# All commands now use vrf-blue routing
ping 8.8.8.8
curl https://ifconfig.me
exit
|
Practical Application: Multi-VPN Setup
Scenario: Route Different Traffic Through Different VPNs
| #!/bin/bash
# multi-vpn-setup.sh - Route work and personal traffic through separate VPNs
set -e
echo "=== Setting up Multi-VPN with Network Namespaces ==="
# Create namespaces
sudo ip netns add vpn-work
sudo ip netns add vpn-personal
# Create veth pairs
sudo ip link add veth-work type veth peer name veth-work-br
sudo ip link add veth-pers type veth peer name veth-pers-br
# Move to namespaces
sudo ip link set veth-work netns vpn-work
sudo ip link set veth-pers netns vpn-personal
# Configure work namespace
sudo ip netns exec vpn-work ip addr add 10.200.1.2/24 dev veth-work
sudo ip netns exec vpn-work ip link set veth-work up
sudo ip netns exec vpn-work ip link set lo up
sudo ip netns exec vpn-work ip route add default via 10.200.1.1
# Configure personal namespace
sudo ip netns exec vpn-personal ip addr add 10.200.2.2/24 dev veth-pers
sudo ip netns exec vpn-personal ip link set veth-pers up
sudo ip netns exec vpn-personal ip link set lo up
sudo ip netns exec vpn-personal ip route add default via 10.200.2.1
# Configure host side
sudo ip addr add 10.200.1.1/24 dev veth-work-br
sudo ip addr add 10.200.2.1/24 dev veth-pers-br
sudo ip link set veth-work-br up
sudo ip link set veth-pers-br up
# Enable forwarding
sudo sysctl -w net.ipv4.ip_forward=1
# Setup NAT for each namespace
sudo iptables -t nat -A POSTROUTING -s 10.200.1.0/24 -o eth0 -j MASQUERADE
sudo iptables -t nat -A POSTROUTING -s 10.200.2.0/24 -o eth0 -j MASQUERADE
echo "=== Namespaces created. Now connect VPNs ==="
# Connect VPN in work namespace
echo "Starting work VPN in vpn-work namespace..."
sudo ip netns exec vpn-work openvpn --config /etc/openvpn/work.ovpn --daemon
# Connect VPN in personal namespace
echo "Starting personal VPN in vpn-personal namespace..."
sudo ip netns exec vpn-personal openvpn --config /etc/openvpn/personal.ovpn --daemon
# Wait for VPNs to connect
sleep 10
echo "=== Testing VPN connections ==="
# Check work VPN IP
WORK_IP=$(sudo ip netns exec vpn-work curl -s https://ifconfig.me)
echo "Work VPN IP: $WORK_IP"
# Check personal VPN IP
PERSONAL_IP=$(sudo ip netns exec vpn-personal curl -s https://ifconfig.me)
echo "Personal VPN IP: $PERSONAL_IP"
echo "=== Setup complete! ==="
echo ""
echo "To use work VPN:"
echo " sudo ip netns exec vpn-work <command>"
echo ""
echo "To use personal VPN:"
echo " sudo ip netns exec vpn-personal <command>"
echo ""
echo "Examples:"
echo " sudo ip netns exec vpn-work firefox"
echo " sudo ip netns exec vpn-personal transmission-gtk"
|
DNS Configuration for Separate VPNs
| # Configure separate DNS for each namespace
# Work namespace - use work DNS servers
sudo mkdir -p /etc/netns/vpn-work
sudo tee /etc/netns/vpn-work/resolv.conf <<EOF
nameserver 10.0.0.1 # Work DNS server
nameserver 10.0.0.2
search company.local
EOF
# Personal namespace - use public DNS
sudo mkdir -p /etc/netns/vpn-personal
sudo tee /etc/netns/vpn-personal/resolv.conf <<EOF
nameserver 1.1.1.1
nameserver 8.8.8.8
EOF
# Test DNS resolution
sudo ip netns exec vpn-work nslookup internal.company.local
sudo ip netns exec vpn-personal nslookup google.com
|
Application Launcher for Specific Namespace
| #!/bin/bash
# run-in-vpn.sh - Launch app in specific VPN namespace
NAMESPACE=$1
shift
COMMAND=$@
if [ -z "$NAMESPACE" ] || [ -z "$COMMAND" ]; then
echo "Usage: $0 <namespace> <command>"
echo "Example: $0 vpn-work firefox"
exit 1
fi
# Preserve display for GUI apps
export DISPLAY=:0
export XAUTHORITY=$HOME/.Xauthority
# Run in namespace
sudo -E ip netns exec $NAMESPACE sudo -u $USER -E $COMMAND
|
Usage:
| # Launch Firefox through work VPN
./run-in-vpn.sh vpn-work firefox
# Download file through personal VPN
./run-in-vpn.sh vpn-personal wget https://example.com/file.zip
# Start torrent client in personal VPN
./run-in-vpn.sh vpn-personal transmission-gtk
|
IoT Network Segmentation
Isolated IoT Network with Restricted Access
| #!/bin/bash
# iot-segmentation.sh - Create isolated network for IoT devices
# Create IoT namespace
sudo ip netns add iot-devices
# Create veth pair
sudo ip link add veth-iot type veth peer name veth-iot-br
# Move to namespace
sudo ip link set veth-iot netns iot-devices
# Configure namespace (no default route initially - isolated)
sudo ip netns exec iot-devices ip addr add 192.168.100.2/24 dev veth-iot
sudo ip netns exec iot-devices ip link set veth-iot up
sudo ip netns exec iot-devices ip link set lo up
# Configure host side
sudo ip addr add 192.168.100.1/24 dev veth-iot-br
sudo ip link set veth-iot-br up
# Create bridge for IoT devices
sudo ip link add br-iot type bridge
sudo ip link set br-iot up
sudo ip addr add 192.168.100.254/24 dev br-iot
# Attach veth to bridge
sudo ip link set veth-iot-br master br-iot
echo "=== IoT Network Created ==="
# Setup DHCP server for IoT devices (dnsmasq)
sudo tee /etc/dnsmasq.d/iot-network.conf <<EOF
interface=br-iot
dhcp-range=192.168.100.10,192.168.100.200,12h
dhcp-option=option:router,192.168.100.254
dhcp-option=option:dns-server,192.168.100.254
EOF
sudo systemctl restart dnsmasq
# Firewall rules: IoT devices can only access specific services
# Block IoT -> Internal network
sudo iptables -A FORWARD -i br-iot -d 192.168.1.0/24 -j DROP
# Allow IoT -> Internet (HTTP/HTTPS only)
sudo iptables -A FORWARD -i br-iot -p tcp --dport 80 -j ACCEPT
sudo iptables -A FORWARD -i br-iot -p tcp --dport 443 -j ACCEPT
sudo iptables -A FORWARD -i br-iot -p udp --dport 53 -j ACCEPT
# Allow specific internal service (e.g., Home Assistant)
sudo iptables -A FORWARD -i br-iot -d 192.168.1.100 -p tcp --dport 8123 -j ACCEPT
# NAT for internet access
sudo iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth0 -j MASQUERADE
# Log dropped IoT traffic for monitoring
sudo iptables -A FORWARD -i br-iot -j LOG --log-prefix "IoT-DROP: "
echo "=== IoT Segmentation Complete ==="
echo "IoT devices on br-iot (192.168.100.0/24)"
echo "Restricted to HTTP/HTTPS and specific internal services only"
|
Monitoring IoT Network Traffic
| # Watch IoT network traffic in real-time
sudo tcpdump -i br-iot -n
# Monitor blocked access attempts
sudo tail -f /var/log/kern.log | grep "IoT-DROP"
# View active connections from IoT network
sudo conntrack -L -s 192.168.100.0/24
# Statistics
sudo iptables -L FORWARD -v -n | grep br-iot
|
Container Network Simulation
Understanding Docker Networking with Namespaces
| #!/bin/bash
# docker-like-networking.sh - Simulate Docker bridge networking
# Create bridge (like docker0)
sudo ip link add docker0 type bridge
sudo ip link set docker0 up
sudo ip addr add 172.17.0.1/16 dev docker0
# Function to create "container"
create_container() {
local NAME=$1
local IP=$2
# Create namespace (container)
sudo ip netns add $NAME
# Create veth pair
sudo ip link add veth-$NAME type veth peer name veth-$NAME-br
# Move one end to namespace
sudo ip link set veth-$NAME netns $NAME
# Configure namespace
sudo ip netns exec $NAME ip addr add $IP/16 dev veth-$NAME
sudo ip netns exec $NAME ip link set veth-$NAME up
sudo ip netns exec $NAME ip link set lo up
sudo ip netns exec $NAME ip route add default via 172.17.0.1
# Attach to bridge
sudo ip link set veth-$NAME-br master docker0
sudo ip link set veth-$NAME-br up
echo "Container $NAME created with IP $IP"
}
# Create multiple containers
create_container container1 172.17.0.10
create_container container2 172.17.0.20
create_container container3 172.17.0.30
# Enable forwarding and NAT
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
# Port forwarding (like docker -p 8080:80)
# Forward host port 8080 to container1 port 80
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.10:80
sudo iptables -A FORWARD -p tcp -d 172.17.0.10 --dport 80 -j ACCEPT
echo "=== Docker-like network created ==="
echo "Test container networking:"
echo " sudo ip netns exec container1 ping 172.17.0.20"
echo " sudo ip netns exec container2 curl http://172.17.0.10"
|
Advanced Routing with VRF
Policy-Based Routing with VRF
| #!/bin/bash
# vrf-policy-routing.sh - Route traffic based on source IP using VRF
# Create VRFs
sudo ip link add vrf-isp1 type vrf table 100
sudo ip link add vrf-isp2 type vrf table 200
sudo ip link set vrf-isp1 up
sudo ip link set vrf-isp2 up
# Assume two internet connections: eth0 (ISP1) and eth1 (ISP2)
# Create dummy interfaces for VRF
sudo ip link add dum-isp1 type dummy
sudo ip link add dum-isp2 type dummy
# Assign to VRFs
sudo ip link set dum-isp1 master vrf-isp1
sudo ip link set dum-isp2 master vrf-isp2
sudo ip link set dum-isp1 up
sudo ip link set dum-isp2 up
# Add routes in VRF tables
sudo ip route add default via 192.168.1.1 dev eth0 table 100 # ISP1
sudo ip route add default via 192.168.2.1 dev eth1 table 200 # ISP2
# Policy routing: Route based on source IP
sudo ip rule add from 10.0.1.0/24 table 100 # Subnet A -> ISP1
sudo ip rule add from 10.0.2.0/24 table 200 # Subnet B -> ISP2
# Mark packets and route based on marks
sudo iptables -t mangle -A PREROUTING -s 10.0.1.0/24 -j MARK --set-mark 1
sudo iptables -t mangle -A PREROUTING -s 10.0.2.0/24 -j MARK --set-mark 2
sudo ip rule add fwmark 1 table 100
sudo ip rule add fwmark 2 table 200
echo "Policy routing configured:"
echo " 10.0.1.0/24 -> ISP1 (eth0)"
echo " 10.0.2.0/24 -> ISP2 (eth1)"
|
Load Balancing Across Multiple Connections
| # Create weighted multipath route
sudo ip route add default \
nexthop via 192.168.1.1 dev eth0 weight 1 \
nexthop via 192.168.2.1 dev eth1 weight 1
# This distributes traffic across both connections
# For per-connection (not per-packet) balancing
sudo sysctl -w net.ipv4.fib_multipath_hash_policy=1
|
Testing and Debugging
Comprehensive Network Namespace Test
| #!/bin/bash
# test-namespace-connectivity.sh
test_namespace() {
local NS=$1
local DESC=$2
echo "=== Testing $DESC ($NS) ==="
# Check interfaces
echo "Interfaces:"
sudo ip netns exec $NS ip link show | grep -E '^[0-9]'
# Check IP addresses
echo "IP Addresses:"
sudo ip netns exec $NS ip addr show | grep "inet "
# Check routing
echo "Routes:"
sudo ip netns exec $NS ip route show
# Test connectivity
echo "Connectivity tests:"
# Gateway
GW=$(sudo ip netns exec $NS ip route show default | awk '{print $3}')
if [ ! -z "$GW" ]; then
sudo ip netns exec $NS ping -c 1 -W 2 $GW > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo " ✓ Gateway ($GW) reachable"
else
echo " ✗ Gateway ($GW) unreachable"
fi
fi
# Internet
sudo ip netns exec $NS ping -c 1 -W 2 8.8.8.8 > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo " ✓ Internet (8.8.8.8) reachable"
else
echo " ✗ Internet unreachable"
fi
# DNS
sudo ip netns exec $NS nslookup google.com > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo " ✓ DNS resolution working"
else
echo " ✗ DNS resolution failed"
fi
echo ""
}
# Test all namespaces
for ns in $(ip netns list | awk '{print $1}'); do
test_namespace $ns "$ns"
done
|
Network Tracing
| # Trace packets through namespaces
# In default namespace
sudo tcpdump -i veth-red-br -n
# In namespace
sudo ip netns exec red tcpdump -i veth-red -n
# Trace all bridges
sudo tcpdump -i br-ns -n
# Monitor iptables hits
sudo watch -n 1 'iptables -L -v -n | head -20'
|
| #!/bin/bash
# namespace-performance-test.sh
# Create test namespace
sudo ip netns add perf-test
sudo ip link add veth-perf type veth peer name veth-perf-br
sudo ip link set veth-perf netns perf-test
sudo ip netns exec perf-test ip addr add 10.99.0.2/24 dev veth-perf
sudo ip netns exec perf-test ip link set veth-perf up
sudo ip netns exec perf-test ip link set lo up
sudo ip addr add 10.99.0.1/24 dev veth-perf-br
sudo ip link set veth-perf-br up
echo "=== Performance Tests ==="
# Latency test
echo "Latency (ping):"
sudo ip netns exec perf-test ping -c 100 -i 0.01 10.99.0.1 | tail -3
# Bandwidth test (iperf3)
echo "Starting iperf3 server in namespace..."
sudo ip netns exec perf-test iperf3 -s -D
sleep 2
echo "Bandwidth test:"
iperf3 -c 10.99.0.2 -t 10
# Cleanup
sudo pkill iperf3
sudo ip netns delete perf-test
|
Systemd Integration
Persistent Namespace Setup
| # /etc/systemd/system/netns-vpn-work.service
[Unit]
Description=Network Namespace for Work VPN
After=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/setup-vpn-work-namespace.sh
ExecStop=/usr/local/bin/teardown-vpn-work-namespace.sh
[Install]
WantedBy=multi-user.target
|
Setup script:
| #!/bin/bash
# /usr/local/bin/setup-vpn-work-namespace.sh
set -e
# Create namespace
ip netns add vpn-work
# Create veth pair
ip link add veth-work type veth peer name veth-work-br
# Configure namespace
ip link set veth-work netns vpn-work
ip netns exec vpn-work ip addr add 10.200.1.2/24 dev veth-work
ip netns exec vpn-work ip link set veth-work up
ip netns exec vpn-work ip link set lo up
ip netns exec vpn-work ip route add default via 10.200.1.1
# Configure host
ip addr add 10.200.1.1/24 dev veth-work-br
ip link set veth-work-br up
# Enable forwarding
sysctl -w net.ipv4.ip_forward=1
# NAT
iptables -t nat -A POSTROUTING -s 10.200.1.0/24 -o eth0 -j MASQUERADE
# Start VPN
ip netns exec vpn-work openvpn --config /etc/openvpn/work.ovpn --daemon
echo "Work VPN namespace ready"
|
Teardown script:
| #!/bin/bash
# /usr/local/bin/teardown-vpn-work-namespace.sh
# Kill VPN
ip netns exec vpn-work pkill openvpn || true
# Remove iptables rules
iptables -t nat -D POSTROUTING -s 10.200.1.0/24 -o eth0 -j MASQUERADE || true
# Delete namespace (automatically deletes veth pair)
ip netns delete vpn-work || true
# Remove host veth
ip link delete veth-work-br || true
echo "Work VPN namespace removed"
|
Enable service:
| sudo systemctl enable netns-vpn-work
sudo systemctl start netns-vpn-work
sudo systemctl status netns-vpn-work
|
Troubleshooting
Common Issues
1. Namespace has no connectivity
| # Check if interfaces are up
sudo ip netns exec <namespace> ip link show
# Bring up if needed
sudo ip netns exec <namespace> ip link set <interface> up
# Check routing
sudo ip netns exec <namespace> ip route show
# Add default route if missing
sudo ip netns exec <namespace> ip route add default via <gateway>
# Check IP forwarding on host
sysctl net.ipv4.ip_forward
# Should be 1
|
2. DNS not working in namespace
| # Check resolv.conf
sudo ip netns exec <namespace> cat /etc/resolv.conf
# Create namespace-specific DNS config
sudo mkdir -p /etc/netns/<namespace>
sudo tee /etc/netns/<namespace>/resolv.conf <<EOF
nameserver 8.8.8.8
nameserver 1.1.1.1
EOF
# Test
sudo ip netns exec <namespace> nslookup google.com
|
3. Cannot delete namespace - "Device or resource busy"
| # Find processes using namespace
sudo ip netns identify <pid>
sudo lsns -t net
# Kill processes in namespace
sudo ip netns pids <namespace> | xargs sudo kill
# Force delete
sudo ip netns delete <namespace>
# If still fails, check for mounted resources
sudo umount /var/run/netns/<namespace> || true
sudo rm -f /var/run/netns/<namespace>
|
4. Performance issues
| # Check for packet drops
ip -s link show
# Monitor interface statistics
watch -n 1 'ip -s link show veth-red'
# Check for MTU issues
ip netns exec <namespace> ip link show | grep mtu
# Set MTU if needed
sudo ip netns exec <namespace> ip link set <interface> mtu 1500
|
5. GUI applications won't start in namespace
| # Need to preserve display and X authority
export DISPLAY=:0
export XAUTHORITY=$HOME/.Xauthority
sudo -E ip netns exec <namespace> sudo -u $USER -E firefox
|
Security Considerations
Hardening Namespace Isolation
| # Prevent namespace from accessing host services
sudo iptables -A INPUT -i veth-red-br -d 192.168.1.10 -j DROP
# Allow only specific ports
sudo iptables -A INPUT -i veth-red-br -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -i veth-red-br -p tcp --dport 53 -j ACCEPT
sudo iptables -A INPUT -i veth-red-br -p udp --dport 53 -j ACCEPT
# Rate limiting
sudo iptables -A INPUT -i veth-red-br -m limit --limit 10/minute -j ACCEPT
sudo iptables -A INPUT -i veth-red-br -j DROP
# Log suspicious activity
sudo iptables -A INPUT -i veth-red-br -j LOG --log-prefix "NS-RED: "
|
AppArmor/SELinux Integration
| # AppArmor profile for namespace processes
sudo tee /etc/apparmor.d/namespace-restricted <<'EOF'
#include <tunables/global>
/usr/bin/* {
#include <abstractions/base>
#include <abstractions/nameservice>
network inet stream,
network inet6 stream,
deny /etc/shadow r,
deny /root/** rw,
deny /home/** rw,
/tmp/** rw,
/var/tmp/** rw,
}
EOF
sudo apparmor_parser -r /etc/apparmor.d/namespace-restricted
|
Raspberry Pi Specific Tuning
| # Increase network buffers
sudo sysctl -w net.core.rmem_max=16777216
sudo sysctl -w net.core.wmem_max=16777216
sudo sysctl -w net.ipv4.tcp_rmem='4096 87380 16777216'
sudo sysctl -w net.ipv4.tcp_wmem='4096 65536 16777216'
# Enable TCP optimizations
sudo sysctl -w net.ipv4.tcp_window_scaling=1
sudo sysctl -w net.ipv4.tcp_timestamps=1
sudo sysctl -w net.ipv4.tcp_sack=1
# Reduce conntrack timeout for limited memory
sudo sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=600
# Make permanent
sudo tee -a /etc/sysctl.conf <<EOF
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
net.ipv4.tcp_window_scaling=1
net.ipv4.tcp_timestamps=1
net.ipv4.tcp_sack=1
net.netfilter.nf_conntrack_tcp_timeout_established=600
EOF
|
Monitoring Resource Usage
| #!/bin/bash
# monitor-namespaces.sh
echo "=== Network Namespace Resource Usage ==="
echo ""
for ns in $(ip netns list | awk '{print $1}'); do
echo "Namespace: $ns"
# Process count
PROCS=$(sudo ip netns pids $ns | wc -l)
echo " Processes: $PROCS"
# Network statistics
sudo ip netns exec $ns ip -s link show | grep -A 1 "RX:" | tail -1
sudo ip netns exec $ns ip -s link show | grep -A 1 "TX:" | tail -1
# Connection count
CONNS=$(sudo ip netns exec $ns ss -tan | grep ESTAB | wc -l)
echo " Active connections: $CONNS"
echo ""
done
|
Summary
This comprehensive guide covered network namespaces and VRF on Raspberry Pi:
✅ Core Concepts
- Network namespace isolation and architecture
- VRF for routing table separation
- veth pairs for virtual connectivity
- Network bridges for complex topologies
✅ Practical Applications
- Multi-VPN setup: Simultaneous VPN connections with traffic routing
- IoT segmentation: Isolated networks for untrusted devices
- Container networking: Docker-like network simulation
- Policy routing: VRF-based traffic engineering
✅ Advanced Features
- DNS configuration per namespace
- GUI application support in namespaces
- Port forwarding and NAT
- Load balancing across multiple connections
✅ Production Deployment
- Systemd service integration
- Persistent namespace configuration
- Monitoring and debugging tools
- Performance optimization
✅ Security
- Network isolation enforcement
- Firewall rules per namespace
- AppArmor/SELinux integration
- Rate limiting and logging
✅ Troubleshooting
- Connectivity debugging
- DNS resolution issues
- Performance analysis
- Resource cleanup
- Raspberry Pi specific tuning
- Buffer optimization
- Connection tracking limits
- Resource monitoring
Next Steps
Advanced Topics:
- SR-IOV and Hardware Offload - Network card virtualization
- VXLAN Overlays - Layer 2 networks over Layer 3
- MPLS with VRF - Label switching for advanced routing
- eBPF-based Networking - Programmable network datapaths
- Kubernetes CNI Development - Custom container networking plugins
Related Guides:
With network namespaces and VRF, your Raspberry Pi can handle enterprise-grade network segmentation, multi-VPN routing, and container networking - all on a single device!