dotfiles/hosts/dlaptop/socks.nix
2024-03-20 01:29:58 +03:00

140 lines
4.5 KiB
Nix

{ pkgs, lib, ... }:
let
socksBuilder = attrs:
{
inherit (attrs) name;
value = {
enable = true;
after = [ "novpn.service" "network-online.target" ];
wants = [ "novpn.service" "network-online.target" ];
bindsTo = [ "novpn.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Restart = "on-failure";
RestartSec = "15";
Type = "simple";
NetworkNamespacePath = "/run/netns/novpn";
User = "socks";
Group = "socks";
};
script = attrs.script;
preStart = "while true; do ip addr show dev novpn1 | grep -q 'inet' && break; sleep 1; done";
path = with pkgs; [shadowsocks-libev shadowsocks-v2ray-plugin sing-box wireproxy iproute2 ];
};
};
# IP of the proxies is 192.168.150.2
socksed = [
{ name = "singbox-aus"; script = "sing-box run -c /run/secrets/singbox-aus"; } # port 4000
#{ name = "socks-warp"; script = "wireproxy -c /etc/wireguard/warp0.conf"; } # port 3333
];
start_novpn = pkgs.writeScriptBin "start_novpn" ''
#!${pkgs.bash}/bin/bash
configure_rules() {
ip rule del fwmark 100 table 150
ip rule del from 192.168.150.2 table 150
ip rule del to 192.168.150.2 table 150
ip route del default via $default_gateway dev $default_interface table 150
ip route del 192.168.150.2 via 192.168.150.1 dev novpn0 table 150
ip rule add fwmark 100 table 150
ip rule add from 192.168.150.2 table 150
ip rule add to 192.168.150.2 table 150
ip route add default via $default_gateway dev $default_interface table 150
ip route add 192.168.150.2 via 192.168.150.1 dev novpn0 table 150
}
default_gateway=$(ip route | awk '/default/ {print $3}')
default_interface=$(ip route | awk '/default/ {print $5}')
if [[ -z "$default_interface" ]]; then
echo "No default interface"
exit 1
fi
mkdir -p /etc/netns/novpn/
echo "nameserver 1.1.1.1" > /etc/netns/novpn/resolv.conf
echo "nameserver 1.1.0.1" >> /etc/netns/novpn/resolv.conf
sysctl -wq net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o "$default_interface" -j MASQUERADE
ip link add novpn0 type veth peer name novpn1
ip link set novpn1 netns novpn
ip addr add 192.168.150.1/24 dev novpn0
ip link set novpn0 up
ip netns exec novpn ip link set lo up
ip netns exec novpn ip addr add 192.168.150.2/24 dev novpn1
ip netns exec novpn ip link set novpn1 up
ip netns exec novpn ip route add default via 192.168.150.1
configure_rules
sleep 3
ip monitor route | while read -r event; do
case "$event" in
'local '*)
default_interface_new=$(ip route | awk '/default/ {print $5}')
default_gateway_new=$(ip route | awk '/default/ {print $3}')
if [[ ! -z "$default_interface_new" && ! -z "$default_gateway_new" ]]; then
default_interface=$default_interface_new
default_gateway=$default_gateway_new
fi
configure_rules
;;
esac
done
'';
stop_novpn = pkgs.writeScriptBin "stop_novpn" ''
#!${pkgs.bash}/bin/bash
rm -rf /etc/netns/novpn/
ip rule del fwmark 100 table 150
ip rule del from 192.168.150.2 table 150
ip rule del to 192.168.150.2 table 150
ip link del novpn0
ip netns del novpn
rm -rf /var/run/netns/novpn/
exit 0
'';
novpn = {
enable = true;
description = "novpn namespace";
after = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
wants = map (s: "${s.name}.service") socksed;
serviceConfig = {
Restart = "on-failure";
RestartSec = "15";
ExecStart = "${start_novpn}/bin/start_novpn";
ExecStop = "${stop_novpn}/bin/stop_novpn";
Type = "simple";
};
preStart = "${stop_novpn}/bin/stop_novpn && ip netns add novpn";
path = with pkgs; [ gawk iproute2 iptables sysctl coreutils ];
};
in {
users.users.socks = {
group = "socks";
isSystemUser = true;
};
users.groups.socks = {};
systemd.services = builtins.listToAttrs (map socksBuilder socksed) // { novpn = novpn; };
users.users.delta.packages = [ (pkgs.makeDesktopItem {
name = "firefox-russia";
desktopName = "Firefox Russia";
icon = "firefox-developer-edition";
exec = ''firejail --blacklist="/var/run/nscd" --ignore="include whitelist-run-common.inc" --netns=novpn firefox -P russia -no-remote'';
}) ];
}