Last active
December 5, 2025 05:45
-
-
Save BeeFox-sys/6c423850093d56258649aa4f4f8aeb55 to your computer and use it in GitHub Desktop.
VPN Manager for systems using Mullvad and Tailscale (without the intergreation)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/zsh | |
| # Requires: notify-send, Mullvad, Tailscale, ZSH | |
| # Option -n creates system notification | |
| flag_notify=0 | |
| zparseopts -D -K -- \ | |
| n=flag_notify | |
| status_func () { | |
| echo -e "\033[31;90mTailscale Status:\033[0m" | |
| tailscale status --peers=false | |
| echo -e "\033[31;90mMullvad Status:\033[0m" | |
| mullvad status | |
| } | |
| notify_func () { | |
| if [[ $flag_notify != "0" ]]; then | |
| notify-send -i mullvad-vpn -a "VPN Manager" "$1" | |
| fi | |
| echo "$1" | |
| } | |
| tailscale_status=$(tailscale status --peers=false) | |
| ts_toggle=1 | |
| if [[ $tailscale_status == "Tailscale is stopped." ]]; then | |
| ts_toggle=0 | |
| fi | |
| #echo $ts_toggle | |
| mullvad_status=$(mullvad status --json | jq -r .state) | |
| mv_toggle=1 | |
| if [[ $mullvad_status == "disconnected" ]]; then | |
| mv_toggle=0 | |
| fi | |
| #echo $mv_toggle | |
| connect_func () { | |
| tailscale down | |
| mullvad connect | |
| notify_func 'Connected to Mullvad and Disabled Tailscale!' | |
| } | |
| disconnect_func () { | |
| mullvad disconnect | |
| tailscale up | |
| notify_func 'Disconnected from Mullvad and Enabled Tailscale!' | |
| } | |
| run_func () { | |
| if [[ $ts_toggle == 1 && $mv_toggle == 0 ]]; then | |
| eval $1 | |
| elif [[ $ts_toggle == 0 && $mv_toggle == 1 ]]; then | |
| eval $2 | |
| elif [[ $ts_toggle == 0 && $mv_toggle == 0 ]]; then | |
| eval $3 | |
| else | |
| eval $4 | |
| fi | |
| } | |
| case $1 in | |
| status) | |
| status_func | |
| ;; | |
| up) | |
| run_func \ | |
| connect_func \ | |
| 'notify_func "Mullvad already up!"' \ | |
| 'notify_func "Both Mullvad and Tailscale Disabled. | |
| Enabling Mullvad!" && mullvad connect'\ | |
| 'notify_func "Both Mullvad and Tailscale Enabled. | |
| Disabling Tailscale!" && tailscale down' | |
| ;; | |
| down) | |
| run_func \ | |
| 'notify_func "Mullvad already down!"' \ | |
| disconnect_func \ | |
| 'notify_func "Both Mullvad and Tailscale Disabled. | |
| Enabling Tailscale!" && tailscale up'\ | |
| 'notify_func "Both Mullvad and Tailscale Enabled. | |
| Disabling Mullvad!" && mullvad disconnect' | |
| ;; | |
| toggle) | |
| run_func \ | |
| connect_func \ | |
| disconnect_func \ | |
| 'notify_func "Both Mullvad and Tailscale Disabled. | |
| Enabling Tailscale!" && tailscale up'\ | |
| 'notify_func "Both Mullvad and Tailscale Enabled. | |
| Disabling Tailscale!" && tailscale down' | |
| ;; | |
| *) | |
| echo "Usage: $0 [-n] {up|down|toggle|status}" | |
| exit 1 | |
| ;; | |
| esac | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment