Skip to content

Network Namespaces

🧠 Objective

By the end of these labs, your colleagues will:

Understand what network namespaces are and how they provide isolation.

Create and manage namespaces manually.

Connect namespaces together using virtual interfaces.

Configure IP addressing, routing, and bridging.

Use namespaces to simulate small network topologies.

🧩 Lab Environment

OS: openSUSE Leap 15.6 (or any modern Linux distribution)

Tools: iproute2, bridge-utils, iptables (optional), tcpdump, iputils

Each student: 1 VM (no need for multiple VMs β€” namespaces simulate them)

πŸ§ͺ LAB 1 – Introduction to Namespaces

Goal: Understand namespace isolation.

Steps:

Create two namespaces:

ip netns add ns1
ip netns add ns2

List all namespaces:

ip netns list

Check network interfaces inside each:

ip netns exec ns1 ip link
ip netns exec ns2 ip link

Notice each namespace only has lo (loopback).

Bring up the loopback:

ip netns exec ns1 ip link set lo up
ip netns exec ns2 ip link set lo up

Concept: Namespaces isolate network interfaces, routes, and IP addresses.

πŸ§ͺ LAB 2 – Connect Two Namespaces with veth Pair

Goal: Connect two isolated namespaces.

Steps:

Create a virtual Ethernet pair:

ip link add veth-ns1 type veth peer name veth-ns2

Move one end to each namespace:

ip link set veth-ns1 netns ns1
ip link set veth-ns2 netns ns2

Assign IP addresses:

ip netns exec ns1 ip addr add 10.0.0.1/24 dev veth-ns1
ip netns exec ns2 ip addr add 10.0.0.2/24 dev veth-ns2

Bring interfaces up:

ip netns exec ns1 ip link set veth-ns1 up
ip netns exec ns2 ip link set veth-ns2 up

Test connectivity:

ip netns exec ns1 ping 10.0.0.2

Concept: veth pairs are like virtual cables between namespaces.

πŸ§ͺ LAB 3 – Add a Bridge to Connect Multiple Namespaces

Goal: Simulate a LAN with 3 hosts.

Steps:

Create three namespaces:

1
2
3
ip netns add host1
ip netns add host2
ip netns add host3

Create a Linux bridge:

ip link add br0 type bridge
ip link set br0 up

Create veth pairs for each host and attach one end to the bridge:

1
2
3
4
5
6
for i in 1 2 3; do
    ip link add veth$i type veth peer name veth$i-br
    ip link set veth$i netns host$i
    ip link set veth$i-br master br0
    ip link set veth$i-br up
done

Assign IPs to each host:

1
2
3
ip netns exec host1 ip addr add 192.168.10.1/24 dev veth1
ip netns exec host2 ip addr add 192.168.10.2/24 dev veth2
ip netns exec host3 ip addr add 192.168.10.3/24 dev veth3

Bring up interfaces:

1
2
3
4
for i in 1 2 3; do
    ip netns exec host$i ip link set veth$i up
    ip netns exec host$i ip link set lo up
done

Ping between namespaces:

ip netns exec host1 ping 192.168.10.2

Concept: The bridge acts like a virtual switch.

πŸ§ͺ LAB 4 – Add a Router Namespace

Goal: Simulate two networks and a router between them.

Topology:

[ns1: 10.0.0.1/24] --- [router: 10.0.0.254/24 | 10.0.1.254/24] --- [ns2: 10.0.1.1/24]
Steps:

  1. Create namespaces:
1
2
3
ip netns add ns1
ip netns add ns2
ip netns add router
  1. Create two veth pairs:
ip link add veth-ns1 type veth peer name veth-r1
ip link add veth-ns2 type veth peer name veth-r2
  1. Assign interfaces:
1
2
3
4
ip link set veth-ns1 netns ns1
ip link set veth-ns2 netns ns2
ip link set veth-r1 netns router
ip link set veth-r2 netns router
  1. Configure IPs:
1
2
3
4
ip netns exec ns1 ip addr add 10.0.0.1/24 dev veth-ns1
ip netns exec router ip addr add 10.0.0.254/24 dev veth-r1
ip netns exec router ip addr add 10.0.1.254/24 dev veth-r2
ip netns exec ns2 ip addr add 10.0.1.1/24 dev veth-ns2
  1. Enable interfaces:
1
2
3
4
5
6
7
for ns in ns1 ns2 router; do
    ip netns exec $ns ip link set lo up
done
ip netns exec ns1 ip link set veth-ns1 up
ip netns exec ns2 ip link set veth-ns2 up
ip netns exec router ip link set veth-r1 up
ip netns exec router ip link set veth-r2 up
  1. Enable IP forwarding:
ip netns exec router sysctl -w net.ipv4.ip_forward=1
  1. Add routes:
ip netns exec ns1 ip route add default via 10.0.0.254
ip netns exec ns2 ip route add default via 10.0.1.254
  1. Test:
ip netns exec ns1 ping 10.0.1.1

Concept: Routing between namespaces.

πŸ§ͺ LAB 5 – Observe Traffic with tcpdump

Goal: Learn how to capture traffic inside namespaces.

Example: ip netns exec router tcpdump -i veth-r1 -n

Then run a ping between namespaces to see packets passing through the router.

πŸ§ͺ LAB 6 – NAT with iptables

🎯 Goal: Simulate a small network where a router namespace performs NAT to let a private host reach an β€œexternal” network.

🧱 Topology

[ns1: 10.0.0.10/24] --- [router: 10.0.0.1/24 | 203.0.113.1/24] --- [ns2: 203.0.113.2/24]
  • ns1 β†’ internal host
  • router β†’ performs NAT
  • ns2 β†’ external server

🧰 Setup Steps

1️⃣ Create namespaces

1
2
3
ip netns add ns1
ip netns add ns2
ip netns add router

2️⃣ Create veth pairs

ip link add veth-ns1 type veth peer name veth-r1
ip link add veth-ns2 type veth peer name veth-r2

3️⃣ Assign interfaces to namespaces

1
2
3
4
ip link set veth-ns1 netns ns1
ip link set veth-ns2 netns ns2
ip link set veth-r1 netns router
ip link set veth-r2 netns router

4️⃣ Configure IP addresses

1
2
3
4
ip netns exec ns1 ip addr add 10.0.0.10/24 dev veth-ns1
ip netns exec router ip addr add 10.0.0.1/24 dev veth-r1
ip netns exec router ip addr add 203.0.113.1/24 dev veth-r2
ip netns exec ns2 ip addr add 203.0.113.2/24 dev veth-ns2

5️⃣ Bring all interfaces up

1
2
3
4
5
6
7
8
for ns in ns1 ns2 router; do
    ip netns exec $ns ip link set lo up
done

ip netns exec ns1 ip link set veth-ns1 up
ip netns exec ns2 ip link set veth-ns2 up
ip netns exec router ip link set veth-r1 up
ip netns exec router ip link set veth-r2 up

6️⃣ Enable IP forwarding in the router

ip netns exec router sysctl -w net.ipv4.ip_forward=1

7️⃣ Set default routes

ip netns exec ns1 ip route add default via 10.0.0.1
ip netns exec ns2 ip route add default via 203.0.113.1

8️⃣ Configure NAT (MASQUERADE) on the router

ip netns exec router iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o veth-r2 -j MASQUERADE

9️⃣ Test connectivity

Start tcpdump in ns2:

ip netns exec ns2 tcpdump -n -i veth-ns2 icmp

From ns1, ping the external host:

ip netns exec ns1 ping 203.0.113.2

βœ… You should see the source address translated to 203.0.113.1.

🧹 Cleanup

for ns in ns1 ns2 router; do ip netns del $ns; done

Concepts reinforced:

  • iptables NAT (POSTROUTING MASQUERADE)
  • Routing between private and public subnets
  • Observing NAT using tcpdump

πŸ§ͺ LAB 7 – nginx and curl in Multiple Namespaces

🎯 Goal:

Run a small web server (nginx) inside one namespace, and access it using curl from others.

This demonstrates running real applications in isolated network namespaces.

🧱 Topology

1
2
3
4
5
6
[client1: 192.168.50.1/24]
[client2: 192.168.50.2/24]
      \          /
        [br0: bridge switch]
             |
      [server: nginx, 192.168.50.10/24]

🧰 Setup Steps

1️⃣ Create namespaces

1
2
3
ip netns add client1
ip netns add client2
ip netns add server

2️⃣ Create a bridge on the root namespace

ip link add br0 type bridge
ip link set br0 up

3️⃣ Create veth pairs and connect them

1
2
3
4
5
6
for i in client1 client2 server; do
    ip link add veth-$i type veth peer name veth-$i-br
    ip link set veth-$i netns $i
    ip link set veth-$i-br master br0
    ip link set veth-$i-br up
done

4️⃣ Assign IP addresses

1
2
3
ip netns exec client1 ip addr add 192.168.50.1/24 dev veth-client1
ip netns exec client2 ip addr add 192.168.50.2/24 dev veth-client2
ip netns exec server ip addr add 192.168.50.10/24 dev veth-server
5️⃣ Bring up interfaces

1
2
3
4
for ns in client1 client2 server; do
    ip netns exec $ns ip link set lo up
    ip netns exec $ns ip link set veth-$ns up
done
6️⃣ Test basic connectivity

ip netns exec client1 ping -c2 192.168.50.10
ip netns exec client2 ping -c2 192.168.50.10

βœ… Should work before installing nginx.

🧩 Run nginx and curl

7️⃣ Install nginx and curl

On openSUSE:

zypper install -y nginx curl

8️⃣ Run nginx inside server namespace

ip netns exec server nginx

(If nginx fails to start due to missing /run/nginx.pid, run this:)

ip netns exec server mkdir -p /run/nginx
ip netns exec server nginx

Check:

ip netns exec server ss -tlnp

β†’ should show port 80 listening on 0.0.0.0:80.

9️⃣ Test with curl from clients

ip netns exec client1 curl http://192.168.50.10
ip netns exec client2 curl http://192.168.50.10

βœ… You should receive the nginx default HTML page.

🧹 Cleanup

for ns in client1 client2 server; do ip netns del $ns; done
ip link del br0