From 93044d6f6d9c4d2a0c086ab4605402937c801792 Mon Sep 17 00:00:00 2001 From: corbolais Date: Sun, 8 Dec 2019 16:13:26 +0100 Subject: [PATCH 1/8] add local resolver as DNS option. Signed-off-by: corbolais --- auto_install/install.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 2305458..9e96e95 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -975,7 +975,11 @@ askClientDNS(){ fi fi - DNSChoseCmd=(whiptail --separate-output --radiolist "Select the DNS Provider for your VPN Clients (press space to select). To use your own, select Custom." ${r} ${c} 6) + DNSChoseCmd=(whiptail --separate-output --radiolist "Select the DNS Provider + for your VPN Clients (press space to select). To use your own, select + Custom.\\n\\nIn case you have a local resolver running, i.e. unbound, select + \"PiVPN-is-local-DNS\" and make sure your resolver is listening on + 10.8.0.1, allowing requests from 10.8.0.1/8" ${r} ${c} 6) DNSChooseOptions=(Google "" on OpenDNS "" off Level3 "" off @@ -983,6 +987,7 @@ askClientDNS(){ Norton "" off FamilyShield "" off CloudFlare "" off + PiVPN-is-local-DNS "" off Custom "" off) if DNSchoices=$("${DNSChoseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty) @@ -997,7 +1002,8 @@ askClientDNS(){ ["DNS.WATCH"]="84.200.69.80 84.200.70.40" ["Norton"]="199.85.126.10 199.85.127.10" ["FamilyShield"]="208.67.222.123 208.67.220.123" - ["CloudFlare"]="1.1.1.1 1.0.0.1") + ["CloudFlare"]="1.1.1.1 1.0.0.1" + ["PiVPN-is-local-DNS"]="10.8.0.1") pivpnDNS1=$(awk '{print $1}' <<< "${DNS_MAP["${DNSchoices}"]}") pivpnDNS2=$(awk '{print $2}' <<< "${DNS_MAP["${DNSchoices}"]}") From 8affc9a3133d0ef2634b1dd17b8d81cfd5ba74e7 Mon Sep 17 00:00:00 2001 From: corbolais Date: Sun, 8 Dec 2019 16:39:46 +0100 Subject: [PATCH 2/8] debian openvpn has dedicated user and group, so rather use those than nobody:nogroup (as do _many_ other packages and thus all having access to such owned files). Signed-off-by: corbolais --- auto_install/install.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 2305458..47f08bb 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -14,6 +14,8 @@ setupVars=/etc/pivpn/setupVars.conf pivpnFilesDir="/etc/.pivpn" +debianOvpnUserGroup="openvpn:openvpn" + ### PKG Vars ### PKG_MANAGER="apt-get" PKG_CACHE="/var/lib/apt/lists/" @@ -1290,7 +1292,11 @@ set_var EASYRSA_KEY_SIZE ${pivpnENCRYPT}" | $SUDO tee vars >/dev/null # Generate an empty Certificate Revocation List ${SUDOE} ./easyrsa gen-crl ${SUDOE} cp pki/crl.pem /etc/openvpn/crl.pem - ${SUDOE} chown nobody:nogroup /etc/openvpn/crl.pem + if test "${PLAT}" = "Debian"; then + ${SUDOE} chown "$debianOvpnUserGroup" /etc/openvpn/crl.pem + else + ${SUDOE} chown nobody:nogroup /etc/openvpn/crl.pem + fi # Write config file for server using the template.txt file $SUDO cp /etc/.pivpn/server_config.txt /etc/openvpn/server.conf From 6e763e024053aa04be666929fd6b713de1d5f05e Mon Sep 17 00:00:00 2001 From: corbolais Date: Sun, 8 Dec 2019 17:34:57 +0100 Subject: [PATCH 3/8] Debian: add openvpn user/group if missing. Signed-off-by: corbolais --- auto_install/install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/auto_install/install.sh b/auto_install/install.sh index 47f08bb..e5d6bbb 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -1293,6 +1293,9 @@ set_var EASYRSA_KEY_SIZE ${pivpnENCRYPT}" | $SUDO tee vars >/dev/null ${SUDOE} ./easyrsa gen-crl ${SUDOE} cp pki/crl.pem /etc/openvpn/crl.pem if test "${PLAT}" = "Debian"; then + if ! getent passwd openvpn; then + ${SUDOE} adduser --system --home /etc/openvpn/ --no-create-home --group ${debianOvpnUserGroup%:*} + fi ${SUDOE} chown "$debianOvpnUserGroup" /etc/openvpn/crl.pem else ${SUDOE} chown nobody:nogroup /etc/openvpn/crl.pem From 1aa6472b726e579e48cba2196f535ceda7e2ad32 Mon Sep 17 00:00:00 2001 From: corbolais Date: Sun, 8 Dec 2019 17:40:30 +0100 Subject: [PATCH 4/8] chg: openvpn-user home, shell. Signed-off-by: corbolais --- 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 e5d6bbb..1d02f7c 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -1294,7 +1294,7 @@ set_var EASYRSA_KEY_SIZE ${pivpnENCRYPT}" | $SUDO tee vars >/dev/null ${SUDOE} cp pki/crl.pem /etc/openvpn/crl.pem if test "${PLAT}" = "Debian"; then if ! getent passwd openvpn; then - ${SUDOE} adduser --system --home /etc/openvpn/ --no-create-home --group ${debianOvpnUserGroup%:*} + ${SUDOE} adduser --system --home /var/lib/openvpn/ --no-create-home --group --disabled-login ${debianOvpnUserGroup%:*} fi ${SUDOE} chown "$debianOvpnUserGroup" /etc/openvpn/crl.pem else From 55dc52d3e0f953d6c88dfce8e645439246eadc77 Mon Sep 17 00:00:00 2001 From: corbolais Date: Sun, 8 Dec 2019 20:41:11 +0100 Subject: [PATCH 5/8] use openvpn:openvpn user/group ownership unconditionally. Signed-off-by: corbolais --- auto_install/install.sh | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 1d02f7c..8749870 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -1292,14 +1292,10 @@ set_var EASYRSA_KEY_SIZE ${pivpnENCRYPT}" | $SUDO tee vars >/dev/null # Generate an empty Certificate Revocation List ${SUDOE} ./easyrsa gen-crl ${SUDOE} cp pki/crl.pem /etc/openvpn/crl.pem - if test "${PLAT}" = "Debian"; then - if ! getent passwd openvpn; then - ${SUDOE} adduser --system --home /var/lib/openvpn/ --no-create-home --group --disabled-login ${debianOvpnUserGroup%:*} - fi - ${SUDOE} chown "$debianOvpnUserGroup" /etc/openvpn/crl.pem - else - ${SUDOE} chown nobody:nogroup /etc/openvpn/crl.pem + if ! getent passwd openvpn; then + ${SUDOE} adduser --system --home /var/lib/openvpn/ --no-create-home --group --disabled-login ${debianOvpnUserGroup%:*} fi + ${SUDOE} chown "$debianOvpnUserGroup" /etc/openvpn/crl.pem # Write config file for server using the template.txt file $SUDO cp /etc/.pivpn/server_config.txt /etc/openvpn/server.conf From e76f3755aba453adde3c4d9153708d1dcc865369 Mon Sep 17 00:00:00 2001 From: corbolais Date: Mon, 9 Dec 2019 12:41:40 +0100 Subject: [PATCH 6/8] consistent use of pivpnNET, subnetClass and vpnGw. Signed-off-by: corbolais --- auto_install/install.sh | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 9e96e95..9b0af3f 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -33,6 +33,8 @@ pivpnGitUrl="https://github.com/pivpn/pivpn.git" easyrsaVer="3.0.6" easyrsaRel="https://github.com/OpenVPN/easy-rsa/releases/download/v${easyrsaVer}/EasyRSA-unix-v${easyrsaVer}.tgz" +subnetClass="24" + # Raspbian's unattended-upgrades package downloads Debian's config, so this is the link for the proper config UNATTUPG_RELEASE="1.14" UNATTUPG_CONFIG="https://github.com/mvo5/unattended-upgrades/archive/${UNATTUPG_RELEASE}.tar.gz" @@ -692,6 +694,7 @@ askWhichVPN(){ pivpnDEV="tun0" pivpnNET="10.8.0.0" fi + vpnGw="${pivpnNET/.0/.1}" echo "VPN=${VPN}" >> /tmp/setupVars.conf } @@ -979,7 +982,7 @@ askClientDNS(){ for your VPN Clients (press space to select). To use your own, select Custom.\\n\\nIn case you have a local resolver running, i.e. unbound, select \"PiVPN-is-local-DNS\" and make sure your resolver is listening on - 10.8.0.1, allowing requests from 10.8.0.1/8" ${r} ${c} 6) + \"$vpnGw\", allowing requests from \"${pivpnNET}/${subnetClass}\"." ${r} ${c} 6) DNSChooseOptions=(Google "" on OpenDNS "" off Level3 "" off @@ -1003,7 +1006,7 @@ askClientDNS(){ ["Norton"]="199.85.126.10 199.85.127.10" ["FamilyShield"]="208.67.222.123 208.67.220.123" ["CloudFlare"]="1.1.1.1 1.0.0.1" - ["PiVPN-is-local-DNS"]="10.8.0.1") + ["PiVPN-is-local-DNS"]="$vpnGw") pivpnDNS1=$(awk '{print $1}' <<< "${DNS_MAP["${DNSchoices}"]}") pivpnDNS2=$(awk '{print $2}' <<< "${DNS_MAP["${DNSchoices}"]}") @@ -1388,7 +1391,7 @@ confWireGuard(){ echo "[Interface] PrivateKey = $($SUDO cat /etc/wireguard/keys/server_priv) -Address = 10.6.0.1/24 +Address = ${vpnGw}/${subnetClass} ListenPort = ${pivpnPORT}" | $SUDO tee /etc/wireguard/wg0.conf &> /dev/null echo "::: Server config generated." } @@ -1407,10 +1410,10 @@ confNetwork(){ USING_UFW=1 echo "::: Detected UFW is enabled." echo "::: Adding UFW rules..." - $SUDO sed "/delete these required/i *nat\n:POSTROUTING ACCEPT [0:0]\n-I POSTROUTING -s ${pivpnNET}\/24 -o ${IPv4dev} -j MASQUERADE\nCOMMIT\n" -i /etc/ufw/before.rules + $SUDO sed "/delete these required/i *nat\n:POSTROUTING ACCEPT [0:0]\n-I POSTROUTING -s ${pivpnNET}\/${subnetClass} -o ${IPv4dev} -j MASQUERADE\nCOMMIT\n" -i /etc/ufw/before.rules # Insert rules at the beginning of the chain (in case there are other rules that may drop the traffic) $SUDO ufw insert 1 allow "${pivpnPORT}"/"${pivpnPROTO}" >/dev/null - $SUDO ufw route insert 1 allow in on "${pivpnDEV}" from "${pivpnNET}/24" out on "${IPv4dev}" to any >/dev/null + $SUDO ufw route insert 1 allow in on "${pivpnDEV}" from "${pivpnNET}/${subnetClass}" out on "${IPv4dev}" to any >/dev/null $SUDO ufw reload >/dev/null echo "::: UFW configuration completed." @@ -1423,7 +1426,7 @@ confNetwork(){ # Now some checks to detect which rules we need to add. On a newly installed system all policies # should be ACCEPT, so the only required rule would be the MASQUERADE one. - $SUDO iptables -t nat -I POSTROUTING -s "${pivpnNET}/24" -o "${IPv4dev}" -j MASQUERADE + $SUDO iptables -t nat -I POSTROUTING -s "${pivpnNET}/${subnetClass}" -o "${IPv4dev}" -j MASQUERADE # Count how many rules are in the INPUT and FORWARD chain. When parsing input from # iptables -S, '^-P' skips the policies and 'ufw-' skips ufw chains (in case ufw was found @@ -1449,8 +1452,8 @@ confNetwork(){ fi if [ "$FORWARD_RULES_COUNT" -ne 0 ] || [ "$FORWARD_POLICY" != "ACCEPT" ]; then - $SUDO iptables -I FORWARD 1 -d "${pivpnNET}/24" -i "${IPv4dev}" -o "${pivpnDEV}" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT - $SUDO iptables -I FORWARD 2 -s "${pivpnNET}/24" -i "${pivpnDEV}" -o "${IPv4dev}" -j ACCEPT + $SUDO iptables -I FORWARD 1 -d "${pivpnNET}/${subnetClass}" -i "${IPv4dev}" -o "${pivpnDEV}" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + $SUDO iptables -I FORWARD 2 -s "${pivpnNET}/${subnetClass}" -i "${pivpnDEV}" -o "${IPv4dev}" -j ACCEPT FORWARD_CHAIN_EDITED=1 else FORWARD_CHAIN_EDITED=0 From 729674595bb9071fcbf06d4384c72fc456b4dcd4 Mon Sep 17 00:00:00 2001 From: corbolais Date: Mon, 9 Dec 2019 13:34:25 +0100 Subject: [PATCH 7/8] rm openvpn:openvpn user/group iff openvpn pkg is removed. shellcheck cleanup. preliminary fixes. add (global) FIXMEs. Signed-off-by: corbolais --- scripts/uninstall.sh | 59 +++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh index 6de5842..1647531 100755 --- a/scripts/uninstall.sh +++ b/scripts/uninstall.sh @@ -1,6 +1,9 @@ #!/usr/bin/env bash # PiVPN: Uninstall Script +### FIXME: global: config storage, refactor all scripts to adhere to the storage +### FIXME: use variables where appropriate, reduce magic numbers by 99.9%, at least. + PKG_MANAGER="apt-get" setupVars="/etc/pivpn/setupVars.conf" @@ -9,12 +12,13 @@ if [ ! -f "${setupVars}" ]; then exit 1 fi +# shellcheck disable=SC1090 source "${setupVars}" # Find the rows and columns. Will default to 80x24 if it can not be detected. screen_size=$(stty size 2>/dev/null || echo 24 80) -rows=$(echo $screen_size | awk '{print $1}') -columns=$(echo $screen_size | awk '{print $2}') +rows=$(echo "$screen_size" | awk '{print $1}') +columns=$(echo "$screen_size" | awk '{print $2}') # Divide by two so the dialogs take up half of the screen, which looks nice. r=$(( rows / 2 )) @@ -23,18 +27,19 @@ c=$(( columns / 2 )) r=$(( r < 20 ? 20 : r )) c=$(( c < 70 ? 70 : c )) +### FIXME: introduce global lib 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 "$pid"; do local temp=${spinstr#?} printf " [%c] " "$spinstr" local spinstr=$temp${spinstr%"$temp"} sleep $delay - printf "\b\b\b\b\b\b" + printf "\\b\\b\\b\\b\\b\\b" done - printf " \b\b\b\b" + printf " \\b\\b\\b\\b" } removeAll(){ @@ -52,6 +57,7 @@ removeAll(){ # Removing firewall rules. echo "::: Removing firewall rules..." + ### FIXME: introduce global config space! if [ "$VPN" = "wireguard" ]; then pivpnPROTO="udp" pivpnDEV="wg0" @@ -63,9 +69,11 @@ removeAll(){ if [ "$USING_UFW" -eq 1 ]; then + ### FIXME: SC2154 ufw delete allow "${pivpnPORT}"/"${pivpnPROTO}" > /dev/null + ### FIXME: SC2154 ufw route delete allow in on "${pivpnDEV}" from "${pivpnNET}/24" out on "${IPv4dev}" to any > /dev/null - sed -z "s/*nat\n:POSTROUTING ACCEPT \[0:0\]\n-I POSTROUTING -s ${pivpnNET}\/24 -o ${IPv4dev} -j MASQUERADE\nCOMMIT\n\n//" -i /etc/ufw/before.rules + sed -z "s/*nat\\n:POSTROUTING ACCEPT \\[0:0\\]\\n-I POSTROUTING -s ${pivpnNET}\\/24 -o ${IPv4dev} -j MASQUERADE\\nCOMMIT\\n\\n//" -i /etc/ufw/before.rules iptables -t nat -D POSTROUTING -s "${pivpnNET}/24" -o "${IPv4dev}" -j MASQUERADE ufw reload &> /dev/null @@ -100,6 +108,7 @@ removeAll(){ # On Debian and armv7l Raspbian, remove the unstable repo (on armv6l Raspbian # there is no wireguard package). On Ubuntu, remove the PPA. + ### FIXME: unconditionally rm'ing unstable.list isn't a good idea, it appears. What if someone else put it there manually? if [ "$PLAT" = "Debian" ] || { [ "$PLAT" = "Raspbian" ] && [ "$(uname -m)" = "armv7l" ]; }; then rm /etc/apt/sources.list.d/unstable.list rm /etc/apt/preferences.d/limit-unstable @@ -126,27 +135,30 @@ removeAll(){ elif [ "${i}" = "unattended-upgrades" ]; then + ### REALLY??? rm -rf /var/log/unattended-upgrades rm -rf /etc/apt/apt.conf.d/*periodic rm -rf /etc/apt/apt.conf.d/*unattended-upgrades + elif [ "${i}" = "openvpn" ]; then + deluser openvpn fi - printf ":::\tRemoving %s..." "$i"; $PKG_MANAGER -y remove --purge "$i" &> /dev/null & spinner $!; printf "done!\n"; + printf ":::\\tRemoving %s..." "$i"; $PKG_MANAGER -y remove --purge "$i" &> /dev/null & spinner $!; printf "done!\\n"; break ;; - [Nn]* ) printf ":::\tSkipping %s\n" "$i"; + [Nn]* ) printf ":::\\tSkipping %s\\n" "$i"; break ;; - * ) printf "::: You must answer yes or no!\n";; + * ) printf "::: You must answer yes or no!\\n";; esac done done # Take care of any additional package cleaning printf "::: Auto removing remaining dependencies..." - $PKG_MANAGER -y autoremove &> /dev/null & spinner $!; printf "done!\n"; + $PKG_MANAGER -y autoremove &> /dev/null & spinner $!; printf "done!\\n"; printf "::: Auto cleaning remaining dependencies..." - $PKG_MANAGER -y autoclean &> /dev/null & spinner $!; printf "done!\n"; + $PKG_MANAGER -y autoclean &> /dev/null & spinner $!; printf "done!\\n"; echo ":::" # Removing pivpn files @@ -160,7 +172,7 @@ removeAll(){ rm -rf /opt/pivpn rm -rf /etc/.pivpn rm -rf /etc/pivpn - rm -rf /var/log/*pivpn* + rm -f /var/log/*pivpn* rm -f /usr/local/bin/pivpn rm -f /etc/bash_completion.d/pivpn @@ -169,28 +181,29 @@ removeAll(){ if [ "$VPN" = "wireguard" ]; then rm -f /etc/wireguard/wg0.conf - rm -rf /etc/wireguard/configs - rm -rf /etc/wireguard/keys - rm -rf $install_home/configs + rm -f /etc/wireguard/configs + rm -f /etc/wireguard/keys + ### FIXME SC2154 + rm -f "$install_home/configs" elif [ "$VPN" = "openvpn" ]; then - rm -rf /var/log/*openvpn* + rm -f /var/log/*openvpn* rm -f /etc/openvpn/server.conf rm -f /etc/openvpn/crl.pem - rm -rf /etc/openvpn/easy-rsa - rm -rf $install_home/ovpns + rm -f /etc/openvpn/easy-rsa + rm -f "$install_home/ovpns" fi echo ":::" - printf "::: Finished removing PiVPN from your system.\n" - printf "::: Reinstall by simpling running\n:::\n:::\tcurl -L https://install.pivpn.io | bash\n:::\n::: at any time!\n:::\n" + printf "::: Finished removing PiVPN from your system.\\n" + printf "::: Reinstall by simpling running\\n:::\\n:::\\tcurl -L https://install.pivpn.io | bash\\n:::\\n::: at any time!\\n:::\\n" } askreboot(){ - printf "It is \e[1mstrongly\e[0m recommended to reboot after un-installation.\n" + printf "It is \\e[1mstrongly\\e[0m recommended to reboot after un-installation.\\n" read -p "Would you like to reboot now? [y/n]: " -n 1 -r echo if [[ ${REPLY} =~ ^[Yy]$ ]]; then - printf "\nRebooting system...\n" + printf "\\nRebooting system...\\n" sleep 3 shutdown -r now fi @@ -204,6 +217,6 @@ while true; do case $yn in [Yy]* ) removeAll; askreboot; break;; - [Nn]* ) printf "::: Not removing anything, exiting...\n"; break;; + [Nn]* ) printf "::: Not removing anything, exiting...\\n"; break;; esac done From cd1b8fbf7faf657aaca58f4cbf8f31f175f5c962 Mon Sep 17 00:00:00 2001 From: Orazio Date: Mon, 9 Dec 2019 17:05:34 +0100 Subject: [PATCH 8/8] Use printf with column in the listCONF.sh script --- auto_install/install.sh | 8 ++++---- scripts/openvpn/clientStat.sh | 2 +- scripts/wireguard/listCONF.sh | 8 +++++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/auto_install/install.sh b/auto_install/install.sh index 2305458..2239ebc 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -22,7 +22,7 @@ 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 iptables-persistent dnsutils whiptail net-tools) +BASE_DEPS=(git tar wget grep iptables-persistent 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 @@ -698,9 +698,9 @@ askWhichVPN(){ installOpenVPN(){ echo "::: Installing OpenVPN from Debian package... " - # grepcidr is used to redact IPs in the debug log, expect is used to feed easy-rsa - # with passwords, bsdmainutils provides column to format the terminal output - PIVPN_DEPS=(openvpn grepcidr expect bsdmainutils) + # 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) installDependentPackages PIVPN_DEPS[@] } diff --git a/scripts/openvpn/clientStat.sh b/scripts/openvpn/clientStat.sh index ef04114..bf2c208 100755 --- a/scripts/openvpn/clientStat.sh +++ b/scripts/openvpn/clientStat.sh @@ -35,4 +35,4 @@ else printf "\nNo Clients Connected!\n" fi printf "\n" -} | column -t -s $'\t' \ No newline at end of file +} | column -t -s $'\t' diff --git a/scripts/wireguard/listCONF.sh b/scripts/wireguard/listCONF.sh index 02e5224..fd808fe 100755 --- a/scripts/wireguard/listCONF.sh +++ b/scripts/wireguard/listCONF.sh @@ -6,8 +6,9 @@ if [ ! -s clients.txt ]; then exit 1 fi +{ # Present the user with a summary of the clients, fetching info from dates. -FORMATTED+=": \e[4mClient\e[0m&\e[4mCreation date\e[0m :\n" +printf ": \e[4mClient\e[0m \t \e[4mCreation date\e[0m :\n" while read -r LINE; do CLIENT_NAME="$(awk '{print $1}' <<< "$LINE")" @@ -17,7 +18,8 @@ while read -r LINE; do # Dates are converted from UNIX time to human readable. CD_FORMAT="$(date -d @"$CREATION_DATE" +'%d %b %Y, %H:%M, %Z')" - FORMATTED+="• $CLIENT_NAME&$CD_FORMAT\n" + printf "• $CLIENT_NAME \t $CD_FORMAT\n" done < clients.txt -echo -e "$FORMATTED" | column -t -s '&' \ No newline at end of file +printf "\n" +} | column -t -s $'\t'