From 87a12898d21fcc5497168b4fe39e91ce9d0f226d Mon Sep 17 00:00:00 2001 From: 4s3ti <4s3ti@protonmail.com> Date: Fri, 24 Jan 2020 16:18:06 +0100 Subject: [PATCH 01/14] added link to server status dashboard --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 2261afd..2602590 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ ![WireGuard + OpenVPN logo](logos.jpg) +[Is pivpn.dev down?](https://p.datadoghq.com/sb/od1t7p4rmqi6x1fm-cd513e61b0eb77a5d5f6a52fe0662205?theme=dark) +----- + About ----- From e725b8cdb53b63ce1739c2717deffb49dcd3b10f Mon Sep 17 00:00:00 2001 From: 4s3ti <4s3ti@protonmail.com> Date: Fri, 24 Jan 2020 16:25:44 +0100 Subject: [PATCH 02/14] Replaced Header with bold instead --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 2602590..1d1f07a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ ![WireGuard + OpenVPN logo](logos.jpg) -[Is pivpn.dev down?](https://p.datadoghq.com/sb/od1t7p4rmqi6x1fm-cd513e61b0eb77a5d5f6a52fe0662205?theme=dark) ------ +**[Is pivpn.dev down?](https://p.datadoghq.com/sb/od1t7p4rmqi6x1fm-cd513e61b0eb77a5d5f6a52fe0662205?theme=dark)** About ----- From deee38b20ef76291e912acab710e1257e90c3af2 Mon Sep 17 00:00:00 2001 From: Orazio Date: Fri, 24 Jan 2020 17:12:36 +0100 Subject: [PATCH 03/14] More safeguards, some fixes, standardized some code, WireGuard update script, removed redundant code - Add curl as a dependency for those who run the script without 'curl URL | bash'. - Use POSIX 'command -v' instead of 'hash'. - Check if packages have actually been installed and abort execution if they have not. - Fixed issue with getStaticIPv4Settings() that prevented existing network settings to be used as static IP settings when running the script unattended with empty $IPv4addr and $IPv4gw variables. - Exit if processing wireguard-linux-compat fails. - Exit if 50unattended-upgrades fails to extract. - Exit clientSTAT.sh if the wg0 interface is not available. - Moved the Self Check to a single script since dedicated versions were very similar. - Add 'pivpn -wg' to update WireGuard for users running Raspbian with armv6l kernel. --- auto_install/install.sh | 119 +++++++++++++-------- scripts/backup.sh | 13 ++- scripts/openvpn/makeOVPN.sh | 2 +- scripts/openvpn/pivpnDebug.sh | 156 +-------------------------- scripts/self_check.sh | 170 ++++++++++++++++++++++++++++++ scripts/uninstall.sh | 2 +- scripts/update.sh | 25 +++-- scripts/wireguard/bash-completion | 4 +- scripts/wireguard/clientSTAT.sh | 6 +- scripts/wireguard/makeCONF.sh | 14 +-- scripts/wireguard/pivpn | 9 +- scripts/wireguard/pivpnDEBUG.sh | 156 +-------------------------- scripts/wireguard/removeCONF.sh | 14 +-- scripts/wireguard/wgUPDATE.sh | 132 +++++++++++++++++++++++ unattended_openvpn_example.conf | 2 + unattended_wireguard_example.conf | 2 + 16 files changed, 444 insertions(+), 382 deletions(-) create mode 100755 scripts/self_check.sh create mode 100755 scripts/wireguard/wgUPDATE.sh diff --git a/auto_install/install.sh b/auto_install/install.sh index da79685..e4817c4 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -24,12 +24,12 @@ PKG_INSTALL="${PKG_MANAGER} --yes --no-install-recommends install" PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true" # Dependencies that are required by the script, regardless of the VPN protocol chosen -BASE_DEPS=(git tar wget grep dnsutils whiptail net-tools bsdmainutils) +BASE_DEPS=(git tar wget curl grep dnsutils whiptail net-tools bsdmainutils) # Dependencies that where actually installed by the script. For example if the script requires # grep and dnsutils but dnsutils is already installed, we save grep here. This way when uninstalling # PiVPN we won't prompt to remove packages that may have been installed by the user for other reasons -TO_INSTALL=() +INSTALLED_PACKAGES=() easyrsaVer="3.0.6" easyrsaRel="https://github.com/OpenVPN/easy-rsa/releases/download/v${easyrsaVer}/EasyRSA-unix-v${easyrsaVer}.tgz" @@ -60,8 +60,8 @@ r=$(( r < 20 ? 20 : r )) c=$(( c < 70 ? 70 : c )) # Find IP used to route to outside world -IPv4addr=$(ip route get 192.0.2.1 | awk '{print $7}') -IPv4gw=$(ip route get 192.0.2.1 | awk '{print $3}') +CurrentIPv4addr=$(ip route get 192.0.2.1 | awk '{print $7}') +CurrentIPv4gw=$(ip route get 192.0.2.1 | awk '{print $3}') availableInterfaces=$(ip -o link | awk '/state UP/ {print $2}' | cut -d':' -f1 | cut -d'@' -f1) ######## SCRIPT ############ @@ -195,7 +195,7 @@ main(){ fi # Save installation setting to the final location - echo "TO_INSTALL=(${TO_INSTALL[*]})" >> /tmp/setupVars.conf + echo "INSTALLED_PACKAGES=(${INSTALLED_PACKAGES[*]})" >> /tmp/setupVars.conf $SUDO cp /tmp/setupVars.conf "$setupVars" installScripts @@ -235,7 +235,7 @@ askAboutExistingInstall(){ # distroCheck, maybeOSSupport, noOSSupport distroCheck(){ # if lsb_release command is on their system - if hash lsb_release 2>/dev/null; then + if command -v lsb_release > /dev/null; then PLAT=$(lsb_release -si) OSCN=$(lsb_release -sc) @@ -436,7 +436,7 @@ preconfigurePackages(){ # if ufw is enabled, configure that. # running as root because sometimes the executable is not in the user's $PATH - if $SUDO bash -c 'hash ufw' 2>/dev/null; then + if $SUDO bash -c 'command -v ufw' > /dev/null; then if LANG=en_US.UTF-8 $SUDO ufw status | grep -q inactive; then USING_UFW=0 else @@ -456,25 +456,46 @@ preconfigurePackages(){ } installDependentPackages(){ + declare -a TO_INSTALL=() + # Install packages passed in via argument array # No spinner - conflicts with set -e declare -a argArray1=("${!1}") for i in "${argArray1[@]}"; do echo -n "::: Checking for $i..." - if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep -q "ok installed"; then - echo " installed!" - else - TO_INSTALL+=("${i}") - echo " not installed!" - fi + if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep -q "ok installed"; then + echo " installed!" + else + echo " not installed!" + # Add this package to the list of packages in the argument array that need to be installed + TO_INSTALL+=("${i}") + fi done - if command -v debconf-apt-progress &> /dev/null; then + if command -v debconf-apt-progress > /dev/null; then # shellcheck disable=SC2086 - $SUDO debconf-apt-progress -- ${PKG_INSTALL} "${argArray1[@]}" + $SUDO debconf-apt-progress -- ${PKG_INSTALL} "${TO_INSTALL[@]}" else - ${PKG_INSTALL} "${argArray1[@]}" + # shellcheck disable=SC2086 + $SUDO ${PKG_INSTALL} "${TO_INSTALL[@]}" + fi + + local FAILED=0 + + for i in "${TO_INSTALL[@]}"; do + if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep -q "ok installed"; then + echo "::: Package $i successfully installed!" + # Add this package to the total list of packages that were actually installed by the script + INSTALLED_PACKAGES+=("${i}") + else + echo "::: Failed to install $i!" + ((FAILED++)) + fi + done + + if [ "$FAILED" -gt 0 ]; then + exit 1 fi } @@ -596,28 +617,21 @@ getStaticIPv4Settings() { if [ "${runUnattended}" = 'true' ]; then if [ -z "$dhcpReserv" ] || [ "$dhcpReserv" -ne 1 ]; then - local INVALID_STATIC_IPV4_SETTINGS=0 + local MISSING_STATIC_IPV4_SETTINGS=0 if [ -z "$IPv4addr" ]; then echo "::: Missing static IP address" - INVALID_STATIC_IPV4_SETTINGS=1 + ((MISSING_STATIC_IPV4_SETTINGS++)) fi if [ -z "$IPv4gw" ]; then echo "::: Missing static IP gateway" - INVALID_STATIC_IPV4_SETTINGS=1 + ((MISSING_STATIC_IPV4_SETTINGS++)) fi - if [ "$INVALID_STATIC_IPV4_SETTINGS" -eq 1 ]; then - echo "::: Incomplete static IP settings" - exit 1 - fi + if [ "$MISSING_STATIC_IPV4_SETTINGS" -eq 0 ]; then - if [ -z "$IPv4addr" ] && [ -z "$IPv4gw" ]; then - echo "::: No static IP settings, using current settings" - echo "::: Your static IPv4 address: ${IPv4addr}" - echo "::: Your static IPv4 gateway: ${IPv4gw}" - else + # If both settings are not empty, check if they are valid and proceed if validIP "${IPv4addr%/*}"; then echo "::: Your static IPv4 address: ${IPv4addr}" else @@ -631,6 +645,22 @@ getStaticIPv4Settings() { echo "::: ${IPv4gw} is not a valid IP address" exit 1 fi + + elif [ "$MISSING_STATIC_IPV4_SETTINGS" -eq 1 ]; then + + # If either of the settings is missing, consider the input inconsistent + echo "::: Incomplete static IP settings" + exit 1 + + elif [ "$MISSING_STATIC_IPV4_SETTINGS" -eq 2 ]; then + + # If both of the settings are missing, assume the user wants to use current settings + IPv4addr="${CurrentIPv4addr}" + IPv4gw="${CurrentIPv4gw}" + echo "::: No static IP settings, using current settings" + echo "::: Your static IPv4 address: ${IPv4addr}" + echo "::: Your static IPv4 gateway: ${IPv4gw}" + fi else echo "::: Skipping setting static IP address" @@ -645,6 +675,8 @@ getStaticIPv4Settings() { local ipSettingsCorrect # Some users reserve IP addresses on another DHCP Server or on their routers, # Lets ask them if they want to make any changes to their interfaces. + IPv4addr="${CurrentIPv4addr}" + IPv4gw="${CurrentIPv4gw}" if (whiptail --backtitle "Calibrating network interface" --title "DHCP Reservation" --yesno \ "Are you Using DHCP Reservation on your Router/DHCP Server? These are your current Network Settings: @@ -1021,7 +1053,7 @@ installWireGuard(){ WG_TOOLS_SOURCE="https://git.zx2c4.com/wireguard-tools/snapshot/wireguard-tools-${WG_TOOLS_SNAPSHOT}.tar.xz" echo "::: Downloading wireguard-tools source code... " - wget -qO- "${WG_TOOLS_SOURCE}" | $SUDO tar Jxf - --directory /usr/src + wget -qO- "${WG_TOOLS_SOURCE}" | $SUDO tar xJ --directory /usr/src echo "done!" ## || exits if cd fails. @@ -1042,7 +1074,7 @@ installWireGuard(){ # files from the file system echo "::: Installing WireGuard tools... " if $SUDO checkinstall --pkgname wireguard-tools --pkgversion "${WG_TOOLS_SNAPSHOT}" -y; then - TO_INSTALL+=("wireguard-tools") + INSTALLED_PACKAGES+=("wireguard-tools") echo "done!" else echo "failed!" @@ -1055,16 +1087,16 @@ installWireGuard(){ WG_MODULE_SOURCE="https://git.zx2c4.com/wireguard-linux-compat/snapshot/wireguard-linux-compat-${WG_MODULE_SNAPSHOT}.tar.xz" echo "::: Downloading wireguard-linux-compat source code... " - wget -qO- "${WG_MODULE_SOURCE}" | $SUDO tar Jxf - --directory /usr/src + wget -qO- "${WG_MODULE_SOURCE}" | $SUDO tar xJ --directory /usr/src echo "done!" # Rename wireguard-linux-compat folder and move the source code to the parent folder # such that dkms picks up the module when referencing wireguard/"${WG_MODULE_SNAPSHOT}" cd /usr/src && \ - $SUDO mv wireguard-linux-compat-"${WG_MODULE_SNAPSHOT}" wireguard-"${WG_MODULE_SNAPSHOT}" + $SUDO mv wireguard-linux-compat-"${WG_MODULE_SNAPSHOT}" wireguard-"${WG_MODULE_SNAPSHOT}" && \ cd wireguard-"${WG_MODULE_SNAPSHOT}" && \ $SUDO mv src/* . && \ - $SUDO rmdir src + $SUDO rmdir src || exit 1 echo "::: Adding WireGuard modules via DKMS... " if $SUDO dkms add wireguard/"${WG_MODULE_SNAPSHOT}"; then @@ -1086,7 +1118,7 @@ installWireGuard(){ echo "::: Installing WireGuard modules via DKMS... " if $SUDO dkms install wireguard/"${WG_MODULE_SNAPSHOT}"; then - TO_INSTALL+=("wireguard-dkms") + INSTALLED_PACKAGES+=("wireguard-dkms") echo "done!" else echo "failed!" @@ -1113,7 +1145,7 @@ installWireGuard(){ echo "::: Installing WireGuard from PPA... " $SUDO add-apt-repository ppa:wireguard/wireguard -y - $SUDO ${UPDATE_PKG_CACHE} + $SUDO ${UPDATE_PKG_CACHE} &> /dev/null PIVPN_DEPS=(qrencode wireguard wireguard-tools wireguard-dkms linux-headers-generic) installDependentPackages PIVPN_DEPS[@] @@ -1259,7 +1291,7 @@ askClientDNS(){ fi # Detect and offer to use Pi-hole - if command -v pihole &>/dev/null; then + if command -v pihole > /dev/null; then if (whiptail --backtitle "Setup PiVPN" --title "Pi-hole" --yesno "We have detected a Pi-hole installation, do you want to use it as the DNS server for the VPN, so you get ad blocking on the go?" ${r} ${c}); then pivpnDNS1="$vpnGw" echo "interface=$pivpnDEV" | $SUDO tee /etc/dnsmasq.d/02-pivpn.conf > /dev/null @@ -1574,7 +1606,7 @@ confOpenVPN(){ fi # Get easy-rsa - wget -qO- "${easyrsaRel}" | $SUDO tar xz -C /etc/openvpn + wget -qO- "${easyrsaRel}" | $SUDO tar xz --directory /etc/openvpn $SUDO mv /etc/openvpn/EasyRSA-v${easyrsaVer} /etc/openvpn/easy-rsa # fix ownership $SUDO chown -R root:root /etc/openvpn/easy-rsa @@ -1939,7 +1971,7 @@ askUnattendedUpgrades(){ confUnattendedUpgrades(){ local PIVPN_DEPS - PIVPN_DEPS+=(unattended-upgrades) + PIVPN_DEPS=(unattended-upgrades) installDependentPackages PIVPN_DEPS[@] aptConfDir="/etc/apt/apt.conf.d" @@ -1956,10 +1988,13 @@ confUnattendedUpgrades(){ # Fix Raspbian config if [ "$PLAT" = "Raspbian" ]; then - wget -q -O "/tmp/${UNATTUPG_RELEASE}.tar.gz" "$UNATTUPG_CONFIG" - cd /tmp/ && $SUDO tar xzf "/tmp/${UNATTUPG_RELEASE}.tar.gz" - $SUDO cp /tmp/"unattended-upgrades-$UNATTUPG_RELEASE/data/50unattended-upgrades.Raspbian" "${aptConfDir}/50unattended-upgrades" - $SUDO rm -rf "/tmp/unattended-upgrades-$UNATTUPG_RELEASE" + wget -qO- "$UNATTUPG_CONFIG" | $SUDO tar xz --directory "${aptConfDir}" "unattended-upgrades-$UNATTUPG_RELEASE/data/50unattended-upgrades.Raspbian" --strip-components 2 + if test -s "${aptConfDir}/50unattended-upgrades.Raspbian"; then + $SUDO mv "${aptConfDir}/50unattended-upgrades.Raspbian" "${aptConfDir}/50unattended-upgrades" + else + echo "$0: ERR: Failed to download \"50unattended-upgrades.Raspbian\"." + exit 1 + fi fi # Add the remaining settings for all other distributions diff --git a/scripts/backup.sh b/scripts/backup.sh index a8e6a1d..56b46e5 100755 --- a/scripts/backup.sh +++ b/scripts/backup.sh @@ -1,9 +1,16 @@ #!/bin/bash -# shellcheck disable=SC1091 -source /etc/pivpn/setupVars.conf -# shellcheck disable=SC1090 + backupdir=pivpnbackup date=$(date +%Y%m%d-%H%M%S) +setupVars="/etc/pivpn/setupVars.conf" + +if [ ! -f "${setupVars}" ]; then + echo "::: Missing setup vars file!" + exit 1 +fi + +# shellcheck disable=SC1090 +source "${setupVars}" checkbackupdir(){ diff --git a/scripts/openvpn/makeOVPN.sh b/scripts/openvpn/makeOVPN.sh index ec89435..4e4bcc4 100755 --- a/scripts/openvpn/makeOVPN.sh +++ b/scripts/openvpn/makeOVPN.sh @@ -91,7 +91,7 @@ do NO_PASS="1" ;; -b|--bitwarden) - if command -v bw &> /dev/null; then + if command -v bw > /dev/null; then BITWARDEN="2" else echo "Bitwarden not found, please install bitwarden" diff --git a/scripts/openvpn/pivpnDebug.sh b/scripts/openvpn/pivpnDebug.sh index df4e938..d72fd8a 100755 --- a/scripts/openvpn/pivpnDebug.sh +++ b/scripts/openvpn/pivpnDebug.sh @@ -2,7 +2,6 @@ # This scripts runs as root setupVars="/etc/pivpn/setupVars.conf" -ERR=0 if [ ! -f "${setupVars}" ]; then echo "::: Missing setup vars file!" @@ -17,14 +16,6 @@ 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 - echo "$filename -> $(cat "$filename")" - fi -done -printf "=============================================\n" -echo -e "::::\t\e[4msetupVars file shown below\e[0m\t ::::" sed "s/$pivpnHOST/REDACTED/" < /etc/pivpn/setupVars.conf printf "=============================================\n" echo -e ":::: \e[4mServer configuration shown below\e[0m ::::" @@ -37,152 +28,7 @@ echo -e ":::: \t\e[4mRecursive list of files in\e[0m\t ::::\n::: \e[4m/etc/openv ls -LR /etc/openvpn/easy-rsa/pki/ -Ireqs -Icerts_by_serial printf "=============================================\n" echo -e "::::\t\t\e[4mSelf check\e[0m\t\t ::::" - -if [ "$(cat /proc/sys/net/ipv4/ip_forward)" -eq 1 ]; then - echo ":: [OK] IP forwarding is enabled" -else - ERR=1 - read -r -p ":: [ERR] IP forwarding is not enabled, attempt fix now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - sed -i '/net.ipv4.ip_forward=1/s/^#//g' /etc/sysctl.conf - sysctl -p - echo "Done" - fi -fi - -if [ "$USING_UFW" -eq 0 ]; then - - if iptables -t nat -C POSTROUTING -s 10.8.0.0/24 -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" &> /dev/null; then - echo ":: [OK] Iptables MASQUERADE rule set" - else - ERR=1 - read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - iptables -t nat -I POSTROUTING -s 10.8.0.0/24 -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" - iptables-save > /etc/iptables/rules.v4 - echo "Done" - fi - fi - - if [ "$INPUT_CHAIN_EDITED" -eq 1 ]; then - - if iptables -C INPUT -i "$IPv4dev" -p "$pivpnPROTO" --dport "$pivpnPORT" -j ACCEPT -m comment --comment "${VPN}-input-rule" &> /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]$ ]] || [[ -z ${REPLY} ]]; then - iptables -I INPUT 1 -i "$IPv4dev" -p "$pivpnPROTO" --dport "$pivpnPORT" -j ACCEPT -m comment --comment "${VPN}-input-rule" - 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 -m comment --comment "${VPN}-forward-rule" &> /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]$ ]] || [[ -z ${REPLY} ]]; then - iptables -I FORWARD 1 -d 10.8.0.0/24 -i "$IPv4dev" -o tun0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "${VPN}-forward-rule" - iptables -I FORWARD 2 -s 10.8.0.0/24 -i tun0 -o "$IPv4dev" -j ACCEPT -m comment --comment "${VPN}-forward-rule" - iptables-save > /etc/iptables/rules.v4 - echo "Done" - fi - fi - fi - -else - - if LANG="en_US.UTF-8" ufw status | grep -qw 'active'; then - echo ":: [OK] Ufw is enabled" - else - ERR=1 - read -r -p ":: [ERR] Ufw is not enabled, try to enable now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - ufw enable - fi - fi - - if iptables -t nat -C POSTROUTING -s 10.8.0.0/24 -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" &> /dev/null; then - echo ":: [OK] Iptables MASQUERADE rule set" - else - ERR=1 - read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - sed "/delete these required/i *nat\n:POSTROUTING ACCEPT [0:0]\n-I POSTROUTING -s 10.8.0.0/24 -o $IPv4dev -j MASQUERADE -m comment --comment ${VPN}-nat-rule\nCOMMIT\n" -i /etc/ufw/before.rules - ufw reload - echo "Done" - fi - fi - - if iptables -C ufw-user-input -p "${pivpnPROTO}" --dport "${pivpnPORT}" -j ACCEPT &> /dev/null; then - echo ":: [OK] Ufw input rule set" - else - ERR=1 - read -r -p ":: [ERR] Ufw input rule is not set, attempt fix now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - ufw insert 1 allow "$pivpnPORT"/"$pivpnPROTO" - ufw reload - echo "Done" - 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" - else - ERR=1 - read -r -p ":: [ERR] Ufw forwarding rule is not set, attempt fix now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; 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 - -if systemctl is-active -q openvpn; then - echo ":: [OK] OpenVPN is running" -else - ERR=1 - read -r -p ":: [ERR] OpenVPN is not running, try to start now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - systemctl start openvpn - echo "Done" - fi -fi - -if systemctl is-enabled -q openvpn; then - echo ":: [OK] OpenVPN is enabled (it will automatically start on reboot)" -else - ERR=1 - read -r -p ":: [ERR] OpenVPN is not enabled, try to enable now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - systemctl enable openvpn - echo "Done" - fi -fi - -# grep -w (whole word) is used so port 11940 won't match when looking for 1194 -if netstat -uanpt | grep openvpn | grep -w "${pivpnPORT}" | grep -q "${pivpnPROTO}"; then - echo ":: [OK] OpenVPN is listening on port ${pivpnPORT}/${pivpnPROTO}" -else - ERR=1 - read -r -p ":: [ERR] OpenVPN is not listening, try to restart now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - systemctl restart openvpn - echo "Done" - fi -fi - -if [ "$ERR" -eq 1 ]; then - echo -e "[INFO] Run \e[1mpivpn -d\e[0m again to see if we detect issues" -fi - +/opt/pivpn/self_check.sh printf "=============================================\n" echo -e ":::: \e[4mSnippet of the server log\e[0m ::::" tail -20 /var/log/openvpn.log > /tmp/snippet diff --git a/scripts/self_check.sh b/scripts/self_check.sh new file mode 100755 index 0000000..b6a2194 --- /dev/null +++ b/scripts/self_check.sh @@ -0,0 +1,170 @@ +#!/bin/bash + +subnetClass="24" +setupVars="/etc/pivpn/setupVars.conf" +ERR=0 + +if [ ! -f "${setupVars}" ]; then + echo "::: Missing setup vars file!" + exit 1 +fi + +source "${setupVars}" + +if [ "$VPN" = "wireguard" ]; then + pivpnPROTO="udp" + pivpnDEV="wg0" + pivpnNET="10.6.0.0" + VPN_SERVICE="wg-quick@wg0" + VPN_PRETTY_NAME="WireGuard" +elif [ "$VPN" = "openvpn" ]; then + pivpnDEV="tun0" + pivpnNET="10.8.0.0" + VPN_SERVICE="openvpn" + VPN_PRETTY_NAME="OpenVPN" +fi + +if [ "$( /dev/null; then + echo ":: [OK] Iptables MASQUERADE rule set" + else + ERR=1 + read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + iptables -t nat -I POSTROUTING -s "${pivpnNET}/${subnetClass}" -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" + iptables-save > /etc/iptables/rules.v4 + echo "Done" + fi + fi + + if [ "$INPUT_CHAIN_EDITED" -eq 1 ]; then + + if iptables -C INPUT -i "${IPv4dev}" -p "${pivpnPROTO}" --dport "${pivpnPORT}" -j ACCEPT -m comment --comment "${VPN}-input-rule" &> /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]$ ]] || [[ -z ${REPLY} ]]; then + iptables -I INPUT 1 -i "${IPv4dev}" -p "${pivpnPROTO}" --dport "${pivpnPORT}" -j ACCEPT -m comment --comment "${VPN}-input-rule" + iptables-save > /etc/iptables/rules.v4 + echo "Done" + fi + fi + fi + + if [ "$FORWARD_CHAIN_EDITED" -eq 1 ]; then + + if iptables -C FORWARD -s "${pivpnNET}/${subnetClass}" -i "${pivpnDEV}" -o "${IPv4dev}" -j ACCEPT -m comment --comment "${VPN}-forward-rule" &> /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]$ ]] || [[ -z ${REPLY} ]]; then + iptables -I FORWARD 1 -d "${pivpnNET}/${subnetClass}" -i "${IPv4dev}" -o "${pivpnDEV}" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "${VPN}-forward-rule" + iptables -I FORWARD 2 -s "${pivpnNET}/${subnetClass}" -i "${pivpnDEV}" -o "${IPv4dev}" -j ACCEPT -m comment --comment "${VPN}-forward-rule" + iptables-save > /etc/iptables/rules.v4 + echo "Done" + fi + fi + fi + +else + + if LANG="en_US.UTF-8" ufw status | grep -qw 'active'; then + echo ":: [OK] Ufw is enabled" + else + ERR=1 + read -r -p ":: [ERR] Ufw is not enabled, try to enable now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + ufw enable + fi + fi + + if iptables -t nat -C POSTROUTING -s "${pivpnNET}/${subnetClass}" -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" &> /dev/null; then + echo ":: [OK] Iptables MASQUERADE rule set" + else + ERR=1 + read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + sed "/delete these required/i *nat\n:POSTROUTING ACCEPT [0:0]\n-I POSTROUTING -s ${pivpnNET}/${subnetClass} -o ${IPv4dev} -j MASQUERADE -m comment --comment ${VPN}-nat-rule\nCOMMIT\n" -i /etc/ufw/before.rules + ufw reload + echo "Done" + fi + fi + + if iptables -C ufw-user-input -p "${pivpnPROTO}" --dport "${pivpnPORT}" -j ACCEPT &> /dev/null; then + echo ":: [OK] Ufw input rule set" + else + ERR=1 + read -r -p ":: [ERR] Ufw input rule is not set, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + ufw insert 1 allow "${pivpnPORT}"/"${pivpnPROTO}" + ufw reload + echo "Done" + fi + fi + + if iptables -C ufw-user-forward -i "${pivpnDEV}" -o "${IPv4dev}" -s "${pivpnNET}/${subnetClass}" -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]$ ]] || [[ -z ${REPLY} ]]; then + ufw route insert 1 allow in on "${pivpnDEV}" from "${pivpnNET}/${subnetClass}" out on "${IPv4dev}" to any + ufw reload + echo "Done" + fi + fi + +fi + +if systemctl is-active -q "${VPN_SERVICE}"; then + echo ":: [OK] ${VPN_PRETTY_NAME} is running" +else + ERR=1 + read -r -p ":: [ERR] ${VPN_PRETTY_NAME} is not running, try to start now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + systemctl start "${VPN_SERVICE}" + echo "Done" + fi +fi + +if systemctl is-enabled -q "${VPN_SERVICE}"; then + echo ":: [OK] ${VPN_PRETTY_NAME} is enabled (it will automatically start on reboot)" +else + ERR=1 + read -r -p ":: [ERR] ${VPN_PRETTY_NAME} is not enabled, try to enable now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + systemctl enable "${VPN_SERVICE}" + echo "Done" + fi +fi + +# grep -w (whole word) is used so port 11940 won't match when looking for 1194 +if netstat -antu | grep -wqE "${pivpnPROTO}.*${pivpnPORT}"; then + echo ":: [OK] ${VPN_PRETTY_NAME} is listening on port ${pivpnPORT}/${pivpnPROTO}" +else + ERR=1 + read -r -p ":: [ERR] ${VPN_PRETTY_NAME} is not listening, try to restart now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + systemctl restart "${VPN_SERVICE}" + echo "Done" + fi +fi + +if [ "$ERR" -eq 1 ]; then + echo -e "[INFO] Run \e[1mpivpn -d\e[0m again to see if we detect issues" +fi diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index 4546044..498b07e 100755 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -101,7 +101,7 @@ removeAll(){ # Purge dependencies echo "::: Purge dependencies..." - for i in "${TO_INSTALL[@]}"; do + 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 diff --git a/scripts/update.sh b/scripts/update.sh index c11d8eb..609c273 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -15,6 +15,17 @@ fi source "${setupVars}" +scriptusage(){ + echo "::: Updates PiVPN scripts" + echo ":::" + echo "::: Usage: pivpn <-up|update> [-t|--test]" + echo ":::" + echo "::: Commands:" + echo "::: [none] Updates from master branch" + echo "::: -t, test Updates from test branch" + echo "::: -h, help Show this usage dialog" +} + ###Functions ##Updates scripts updatepivpnscripts(){ @@ -68,14 +79,6 @@ cloneupdttest(){ git -C "$pivpnlocalpath" checkout master } -scriptusage(){ - echo -e "Updates pivpn scripts, - - Usage: - pivpn update | updates from master branch - pivpn update -t or --test | updates from test branch" -} - ## SCRIPT if [[ $# -eq 0 ]]; then @@ -83,15 +86,15 @@ if [[ $# -eq 0 ]]; then else while true; do case "$1" in - -t|--test|test) + -t|test) updatefromtest exit 0 ;; - -h|--help|help) + -h|help) scriptusage exit 0 ;; - * ) + *) updatepivpnscripts exit 0 ;; diff --git a/scripts/wireguard/bash-completion b/scripts/wireguard/bash-completion index a971696..412072a 100644 --- a/scripts/wireguard/bash-completion +++ b/scripts/wireguard/bash-completion @@ -4,8 +4,8 @@ _pivpn() COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" - dashopts="-a -c -d -l -qr -r -h -u -up -bk" - opts="add clients debug list qrcode remove help uninstall update backup" + dashopts="-a -c -d -l -qr -r -h -u -up -wg -bk" + opts="add clients debug list qrcode remove help uninstall update wgupdate backup" if [ "${#COMP_WORDS[@]}" -eq 2 ] then if [[ ${cur} == -* ]] ; then diff --git a/scripts/wireguard/clientSTAT.sh b/scripts/wireguard/clientSTAT.sh index d8c94cd..93abc22 100755 --- a/scripts/wireguard/clientSTAT.sh +++ b/scripts/wireguard/clientSTAT.sh @@ -10,7 +10,11 @@ hr(){ numfmt --to=iec-i --suffix=B "$1" } -DUMP="$(wg show wg0 dump | tail -n +2)" +if DUMP="$(wg show wg0 dump)"; then + DUMP="$(tail -n +2 <<< "$DUMP")" +else + exit 1 +fi printf "\e[1m::: Connected Clients List :::\e[0m\n" diff --git a/scripts/wireguard/makeCONF.sh b/scripts/wireguard/makeCONF.sh index 561aa69..2a0b0d3 100755 --- a/scripts/wireguard/makeCONF.sh +++ b/scripts/wireguard/makeCONF.sh @@ -2,6 +2,13 @@ setupVars="/etc/pivpn/setupVars.conf" +if [ ! -f "${setupVars}" ]; then + echo "::: Missing setup vars file!" + exit 1 +fi + +source "${setupVars}" + helpFunc(){ echo "::: Create a client conf profile" echo ":::" @@ -39,13 +46,6 @@ while test $# -gt 0; do shift done -if [ ! -f "${setupVars}" ]; then - echo "::: Missing setup vars file!" - exit 1 -fi - -source "${setupVars}" - # The home folder variable was sourced from the settings file. if [ ! -d "${install_home}/configs" ]; then mkdir "${install_home}/configs" diff --git a/scripts/wireguard/pivpn b/scripts/wireguard/pivpn index 4400a3f..a08ca61 100755 --- a/scripts/wireguard/pivpn +++ b/scripts/wireguard/pivpn @@ -54,6 +54,11 @@ updateScripts(){ exit 0 } +updateWireGuard(){ + $SUDO /opt/pivpn/wgUPDATE.sh + exit 0 +} + backup(){ $SUDO /opt/pivpn/backup.sh } @@ -73,7 +78,8 @@ showHelp(){ echo "::: -h, help Show this help dialog" echo "::: -u, uninstall Uninstall pivpn from your system!" echo "::: -up, update Updates PiVPN Scripts" - echo "::: -bk, Backup Backup vpn configs and user profiles" + echo "::: -wg, wgupdate Updates WireGuard" + echo "::: -bk, backup Backup VPN configs and user profiles" exit 0 } @@ -92,6 +98,7 @@ case "$1" in "-h" | "help" ) showHelp;; "-u" | "uninstall" ) uninstallServer;; "-up" | "update" ) updateScripts "$@" ;; +"-wg" | "wgupdate" ) updateWireGuard ;; "-bk" | "backup" ) backup ;; * ) showHelp;; esac diff --git a/scripts/wireguard/pivpnDEBUG.sh b/scripts/wireguard/pivpnDEBUG.sh index f2fe45c..0aebdd6 100755 --- a/scripts/wireguard/pivpnDEBUG.sh +++ b/scripts/wireguard/pivpnDEBUG.sh @@ -10,32 +10,30 @@ fi source "${setupVars}" -EXAMPLE="$(head -1 /etc/wireguard/configs/clients.txt | awk '{print $1}')" -ERR=0 - echo -e "::::\t\t\e[4mPiVPN debug\e[0m\t\t ::::" printf "=============================================\n" 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 ::::" -sed "s/$pivpnHOST/REDACTED/" < /etc/pivpn/setupVars.conf +sed "s/$pivpnHOST/REDACTED/" < /etc/pivpn/setupVars.conf printf "=============================================\n" echo -e ":::: \e[4mServer configuration shown below\e[0m ::::" cd /etc/wireguard/keys cp ../wg0.conf ../wg0.tmp # Replace every key in the server configuration with just its file name for k in *; do - sed "s#$(cat "$k")#$k#" -i ../wg0.tmp + sed "s#$(<"$k")#$k#" -i ../wg0.tmp done cat ../wg0.tmp rm ../wg0.tmp printf "=============================================\n" echo -e ":::: \e[4mClient configuration shown below\e[0m ::::" +EXAMPLE="$(head -1 /etc/wireguard/configs/clients.txt | awk '{print $1}')" if [ -n "$EXAMPLE" ]; then cp ../configs/"$EXAMPLE".conf ../configs/"$EXAMPLE".tmp for k in *; do - sed "s#$(cat "$k")#$k#" -i ../configs/"$EXAMPLE".tmp + sed "s#$(<"$k")#$k#" -i ../configs/"$EXAMPLE".tmp done sed "s/$pivpnHOST/REDACTED/" < ../configs/"$EXAMPLE".tmp rm ../configs/"$EXAMPLE".tmp @@ -48,151 +46,7 @@ echo -e ":::: \t\e[4mRecursive list of files in\e[0m\t ::::\n::::\e\t[4m/etc/wir ls -LR /etc/wireguard printf "=============================================\n" echo -e "::::\t\t\e[4mSelf check\e[0m\t\t ::::" - -if [ "$(cat /proc/sys/net/ipv4/ip_forward)" -eq 1 ]; then - echo ":: [OK] IP forwarding is enabled" -else - ERR=1 - read -r -p ":: [ERR] IP forwarding is not enabled, attempt fix now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - sed -i '/net.ipv4.ip_forward=1/s/^#//g' /etc/sysctl.conf - sysctl -p - echo "Done" - fi -fi - -if [ "$USING_UFW" -eq 0 ]; then - - if iptables -t nat -C POSTROUTING -s 10.6.0.0/24 -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" &> /dev/null; then - echo ":: [OK] Iptables MASQUERADE rule set" - else - ERR=1 - read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - iptables -t nat -I POSTROUTING -s 10.6.0.0/24 -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" - iptables-save > /etc/iptables/rules.v4 - echo "Done" - fi - fi - - if [ "$INPUT_CHAIN_EDITED" -eq 1 ]; then - - if iptables -C INPUT -i "$IPv4dev" -p udp --dport "$pivpnPORT" -j ACCEPT -m comment --comment "${VPN}-input-rule" &> /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]$ ]] || [[ -z ${REPLY} ]]; then - iptables -I INPUT 1 -i "$IPv4dev" -p udp --dport "$pivpnPORT" -j ACCEPT -m comment --comment "${VPN}-input-rule" - iptables-save > /etc/iptables/rules.v4 - echo "Done" - fi - fi - fi - - if [ "$FORWARD_CHAIN_EDITED" -eq 1 ]; then - - if iptables -C FORWARD -s 10.6.0.0/24 -i wg0 -o "$IPv4dev" -j ACCEPT -m comment --comment "${VPN}-forward-rule" &> /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]$ ]] || [[ -z ${REPLY} ]]; then - iptables -I FORWARD 1 -d 10.6.0.0/24 -i "$IPv4dev" -o wg0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "${VPN}-forward-rule" - iptables -I FORWARD 2 -s 10.6.0.0/24 -i wg0 -o "$IPv4dev" -j ACCEPT -m comment --comment "${VPN}-forward-rule" - iptables-save > /etc/iptables/rules.v4 - echo "Done" - fi - fi - fi - -else - - if LANG="en_US.UTF-8" ufw status | grep -qw 'active'; then - echo ":: [OK] Ufw is enabled" - else - ERR=1 - read -r -p ":: [ERR] Ufw is not enabled, try to enable now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - ufw enable - fi - fi - - if iptables -t nat -C POSTROUTING -s 10.6.0.0/24 -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" &> /dev/null; then - echo ":: [OK] Iptables MASQUERADE rule set" - else - ERR=1 - read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - sed "/delete these required/i *nat\n:POSTROUTING ACCEPT [0:0]\n-I POSTROUTING -s 10.6.0.0/24 -o $IPv4dev -j MASQUERADE -m comment --comment ${VPN}-nat-rule\nCOMMIT\n" -i /etc/ufw/before.rules - ufw reload - echo "Done" - fi - fi - - if iptables -C ufw-user-input -p udp --dport "${pivpnPORT}" -j ACCEPT &> /dev/null; then - echo ":: [OK] Ufw input rule set" - else - ERR=1 - read -r -p ":: [ERR] Ufw input rule is not set, attempt fix now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - ufw insert 1 allow "$pivpnPORT"/udp - ufw reload - echo "Done" - fi - fi - - if iptables -C ufw-user-forward -i wg0 -o "${IPv4dev}" -s 10.6.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]$ ]] || [[ -z ${REPLY} ]]; then - ufw route insert 1 allow in on wg0 from 10.6.0.0/24 out on "$IPv4dev" to any - ufw reload - echo "Done" - fi - fi - -fi - -if systemctl is-active -q wg-quick@wg0; then - echo ":: [OK] WireGuard is running" -else - ERR=1 - read -r -p ":: [ERR] WireGuard is not running, try to start now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - systemctl start wg-quick@wg0 - echo "Done" - fi -fi - -if systemctl is-enabled -q wg-quick@wg0; then - echo ":: [OK] WireGuard is enabled (it will automatically start on reboot)" -else - ERR=1 - read -r -p ":: [ERR] WireGuard is not enabled, try to enable now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - systemctl enable wg-quick@wg0 - echo "Done" - fi -fi - -# grep -w (whole word) is used so port 11940 won't match when looking for 1194 -if netstat -uanp | grep -w "${pivpnPORT}" | grep -q 'udp'; then - echo ":: [OK] WireGuard is listening on port ${pivpnPORT}/udp" -else - ERR=1 - read -r -p ":: [ERR] WireGuard is not listening, try to restart now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - systemctl restart wg-quick@wg0 - echo "Done" - fi -fi - -if [ "$ERR" -eq 1 ]; then - echo -e "[INFO] Run \e[1mpivpn -d\e[0m again to see if we detect issues" -fi +/opt/pivpn/self_check.sh printf "=============================================\n" echo -e ":::: \e[1mWARNING\e[0m: This script should have automatically masked sensitive ::::" echo -e ":::: information, however, still make sure that \e[4mPrivateKey\e[0m, \e[4mPublicKey\e[0m ::::" diff --git a/scripts/wireguard/removeCONF.sh b/scripts/wireguard/removeCONF.sh index b00deb6..36aa249 100755 --- a/scripts/wireguard/removeCONF.sh +++ b/scripts/wireguard/removeCONF.sh @@ -2,6 +2,13 @@ setupVars="/etc/pivpn/setupVars.conf" +if [ ! -f "${setupVars}" ]; then + echo "::: Missing setup vars file!" + exit 1 +fi + +source "${setupVars}" + helpFunc(){ echo "::: Remove a client conf profile" echo ":::" @@ -29,13 +36,6 @@ do shift done -if [ ! -f "${setupVars}" ]; then - echo "::: Missing setup vars file!" - exit 1 -fi - -source "${setupVars}" - cd /etc/wireguard if [ ! -s configs/clients.txt ]; then echo "::: There are no clients to remove" diff --git a/scripts/wireguard/wgUPDATE.sh b/scripts/wireguard/wgUPDATE.sh new file mode 100755 index 0000000..6a17993 --- /dev/null +++ b/scripts/wireguard/wgUPDATE.sh @@ -0,0 +1,132 @@ +#!/bin/bash + +setupVars="/etc/pivpn/setupVars.conf" + +if [ ! -f "${setupVars}" ]; then + echo "::: Missing setup vars file!" + exit 1 +fi + +source "${setupVars}" + +if [ "$(uname -m)" != "armv6l" ]; then + echo "On your system, WireGuard updates via the package manager" + exit 0 +fi + +CURRENT_WG_TOOLS_SNAPSHOT="${WG_TOOLS_SNAPSHOT}" +WG_TOOLS_SNAPSHOT="$(curl -s https://build.wireguard.com/distros.json | jq -r '."upstream-tools"."version"')" + +if dpkg --compare-versions "${WG_TOOLS_SNAPSHOT}" gt "${CURRENT_WG_TOOLS_SNAPSHOT}"; then + + read -r -p "A new wireguard-tools update is available (${WG_TOOLS_SNAPSHOT}), install? [Y/n]: " + + if [[ ${REPLY} =~ ^[Yy]$ ]]; then + echo "::: Upgrading wireguard-tools from ${CURRENT_WG_TOOLS_SNAPSHOT} to ${WG_TOOLS_SNAPSHOT}..." + + WG_TOOLS_SOURCE="https://git.zx2c4.com/wireguard-tools/snapshot/wireguard-tools-${WG_TOOLS_SNAPSHOT}.tar.xz" + echo "::: Downloading wireguard-tools source code... " + wget -qO- "${WG_TOOLS_SOURCE}" | tar xJ --directory /usr/src + echo "done!" + + ## || exits if cd fails. + cd /usr/src/wireguard-tools-"${WG_TOOLS_SNAPSHOT}/src" || exit 1 + + # We install the userspace tools manually since DKMS only compiles and + # installs the kernel module + echo "::: Compiling WireGuard tools... " + if make; then + echo "done!" + else + echo "failed!" + exit 1 + fi + + # Use checkinstall to install userspace tools so if the user wants to uninstall + # PiVPN we can just do apt remove wireguard-tools, instead of manually removing + # files from the file system + echo "::: Installing WireGuard tools... " + if checkinstall --pkgname wireguard-tools --pkgversion "${WG_TOOLS_SNAPSHOT}" -y; then + echo "done!" + else + echo "failed!" + exit 1 + fi + + echo "::: Removing old source code ..." + rm -rf /usr/src/wireguard-tools-"${CURRENT_WG_TOOLS_SNAPSHOT}" + + sed "s/WG_TOOLS_SNAPSHOT=${CURRENT_WG_TOOLS_SNAPSHOT}/WG_TOOLS_SNAPSHOT=${WG_TOOLS_SNAPSHOT}/" -i "${setupVars}" + + echo "::: Upgrade completed!" + fi +else + echo "::: You are running the lastest version of wireguard-tools (${CURRENT_WG_TOOLS_SNAPSHOT})" +fi + +CURRENT_WG_MODULE_SNAPSHOT="${WG_MODULE_SNAPSHOT}" +WG_MODULE_SNAPSHOT="$(curl -s https://build.wireguard.com/distros.json | jq -r '."upstream-linuxcompat"."version"')" + +if dpkg --compare-versions "${WG_MODULE_SNAPSHOT}" gt "${CURRENT_WG_MODULE_SNAPSHOT}"; then + + read -r -p "A new wireguard-dkms update is available (${WG_MODULE_SNAPSHOT}), install? [Y/n]: " + + if [[ ${REPLY} =~ ^[Yy]$ ]]; then + echo "::: Upgrading wireguard-dkms from ${CURRENT_WG_MODULE_SNAPSHOT} to ${WG_MODULE_SNAPSHOT}..." + + WG_MODULE_SOURCE="https://git.zx2c4.com/wireguard-linux-compat/snapshot/wireguard-linux-compat-${WG_MODULE_SNAPSHOT}.tar.xz" + echo "::: Downloading wireguard-linux-compat source code... " + wget -qO- "${WG_MODULE_SOURCE}" | tar xJ --directory /usr/src + echo "done!" + + # Rename wireguard-linux-compat folder and move the source code to the parent folder + # such that dkms picks up the module when referencing wireguard/"${WG_MODULE_SNAPSHOT}" + cd /usr/src && \ + mv wireguard-linux-compat-"${WG_MODULE_SNAPSHOT}" wireguard-"${WG_MODULE_SNAPSHOT}" && \ + cd wireguard-"${WG_MODULE_SNAPSHOT}" && \ + mv src/* . && \ + rmdir src || exit 1 + + echo "::: Adding WireGuard module via DKMS... " + if dkms add wireguard/"${WG_MODULE_SNAPSHOT}"; then + echo "done!" + else + echo "failed!" + dkms remove wireguard/"${WG_MODULE_SNAPSHOT}" --all + exit 1 + fi + + echo "::: Compiling WireGuard module via DKMS... " + if dkms build wireguard/"${WG_MODULE_SNAPSHOT}"; then + echo "done!" + else + echo "failed!" + dkms remove wireguard/"${WG_MODULE_SNAPSHOT}" --all + exit 1 + fi + + echo "::: Installing WireGuard module via DKMS... " + if dkms install wireguard/"${WG_MODULE_SNAPSHOT}"; then + echo "done!" + else + echo "failed!" + dkms remove wireguard/"${WG_MODULE_SNAPSHOT}" --all + exit 1 + fi + + echo "::: Removing old kernel module and source code..." + if dkms remove wireguard/"${CURRENT_WG_MODULE_SNAPSHOT}" --all; then + rm -rf /usr/src/wireguard-"${CURRENT_WG_MODULE_SNAPSHOT}" + echo "done!" + else + echo "failed!" + exit 1 + fi + + sed "s/WG_TOOLS_SNAPSHOT=${CURRENT_WG_MODULE_SNAPSHOT}/WG_TOOLS_SNAPSHOT=${WG_MODULE_SNAPSHOT}/" -i "${setupVars}" + + echo "::: Upgrade completed!" + fi +else + echo "::: You are running the lastest version of wireguard-dkms (${CURRENT_WG_MODULE_SNAPSHOT})" +fi diff --git a/unattended_openvpn_example.conf b/unattended_openvpn_example.conf index f0094bc..091877a 100644 --- a/unattended_openvpn_example.conf +++ b/unattended_openvpn_example.conf @@ -1,4 +1,6 @@ IPv4dev=eth0 +IPv4addr=192.168.23.211 +IPv4gw=192.168.23.1 dhcpReserv=0 install_user=pi VPN=openvpn diff --git a/unattended_wireguard_example.conf b/unattended_wireguard_example.conf index 196d4d5..3fe774d 100644 --- a/unattended_wireguard_example.conf +++ b/unattended_wireguard_example.conf @@ -1,4 +1,6 @@ IPv4dev=eth0 +IPv4addr=192.168.23.211 +IPv4gw=192.168.23.1 dhcpReserv=0 install_user=pi VPN=wireguard From 0994ac7d5a26290a46bbf033d6bd63cb4a4d5ad3 Mon Sep 17 00:00:00 2001 From: Orazio Date: Sat, 25 Jan 2020 14:24:04 +0100 Subject: [PATCH 04/14] Fixed cosmetic issue with spinner, added missing spinner to some APT commands --- auto_install/install.sh | 13 +++++++------ scripts/uninstall.sh | 9 +++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index e4817c4..774eb43 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -335,7 +335,7 @@ spinner(){ local pid=$1 local delay=0.50 local spinstr='/-\|' - while ps a | awk '{print $1}' | grep "${pid}"; do + while ps a | awk '{print $1}' | grep -q "$pid"; do local temp=${spinstr#?} printf " [%c] " "${spinstr}" local spinstr=${temp}${spinstr%"$temp"} @@ -399,7 +399,7 @@ updatePackageCache(){ echo ":::" echo -ne "::: ${PKG_MANAGER} update has not been run today. Running now...\\n" # shellcheck disable=SC2086 - $SUDO ${UPDATE_PKG_CACHE} &> /dev/null + $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! echo " done!" fi } @@ -1004,7 +1004,7 @@ installOpenVPN(){ wget -qO- https://swupdate.openvpn.net/repos/repo-public.gpg | $SUDO apt-key add - echo "deb https://build.openvpn.net/debian/openvpn/stable $OSCN main" | $SUDO tee /etc/apt/sources.list.d/pivpn-openvpn-repo.list > /dev/null # shellcheck disable=SC2086 - $SUDO ${UPDATE_PKG_CACHE} &> /dev/null + $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! fi echo "::: Installing OpenVPN from Debian package... " @@ -1036,7 +1036,7 @@ installWireGuard(){ $SUDO apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC 648ACFD622F3D138 # shellcheck disable=SC2086 - $SUDO ${UPDATE_PKG_CACHE} &> /dev/null + $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! PIVPN_DEPS=(raspberrypi-kernel-headers wireguard wireguard-tools wireguard-dkms) installDependentPackages PIVPN_DEPS[@] @@ -1137,7 +1137,7 @@ installWireGuard(){ echo "deb https://deb.debian.org/debian/ unstable main" | $SUDO tee /etc/apt/sources.list.d/pivpn-unstable.list > /dev/null printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' | $SUDO tee /etc/apt/preferences.d/pivpn-limit-unstable > /dev/null # shellcheck disable=SC2086 - $SUDO ${UPDATE_PKG_CACHE} &> /dev/null + $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! PIVPN_DEPS=(linux-headers-amd64 qrencode wireguard wireguard-tools wireguard-dkms) installDependentPackages PIVPN_DEPS[@] @@ -1145,7 +1145,8 @@ installWireGuard(){ echo "::: Installing WireGuard from PPA... " $SUDO add-apt-repository ppa:wireguard/wireguard -y - $SUDO ${UPDATE_PKG_CACHE} &> /dev/null + # shellcheck disable=SC2086 + $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! PIVPN_DEPS=(qrencode wireguard wireguard-tools wireguard-dkms linux-headers-generic) installDependentPackages PIVPN_DEPS[@] diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index 498b07e..23c06e3 100755 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -5,6 +5,7 @@ ### FIXME: use variables where appropriate, reduce magic numbers by 99.9%, at least. PKG_MANAGER="apt-get" +UPDATE_PKG_CACHE="${PKG_MANAGER} update" subnetClass="24" setupVars="/etc/pivpn/setupVars.conf" @@ -33,7 +34,7 @@ spinner(){ local pid=$1 local delay=0.50 local spinstr='/-\|' - while ps a | awk '{print $1}' | grep "$pid"; do + while ps a | awk '{print $1}' | grep -q "$pid"; do local temp=${spinstr#?} printf " [%c] " "$spinstr" local spinstr=$temp${spinstr%"$temp"} @@ -113,10 +114,10 @@ removeAll(){ if [ "$PLAT" = "Debian" ] || { [ "$PLAT" = "Raspbian" ] && [ "$(uname -m)" = "armv7l" ]; }; then rm -f /etc/apt/sources.list.d/pivpn-unstable.list rm -f /etc/apt/preferences.d/pivpn-limit-unstable - $PKG_MANAGER update &> /dev/null + ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! elif [ "$PLAT" = "Ubuntu" ]; then add-apt-repository ppa:wireguard/wireguard -r -y - $PKG_MANAGER update &> /dev/null + ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! fi elif [ "${i}" = "wireguard-dkms" ]; then @@ -152,7 +153,7 @@ removeAll(){ if [ "$PLAT" = "Debian" ] || [ "$PLAT" = "Ubuntu" ]; then rm -f /etc/apt/sources.list.d/pivpn-openvpn-repo.list - $PKG_MANAGER update &> /dev/null + ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! fi deluser openvpn rm -f /etc/rsyslog.d/30-openvpn.conf From d1a781075ae484fbb7ec5fbb589d678ebfb3e3a7 Mon Sep 17 00:00:00 2001 From: Orazio Date: Sat, 25 Jan 2020 17:43:23 +0100 Subject: [PATCH 05/14] Detect current netmask, validate user input when configuring a static IP --- auto_install/install.sh | 134 ++++++++++++++++++++---------- unattended_openvpn_example.conf | 2 +- unattended_wireguard_example.conf | 2 +- 3 files changed, 92 insertions(+), 46 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 774eb43..8a76550 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -59,9 +59,12 @@ c=$(( columns / 2 )) r=$(( r < 20 ? 20 : r )) c=$(( c < 70 ? 70 : c )) -# Find IP used to route to outside world -CurrentIPv4addr=$(ip route get 192.0.2.1 | awk '{print $7}') +# Find IP (with netmask) and gateway used to route to outside world +BaseIPv4addr=$(ip route get 192.0.2.1| awk '{print $7}') +CurrentIPv4addr=$(ip -o -f inet address | grep "${BaseIPv4addr}/" | awk '{print $4}') CurrentIPv4gw=$(ip route get 192.0.2.1 | awk '{print $3}') + +# Find network interfaces whose state is UP, so as to skip virtual interfaces and the loopback interface availableInterfaces=$(ip -o link | awk '/state UP/ {print $2}' | cut -d':' -f1 | cut -d'@' -f1) ######## SCRIPT ############ @@ -601,7 +604,7 @@ validIP(){ if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then OIFS=$IFS IFS='.' - read -r -a ip <<< "$ip" + read -r -a ip <<< "$ip" IFS=$OIFS [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] @@ -610,6 +613,24 @@ validIP(){ return $stat } +validIPAndNetmask(){ + local ip=$1 + local stat=1 + ip="${ip/\//.}" + + if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,2}$ ]]; then + OIFS=$IFS + IFS='.' + read -r -a ip <<< "$ip" + IFS=$OIFS + [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ + && ${ip[2]} -le 255 && ${ip[3]} -le 255 \ + && ${ip[4]} -le 32 ]] + stat=$? + fi + return $stat +} + getStaticIPv4Settings() { # Grab their current DNS Server IPv4dns=$(grep nameserver /etc/resolv.conf | awk '{print $2}' | xargs) @@ -632,10 +653,10 @@ getStaticIPv4Settings() { if [ "$MISSING_STATIC_IPV4_SETTINGS" -eq 0 ]; then # If both settings are not empty, check if they are valid and proceed - if validIP "${IPv4addr%/*}"; then + if validIPAndNetmask "${IPv4addr}"; then echo "::: Your static IPv4 address: ${IPv4addr}" else - echo "::: ${IPv4addr%/*} is not a valid IP address" + echo "::: ${IPv4addr} is not a valid IP address" exit 1 fi @@ -667,22 +688,23 @@ getStaticIPv4Settings() { fi echo "dhcpReserv=${dhcpReserv}" >> /tmp/setupVars.conf - echo "IPv4addr=${IPv4addr%/*}" >> /tmp/setupVars.conf + echo "IPv4addr=${IPv4addr}" >> /tmp/setupVars.conf echo "IPv4gw=${IPv4gw}" >> /tmp/setupVars.conf return fi local ipSettingsCorrect + local IPv4AddrValid + local IPv4gwValid # Some users reserve IP addresses on another DHCP Server or on their routers, # Lets ask them if they want to make any changes to their interfaces. - IPv4addr="${CurrentIPv4addr}" - IPv4gw="${CurrentIPv4gw}" + if (whiptail --backtitle "Calibrating network interface" --title "DHCP Reservation" --yesno \ "Are you Using DHCP Reservation on your Router/DHCP Server? These are your current Network Settings: - IP address: ${IPv4addr} - Gateway: ${IPv4gw} + IP address: ${CurrentIPv4addr} + Gateway: ${CurrentIPv4gw} Yes: Keep using DHCP reservation No: Setup static IP address @@ -690,56 +712,80 @@ Don't know what DHCP Reservation is? Answer No." ${r} ${c}); then dhcpReserv=1 # shellcheck disable=SC2129 echo "dhcpReserv=${dhcpReserv}" >> /tmp/setupVars.conf - echo "IPv4addr=${IPv4addr%/*}" >> /tmp/setupVars.conf - echo "IPv4gw=${IPv4gw}" >> /tmp/setupVars.conf + # We don't really need to save them as we won't set a static IP but they might be useful for debugging + echo "IPv4addr=${CurrentIPv4addr}" >> /tmp/setupVars.conf + echo "IPv4gw=${CurrentIPv4gw}" >> /tmp/setupVars.conf else # Ask if the user wants to use DHCP settings as their static IP if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address? - IP address: ${IPv4addr} - Gateway: ${IPv4gw}" ${r} ${c}); then - echo "IPv4addr=${IPv4addr%/*}" >> /tmp/setupVars.conf - echo "IPv4gw=${IPv4gw}" >> /tmp/setupVars.conf - # If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict. - whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that. + IP address: ${CurrentIPv4addr} + Gateway: ${CurrentIPv4gw}" ${r} ${c}); then + IPv4addr=${CurrentIPv4addr} + IPv4gw=${CurrentIPv4gw} + echo "IPv4addr=${IPv4addr}" >> /tmp/setupVars.conf + echo "IPv4gw=${IPv4gw}" >> /tmp/setupVars.conf + + # If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict. + whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that. If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want. It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." ${r} ${c} - # Nothing else to do since the variables are already set above + # Nothing else to do since the variables are already set above else - # Otherwise, we need to ask the user to input their desired settings. - # Start by getting the IPv4 address (pre-filling it with info gathered from DHCP) - # Start a loop to let the user enter their information with the chance to go back and edit it if necessary + # Otherwise, we need to ask the user to input their desired settings. + # Start by getting the IPv4 address (pre-filling it with info gathered from DHCP) + # Start a loop to let the user enter their information with the chance to go back and edit it if necessary until [[ ${ipSettingsCorrect} = True ]]; do - # Ask for the IPv4 address - if IPv4addr=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPv4addr}" 3>&1 1>&2 2>&3) ; then - echo "::: Your static IPv4 address: ${IPv4addr}" - # Ask for the gateway - if IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${IPv4gw}" 3>&1 1>&2 2>&3) ; then - echo "::: Your static IPv4 gateway: ${IPv4gw}" - # Give the user a chance to review their settings before moving on - if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct? - IP address: ${IPv4addr} - Gateway: ${IPv4gw}" ${r} ${c}); then - # If the settings are correct, then we need to set the pivpnIP - echo "IPv4addr=${IPv4addr%/*}" >> /tmp/setupVars.conf - echo "IPv4gw=${IPv4gw}" >> /tmp/setupVars.conf - # After that's done, the loop ends and we move on - ipSettingsCorrect=True + + until [[ ${IPv4AddrValid} = True ]]; do + # Ask for the IPv4 address + if IPv4addr=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${CurrentIPv4addr}" 3>&1 1>&2 2>&3) ; then + if validIPAndNetmask "${IPv4addr}"; then + echo "::: Your static IPv4 address: ${IPv4addr}" + IPv4AddrValid=True else - # If the settings are wrong, the loop continues - ipSettingsCorrect=False + whiptail --msgbox --backtitle "Calibrating network interface" --title "IPv4 address" "You entered an invalid IPv4 address.\\n\\nPlease enter an IP address in the CIDR notation, example: 192.168.23.211/24.\\n\\nIf you are not sure, please just keep the default." ${r} ${c} + echo "::: Invalid IPv4 address: ${IPv4addr}" + IPv4AddrValid=False fi else - # Cancelling gateway settings window - ipSettingsCorrect=False + # Cancelling IPv4 settings window echo "::: Cancel selected. Exiting..." exit 1 fi + done + + until [[ ${IPv4gwValid} = True ]]; do + # Ask for the gateway + if IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${CurrentIPv4gw}" 3>&1 1>&2 2>&3) ; then + if validIP "${IPv4gw}"; then + echo "::: Your static IPv4 gateway: ${IPv4gw}" + IPv4gwValid=True + else + whiptail --msgbox --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" "You entered an invalid IPv4 address.\\n\\nPlease enter the IP address of your gateway (router), example: 192.168.23.1.\\n\\nIf you are not sure, please just keep the default." ${r} ${c} + echo "::: Invalid IPv4 gateway: ${IPv4gw}" + IPv4gwValid=False + fi + else + # Cancelling gateway settings window + echo "::: Cancel selected. Exiting..." + exit 1 + fi + done + + # Give the user a chance to review their settings before moving on + if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct? + + IP address: ${IPv4addr} + Gateway: ${IPv4gw}" ${r} ${c}); then + # If the settings are correct, then we need to set the pivpnIP + echo "IPv4addr=${IPv4addr}" >> /tmp/setupVars.conf + echo "IPv4gw=${IPv4gw}" >> /tmp/setupVars.conf + # After that's done, the loop ends and we move on + ipSettingsCorrect=True else - # Cancelling IPv4 settings window + # If the settings are wrong, the loop continues ipSettingsCorrect=False - echo "::: Cancel selected. Exiting..." - exit 1 fi done # End the if statement for DHCP vs. static diff --git a/unattended_openvpn_example.conf b/unattended_openvpn_example.conf index 091877a..969c915 100644 --- a/unattended_openvpn_example.conf +++ b/unattended_openvpn_example.conf @@ -1,5 +1,5 @@ IPv4dev=eth0 -IPv4addr=192.168.23.211 +IPv4addr=192.168.23.211/24 IPv4gw=192.168.23.1 dhcpReserv=0 install_user=pi diff --git a/unattended_wireguard_example.conf b/unattended_wireguard_example.conf index 3fe774d..e417927 100644 --- a/unattended_wireguard_example.conf +++ b/unattended_wireguard_example.conf @@ -1,5 +1,5 @@ IPv4dev=eth0 -IPv4addr=192.168.23.211 +IPv4addr=192.168.23.211/24 IPv4gw=192.168.23.1 dhcpReserv=0 install_user=pi From b12996df37f2ac82be28a7775a055f02742b9283 Mon Sep 17 00:00:00 2001 From: Orazio Date: Sat, 25 Jan 2020 18:01:07 +0100 Subject: [PATCH 06/14] Inform the user when updating the package cache, which can be slow on some RPis --- auto_install/install.sh | 8 ++++++-- scripts/uninstall.sh | 3 +++ scripts/wireguard/clientSTAT.sh | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 8a76550..68e09bd 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -1049,6 +1049,7 @@ installOpenVPN(){ installDependentPackages PIVPN_DEPS[@] wget -qO- https://swupdate.openvpn.net/repos/repo-public.gpg | $SUDO apt-key add - echo "deb https://build.openvpn.net/debian/openvpn/stable $OSCN main" | $SUDO tee /etc/apt/sources.list.d/pivpn-openvpn-repo.list > /dev/null + echo "::: Updating package cache..." # shellcheck disable=SC2086 $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! fi @@ -1081,7 +1082,8 @@ installWireGuard(){ printf 'Package: *\nPin: release a=unstable\nPin-Priority: 1\n\nPackage: wireguard wireguard-dkms wireguard-tools\nPin: release a=unstable\nPin-Priority: 500\n' | $SUDO tee /etc/apt/preferences.d/pivpn-limit-unstable > /dev/null $SUDO apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC 648ACFD622F3D138 - # shellcheck disable=SC2086 + echo "::: Updating package cache..." + # shellcheck disable=SC2086 $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! PIVPN_DEPS=(raspberrypi-kernel-headers wireguard wireguard-tools wireguard-dkms) installDependentPackages PIVPN_DEPS[@] @@ -1182,7 +1184,8 @@ installWireGuard(){ echo "::: Adding Debian repository... " echo "deb https://deb.debian.org/debian/ unstable main" | $SUDO tee /etc/apt/sources.list.d/pivpn-unstable.list > /dev/null printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' | $SUDO tee /etc/apt/preferences.d/pivpn-limit-unstable > /dev/null - # shellcheck disable=SC2086 + echo "::: Updating package cache..." + # shellcheck disable=SC2086 $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! PIVPN_DEPS=(linux-headers-amd64 qrencode wireguard wireguard-tools wireguard-dkms) installDependentPackages PIVPN_DEPS[@] @@ -1191,6 +1194,7 @@ installWireGuard(){ echo "::: Installing WireGuard from PPA... " $SUDO add-apt-repository ppa:wireguard/wireguard -y + echo "::: Updating package cache..." # shellcheck disable=SC2086 $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! PIVPN_DEPS=(qrencode wireguard wireguard-tools wireguard-dkms linux-headers-generic) diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index 23c06e3..b570fd1 100755 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -114,9 +114,11 @@ removeAll(){ if [ "$PLAT" = "Debian" ] || { [ "$PLAT" = "Raspbian" ] && [ "$(uname -m)" = "armv7l" ]; }; then rm -f /etc/apt/sources.list.d/pivpn-unstable.list rm -f /etc/apt/preferences.d/pivpn-limit-unstable + echo "::: Updating package cache..." ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! elif [ "$PLAT" = "Ubuntu" ]; then add-apt-repository ppa:wireguard/wireguard -r -y + echo "::: Updating package cache..." ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! fi @@ -153,6 +155,7 @@ removeAll(){ if [ "$PLAT" = "Debian" ] || [ "$PLAT" = "Ubuntu" ]; then rm -f /etc/apt/sources.list.d/pivpn-openvpn-repo.list + echo "::: Updating package cache..." ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! fi deluser openvpn diff --git a/scripts/wireguard/clientSTAT.sh b/scripts/wireguard/clientSTAT.sh index 93abc22..a63d176 100755 --- a/scripts/wireguard/clientSTAT.sh +++ b/scripts/wireguard/clientSTAT.sh @@ -13,7 +13,7 @@ hr(){ if DUMP="$(wg show wg0 dump)"; then DUMP="$(tail -n +2 <<< "$DUMP")" else - exit 1 + exit 1 fi printf "\e[1m::: Connected Clients List :::\e[0m\n" From e0ee6cf9378560132fdab77e9077864c31b96210 Mon Sep 17 00:00:00 2001 From: Orazio Date: Sun, 26 Jan 2020 14:47:31 +0100 Subject: [PATCH 07/14] Invalidate $IPv4Addr and $IPv4gw when the user claims those settings are not correct --- auto_install/install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 68e09bd..a37c68f 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -60,7 +60,7 @@ r=$(( r < 20 ? 20 : r )) c=$(( c < 70 ? 70 : c )) # Find IP (with netmask) and gateway used to route to outside world -BaseIPv4addr=$(ip route get 192.0.2.1| awk '{print $7}') +BaseIPv4addr=$(ip route get 192.0.2.1 | awk '{print $7}') CurrentIPv4addr=$(ip -o -f inet address | grep "${BaseIPv4addr}/" | awk '{print $4}') CurrentIPv4gw=$(ip route get 192.0.2.1 | awk '{print $3}') @@ -786,6 +786,8 @@ It is also possible to use a DHCP reservation, but if you are going to do that, else # If the settings are wrong, the loop continues ipSettingsCorrect=False + IPv4AddrValid=False + IPv4gwValid=False fi done # End the if statement for DHCP vs. static @@ -1062,6 +1064,8 @@ installOpenVPN(){ } installWireGuard(){ + local PIVPN_DEPS + if [ "$PLAT" = "Raspbian" ]; then # If this Raspberry Pi uses armv7l we can use the package from the repo From 8886eab1dc8be7f18182b0ebf124c4156bf889e5 Mon Sep 17 00:00:00 2001 From: Orazio Date: Sun, 26 Jan 2020 15:37:42 +0100 Subject: [PATCH 08/14] Restart pihole in the more appropriate restartServices() function --- auto_install/install.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index a37c68f..bbb88ee 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -1350,7 +1350,6 @@ askClientDNS(){ if (whiptail --backtitle "Setup PiVPN" --title "Pi-hole" --yesno "We have detected a Pi-hole installation, do you want to use it as the DNS server for the VPN, so you get ad blocking on the go?" ${r} ${c}); then pivpnDNS1="$vpnGw" echo "interface=$pivpnDEV" | $SUDO tee /etc/dnsmasq.d/02-pivpn.conf > /dev/null - $SUDO pihole restartdns echo "pivpnDNS1=${pivpnDNS1}" >> /tmp/setupVars.conf echo "pivpnDNS2=${pivpnDNS2}" >> /tmp/setupVars.conf return @@ -1995,6 +1994,10 @@ restartServices(){ fi ;; esac + + if [ -f /etc/dnsmasq.d/02-pivpn.conf ]; then + $SUDO pihole restartdns + fi } askUnattendedUpgrades(){ From b6a47a02c3099db438ff6e2181a744d024aea16c Mon Sep 17 00:00:00 2001 From: Orazio Date: Sun, 26 Jan 2020 18:45:25 +0100 Subject: [PATCH 09/14] Improve static IP selection, validate public DNS name of the server - Default to 'No' when asking if the RPi has DHCP reservation, considered that the user may not be fully aware, furthermore, setting a static IP anyways doesn't do harm. - Validate existing IPv4 settings (address, gateway, DNS) to avoid filling '/etc/dhcpcd.conf' with invalid data. - Validate public DNS name of the server inside askPublicIPOrDNS() function --- auto_install/install.sh | 97 ++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 31 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index bbb88ee..91d6cf9 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -632,8 +632,33 @@ validIPAndNetmask(){ } getStaticIPv4Settings() { - # Grab their current DNS Server - IPv4dns=$(grep nameserver /etc/resolv.conf | awk '{print $2}' | xargs) + # Grab their current DNS servers + CurrentIPv4dns=$(grep -v "^#" /etc/resolv.conf | grep -w nameserver | awk '{print $2}' | xargs) + read -r -a CurrentIPv4dns <<< "${CurrentIPv4dns}" + + IPv4dns=() + for dns in "${CurrentIPv4dns[@]}"; do + if validIP "${dns}"; then + IPv4dns+=("${dns}") + else + echo "::: Warning: invalid system DNS ${dns}" + fi + done + + if [ "${#IPv4dns[@]}" -eq 0 ]; then + echo "::: Couldn't get current DNS servers from \"/etc/resolv.conf\", exiting..." + exit 1 + fi + + if ! validIPAndNetmask "${CurrentIPv4addr}"; then + echo "::: Couldn't get current IP address, exiting..." + exit 1 + fi + + if ! validIP "${CurrentIPv4gw}"; then + echo "::: Couldn't get current gateway IP, exiting..." + exit 1 + fi if [ "${runUnattended}" = 'true' ]; then @@ -699,7 +724,7 @@ getStaticIPv4Settings() { # Some users reserve IP addresses on another DHCP Server or on their routers, # Lets ask them if they want to make any changes to their interfaces. - if (whiptail --backtitle "Calibrating network interface" --title "DHCP Reservation" --yesno \ + if (whiptail --backtitle "Calibrating network interface" --title "DHCP Reservation" --yesno --defaultno \ "Are you Using DHCP Reservation on your Router/DHCP Server? These are your current Network Settings: @@ -744,7 +769,7 @@ It is also possible to use a DHCP reservation, but if you are going to do that, echo "::: Your static IPv4 address: ${IPv4addr}" IPv4AddrValid=True else - whiptail --msgbox --backtitle "Calibrating network interface" --title "IPv4 address" "You entered an invalid IPv4 address.\\n\\nPlease enter an IP address in the CIDR notation, example: 192.168.23.211/24.\\n\\nIf you are not sure, please just keep the default." ${r} ${c} + whiptail --msgbox --backtitle "Calibrating network interface" --title "IPv4 address" "You've entered an invalid IP address: ${IPv4addr}\\n\\nPlease enter an IP address in the CIDR notation, example: 192.168.23.211/24\\n\\nIf you are not sure, please just keep the default." ${r} ${c} echo "::: Invalid IPv4 address: ${IPv4addr}" IPv4AddrValid=False fi @@ -762,7 +787,7 @@ It is also possible to use a DHCP reservation, but if you are going to do that, echo "::: Your static IPv4 gateway: ${IPv4gw}" IPv4gwValid=True else - whiptail --msgbox --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" "You entered an invalid IPv4 address.\\n\\nPlease enter the IP address of your gateway (router), example: 192.168.23.1.\\n\\nIf you are not sure, please just keep the default." ${r} ${c} + whiptail --msgbox --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" "You've entered an invalid gateway IP: ${IPv4gw}\\n\\nPlease enter the IP address of your gateway (router), example: 192.168.23.1\\n\\nIf you are not sure, please just keep the default." ${r} ${c} echo "::: Invalid IPv4 gateway: ${IPv4gw}" IPv4gwValid=False fi @@ -801,7 +826,7 @@ setDHCPCD(){ echo "interface ${IPv4dev} static ip_address=${IPv4addr} static routers=${IPv4gw} - static domain_name_servers=${IPv4dns}" | $SUDO tee -a ${dhcpcdFile} >/dev/null + static domain_name_servers=${IPv4dns[*]}" | $SUDO tee -a ${dhcpcdFile} >/dev/null } setStaticIPv4(){ @@ -1523,36 +1548,46 @@ askPublicIPOrDNS(){ return fi - METH=$(whiptail --title "Public IP or DNS" --radiolist "Will clients use a Public IP or DNS Name to connect to your server (press space to select)?" ${r} ${c} 2 \ - "$IPv4pub" "Use this public IP" "ON" \ - "DNS Entry" "Use a public DNS" "OFF" 3>&1 1>&2 2>&3) + local publicDNSCorrect + local publicDNSValid - exitstatus=$? - if [ $exitstatus != 0 ]; then + if METH=$(whiptail --title "Public IP or DNS" --radiolist "Will clients use a Public IP or DNS Name to connect to your server (press space to select)?" ${r} ${c} 2 \ + "$IPv4pub" "Use this public IP" "ON" \ + "DNS Entry" "Use a public DNS" "OFF" 3>&1 1>&2 2>&3); then + + if [ "$METH" = "$IPv4pub" ]; then + pivpnHOST="${IPv4pub}" + else + until [[ ${publicDNSCorrect} = True ]]; do + + until [[ ${publicDNSValid} = True ]]; do + if PUBLICDNS=$(whiptail --title "PiVPN Setup" --inputbox "What is the public DNS name of this Server?" ${r} ${c} 3>&1 1>&2 2>&3); then + if validDomain "$PUBLICDNS"; then + publicDNSValid=True + pivpnHOST="${PUBLICDNS}" + else + whiptail --msgbox --backtitle "PiVPN Setup" --title "Invalid DNS name" "This DNS name is invalid. Please try again.\\n\\n DNS name: $PUBLICDNS\\n" ${r} ${c} + publicDNSValid=False + fi + else + echo "::: Cancel selected. Exiting..." + exit 1 + fi + done + + if (whiptail --backtitle "PiVPN Setup" --title "Confirm DNS Name" --yesno "Is this correct?\\n\\n Public DNS Name: $PUBLICDNS" ${r} ${c}) then + publicDNSCorrect=True + else + publicDNSCorrect=False + publicDNSValid=False + fi + done + fi + else echo "::: Cancel selected. Exiting..." exit 1 fi - if [ "$METH" == "$IPv4pub" ]; then - pivpnHOST="${IPv4pub}" - else - until [[ $publicDNSCorrect = True ]] - do - PUBLICDNS=$(whiptail --title "PiVPN Setup" --inputbox "What is the public DNS name of this Server?" ${r} ${c} 3>&1 1>&2 2>&3) - exitstatus=$? - if [ $exitstatus != 0 ]; then - echo "::: Cancel selected. Exiting..." - exit 1 - fi - if (whiptail --backtitle "Confirm DNS Name" --title "Confirm DNS Name" --yesno "Is this correct?\\n\\n Public DNS Name: $PUBLICDNS" ${r} ${c}) then - publicDNSCorrect=True - pivpnHOST="${PUBLICDNS}" - else - publicDNSCorrect=False - fi - done - fi - echo "pivpnHOST=${pivpnHOST}" >> /tmp/setupVars.conf } From 9679a600c165a7f100b638ea29b813a8005ea918 Mon Sep 17 00:00:00 2001 From: Orazio Date: Mon, 27 Jan 2020 14:44:03 +0100 Subject: [PATCH 10/14] Check DH parameters, fix 'pivpn -c', improvements when dealing with external repositories - Added a basic sanity check to downloaded DH paramenters, which doubles as a check for missing .pem file. - Fix 'pivpn -c' showing the month number instead of the day of the month when using WireGuard. - Removing APT keys is risky, it would break APT update/upgrade if the user already was already using the unstable repo. - Replaced 'Checking for $i... installed' in favor of a more clear 'Checking for $i... already installed'. - Check whether the OpenVPN repo and the Debian unstable repo are already used. --- auto_install/install.sh | 60 ++++++++++++++++++++++++++------- scripts/uninstall.sh | 12 ++----- scripts/wireguard/clientSTAT.sh | 2 +- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 91d6cf9..074685c 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -468,7 +468,7 @@ installDependentPackages(){ for i in "${argArray1[@]}"; do echo -n "::: Checking for $i..." if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep -q "ok installed"; then - echo " installed!" + echo " already installed!" else echo " not installed!" # Add this package to the list of packages in the argument array that need to be installed @@ -1069,19 +1069,29 @@ askWhichVPN(){ installOpenVPN(){ local PIVPN_DEPS + echo "::: Installing OpenVPN from Debian package... " + if [ "$PLAT" = "Debian" ] || [ "$PLAT" = "Ubuntu" ]; then - echo "::: Adding OpenVPN repository... " # gnupg is used to add the openvpn PGP key to the APT keyring PIVPN_DEPS=(gnupg) installDependentPackages PIVPN_DEPS[@] + + # We will download the repository key regardless of whether the user + # has already enabled the openvpn repository or not, just to make sure + # we have the right key + echo "::: Adding repository key..." wget -qO- https://swupdate.openvpn.net/repos/repo-public.gpg | $SUDO apt-key add - - echo "deb https://build.openvpn.net/debian/openvpn/stable $OSCN main" | $SUDO tee /etc/apt/sources.list.d/pivpn-openvpn-repo.list > /dev/null + + if ! grep -qR "deb http.\?://build.openvpn.net/debian/openvpn/stable.\? $OSCN main" /etc/apt/sources.list*; then + echo "::: Adding OpenVPN repository... " + echo "deb https://build.openvpn.net/debian/openvpn/stable $OSCN main" | $SUDO tee /etc/apt/sources.list.d/pivpn-openvpn-repo.list > /dev/null + fi + echo "::: Updating package cache..." # shellcheck disable=SC2086 $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! fi - echo "::: Installing OpenVPN from Debian package... " # grepcidr is used to redact IPs in the debug log whereas expect is used # to feed easy-rsa with passwords PIVPN_DEPS=(openvpn grepcidr expect) @@ -1101,20 +1111,28 @@ installWireGuard(){ if [ "$(uname -m)" = "armv7l" ]; then echo "::: Installing WireGuard from Debian package... " - # dirmngr is used to download repository keys, whereas qrencode is used to generate qrcodes - # from config file, for use with mobile clients - PIVPN_DEPS=(dirmngr qrencode) + # dirmngr is used to download repository keys for the unstable repo + PIVPN_DEPS=(dirmngr) installDependentPackages PIVPN_DEPS[@] + + echo "::: Adding repository keys..." + $SUDO apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC 648ACFD622F3D138 + + # This regular expression should match combinations like http[s]://mirror.example.com/debian[/] unstable main + if ! grep -qR 'deb http.\?://.*/debian.\? unstable main' /etc/apt/sources.list*; then + echo "::: Adding Debian repository... " + echo "deb https://deb.debian.org/debian/ unstable main" | $SUDO tee /etc/apt/sources.list.d/pivpn-unstable.list > /dev/null + fi + # Do not upgrade packages from the unstable repository except for wireguard - echo "::: Adding Debian repository... " - echo "deb https://deb.debian.org/debian/ unstable main" | $SUDO tee /etc/apt/sources.list.d/pivpn-unstable.list > /dev/null printf 'Package: *\nPin: release a=unstable\nPin-Priority: 1\n\nPackage: wireguard wireguard-dkms wireguard-tools\nPin: release a=unstable\nPin-Priority: 500\n' | $SUDO tee /etc/apt/preferences.d/pivpn-limit-unstable > /dev/null - $SUDO apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC 648ACFD622F3D138 echo "::: Updating package cache..." # shellcheck disable=SC2086 $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! - PIVPN_DEPS=(raspberrypi-kernel-headers wireguard wireguard-tools wireguard-dkms) + + # qrencode is used to generate qrcodes from config file, for use with mobile clients + PIVPN_DEPS=(raspberrypi-kernel-headers wireguard wireguard-tools wireguard-dkms qrencode) installDependentPackages PIVPN_DEPS[@] elif [ "$(uname -m)" = "armv6l" ]; then @@ -1210,12 +1228,17 @@ installWireGuard(){ elif [ "$PLAT" = "Debian" ]; then echo "::: Installing WireGuard from Debian package... " - echo "::: Adding Debian repository... " - echo "deb https://deb.debian.org/debian/ unstable main" | $SUDO tee /etc/apt/sources.list.d/pivpn-unstable.list > /dev/null + if ! grep -qR 'deb http.\?://.*/debian.\? unstable main' /etc/apt/sources.list*; then + echo "::: Adding Debian repository... " + echo "deb https://deb.debian.org/debian/ unstable main" | $SUDO tee /etc/apt/sources.list.d/pivpn-unstable.list > /dev/null + fi + printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' | $SUDO tee /etc/apt/preferences.d/pivpn-limit-unstable > /dev/null + echo "::: Updating package cache..." # shellcheck disable=SC2086 $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! + PIVPN_DEPS=(linux-headers-amd64 qrencode wireguard wireguard-tools wireguard-dkms) installDependentPackages PIVPN_DEPS[@] @@ -1223,9 +1246,11 @@ installWireGuard(){ echo "::: Installing WireGuard from PPA... " $SUDO add-apt-repository ppa:wireguard/wireguard -y + echo "::: Updating package cache..." # shellcheck disable=SC2086 $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! + PIVPN_DEPS=(qrencode wireguard wireguard-tools wireguard-dkms linux-headers-generic) installDependentPackages PIVPN_DEPS[@] @@ -1759,6 +1784,15 @@ set_var EASYRSA_ALGO ${pivpnCERT}" | $SUDO tee vars >/dev/null if [ ${DOWNLOAD_DH_PARAM} -eq 1 ]; then # Downloading parameters ${SUDOE} curl -s "https://2ton.com.au/getprimes/random/dhparam/${pivpnENCRYPT}" -o "/etc/openvpn/easy-rsa/pki/dh${pivpnENCRYPT}.pem" + # Basic sanity check + if DH_MSG="$(${SUDOE} openssl dhparam -check -noout -in "/etc/openvpn/easy-rsa/pki/dh${pivpnENCRYPT}.pem" 2>&1 | tee /dev/tty)"; then + if [ "$DH_MSG" != "DH parameters appear to be ok." ]; then + echo "Invalid DH parameters, exiting..." + exit 1 + fi + else + exit 1 + fi else # Generate Diffie-Hellman key exchange ${SUDOE} ./easyrsa gen-dh diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index b570fd1..defba8f 100755 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -114,13 +114,11 @@ removeAll(){ if [ "$PLAT" = "Debian" ] || { [ "$PLAT" = "Raspbian" ] && [ "$(uname -m)" = "armv7l" ]; }; then rm -f /etc/apt/sources.list.d/pivpn-unstable.list rm -f /etc/apt/preferences.d/pivpn-limit-unstable - echo "::: Updating package cache..." - ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! elif [ "$PLAT" = "Ubuntu" ]; then add-apt-repository ppa:wireguard/wireguard -r -y - echo "::: Updating package cache..." - ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! fi + echo "::: Updating package cache..." + ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! elif [ "${i}" = "wireguard-dkms" ]; then @@ -138,12 +136,6 @@ removeAll(){ rm -rf /usr/src/wireguard-tools-"${WG_TOOLS_SNAPSHOT}" fi - elif [ "${i}" = "dirmngr" ]; then - - # If dirmngr was installed, then we had previously installed wireguard on armv7l Raspbian - # so we remove the repository keys - apt-key remove E1CF20DDFFE4B89E802658F1E0B11894F66AEC98 80D15823B7FD1561F9F7BCDDDC30D7C23CBBABEE &> /dev/null - elif [ "${i}" = "unattended-upgrades" ]; then ### REALLY??? diff --git a/scripts/wireguard/clientSTAT.sh b/scripts/wireguard/clientSTAT.sh index a63d176..f75050f 100755 --- a/scripts/wireguard/clientSTAT.sh +++ b/scripts/wireguard/clientSTAT.sh @@ -32,7 +32,7 @@ while IFS= read -r LINE; do CLIENT_NAME="$(grep "$PUBLIC_KEY" clients.txt | awk '{ print $1 }')" if [ "$LAST_SEEN" -ne 0 ]; then - printf "%s \t %s \t %s \t %s \t %s \t %s\n" "$CLIENT_NAME" "$REMOTE_IP" "${VIRTUAL_IP/\/32/}" "$(hr "$BYTES_RECEIVED")" "$(hr "$BYTES_SENT")" "$(date -d @"$LAST_SEEN" '+%b %m %Y - %T')" + printf "%s \t %s \t %s \t %s \t %s \t %s\n" "$CLIENT_NAME" "$REMOTE_IP" "${VIRTUAL_IP/\/32/}" "$(hr "$BYTES_RECEIVED")" "$(hr "$BYTES_SENT")" "$(date -d @"$LAST_SEEN" '+%b %d %Y - %T')" else printf "%s \t %s \t %s \t %s \t %s \t %s\n" "$CLIENT_NAME" "$REMOTE_IP" "${VIRTUAL_IP/\/32/}" "$(hr "$BYTES_RECEIVED")" "$(hr "$BYTES_SENT")" "(not yet)" fi From 380dc0ab373863aa283726ad14c65e2421875aa6 Mon Sep 17 00:00:00 2001 From: Orazio Date: Wed, 29 Jan 2020 14:11:38 +0100 Subject: [PATCH 11/14] Improvements to getStaticIPv4Settings() - Use a regular expression to extract IPs from the 'ip' command. With this, there is a little need to validate output. Even though the regex will match invalid IPs like 192.168.23.444, 'ip' can't return them, and even if it did, the script would not have reached this function due to previous functions using the network with broken routes and addresses. - Get the IP address from the selected interface rather then from the 'ip route' command as it's not guaranteed that such IP is the same of the interface the user decided to use (though on a Raspberry Pi inside a home LAN, most likely it is, but it also maskes easier to get the IP in the CIDR notation with a single 'ip | grep' pipe). --- auto_install/install.sh | 38 +++++++------------------------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 074685c..68083e5 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -59,10 +59,8 @@ c=$(( columns / 2 )) r=$(( r < 20 ? 20 : r )) c=$(( c < 70 ? 70 : c )) -# Find IP (with netmask) and gateway used to route to outside world -BaseIPv4addr=$(ip route get 192.0.2.1 | awk '{print $7}') -CurrentIPv4addr=$(ip -o -f inet address | grep "${BaseIPv4addr}/" | awk '{print $4}') -CurrentIPv4gw=$(ip route get 192.0.2.1 | awk '{print $3}') +# Find the gateway IP used to route to outside world +CurrentIPv4gw="$(ip -o route get 192.0.2.1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk 'NR==2')" # Find network interfaces whose state is UP, so as to skip virtual interfaces and the loopback interface availableInterfaces=$(ip -o link | awk '/state UP/ {print $2}' | cut -d':' -f1 | cut -d'@' -f1) @@ -632,33 +630,11 @@ validIPAndNetmask(){ } getStaticIPv4Settings() { + # Find the IP address (and netmask) of the desidered interface + CurrentIPv4addr="$(ip -o -f inet address show dev "${IPv4dev}" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,2}')" + # Grab their current DNS servers - CurrentIPv4dns=$(grep -v "^#" /etc/resolv.conf | grep -w nameserver | awk '{print $2}' | xargs) - read -r -a CurrentIPv4dns <<< "${CurrentIPv4dns}" - - IPv4dns=() - for dns in "${CurrentIPv4dns[@]}"; do - if validIP "${dns}"; then - IPv4dns+=("${dns}") - else - echo "::: Warning: invalid system DNS ${dns}" - fi - done - - if [ "${#IPv4dns[@]}" -eq 0 ]; then - echo "::: Couldn't get current DNS servers from \"/etc/resolv.conf\", exiting..." - exit 1 - fi - - if ! validIPAndNetmask "${CurrentIPv4addr}"; then - echo "::: Couldn't get current IP address, exiting..." - exit 1 - fi - - if ! validIP "${CurrentIPv4gw}"; then - echo "::: Couldn't get current gateway IP, exiting..." - exit 1 - fi + IPv4dns=$(grep -v "^#" /etc/resolv.conf | grep -w nameserver | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | xargs) if [ "${runUnattended}" = 'true' ]; then @@ -826,7 +802,7 @@ setDHCPCD(){ echo "interface ${IPv4dev} static ip_address=${IPv4addr} static routers=${IPv4gw} - static domain_name_servers=${IPv4dns[*]}" | $SUDO tee -a ${dhcpcdFile} >/dev/null + static domain_name_servers=${IPv4dns}" | $SUDO tee -a ${dhcpcdFile} >/dev/null } setStaticIPv4(){ From 379ab50f5f63d1950d0977dc9f6e40db97714853 Mon Sep 17 00:00:00 2001 From: Orazio Date: Thu, 30 Jan 2020 17:29:31 +0100 Subject: [PATCH 12/14] Moved command substitution to specific functions to avoid unnecessary execution - Moved $availableInterfaces and $CurrentIPv4gw from the script header to their relevant function, considered that if the OS is not Raspbian a static IP is not set, so those variables are not used. --- auto_install/install.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 68083e5..d2a1e96 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -59,12 +59,6 @@ c=$(( columns / 2 )) r=$(( r < 20 ? 20 : r )) c=$(( c < 70 ? 70 : c )) -# Find the gateway IP used to route to outside world -CurrentIPv4gw="$(ip -o route get 192.0.2.1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk 'NR==2')" - -# Find network interfaces whose state is UP, so as to skip virtual interfaces and the loopback interface -availableInterfaces=$(ip -o link | awk '/state UP/ {print $2}' | cut -d':' -f1 | cut -d'@' -f1) - ######## SCRIPT ############ main(){ @@ -529,6 +523,9 @@ local chooseInterfaceOptions # Loop sentinel variable local firstloop=1 +# Find network interfaces whose state is UP, so as to skip virtual interfaces and the loopback interface +availableInterfaces=$(ip -o link | awk '/state UP/ {print $2}' | cut -d':' -f1 | cut -d'@' -f1) + if [ -z "$availableInterfaces" ]; then echo "::: Could not find any active network interface, exiting" exit 1 @@ -630,6 +627,9 @@ validIPAndNetmask(){ } getStaticIPv4Settings() { + # Find the gateway IP used to route to outside world + CurrentIPv4gw="$(ip -o route get 192.0.2.1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk 'NR==2')" + # Find the IP address (and netmask) of the desidered interface CurrentIPv4addr="$(ip -o -f inet address show dev "${IPv4dev}" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,2}')" From e949aadbc3b08c397e0b68ca17c2f638a9df34c3 Mon Sep 17 00:00:00 2001 From: Orazio Date: Fri, 31 Jan 2020 14:07:58 +0100 Subject: [PATCH 13/14] Copy files from git repo using the 'install' command, switch DH params from 2ton.com.au to RFC 7919 - Now using DH parameters suggested by the RFC 7919 for use by TLS servers (the user can still generate his own if he wishes). https://wiki.mozilla.org/Security/Archive/Server_Side_TLS_4.0#Pre-defined_DHE_groups --- auto_install/install.sh | 60 ++++++++----------- .../unattended_openvpn_example.conf | 2 +- .../unattended_wireguard_example.conf | 0 .../etc/openvpn/easy-rsa/pki/Default.txt | 0 files/etc/openvpn/easy-rsa/pki/ffdhe2048.pem | 8 +++ files/etc/openvpn/easy-rsa/pki/ffdhe3072.pem | 11 ++++ files/etc/openvpn/easy-rsa/pki/ffdhe4096.pem | 13 ++++ .../etc/openvpn/server_config.txt | 0 8 files changed, 59 insertions(+), 35 deletions(-) rename unattended_openvpn_example.conf => examples/unattended_openvpn_example.conf (91%) rename unattended_wireguard_example.conf => examples/unattended_wireguard_example.conf (100%) rename Default.txt => files/etc/openvpn/easy-rsa/pki/Default.txt (100%) create mode 100644 files/etc/openvpn/easy-rsa/pki/ffdhe2048.pem create mode 100644 files/etc/openvpn/easy-rsa/pki/ffdhe3072.pem create mode 100644 files/etc/openvpn/easy-rsa/pki/ffdhe4096.pem rename server_config.txt => files/etc/openvpn/server_config.txt (100%) diff --git a/auto_install/install.sh b/auto_install/install.sh index d2a1e96..5d9de4e 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -1626,17 +1626,21 @@ askEncryption(){ fi fi - if [ -z "$DOWNLOAD_DH_PARAM" ] || [ "$DOWNLOAD_DH_PARAM" -ne 1 ]; then - DOWNLOAD_DH_PARAM=0 - echo "::: DH parameters will be generated locally" + if [ -z "$USE_PREDEFINED_DH_PARAM" ]; then + USE_PREDEFINED_DH_PARAM=1 + echo "::: Pre-defined DH parameters will be used" else - echo "::: DH parameters will be downloaded from \"2 Ton Digital\"" + if [ "$USE_PREDEFINED_DH_PARAM" -eq 1 ]; then + echo "::: Pre-defined DH parameters will be used" + else + echo "::: DH parameters will be generated locally" + fi fi fi echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}" >> /tmp/setupVars.conf echo "pivpnENCRYPT=${pivpnENCRYPT}" >> /tmp/setupVars.conf - echo "DOWNLOAD_DH_PARAM=${DOWNLOAD_DH_PARAM}" >> /tmp/setupVars.conf + echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}" >> /tmp/setupVars.conf return fi @@ -1662,15 +1666,15 @@ askEncryption(){ exit 1 fi - if ([ "$pivpnENCRYPT" -ge 3072 ] && whiptail --backtitle "Setup OpenVPN" --title "Download Diffie-Hellman Parameters" --yesno --defaultno "Download Diffie-Hellman parameters from a public DH parameter generation service?\\n\\nGenerating DH parameters for a $pivpnENCRYPT-bit key can take many hours on a Raspberry Pi. You can instead download DH parameters from \"2 Ton Digital\" that are generated at regular intervals as part of a public service. Downloaded DH parameters will be randomly selected from their database.\\nMore information about this service can be found here: https://2ton.com.au/safeprimes/\\n\\nIf you're paranoid, choose 'No' and Diffie-Hellman parameters will be generated on your device." ${r} ${c}); then - DOWNLOAD_DH_PARAM=1 + if ([ "$pivpnENCRYPT" -ge 2048 ] && whiptail --backtitle "Setup OpenVPN" --title "Generate Diffie-Hellman Parameters" --yesno "Generating DH parameters can take many hours on a Raspberry Pi. You can instead use Pre-defined DH parameters recommended by the Internet Engineering Task Force.\\n\\nMore information about those can be found here: https://wiki.mozilla.org/Security/Archive/Server_Side_TLS_4.0#Pre-defined_DHE_groups\\n\\nIf you want unique parameters, choose 'No' and new Diffie-Hellman parameters will be generated on your device." ${r} ${c}); then + USE_PREDEFINED_DH_PARAM=1 else - DOWNLOAD_DH_PARAM=0 + USE_PREDEFINED_DH_PARAM=0 fi echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}" >> /tmp/setupVars.conf echo "pivpnENCRYPT=${pivpnENCRYPT}" >> /tmp/setupVars.conf - echo "DOWNLOAD_DH_PARAM=${DOWNLOAD_DH_PARAM}" >> /tmp/setupVars.conf + echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}" >> /tmp/setupVars.conf } confOpenVPN(){ @@ -1739,13 +1743,13 @@ set_var EASYRSA_ALGO ${pivpnCERT}" | $SUDO tee vars >/dev/null ${SUDOE} ./easyrsa --batch build-ca nopass printf "\\n::: CA Complete.\\n" - if [ "$pivpnCERT" = "rsa" ]; then + if [ "$pivpnCERT" = "rsa" ] && [ "$USE_PREDEFINED_DH_PARAM" -ne 1 ]; then if [ "${runUnattended}" = 'true' ]; then echo "::: The server key, Diffie-Hellman parameters, and HMAC key will now be generated." else whiptail --msgbox --backtitle "Setup OpenVPN" --title "Server Information" "The server key, Diffie-Hellman parameters, and HMAC key will now be generated." ${r} ${c} fi - elif [ "$pivpnCERT" = "ec" ]; then + elif [ "$pivpnCERT" = "ec" ] || { [ "$pivpnCERT" = "rsa" ] && [ "$USE_PREDEFINED_DH_PARAM" -eq 1 ]; }; then if [ "${runUnattended}" = 'true' ]; then echo "::: The server key and HMAC key will now be generated." else @@ -1757,22 +1761,13 @@ set_var EASYRSA_ALGO ${pivpnCERT}" | $SUDO tee vars >/dev/null EASYRSA_CERT_EXPIRE=3650 ${SUDOE} ./easyrsa build-server-full "${SERVER_NAME}" nopass if [ "$pivpnCERT" = "rsa" ]; then - if [ ${DOWNLOAD_DH_PARAM} -eq 1 ]; then - # Downloading parameters - ${SUDOE} curl -s "https://2ton.com.au/getprimes/random/dhparam/${pivpnENCRYPT}" -o "/etc/openvpn/easy-rsa/pki/dh${pivpnENCRYPT}.pem" - # Basic sanity check - if DH_MSG="$(${SUDOE} openssl dhparam -check -noout -in "/etc/openvpn/easy-rsa/pki/dh${pivpnENCRYPT}.pem" 2>&1 | tee /dev/tty)"; then - if [ "$DH_MSG" != "DH parameters appear to be ok." ]; then - echo "Invalid DH parameters, exiting..." - exit 1 - fi - else - exit 1 - fi + if [ "${USE_PREDEFINED_DH_PARAM}" -eq 1 ]; then + # Use Diffie-Hellman parameters from RFC 7919 (FFDHE) + ${SUDOE} install -m 644 "${pivpnFilesDir}"/files/etc/openvpn/easy-rsa/pki/ffdhe"${pivpnENCRYPT}".pem pki/dh"${pivpnENCRYPT}".pem else # Generate Diffie-Hellman key exchange ${SUDOE} ./easyrsa gen-dh - ${SUDOE} mv "pki/dh.pem" "pki/dh${pivpnENCRYPT}.pem" + ${SUDOE} mv pki/dh.pem pki/dh"${pivpnENCRYPT}".pem fi fi @@ -1788,7 +1783,7 @@ set_var EASYRSA_ALGO ${pivpnCERT}" | $SUDO tee vars >/dev/null ${SUDOE} chown "$debianOvpnUserGroup" /etc/openvpn/crl.pem # Write config file for server using the template.txt file - $SUDO cp $pivpnFilesDir/server_config.txt /etc/openvpn/server.conf + $SUDO install -m 644 "$pivpnFilesDir"/files/etc/openvpn/server_config.txt /etc/openvpn/server.conf # Apply client DNS settings ${SUDOE} sed -i '0,/\(dhcp-option DNS \)/ s/\(dhcp-option DNS \).*/\1'${pivpnDNS1}'\"/' /etc/openvpn/server.conf @@ -1835,7 +1830,7 @@ set_var EASYRSA_ALGO ${pivpnCERT}" | $SUDO tee vars >/dev/null } confOVPN(){ - $SUDO cp $pivpnFilesDir/Default.txt /etc/openvpn/easy-rsa/pki/Default.txt + $SUDO install -m 644 "$pivpnFilesDir"/files/etc/openvpn/easy-rsa/pki/Default.txt /etc/openvpn/easy-rsa/pki/Default.txt $SUDO sed -i 's/IPv4pub/'"$pivpnHOST"'/' /etc/openvpn/easy-rsa/pki/Default.txt @@ -2128,14 +2123,11 @@ installScripts(){ $SUDO chmod 0755 /opt/pivpn fi - $SUDO cp "$pivpnFilesDir"/scripts/*.sh /opt/pivpn/ - $SUDO cp "$pivpnFilesDir"/scripts/"$VPN"/*.sh /opt/pivpn/ - $SUDO chmod 0755 /opt/pivpn/*.sh - $SUDO cp "$pivpnFilesDir"/scripts/"$VPN"/pivpn /usr/local/bin/pivpn - $SUDO chmod 0755 /usr/local/bin/pivpn - $SUDO cp "$pivpnFilesDir"/scripts/"$VPN"/bash-completion /etc/bash_completion.d/pivpn - $SUDO chmod 0644 /etc/bash_completion.d/pivpn - # shellcheck disable=SC1091 + $SUDO install -m 755 "$pivpnFilesDir"/scripts/*.sh -t /opt/pivpn + $SUDO install -m 755 "$pivpnFilesDir"/scripts/"$VPN"/*.sh -t /opt/pivpn + $SUDO install -m 755 "$pivpnFilesDir"/scripts/"$VPN"/pivpn /usr/local/bin/pivpn + $SUDO install -m 644 "$pivpnFilesDir"/scripts/"$VPN"/bash-completion /etc/bash_completion.d/pivpn + # shellcheck disable=SC1091 . /etc/bash_completion.d/pivpn echo " done." } diff --git a/unattended_openvpn_example.conf b/examples/unattended_openvpn_example.conf similarity index 91% rename from unattended_openvpn_example.conf rename to examples/unattended_openvpn_example.conf index 969c915..a20f917 100644 --- a/unattended_openvpn_example.conf +++ b/examples/unattended_openvpn_example.conf @@ -12,5 +12,5 @@ pivpnHOST=pivpn.example.com pivpnENCRYPT=256 pivpnSEARCHDOMAIN=searchdomain.example.com TWO_POINT_FOUR=1 -DOWNLOAD_DH_PARAM=0 +USE_PREDEFINED_DH_PARAM=1 UNATTUPG=1 diff --git a/unattended_wireguard_example.conf b/examples/unattended_wireguard_example.conf similarity index 100% rename from unattended_wireguard_example.conf rename to examples/unattended_wireguard_example.conf diff --git a/Default.txt b/files/etc/openvpn/easy-rsa/pki/Default.txt similarity index 100% rename from Default.txt rename to files/etc/openvpn/easy-rsa/pki/Default.txt diff --git a/files/etc/openvpn/easy-rsa/pki/ffdhe2048.pem b/files/etc/openvpn/easy-rsa/pki/ffdhe2048.pem new file mode 100644 index 0000000..9b182b7 --- /dev/null +++ b/files/etc/openvpn/easy-rsa/pki/ffdhe2048.pem @@ -0,0 +1,8 @@ +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz ++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a +87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 +YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi +7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD +ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== +-----END DH PARAMETERS----- diff --git a/files/etc/openvpn/easy-rsa/pki/ffdhe3072.pem b/files/etc/openvpn/easy-rsa/pki/ffdhe3072.pem new file mode 100644 index 0000000..fb31ccd --- /dev/null +++ b/files/etc/openvpn/easy-rsa/pki/ffdhe3072.pem @@ -0,0 +1,11 @@ +-----BEGIN DH PARAMETERS----- +MIIBiAKCAYEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz ++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a +87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 +YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi +7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD +ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3 +7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32 +nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZsYu +N///////////AgEC +-----END DH PARAMETERS----- diff --git a/files/etc/openvpn/easy-rsa/pki/ffdhe4096.pem b/files/etc/openvpn/easy-rsa/pki/ffdhe4096.pem new file mode 100644 index 0000000..3cf0fcb --- /dev/null +++ b/files/etc/openvpn/easy-rsa/pki/ffdhe4096.pem @@ -0,0 +1,13 @@ +-----BEGIN DH PARAMETERS----- +MIICCAKCAgEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz ++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a +87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 +YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi +7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD +ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3 +7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32 +nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZp4e +8W5vUsMWTfT7eTDp5OWIV7asfV9C1p9tGHdjzx1VA0AEh/VbpX4xzHpxNciG77Qx +iu1qHgEtnmgyqQdgCpGBMMRtx3j5ca0AOAkpmaMzy4t6Gh25PXFAADwqTs6p+Y0K +zAqCkc3OyX3Pjsm1Wn+IpGtNtahR9EGC4caKAH5eZV9q//////////8CAQI= +-----END DH PARAMETERS----- diff --git a/server_config.txt b/files/etc/openvpn/server_config.txt similarity index 100% rename from server_config.txt rename to files/etc/openvpn/server_config.txt From b8f89ab015477387d4c3169da82b7e9be518ecf8 Mon Sep 17 00:00:00 2001 From: 4s3ti <4s3ti@protonmail.com> Date: Fri, 31 Jan 2020 20:24:31 +0100 Subject: [PATCH 14/14] Revert "Merge test (#929)" This reverts commit d691321b3e0aa2e15654e91c7a23e303c01ca0bb. --- .../easy-rsa/pki/Default.txt => Default.txt | 0 auto_install/install.sh | 440 ++++++------------ files/etc/openvpn/easy-rsa/pki/ffdhe2048.pem | 8 - files/etc/openvpn/easy-rsa/pki/ffdhe3072.pem | 11 - files/etc/openvpn/easy-rsa/pki/ffdhe4096.pem | 13 - scripts/backup.sh | 13 +- scripts/openvpn/makeOVPN.sh | 2 +- scripts/openvpn/pivpnDebug.sh | 156 ++++++- scripts/self_check.sh | 170 ------- scripts/uninstall.sh | 18 +- scripts/update.sh | 25 +- scripts/wireguard/bash-completion | 4 +- scripts/wireguard/clientSTAT.sh | 8 +- scripts/wireguard/makeCONF.sh | 14 +- scripts/wireguard/pivpn | 9 +- scripts/wireguard/pivpnDEBUG.sh | 156 ++++++- scripts/wireguard/removeCONF.sh | 14 +- scripts/wireguard/wgUPDATE.sh | 132 ------ .../server_config.txt => server_config.txt | 0 ...le.conf => unattended_openvpn_example.conf | 4 +- ....conf => unattended_wireguard_example.conf | 2 - 21 files changed, 507 insertions(+), 692 deletions(-) rename files/etc/openvpn/easy-rsa/pki/Default.txt => Default.txt (100%) delete mode 100644 files/etc/openvpn/easy-rsa/pki/ffdhe2048.pem delete mode 100644 files/etc/openvpn/easy-rsa/pki/ffdhe3072.pem delete mode 100644 files/etc/openvpn/easy-rsa/pki/ffdhe4096.pem delete mode 100755 scripts/self_check.sh delete mode 100755 scripts/wireguard/wgUPDATE.sh rename files/etc/openvpn/server_config.txt => server_config.txt (100%) rename examples/unattended_openvpn_example.conf => unattended_openvpn_example.conf (76%) rename examples/unattended_wireguard_example.conf => unattended_wireguard_example.conf (76%) diff --git a/files/etc/openvpn/easy-rsa/pki/Default.txt b/Default.txt similarity index 100% rename from files/etc/openvpn/easy-rsa/pki/Default.txt rename to Default.txt diff --git a/auto_install/install.sh b/auto_install/install.sh index a819238..9e9d7b8 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -24,12 +24,12 @@ PKG_INSTALL="${PKG_MANAGER} --yes --no-install-recommends install" PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true" # Dependencies that are required by the script, regardless of the VPN protocol chosen -BASE_DEPS=(git tar wget curl grep dnsutils whiptail net-tools bsdmainutils) +BASE_DEPS=(git tar wget grep dnsutils whiptail net-tools bsdmainutils) # Dependencies that where actually installed by the script. For example if the script requires # grep and dnsutils but dnsutils is already installed, we save grep here. This way when uninstalling # PiVPN we won't prompt to remove packages that may have been installed by the user for other reasons -INSTALLED_PACKAGES=() +TO_INSTALL=() easyrsaVer="3.0.6" easyrsaRel="https://github.com/OpenVPN/easy-rsa/releases/download/v${easyrsaVer}/EasyRSA-unix-v${easyrsaVer}.tgz" @@ -59,6 +59,11 @@ c=$(( columns / 2 )) r=$(( r < 20 ? 20 : r )) c=$(( c < 70 ? 70 : c )) +# Find IP used to route to outside world +IPv4addr=$(ip route get 192.0.2.1 | awk '{print $7}') +IPv4gw=$(ip route get 192.0.2.1 | awk '{print $3}') +availableInterfaces=$(ip -o link | awk '/state UP/ {print $2}' | cut -d':' -f1 | cut -d'@' -f1) + ######## SCRIPT ############ main(){ @@ -190,7 +195,7 @@ main(){ fi # Save installation setting to the final location - echo "INSTALLED_PACKAGES=(${INSTALLED_PACKAGES[*]})" >> /tmp/setupVars.conf + echo "TO_INSTALL=(${TO_INSTALL[*]})" >> /tmp/setupVars.conf $SUDO cp /tmp/setupVars.conf "$setupVars" installScripts @@ -230,7 +235,7 @@ askAboutExistingInstall(){ # distroCheck, maybeOSSupport, noOSSupport distroCheck(){ # if lsb_release command is on their system - if command -v lsb_release > /dev/null; then + if hash lsb_release 2>/dev/null; then PLAT=$(lsb_release -si) OSCN=$(lsb_release -sc) @@ -330,7 +335,7 @@ spinner(){ local pid=$1 local delay=0.50 local spinstr='/-\|' - while ps a | awk '{print $1}' | grep -q "$pid"; do + while ps a | awk '{print $1}' | grep "${pid}"; do local temp=${spinstr#?} printf " [%c] " "${spinstr}" local spinstr=${temp}${spinstr%"$temp"} @@ -394,7 +399,7 @@ updatePackageCache(){ echo ":::" echo -ne "::: ${PKG_MANAGER} update has not been run today. Running now...\\n" # shellcheck disable=SC2086 - $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! + $SUDO ${UPDATE_PKG_CACHE} &> /dev/null echo " done!" fi } @@ -431,7 +436,7 @@ preconfigurePackages(){ # if ufw is enabled, configure that. # running as root because sometimes the executable is not in the user's $PATH - if $SUDO bash -c 'command -v ufw' > /dev/null; then + if $SUDO bash -c 'hash ufw' 2>/dev/null; then if LANG=en_US.UTF-8 $SUDO ufw status | grep -q inactive; then USING_UFW=0 else @@ -451,46 +456,25 @@ preconfigurePackages(){ } installDependentPackages(){ - declare -a TO_INSTALL=() - # Install packages passed in via argument array # No spinner - conflicts with set -e declare -a argArray1=("${!1}") for i in "${argArray1[@]}"; do echo -n "::: Checking for $i..." - if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep -q "ok installed"; then - echo " already installed!" - else - echo " not installed!" - # Add this package to the list of packages in the argument array that need to be installed - TO_INSTALL+=("${i}") - fi + if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep -q "ok installed"; then + echo " installed!" + else + TO_INSTALL+=("${i}") + echo " not installed!" + fi done - if command -v debconf-apt-progress > /dev/null; then + if command -v debconf-apt-progress &> /dev/null; then # shellcheck disable=SC2086 - $SUDO debconf-apt-progress -- ${PKG_INSTALL} "${TO_INSTALL[@]}" + $SUDO debconf-apt-progress -- ${PKG_INSTALL} "${argArray1[@]}" else - # shellcheck disable=SC2086 - $SUDO ${PKG_INSTALL} "${TO_INSTALL[@]}" - fi - - local FAILED=0 - - for i in "${TO_INSTALL[@]}"; do - if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep -q "ok installed"; then - echo "::: Package $i successfully installed!" - # Add this package to the total list of packages that were actually installed by the script - INSTALLED_PACKAGES+=("${i}") - else - echo "::: Failed to install $i!" - ((FAILED++)) - fi - done - - if [ "$FAILED" -gt 0 ]; then - exit 1 + ${PKG_INSTALL} "${argArray1[@]}" fi } @@ -523,9 +507,6 @@ local chooseInterfaceOptions # Loop sentinel variable local firstloop=1 -# Find network interfaces whose state is UP, so as to skip virtual interfaces and the loopback interface -availableInterfaces=$(ip -o link | awk '/state UP/ {print $2}' | cut -d':' -f1 | cut -d'@' -f1) - if [ -z "$availableInterfaces" ]; then echo "::: Could not find any active network interface, exiting" exit 1 @@ -599,7 +580,7 @@ validIP(){ if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then OIFS=$IFS IFS='.' - read -r -a ip <<< "$ip" + read -r -a ip <<< "$ip" IFS=$OIFS [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] @@ -608,56 +589,39 @@ validIP(){ return $stat } -validIPAndNetmask(){ - local ip=$1 - local stat=1 - ip="${ip/\//.}" - - if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,2}$ ]]; then - OIFS=$IFS - IFS='.' - read -r -a ip <<< "$ip" - IFS=$OIFS - [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ - && ${ip[2]} -le 255 && ${ip[3]} -le 255 \ - && ${ip[4]} -le 32 ]] - stat=$? - fi - return $stat -} - getStaticIPv4Settings() { - # Find the gateway IP used to route to outside world - CurrentIPv4gw="$(ip -o route get 192.0.2.1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk 'NR==2')" - - # Find the IP address (and netmask) of the desidered interface - CurrentIPv4addr="$(ip -o -f inet address show dev "${IPv4dev}" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,2}')" - - # Grab their current DNS servers - IPv4dns=$(grep -v "^#" /etc/resolv.conf | grep -w nameserver | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | xargs) + # Grab their current DNS Server + IPv4dns=$(grep nameserver /etc/resolv.conf | awk '{print $2}' | xargs) if [ "${runUnattended}" = 'true' ]; then if [ -z "$dhcpReserv" ] || [ "$dhcpReserv" -ne 1 ]; then - local MISSING_STATIC_IPV4_SETTINGS=0 + local INVALID_STATIC_IPV4_SETTINGS=0 if [ -z "$IPv4addr" ]; then echo "::: Missing static IP address" - ((MISSING_STATIC_IPV4_SETTINGS++)) + INVALID_STATIC_IPV4_SETTINGS=1 fi if [ -z "$IPv4gw" ]; then echo "::: Missing static IP gateway" - ((MISSING_STATIC_IPV4_SETTINGS++)) + INVALID_STATIC_IPV4_SETTINGS=1 fi - if [ "$MISSING_STATIC_IPV4_SETTINGS" -eq 0 ]; then + if [ "$INVALID_STATIC_IPV4_SETTINGS" -eq 1 ]; then + echo "::: Incomplete static IP settings" + exit 1 + fi - # If both settings are not empty, check if they are valid and proceed - if validIPAndNetmask "${IPv4addr}"; then + if [ -z "$IPv4addr" ] && [ -z "$IPv4gw" ]; then + echo "::: No static IP settings, using current settings" + echo "::: Your static IPv4 address: ${IPv4addr}" + echo "::: Your static IPv4 gateway: ${IPv4gw}" + else + if validIP "${IPv4addr%/*}"; then echo "::: Your static IPv4 address: ${IPv4addr}" else - echo "::: ${IPv4addr} is not a valid IP address" + echo "::: ${IPv4addr%/*} is not a valid IP address" exit 1 fi @@ -667,45 +631,26 @@ getStaticIPv4Settings() { echo "::: ${IPv4gw} is not a valid IP address" exit 1 fi - - elif [ "$MISSING_STATIC_IPV4_SETTINGS" -eq 1 ]; then - - # If either of the settings is missing, consider the input inconsistent - echo "::: Incomplete static IP settings" - exit 1 - - elif [ "$MISSING_STATIC_IPV4_SETTINGS" -eq 2 ]; then - - # If both of the settings are missing, assume the user wants to use current settings - IPv4addr="${CurrentIPv4addr}" - IPv4gw="${CurrentIPv4gw}" - echo "::: No static IP settings, using current settings" - echo "::: Your static IPv4 address: ${IPv4addr}" - echo "::: Your static IPv4 gateway: ${IPv4gw}" - fi else echo "::: Skipping setting static IP address" fi echo "dhcpReserv=${dhcpReserv}" >> /tmp/setupVars.conf - echo "IPv4addr=${IPv4addr}" >> /tmp/setupVars.conf + echo "IPv4addr=${IPv4addr%/*}" >> /tmp/setupVars.conf echo "IPv4gw=${IPv4gw}" >> /tmp/setupVars.conf return fi local ipSettingsCorrect - local IPv4AddrValid - local IPv4gwValid # Some users reserve IP addresses on another DHCP Server or on their routers, # Lets ask them if they want to make any changes to their interfaces. - - if (whiptail --backtitle "Calibrating network interface" --title "DHCP Reservation" --yesno --defaultno \ + if (whiptail --backtitle "Calibrating network interface" --title "DHCP Reservation" --yesno \ "Are you Using DHCP Reservation on your Router/DHCP Server? These are your current Network Settings: - IP address: ${CurrentIPv4addr} - Gateway: ${CurrentIPv4gw} + IP address: ${IPv4addr} + Gateway: ${IPv4gw} Yes: Keep using DHCP reservation No: Setup static IP address @@ -713,82 +658,56 @@ Don't know what DHCP Reservation is? Answer No." ${r} ${c}); then dhcpReserv=1 # shellcheck disable=SC2129 echo "dhcpReserv=${dhcpReserv}" >> /tmp/setupVars.conf - # We don't really need to save them as we won't set a static IP but they might be useful for debugging - echo "IPv4addr=${CurrentIPv4addr}" >> /tmp/setupVars.conf - echo "IPv4gw=${CurrentIPv4gw}" >> /tmp/setupVars.conf + echo "IPv4addr=${IPv4addr%/*}" >> /tmp/setupVars.conf + echo "IPv4gw=${IPv4gw}" >> /tmp/setupVars.conf else # Ask if the user wants to use DHCP settings as their static IP if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address? + IP address: ${IPv4addr} + Gateway: ${IPv4gw}" ${r} ${c}); then - IP address: ${CurrentIPv4addr} - Gateway: ${CurrentIPv4gw}" ${r} ${c}); then - IPv4addr=${CurrentIPv4addr} - IPv4gw=${CurrentIPv4gw} - echo "IPv4addr=${IPv4addr}" >> /tmp/setupVars.conf - echo "IPv4gw=${IPv4gw}" >> /tmp/setupVars.conf - - # If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict. - whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that. + echo "IPv4addr=${IPv4addr%/*}" >> /tmp/setupVars.conf + echo "IPv4gw=${IPv4gw}" >> /tmp/setupVars.conf + # If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict. + whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that. If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want. It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." ${r} ${c} - # Nothing else to do since the variables are already set above + # Nothing else to do since the variables are already set above else - # Otherwise, we need to ask the user to input their desired settings. - # Start by getting the IPv4 address (pre-filling it with info gathered from DHCP) - # Start a loop to let the user enter their information with the chance to go back and edit it if necessary + # Otherwise, we need to ask the user to input their desired settings. + # Start by getting the IPv4 address (pre-filling it with info gathered from DHCP) + # Start a loop to let the user enter their information with the chance to go back and edit it if necessary until [[ ${ipSettingsCorrect} = True ]]; do - - until [[ ${IPv4AddrValid} = True ]]; do - # Ask for the IPv4 address - if IPv4addr=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${CurrentIPv4addr}" 3>&1 1>&2 2>&3) ; then - if validIPAndNetmask "${IPv4addr}"; then - echo "::: Your static IPv4 address: ${IPv4addr}" - IPv4AddrValid=True - else - whiptail --msgbox --backtitle "Calibrating network interface" --title "IPv4 address" "You've entered an invalid IP address: ${IPv4addr}\\n\\nPlease enter an IP address in the CIDR notation, example: 192.168.23.211/24\\n\\nIf you are not sure, please just keep the default." ${r} ${c} - echo "::: Invalid IPv4 address: ${IPv4addr}" - IPv4AddrValid=False - fi - else - # Cancelling IPv4 settings window - echo "::: Cancel selected. Exiting..." - exit 1 - fi - done - - until [[ ${IPv4gwValid} = True ]]; do + # Ask for the IPv4 address + if IPv4addr=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPv4addr}" 3>&1 1>&2 2>&3) ; then + echo "::: Your static IPv4 address: ${IPv4addr}" # Ask for the gateway - if IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${CurrentIPv4gw}" 3>&1 1>&2 2>&3) ; then - if validIP "${IPv4gw}"; then - echo "::: Your static IPv4 gateway: ${IPv4gw}" - IPv4gwValid=True + if IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${IPv4gw}" 3>&1 1>&2 2>&3) ; then + echo "::: Your static IPv4 gateway: ${IPv4gw}" + # Give the user a chance to review their settings before moving on + if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct? + IP address: ${IPv4addr} + Gateway: ${IPv4gw}" ${r} ${c}); then + # If the settings are correct, then we need to set the pivpnIP + echo "IPv4addr=${IPv4addr%/*}" >> /tmp/setupVars.conf + echo "IPv4gw=${IPv4gw}" >> /tmp/setupVars.conf + # After that's done, the loop ends and we move on + ipSettingsCorrect=True else - whiptail --msgbox --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" "You've entered an invalid gateway IP: ${IPv4gw}\\n\\nPlease enter the IP address of your gateway (router), example: 192.168.23.1\\n\\nIf you are not sure, please just keep the default." ${r} ${c} - echo "::: Invalid IPv4 gateway: ${IPv4gw}" - IPv4gwValid=False + # If the settings are wrong, the loop continues + ipSettingsCorrect=False fi else # Cancelling gateway settings window + ipSettingsCorrect=False echo "::: Cancel selected. Exiting..." exit 1 fi - done - - # Give the user a chance to review their settings before moving on - if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct? - - IP address: ${IPv4addr} - Gateway: ${IPv4gw}" ${r} ${c}); then - # If the settings are correct, then we need to set the pivpnIP - echo "IPv4addr=${IPv4addr}" >> /tmp/setupVars.conf - echo "IPv4gw=${IPv4gw}" >> /tmp/setupVars.conf - # After that's done, the loop ends and we move on - ipSettingsCorrect=True else - # If the settings are wrong, the loop continues + # Cancelling IPv4 settings window ipSettingsCorrect=False - IPv4AddrValid=False - IPv4gwValid=False + echo "::: Cancel selected. Exiting..." + exit 1 fi done # End the if statement for DHCP vs. static @@ -1045,29 +964,18 @@ askWhichVPN(){ installOpenVPN(){ local PIVPN_DEPS - echo "::: Installing OpenVPN from Debian package... " - if [ "$PLAT" = "Debian" ] || [ "$PLAT" = "Ubuntu" ]; then + echo "::: Adding OpenVPN repository... " # gnupg is used to add the openvpn PGP key to the APT keyring PIVPN_DEPS=(gnupg) installDependentPackages PIVPN_DEPS[@] - - # We will download the repository key regardless of whether the user - # has already enabled the openvpn repository or not, just to make sure - # we have the right key - echo "::: Adding repository key..." wget -qO- https://swupdate.openvpn.net/repos/repo-public.gpg | $SUDO apt-key add - - - if ! grep -qR "deb http.\?://build.openvpn.net/debian/openvpn/stable.\? $OSCN main" /etc/apt/sources.list*; then - echo "::: Adding OpenVPN repository... " - echo "deb https://build.openvpn.net/debian/openvpn/stable $OSCN main" | $SUDO tee /etc/apt/sources.list.d/pivpn-openvpn-repo.list > /dev/null - fi - - echo "::: Updating package cache..." + echo "deb https://build.openvpn.net/debian/openvpn/stable $OSCN main" | $SUDO tee /etc/apt/sources.list.d/pivpn-openvpn-repo.list > /dev/null # shellcheck disable=SC2086 - $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! + $SUDO ${UPDATE_PKG_CACHE} &> /dev/null fi + echo "::: Installing OpenVPN from Debian package... " # grepcidr is used to redact IPs in the debug log whereas expect is used # to feed easy-rsa with passwords PIVPN_DEPS=(openvpn grepcidr expect) @@ -1075,8 +983,6 @@ installOpenVPN(){ } installWireGuard(){ - local PIVPN_DEPS - if [ "$PLAT" = "Raspbian" ]; then # If the running kernel is older than the kernel from the repo, dkms will @@ -1130,28 +1036,19 @@ installWireGuard(){ if [ "$(uname -m)" = "armv7l" ]; then echo "::: Installing WireGuard from Debian package... " - # dirmngr is used to download repository keys for the unstable repo - PIVPN_DEPS=(dirmngr) + # dirmngr is used to download repository keys, whereas qrencode is used to generate qrcodes + # from config file, for use with mobile clients + PIVPN_DEPS=(dirmngr qrencode) installDependentPackages PIVPN_DEPS[@] - - echo "::: Adding repository keys..." - $SUDO apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC 648ACFD622F3D138 - - # This regular expression should match combinations like http[s]://mirror.example.com/debian[/] unstable main - if ! grep -qR 'deb http.\?://.*/debian.\? unstable main' /etc/apt/sources.list*; then - echo "::: Adding Debian repository... " - echo "deb https://deb.debian.org/debian/ unstable main" | $SUDO tee /etc/apt/sources.list.d/pivpn-unstable.list > /dev/null - fi - # Do not upgrade packages from the unstable repository except for wireguard + echo "::: Adding Debian repository... " + echo "deb https://deb.debian.org/debian/ unstable main" | $SUDO tee /etc/apt/sources.list.d/pivpn-unstable.list > /dev/null printf 'Package: *\nPin: release a=unstable\nPin-Priority: 1\n\nPackage: wireguard wireguard-dkms wireguard-tools\nPin: release a=unstable\nPin-Priority: 500\n' | $SUDO tee /etc/apt/preferences.d/pivpn-limit-unstable > /dev/null - echo "::: Updating package cache..." - # shellcheck disable=SC2086 - $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! - - # qrencode is used to generate qrcodes from config file, for use with mobile clients - PIVPN_DEPS=(raspberrypi-kernel-headers wireguard wireguard-tools wireguard-dkms qrencode) + $SUDO apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC 648ACFD622F3D138 + # shellcheck disable=SC2086 + $SUDO ${UPDATE_PKG_CACHE} &> /dev/null + PIVPN_DEPS=(raspberrypi-kernel-headers wireguard wireguard-tools wireguard-dkms) installDependentPackages PIVPN_DEPS[@] elif [ "$(uname -m)" = "armv6l" ]; then @@ -1167,7 +1064,7 @@ installWireGuard(){ WG_TOOLS_SOURCE="https://git.zx2c4.com/wireguard-tools/snapshot/wireguard-tools-${WG_TOOLS_SNAPSHOT}.tar.xz" echo "::: Downloading wireguard-tools source code... " - wget -qO- "${WG_TOOLS_SOURCE}" | $SUDO tar xJ --directory /usr/src + wget -qO- "${WG_TOOLS_SOURCE}" | $SUDO tar Jxf - --directory /usr/src echo "done!" ## || exits if cd fails. @@ -1188,7 +1085,7 @@ installWireGuard(){ # files from the file system echo "::: Installing WireGuard tools... " if $SUDO checkinstall --pkgname wireguard-tools --pkgversion "${WG_TOOLS_SNAPSHOT}" -y; then - INSTALLED_PACKAGES+=("wireguard-tools") + TO_INSTALL+=("wireguard-tools") echo "done!" else echo "failed!" @@ -1201,16 +1098,16 @@ installWireGuard(){ WG_MODULE_SOURCE="https://git.zx2c4.com/wireguard-linux-compat/snapshot/wireguard-linux-compat-${WG_MODULE_SNAPSHOT}.tar.xz" echo "::: Downloading wireguard-linux-compat source code... " - wget -qO- "${WG_MODULE_SOURCE}" | $SUDO tar xJ --directory /usr/src + wget -qO- "${WG_MODULE_SOURCE}" | $SUDO tar Jxf - --directory /usr/src echo "done!" # Rename wireguard-linux-compat folder and move the source code to the parent folder # such that dkms picks up the module when referencing wireguard/"${WG_MODULE_SNAPSHOT}" cd /usr/src && \ - $SUDO mv wireguard-linux-compat-"${WG_MODULE_SNAPSHOT}" wireguard-"${WG_MODULE_SNAPSHOT}" && \ + $SUDO mv wireguard-linux-compat-"${WG_MODULE_SNAPSHOT}" wireguard-"${WG_MODULE_SNAPSHOT}" cd wireguard-"${WG_MODULE_SNAPSHOT}" && \ $SUDO mv src/* . && \ - $SUDO rmdir src || exit 1 + $SUDO rmdir src echo "::: Adding WireGuard modules via DKMS... " if $SUDO dkms add wireguard/"${WG_MODULE_SNAPSHOT}"; then @@ -1232,7 +1129,7 @@ installWireGuard(){ echo "::: Installing WireGuard modules via DKMS... " if $SUDO dkms install wireguard/"${WG_MODULE_SNAPSHOT}"; then - INSTALLED_PACKAGES+=("wireguard-dkms") + TO_INSTALL+=("wireguard-dkms") echo "done!" else echo "failed!" @@ -1247,17 +1144,11 @@ installWireGuard(){ elif [ "$PLAT" = "Debian" ]; then echo "::: Installing WireGuard from Debian package... " - if ! grep -qR 'deb http.\?://.*/debian.\? unstable main' /etc/apt/sources.list*; then - echo "::: Adding Debian repository... " - echo "deb https://deb.debian.org/debian/ unstable main" | $SUDO tee /etc/apt/sources.list.d/pivpn-unstable.list > /dev/null - fi - + echo "::: Adding Debian repository... " + echo "deb https://deb.debian.org/debian/ unstable main" | $SUDO tee /etc/apt/sources.list.d/pivpn-unstable.list > /dev/null printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' | $SUDO tee /etc/apt/preferences.d/pivpn-limit-unstable > /dev/null - - echo "::: Updating package cache..." - # shellcheck disable=SC2086 - $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! - + # shellcheck disable=SC2086 + $SUDO ${UPDATE_PKG_CACHE} &> /dev/null PIVPN_DEPS=(linux-headers-amd64 qrencode wireguard wireguard-tools wireguard-dkms) installDependentPackages PIVPN_DEPS[@] @@ -1265,11 +1156,7 @@ installWireGuard(){ echo "::: Installing WireGuard from PPA... " $SUDO add-apt-repository ppa:wireguard/wireguard -y - - echo "::: Updating package cache..." - # shellcheck disable=SC2086 - $SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! - + $SUDO ${UPDATE_PKG_CACHE} PIVPN_DEPS=(qrencode wireguard wireguard-tools wireguard-dkms linux-headers-generic) installDependentPackages PIVPN_DEPS[@] @@ -1415,10 +1302,11 @@ askClientDNS(){ fi # Detect and offer to use Pi-hole - if command -v pihole > /dev/null; then + if command -v pihole &>/dev/null; then if (whiptail --backtitle "Setup PiVPN" --title "Pi-hole" --yesno "We have detected a Pi-hole installation, do you want to use it as the DNS server for the VPN, so you get ad blocking on the go?" ${r} ${c}); then pivpnDNS1="$vpnGw" echo "interface=$pivpnDEV" | $SUDO tee /etc/dnsmasq.d/02-pivpn.conf > /dev/null + $SUDO pihole restartdns echo "pivpnDNS1=${pivpnDNS1}" >> /tmp/setupVars.conf echo "pivpnDNS2=${pivpnDNS2}" >> /tmp/setupVars.conf return @@ -1592,46 +1480,36 @@ askPublicIPOrDNS(){ return fi - local publicDNSCorrect - local publicDNSValid - - if METH=$(whiptail --title "Public IP or DNS" --radiolist "Will clients use a Public IP or DNS Name to connect to your server (press space to select)?" ${r} ${c} 2 \ + METH=$(whiptail --title "Public IP or DNS" --radiolist "Will clients use a Public IP or DNS Name to connect to your server (press space to select)?" ${r} ${c} 2 \ "$IPv4pub" "Use this public IP" "ON" \ - "DNS Entry" "Use a public DNS" "OFF" 3>&1 1>&2 2>&3); then + "DNS Entry" "Use a public DNS" "OFF" 3>&1 1>&2 2>&3) - if [ "$METH" = "$IPv4pub" ]; then - pivpnHOST="${IPv4pub}" - else - until [[ ${publicDNSCorrect} = True ]]; do - - until [[ ${publicDNSValid} = True ]]; do - if PUBLICDNS=$(whiptail --title "PiVPN Setup" --inputbox "What is the public DNS name of this Server?" ${r} ${c} 3>&1 1>&2 2>&3); then - if validDomain "$PUBLICDNS"; then - publicDNSValid=True - pivpnHOST="${PUBLICDNS}" - else - whiptail --msgbox --backtitle "PiVPN Setup" --title "Invalid DNS name" "This DNS name is invalid. Please try again.\\n\\n DNS name: $PUBLICDNS\\n" ${r} ${c} - publicDNSValid=False - fi - else - echo "::: Cancel selected. Exiting..." - exit 1 - fi - done - - if (whiptail --backtitle "PiVPN Setup" --title "Confirm DNS Name" --yesno "Is this correct?\\n\\n Public DNS Name: $PUBLICDNS" ${r} ${c}) then - publicDNSCorrect=True - else - publicDNSCorrect=False - publicDNSValid=False - fi - done - fi - else + exitstatus=$? + if [ $exitstatus != 0 ]; then echo "::: Cancel selected. Exiting..." exit 1 fi + if [ "$METH" == "$IPv4pub" ]; then + pivpnHOST="${IPv4pub}" + else + until [[ $publicDNSCorrect = True ]] + do + PUBLICDNS=$(whiptail --title "PiVPN Setup" --inputbox "What is the public DNS name of this Server?" ${r} ${c} 3>&1 1>&2 2>&3) + exitstatus=$? + if [ $exitstatus != 0 ]; then + echo "::: Cancel selected. Exiting..." + exit 1 + fi + if (whiptail --backtitle "Confirm DNS Name" --title "Confirm DNS Name" --yesno "Is this correct?\\n\\n Public DNS Name: $PUBLICDNS" ${r} ${c}) then + publicDNSCorrect=True + pivpnHOST="${PUBLICDNS}" + else + publicDNSCorrect=False + fi + done + fi + echo "pivpnHOST=${pivpnHOST}" >> /tmp/setupVars.conf } @@ -1669,21 +1547,17 @@ askEncryption(){ fi fi - if [ -z "$USE_PREDEFINED_DH_PARAM" ]; then - USE_PREDEFINED_DH_PARAM=1 - echo "::: Pre-defined DH parameters will be used" + if [ -z "$DOWNLOAD_DH_PARAM" ] || [ "$DOWNLOAD_DH_PARAM" -ne 1 ]; then + DOWNLOAD_DH_PARAM=0 + echo "::: DH parameters will be generated locally" else - if [ "$USE_PREDEFINED_DH_PARAM" -eq 1 ]; then - echo "::: Pre-defined DH parameters will be used" - else - echo "::: DH parameters will be generated locally" - fi + echo "::: DH parameters will be downloaded from \"2 Ton Digital\"" fi fi echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}" >> /tmp/setupVars.conf echo "pivpnENCRYPT=${pivpnENCRYPT}" >> /tmp/setupVars.conf - echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}" >> /tmp/setupVars.conf + echo "DOWNLOAD_DH_PARAM=${DOWNLOAD_DH_PARAM}" >> /tmp/setupVars.conf return fi @@ -1709,15 +1583,15 @@ askEncryption(){ exit 1 fi - if ([ "$pivpnENCRYPT" -ge 2048 ] && whiptail --backtitle "Setup OpenVPN" --title "Generate Diffie-Hellman Parameters" --yesno "Generating DH parameters can take many hours on a Raspberry Pi. You can instead use Pre-defined DH parameters recommended by the Internet Engineering Task Force.\\n\\nMore information about those can be found here: https://wiki.mozilla.org/Security/Archive/Server_Side_TLS_4.0#Pre-defined_DHE_groups\\n\\nIf you want unique parameters, choose 'No' and new Diffie-Hellman parameters will be generated on your device." ${r} ${c}); then - USE_PREDEFINED_DH_PARAM=1 + if ([ "$pivpnENCRYPT" -ge 3072 ] && whiptail --backtitle "Setup OpenVPN" --title "Download Diffie-Hellman Parameters" --yesno --defaultno "Download Diffie-Hellman parameters from a public DH parameter generation service?\\n\\nGenerating DH parameters for a $pivpnENCRYPT-bit key can take many hours on a Raspberry Pi. You can instead download DH parameters from \"2 Ton Digital\" that are generated at regular intervals as part of a public service. Downloaded DH parameters will be randomly selected from their database.\\nMore information about this service can be found here: https://2ton.com.au/safeprimes/\\n\\nIf you're paranoid, choose 'No' and Diffie-Hellman parameters will be generated on your device." ${r} ${c}); then + DOWNLOAD_DH_PARAM=1 else - USE_PREDEFINED_DH_PARAM=0 + DOWNLOAD_DH_PARAM=0 fi echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}" >> /tmp/setupVars.conf echo "pivpnENCRYPT=${pivpnENCRYPT}" >> /tmp/setupVars.conf - echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}" >> /tmp/setupVars.conf + echo "DOWNLOAD_DH_PARAM=${DOWNLOAD_DH_PARAM}" >> /tmp/setupVars.conf } confOpenVPN(){ @@ -1743,7 +1617,7 @@ confOpenVPN(){ fi # Get easy-rsa - wget -qO- "${easyrsaRel}" | $SUDO tar xz --directory /etc/openvpn + wget -qO- "${easyrsaRel}" | $SUDO tar xz -C /etc/openvpn $SUDO mv /etc/openvpn/EasyRSA-v${easyrsaVer} /etc/openvpn/easy-rsa # fix ownership $SUDO chown -R root:root /etc/openvpn/easy-rsa @@ -1786,13 +1660,13 @@ set_var EASYRSA_ALGO ${pivpnCERT}" | $SUDO tee vars >/dev/null ${SUDOE} ./easyrsa --batch build-ca nopass printf "\\n::: CA Complete.\\n" - if [ "$pivpnCERT" = "rsa" ] && [ "$USE_PREDEFINED_DH_PARAM" -ne 1 ]; then + if [ "$pivpnCERT" = "rsa" ]; then if [ "${runUnattended}" = 'true' ]; then echo "::: The server key, Diffie-Hellman parameters, and HMAC key will now be generated." else whiptail --msgbox --backtitle "Setup OpenVPN" --title "Server Information" "The server key, Diffie-Hellman parameters, and HMAC key will now be generated." ${r} ${c} fi - elif [ "$pivpnCERT" = "ec" ] || { [ "$pivpnCERT" = "rsa" ] && [ "$USE_PREDEFINED_DH_PARAM" -eq 1 ]; }; then + elif [ "$pivpnCERT" = "ec" ]; then if [ "${runUnattended}" = 'true' ]; then echo "::: The server key and HMAC key will now be generated." else @@ -1804,13 +1678,13 @@ set_var EASYRSA_ALGO ${pivpnCERT}" | $SUDO tee vars >/dev/null EASYRSA_CERT_EXPIRE=3650 ${SUDOE} ./easyrsa build-server-full "${SERVER_NAME}" nopass if [ "$pivpnCERT" = "rsa" ]; then - if [ "${USE_PREDEFINED_DH_PARAM}" -eq 1 ]; then - # Use Diffie-Hellman parameters from RFC 7919 (FFDHE) - ${SUDOE} install -m 644 "${pivpnFilesDir}"/files/etc/openvpn/easy-rsa/pki/ffdhe"${pivpnENCRYPT}".pem pki/dh"${pivpnENCRYPT}".pem + if [ ${DOWNLOAD_DH_PARAM} -eq 1 ]; then + # Downloading parameters + ${SUDOE} curl -s "https://2ton.com.au/getprimes/random/dhparam/${pivpnENCRYPT}" -o "/etc/openvpn/easy-rsa/pki/dh${pivpnENCRYPT}.pem" else # Generate Diffie-Hellman key exchange ${SUDOE} ./easyrsa gen-dh - ${SUDOE} mv pki/dh.pem pki/dh"${pivpnENCRYPT}".pem + ${SUDOE} mv "pki/dh.pem" "pki/dh${pivpnENCRYPT}.pem" fi fi @@ -1826,7 +1700,7 @@ set_var EASYRSA_ALGO ${pivpnCERT}" | $SUDO tee vars >/dev/null ${SUDOE} chown "$debianOvpnUserGroup" /etc/openvpn/crl.pem # Write config file for server using the template.txt file - $SUDO install -m 644 "$pivpnFilesDir"/files/etc/openvpn/server_config.txt /etc/openvpn/server.conf + $SUDO cp $pivpnFilesDir/server_config.txt /etc/openvpn/server.conf # Apply client DNS settings ${SUDOE} sed -i '0,/\(dhcp-option DNS \)/ s/\(dhcp-option DNS \).*/\1'${pivpnDNS1}'\"/' /etc/openvpn/server.conf @@ -1873,7 +1747,7 @@ set_var EASYRSA_ALGO ${pivpnCERT}" | $SUDO tee vars >/dev/null } confOVPN(){ - $SUDO install -m 644 "$pivpnFilesDir"/files/etc/openvpn/easy-rsa/pki/Default.txt /etc/openvpn/easy-rsa/pki/Default.txt + $SUDO cp $pivpnFilesDir/Default.txt /etc/openvpn/easy-rsa/pki/Default.txt $SUDO sed -i 's/IPv4pub/'"$pivpnHOST"'/' /etc/openvpn/easy-rsa/pki/Default.txt @@ -2077,10 +1951,6 @@ restartServices(){ fi ;; esac - - if [ -f /etc/dnsmasq.d/02-pivpn.conf ]; then - $SUDO pihole restartdns - fi } askUnattendedUpgrades(){ @@ -2112,7 +1982,7 @@ askUnattendedUpgrades(){ confUnattendedUpgrades(){ local PIVPN_DEPS - PIVPN_DEPS=(unattended-upgrades) + PIVPN_DEPS+=(unattended-upgrades) installDependentPackages PIVPN_DEPS[@] aptConfDir="/etc/apt/apt.conf.d" @@ -2129,13 +1999,10 @@ confUnattendedUpgrades(){ # Fix Raspbian config if [ "$PLAT" = "Raspbian" ]; then - wget -qO- "$UNATTUPG_CONFIG" | $SUDO tar xz --directory "${aptConfDir}" "unattended-upgrades-$UNATTUPG_RELEASE/data/50unattended-upgrades.Raspbian" --strip-components 2 - if test -s "${aptConfDir}/50unattended-upgrades.Raspbian"; then - $SUDO mv "${aptConfDir}/50unattended-upgrades.Raspbian" "${aptConfDir}/50unattended-upgrades" - else - echo "$0: ERR: Failed to download \"50unattended-upgrades.Raspbian\"." - exit 1 - fi + wget -q -O "/tmp/${UNATTUPG_RELEASE}.tar.gz" "$UNATTUPG_CONFIG" + cd /tmp/ && $SUDO tar xzf "/tmp/${UNATTUPG_RELEASE}.tar.gz" + $SUDO cp /tmp/"unattended-upgrades-$UNATTUPG_RELEASE/data/50unattended-upgrades.Raspbian" "${aptConfDir}/50unattended-upgrades" + $SUDO rm -rf "/tmp/unattended-upgrades-$UNATTUPG_RELEASE" fi # Add the remaining settings for all other distributions @@ -2166,11 +2033,14 @@ installScripts(){ $SUDO chmod 0755 /opt/pivpn fi - $SUDO install -m 755 "$pivpnFilesDir"/scripts/*.sh -t /opt/pivpn - $SUDO install -m 755 "$pivpnFilesDir"/scripts/"$VPN"/*.sh -t /opt/pivpn - $SUDO install -m 755 "$pivpnFilesDir"/scripts/"$VPN"/pivpn /usr/local/bin/pivpn - $SUDO install -m 644 "$pivpnFilesDir"/scripts/"$VPN"/bash-completion /etc/bash_completion.d/pivpn - # shellcheck disable=SC1091 + $SUDO cp "$pivpnFilesDir"/scripts/*.sh /opt/pivpn/ + $SUDO cp "$pivpnFilesDir"/scripts/"$VPN"/*.sh /opt/pivpn/ + $SUDO chmod 0755 /opt/pivpn/*.sh + $SUDO cp "$pivpnFilesDir"/scripts/"$VPN"/pivpn /usr/local/bin/pivpn + $SUDO chmod 0755 /usr/local/bin/pivpn + $SUDO cp "$pivpnFilesDir"/scripts/"$VPN"/bash-completion /etc/bash_completion.d/pivpn + $SUDO chmod 0644 /etc/bash_completion.d/pivpn + # shellcheck disable=SC1091 . /etc/bash_completion.d/pivpn echo " done." } diff --git a/files/etc/openvpn/easy-rsa/pki/ffdhe2048.pem b/files/etc/openvpn/easy-rsa/pki/ffdhe2048.pem deleted file mode 100644 index 9b182b7..0000000 --- a/files/etc/openvpn/easy-rsa/pki/ffdhe2048.pem +++ /dev/null @@ -1,8 +0,0 @@ ------BEGIN DH PARAMETERS----- -MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz -+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a -87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 -YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi -7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD -ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== ------END DH PARAMETERS----- diff --git a/files/etc/openvpn/easy-rsa/pki/ffdhe3072.pem b/files/etc/openvpn/easy-rsa/pki/ffdhe3072.pem deleted file mode 100644 index fb31ccd..0000000 --- a/files/etc/openvpn/easy-rsa/pki/ffdhe3072.pem +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN DH PARAMETERS----- -MIIBiAKCAYEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz -+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a -87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 -YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi -7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD -ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3 -7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32 -nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZsYu -N///////////AgEC ------END DH PARAMETERS----- diff --git a/files/etc/openvpn/easy-rsa/pki/ffdhe4096.pem b/files/etc/openvpn/easy-rsa/pki/ffdhe4096.pem deleted file mode 100644 index 3cf0fcb..0000000 --- a/files/etc/openvpn/easy-rsa/pki/ffdhe4096.pem +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN DH PARAMETERS----- -MIICCAKCAgEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz -+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a -87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 -YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi -7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD -ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3 -7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32 -nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZp4e -8W5vUsMWTfT7eTDp5OWIV7asfV9C1p9tGHdjzx1VA0AEh/VbpX4xzHpxNciG77Qx -iu1qHgEtnmgyqQdgCpGBMMRtx3j5ca0AOAkpmaMzy4t6Gh25PXFAADwqTs6p+Y0K -zAqCkc3OyX3Pjsm1Wn+IpGtNtahR9EGC4caKAH5eZV9q//////////8CAQI= ------END DH PARAMETERS----- diff --git a/scripts/backup.sh b/scripts/backup.sh index 56b46e5..a8e6a1d 100755 --- a/scripts/backup.sh +++ b/scripts/backup.sh @@ -1,16 +1,9 @@ #!/bin/bash - +# shellcheck disable=SC1091 +source /etc/pivpn/setupVars.conf +# shellcheck disable=SC1090 backupdir=pivpnbackup date=$(date +%Y%m%d-%H%M%S) -setupVars="/etc/pivpn/setupVars.conf" - -if [ ! -f "${setupVars}" ]; then - echo "::: Missing setup vars file!" - exit 1 -fi - -# shellcheck disable=SC1090 -source "${setupVars}" checkbackupdir(){ diff --git a/scripts/openvpn/makeOVPN.sh b/scripts/openvpn/makeOVPN.sh index 4e4bcc4..ec89435 100755 --- a/scripts/openvpn/makeOVPN.sh +++ b/scripts/openvpn/makeOVPN.sh @@ -91,7 +91,7 @@ do NO_PASS="1" ;; -b|--bitwarden) - if command -v bw > /dev/null; then + if command -v bw &> /dev/null; then BITWARDEN="2" else echo "Bitwarden not found, please install bitwarden" diff --git a/scripts/openvpn/pivpnDebug.sh b/scripts/openvpn/pivpnDebug.sh index d72fd8a..df4e938 100755 --- a/scripts/openvpn/pivpnDebug.sh +++ b/scripts/openvpn/pivpnDebug.sh @@ -2,6 +2,7 @@ # This scripts runs as root setupVars="/etc/pivpn/setupVars.conf" +ERR=0 if [ ! -f "${setupVars}" ]; then echo "::: Missing setup vars file!" @@ -16,6 +17,14 @@ 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 + echo "$filename -> $(cat "$filename")" + fi +done +printf "=============================================\n" +echo -e "::::\t\e[4msetupVars file shown below\e[0m\t ::::" sed "s/$pivpnHOST/REDACTED/" < /etc/pivpn/setupVars.conf printf "=============================================\n" echo -e ":::: \e[4mServer configuration shown below\e[0m ::::" @@ -28,7 +37,152 @@ echo -e ":::: \t\e[4mRecursive list of files in\e[0m\t ::::\n::: \e[4m/etc/openv ls -LR /etc/openvpn/easy-rsa/pki/ -Ireqs -Icerts_by_serial printf "=============================================\n" echo -e "::::\t\t\e[4mSelf check\e[0m\t\t ::::" -/opt/pivpn/self_check.sh + +if [ "$(cat /proc/sys/net/ipv4/ip_forward)" -eq 1 ]; then + echo ":: [OK] IP forwarding is enabled" +else + ERR=1 + read -r -p ":: [ERR] IP forwarding is not enabled, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + sed -i '/net.ipv4.ip_forward=1/s/^#//g' /etc/sysctl.conf + sysctl -p + echo "Done" + fi +fi + +if [ "$USING_UFW" -eq 0 ]; then + + if iptables -t nat -C POSTROUTING -s 10.8.0.0/24 -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" &> /dev/null; then + echo ":: [OK] Iptables MASQUERADE rule set" + else + ERR=1 + read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + iptables -t nat -I POSTROUTING -s 10.8.0.0/24 -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" + iptables-save > /etc/iptables/rules.v4 + echo "Done" + fi + fi + + if [ "$INPUT_CHAIN_EDITED" -eq 1 ]; then + + if iptables -C INPUT -i "$IPv4dev" -p "$pivpnPROTO" --dport "$pivpnPORT" -j ACCEPT -m comment --comment "${VPN}-input-rule" &> /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]$ ]] || [[ -z ${REPLY} ]]; then + iptables -I INPUT 1 -i "$IPv4dev" -p "$pivpnPROTO" --dport "$pivpnPORT" -j ACCEPT -m comment --comment "${VPN}-input-rule" + 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 -m comment --comment "${VPN}-forward-rule" &> /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]$ ]] || [[ -z ${REPLY} ]]; then + iptables -I FORWARD 1 -d 10.8.0.0/24 -i "$IPv4dev" -o tun0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "${VPN}-forward-rule" + iptables -I FORWARD 2 -s 10.8.0.0/24 -i tun0 -o "$IPv4dev" -j ACCEPT -m comment --comment "${VPN}-forward-rule" + iptables-save > /etc/iptables/rules.v4 + echo "Done" + fi + fi + fi + +else + + if LANG="en_US.UTF-8" ufw status | grep -qw 'active'; then + echo ":: [OK] Ufw is enabled" + else + ERR=1 + read -r -p ":: [ERR] Ufw is not enabled, try to enable now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + ufw enable + fi + fi + + if iptables -t nat -C POSTROUTING -s 10.8.0.0/24 -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" &> /dev/null; then + echo ":: [OK] Iptables MASQUERADE rule set" + else + ERR=1 + read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + sed "/delete these required/i *nat\n:POSTROUTING ACCEPT [0:0]\n-I POSTROUTING -s 10.8.0.0/24 -o $IPv4dev -j MASQUERADE -m comment --comment ${VPN}-nat-rule\nCOMMIT\n" -i /etc/ufw/before.rules + ufw reload + echo "Done" + fi + fi + + if iptables -C ufw-user-input -p "${pivpnPROTO}" --dport "${pivpnPORT}" -j ACCEPT &> /dev/null; then + echo ":: [OK] Ufw input rule set" + else + ERR=1 + read -r -p ":: [ERR] Ufw input rule is not set, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + ufw insert 1 allow "$pivpnPORT"/"$pivpnPROTO" + ufw reload + echo "Done" + 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" + else + ERR=1 + read -r -p ":: [ERR] Ufw forwarding rule is not set, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; 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 + +if systemctl is-active -q openvpn; then + echo ":: [OK] OpenVPN is running" +else + ERR=1 + read -r -p ":: [ERR] OpenVPN is not running, try to start now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + systemctl start openvpn + echo "Done" + fi +fi + +if systemctl is-enabled -q openvpn; then + echo ":: [OK] OpenVPN is enabled (it will automatically start on reboot)" +else + ERR=1 + read -r -p ":: [ERR] OpenVPN is not enabled, try to enable now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + systemctl enable openvpn + echo "Done" + fi +fi + +# grep -w (whole word) is used so port 11940 won't match when looking for 1194 +if netstat -uanpt | grep openvpn | grep -w "${pivpnPORT}" | grep -q "${pivpnPROTO}"; then + echo ":: [OK] OpenVPN is listening on port ${pivpnPORT}/${pivpnPROTO}" +else + ERR=1 + read -r -p ":: [ERR] OpenVPN is not listening, try to restart now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + systemctl restart openvpn + echo "Done" + fi +fi + +if [ "$ERR" -eq 1 ]; then + echo -e "[INFO] Run \e[1mpivpn -d\e[0m again to see if we detect issues" +fi + printf "=============================================\n" echo -e ":::: \e[4mSnippet of the server log\e[0m ::::" tail -20 /var/log/openvpn.log > /tmp/snippet diff --git a/scripts/self_check.sh b/scripts/self_check.sh deleted file mode 100755 index b6a2194..0000000 --- a/scripts/self_check.sh +++ /dev/null @@ -1,170 +0,0 @@ -#!/bin/bash - -subnetClass="24" -setupVars="/etc/pivpn/setupVars.conf" -ERR=0 - -if [ ! -f "${setupVars}" ]; then - echo "::: Missing setup vars file!" - exit 1 -fi - -source "${setupVars}" - -if [ "$VPN" = "wireguard" ]; then - pivpnPROTO="udp" - pivpnDEV="wg0" - pivpnNET="10.6.0.0" - VPN_SERVICE="wg-quick@wg0" - VPN_PRETTY_NAME="WireGuard" -elif [ "$VPN" = "openvpn" ]; then - pivpnDEV="tun0" - pivpnNET="10.8.0.0" - VPN_SERVICE="openvpn" - VPN_PRETTY_NAME="OpenVPN" -fi - -if [ "$( /dev/null; then - echo ":: [OK] Iptables MASQUERADE rule set" - else - ERR=1 - read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - iptables -t nat -I POSTROUTING -s "${pivpnNET}/${subnetClass}" -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" - iptables-save > /etc/iptables/rules.v4 - echo "Done" - fi - fi - - if [ "$INPUT_CHAIN_EDITED" -eq 1 ]; then - - if iptables -C INPUT -i "${IPv4dev}" -p "${pivpnPROTO}" --dport "${pivpnPORT}" -j ACCEPT -m comment --comment "${VPN}-input-rule" &> /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]$ ]] || [[ -z ${REPLY} ]]; then - iptables -I INPUT 1 -i "${IPv4dev}" -p "${pivpnPROTO}" --dport "${pivpnPORT}" -j ACCEPT -m comment --comment "${VPN}-input-rule" - iptables-save > /etc/iptables/rules.v4 - echo "Done" - fi - fi - fi - - if [ "$FORWARD_CHAIN_EDITED" -eq 1 ]; then - - if iptables -C FORWARD -s "${pivpnNET}/${subnetClass}" -i "${pivpnDEV}" -o "${IPv4dev}" -j ACCEPT -m comment --comment "${VPN}-forward-rule" &> /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]$ ]] || [[ -z ${REPLY} ]]; then - iptables -I FORWARD 1 -d "${pivpnNET}/${subnetClass}" -i "${IPv4dev}" -o "${pivpnDEV}" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "${VPN}-forward-rule" - iptables -I FORWARD 2 -s "${pivpnNET}/${subnetClass}" -i "${pivpnDEV}" -o "${IPv4dev}" -j ACCEPT -m comment --comment "${VPN}-forward-rule" - iptables-save > /etc/iptables/rules.v4 - echo "Done" - fi - fi - fi - -else - - if LANG="en_US.UTF-8" ufw status | grep -qw 'active'; then - echo ":: [OK] Ufw is enabled" - else - ERR=1 - read -r -p ":: [ERR] Ufw is not enabled, try to enable now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - ufw enable - fi - fi - - if iptables -t nat -C POSTROUTING -s "${pivpnNET}/${subnetClass}" -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" &> /dev/null; then - echo ":: [OK] Iptables MASQUERADE rule set" - else - ERR=1 - read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - sed "/delete these required/i *nat\n:POSTROUTING ACCEPT [0:0]\n-I POSTROUTING -s ${pivpnNET}/${subnetClass} -o ${IPv4dev} -j MASQUERADE -m comment --comment ${VPN}-nat-rule\nCOMMIT\n" -i /etc/ufw/before.rules - ufw reload - echo "Done" - fi - fi - - if iptables -C ufw-user-input -p "${pivpnPROTO}" --dport "${pivpnPORT}" -j ACCEPT &> /dev/null; then - echo ":: [OK] Ufw input rule set" - else - ERR=1 - read -r -p ":: [ERR] Ufw input rule is not set, attempt fix now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - ufw insert 1 allow "${pivpnPORT}"/"${pivpnPROTO}" - ufw reload - echo "Done" - fi - fi - - if iptables -C ufw-user-forward -i "${pivpnDEV}" -o "${IPv4dev}" -s "${pivpnNET}/${subnetClass}" -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]$ ]] || [[ -z ${REPLY} ]]; then - ufw route insert 1 allow in on "${pivpnDEV}" from "${pivpnNET}/${subnetClass}" out on "${IPv4dev}" to any - ufw reload - echo "Done" - fi - fi - -fi - -if systemctl is-active -q "${VPN_SERVICE}"; then - echo ":: [OK] ${VPN_PRETTY_NAME} is running" -else - ERR=1 - read -r -p ":: [ERR] ${VPN_PRETTY_NAME} is not running, try to start now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - systemctl start "${VPN_SERVICE}" - echo "Done" - fi -fi - -if systemctl is-enabled -q "${VPN_SERVICE}"; then - echo ":: [OK] ${VPN_PRETTY_NAME} is enabled (it will automatically start on reboot)" -else - ERR=1 - read -r -p ":: [ERR] ${VPN_PRETTY_NAME} is not enabled, try to enable now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - systemctl enable "${VPN_SERVICE}" - echo "Done" - fi -fi - -# grep -w (whole word) is used so port 11940 won't match when looking for 1194 -if netstat -antu | grep -wqE "${pivpnPROTO}.*${pivpnPORT}"; then - echo ":: [OK] ${VPN_PRETTY_NAME} is listening on port ${pivpnPORT}/${pivpnPROTO}" -else - ERR=1 - read -r -p ":: [ERR] ${VPN_PRETTY_NAME} is not listening, try to restart now? [Y/n] " REPLY - if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then - systemctl restart "${VPN_SERVICE}" - echo "Done" - fi -fi - -if [ "$ERR" -eq 1 ]; then - echo -e "[INFO] Run \e[1mpivpn -d\e[0m again to see if we detect issues" -fi diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index defba8f..4546044 100755 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -5,7 +5,6 @@ ### FIXME: use variables where appropriate, reduce magic numbers by 99.9%, at least. PKG_MANAGER="apt-get" -UPDATE_PKG_CACHE="${PKG_MANAGER} update" subnetClass="24" setupVars="/etc/pivpn/setupVars.conf" @@ -34,7 +33,7 @@ spinner(){ local pid=$1 local delay=0.50 local spinstr='/-\|' - while ps a | awk '{print $1}' | grep -q "$pid"; do + while ps a | awk '{print $1}' | grep "$pid"; do local temp=${spinstr#?} printf " [%c] " "$spinstr" local spinstr=$temp${spinstr%"$temp"} @@ -102,7 +101,7 @@ removeAll(){ # Purge dependencies echo "::: Purge dependencies..." - for i in "${INSTALLED_PACKAGES[@]}"; do + for i in "${TO_INSTALL[@]}"; do while true; do read -rp "::: Do you wish to remove $i from your system? [Y/n]: " yn case $yn in @@ -114,11 +113,11 @@ removeAll(){ if [ "$PLAT" = "Debian" ] || { [ "$PLAT" = "Raspbian" ] && [ "$(uname -m)" = "armv7l" ]; }; then rm -f /etc/apt/sources.list.d/pivpn-unstable.list rm -f /etc/apt/preferences.d/pivpn-limit-unstable + $PKG_MANAGER update &> /dev/null elif [ "$PLAT" = "Ubuntu" ]; then add-apt-repository ppa:wireguard/wireguard -r -y + $PKG_MANAGER update &> /dev/null fi - echo "::: Updating package cache..." - ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! elif [ "${i}" = "wireguard-dkms" ]; then @@ -136,6 +135,12 @@ removeAll(){ rm -rf /usr/src/wireguard-tools-"${WG_TOOLS_SNAPSHOT}" fi + elif [ "${i}" = "dirmngr" ]; then + + # If dirmngr was installed, then we had previously installed wireguard on armv7l Raspbian + # so we remove the repository keys + apt-key remove E1CF20DDFFE4B89E802658F1E0B11894F66AEC98 80D15823B7FD1561F9F7BCDDDC30D7C23CBBABEE &> /dev/null + elif [ "${i}" = "unattended-upgrades" ]; then ### REALLY??? @@ -147,8 +152,7 @@ removeAll(){ if [ "$PLAT" = "Debian" ] || [ "$PLAT" = "Ubuntu" ]; then rm -f /etc/apt/sources.list.d/pivpn-openvpn-repo.list - echo "::: Updating package cache..." - ${UPDATE_PKG_CACHE} &> /dev/null & spinner $! + $PKG_MANAGER update &> /dev/null fi deluser openvpn rm -f /etc/rsyslog.d/30-openvpn.conf diff --git a/scripts/update.sh b/scripts/update.sh index 609c273..c11d8eb 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -15,17 +15,6 @@ fi source "${setupVars}" -scriptusage(){ - echo "::: Updates PiVPN scripts" - echo ":::" - echo "::: Usage: pivpn <-up|update> [-t|--test]" - echo ":::" - echo "::: Commands:" - echo "::: [none] Updates from master branch" - echo "::: -t, test Updates from test branch" - echo "::: -h, help Show this usage dialog" -} - ###Functions ##Updates scripts updatepivpnscripts(){ @@ -79,6 +68,14 @@ cloneupdttest(){ git -C "$pivpnlocalpath" checkout master } +scriptusage(){ + echo -e "Updates pivpn scripts, + + Usage: + pivpn update | updates from master branch + pivpn update -t or --test | updates from test branch" +} + ## SCRIPT if [[ $# -eq 0 ]]; then @@ -86,15 +83,15 @@ if [[ $# -eq 0 ]]; then else while true; do case "$1" in - -t|test) + -t|--test|test) updatefromtest exit 0 ;; - -h|help) + -h|--help|help) scriptusage exit 0 ;; - *) + * ) updatepivpnscripts exit 0 ;; diff --git a/scripts/wireguard/bash-completion b/scripts/wireguard/bash-completion index 412072a..a971696 100644 --- a/scripts/wireguard/bash-completion +++ b/scripts/wireguard/bash-completion @@ -4,8 +4,8 @@ _pivpn() COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" - dashopts="-a -c -d -l -qr -r -h -u -up -wg -bk" - opts="add clients debug list qrcode remove help uninstall update wgupdate backup" + dashopts="-a -c -d -l -qr -r -h -u -up -bk" + opts="add clients debug list qrcode remove help uninstall update backup" if [ "${#COMP_WORDS[@]}" -eq 2 ] then if [[ ${cur} == -* ]] ; then diff --git a/scripts/wireguard/clientSTAT.sh b/scripts/wireguard/clientSTAT.sh index f75050f..d8c94cd 100755 --- a/scripts/wireguard/clientSTAT.sh +++ b/scripts/wireguard/clientSTAT.sh @@ -10,11 +10,7 @@ hr(){ numfmt --to=iec-i --suffix=B "$1" } -if DUMP="$(wg show wg0 dump)"; then - DUMP="$(tail -n +2 <<< "$DUMP")" -else - exit 1 -fi +DUMP="$(wg show wg0 dump | tail -n +2)" printf "\e[1m::: Connected Clients List :::\e[0m\n" @@ -32,7 +28,7 @@ while IFS= read -r LINE; do CLIENT_NAME="$(grep "$PUBLIC_KEY" clients.txt | awk '{ print $1 }')" if [ "$LAST_SEEN" -ne 0 ]; then - printf "%s \t %s \t %s \t %s \t %s \t %s\n" "$CLIENT_NAME" "$REMOTE_IP" "${VIRTUAL_IP/\/32/}" "$(hr "$BYTES_RECEIVED")" "$(hr "$BYTES_SENT")" "$(date -d @"$LAST_SEEN" '+%b %d %Y - %T')" + printf "%s \t %s \t %s \t %s \t %s \t %s\n" "$CLIENT_NAME" "$REMOTE_IP" "${VIRTUAL_IP/\/32/}" "$(hr "$BYTES_RECEIVED")" "$(hr "$BYTES_SENT")" "$(date -d @"$LAST_SEEN" '+%b %m %Y - %T')" else printf "%s \t %s \t %s \t %s \t %s \t %s\n" "$CLIENT_NAME" "$REMOTE_IP" "${VIRTUAL_IP/\/32/}" "$(hr "$BYTES_RECEIVED")" "$(hr "$BYTES_SENT")" "(not yet)" fi diff --git a/scripts/wireguard/makeCONF.sh b/scripts/wireguard/makeCONF.sh index 2a0b0d3..561aa69 100755 --- a/scripts/wireguard/makeCONF.sh +++ b/scripts/wireguard/makeCONF.sh @@ -2,13 +2,6 @@ setupVars="/etc/pivpn/setupVars.conf" -if [ ! -f "${setupVars}" ]; then - echo "::: Missing setup vars file!" - exit 1 -fi - -source "${setupVars}" - helpFunc(){ echo "::: Create a client conf profile" echo ":::" @@ -46,6 +39,13 @@ while test $# -gt 0; do shift done +if [ ! -f "${setupVars}" ]; then + echo "::: Missing setup vars file!" + exit 1 +fi + +source "${setupVars}" + # The home folder variable was sourced from the settings file. if [ ! -d "${install_home}/configs" ]; then mkdir "${install_home}/configs" diff --git a/scripts/wireguard/pivpn b/scripts/wireguard/pivpn index a08ca61..4400a3f 100755 --- a/scripts/wireguard/pivpn +++ b/scripts/wireguard/pivpn @@ -54,11 +54,6 @@ updateScripts(){ exit 0 } -updateWireGuard(){ - $SUDO /opt/pivpn/wgUPDATE.sh - exit 0 -} - backup(){ $SUDO /opt/pivpn/backup.sh } @@ -78,8 +73,7 @@ showHelp(){ echo "::: -h, help Show this help dialog" echo "::: -u, uninstall Uninstall pivpn from your system!" echo "::: -up, update Updates PiVPN Scripts" - echo "::: -wg, wgupdate Updates WireGuard" - echo "::: -bk, backup Backup VPN configs and user profiles" + echo "::: -bk, Backup Backup vpn configs and user profiles" exit 0 } @@ -98,7 +92,6 @@ case "$1" in "-h" | "help" ) showHelp;; "-u" | "uninstall" ) uninstallServer;; "-up" | "update" ) updateScripts "$@" ;; -"-wg" | "wgupdate" ) updateWireGuard ;; "-bk" | "backup" ) backup ;; * ) showHelp;; esac diff --git a/scripts/wireguard/pivpnDEBUG.sh b/scripts/wireguard/pivpnDEBUG.sh index 0aebdd6..f2fe45c 100755 --- a/scripts/wireguard/pivpnDEBUG.sh +++ b/scripts/wireguard/pivpnDEBUG.sh @@ -10,30 +10,32 @@ fi source "${setupVars}" +EXAMPLE="$(head -1 /etc/wireguard/configs/clients.txt | awk '{print $1}')" +ERR=0 + echo -e "::::\t\t\e[4mPiVPN debug\e[0m\t\t ::::" printf "=============================================\n" 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 ::::" -sed "s/$pivpnHOST/REDACTED/" < /etc/pivpn/setupVars.conf +sed "s/$pivpnHOST/REDACTED/" < /etc/pivpn/setupVars.conf printf "=============================================\n" echo -e ":::: \e[4mServer configuration shown below\e[0m ::::" cd /etc/wireguard/keys cp ../wg0.conf ../wg0.tmp # Replace every key in the server configuration with just its file name for k in *; do - sed "s#$(<"$k")#$k#" -i ../wg0.tmp + sed "s#$(cat "$k")#$k#" -i ../wg0.tmp done cat ../wg0.tmp rm ../wg0.tmp printf "=============================================\n" echo -e ":::: \e[4mClient configuration shown below\e[0m ::::" -EXAMPLE="$(head -1 /etc/wireguard/configs/clients.txt | awk '{print $1}')" if [ -n "$EXAMPLE" ]; then cp ../configs/"$EXAMPLE".conf ../configs/"$EXAMPLE".tmp for k in *; do - sed "s#$(<"$k")#$k#" -i ../configs/"$EXAMPLE".tmp + sed "s#$(cat "$k")#$k#" -i ../configs/"$EXAMPLE".tmp done sed "s/$pivpnHOST/REDACTED/" < ../configs/"$EXAMPLE".tmp rm ../configs/"$EXAMPLE".tmp @@ -46,7 +48,151 @@ echo -e ":::: \t\e[4mRecursive list of files in\e[0m\t ::::\n::::\e\t[4m/etc/wir ls -LR /etc/wireguard printf "=============================================\n" echo -e "::::\t\t\e[4mSelf check\e[0m\t\t ::::" -/opt/pivpn/self_check.sh + +if [ "$(cat /proc/sys/net/ipv4/ip_forward)" -eq 1 ]; then + echo ":: [OK] IP forwarding is enabled" +else + ERR=1 + read -r -p ":: [ERR] IP forwarding is not enabled, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + sed -i '/net.ipv4.ip_forward=1/s/^#//g' /etc/sysctl.conf + sysctl -p + echo "Done" + fi +fi + +if [ "$USING_UFW" -eq 0 ]; then + + if iptables -t nat -C POSTROUTING -s 10.6.0.0/24 -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" &> /dev/null; then + echo ":: [OK] Iptables MASQUERADE rule set" + else + ERR=1 + read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + iptables -t nat -I POSTROUTING -s 10.6.0.0/24 -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" + iptables-save > /etc/iptables/rules.v4 + echo "Done" + fi + fi + + if [ "$INPUT_CHAIN_EDITED" -eq 1 ]; then + + if iptables -C INPUT -i "$IPv4dev" -p udp --dport "$pivpnPORT" -j ACCEPT -m comment --comment "${VPN}-input-rule" &> /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]$ ]] || [[ -z ${REPLY} ]]; then + iptables -I INPUT 1 -i "$IPv4dev" -p udp --dport "$pivpnPORT" -j ACCEPT -m comment --comment "${VPN}-input-rule" + iptables-save > /etc/iptables/rules.v4 + echo "Done" + fi + fi + fi + + if [ "$FORWARD_CHAIN_EDITED" -eq 1 ]; then + + if iptables -C FORWARD -s 10.6.0.0/24 -i wg0 -o "$IPv4dev" -j ACCEPT -m comment --comment "${VPN}-forward-rule" &> /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]$ ]] || [[ -z ${REPLY} ]]; then + iptables -I FORWARD 1 -d 10.6.0.0/24 -i "$IPv4dev" -o wg0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "${VPN}-forward-rule" + iptables -I FORWARD 2 -s 10.6.0.0/24 -i wg0 -o "$IPv4dev" -j ACCEPT -m comment --comment "${VPN}-forward-rule" + iptables-save > /etc/iptables/rules.v4 + echo "Done" + fi + fi + fi + +else + + if LANG="en_US.UTF-8" ufw status | grep -qw 'active'; then + echo ":: [OK] Ufw is enabled" + else + ERR=1 + read -r -p ":: [ERR] Ufw is not enabled, try to enable now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + ufw enable + fi + fi + + if iptables -t nat -C POSTROUTING -s 10.6.0.0/24 -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" &> /dev/null; then + echo ":: [OK] Iptables MASQUERADE rule set" + else + ERR=1 + read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + sed "/delete these required/i *nat\n:POSTROUTING ACCEPT [0:0]\n-I POSTROUTING -s 10.6.0.0/24 -o $IPv4dev -j MASQUERADE -m comment --comment ${VPN}-nat-rule\nCOMMIT\n" -i /etc/ufw/before.rules + ufw reload + echo "Done" + fi + fi + + if iptables -C ufw-user-input -p udp --dport "${pivpnPORT}" -j ACCEPT &> /dev/null; then + echo ":: [OK] Ufw input rule set" + else + ERR=1 + read -r -p ":: [ERR] Ufw input rule is not set, attempt fix now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + ufw insert 1 allow "$pivpnPORT"/udp + ufw reload + echo "Done" + fi + fi + + if iptables -C ufw-user-forward -i wg0 -o "${IPv4dev}" -s 10.6.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]$ ]] || [[ -z ${REPLY} ]]; then + ufw route insert 1 allow in on wg0 from 10.6.0.0/24 out on "$IPv4dev" to any + ufw reload + echo "Done" + fi + fi + +fi + +if systemctl is-active -q wg-quick@wg0; then + echo ":: [OK] WireGuard is running" +else + ERR=1 + read -r -p ":: [ERR] WireGuard is not running, try to start now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + systemctl start wg-quick@wg0 + echo "Done" + fi +fi + +if systemctl is-enabled -q wg-quick@wg0; then + echo ":: [OK] WireGuard is enabled (it will automatically start on reboot)" +else + ERR=1 + read -r -p ":: [ERR] WireGuard is not enabled, try to enable now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + systemctl enable wg-quick@wg0 + echo "Done" + fi +fi + +# grep -w (whole word) is used so port 11940 won't match when looking for 1194 +if netstat -uanp | grep -w "${pivpnPORT}" | grep -q 'udp'; then + echo ":: [OK] WireGuard is listening on port ${pivpnPORT}/udp" +else + ERR=1 + read -r -p ":: [ERR] WireGuard is not listening, try to restart now? [Y/n] " REPLY + if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then + systemctl restart wg-quick@wg0 + echo "Done" + fi +fi + +if [ "$ERR" -eq 1 ]; then + echo -e "[INFO] Run \e[1mpivpn -d\e[0m again to see if we detect issues" +fi printf "=============================================\n" echo -e ":::: \e[1mWARNING\e[0m: This script should have automatically masked sensitive ::::" echo -e ":::: information, however, still make sure that \e[4mPrivateKey\e[0m, \e[4mPublicKey\e[0m ::::" diff --git a/scripts/wireguard/removeCONF.sh b/scripts/wireguard/removeCONF.sh index 36aa249..b00deb6 100755 --- a/scripts/wireguard/removeCONF.sh +++ b/scripts/wireguard/removeCONF.sh @@ -2,13 +2,6 @@ setupVars="/etc/pivpn/setupVars.conf" -if [ ! -f "${setupVars}" ]; then - echo "::: Missing setup vars file!" - exit 1 -fi - -source "${setupVars}" - helpFunc(){ echo "::: Remove a client conf profile" echo ":::" @@ -36,6 +29,13 @@ do shift done +if [ ! -f "${setupVars}" ]; then + echo "::: Missing setup vars file!" + exit 1 +fi + +source "${setupVars}" + cd /etc/wireguard if [ ! -s configs/clients.txt ]; then echo "::: There are no clients to remove" diff --git a/scripts/wireguard/wgUPDATE.sh b/scripts/wireguard/wgUPDATE.sh deleted file mode 100755 index 6a17993..0000000 --- a/scripts/wireguard/wgUPDATE.sh +++ /dev/null @@ -1,132 +0,0 @@ -#!/bin/bash - -setupVars="/etc/pivpn/setupVars.conf" - -if [ ! -f "${setupVars}" ]; then - echo "::: Missing setup vars file!" - exit 1 -fi - -source "${setupVars}" - -if [ "$(uname -m)" != "armv6l" ]; then - echo "On your system, WireGuard updates via the package manager" - exit 0 -fi - -CURRENT_WG_TOOLS_SNAPSHOT="${WG_TOOLS_SNAPSHOT}" -WG_TOOLS_SNAPSHOT="$(curl -s https://build.wireguard.com/distros.json | jq -r '."upstream-tools"."version"')" - -if dpkg --compare-versions "${WG_TOOLS_SNAPSHOT}" gt "${CURRENT_WG_TOOLS_SNAPSHOT}"; then - - read -r -p "A new wireguard-tools update is available (${WG_TOOLS_SNAPSHOT}), install? [Y/n]: " - - if [[ ${REPLY} =~ ^[Yy]$ ]]; then - echo "::: Upgrading wireguard-tools from ${CURRENT_WG_TOOLS_SNAPSHOT} to ${WG_TOOLS_SNAPSHOT}..." - - WG_TOOLS_SOURCE="https://git.zx2c4.com/wireguard-tools/snapshot/wireguard-tools-${WG_TOOLS_SNAPSHOT}.tar.xz" - echo "::: Downloading wireguard-tools source code... " - wget -qO- "${WG_TOOLS_SOURCE}" | tar xJ --directory /usr/src - echo "done!" - - ## || exits if cd fails. - cd /usr/src/wireguard-tools-"${WG_TOOLS_SNAPSHOT}/src" || exit 1 - - # We install the userspace tools manually since DKMS only compiles and - # installs the kernel module - echo "::: Compiling WireGuard tools... " - if make; then - echo "done!" - else - echo "failed!" - exit 1 - fi - - # Use checkinstall to install userspace tools so if the user wants to uninstall - # PiVPN we can just do apt remove wireguard-tools, instead of manually removing - # files from the file system - echo "::: Installing WireGuard tools... " - if checkinstall --pkgname wireguard-tools --pkgversion "${WG_TOOLS_SNAPSHOT}" -y; then - echo "done!" - else - echo "failed!" - exit 1 - fi - - echo "::: Removing old source code ..." - rm -rf /usr/src/wireguard-tools-"${CURRENT_WG_TOOLS_SNAPSHOT}" - - sed "s/WG_TOOLS_SNAPSHOT=${CURRENT_WG_TOOLS_SNAPSHOT}/WG_TOOLS_SNAPSHOT=${WG_TOOLS_SNAPSHOT}/" -i "${setupVars}" - - echo "::: Upgrade completed!" - fi -else - echo "::: You are running the lastest version of wireguard-tools (${CURRENT_WG_TOOLS_SNAPSHOT})" -fi - -CURRENT_WG_MODULE_SNAPSHOT="${WG_MODULE_SNAPSHOT}" -WG_MODULE_SNAPSHOT="$(curl -s https://build.wireguard.com/distros.json | jq -r '."upstream-linuxcompat"."version"')" - -if dpkg --compare-versions "${WG_MODULE_SNAPSHOT}" gt "${CURRENT_WG_MODULE_SNAPSHOT}"; then - - read -r -p "A new wireguard-dkms update is available (${WG_MODULE_SNAPSHOT}), install? [Y/n]: " - - if [[ ${REPLY} =~ ^[Yy]$ ]]; then - echo "::: Upgrading wireguard-dkms from ${CURRENT_WG_MODULE_SNAPSHOT} to ${WG_MODULE_SNAPSHOT}..." - - WG_MODULE_SOURCE="https://git.zx2c4.com/wireguard-linux-compat/snapshot/wireguard-linux-compat-${WG_MODULE_SNAPSHOT}.tar.xz" - echo "::: Downloading wireguard-linux-compat source code... " - wget -qO- "${WG_MODULE_SOURCE}" | tar xJ --directory /usr/src - echo "done!" - - # Rename wireguard-linux-compat folder and move the source code to the parent folder - # such that dkms picks up the module when referencing wireguard/"${WG_MODULE_SNAPSHOT}" - cd /usr/src && \ - mv wireguard-linux-compat-"${WG_MODULE_SNAPSHOT}" wireguard-"${WG_MODULE_SNAPSHOT}" && \ - cd wireguard-"${WG_MODULE_SNAPSHOT}" && \ - mv src/* . && \ - rmdir src || exit 1 - - echo "::: Adding WireGuard module via DKMS... " - if dkms add wireguard/"${WG_MODULE_SNAPSHOT}"; then - echo "done!" - else - echo "failed!" - dkms remove wireguard/"${WG_MODULE_SNAPSHOT}" --all - exit 1 - fi - - echo "::: Compiling WireGuard module via DKMS... " - if dkms build wireguard/"${WG_MODULE_SNAPSHOT}"; then - echo "done!" - else - echo "failed!" - dkms remove wireguard/"${WG_MODULE_SNAPSHOT}" --all - exit 1 - fi - - echo "::: Installing WireGuard module via DKMS... " - if dkms install wireguard/"${WG_MODULE_SNAPSHOT}"; then - echo "done!" - else - echo "failed!" - dkms remove wireguard/"${WG_MODULE_SNAPSHOT}" --all - exit 1 - fi - - echo "::: Removing old kernel module and source code..." - if dkms remove wireguard/"${CURRENT_WG_MODULE_SNAPSHOT}" --all; then - rm -rf /usr/src/wireguard-"${CURRENT_WG_MODULE_SNAPSHOT}" - echo "done!" - else - echo "failed!" - exit 1 - fi - - sed "s/WG_TOOLS_SNAPSHOT=${CURRENT_WG_MODULE_SNAPSHOT}/WG_TOOLS_SNAPSHOT=${WG_MODULE_SNAPSHOT}/" -i "${setupVars}" - - echo "::: Upgrade completed!" - fi -else - echo "::: You are running the lastest version of wireguard-dkms (${CURRENT_WG_MODULE_SNAPSHOT})" -fi diff --git a/files/etc/openvpn/server_config.txt b/server_config.txt similarity index 100% rename from files/etc/openvpn/server_config.txt rename to server_config.txt diff --git a/examples/unattended_openvpn_example.conf b/unattended_openvpn_example.conf similarity index 76% rename from examples/unattended_openvpn_example.conf rename to unattended_openvpn_example.conf index a20f917..f0094bc 100644 --- a/examples/unattended_openvpn_example.conf +++ b/unattended_openvpn_example.conf @@ -1,6 +1,4 @@ IPv4dev=eth0 -IPv4addr=192.168.23.211/24 -IPv4gw=192.168.23.1 dhcpReserv=0 install_user=pi VPN=openvpn @@ -12,5 +10,5 @@ pivpnHOST=pivpn.example.com pivpnENCRYPT=256 pivpnSEARCHDOMAIN=searchdomain.example.com TWO_POINT_FOUR=1 -USE_PREDEFINED_DH_PARAM=1 +DOWNLOAD_DH_PARAM=0 UNATTUPG=1 diff --git a/examples/unattended_wireguard_example.conf b/unattended_wireguard_example.conf similarity index 76% rename from examples/unattended_wireguard_example.conf rename to unattended_wireguard_example.conf index e417927..196d4d5 100644 --- a/examples/unattended_wireguard_example.conf +++ b/unattended_wireguard_example.conf @@ -1,6 +1,4 @@ IPv4dev=eth0 -IPv4addr=192.168.23.211/24 -IPv4gw=192.168.23.1 dhcpReserv=0 install_user=pi VPN=wireguard