#!/bin/bash
# wpm.sh - Wireguard (VPN) Peer Manager (zenity-based GUI)
# ========================================================
# Setup for Debian-based Linux distros:
# 0) install zenity, wireguard & openresolv apt packages
# 1) create several ProtonVPN wireguard peer profiles[1]
# 2) download profiles & place in /etc/wireguard/
# 3) run 'sudo chmod 705 /etc/wireguard'
# 4) run 'sudo chmod 600 /etc/wireguard/*.conf'
# 5) copy script to ~/bin & run 'chmod 700 ~/bin/wvpm.sh'
# 6) optionally create menu entry for Desktop Environment
#
# [1] wg-quick(8): "MY_WG_PEER_NAME" must be unique and
# limited to 15 charaters in length; doesn't include
# the ".conf" extension.
# ========================================================
# :adjust these as needed:
# location of wireguard peer config files:
WG_PEERS="/etc/wireguard/*.conf"
#
# ssh/sudo GUI password prompter:
export SUDO_ASKPASS=/usr/libexec/seahorse/ssh-askpass
#
# Width & Height of Zenity Window:
WZW=200
HZW=400
# ========================================================
# !!!!!!!! leave everything below this line alone !!!!!!!!
# ========================================================
# gather peer names into PEERS var:
for I in $WG_PEERS ;do
PEERS+="$(basename $I .conf) "
done
# tests if peer is enabled:
if_enabled() {
if [[ "$(systemctl is-enabled wg-quick@"$1")" == enabled ]]
then
return 0
else
return 1
fi
}
# tests if peer is active:
if_active() {
if [[ "$(systemctl is-active wg-quick@"$1")" == active ]]
then
return 0
else
return 1
fi
}
# set radio button TRUE if peer is UP:
button_state() {
if ( if_active "$1" ) ;then
echo 'TRUE'
else
echo 'FALSE'
fi
}
# report if peer is ENABLED/DISABLED at system startup:
startup_state() {
if ( if_enabled "$1" ) ;then
echo '√'
else
echo '-'
fi
}
# generate peer listing for zenity menu:
peer_list() {
for PEER in $PEERS ;do
echo "$(button_state $PEER)" "$PEER" "$(startup_state $PEER)"
done
}
# shutdown ALL peers:
all_down() {
for PEER in $PEERS ;do
( if_active "$PEER" ) && sudo -AE systemctl stop wg-quick@"$PEER"
done
}
# enable||disable *active* peer at startup:
active_peer_toggle() {
for PEER in $PEERS ;do
if ( if_active "$PEER" ) ;then
if ( if_enabled "$PEER" ) ;then
sudo -AE systemctl disable wg-quick@"$PEER"
else
sudo -AE systemctl enable wg-quick@"$PEER"
fi
else
sudo -AE systemctl disable wg-quick@"$PEER"
fi
done
}
# toggle peer (ARG1) to UP:
peer_up() {
all_down
sudo -AE systemctl start wg-quick@"$1"
}
# zenity window header text (here-doc; uses Pango markup):
zen_head() {
cat < VPN service: \
Proton\
VPN
Select a peer and click ON to switch.
OFF shuts down ALL peers.
√ => enabled at boot-up; click @BOOT to
toggle. Selected peer must be active.
EOF
}
# pick a peer or shut all down:
pick_peer() {
zenity --title='Wireguard Peer Manager' --width=$WZW --height=$HZW \
--list --radiolist --column='State ' --column='Wireguard Peers ' \
--column='enabled @ boot' --print-column=2 --text="$(zen_head)" \
--ok-label=ON --extra-button=OFF --extra-button=@BOOT --cancel-label=Quit \
$(peer_list)
}
# conditional action based on return value of pick_peer():
set_state() {
case "$1" in
'') exit 1 ;;
OFF) all_down ;;
@BOOT) active_peer_toggle ;;
*) peer_up $1 ;;
esac
}
# main - loops until set_state exit 1 (false):
main() {
while : ;do
set_state "$(pick_peer)"
sleep 1
done
}
main &