Linux Network Namespace

From W9CR
Revision as of 01:08, 15 May 2023 by Bryan (talk | contribs) (Created page with "This is an absolutely stupid use of a /24. I've seen this done before but it was routing back and forth between two cisco routers. This is hosted on a single Linux host and...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

This is an absolutely stupid use of a /24.

I've seen this done before but it was routing back and forth between two cisco routers. This is hosted on a single Linux host and self contained.

My first testing was using VRF's on Linux, but they are not true VRF's, ICMP will fail inside on them, and in general not an easy way to do it.

Second try was using GRE interfaces into VRF's across the loopback interface, but that didn't work for some reason. I did a bit of testing and saw them making it across the interface, but just dropping for some reason.

I then stumbled on the user mode linux and found Linux namespaces. This appeared to be the way to do it and I configured 10 by hand just to get a feel for it. I knew I'd have to write a script to generate the config as it was way to lengthy to do by hand.

Config

The basic concept was to have a chain of tunnels or name spaces with a left and right interface. Each interface would be connected to the next with a /31, so we can scale this to 127 name spaces for a /24. This makes efficient use of a limited resource for a stupid application.


Code Generator

This is a small python program to generate the config.

#!/usr/local/bin/python3
#  subnetmaker
#  Build /31 network interfaces and name space config
#  Copyright Bryan Fields, 2023
#  bryan@bryanfields.net
#  Licensed under the AGPL 3
#
import sys
import ipaddress
#set the base namespace
base_namespace = 'vnet'
basesubnet = ipaddress.ip_network('192.77.144.0/24')
net_array = list(basesubnet.subnets(new_prefix=31))

n=0
#setup the 000 interface
#ip link add veth001-L type veth peer name veth000-R
#ip addr add 192.77.144.0/31 dev veth000-L
#ip link set veth000-R up
#ip route add 192.77.144.0/24 via 192.77.144.1
network=str(net_array[0])
hosts=list(net_array[0].hosts())
nextHosts=list(net_array[0].hosts())
prefixlen=str(net_array[0].prefixlen)
host1=str(hosts[0])+"/"+prefixlen
host2=str(hosts[1])+"/"+prefixlen
thisNetdevL="veth""{:03d}".format(n)+ "-L"
thisNetdevR="veth""{:03d}".format(n)+ "-R"
nextNetdevL="veth""{:03d}".format(n+1)+ "-L"
nextNetdevR="veth""{:03d}".format(n+1)+ "-R"
nextHostL =str(hosts[1])

print ("ip link add "+nextNetdevL+" type veth peer name "+thisNetdevR)
print ("ip addr add "+ host1 +" dev " + thisNetdevR)
print ("ip link set "+thisNetdevR+" up")
print ("ip route add "+str(basesubnet)+" via "+nextHostL)
print ("#end of hostnet")

n=1
for n in range(1,128):
    thisNameSpace="vnet""{:03d}".format(n)
    network=str(net_array[n])
    hostsL = list(net_array[n-1].hosts())
    hostsR = list(net_array[n].hosts())
    prefixlen=str(net_array[n].prefixlen)
    hostL=str(hostsL[1])+"/"+prefixlen
    hostR=str(hostsR[0])+"/"+prefixlen
    thisNetdevL="veth""{:03d}".format(n)+ "-L"
    thisNetdevR="veth""{:03d}".format(n)+ "-R"
    nextNetdevL="veth""{:03d}".format(n+1)+ "-L"
    nextNetdevR="veth""{:03d}".format(n+1)+ "-R"
    nextHostR =str(hostsR[1])
    nextHostL =str(hostsL[0])
    print ("ip netns add "+thisNameSpace)
    print ("ip link add "+nextNetdevL+" type veth peer name "+thisNetdevR)
    print ("ip link set "+thisNetdevL+" netns "+thisNameSpace)
    print ("ip link set "+thisNetdevR+" netns "+thisNameSpace)
    print ("ip -n "+thisNameSpace+" link set "+thisNetdevL+" up")
    print ("ip -n "+thisNameSpace+" link set "+thisNetdevR+" up")
    print ("ip -n "+thisNameSpace+" link set lo up")
    print ("ip -n "+thisNameSpace+" addr add "+hostL+" dev "+thisNetdevL)
    print ("ip -n "+thisNameSpace+" addr add "+hostR+" dev "+thisNetdevR)
    print ("#Linux Sys settings")
    print ("ip netns exec "+thisNameSpace+" sysctl -w net.ipv4.ip_forward=1")
    print ("ip netns exec "+thisNameSpace+" sysctl -w net.ipv4.ip_default_ttl=255")
    print ("#Default Route Left")
    print ("ip -n "+thisNameSpace+" route add 0/0 via "+nextHostL)
    print ("#.0 Route Left")
    print ("ip -n "+thisNameSpace+" route add "+str(net_array[0])+" via "+nextHostL)
    print ("#Subnet /24 Right")
    print ("ip -n "+thisNameSpace+" route add "+str(basesubnet)+" via "+nextHostR)
exit