1
votes

I'm writing a bash application that runs on a cluster of Ubuntu 18.04 servers and provisions and syncs user accounts across several servers deployed in different geographic regions. The server allows users to be redirected to the appropriate geographic server depending on their current location and then grants them SSH shell access.

The server currently has one one public network interface (eth0). I'm trying to incorporate provisioning additional "virtual" network interfaces for each user to the bash script. This should allow each user to have a separate internal IP address which should be able to access the internet with NAT rules set up. Each user will always be provisioned the same internal IP address regardless of which geographic server they are redirected to.

For example the following config file defines virtual interface names and IP addresses for every user that logs in. This config file is synced across each server with a REST API I've written:

{
  "users": [
    {
      "username": "user0",
      "interface": "veth0",
      "ip_address": "192.168.1.0"
    },
    {
      "username": "user1",
      "interface": "veth1",
      "ip_address": "192.168.1.1"
    },
    {
      "username": "user2",
      "interface": "veth2",
      "ip_address": "192.168.1.2"
    },
    {
      "username": "user3",
      "interface": "veth3",
      "ip_address": "192.168.1.3"
    }
  ]
} 

If user2 logs into the server the bash script automatically creates the appropriate interface and IP as follows:

ip link add type $interface
ifconfig $interface $ip_address

This adds the following to ifconfig output:

veth2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    inet 192.168.1.2  netmask 255.255.255.0  broadcast 192.168.1.255
    ether a6:e7:de:40:9a:28  txqueuelen 1000  (Ethernet)
    RX packets 27  bytes 2082 (2.0 KB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 1132  bytes 48520 (48.5 KB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

I have "/proc/sys/net/ipv4/ip_forward" set to 1 on the server to enable IP forwarding but I can't figure out the proper iptables MASQUERADE, FORWARD, and NAT rules to add to a startup script.

So far I am unable to get internet access working from the virtual interfaces.

I can't seem to figure out what I'm doing wrong and any help would be appreciated.

1

1 Answers

0
votes

I was able to solve this by autmating the creation of network namespaces with two veth pairs as follows:

#!/bin/bash

#enable port forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

#create network namespace (netns0)
ip netns add $netns

#add loopback interface to namespace
ip netns exec $netns ip link set lo up

#create veth pairs
ip link add $vetha type veth peer name $vethb

#add $vethb to namespace
ip link set $vethb netns $netns

#add ip addresses to interfaces
ip addr add $ip1 dev $vetha
ip netns exec $netns ip addr add $ip2 dev $vethb

#enable interfaces
ip link set $vetha up
ip netns exec $netns ip link set $vethb up

#enable ip forwarding and nating with iptables
iptables -A FORWARD -o eth0 -i $vetha -j ACCEPT
iptables -A FORWARD -i eth0 -o $vetha -j ACCEPT
iptables -t nat -A POSTROUTING -s $ip2 -o eth0 -j MASQUERADE

#add default route to namespace
ip netns exec $netns ip route add default via $ip1

#set dns servers for namespace
mkdir -p /etc/netns/netns0
echo "nameserver 1.1.1.1" > /etc/netns/netns0/resolv.conf