diff --git a/auto_install/install.sh b/auto_install/install.sh index e6e631c..bedbb8e 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -21,7 +21,8 @@ PKG_CACHE="/var/lib/apt/lists/" UPDATE_PKG_CACHE="${PKG_MANAGER} update" PKG_INSTALL="${PKG_MANAGER} --yes --no-install-recommends install" PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true" -PIVPN_DEPS=(openvpn git tar wget grep iptables-persistent dnsutils expect whiptail net-tools) +PIVPN_DEPS=(openvpn git tar wget grep iptables-persistent dnsutils expect whiptail net-tools grepcidr jq) + ### ### pivpnGitUrl="https://github.com/pivpn/pivpn.git" @@ -29,7 +30,7 @@ pivpnFilesDir="/etc/.pivpn" easyrsaVer="3.0.6" easyrsaRel="https://github.com/OpenVPN/easy-rsa/releases/download/v${easyrsaVer}/EasyRSA-unix-v${easyrsaVer}.tgz" -# Raspbian's unattended-upgrades package downloads Debian's config, so this is the link for the proper config +# Raspbian's unattended-upgrades package downloads Debian's config, so this is the link for the proper config UNATTUPG_RELEASE="1.9" UNATTUPG_CONFIG="https://github.com/mvo5/unattended-upgrades/archive/${UNATTUPG_RELEASE}.tar.gz" @@ -92,18 +93,19 @@ distro_check() { source /etc/os-release PLAT=$(awk '{print $1}' <<< "$NAME") VER="$VERSION_ID" - declare -A VER_MAP=(["9"]="stretch" ["8"]="jessie" ["18.04"]="bionic" ["16.04"]="xenial" ["14.04"]="trusty") + declare -A VER_MAP=(["10"]="buster" ["9"]="stretch" ["8"]="jessie" ["18.04"]="bionic" ["16.04"]="xenial" ["14.04"]="trusty") OSCN=${VER_MAP["${VER}"]} fi if [[ ${OSCN} != "bionic" ]]; then PIVPN_DEPS+=(dhcpcd5) + fi case ${PLAT} in Ubuntu|Raspbian|Debian|Devuan) case ${OSCN} in - trusty|xenial|jessie|stretch) + trusty|xenial|jessie|stretch|buster) ;; *) maybeOS_Support @@ -474,11 +476,21 @@ notify_package_updates_available() { fi } +install_bitwarden() { + # Install Bitwarden through NPM - this is the preferred installation method since NPM makes it easy to update the package + apt-get install -y nodejs npm + npm install -g @bitwarden/cli +} + install_dependent_packages() { # Install packages passed in via argument array # No spinner - conflicts with set -e declare -a argArray1=("${!1}") + if [[ ${OSCN} == "buster" ]]; then + $SUDO update-alternatives --set iptables /usr/sbin/iptables-legacy + $SUDO update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy + fi echo iptables-persistent iptables-persistent/autosave_v4 boolean true | $SUDO debconf-set-selections echo iptables-persistent iptables-persistent/autosave_v6 boolean false | $SUDO debconf-set-selections @@ -528,7 +540,7 @@ getGitFiles() { echo ":::" echo "::: Checking for existing base files..." if is_repo "${1}"; then - update_repo "${1}" + update_repo "${1}" "${2}" else make_repo "${1}" "${2}" fi @@ -561,6 +573,9 @@ update_repo() { # Pull the latest commits echo -n "::: Updating repo in $1..." $SUDO rm -rf "${1}" + # Go back to /etc otherwhise git will complain when the current working directory has + # just been deleted (/etc/.pivpn). + cd /etc $SUDO git clone -q --depth 1 --no-single-branch "${2}" "${1}" > /dev/null & spinner $! cd "${1}" || exit 1 if [ -z "${TESTING+x}" ]; then @@ -664,7 +679,7 @@ setClientDNS() { do strInvalid="Invalid" - if OVPNDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "" 3>&1 1>&2 2>&3) + if OVPNDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), separated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "" 3>&1 1>&2 2>&3) then OVPNDNS1=$(echo "$OVPNDNS" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}') OVPNDNS2=$(echo "$OVPNDNS" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}') @@ -745,15 +760,22 @@ setCustomDomain() { } confOpenVPN() { - # Generate a random, alphanumeric identifier of 16 characters for this server so that we can use verify-x509-name later that is unique for this server installation. Source: Earthgecko (https://gist.github.com/earthgecko/3089509) - NEW_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1) - SERVER_NAME="server_${NEW_UUID}" + # Grab the existing Hostname + HOST_NAME=$(hostname -s) + # Generate a random UUID for this server so that we can use verify-x509-name later that is unique for this server installation. + NEW_UUID=$(&1 1>&2 2>&3) @@ -847,7 +868,7 @@ EOF fi # Build the server - ${SUDOE} ./easyrsa build-server-full ${SERVER_NAME} nopass + EASYRSA_CERT_EXPIRE=3650 ${SUDOE} ./easyrsa build-server-full ${SERVER_NAME} nopass if [[ ${useUpdateVars} == false ]]; then if [[ ${APPLY_TWO_POINT_FOUR} == false ]]; then @@ -963,8 +984,21 @@ confNetwork() { $SUDO sed "/delete these required/i *nat\n:POSTROUTING ACCEPT [0:0]\n-I POSTROUTING -s 10.8.0.0/24 -o $IPv4dev -j MASQUERADE\nCOMMIT\n" -i /etc/ufw/before.rules # Insert rules at the beginning of the chain (in case there are other rules that may drop the traffic) $SUDO ufw insert 1 allow "$PORT"/"$PROTO" >/dev/null - # Don't forward everything, just the traffic originated from the VPN subnet - $SUDO ufw route insert 1 allow in on tun0 from 10.8.0.0/24 out on "$IPv4dev" to any >/dev/null + + # https://askubuntu.com/a/712202 + INSTALLED_UFW=$(dpkg-query --showformat='${Version}' --show ufw) + MINIMUM_UFW=0.34 + + if $SUDO dpkg --compare-versions "$INSTALLED_UFW" ge "$MINIMUM_UFW"; then + # Don't forward everything, just the traffic originated from the VPN subnet + $SUDO ufw route insert 1 allow in on tun0 from 10.8.0.0/24 out on "$IPv4dev" to any >/dev/null + echo 0 > /tmp/OLD_UFW + else + # This ufw version does not support route command, fallback to policy change + $SUDO sed -i "s/\(DEFAULT_FORWARD_POLICY=\).*/\1\"ACCEPT\"/" /etc/default/ufw + echo 1 > /tmp/OLD_UFW + fi + $SUDO ufw reload >/dev/null echo "::: UFW configuration completed." fi @@ -974,7 +1008,43 @@ confNetwork() { # else configure iptables if [[ $noUFW -eq 1 ]]; then echo 1 > /tmp/noUFW + + # Now some checks to detect which rules we need to add. On a newly installed system all policies + # should be ACCEPT, so the only required rule would be the MASQUERADE one. + $SUDO iptables -t nat -I POSTROUTING -s 10.8.0.0/24 -o "$IPv4dev" -j MASQUERADE + + # Count how many rules are in the INPUT and FORWARD chain. When parsing input from + # iptables -S, '^-P' skips the policies and 'ufw-' skips ufw chains (in case ufw was found + # installed but not enabled). + + # Grep returns non 0 exit code where there are no matches, however that would make the script exit, + # for this reasons we use '|| true' to force exit code 0 + INPUT_RULES_COUNT="$($SUDO iptables -S INPUT | grep -vcE '(^-P|ufw-)' || true)" + FORWARD_RULES_COUNT="$($SUDO iptables -S FORWARD | grep -vcE '(^-P|ufw-)' || true)" + + INPUT_POLICY="$($SUDO iptables -S INPUT | grep '^-P' | awk '{print $3}')" + FORWARD_POLICY="$($SUDO iptables -S FORWARD | grep '^-P' | awk '{print $3}')" + + # If rules count is not zero, we assume we need to explicitly allow traffic. Same conclusion if + # there are no rules and the policy is not ACCEPT. Note that rules are being added to the top of the + # chain (using -I). + + if [ "$INPUT_RULES_COUNT" -ne 0 ] || [ "$INPUT_POLICY" != "ACCEPT" ]; then + $SUDO iptables -I INPUT 1 -i "$IPv4dev" -p "$PROTO" --dport "$PORT" -j ACCEPT + INPUT_CHAIN_EDITED=1 + else + INPUT_CHAIN_EDITED=0 + fi + + if [ "$FORWARD_RULES_COUNT" -ne 0 ] || [ "$FORWARD_POLICY" != "ACCEPT" ]; then + $SUDO iptables -I FORWARD 1 -d 10.8.0.0/24 -i "$IPv4dev" -o tun0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + $SUDO iptables -I FORWARD 2 -s 10.8.0.0/24 -i tun0 -o "$IPv4dev" -j ACCEPT + FORWARD_CHAIN_EDITED=1 + else + FORWARD_CHAIN_EDITED=0 + fi + case ${PLAT} in Ubuntu|Debian|Devuan) $SUDO iptables-save | $SUDO tee /etc/iptables/rules.v4 > /dev/null @@ -987,7 +1057,13 @@ confNetwork() { echo 0 > /tmp/noUFW fi + echo "$INPUT_CHAIN_EDITED" > /tmp/INPUT_CHAIN_EDITED + echo "$FORWARD_CHAIN_EDITED" > /tmp/FORWARD_CHAIN_EDITED + $SUDO cp /tmp/noUFW /etc/pivpn/NO_UFW + $SUDO cp /tmp/OLD_UFW /etc/pivpn/OLD_UFW + $SUDO cp /tmp/INPUT_CHAIN_EDITED /etc/pivpn/INPUT_CHAIN_EDITED + $SUDO cp /tmp/FORWARD_CHAIN_EDITED /etc/pivpn/FORWARD_CHAIN_EDITED } confOVPN() { @@ -1295,6 +1371,9 @@ main() { # Notify user of package availability notify_package_updates_available + # Install packages for Bitwarden + install_bitwarden + # Install packages used by this installation script install_dependent_packages PIVPN_DEPS[@] @@ -1375,7 +1454,7 @@ main() { $SUDO systemctl start openvpn.service ;; esac - + # Ensure that cached writes reach persistent storage echo "::: Flushing writes to disk..." sync diff --git a/pivpn b/pivpn index 8f82a93..495ffcf 100644 --- a/pivpn +++ b/pivpn @@ -58,6 +58,7 @@ function helpFunc { echo ":::" echo "::: Commands:" echo "::: -a, add [nopass] Create a client ovpn profile, optional nopass" + echo "::: -b,--bitwarden Create and save a client through Bitwarden" echo "::: -c, clients List any connected clients to the server" echo "::: -d, debug Start a debugging session if having trouble" echo "::: -l, list List all valid and revoked certificates" @@ -74,6 +75,7 @@ fi # Handle redirecting to specific functions based on arguments case "$1" in "-a" | "add" ) makeOVPNFunc "$@";; +"-b" | "bitwarden" ) makeOVPNFunc "$@";; "-c" | "clients" ) listClientsFunc;; "-d" | "debug" ) debugFunc;; "-l" | "list" ) listOVPNFunc;; diff --git a/scripts/makeOVPN.sh b/scripts/makeOVPN.sh index e937475..29605eb 100755 --- a/scripts/makeOVPN.sh +++ b/scripts/makeOVPN.sh @@ -13,14 +13,16 @@ INSTALL_USER=$(cat /etc/pivpn/INSTALL_USER) helpFunc() { echo "::: Create a client ovpn profile, optional nopass" echo ":::" - echo "::: Usage: pivpn <-a|add> [-n|--name ] [-p|--password ]|[nopass] [-d|--days ] [-h|--help]" + echo "::: Usage: pivpn <-a|add> [-n|--name ] [-p|--password ]|[nopass] [-d|--days ] [-i|--iOS] [-h|--help]" echo ":::" echo "::: Commands:" echo "::: [none] Interactive mode" echo "::: nopass Create a client without a password" + echo "::: -b,--bitwarden Create and save a client through Bitwarden" echo "::: -d,--days Expire the certificate after specified number of days (default: 1080)" echo "::: -n,--name Name for the Client (default: '"$(hostname)"')" echo "::: -p,--password Password for the Client (no default)" + echo "::: -i,--iOS Generate a certificate that leverages iOS keychain" echo "::: -h,--help Show this help dialog" } @@ -59,13 +61,19 @@ do fi DAYS="$_val" ;; - -h|--help) + -i|--iOS) + iOS=1 + ;; + -h|--help) helpFunc exit 0 ;; nopass) NO_PASS="1" ;; + -b|--bitwarden) + BITWARDEN="2" + ;; *) echo "Error: Got an unexpected argument '$1'" helpFunc @@ -91,6 +99,52 @@ EOF } +function useBitwarden() { + + # login and unlock vault + printf "****Bitwarden Login****" + printf "\n" + SESSION_KEY=`bw login --raw` + export BW_SESSION=$SESSION_KEY + printf "Successfully Logged in!" + printf "\n" + + # ask user for username + printf "Enter the username: " + read -r NAME + + # check name + until [[ "$NAME" =~ ^[a-zA-Z0-9.@_-]+$ && ${NAME::1} != "." && ${NAME::1} != "-" ]] + do + echo "Name can only contain alphanumeric characters and these characters (.-@_). The name also cannot start with a dot (.) or a dash (-). Please try again." + # ask user for username again + printf "Enter the username: " + read -r NAME + done + + + # ask user for length of password + printf "Please enter the length of characters you want your password to be (minimum 12): " + read -r LENGTH + + # check length + until [[ "$LENGTH" -gt 11 && "$LENGTH" -lt 129 ]] + do + echo "Password must be between from 12 to 128 characters, please try again." + # ask user for length of password + printf "Enter the length of characters you want your password to be (minimum 12): " + read -r LENGTH + done + + printf "Creating a PiVPN item for your vault..." + printf "\n" + # create a new item for your PiVPN Password + PASSWD=`bw generate -usln --length $LENGTH` + bw get template item | jq '.login.type = "1"'| jq '.name = "PiVPN"' | jq -r --arg NAME "$NAME" '.login.username = $NAME' | jq -r --arg PASSWD "$PASSWD" '.login.password = $PASSWD' | bw encode | bw create item + bw logout + +} + function keyPASS() { if [[ -z "${PASSWD}" ]]; then @@ -137,6 +191,11 @@ EOF } +# bitWarden first +if [[ "${BITWARDEN}" =~ "2" ]]; then + useBitwarden +fi + if [ -z "${NAME}" ]; then printf "Enter a Name for the Client: " read -r NAME @@ -147,7 +206,7 @@ if [[ ${NAME::1} == "." ]] || [[ ${NAME::1} == "-" ]]; then exit 1 fi -if [[ "${NAME}" =~ [^a-zA-Z0-9\.\-\@\_] ]]; then +if [[ "${NAME}" =~ [^a-zA-Z0-9.@_-] ]]; then echo "Name can only contain alphanumeric characters and these characters (.-@_)." exit 1 fi @@ -228,15 +287,65 @@ if [ ! -f "${CA}" ]; then fi echo "CA public Key found: $CA" -#Confirm the tls-auth ta key file exists +#Confirm the tls key file exists if [ ! -f "${TA}" ]; then - echo "[ERROR]: tls-auth Key not found: $TA" + echo "[ERROR]: tls Private Key not found: $TA" exit fi -echo "tls-auth Private Key found: $TA" +echo "tls Private Key found: $TA" + +## Added new step to create an .ovpn12 file that can be stored on iOS keychain +## This step is more secure method and does not require the end-user to keep entering passwords, or storing the client private cert where it can be easily tampered +## https://openvpn.net/faq/how-do-i-use-a-client-certificate-and-private-key-from-the-ios-keychain/ +if [ "$iOS" = "1" ]; then + #Generates the .ovpn file WITHOUT the client private key + { + # Start by populating with the default file + cat "${DEFAULT}" + + #Now, append the CA Public Cert + echo "" + cat "${CA}" + echo "" + + #Next append the client Public Cert + echo "" + sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' < "issued/${NAME}${CRT}" + echo "" + + #Finally, append the TA Private Key + if [ -f /etc/pivpn/TWO_POINT_FOUR ]; then + echo "" + cat "${TA}" + echo "" + else + echo "" + cat "${TA}" + echo "" + fi + + } > "${NAME}${FILEEXT}" + + # Copy the .ovpn profile to the home directory for convenient remote access + + printf "========================================================\n" + printf "Generating an .ovpn12 file for use with iOS devices\n" + printf "Please remember the export password\n" + printf "as you will need this import the certificate on your iOS device\n" + printf "========================================================\n" + openssl pkcs12 -passin env:$PASSWD -export -in issued/${NAME}${CRT} -inkey private/${NAME}${KEY} -certfile ${CA} -name ${NAME} -out /home/$INSTALL_USER/ovpns/$NAME.ovpn12 + chown "$INSTALL_USER" "/home/$INSTALL_USER/ovpns/$NAME.ovpn12" + chmod 600 "/home/$INSTALL_USER/ovpns/$NAME.ovpn12" + printf "========================================================\n" + printf "\e[1mDone! %s successfully created!\e[0m \n" "$NAME.ovpn12" + printf "You will need to transfer both the .ovpn and .ovpn12 files\n" + printf "to your iOS device.\n" + printf "========================================================\n\n" +else + #This is the standard non-iOS configuration #Ready to make a new .ovpn file -{ + { # Start by populating with the default file cat "${DEFAULT}" @@ -255,7 +364,7 @@ echo "tls-auth Private Key found: $TA" cat "private/${NAME}${KEY}" echo "" - #Finally, append the TA Private Key + #Finally, append the tls Private Key if [ -f /etc/pivpn/TWO_POINT_FOUR ]; then echo "" cat "${TA}" @@ -266,7 +375,32 @@ echo "tls-auth Private Key found: $TA" echo "" fi -} > "${NAME}${FILEEXT}" + } > "${NAME}${FILEEXT}" + +fi + +if [ ! -d "/home/$INSTALL_USER/ovpns" ]; then + mkdir "/home/$INSTALL_USER/ovpns" + chmod 0777 -R "/home/$INSTALL_USER/ovpns" +fi + +# If user is using Bitwarden, have them login again to submit their .ovpn file to their vault +printf "Would you like to export your .ovpn file to your Bitwarden vault? (y or n)" +read -r RESPONSE +if [ $RESPONSE == "y" ] || [ $RESPONSE == "Y" ]; then + $OVPN_FILE="$(< "/etc/openvpn/easy-rsa/pki/$NAME$FILEEXT")" + # Login to Bitwarden + printf "****Bitwarden Login****" + printf "\n" + SESSION_KEY=`bw login --raw` + export BW_SESSION=$SESSION_KEY + printf "Successfully Logged in!" + printf "\n" + # Create a Bitwarden secure note to export the .ovpn file + bw get template item | jq '.name = "PiVPN OVPN File"' | jq '.type = 2' | jq -r --arg VAL "$OVPN_FILE" '.notes = $VAL' | jq ".secureNote = $(bw get template item.secureNote)" | bw encode | bw create item + bw logout + exit + fi # Copy the .ovpn profile to the home directory for convenient remote access INSTALL_HOME=$(cat /etc/passwd | grep "$INSTALL_USER" | cut -d: -f6) diff --git a/scripts/pivpnDebug.sh b/scripts/pivpnDebug.sh index 849c70d..25a4bf1 100755 --- a/scripts/pivpnDebug.sh +++ b/scripts/pivpnDebug.sh @@ -5,6 +5,10 @@ PORT=$(cat /etc/pivpn/INSTALL_PORT) PROTO=$(cat /etc/pivpn/INSTALL_PROTO) IPv4dev="$(cat /etc/pivpn/pivpnINTERFACE)" REMOTE="$(grep 'remote ' /etc/openvpn/easy-rsa/pki/Default.txt | awk '{print $2}')" +NO_UFW=$(cat /etc/pivpn/NO_UFW) +OLD_UFW=$(cat /etc/pivpn/NO_UFW) +INPUT_CHAIN_EDITED="$(cat /etc/pivpn/INPUT_CHAIN_EDITED)" +FORWARD_CHAIN_EDITED="$(cat /etc/pivpn/FORWARD_CHAIN_EDITED)" ERR=0 echo -e "::::\t\t\e[4mPiVPN debug\e[0m\t\t ::::" @@ -13,8 +17,9 @@ echo -e "::::\t\t\e[4mLatest commit\e[0m\t\t ::::" git --git-dir /etc/.pivpn/.git log -n 1 printf "=============================================\n" echo -e "::::\t \e[4mInstallation settings\e[0m \t ::::" +# Use the wildcard so setupVars.conf.update.bak from the previous install is not shown for filename in /etc/pivpn/*; do - if [ "$filename" != "/etc/pivpn/setupVars.conf" ]; then + if [[ "$filename" != "/etc/pivpn/setupVars.conf"* ]]; then echo "$filename -> $(cat "$filename")" fi done @@ -45,7 +50,7 @@ else fi fi -if [ "$(cat /etc/pivpn/NO_UFW)" -eq 1 ]; then +if [ "$NO_UFW" -eq 1 ]; then if iptables -t nat -C POSTROUTING -s 10.8.0.0/24 -o "${IPv4dev}" -j MASQUERADE &> /dev/null; then echo ":: [OK] Iptables MASQUERADE rule set" @@ -56,11 +61,42 @@ if [ "$(cat /etc/pivpn/NO_UFW)" -eq 1 ]; then iptables -t nat -F iptables -t nat -I POSTROUTING -s 10.8.0.0/24 -o "${IPv4dev}" -j MASQUERADE iptables-save > /etc/iptables/rules.v4 - iptables-restore < /etc/iptables/rules.v4 echo "Done" fi fi + + if [ "$INPUT_CHAIN_EDITED" -eq 1 ]; then + + if iptables -C INPUT -i "$IPv4dev" -p "$PROTO" --dport "$PORT" -j ACCEPT &> /dev/null; then + echo ":: [OK] Iptables INPUT rule set" + else + ERR=1 + read -r -p ":: [ERR] Iptables INPUT rule is not set, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]]; then + iptables -I INPUT 1 -i "$IPv4dev" -p "$PROTO" --dport "$PORT" -j ACCEPT + iptables-save > /etc/iptables/rules.v4 + echo "Done" + fi + fi + fi + + if [ "$FORWARD_CHAIN_EDITED" -eq 1 ]; then + + if iptables -C FORWARD -s 10.8.0.0/24 -i tun0 -o "$IPv4dev" -j ACCEPT &> /dev/null; then + echo ":: [OK] Iptables FORWARD rule set" + else + ERR=1 + read -r -p ":: [ERR] Iptables FORWARD rule is not set, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]]; then + iptables -I FORWARD 1 -d 10.8.0.0/24 -i "$IPv4dev" -o tun0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + iptables -I FORWARD 2 -s 10.8.0.0/24 -i tun0 -o "$IPv4dev" -j ACCEPT + iptables-save > /etc/iptables/rules.v4 + echo "Done" + fi + fi + fi + else if LANG="en_US.UTF-8" ufw status | grep -qw 'active'; then @@ -97,15 +133,30 @@ else fi fi - if iptables -C ufw-user-forward -i tun0 -o "${IPv4dev}" -s 10.8.0.0/24 -j ACCEPT &> /dev/null; then - echo ":: [OK] Ufw forwarding rule set" + if [ "$OLD_UFW" -eq 1 ]; then + FORWARD_POLICY="$(iptables -S FORWARD | grep '^-P' | awk '{print $3}')" + if [ "$FORWARD_POLICY" = "ACCEPT" ]; then + echo ":: [OK] Ufw forwarding policy is accept" + else + ERR=1 + read -r -p ":: [ERR] Ufw forwarding policy is not 'ACCEPT', attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]]; then + sed -i "s/\(DEFAULT_FORWARD_POLICY=\).*/\1\"ACCEPT\"/" /etc/default/ufw + ufw reload > /dev/null + echo "Done" + fi + fi else - ERR=1 - read -r -p ":: [ERR] Ufw forwarding rule is not set, attempt fix now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]]; then - ufw route insert 1 allow in on tun0 from 10.8.0.0/24 out on "$IPv4dev" to any - ufw reload - echo "Done" + if iptables -C ufw-user-forward -i tun0 -o "${IPv4dev}" -s 10.8.0.0/24 -j ACCEPT &> /dev/null; then + echo ":: [OK] Ufw forwarding rule set" + else + ERR=1 + read -r -p ":: [ERR] Ufw forwarding rule is not set, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]]; then + ufw route insert 1 allow in on tun0 from 10.8.0.0/24 out on "$IPv4dev" to any + ufw reload + echo "Done" + fi fi fi @@ -151,7 +202,17 @@ fi printf "=============================================\n" echo -e ":::: \e[4mSnippet of the server log\e[0m ::::" -tail -20 /var/log/openvpn.log +tail -20 /var/log/openvpn.log > /tmp/snippet + +# Regular expession taken from https://superuser.com/a/202835, it will match invalid IPs +# like 123.456.789.012 but it's fine because the log only contains valid ones. +declare -a IPS_TO_HIDE=($(grepcidr -v 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 /tmp/snippet | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | uniq)) +for IP in "${IPS_TO_HIDE[@]}"; do + sed -i "s/$IP/REDACTED/g" /tmp/snippet +done + +cat /tmp/snippet +rm /tmp/snippet printf "=============================================\n" echo -e "::::\t\t\e[4mDebug complete\e[0m\t\t ::::" diff --git a/scripts/removeOVPN.sh b/scripts/removeOVPN.sh index f6bd09c..462b25c 100755 --- a/scripts/removeOVPN.sh +++ b/scripts/removeOVPN.sh @@ -114,6 +114,7 @@ for (( ii = 0; ii < ${#CERTS_TO_REVOKE[@]}; ii++)); do rm -rf "pki/reqs/${CERTS_TO_REVOKE[ii]}.req" rm -rf "pki/private/${CERTS_TO_REVOKE[ii]}.key" rm -rf "pki/issued/${CERTS_TO_REVOKE[ii]}.crt" + rm -rf "${INSTALL_HOME}/ovpns/${CERTS_TO_REVOKE[ii]}.ovpn" rm -rf "/etc/openvpn/easy-rsa/pki/${CERTS_TO_REVOKE[ii]}.ovpn" cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index 2053645..ecd2765 100755 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -1,28 +1,16 @@ #!/usr/bin/env bash # PiVPN: Uninstall Script -# Must be root to uninstall -if [[ $EUID -eq 0 ]];then - echo "::: You are root." -else - echo "::: Sudo will be used for the uninstall." - # Check if it is actually installed - # If it isn't, exit because the unnstall cannot complete - if [[ $(dpkg-query -s sudo) ]];then - export SUDO="sudo" - else - echo "::: Please install sudo or run this as root." - exit 1 - fi -fi - INSTALL_USER=$(cat /etc/pivpn/INSTALL_USER) INSTALL_HOME=$(cat /etc/passwd | grep "$INSTALL_USER" | cut -d: -f6) PLAT=$(cat /etc/pivpn/DET_PLATFORM) NO_UFW=$(cat /etc/pivpn/NO_UFW) +OLD_UFW=$(cat /etc/pivpn/NO_UFW) PORT=$(cat /etc/pivpn/INSTALL_PORT) PROTO=$(cat /etc/pivpn/INSTALL_PROTO) IPv4dev="$(cat /etc/pivpn/pivpnINTERFACE)" +INPUT_CHAIN_EDITED="$(cat /etc/pivpn/INPUT_CHAIN_EDITED)" +FORWARD_CHAIN_EDITED="$(cat /etc/pivpn/FORWARD_CHAIN_EDITED)" # 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) @@ -60,7 +48,7 @@ echo ":::" while true; do read -rp "::: Do you wish to remove $i from your system? [y/n]: " yn case $yn in - [Yy]* ) printf ":::\tRemoving %s..." "$i"; $SUDO apt-get -y remove --purge "$i" &> /dev/null & spinner $!; printf "done!\n"; + [Yy]* ) printf ":::\tRemoving %s..." "$i"; apt-get -y remove --purge "$i" &> /dev/null & spinner $!; printf "done!\n"; if [ "$i" == "openvpn" ]; then UINST_OVPN=1 ; fi if [ "$i" == "unattended-upgrades" ]; then UINST_UNATTUPG=1 ; fi break;; @@ -75,44 +63,63 @@ echo ":::" # Take care of any additional package cleaning printf "::: Auto removing remaining dependencies..." - $SUDO apt-get -y autoremove &> /dev/null & spinner $!; printf "done!\n"; + apt-get -y autoremove &> /dev/null & spinner $!; printf "done!\n"; printf "::: Auto cleaning remaining dependencies..." - $SUDO apt-get -y autoclean &> /dev/null & spinner $!; printf "done!\n"; + apt-get -y autoclean &> /dev/null & spinner $!; printf "done!\n"; echo ":::" # Removing pivpn files echo "::: Removing pivpn system files..." + $SUDO rm -rf /opt/pivpn &> /dev/null $SUDO rm -rf /etc/.pivpn &> /dev/null $SUDO rm -rf $INSTALL_HOME/ovpns &> /dev/null - $SUDO rm -rf /var/log/*pivpn* &> /dev/null - $SUDO rm -rf /var/log/*openvpn* &> /dev/null + rm -rf /var/log/*pivpn* &> /dev/null + rm -rf /var/log/*openvpn* &> /dev/null if [[ $UINST_OVPN = 1 ]]; then - $SUDO rm -rf /etc/openvpn &> /dev/null + rm -rf /etc/openvpn &> /dev/null if [[ $PLAT == "Ubuntu" || $PLAT == "Debian" ]]; then printf "::: Removing openvpn apt source..." - $SUDO rm -rf /etc/apt/sources.list.d/swupdate.openvpn.net.list &> /dev/null - $SUDO apt-get -qq update & spinner $!; printf "done!\n"; + rm -rf /etc/apt/sources.list.d/swupdate.openvpn.net.list &> /dev/null + apt-get -qq update & spinner $!; printf "done!\n"; fi fi if [[ $UINST_UNATTUPG = 1 ]]; then - $SUDO rm -rf /var/log/unattended-upgrades - $SUDO rm -rf /etc/apt/apt.conf.d/*periodic + rm -rf /var/log/unattended-upgrades + rm -rf /etc/apt/apt.conf.d/*periodic fi - $SUDO rm -rf /etc/pivpn &> /dev/null - $SUDO rm /usr/local/bin/pivpn &> /dev/null - $SUDO rm /etc/bash_completion.d/pivpn + rm -rf /etc/pivpn &> /dev/null + rm /usr/local/bin/pivpn &> /dev/null + rm /etc/bash_completion.d/pivpn # Disable IPv4 forwarding sed -i '/net.ipv4.ip_forward=1/c\#net.ipv4.ip_forward=1' /etc/sysctl.conf sysctl -p if [[ $NO_UFW -eq 0 ]]; then - $SUDO sed -z "s/*nat\n:POSTROUTING ACCEPT \[0:0\]\n-I POSTROUTING -s 10.8.0.0\/24 -o $IPv4dev -j MASQUERADE\nCOMMIT\n\n//" -i /etc/ufw/before.rules - $SUDO ufw delete allow "$PORT"/"$PROTO" >/dev/null - $SUDO ufw route delete allow in on tun0 from 10.8.0.0/24 out on "$IPv4dev" to any >/dev/null - $SUDO ufw reload >/dev/null + + sed -z "s/*nat\n:POSTROUTING ACCEPT \[0:0\]\n-I POSTROUTING -s 10.8.0.0\/24 -o $IPv4dev -j MASQUERADE\nCOMMIT\n\n//" -i /etc/ufw/before.rules + ufw delete allow "$PORT"/"$PROTO" >/dev/null + if [ "$OLD_UFW" -eq 1 ]; then + sed -i "s/\(DEFAULT_FORWARD_POLICY=\).*/\1\"DROP\"/" /etc/default/ufw + else + ufw route delete allow in on tun0 from 10.8.0.0/24 out on "$IPv4dev" to any >/dev/null + fi + ufw reload >/dev/null + else + iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o "${IPv4dev}" -j MASQUERADE + + if [ "$INPUT_CHAIN_EDITED" -eq 1 ]; then + iptables -D INPUT -i "$IPv4dev" -p "$PROTO" --dport "$PORT" -j ACCEPT + fi + + if [ "$FORWARD_CHAIN_EDITED" -eq 1 ]; then + iptables -D FORWARD -d 10.8.0.0/24 -i "$IPv4dev" -o tun0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + iptables -D FORWARD -s 10.8.0.0/24 -i tun0 -o "$IPv4dev" -j ACCEPT + fi + + iptables-save > /etc/iptables/rules.v4 fi echo ":::"