#!/usr/bin/env bash # PiVPN: Uninstall Script ### FIXME: global: config storage, refactor all scripts to adhere to the storage ### FIXME: use variables where appropriate, reduce magic numbers by 99.9%, at least. # Find the rows and columns. Will default to 80x24 if it can not be detected. screen_size=$(stty size 2>/dev/null || echo 24 80) rows=$(echo "$screen_size" | awk '{print $1}') columns=$(echo "$screen_size" | awk '{print $2}') # Divide by two so the dialogs take up half of the screen, which looks nice. r=$(( rows / 2 )) c=$(( columns / 2 )) # Unless the screen is tiny r=$(( r < 20 ? 20 : r )) c=$(( c < 70 ? 70 : c )) PKG_MANAGER="apt-get" UPDATE_PKG_CACHE="${PKG_MANAGER} update" dnsmasqConfig="/etc/dnsmasq.d/02-pivpn.conf" setupVarsFile="setupVars.conf" setupConfigDir="/etc/pivpn" pivpnFilesDir="/usr/local/src/pivpn" pivpnScriptDir="/opt/pivpn" if [ -r "${setupConfigDir}/wireguard/${setupVarsFile}" ] && [ -r "${setupConfigDir}/openvpn/${setupVarsFile}" ]; then vpnStillExists=1 # Two protocols have been installed, check if the script has passed # an argument, otherwise ask the user which one he wants to remove if [ $# -ge 1 ]; then VPN="$1" echo "::: Uninstalling VPN: $VPN" else chooseVPNCmd=(whiptail --backtitle "Setup PiVPN" --title "Uninstall" --separate-output --radiolist "Both OpenVPN and WireGuard are installed, choose a VPN to uninstall (press space to select):" "${r}" "${c}" 2) VPNChooseOptions=(WireGuard "" on OpenVPN "" off) if VPN=$("${chooseVPNCmd[@]}" "${VPNChooseOptions[@]}" 2>&1 >/dev/tty) ; then echo "::: Uninstalling VPN: $VPN" VPN="${VPN,,}" else echo "::: Cancel selected, exiting...." exit 1 fi fi setupVars="${setupConfigDir}/${VPN}/${setupVarsFile}" else vpnStillExists=0 if [ -r "${setupConfigDir}/wireguard/${setupVarsFile}" ]; then setupVars="${setupConfigDir}/wireguard/${setupVarsFile}" elif [ -r "${setupConfigDir}/openvpn/${setupVarsFile}" ]; then setupVars="${setupConfigDir}/openvpn/${setupVarsFile}" fi fi if [ ! -f "${setupVars}" ]; then echo "::: Missing setup vars file!" exit 1 fi # shellcheck disable=SC1090 source "${setupVars}" ### FIXME: introduce global lib spinner(){ local pid=$1 local delay=0.50 local spinstr='/-\|' while ps a | awk '{print $1}' | grep -q "$pid"; do local temp=${spinstr#?} printf " [%c] " "$spinstr" local spinstr=$temp${spinstr%"$temp"} sleep $delay printf "\\b\\b\\b\\b\\b\\b" done printf " \\b\\b\\b\\b" } removeAll(){ # Stopping and disabling services echo "::: Stopping and disabling services..." if [ "$VPN" = "wireguard" ]; then systemctl stop wg-quick@wg0 systemctl disable wg-quick@wg0 &> /dev/null elif [ "$VPN" = "openvpn" ]; then systemctl stop openvpn systemctl disable openvpn &> /dev/null fi # Removing firewall rules. echo "::: Removing firewall rules..." if [ "$USING_UFW" -eq 1 ]; then ### FIXME: SC2154 ufw delete allow "${pivpnPORT}"/"${pivpnPROTO}" > /dev/null ### FIXME: SC2154 ufw route delete allow in on "${pivpnDEV}" from "${pivpnNET}/${subnetClass}" out on "${IPv4dev}" to any > /dev/null sed "/-I POSTROUTING -s ${pivpnNET}\\/${subnetClass} -o ${IPv4dev} -j MASQUERADE -m comment --comment ${VPN}-nat-rule/d" -i /etc/ufw/before.rules iptables -t nat -D POSTROUTING -s "${pivpnNET}/${subnetClass}" -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" ufw reload &> /dev/null elif [ "$USING_UFW" -eq 0 ]; then if [ "$INPUT_CHAIN_EDITED" -eq 1 ]; then iptables -D INPUT -i "${IPv4dev}" -p "${pivpnPROTO}" --dport "${pivpnPORT}" -j ACCEPT -m comment --comment "${VPN}-input-rule" fi if [ "$FORWARD_CHAIN_EDITED" -eq 1 ]; then iptables -D FORWARD -d "${pivpnNET}/${subnetClass}" -i "${IPv4dev}" -o "${pivpnDEV}" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "${VPN}-forward-rule" iptables -D FORWARD -s "${pivpnNET}/${subnetClass}" -i "${pivpnDEV}" -o "${IPv4dev}" -j ACCEPT -m comment --comment "${VPN}-forward-rule" fi iptables -t nat -D POSTROUTING -s "${pivpnNET}/${subnetClass}" -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" iptables-save > /etc/iptables/rules.v4 fi # Disable IPv4 forwarding if [ "${vpnStillExists}" -eq 0 ]; then sed -i '/net.ipv4.ip_forward=1/c\#net.ipv4.ip_forward=1' /etc/sysctl.conf sysctl -p fi # Purge dependencies echo "::: Purge dependencies..." for i in "${INSTALLED_PACKAGES[@]}"; do while true; do read -rp "::: Do you wish to remove $i from your system? [Y/n]: " yn case $yn in [Yy]* ) if [ "${i}" = "wireguard-tools" ]; then # The bullseye repo may not exist if wireguard was available at the # time of installation. if [ -f /etc/apt/sources.list.d/pivpn-bullseye-repo.list ]; then echo "::: Removing Debian Bullseye repo..." rm -f /etc/apt/sources.list.d/pivpn-bullseye-repo.list rm -f /etc/apt/preferences.d/pivpn-limit-bullseye echo "::: Updating package cache..." ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! fi if [ -f /etc/systemd/system/wg-quick@.service.d/override.conf ]; then rm -f /etc/systemd/system/wg-quick@.service.d/override.conf fi elif [ "${i}" = "unattended-upgrades" ]; then rm -rf /var/log/unattended-upgrades rm -rf /etc/apt/apt.conf.d/*periodic rm -rf /etc/apt/apt.conf.d/*unattended-upgrades elif [ "${i}" = "openvpn" ]; then if [ -f /etc/apt/sources.list.d/pivpn-openvpn-repo.list ]; then echo "::: Removing OpenVPN software repo..." rm -f /etc/apt/sources.list.d/pivpn-openvpn-repo.list echo "::: Updating package cache..." ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! fi deluser openvpn rm -f /etc/rsyslog.d/30-openvpn.conf rm -f /etc/logrotate.d/openvpn fi printf ":::\\tRemoving %s..." "$i"; $PKG_MANAGER -y remove --purge "$i" &> /dev/null & spinner $!; printf "done!\\n"; break ;; [Nn]* ) printf ":::\\tSkipping %s\\n" "$i"; break ;; * ) printf "::: You must answer yes or no!\\n";; esac done done # Take care of any additional package cleaning printf "::: Auto removing remaining dependencies..." $PKG_MANAGER -y autoremove &> /dev/null & spinner $!; printf "done!\\n"; printf "::: Auto cleaning remaining dependencies..." $PKG_MANAGER -y autoclean &> /dev/null & spinner $!; printf "done!\\n"; if [ -f "$dnsmasqConfig" ]; then rm -f "$dnsmasqConfig" pihole restartdns fi echo ":::" echo "::: Removing VPN configuration files..." if [ "$VPN" = "wireguard" ]; then rm -f /etc/wireguard/wg0.conf rm -rf /etc/wireguard/configs rm -rf /etc/wireguard/keys ### FIXME SC2154 rm -rf "$install_home/configs" elif [ "$VPN" = "openvpn" ]; then rm -rf /var/log/*openvpn* rm -f /etc/openvpn/server.conf rm -f /etc/openvpn/crl.pem rm -rf /etc/openvpn/easy-rsa rm -rf /etc/openvpn/ccd rm -rf "$install_home/ovpns" fi if [ "${vpnStillExists}" -eq 0 ]; then echo ":::" echo "::: Removing pivpn system files..." rm -rf "${setupConfigDir}" rm -rf "${pivpnFilesDir}" rm -f /var/log/*pivpn* rm -f /etc/bash_completion.d/pivpn unlink "${pivpnScriptDir}" unlink /usr/local/bin/pivpn else if [[ ${VPN} == 'wireguard' ]]; then othervpn='openvpn' else othervpn='wireguard' fi echo ":::" echo "::: Other VPN ${othervpn} still present, so not" echo "::: removing pivpn system files" rm -f "${setupConfigDir}/${VPN}/${setupVarsFile}" # Restore single pivpn script and bash completion for the remaining VPN $SUDO unlink /usr/local/bin/pivpn $SUDO ln -s -T "${pivpnFilesDir}/scripts/${othervpn}/pivpn.sh" /usr/local/bin/pivpn $SUDO ln -s -T "${pivpnFilesDir}/scripts/${othervpn}/bash-completion" /etc/bash_completion.d/pivpn # shellcheck disable=SC1091 . /etc/bash_completion.d/pivpn fi echo ":::" printf "::: Finished removing PiVPN from your system.\\n" printf "::: Reinstall by simpling running\\n:::\\n:::\\tcurl -L https://install.pivpn.io | bash\\n:::\\n::: at any time!\\n:::\\n" } askreboot(){ printf "It is \\e[1mstrongly\\e[0m recommended to reboot after un-installation.\\n" read -p "Would you like to reboot now? [y/n]: " -n 1 -r echo if [[ ${REPLY} =~ ^[Yy]$ ]]; then printf "\\nRebooting system...\\n" sleep 3 shutdown -r now fi } ######### SCRIPT ########### echo "::: Preparing to remove packages, be sure that each may be safely removed depending on your operating system." echo "::: (SAFE TO REMOVE ALL ON RASPBIAN)" while true; do read -rp "::: Do you wish to completely remove PiVPN configuration and installed packages from your system? (You will be prompted for each package) [y/n]: " yn case $yn in [Yy]* ) removeAll; askreboot; break;; [Nn]* ) printf "::: Not removing anything, exiting...\\n"; break;; esac done