TCP/UDP Relay

TBD

Intended to be a means of allowing WireGuard and OpenVPN to operate in a network namespace that was created in a user namespace without having any root privileges on the host. The overall setup is similar to https://www.wireguard.com/netns/, but the network namespace is created in a new user namespace, and there are no root privileges to be given in the initial user namespace. Intended to be used in conjunction with ctrtool ns_open_file (or Python wrappers), and thus there is no code to create a listening or connecting socket. It can also relay between a protocol 41 raw socket and a TUN device (which still requires root privileges to create the raw socket), essentially creating a userspace 6in4 tunnel. It does not appear that NETIF_F_NETNS_LOCAL is set on the Linux kernel's 6in4 device[1], so it might be possible to move the kernel's 6in4 device to another network namespace in the same way that Wireguard handles movement between network namespaces.

Sadly, ip link add wg0 netns <netns> type wireguard does not work, unlike for veth devices.

To do

  • Allow prepending of a (fixed) header in front of relayed data, and allow verification of such a header for the opposite direction.

Example

(Untested)

Use the nsof_special branch of ctrtool. (Clone the repository, then checkout nsof_special.)

ctrtool ns_open_file \
-n -d inet -t udp -s 0 \
-I connect -i 0 -4 [your-original-wireguard-endpoint-ip-address],51820 \
-n -N [path to network namespace or /proc/PID/ns/net] -U -d inet -t udp -4 127.0.0.10,12345 -s 1 \
-I connect -i 1 -4 127.0.0.1,23456 \
sh -c 'exec ./tcp-udp-relay "$CTRTOOL_NS_OPEN_FILE_FD_0" "$CTRTOOL_NS_OPEN_FILE_FD_1"'

In the network namespace, run

ip link add wg0 type wireguard
wg setconf wg0 wg.conf
ip link set wg0 up

(Not sure if you can use wg-quick for this. I haven't really used that tool at all; it's all manual for me :))

In wg.conf:

[Interface]
PrivateKey=[private key]
ListenPort=23456
# 23456 matches that in 127.0.0.1,23456 in the ns_open_file -I connect line

[Peer]
PublicKey=[public key]
Endpoint=127.0.0.10:12345
# the above address matches 127.0.0.10,12345 in the -n -N line
AllowedIPs=::/0,0.0.0.0/0
PersistentKeepAlive=25