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
|
||||
|
||||
all: wireguard_mount wireguard_resolve enter_vpn
|
||||
all: wireguard_mount wireguard_resolve vpn
|
||||
|
||||
wireguard_mount: src/wireguard-mount.c
|
||||
mkdir -p bin
|
||||
@ -10,9 +10,9 @@ 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
|
||||
|
||||
enter_vpn: src/enter_vpn.c
|
||||
vpn: src/vpn.c
|
||||
mkdir -p bin
|
||||
gcc $(CFLAGS) -o bin/enter_vpn src/enter_vpn.c
|
||||
gcc $(CFLAGS) -o bin/vpn src/vpn.c
|
||||
|
||||
format: src scripts
|
||||
clang-format -i src/*.c
|
||||
@ -31,12 +31,14 @@ install_mount: systemd bin
|
||||
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 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/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
|
||||
systemctl daemon-reload
|
||||
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess, os
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
newenv = os.environ.copy()
|
||||
newenv["LD_PRELOAD"] = "/snacks/wireguard/bin/wireguard-resolve.so"
|
||||
|
@ -1,8 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess, os
|
||||
|
||||
newenv = os.environ.copy()
|
||||
newenv["LD_PRELOAD"] = "/snacks/wireguard/bin/wireguard-resolve.so"
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
|
||||
def default_devices():
|
||||
@ -69,8 +67,13 @@ def wireguard():
|
||||
]
|
||||
)
|
||||
subprocess.run(
|
||||
["nsenter", "--net=/run/vpn/net", "/snacks/wireguard/scripts/inner_basic.sh"],
|
||||
env=newenv,
|
||||
["nsenter", "--net=/proc/1/ns/net", "/snacks/wireguard/scripts/create_conf.py"],
|
||||
)
|
||||
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
|
||||
wg setconf vpn /snacks/wireguard/wg.conf
|
||||
wg setconf vpn /run/vpnclient/wg.conf
|
||||
ip link set dev vpn up
|
||||
ip addr 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
|
||||
|
||||
#include <sys/prctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <sched.h>
|
||||
@ -8,12 +9,6 @@
|
||||
#include <unistd.h>
|
||||
|
||||
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);
|
||||
|
||||
@ -30,7 +25,8 @@ int main() {
|
||||
perror("open /run/vpn/net");
|
||||
return 1;
|
||||
}
|
||||
execl("csshell", "bshell", NULL);
|
||||
|
||||
execl("/usr/bin/zsh", "/usr/bin/zsh", NULL);
|
||||
perror(NULL);
|
||||
return 0;
|
||||
}
|
@ -1,13 +1,28 @@
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/mount.h>
|
||||
#include <systemd/sd-daemon.h>
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
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};
|
||||
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) {
|
||||
perror("Error");
|
||||
return 1;
|
||||
|
@ -12,6 +12,8 @@ EnvironmentFile=/snacks/wireguard/env
|
||||
ExecStart=/snacks/wireguard/scripts/connect_basic.py
|
||||
NetworkNamespacePath=/run/vpn/net
|
||||
RemainAfterExit=true
|
||||
RuntimeDirectory=vpnclient
|
||||
RuntimeDirectoryMode=0600
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
@ -7,11 +7,7 @@ RefuseManualStop=true
|
||||
[Service]
|
||||
Type=notify
|
||||
NotifyAccess=main
|
||||
RuntimeDirectory=vpn
|
||||
RuntimeDirectoryMode=0755
|
||||
ExecStart=/snacks/wireguard/bin/wireguard-mount
|
||||
PrivateNetwork=true
|
||||
PrivateMounts=false
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
Reference in New Issue
Block a user