2020-11-15 15:43:35 +00:00
# wg-netns
2021-05-28 09:31:21 +00:00
[wg-quick ](https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8 ) with support for Linux network namespaces.
A simple Python script that implements the steps described at [wireguard.com/netns ](https://www.wireguard.com/netns/#ordinary-containerization ).
2020-11-15 15:43:35 +00:00
## Setup
Requirements:
2020-11-15 21:41:42 +00:00
- Python 3.7 or newer
2021-05-28 09:31:21 +00:00
- `ip` from iproute2
- `wg` from wireguard-tools
2022-01-25 23:10:17 +00:00
- optional: [pyyaml ](https://pypi.org/project/PyYAML/ ) python package for configuration files in YAML format, otherwise only JSON is supported
2020-11-15 15:43:35 +00:00
2021-05-28 09:31:21 +00:00
Installation:
2020-11-15 15:43:35 +00:00
2022-07-10 10:48:20 +00:00
a) With [pipx ](https://github.com/pypa/pipx ).
~~~ bash
pipx install git+https://github.com/dadevel/wg-netns.git@main
~~~
b) With `pip` .
~~~ bash
pip install --user git+https://github.com/dadevel/wg-netns.git@main
~~~
c) As standalone script.
2020-11-15 15:43:35 +00:00
~~~ bash
2022-07-10 10:48:20 +00:00
curl -o ~/.local/bin/wg-netns https://raw.githubusercontent.com/dadevel/wg-netns/main/wgnetns/main.py
chmod +x ~/.local/bin/wg-netns
2020-11-15 15:43:35 +00:00
~~~
## Usage
2020-12-06 21:53:31 +00:00
First, create a configuration profile.
2022-01-25 23:10:17 +00:00
JSON and YAML file formats are supported.
2020-12-06 21:53:31 +00:00
2022-01-25 23:10:17 +00:00
Minimal JSON example:
2020-12-06 21:53:31 +00:00
~~~ 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"]
}
]
}
]
}
~~~
2022-01-25 23:10:17 +00:00
Full YAML example:
~~~ yaml
# name of the network namespace
name: ns-example
# if false, the netns itself won't be created or deleted, just the interfaces inside it
managed: true
# list of dns servers, if empty dns servers from default netns will be used
dns-server: [10.10.10.1, 10.10.10.2]
2022-10-01 03:39:31 +00:00
# shell hooks, e.g. to set firewall rules, two formats are supported
pre-up: echo pre-up from managed netns
post-up:
- host-namespace: true
command: echo post-up from host netns
- host-namespace: false
command: echo post-up from managed netns
pre-down: echo pre-down from managed netns
post-down: echo post-down from managed netns
2022-01-25 23:10:17 +00:00
# list of wireguard interfaces inside the netns
interfaces:
# interface name, required
- name: wg-site-a
# list of ip addresses, at least one entry required
address:
- 10.10.11.172/32
- fc00:dead:beef:1::172/128
private-key: nFkQQjN+...
# optional settings
listen-port: 51821
fwmark: 21
mtu: 1420
# list of wireguard peers
peers:
# public key is required
- public-key: Kx+wpJpj...
# optional settings
preshared-key: 5daskLoW...
endpoint: a.example.com:51821
persistent-keepalive: 25
# list of ips the peer is allowed to use, at least one entry required
allowed-ips:
- 10.10.11.0/24
- fc00:dead:beef:1::/64
# by default the networks specified in 'allowed-ips' are routed over the interface, 'routes' can be used to overwrite this behaivor
routes:
- 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
private-key: guYPuE3X...
listen-port: 51822
fwmark: 22
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
2020-12-06 21:53:31 +00:00
~~~
Now it's time to setup your new network namespace and all associated wireguard interfaces.
~~~ bash
2022-01-25 23:10:17 +00:00
wg-netns up ./example.yaml
~~~
Profiles stored under `/etc/wireguard/` can be referenced by their name.
~~~ bash
wg-netns up example
2020-12-06 21:53:31 +00:00
~~~
You can verify the success with a combination of `ip` and `wg` .
~~~ bash
ip netns exec ns-example wg show
~~~
2020-11-15 15:43:35 +00:00
2022-03-20 20:56:45 +00:00
You can also spawn a shell inside the netns.
2020-11-15 15:43:35 +00:00
~~~ bash
2020-12-06 21:53:31 +00:00
ip netns exec ns-example bash -i
2020-11-15 15:43:35 +00:00
~~~
2022-03-20 20:56:45 +00:00
### Systemd Service
2020-11-30 12:06:44 +00:00
2022-07-10 10:48:20 +00:00
You can find a `wg-quick@.service` equivalent at [wg-netns@.service ](./extras/wg-netns@.service ).
2022-01-25 23:10:17 +00:00
Place your profile in `/etc/wireguard/` , e.g. `example.json` , then start the service.
~~~ bash
2022-07-10 10:48:20 +00:00
curl -o /etc/systemd/system/wg-netns@.service https://raw.githubusercontent.com/dadevel/wg-netns/main/extras/wg-netns@.service
2022-03-20 20:56:45 +00:00
systemctl enable --now wg-netns@example.service
2022-01-25 23:10:17 +00:00
~~~
2020-11-15 16:13:46 +00:00
2022-03-20 20:56:45 +00:00
### Podman Integration
2020-11-30 12:06:44 +00:00
2022-03-20 20:56:45 +00:00
A podman container can be easily attached to a network namespace created by `wg-netns` .
The example below starts a container connected to a netns named *ns-example* .
2020-11-30 12:06:44 +00:00
~~~ bash
2022-03-20 20:56:45 +00:00
podman run -it --rm --network ns:/run/netns/ns-example docker.io/library/alpine wget -q -O - https://ipinfo.io
2020-11-30 12:06:44 +00:00
~~~
2022-03-20 20:56:45 +00:00
### Port Forwarding with Socat
[netns-publish ](./extras/netns-publish.sh ) is a small wrapper around `socat` that can forward TCP traffic from outside a network namespace to a port inside a network namespace.
2022-01-25 23:10:17 +00:00
Example: All connections to port 1234/tcp in the main/default netns are forwarded to port 5678/tcp in the *ns-example* namespace.
2020-11-30 12:06:44 +00:00
~~~ bash
# terminal 1, create netns and start http server inside
2020-12-06 21:53:31 +00:00
wg-netns up ns-example
2022-01-25 23:10:17 +00:00
echo 'Hello from ns-example!' > ./hello.txt
2020-12-06 21:53:31 +00:00
ip netns exec ns-example python3 -m http.server 5678
2020-11-30 12:06:44 +00:00
# terminal 2, setup port forwarding
2022-03-20 20:56:45 +00:00
./extras/netns-publish.sh 1234 ns-example 127.0.0.1:5678
2020-12-06 21:53:31 +00:00
# terminal 3, test access
2020-11-30 12:06:44 +00:00
curl http://127.0.0.1:1234/hello.txt
~~~
2022-03-20 20:56:45 +00:00
### WireGuard with DynDNS
If your WireGuard server endpoint is a DynDNS domain you can use the [wg-resolve ](./extras/wg-resolve/ ) script to periodically check the connectivity and re-resolve the endpoint if necessary.
2022-10-02 16:24:02 +00:00
### Firefox in Network Namespace
Start a dedicated Firefox profile with working audio inside the netns created by `wg-netns` .
~~~ bash
sudo ip netns exec ns-example sudo -u "$USER" "HOME=$HOME" "PULSE_SERVER=/run/user/$(id -u)/pulse/native" "PULSE_COOKIE=$HOME/.config/pulse/cookie" firefox -P vpn
~~~