Compare commits
18 Commits
243f72c103
...
master
Author | SHA1 | Date | |
---|---|---|---|
ef0d8c75bd
|
|||
e8d8e1f5be
|
|||
d03c722517
|
|||
42af0652e4
|
|||
e2b7965287
|
|||
7ec5a4c22a
|
|||
6161013986
|
|||
7d37f12b93
|
|||
83caf49675
|
|||
3b54d77984
|
|||
27096b766c
|
|||
2627bad25d
|
|||
ea878ddc62
|
|||
1226491169
|
|||
2e7e3fda44
|
|||
579487db91
|
|||
e15d424a38
|
|||
875138142d
|
16
Makefile
16
Makefile
@ -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 enter_vpn
|
all: wireguard_mount wireguard_resolve vpn
|
||||||
|
|
||||||
wireguard_mount: src/wireguard-mount.c
|
wireguard_mount: src/wireguard-mount.c
|
||||||
mkdir -p bin
|
mkdir -p bin
|
||||||
@ -10,9 +10,9 @@ 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
|
||||||
|
|
||||||
enter_vpn: src/enter_vpn.c
|
vpn: src/vpn.c
|
||||||
mkdir -p bin
|
mkdir -p bin
|
||||||
gcc $(CFLAGS) -o bin/enter_vpn src/enter_vpn.c
|
gcc $(CFLAGS) -o bin/vpn src/vpn.c
|
||||||
|
|
||||||
format: src scripts
|
format: src scripts
|
||||||
clang-format -i src/*.c
|
clang-format -i src/*.c
|
||||||
@ -31,12 +31,14 @@ install_mount: systemd bin
|
|||||||
install_basic: systemd scripts bin
|
install_basic: systemd scripts bin
|
||||||
mkdir -p /snacks/wireguard/bin
|
mkdir -p /snacks/wireguard/bin
|
||||||
mkdir -p /snacks/wireguard/scripts
|
mkdir -p /snacks/wireguard/scripts
|
||||||
cp bin/wireguard-resolve.so /snacks/wireguard/bin/wireguard-resolve.so
|
|
||||||
cp systemd/vpnclient-wg-basic.service /etc/systemd/system/vpnclient-wg-basic.service
|
cp systemd/vpnclient-wg-basic.service /etc/systemd/system/vpnclient-wg-basic.service
|
||||||
cp scripts/connect_basic.py /snacks/wireguard/scripts/connect_basic.py
|
cp scripts/connect_basic.py /snacks/wireguard/scripts/connect_basic.py
|
||||||
cp scripts/inner_basic.sh /snacks/wireguard/scripts/inner_basic.sh
|
cp scripts/inner_basic.sh /snacks/wireguard/scripts/inner_basic.sh
|
||||||
|
cp scripts/is_root_namespace.py /snacks/wireguard/scripts/is_root_namespace.py
|
||||||
|
cp scripts/dns.nft /snacks/wireguard/scripts/dns.nft
|
||||||
|
cp scripts/create_conf.py /snacks/wireguard/scripts/create_conf.py
|
||||||
|
cat scripts/vpn_prompt.sh >> /etc/zsh/zshrc
|
||||||
|
cp bin/vpn /usr/local/bin/vpn
|
||||||
|
setcap cap_sys_admin,cap_sys_ptrace=ep /usr/local/bin/vpn
|
||||||
chmod -R 755 /snacks/wireguard
|
chmod -R 755 /snacks/wireguard
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import subprocess, os
|
import subprocess
|
||||||
|
import 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"
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import subprocess, os
|
import subprocess
|
||||||
|
import os
|
||||||
newenv = os.environ.copy()
|
|
||||||
newenv["LD_PRELOAD"] = "/snacks/wireguard/bin/wireguard-resolve.so"
|
|
||||||
|
|
||||||
|
|
||||||
def default_devices():
|
def default_devices():
|
||||||
@ -69,8 +67,13 @@ def wireguard():
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
["nsenter", "--net=/run/vpn/net", "/snacks/wireguard/scripts/inner_basic.sh"],
|
["nsenter", "--net=/proc/1/ns/net", "/snacks/wireguard/scripts/create_conf.py"],
|
||||||
env=newenv,
|
)
|
||||||
|
subprocess.run(
|
||||||
|
["/snacks/wireguard/scripts/inner_basic.sh"],
|
||||||
|
)
|
||||||
|
subprocess.run(
|
||||||
|
["nft", "-f", "/snacks/wireguard/scripts/dns.nft"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
39
scripts/create_conf.py
Normal file
39
scripts/create_conf.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import pydantic
|
||||||
|
from typing import Optional
|
||||||
|
import socket
|
||||||
|
|
||||||
|
|
||||||
|
class Config(pydantic.BaseModel):
|
||||||
|
public_key: str
|
||||||
|
host: str
|
||||||
|
port: int
|
||||||
|
private_key: str
|
||||||
|
|
||||||
|
|
||||||
|
def write_wg(config: Config):
|
||||||
|
wg_conf = (
|
||||||
|
"[Interface]\n"
|
||||||
|
f"privatekey = {config.private_key}\n\n"
|
||||||
|
"[Peer]\n"
|
||||||
|
f"publickey = {config.public_key}\n"
|
||||||
|
f"endpoint = {config.host}:{config.port}\n"
|
||||||
|
"persistentkeepalive = 20\n"
|
||||||
|
"allowedips = 0.0.0.0/0, ::/0\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open("/run/vpnclient/wg.conf", mode="w", encoding="utf-8") as f:
|
||||||
|
f.write(wg_conf)
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def get_config() -> Optional[Config]:
|
||||||
|
with open("/snacks/wireguard/wg.json", "r", encoding="utf-8") as f:
|
||||||
|
config = Config.model_validate_json(f.read())
|
||||||
|
config.host = socket.gethostbyname(config.host)
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
write_wg(get_config())
|
10
scripts/dns.nft
Normal file
10
scripts/dns.nft
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
table ip nat {
|
||||||
|
chain prerouting {
|
||||||
|
type nat hook prerouting priority 15; policy accept;
|
||||||
|
udp dport 53 dnat to 1.1.1.1
|
||||||
|
}
|
||||||
|
chain postrouting {
|
||||||
|
type nat hook postrouting priority 15; policy accept;
|
||||||
|
masquerade
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
wg setconf vpn /snacks/wireguard/wg.conf
|
wg setconf vpn /run/vpnclient/wg.conf
|
||||||
ip link set dev vpn up
|
ip link set dev vpn up
|
||||||
ip addr flush dev vpn
|
ip addr flush dev vpn
|
||||||
ip route flush dev vpn
|
ip route flush dev vpn
|
||||||
|
11
scripts/is_root_namespace.py
Normal file
11
scripts/is_root_namespace.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
with open("/proc/self/net/dev", "r") as f:
|
||||||
|
data = f.read()
|
||||||
|
match = re.search("^enp[0-9a-z]+:", data, re.MULTILINE)
|
||||||
|
if match is None:
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
sys.exit(0)
|
6
scripts/vpn_prompt.sh
Normal file
6
scripts/vpn_prompt.sh
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
if /snacks/wireguard/scripts/is_root_namespace.py
|
||||||
|
then
|
||||||
|
export PS1='%n@%m % %c %#'
|
||||||
|
else
|
||||||
|
export PS1='%F{red}<vpn>%f %n@%m % %c %#'
|
||||||
|
fi
|
@ -1,5 +1,6 @@
|
|||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <sys/prctl.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
@ -8,12 +9,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
char shell[128] = {0};
|
|
||||||
|
|
||||||
struct passwd *pw = getpwent();
|
|
||||||
strlcpy(shell, pw->pw_shell, sizeof(shell));
|
|
||||||
|
|
||||||
endpwent();
|
|
||||||
|
|
||||||
int fd = open("/run/vpn/net", 0);
|
int fd = open("/run/vpn/net", 0);
|
||||||
|
|
||||||
@ -30,7 +25,8 @@ int main() {
|
|||||||
perror("open /run/vpn/net");
|
perror("open /run/vpn/net");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
execl("csshell", "bshell", NULL);
|
|
||||||
|
execl("/usr/bin/zsh", "/usr/bin/zsh", NULL);
|
||||||
perror(NULL);
|
perror(NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -1,13 +1,28 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <systemd/sd-daemon.h>
|
#include <systemd/sd-daemon.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
int err = unshare(CLONE_NEWNET);
|
||||||
|
if (err) {
|
||||||
|
perror("Error");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = mkdir("/run/vpn", 0755);
|
||||||
|
if (err) {
|
||||||
|
perror("Error");
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
err = mount(mount_path, "/run/vpn", NULL, MS_BIND, NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
perror("Error");
|
perror("Error");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -12,6 +12,8 @@ EnvironmentFile=/snacks/wireguard/env
|
|||||||
ExecStart=/snacks/wireguard/scripts/connect_basic.py
|
ExecStart=/snacks/wireguard/scripts/connect_basic.py
|
||||||
NetworkNamespacePath=/run/vpn/net
|
NetworkNamespacePath=/run/vpn/net
|
||||||
RemainAfterExit=true
|
RemainAfterExit=true
|
||||||
|
RuntimeDirectory=vpnclient
|
||||||
|
RuntimeDirectoryMode=0600
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
@ -7,11 +7,7 @@ RefuseManualStop=true
|
|||||||
[Service]
|
[Service]
|
||||||
Type=notify
|
Type=notify
|
||||||
NotifyAccess=main
|
NotifyAccess=main
|
||||||
RuntimeDirectory=vpn
|
|
||||||
RuntimeDirectoryMode=0755
|
|
||||||
ExecStart=/snacks/wireguard/bin/wireguard-mount
|
ExecStart=/snacks/wireguard/bin/wireguard-mount
|
||||||
PrivateNetwork=true
|
|
||||||
PrivateMounts=false
|
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
Reference in New Issue
Block a user