From 3f616d9254acab1a153190c7fde821e95bfc46a9 Mon Sep 17 00:00:00 2001 From: Orazio Date: Fri, 7 Feb 2020 18:07:15 +0100 Subject: [PATCH 01/12] Implemented feature request from issue #942 (WireGuard) --- auto_install/install.sh | 7 +++++-- scripts/uninstall.sh | 5 +++-- scripts/wireguard/makeCONF.sh | 9 +++++++++ scripts/wireguard/removeCONF.sh | 12 +++++++++++- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index e5c76ca..3015a84 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -14,6 +14,7 @@ pivpnGitUrl="https://github.com/pivpn/pivpn.git" setupVars="/etc/pivpn/setupVars.conf" pivpnFilesDir="/etc/.pivpn" +dnsmasqConfig="/etc/dnsmasq.d/02-pivpn.conf" ### PKG Vars ### PKG_MANAGER="apt-get" @@ -1417,8 +1418,10 @@ askClientDNS(){ # Detect and offer to use Pi-hole 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 + echo "interface=$pivpnDEV" | $SUDO tee "$dnsmasqConfig" > /dev/null + echo "addn-hosts=/etc/pivpn/hosts.$VPN" | $SUDO tee -a "$dnsmasqConfig" > /dev/null + $SUDO bash -c "> /etc/pivpn/hosts.$VPN" pivpnDNS1="$vpnGw" - echo "interface=$pivpnDEV" | $SUDO tee /etc/dnsmasq.d/02-pivpn.conf > /dev/null echo "pivpnDNS1=${pivpnDNS1}" >> /tmp/setupVars.conf echo "pivpnDNS2=${pivpnDNS2}" >> /tmp/setupVars.conf return @@ -2078,7 +2081,7 @@ restartServices(){ ;; esac - if [ -f /etc/dnsmasq.d/02-pivpn.conf ]; then + if [ -f "$dnsmasqConfig" ]; then $SUDO pihole restartdns fi } diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index 4bd2460..657da63 100755 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -7,6 +7,7 @@ PKG_MANAGER="apt-get" UPDATE_PKG_CACHE="${PKG_MANAGER} update" subnetClass="24" +dnsmasqConfig="/etc/dnsmasq.d/02-pivpn.conf" setupVars="/etc/pivpn/setupVars.conf" if [ ! -f "${setupVars}" ]; then @@ -176,8 +177,8 @@ removeAll(){ # Removing pivpn files echo "::: Removing pivpn system files..." - if [ -f /etc/dnsmasq.d/02-pivpn.conf ]; then - rm -f /etc/dnsmasq.d/02-pivpn.conf + if [ -f "$dnsmasqConfig" ]; then + rm -f "$dnsmasqConfig" pihole restartdns fi diff --git a/scripts/wireguard/makeCONF.sh b/scripts/wireguard/makeCONF.sh index 2a0b0d3..f978fcb 100755 --- a/scripts/wireguard/makeCONF.sh +++ b/scripts/wireguard/makeCONF.sh @@ -113,6 +113,15 @@ AllowedIPs = 10.6.0.${COUNT}/32 # end ${CLIENT_NAME}" >> wg0.conf echo "::: Updated server config" +if [ -f /etc/pivpn/hosts.wireguard ]; then + echo "10.6.0.${COUNT} ${CLIENT_NAME}.pivpn" >> /etc/pivpn/hosts.wireguard + if killall -SIGHUP pihole-FTL; then + echo "::: Updated hosts file for Pi-hole" + else + echo "::: Failed to reload pihole-FTL configuration" + fi +fi + if systemctl restart wg-quick@wg0; then echo "::: WireGuard restarted" else diff --git a/scripts/wireguard/removeCONF.sh b/scripts/wireguard/removeCONF.sh index 36aa249..0085809 100755 --- a/scripts/wireguard/removeCONF.sh +++ b/scripts/wireguard/removeCONF.sh @@ -101,9 +101,19 @@ for CLIENT_NAME in "${CLIENTS_TO_REMOVE[@]}"; do fi done + ((DELETED_COUNT++)) echo "::: Successfully deleted ${CLIENT_NAME}" - ((DELETED_COUNT++)) + # If using Pi-hole, remove the client from the hosts file + if [ -f /etc/pivpn/hosts.wireguard ]; then + sed "\#10.6.0.${COUNT} ${CLIENT_NAME}.pivpn#d" -i /etc/pivpn/hosts.wireguard + if killall -SIGHUP pihole-FTL; then + echo "::: Updated hosts file for Pi-hole" + else + echo "::: Failed to reload pihole-FTL configuration" + fi + fi + fi fi From ead280e60f3613eccdd6bc7e99ef3e3167f6b7d1 Mon Sep 17 00:00:00 2001 From: Orazio Date: Sun, 9 Feb 2020 18:51:30 +0100 Subject: [PATCH 02/12] Set static IPs when using OpenVPN - Preparation for feature request from issue #942 --- auto_install/install.sh | 7 +++++++ files/etc/openvpn/server_config.txt | 1 + scripts/openvpn/makeOVPN.sh | 11 +++++++++++ scripts/openvpn/removeOVPN.sh | 1 + scripts/uninstall.sh | 1 + 5 files changed, 21 insertions(+) diff --git a/auto_install/install.sh b/auto_install/install.sh index 3015a84..48907e5 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -1740,6 +1740,13 @@ confOpenVPN(){ $SUDO rm /etc/openvpn/server.conf fi + if [ -d /etc/openvpn/ccd ]; then + $SUDO rm -rf /etc/openvpn/ccd + fi + + # Create folder to store client specific directives used to push static IPs + $SUDO mkdir /etc/openvpn/ccd + # If easy-rsa exists, remove it if [[ -d /etc/openvpn/easy-rsa/ ]]; then $SUDO rm -rf /etc/openvpn/easy-rsa/ diff --git a/files/etc/openvpn/server_config.txt b/files/etc/openvpn/server_config.txt index 5032a12..87aff92 100644 --- a/files/etc/openvpn/server_config.txt +++ b/files/etc/openvpn/server_config.txt @@ -17,6 +17,7 @@ push "block-outside-dns" # overriding but not wiping out the original default gateway. push "redirect-gateway def1" client-to-client +client-config-dir /etc/openvpn/ccd keepalive 15 120 remote-cert-tls client tls-version-min 1.2 diff --git a/scripts/openvpn/makeOVPN.sh b/scripts/openvpn/makeOVPN.sh index 4e4bcc4..d9cf974 100755 --- a/scripts/openvpn/makeOVPN.sh +++ b/scripts/openvpn/makeOVPN.sh @@ -405,6 +405,17 @@ else fi +# Find an unused number for the last octet of the client IP +for i in {2..254}; do + # find returns 0 if the folder is empty, so we create the 'ls -A [...]' + # exception to stop at the first static IP (10.8.0.2). Otherwise it would + # cycle to the end without finding and available octet. + if [ -z "$(ls -A /etc/openvpn/ccd)" ] || ! find /etc/openvpn/ccd -type f -exec grep -q "10.8.0.$i" {} +; then + COUNT="$i" + echo "ifconfig-push 10.8.0.$i 255.255.255.0" >> /etc/openvpn/ccd/"${NAME}" + break + fi +done # Copy the .ovpn profile to the home directory for convenient remote access cp "/etc/openvpn/easy-rsa/pki/$NAME$FILEEXT" "$install_home/ovpns/$NAME$FILEEXT" diff --git a/scripts/openvpn/removeOVPN.sh b/scripts/openvpn/removeOVPN.sh index f191eab..62a8f4e 100755 --- a/scripts/openvpn/removeOVPN.sh +++ b/scripts/openvpn/removeOVPN.sh @@ -119,6 +119,7 @@ for (( ii = 0; ii < ${#CERTS_TO_REVOKE[@]}; ii++)); do rm -rf "pki/reqs/${CERTS_TO_REVOKE[ii]}.req" rm -rf "pki/private/${CERTS_TO_REVOKE[ii]}.key" rm -rf "pki/issued/${CERTS_TO_REVOKE[ii]}.crt" + rm -rf /etc/openvpn/ccd/"${CERTS_TO_REVOKE[ii]}" rm -rf "${install_home}/ovpns/${CERTS_TO_REVOKE[ii]}.ovpn" rm -rf "/etc/openvpn/easy-rsa/pki/${CERTS_TO_REVOKE[ii]}.ovpn" diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index 657da63..2a7409c 100755 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -203,6 +203,7 @@ removeAll(){ rm -f /etc/openvpn/server.conf rm -f /etc/openvpn/crl.pem rm -rf /etc/openvpn/easy-rsa + rm -rf /etc/openvpn/ccd rm -rf "$install_home/ovpns" fi From 2c6ba652880ad2cfdb33c540fe02085399caf55e Mon Sep 17 00:00:00 2001 From: Orazio Date: Sun, 9 Feb 2020 18:55:30 +0100 Subject: [PATCH 03/12] Implemented feature request from issue #942 (OpenVPN) --- scripts/openvpn/makeOVPN.sh | 9 +++++++++ scripts/openvpn/removeOVPN.sh | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/scripts/openvpn/makeOVPN.sh b/scripts/openvpn/makeOVPN.sh index d9cf974..2071744 100755 --- a/scripts/openvpn/makeOVPN.sh +++ b/scripts/openvpn/makeOVPN.sh @@ -417,6 +417,15 @@ for i in {2..254}; do fi done +if [ -f /etc/pivpn/hosts.openvpn ]; then + echo "10.8.0.${COUNT} ${NAME}.pivpn" >> /etc/pivpn/hosts.openvpn + if killall -SIGHUP pihole-FTL; then + echo "::: Updated hosts file for Pi-hole" + else + echo "::: Failed to reload pihole-FTL configuration" + fi +fi + # Copy the .ovpn profile to the home directory for convenient remote access cp "/etc/openvpn/easy-rsa/pki/$NAME$FILEEXT" "$install_home/ovpns/$NAME$FILEEXT" chown "$install_user":"$install_user" "$install_home/ovpns/$NAME$FILEEXT" diff --git a/scripts/openvpn/removeOVPN.sh b/scripts/openvpn/removeOVPN.sh index 62a8f4e..8e300a5 100755 --- a/scripts/openvpn/removeOVPN.sh +++ b/scripts/openvpn/removeOVPN.sh @@ -124,5 +124,17 @@ for (( ii = 0; ii < ${#CERTS_TO_REVOKE[@]}; ii++)); do rm -rf "${install_home}/ovpns/${CERTS_TO_REVOKE[ii]}.ovpn" rm -rf "/etc/openvpn/easy-rsa/pki/${CERTS_TO_REVOKE[ii]}.ovpn" cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem + + # If using Pi-hole, remove the client from the hosts file + if [ -f /etc/pivpn/hosts.openvpn ]; then + # Grab the client IP address + STATIC_IP=$(awk '{print $2}' <<< /etc/openvpn/ccd/"${CERTS_TO_REVOKE[ii]}") + sed "\#${STATIC_IP} ${CERTS_TO_REVOKE[ii]}.pivpn#d" -i /etc/pivpn/hosts.openvpn + if killall -SIGHUP pihole-FTL; then + echo "::: Updated hosts file for Pi-hole" + else + echo "::: Failed to reload pihole-FTL configuration" + fi + fi done printf "::: Completed!\n" From 6fd451dac0ea8d834e29fbb8a0e8fe10ea5b0b5a Mon Sep 17 00:00:00 2001 From: Orazio Date: Mon, 10 Feb 2020 17:34:11 +0100 Subject: [PATCH 04/12] apt-transport-https is required since we will use HTTPS repos in the script --- auto_install/install.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 48907e5..6780e82 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -418,12 +418,13 @@ notifyPackageUpdatesAvailable(){ } preconfigurePackages(){ - # Add support for https repositories if there are any that use it otherwise the installation will silently fail - if [[ -f /etc/apt/sources.list ]]; then - if grep -q https /etc/apt/sources.list; then - BASE_DEPS+=("apt-transport-https") + # Add support for https repositories that will be used later on + if [[ -f /etc/apt/sources.list ]]; then + # Only on stretch because on buster apt already support https transport + if [[ ${OSCN} == "stretch" ]]; then + BASE_DEPS+=("apt-transport-https") fi - fi + fi if [[ ${OSCN} == "buster" ]]; then $SUDO update-alternatives --set iptables /usr/sbin/iptables-legacy From 0cb5546608784dc609493424f7aef69791f1b728 Mon Sep 17 00:00:00 2001 From: Orazio Date: Mon, 10 Feb 2020 17:36:39 +0100 Subject: [PATCH 05/12] Get $STATIC_IP before ccd folder is deleted (otherwhise $STATIC_IP will be empty) --- scripts/openvpn/removeOVPN.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/openvpn/removeOVPN.sh b/scripts/openvpn/removeOVPN.sh index 8e300a5..4b5124c 100755 --- a/scripts/openvpn/removeOVPN.sh +++ b/scripts/openvpn/removeOVPN.sh @@ -119,6 +119,9 @@ for (( ii = 0; ii < ${#CERTS_TO_REVOKE[@]}; ii++)); do rm -rf "pki/reqs/${CERTS_TO_REVOKE[ii]}.req" rm -rf "pki/private/${CERTS_TO_REVOKE[ii]}.key" rm -rf "pki/issued/${CERTS_TO_REVOKE[ii]}.crt" + + # Grab the client IP address + STATIC_IP=$(grep -v "^#" /etc/openvpn/ccd/"${CERTS_TO_REVOKE[ii]}" | grep -w ifconfig-push | grep -oE '10.8.0\.[0-9]{1,3}') rm -rf /etc/openvpn/ccd/"${CERTS_TO_REVOKE[ii]}" rm -rf "${install_home}/ovpns/${CERTS_TO_REVOKE[ii]}.ovpn" @@ -127,8 +130,6 @@ for (( ii = 0; ii < ${#CERTS_TO_REVOKE[@]}; ii++)); do # If using Pi-hole, remove the client from the hosts file if [ -f /etc/pivpn/hosts.openvpn ]; then - # Grab the client IP address - STATIC_IP=$(awk '{print $2}' <<< /etc/openvpn/ccd/"${CERTS_TO_REVOKE[ii]}") sed "\#${STATIC_IP} ${CERTS_TO_REVOKE[ii]}.pivpn#d" -i /etc/pivpn/hosts.openvpn if killall -SIGHUP pihole-FTL; then echo "::: Updated hosts file for Pi-hole" From 3730d315e9a22324efe3f0e0bac025143b611328 Mon Sep 17 00:00:00 2001 From: Orazio Date: Mon, 10 Feb 2020 17:58:32 +0100 Subject: [PATCH 06/12] Automatic backup of existing OpenVPN/WireGuard folder should only be readable by root --- auto_install/install.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/auto_install/install.sh b/auto_install/install.sh index 6780e82..b801569 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -1735,7 +1735,10 @@ confOpenVPN(){ # Backup the openvpn folder OPENVPN_BACKUP="openvpn_$(date +%Y-%m-%d-%H%M%S).tar.gz" echo "::: Backing up the openvpn folder to /etc/${OPENVPN_BACKUP}" + CURRENT_UMASK=$(umask) + umask 0077 $SUDO tar czf "/etc/${OPENVPN_BACKUP}" /etc/openvpn &> /dev/null + umask "$CURRENT_UMASK" if [ -f /etc/openvpn/server.conf ]; then $SUDO rm /etc/openvpn/server.conf @@ -1912,7 +1915,10 @@ confWireGuard(){ # Backup the wireguard folder WIREGUARD_BACKUP="wireguard_$(date +%Y-%m-%d-%H%M%S).tar.gz" echo "::: Backing up the wireguard folder to /etc/${WIREGUARD_BACKUP}" + CURRENT_UMASK=$(umask) + umask 0077 $SUDO tar czf "/etc/${WIREGUARD_BACKUP}" /etc/wireguard &> /dev/null + umask "$CURRENT_UMASK" if [ -f /etc/wireguard/wg0.conf ]; then $SUDO rm /etc/wireguard/wg0.conf From 337fa10fdcc49cbfe5a077aa472fa0de1fc5e9af Mon Sep 17 00:00:00 2001 From: Orazio Date: Mon, 10 Feb 2020 21:57:09 +0100 Subject: [PATCH 07/12] Improvements when importing GPG keys - Importing OpenVPN PGP key from keyserver should be more secure than downloading from the website as we specifically tell the keyserver which key we want, referring to its fingerprint - Exit if import is unsuccessful --- auto_install/install.sh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index b801569..384d9bb 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -43,6 +43,11 @@ debianOvpnUserGroup="openvpn:openvpn" UNATTUPG_RELEASE="1.16" UNATTUPG_CONFIG="https://github.com/mvo5/unattended-upgrades/archive/${UNATTUPG_RELEASE}.tar.gz" +# GPG fingerprints (you can look them up at https://keyserver.ubuntu.com) +OPENVPN_REPO_KEY="0x30ebf4e73cce63eee124dd278e6da8b4e158c569" +DEBIAN_STRETCH_KEY="0xe1cf20ddffe4b89e802658f1e0b11894f66aec98" +DEBIAN_BUSTER_KEY="0x80d15823b7fd1561f9f7bcdddc30d7c23cbbabee" + # Find the rows and columns. Will default to 80x24 if it can not be detected. screen_size=$(stty size 2>/dev/null || echo 24 80) rows=$(echo "$screen_size" | awk '{print $1}') @@ -1050,7 +1055,8 @@ installOpenVPN(){ echo "::: Installing OpenVPN from Debian package... " if [ "$PLAT" = "Debian" ] || [ "$PLAT" = "Ubuntu" ]; then - # gnupg is used to add the openvpn PGP key to the APT keyring + # gnupg is used by apt-key to import the openvpn GPG key into the + # APT keyring PIVPN_DEPS=(gnupg) installDependentPackages PIVPN_DEPS[@] @@ -1058,7 +1064,10 @@ installOpenVPN(){ # 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 ! $SUDO apt-key adv --keyserver keyserver.ubuntu.com --recv-keys "$OPENVPN_REPO_KEY"; then + echo "::: Failed to import OpenVPN GPG key" + exit 1 + fi if ! grep -qR "deb http.\?://build.openvpn.net/debian/openvpn/stable.\? $OSCN main" /etc/apt/sources.list*; then echo "::: Adding OpenVPN repository... " @@ -1132,12 +1141,16 @@ installWireGuard(){ if [ "$(uname -m)" = "armv7l" ]; then echo "::: Installing WireGuard from Debian package... " - # dirmngr is used to download repository keys for the unstable repo + # dirmngr is used by apt-key to import the debian GPG keys for the unstable + # repo into the APT keyring. PIVPN_DEPS=(dirmngr) installDependentPackages PIVPN_DEPS[@] echo "::: Adding repository keys..." - $SUDO apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC 648ACFD622F3D138 + if ! $SUDO apt-key adv --keyserver keyserver.ubuntu.com --recv-keys "$DEBIAN_STRETCH_KEY" "$DEBIAN_BUSTER_KEY"; then + echo "::: Failed to import Debian GPG keys" + exit 1 + fi # 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 From 41ed9c4a6faa11770564cbed612ffa2f8611bd96 Mon Sep 17 00:00:00 2001 From: Orazio Date: Tue, 11 Feb 2020 11:50:18 +0100 Subject: [PATCH 08/12] Minor fixes - LC_ALL=C should be the canonical way to override the locale, instead of setting a specific one. - apt-transport-https is required on Ubuntu < Bionic and Debian < Buster --- auto_install/install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 384d9bb..c65bc84 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -425,8 +425,8 @@ notifyPackageUpdatesAvailable(){ preconfigurePackages(){ # Add support for https repositories that will be used later on if [[ -f /etc/apt/sources.list ]]; then - # Only on stretch because on buster apt already support https transport - if [[ ${OSCN} == "stretch" ]]; then + # buster and bionic have apt >= 1.5 which has https support built in + if [[ ${OSCN} != "buster" ]] && [[ ${OSCN} != "bionic" ]]; then BASE_DEPS+=("apt-transport-https") fi fi @@ -439,7 +439,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 LANG=en_US.UTF-8 $SUDO ufw status | grep -q inactive; then + if LC_ALL=C $SUDO ufw status | grep -q inactive; then USING_UFW=0 else USING_UFW=1 From 87cf243abca687b680849de0fbead48c6b6e325d Mon Sep 17 00:00:00 2001 From: Orazio Date: Thu, 13 Feb 2020 11:30:13 +0100 Subject: [PATCH 09/12] Fix Pi-hole support when dnsmasq is set to listen on all interfaces --- auto_install/install.sh | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index c65bc84..e0be3ee 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -14,6 +14,7 @@ pivpnGitUrl="https://github.com/pivpn/pivpn.git" setupVars="/etc/pivpn/setupVars.conf" pivpnFilesDir="/etc/.pivpn" +piholeSetupVars="/etc/pihole/setupVars.conf" dnsmasqConfig="/etc/dnsmasq.d/02-pivpn.conf" ### PKG Vars ### @@ -1432,10 +1433,28 @@ askClientDNS(){ # Detect and offer to use Pi-hole 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 - echo "interface=$pivpnDEV" | $SUDO tee "$dnsmasqConfig" > /dev/null - echo "addn-hosts=/etc/pivpn/hosts.$VPN" | $SUDO tee -a "$dnsmasqConfig" > /dev/null + if [ ! -r "$piholeSetupVars" ]; then + echo "::: Unable to read $piholeSetupVars" + exit 1 + fi + + # Add a custom hosts file for VPN clients so they appear as 'name.pivpn' in the + # Pi-hole dashboard as well as resolve by their names. + echo "addn-hosts=/etc/pivpn/hosts.$VPN" | $SUDO tee "$dnsmasqConfig" > /dev/null + + # Then create an empty hosts file or clear if it exists. $SUDO bash -c "> /etc/pivpn/hosts.$VPN" + + # If the listening behavior is "Listen only on interface whatever", tell dnsmasq + # to listen on the VPN interface as well. Other listening behaviors are permissive + # enough. + if [ "$(source "$piholeSetupVars" && echo "${DNSMASQ_LISTENING}")" = "single" ]; then + echo "interface=$pivpnDEV" | $SUDO tee -a "$dnsmasqConfig" > /dev/null + fi + + # Use the Raspberry Pi VPN IP as DNS server. pivpnDNS1="$vpnGw" + echo "pivpnDNS1=${pivpnDNS1}" >> /tmp/setupVars.conf echo "pivpnDNS2=${pivpnDNS2}" >> /tmp/setupVars.conf return From 660d83468cedddd5bf844fd1939615906683867a Mon Sep 17 00:00:00 2001 From: Orazio Date: Thu, 13 Feb 2020 11:42:23 +0100 Subject: [PATCH 10/12] Drop libmnl-dev requirement on armv6l - https://lists.zx2c4.com/pipermail/wireguard/2020-February/004963.html --- auto_install/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index e0be3ee..3265851 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -1173,7 +1173,7 @@ installWireGuard(){ elif [ "$(uname -m)" = "armv6l" ]; then echo "::: Installing WireGuard from source... " - PIVPN_DEPS=(checkinstall dkms libmnl-dev libelf-dev raspberrypi-kernel-headers build-essential pkg-config qrencode jq) + PIVPN_DEPS=(checkinstall dkms libelf-dev raspberrypi-kernel-headers build-essential pkg-config qrencode jq) installDependentPackages PIVPN_DEPS[@] # Delete any leftover code From edbd23a2a1bc8680246dfd828764dffb400e468f Mon Sep 17 00:00:00 2001 From: Orazio Date: Sat, 15 Feb 2020 13:24:42 +0100 Subject: [PATCH 11/12] Fixed missing condition in if statement when deciding whether to listen on tun0/wg0 --- auto_install/install.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 3265851..82b3c6f 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -1445,10 +1445,16 @@ askClientDNS(){ # Then create an empty hosts file or clear if it exists. $SUDO bash -c "> /etc/pivpn/hosts.$VPN" - # If the listening behavior is "Listen only on interface whatever", tell dnsmasq - # to listen on the VPN interface as well. Other listening behaviors are permissive - # enough. - if [ "$(source "$piholeSetupVars" && echo "${DNSMASQ_LISTENING}")" = "single" ]; then + # If the listening behavior is "Listen only on interface whatever", which is the + # default, tell dnsmasq to listen on the VPN interface as well. Other listening + # behaviors are permissive enough. + + # Source in a subshell to prevent overwriting script's variables + DNSMASQ_LISTENING="$(source "$piholeSetupVars" && echo "${DNSMASQ_LISTENING}")" + + # $DNSMASQ_LISTENING is not set if you never edit/save settings in the DNS page, + # so if the variable is empty, we still add the 'interface=' directive. + if [ -z "${DNSMASQ_LISTENING}" ] || [ "${DNSMASQ_LISTENING}" = "single" ]; then echo "interface=$pivpnDEV" | $SUDO tee -a "$dnsmasqConfig" > /dev/null fi From 9846d3787a504de97ddb11cf2e51ae38a148a459 Mon Sep 17 00:00:00 2001 From: Orazio Date: Sun, 16 Feb 2020 09:09:09 +0100 Subject: [PATCH 12/12] Use variables to define VPN ranges instead of hard coding IPs --- auto_install/install.sh | 24 ++++++++++++++++++++++++ scripts/openvpn/makeOVPN.sh | 17 +++++++++++++---- scripts/openvpn/removeOVPN.sh | 3 ++- scripts/self_check.sh | 6 ------ scripts/uninstall.sh | 11 ----------- scripts/wireguard/makeCONF.sh | 8 +++++--- scripts/wireguard/removeCONF.sh | 3 ++- 7 files changed, 46 insertions(+), 26 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 82b3c6f..b109c60 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -1038,7 +1038,11 @@ askWhichVPN(){ fi if [ "$VPN" = "wireguard" ]; then + # Since WireGuard only uses UDP, askCustomProto() is never called so we + # set the protocol here (it's not actually required to save the value, but + # it might be useful for the user when port forwarding). pivpnPROTO="udp" + echo "pivpnPROTO=${pivpnPROTO}" >> /tmp/setupVars.conf pivpnDEV="wg0" pivpnNET="10.6.0.0" elif [ "$VPN" = "openvpn" ]; then @@ -1048,6 +1052,9 @@ askWhichVPN(){ vpnGw="${pivpnNET/.0.0/.0.1}" echo "VPN=${VPN}" >> /tmp/setupVars.conf + echo "pivpnDEV=${pivpnDEV}" >> /tmp/setupVars.conf + echo "pivpnNET=${pivpnNET}" >> /tmp/setupVars.conf + echo "subnetClass=${subnetClass}" >> /tmp/setupVars.conf } installOpenVPN(){ @@ -1762,6 +1769,13 @@ askEncryption(){ echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}" >> /tmp/setupVars.conf } +cidrToMask(){ + # Source: https://stackoverflow.com/a/20767392 + set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0 + [ $1 -gt 1 ] && shift $1 || shift + echo ${1-0}.${2-0}.${3-0}.${4-0} +} + confOpenVPN(){ # Grab the existing Hostname host_name=$(hostname -s) @@ -1905,6 +1919,16 @@ set_var EASYRSA_ALGO ${pivpnCERT}" | $SUDO tee vars >/dev/null $SUDO sed -i "s#\\(dh /etc/openvpn/easy-rsa/pki/dh\\).*#\\1${pivpnENCRYPT}.pem#" /etc/openvpn/server.conf fi + # if they modified VPN network put value in server.conf + if [ "$pivpnNET" != "10.8.0.0" ]; then + $SUDO sed -i "s/10.8.0.0/${pivpnNET}/g" /etc/openvpn/server.conf + fi + + # if they modified VPN subnet class put value in server.conf + if [ "$(cidrToMask "$subnetClass")" != "255.255.255.0" ]; then + $SUDO sed -i "s/255.255.255.0/$(cidrToMask "$subnetClass")/g" /etc/openvpn/server.conf + fi + # if they modified port put value in server.conf if [ "$pivpnPORT" != 1194 ]; then $SUDO sed -i "s/1194/${pivpnPORT}/g" /etc/openvpn/server.conf diff --git a/scripts/openvpn/makeOVPN.sh b/scripts/openvpn/makeOVPN.sh index 2071744..c645c55 100755 --- a/scripts/openvpn/makeOVPN.sh +++ b/scripts/openvpn/makeOVPN.sh @@ -405,20 +405,29 @@ else fi +cidrToMask(){ + # Source: https://stackoverflow.com/a/20767392 + set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0 + [ $1 -gt 1 ] && shift $1 || shift + echo ${1-0}.${2-0}.${3-0}.${4-0} +} + +NET_REDUCED="${pivpnNET::-2}" + # Find an unused number for the last octet of the client IP for i in {2..254}; do # find returns 0 if the folder is empty, so we create the 'ls -A [...]' # exception to stop at the first static IP (10.8.0.2). Otherwise it would # cycle to the end without finding and available octet. - if [ -z "$(ls -A /etc/openvpn/ccd)" ] || ! find /etc/openvpn/ccd -type f -exec grep -q "10.8.0.$i" {} +; then - COUNT="$i" - echo "ifconfig-push 10.8.0.$i 255.255.255.0" >> /etc/openvpn/ccd/"${NAME}" + if [ -z "$(ls -A /etc/openvpn/ccd)" ] || ! find /etc/openvpn/ccd -type f -exec grep -q "${NET_REDUCED}.${i}" {} +; then + COUNT="${i}" + echo "ifconfig-push ${NET_REDUCED}.${i} $(cidrToMask "$subnetClass")" >> /etc/openvpn/ccd/"${NAME}" break fi done if [ -f /etc/pivpn/hosts.openvpn ]; then - echo "10.8.0.${COUNT} ${NAME}.pivpn" >> /etc/pivpn/hosts.openvpn + echo "${NET_REDUCED}.${COUNT} ${NAME}.pivpn" >> /etc/pivpn/hosts.openvpn if killall -SIGHUP pihole-FTL; then echo "::: Updated hosts file for Pi-hole" else diff --git a/scripts/openvpn/removeOVPN.sh b/scripts/openvpn/removeOVPN.sh index 4b5124c..50666f0 100755 --- a/scripts/openvpn/removeOVPN.sh +++ b/scripts/openvpn/removeOVPN.sh @@ -121,7 +121,8 @@ for (( ii = 0; ii < ${#CERTS_TO_REVOKE[@]}; ii++)); do rm -rf "pki/issued/${CERTS_TO_REVOKE[ii]}.crt" # Grab the client IP address - STATIC_IP=$(grep -v "^#" /etc/openvpn/ccd/"${CERTS_TO_REVOKE[ii]}" | grep -w ifconfig-push | grep -oE '10.8.0\.[0-9]{1,3}') + NET_REDUCED="${pivpnNET::-2}" + STATIC_IP=$(grep -v "^#" /etc/openvpn/ccd/"${CERTS_TO_REVOKE[ii]}" | grep -w ifconfig-push | grep -oE "${NET_REDUCED}\.[0-9]{1,3}") rm -rf /etc/openvpn/ccd/"${CERTS_TO_REVOKE[ii]}" rm -rf "${install_home}/ovpns/${CERTS_TO_REVOKE[ii]}.ovpn" diff --git a/scripts/self_check.sh b/scripts/self_check.sh index b6a2194..1ef555d 100755 --- a/scripts/self_check.sh +++ b/scripts/self_check.sh @@ -1,6 +1,5 @@ #!/bin/bash -subnetClass="24" setupVars="/etc/pivpn/setupVars.conf" ERR=0 @@ -12,14 +11,9 @@ 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 diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index 2a7409c..35df520 100755 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -6,7 +6,6 @@ PKG_MANAGER="apt-get" UPDATE_PKG_CACHE="${PKG_MANAGER} update" -subnetClass="24" dnsmasqConfig="/etc/dnsmasq.d/02-pivpn.conf" setupVars="/etc/pivpn/setupVars.conf" @@ -60,16 +59,6 @@ removeAll(){ # Removing firewall rules. echo "::: Removing firewall rules..." - ### FIXME: introduce global config space! - if [ "$VPN" = "wireguard" ]; then - pivpnPROTO="udp" - pivpnDEV="wg0" - pivpnNET="10.6.0.0" - elif [ "$VPN" = "openvpn" ]; then - pivpnDEV="tun0" - pivpnNET="10.8.0.0" - fi - if [ "$USING_UFW" -eq 1 ]; then ### FIXME: SC2154 diff --git a/scripts/wireguard/makeCONF.sh b/scripts/wireguard/makeCONF.sh index f978fcb..d99310d 100755 --- a/scripts/wireguard/makeCONF.sh +++ b/scripts/wireguard/makeCONF.sh @@ -86,9 +86,11 @@ for i in {2..254}; do fi done +NET_REDUCED="${pivpnNET::-2}" + echo -n "[Interface] PrivateKey = $(cat "keys/${CLIENT_NAME}_priv") -Address = 10.6.0.${COUNT}/24 +Address = ${NET_REDUCED}.${COUNT}/${subnetClass} DNS = ${pivpnDNS1}" > "configs/${CLIENT_NAME}.conf" if [ -n "${pivpnDNS2}" ]; then @@ -109,12 +111,12 @@ echo "# begin ${CLIENT_NAME} [Peer] PublicKey = $(cat "keys/${CLIENT_NAME}_pub") PresharedKey = $(cat keys/psk) -AllowedIPs = 10.6.0.${COUNT}/32 +AllowedIPs = ${NET_REDUCED}.${COUNT}/32 # end ${CLIENT_NAME}" >> wg0.conf echo "::: Updated server config" if [ -f /etc/pivpn/hosts.wireguard ]; then - echo "10.6.0.${COUNT} ${CLIENT_NAME}.pivpn" >> /etc/pivpn/hosts.wireguard + echo "${NET_REDUCED}.${COUNT} ${CLIENT_NAME}.pivpn" >> /etc/pivpn/hosts.wireguard if killall -SIGHUP pihole-FTL; then echo "::: Updated hosts file for Pi-hole" else diff --git a/scripts/wireguard/removeCONF.sh b/scripts/wireguard/removeCONF.sh index 0085809..414b492 100755 --- a/scripts/wireguard/removeCONF.sh +++ b/scripts/wireguard/removeCONF.sh @@ -106,7 +106,8 @@ for CLIENT_NAME in "${CLIENTS_TO_REMOVE[@]}"; do # If using Pi-hole, remove the client from the hosts file if [ -f /etc/pivpn/hosts.wireguard ]; then - sed "\#10.6.0.${COUNT} ${CLIENT_NAME}.pivpn#d" -i /etc/pivpn/hosts.wireguard + NET_REDUCED="${pivpnNET::-2}" + sed "\#${NET_REDUCED}.${COUNT} ${CLIENT_NAME}.pivpn#d" -i /etc/pivpn/hosts.wireguard if killall -SIGHUP pihole-FTL; then echo "::: Updated hosts file for Pi-hole" else