add tool to enter vpn

This commit is contained in:
Roy Olav Purser 2024-02-09 19:49:10 +01:00
parent 266bac7e21
commit 243f72c103
Signed by: roypur
GPG Key ID: 063DAA01D56E28CB
7 changed files with 148 additions and 33 deletions

12
.clang-format Normal file
View File

@ -0,0 +1,12 @@
---
AccessModifierOffset: 0
IndentAccessModifiers: true
AlignTrailingComments: true
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
BreakBeforeBinaryOperators: false
IndentWidth: 4
SortIncludes: false
NamespaceIndentation: All
...

View File

@ -1,6 +1,6 @@
CFLAGS = -std=gnu99 -pie -fPIC -pedantic -Wno-imports -Wunused -Wno-missing-field-initializers -Wextra -Wunreachable-code -O3 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 enter_vpn
wireguard_mount: src/wireguard-mount.c wireguard_mount: src/wireguard-mount.c
mkdir -p bin mkdir -p bin
@ -10,7 +10,16 @@ wireguard_resolve: src/resolve.c src/resolve.s
mkdir -p bin mkdir -p bin
gcc -shared -o bin/wireguard-resolve.so -nostdlib -fPIC src/resolve.c src/resolve.s gcc -shared -o bin/wireguard-resolve.so -nostdlib -fPIC src/resolve.c src/resolve.s
install_mount: systemd bin: enter_vpn: src/enter_vpn.c
mkdir -p bin
gcc $(CFLAGS) -o bin/enter_vpn src/enter_vpn.c
format: src scripts
clang-format -i src/*.c
ruff --fix scripts
black scripts
install_mount: systemd bin
mkdir -p /snacks/wireguard/bin mkdir -p /snacks/wireguard/bin
cp bin/wireguard-mount /snacks/wireguard/bin/wireguard-mount cp bin/wireguard-mount /snacks/wireguard/bin/wireguard-mount
cp systemd/wireguard-mount.service /etc/systemd/system/wireguard-mount.service cp systemd/wireguard-mount.service /etc/systemd/system/wireguard-mount.service
@ -28,3 +37,6 @@ install_basic: systemd scripts bin
cp scripts/inner_basic.sh /snacks/wireguard/scripts/inner_basic.sh cp scripts/inner_basic.sh /snacks/wireguard/scripts/inner_basic.sh
chmod -R 755 /snacks/wireguard chmod -R 755 /snacks/wireguard
systemctl daemon-reload systemctl daemon-reload

View File

@ -1,21 +1,26 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import subprocess,os import subprocess, os
newenv = os.environ.copy() newenv = os.environ.copy()
newenv["LD_PRELOAD"] = "/snacks/wireguard/bin/wireguard-resolve.so" newenv["LD_PRELOAD"] = "/snacks/wireguard/bin/wireguard-resolve.so"
def default_devices(): def default_devices():
with open("/proc/1/net/dev", "r") as f: with open("/proc/1/net/dev", "r") as f:
return f.read() return f.read()
def vpn_devices(): def vpn_devices():
with open("/proc/self/net/dev", "r") as f: with open("/proc/self/net/dev", "r") as f:
return f.read() return f.read()
def wireguard(): def wireguard():
try: try:
os.mkdir("/run/netns") os.mkdir("/run/netns")
except FileExistsError: except FileExistsError:
pass pass
try: try:
os.symlink("/run/vpn/net", "/run/netns/vpn") os.symlink("/run/vpn/net", "/run/netns/vpn")
os.symlink("/proc/1/ns/net", "/run/netns/default") os.symlink("/proc/1/ns/net", "/run/netns/default")
@ -37,19 +42,72 @@ def wireguard():
subprocess.run(["ip", "link", "del", "dev", "vpn"]) subprocess.run(["ip", "link", "del", "dev", "vpn"])
if "mynet0" not in vpn_devices(): if "mynet0" not in vpn_devices():
subprocess.run(["ip", "link", "add", "name", "mynet0", "type", "bridge"]) subprocess.run(["ip", "link", "add", "name", "mynet0", "type", "bridge"])
if "veth-inner" in default_devices(): if "veth-inner" in default_devices():
subprocess.run(["nsenter", "--net=/proc/1/ns/net", "ip", "link", "del", "dev", "veth-inner"]) subprocess.run(
[
"nsenter",
"--net=/proc/1/ns/net",
"ip",
"link",
"del",
"dev",
"veth-inner",
]
)
if "veth-outer" in default_devices(): if "veth-outer" in default_devices():
subprocess.run(["nsenter", "--net=/proc/1/ns/net", "ip", "link", "del", "dev", "veth-outer"]) subprocess.run(
[
"nsenter",
"--net=/proc/1/ns/net",
"ip",
"link",
"del",
"dev",
"veth-outer",
]
)
if "vpn" in default_devices(): if "vpn" in default_devices():
subprocess.run(["nsenter", "--net=/proc/1/ns/net", "ip", "link", "del", "dev", "vpn"]) subprocess.run(
["nsenter", "--net=/proc/1/ns/net", "ip", "link", "del", "dev", "vpn"]
)
subprocess.run(["modprobe", "wireguard"]) subprocess.run(["modprobe", "wireguard"])
subprocess.run(["nsenter", "--net=/proc/1/ns/net", "ip", "link", "add", "dev", "vpn", "type", "wireguard"]) subprocess.run(
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.sh"], env=newenv) "nsenter",
subprocess.run(["nsenter", "--net=/proc/1/ns/net", "/snacks/wireguard/scripts/outer.sh"], env=newenv) "--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.sh"],
env=newenv,
)
subprocess.run(
["nsenter", "--net=/proc/1/ns/net", "/snacks/wireguard/scripts/outer.sh"],
env=newenv,
)
try: try:
self_ns = os.readlink("/proc/self/ns/net") self_ns = os.readlink("/proc/self/ns/net")
@ -61,4 +119,3 @@ else:
wireguard() wireguard()
else: else:
print("This script should be called from the VPN network namespace.") print("This script should be called from the VPN network namespace.")

View File

@ -1,21 +1,26 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import subprocess,os import subprocess, os
newenv = os.environ.copy() newenv = os.environ.copy()
newenv["LD_PRELOAD"] = "/snacks/wireguard/bin/wireguard-resolve.so" newenv["LD_PRELOAD"] = "/snacks/wireguard/bin/wireguard-resolve.so"
def default_devices(): def default_devices():
with open("/proc/1/net/dev", "r") as f: with open("/proc/1/net/dev", "r") as f:
return f.read() return f.read()
def vpn_devices(): def vpn_devices():
with open("/proc/self/net/dev", "r") as f: with open("/proc/self/net/dev", "r") as f:
return f.read() return f.read()
def wireguard(): def wireguard():
try: try:
os.mkdir("/run/netns") os.mkdir("/run/netns")
except FileExistsError: except FileExistsError:
pass pass
try: try:
os.symlink("/run/vpn/net", "/run/netns/vpn") os.symlink("/run/vpn/net", "/run/netns/vpn")
os.symlink("/proc/1/ns/net", "/run/netns/default") os.symlink("/proc/1/ns/net", "/run/netns/default")
@ -32,12 +37,42 @@ def wireguard():
if "vpn" in vpn_devices(): if "vpn" in vpn_devices():
subprocess.run(["ip", "link", "del", "dev", "vpn"]) subprocess.run(["ip", "link", "del", "dev", "vpn"])
if "vpn" in default_devices(): if "vpn" in default_devices():
subprocess.run(["nsenter", "--net=/proc/1/ns/net", "ip", "link", "del", "dev", "vpn"]) subprocess.run(
["nsenter", "--net=/proc/1/ns/net", "ip", "link", "del", "dev", "vpn"]
)
subprocess.run(["modprobe", "wireguard"]) subprocess.run(["modprobe", "wireguard"])
subprocess.run(["nsenter", "--net=/proc/1/ns/net", "ip", "link", "add", "dev", "vpn", "type", "wireguard"]) subprocess.run(
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) "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: try:
self_ns = os.readlink("/proc/self/ns/net") self_ns = os.readlink("/proc/self/ns/net")
@ -49,4 +84,3 @@ else:
wireguard() wireguard()
else: else:
print("This script should be called from the VPN network namespace.") print("This script should be called from the VPN network namespace.")

View File

@ -1,11 +1,11 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#include <sched.h>
#include <fcntl.h> #include <fcntl.h>
#include <pwd.h> #include <pwd.h>
#include <sched.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <string.h> #include <string.h>
#include <unistd.h>
int main() { int main() {
char shell[128] = {0}; char shell[128] = {0};
@ -17,20 +17,20 @@ int main() {
int fd = open("/run/vpn/net", 0); int fd = open("/run/vpn/net", 0);
if(fd > 0) { if (fd > 0) {
int failure = setns(fd, CLONE_NEWNET); int failure = setns(fd, CLONE_NEWNET);
if(failure) { if (failure) {
perror("setns /run/vpn/net"); perror("setns /run/vpn/net");
} }
close(fd); close(fd);
if(failure) { if (failure) {
return 1; return 1;
} }
} else { } else {
perror("open /run/vpn/net"); perror("open /run/vpn/net");
return 1; return 1;
} }
execl(shell, shell, NULL); execl("csshell", "bshell", NULL);
perror(NULL); perror(NULL);
return 0; return 0;
} }

View File

@ -4,21 +4,21 @@ extern int override_socket(int domain, int type, int protocol);
extern int override_setns(int fd, int nstype); extern int override_setns(int fd, int nstype);
int socket(int domain, int type, int protocol) { int socket(int domain, int type, int protocol) {
if(domain > 15) { if (domain > 15) {
return override_socket(domain, type, protocol); return override_socket(domain, type, protocol);
} }
int fda = override_open("/proc/1/ns/net", 0); int fda = override_open("/proc/1/ns/net", 0);
int fdb = override_open("/run/netns/vpn", 0); int fdb = override_open("/run/netns/vpn", 0);
int retval = 0; int retval = 0;
if(fda > 0) { if (fda > 0) {
override_setns(fda, 0); override_setns(fda, 0);
override_close(fda); override_close(fda);
} }
retval = override_socket(domain, type, protocol); retval = override_socket(domain, type, protocol);
if(fdb > 0) { if (fdb > 0) {
override_setns(fdb, 0); override_setns(fdb, 0);
override_close(fdb); override_close(fdb);
} }

View File

@ -1,19 +1,19 @@
#include <sys/mount.h>
#include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <sys/mount.h>
#include <systemd/sd-daemon.h> #include <systemd/sd-daemon.h>
#include <unistd.h>
int main() { int main() {
char mount_path[32] = {0}; char mount_path[32] = {0};
snprintf(mount_path, sizeof(mount_path), "/proc/%d/ns", getpid()); snprintf(mount_path, sizeof(mount_path), "/proc/%d/ns", getpid());
int err = mount(mount_path, "/run/vpn", NULL, MS_BIND, NULL); int err = mount(mount_path, "/run/vpn", NULL, MS_BIND, NULL);
if(err) { if (err) {
perror("Error"); perror("Error");
return 1; return 1;
} }
sd_notify(0, "READY=1"); sd_notify(0, "READY=1");
while(1) { while (1) {
sleep(10); sleep(10);
} }
return 1; return 1;