diff --git a/README.md b/README.md index 214cbf2..c90693a 100644 --- a/README.md +++ b/README.md @@ -124,37 +124,34 @@ 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. +You can also spawn a shell inside the netns. ~~~ bash ip netns exec ns-example bash -i ~~~ -Or connect a container to it. - -~~~ bash -podman run -it --rm --network ns:/run/netns/ns-example alpine wget -O - https://ipinfo.io -~~~ - -Or do whatever else you want. - -### System Service +### Systemd Service You can find a `wg-quick@.service` equivalent at [wg-netns@.service](./wg-netns@.service). Place your profile in `/etc/wireguard/`, e.g. `example.json`, then start the service. ~~~ bash -systemctl start wg-netns@example.service +systemctl enable --now wg-netns@example.service ~~~ -### Port Forwarding +### Podman Integration -With `socat` you can forward TCP traffic from outside a network namespace to a port inside a network namespace. +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*. ~~~ bash -socat tcp-listen:$OUTSIDE_PORT,reuseaddr,fork "exec:ip netns exec $NETNS_NAME socat stdio 'tcp-connect:$INSIDE_PORT',nofork" +podman run -it --rm --network ns:/run/netns/ns-example docker.io/library/alpine wget -q -O - https://ipinfo.io ~~~ +### 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. + Example: All connections to port 1234/tcp in the main/default netns are forwarded to port 5678/tcp in the *ns-example* namespace. ~~~ bash @@ -163,7 +160,11 @@ wg-netns up ns-example echo 'Hello from ns-example!' > ./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" +./extras/netns-publish.sh 1234 ns-example 127.0.0.1:5678 # terminal 3, test access curl http://127.0.0.1:1234/hello.txt ~~~ + +### 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. diff --git a/extras/netns-publish.sh b/extras/netns-publish.sh new file mode 100755 index 0000000..47193ed --- /dev/null +++ b/extras/netns-publish.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -eu + +if [ $# -ne 3 ]; then + echo 'usage: netns-publish PUBLIC_PORT NETNS_NAME NETNS_ADDRESS:NETNS_PORT' + exit 1 +fi + +exec socat tcp-listen:"$1",reuseaddr,fork "exec:ip netns exec $2 socat stdio 'tcp-connect:$3',nofork" diff --git a/extras/wg-resolve/config.env b/extras/wg-resolve/config.env new file mode 100644 index 0000000..393cd3a --- /dev/null +++ b/extras/wg-resolve/config.env @@ -0,0 +1,8 @@ +# local wireguard interface name +WG_INTERFACE=wg0 +# server wireguard public key +WG_PEER=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +# server wireguard interface ip +WG_GATEWAY=192.168.100.1 +# server dyndns domain +WG_ENDPOINT=vpn.dyndns.example:51820 diff --git a/extras/wg-resolve/wg-resolve.sh b/extras/wg-resolve/wg-resolve.sh new file mode 100755 index 0000000..eef13ff --- /dev/null +++ b/extras/wg-resolve/wg-resolve.sh @@ -0,0 +1,7 @@ +#!/bin/sh +set -eu + +if ! ping -q -c 1 -W "${WG_TIMEOUT:-5}" "$WG_GATEWAY"; then + echo 'probe failed, resolving endpoint' + wg set "$WG_INTERFACE" peer "$WG_PEER" endpoint "$WG_ENDPOINT" +fi diff --git a/extras/wg-resolve/wg-resolve@.service b/extras/wg-resolve/wg-resolve@.service new file mode 100644 index 0000000..26e68bc --- /dev/null +++ b/extras/wg-resolve/wg-resolve@.service @@ -0,0 +1,10 @@ +[Unit] +Description=WireGuard Endpoint Resolver (%i) +Wants=network-online.target nss-lookup.target +After=network-online.target nss-lookup.target + +[Service] +Type=oneshot +EnvironmentFile=%E/wireguard/%i.env +Environment=WG_ENDPOINT_RESOLUTION_RETRIES=infinity +ExecStart=/usr/local/lib/wg-resolve.sh diff --git a/extras/wg-resolve/wg-resolve@.timer b/extras/wg-resolve/wg-resolve@.timer new file mode 100644 index 0000000..d4d8e26 --- /dev/null +++ b/extras/wg-resolve/wg-resolve@.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Minutely WireGuard Endpoint Resolver + +[Timer] +OnCalendar=minutely +AccuracySec=5s + +[Install] +WantedBy=timers.target