Skip to content

Latest commit

 

History

History
163 lines (130 loc) · 4.07 KB

README.md

File metadata and controls

163 lines (130 loc) · 4.07 KB

wg-netns

wg-quick with support for linux network namespaces. It's a simple python script that implements the steps described at wireguard.com/netns.

Setup

Requirements:

  • Linux
  • Python 3.7 or newer
  • ip from iproute2
  • wg from wireguard-tools

Have a look at the Makefile to see where it is installed. Just run:

make install

Usage

First, create a configuration profile. You can find two examples below.

./mini.json:

{
  "name": "ns-example",
  "interfaces": [
    {
      "name": "wg-example",
      "address": ["10.10.10.192/32", "fc00:dead:beef::192/128"],
      "private-key": "4bvaEZHI...",
      "peers": [
        {
          "public-key": "bELgMXGt...",
          "endpoint": "vpn.example.com:51820",
          "allowed-ips": ["0.0.0.0/0", "::/0"]
        }
      ]
    }
  ]
}

./maxi.json:

{
  "name": "ns-example",
  "dns-server": ["10.10.10.1", "10.10.10.2"],
  "pre-up": "some shell command executed in netns",
  "post-up": "some shell command executed in netns",
  "pre-down": "some shell command executed in netns",
  "post-down": "some shell command executed in netns",
  "no-netns-post-up": "some shell command that is *not executed* in netns",
  "no-resolvconf-write": "true",
  "interfaces": [
    {
      "name": "wg-site-a",
      "address": ["10.10.11.172/32", "fc00:dead:beef:1::172/128"],
      "listen-port": 51821,
      "fwmark": 51821,
      "private-key": "nFkQQjN+...",
      "mtu": 1420,
      "peers": [
        {
          "public-key": "Kx+wpJpj...",
          "preshared-key": "5daskLoW...",
          "endpoint": "a.example.com:51821",
          "persistent-keepalive": 25,
          "allowed-ips": ["10.10.11.0/24", "fc00:dead:beef:1::/64"]
        }
      ]
    },
    {
      "name": "wg-site-b",
      "address": ["10.10.12.172/32", "fc00:dead:beef:2::172/128"],
      "listen-port": 51822,
      "fwmark": 51822,
      "private-key": "guYPuE3X...",
      "mtu": 1420,
      "peers": [
        {
          "public-key": "NvZMoyrg...",
          "preshared-key": "cFQuyIX/...",
          "endpoint": "b.example.com:51822",
          "persistent-keepalive": 25,
          "allowed-ips": ["10.10.12.0/24", "fc00:dead:beef:2::/64"]
        }
      ]
    }
  ]
}

Notes

setting no-resolvconf-write to true explicitly disables writing a resolv.conf file and therefore specifying dns-server unnecessary. Both are just listed for the sake of completeness.

Examples

Now it's time to setup your new network namespace and all associated wireguard interfaces.

wg-netns up ./example.json

You can verify the success with a combination of ip and wg.

ip netns exec ns-example wg show

Or you can spawn a shell inside the netns.

ip netns exec ns-example bash -i

Or connect a container to it.

podman run -it --rm --network ns:/var/run/netns/ns-example docker.io/alpine wget -O - https://ipinfo.io

Or do whatever else you want.

System Service

You can find a [email protected] equivalent at [email protected]. Place your config in /etc/wg-netns/ and start the service:

(Assuming the config file is named example.json)

systemctl start [email protected]

Port Forwarding

With socat you can forward TCP traffic from outside a network namespace to a port inside a network namespace.

socat tcp-listen:$LHOST,reuseaddr,fork "exec:ip netns exec $NETNS socat stdio 'tcp-connect:$RHOST',nofork"

Example: All connections to port 1234/tcp in the main netns are forwarded into the ns-example namespace to port 5678/tcp.

# terminal 1, create netns and start http server inside
wg-netns up ns-example
hello > ./hello.txt
ip netns exec ns-example python3 -m http.server 5678
# terminal 2, setup port forwarding
socat tcp-listen:1234,reuseaddr,fork "exec:ip netns exec ns-example socat stdio 'tcp-connect:127.0.0.1:5678',nofork"
# terminal 3, test access
curl http://127.0.0.1:1234/hello.txt