nix-files/pkgs/additional/sane-scripts/src/sane-vpn

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