92 lines
2.3 KiB
Plaintext
Executable File
92 lines
2.3 KiB
Plaintext
Executable File
#!/usr/bin/env nix-shell
|
|
#!nix-shell -i bash -p coreutils-full -p gnugrep -p gnused -p sane-scripts.ip-check -p systemd
|
|
|
|
oper="$1"
|
|
shift
|
|
region="$1"
|
|
shift
|
|
# region should be e.g. `us` or `ukr`
|
|
|
|
get_vpns() {
|
|
vpns=$(systemctl list-unit-files \
|
|
| grep vpn- | cut -f 1 -d ' ' \
|
|
| sed s'/\.service$//' \
|
|
| sed s'/^vpn-//' \
|
|
| sed s'/^ovpnd-//'
|
|
)
|
|
}
|
|
|
|
canonicalize_region() {
|
|
if [ "$region" = "default" ]; then
|
|
# TODO: don't special-case this, but e.g. grab whichever VPN has the lowest `ip rule` priority.
|
|
region="us"
|
|
fi
|
|
if networkctl list "br-$region"; then
|
|
bridge="br-$region"
|
|
elif networkctl list "br-ovpnd-$region"; then
|
|
bridge="br-ovpnd-$region"
|
|
fi
|
|
|
|
if systemctl -q list-unit-files "$region"; then
|
|
service="$region"
|
|
elif systemctl -q list-unit-files "vpn-$region.service"; then
|
|
service="vpn-$region.service"
|
|
elif systemctl -q list-unit-files "vpn-ovpnd-$region.service"; then
|
|
service="vpn-ovpnd-$region.service"
|
|
elif systemctl -q list-unit-files "wg-quick-$region.service"; then
|
|
service="wg-quick-$region.service"
|
|
fi
|
|
}
|
|
|
|
usage() {
|
|
rc="$1"
|
|
msg="$2"
|
|
|
|
get_vpns
|
|
test -n "$msg" && echo "$msg"
|
|
|
|
echo "usage:"
|
|
echo "sane-vpn up REGION"
|
|
echo "sane-vpn down REGION"
|
|
echo "sane-vpn do REGION COMMAND [COMMAND ARGS ...]"
|
|
echo "sane-vpn help"
|
|
echo ""
|
|
echo "regions:"
|
|
echo "$vpns"
|
|
|
|
test -n "$rc" && exit "$rc"
|
|
}
|
|
|
|
vpn_toggle() {
|
|
verb="$1"
|
|
canonicalize_region
|
|
test -n "$service" || usage 1 "invalid region '$region'"
|
|
|
|
echo before: $(sane-ip-check --no-upnp)
|
|
sudo systemctl "$verb" "$service"
|
|
echo after: $(sane-ip-check --no-upnp)
|
|
}
|
|
|
|
vpn_do() {
|
|
canonicalize_region
|
|
test -n "$bridge" || usage 1 "invalid or unsupported region '$region'"
|
|
|
|
# this is nasty. `networkctl --json=pretty` gives json output that can be consumed with jq,
|
|
# but it converts the DNS server to octets ([10, 78, 79, 1]), which i would have to reassemble
|
|
dns=$(networkctl status "$bridge" | grep 'DNS:' | sed 's/ *DNS: //')
|
|
|
|
firejail --noprofile --net="$bridge" --dns="$dns" "$@"
|
|
}
|
|
|
|
if [ "$oper" == up ]; then
|
|
vpn_toggle start
|
|
elif [ "$oper" == down ]; then
|
|
vpn_toggle stop
|
|
elif [ "$oper" == do ]; then
|
|
vpn_do "$@"
|
|
elif [ "$oper" == help ] || [ "$oper" == --help ] || [ -z "$oper" ]; then
|
|
usage 0
|
|
else
|
|
usage 1 "invalid operation '$oper'"
|
|
fi
|