diff --git a/Makefile b/Makefile index 077e48c..7eef795 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,25 @@ CFLAGS = -std=gnu99 -pie -fPIC -pedantic -Wno-imports -Wunused -Wno-missing-field-initializers -Wextra -Wunreachable-code -O3 -all: wireguard-mount wireguard-resolve +all: wireguard_mount wireguard_resolve -wireguard-mount: src/wireguard-mount.c +wireguard_mount: src/wireguard-mount.c mkdir -p bin gcc $(CFLAGS) -o bin/wireguard-mount src/wireguard-mount.c -lsystemd -wireguard-resolve: src/resolve.c src/resolve.s +wireguard_resolve: src/resolve.c src/resolve.s mkdir -p bin gcc -shared -o bin/wireguard-resolve.so -nostdlib -fPIC src/resolve.c src/resolve.s + +install_basic: systemd scripts bin + mkdir -p /snacks/wireguard/bin + mkdir -p /snacks/wireguard/scripts + cp bin/wireguard-resolve.so /snacks/wireguard/bin/wireguard-resolve.so + cp bin/wireguard-mount /snacks/wireguard/bin/wireguard-mount + cp systemd/vpnclient-wg-basic.service /etc/systemd/system/vpnclient-wg-basic.service + cp systemd/wireguard-mount.service /etc/systemd/system/wireguard-mount.service + cp scripts/connect_basic.py /snacks/wireguard/scripts/connect_basic.py + cp scripts/inner_basic.sh /snacks/wireguard/scripts/inner_basic.sh + chmod -R 755 /snacks/wireguard + systemctl daemon-reload + systemctl enable wireguard-mount + systemctl start wireguard-mount diff --git a/scripts/connect_basic.py b/scripts/connect_basic.py new file mode 100644 index 0000000..1cefaf7 --- /dev/null +++ b/scripts/connect_basic.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +import subprocess,os +newenv = os.environ.copy() +newenv["LD_PRELOAD"] = "/snacks/wireguard/bin/wireguard-resolve.so" + +def default_devices(): + with open("/proc/1/net/dev", "r") as f: + return f.read() +def vpn_devices(): + with open("/proc/self/net/dev", "r") as f: + return f.read() + +def wireguard(): + try: + os.mkdir("/run/netns") + except FileExistsError: + pass + + try: + os.symlink("/run/vpn/net", "/run/netns/vpn") + os.symlink("/proc/1/ns/net", "/run/netns/default") + except FileExistsError: + pass + + with open("/proc/sys/net/ipv4/conf/all/forwarding", "w") as f: + f.write("1") + with open("/proc/sys/net/ipv6/conf/all/forwarding", "w") as f: + f.write("1") + with open("/proc/sys/net/ipv4/ping_group_range", "w") as f: + f.write("0 2147483647") + + if "vpn" in vpn_devices(): + subprocess.run(["ip", "link", "del", "dev", "vpn"]) + if "vpn" in default_devices(): + subprocess.run(["nsenter", "--net=/proc/1/ns/net", "ip", "link", "del", "dev", "vpn"]) + + subprocess.run(["modprobe", "wireguard"]) + subprocess.run(["nsenter", "--net=/proc/1/ns/net", "ip", "link", "add", "dev", "vpn", "type", "wireguard"]) + subprocess.run(["nsenter", "--net=/proc/1/ns/net", "ip", "link", "set", "dev", "vpn", "netns", "vpn"]) + subprocess.run(["nsenter", "--net=/run/vpn/net", "/snacks/wireguard/scripts/inner_basic.sh"], env=newenv) + +try: + self_ns = os.readlink("/proc/self/ns/net") + vpn_ns = os.readlink("/run/vpn/net") +except Exception as e: + print(e) +else: + if self_ns == vpn_ns: + wireguard() + else: + print("This script should be called from the VPN network namespace.") + diff --git a/scripts/inner_basic.sh b/scripts/inner_basic.sh new file mode 100644 index 0000000..e750e9b --- /dev/null +++ b/scripts/inner_basic.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +wg setconf vpn /snacks/wireguard/wg.conf +ip link set dev vpn up +ip addr flush dev vpn +ip route flush dev vpn + +echo "-- inner_basic.sh --" + +echo "VPN_IPV4_ADDRESS=${VPN_IPV4_ADDRESS}" +echo "VPN_IPV6_ADDRESS=${VPN_IPV6_ADDRESS}" + +echo "-- inner_basic.sh --" +if [ -z "${VPN_IPV4_ADDRESS}" ] +then + ip addr add ${VPN_IPV4_ADDRESS} dev vpn +fi + +if [ -z "${VPN_IPV6_ADDRESS}" ] +then + ip addr add ${VPN_IPV6_ADDRESS} dev vpn +fi + +if [ -z "${VPN_IPV4_ADDRESS}" ] +then + ip -4 route add default dev vpn +fi + +if [ -z "${VPN_IPV6_ADDRESS}" ] +then + ip -6 route add default dev vpn +fi diff --git a/systemd/vpnclient-wg-basic.service b/systemd/vpnclient-wg-basic.service new file mode 100644 index 0000000..c73a23d --- /dev/null +++ b/systemd/vpnclient-wg-basic.service @@ -0,0 +1,17 @@ +[Unit] +Description=Wireguard +After=network-online.target vpnclient-mount.service +Requires=network-online.target +Requisite=wireguard-mount.service + +[Service] +User=root +Group=root +Type=oneshot +EnvironmentFile=/snacks/wireguard/env +ExecStart=/snacks/wireguard/scripts/connect_basic.py +NetworkNamespacePath=/run/vpn/net +RemainAfterExit=true + +[Install] +WantedBy=multi-user.target diff --git a/systemd/wireguard-mount.service b/systemd/wireguard-mount.service index a6636e4..e593303 100644 --- a/systemd/wireguard-mount.service +++ b/systemd/wireguard-mount.service @@ -11,6 +11,7 @@ RuntimeDirectory=vpn RuntimeDirectoryMode=0755 ExecStart=/snacks/wireguard/bin/wireguard-mount PrivateNetwork=true +PrivateMounts=false [Install] WantedBy=multi-user.target