diff --git a/.travis.yml b/.travis.yml index 429f10f..16da8a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ jobs: name: "Shellcheck lint" dist: linux script: - - shellcheck autoinstall/install.sh + - shellcheck auto_install/install.sh - find scripts/ -type f -exec shellcheck {} \; - stage: test diff --git a/README.md b/README.md index 98d4af0..4742a5a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ ![WireGuard + OpenVPN logo](logos.jpg) **[Is pivpn.io down?](https://status.pivpn.io)** | +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/452112df3c2c435d93aacc113f546eae)](https://app.codacy.com/gh/pivpn/pivpn?utm_source=github.com&utm_medium=referral&utm_content=pivpn/pivpn&utm_campaign=Badge_Grade_Settings) **Test:** [![Build Status](https://travis-ci.com/pivpn/pivpn.svg?branch=test)](https://travis-ci.com/pivpn/pivpn) | **Master:** [![Build Status](https://travis-ci.com/pivpn/pivpn.svg?branch=master)](https://travis-ci.com/pivpn/pivpn) diff --git a/auto_install/install.sh b/auto_install/install.sh index 34850a6..6ba1625 100755 --- a/auto_install/install.sh +++ b/auto_install/install.sh @@ -28,7 +28,6 @@ debianOvpnUserGroup="openvpn:openvpn" ######## PKG Vars ######## PKG_MANAGER="apt-get" -PKG_CACHE="/var/lib/apt/lists/" ### FIXME: quoting UPDATE_PKG_CACHE and PKG_INSTALL hangs the script, shellcheck SC2086 UPDATE_PKG_CACHE="${PKG_MANAGER} update -y" PKG_INSTALL="${PKG_MANAGER} --yes --no-install-recommends install" @@ -438,8 +437,10 @@ preconfigurePackages(){ BASE_DEPS+=(dhcpcd5) fi - AVAILABLE_OPENVPN="$(apt-cache policy openvpn | grep -m1 'Candidate: ' | grep -v '(none)' | awk '{print $2}')" DPKG_ARCH="$(dpkg --print-architecture)" + + AVAILABLE_OPENVPN="$(apt-cache policy openvpn | grep -m1 'Candidate: ' | grep -v '(none)' | awk '{print $2}')" + OPENVPN_SUPPORT=0 NEED_OPENVPN_REPO=0 # We require OpenVPN 2.4 or later for ECC support. If not available in the @@ -461,6 +462,7 @@ preconfigurePackages(){ fi AVAILABLE_WIREGUARD="$(apt-cache policy wireguard | grep -m1 'Candidate: ' | grep -v '(none)' | awk '{print $2}')" + WIREGUARD_SUPPORT=0 # If a wireguard kernel object is found and is part of any installed package, then # it has not been build via DKMS or manually (installing via wireguard-dkms does not @@ -534,14 +536,20 @@ installDependentPackages(){ fi done - local APTLOGFILE="$($SUDO mktemp)" + local APTLOGFILE + APTLOGFILE="$($SUDO mktemp)" - if command -v debconf-apt-progress > /dev/null; then - # shellcheck disable=SC2086 - $SUDO debconf-apt-progress --logfile "${APTLOGFILE}" -- ${PKG_INSTALL} "${TO_INSTALL[@]}" - else + if [ "${runUnattended}" = 'true' ]; then # shellcheck disable=SC2086 $SUDO ${PKG_INSTALL} "${TO_INSTALL[@]}" + else + if command -v debconf-apt-progress > /dev/null; then + # shellcheck disable=SC2086 + $SUDO debconf-apt-progress --logfile "${APTLOGFILE}" -- ${PKG_INSTALL} "${TO_INSTALL[@]}" + else + # shellcheck disable=SC2086 + $SUDO ${PKG_INSTALL} "${TO_INSTALL[@]}" + fi fi local FAILED=0 @@ -684,7 +692,8 @@ validIP(){ } validIPAndNetmask(){ - local ip=$1 + local ip + ip=$1 local stat=1 ip="${ip/\//.}" @@ -763,9 +772,11 @@ getStaticIPv4Settings() { echo "::: Skipping setting static IP address" fi - echo "dhcpReserv=${dhcpReserv}" >> ${tempsetupVarsFile} - echo "IPv4addr=${IPv4addr}" >> ${tempsetupVarsFile} - echo "IPv4gw=${IPv4gw}" >> ${tempsetupVarsFile} + { + echo "dhcpReserv=${dhcpReserv}" + echo "IPv4addr=${IPv4addr}" + echo "IPv4gw=${IPv4gw}" + } >> ${tempsetupVarsFile} return fi @@ -1099,6 +1110,13 @@ installPiVPN(){ # the user after the installation. ALLOWED_IPS="0.0.0.0/0, ::0/0" fi + # The default MTU should be fine for most users but we allow to set a + # custom MTU via unattend setupVARs file. Use default if not provided. + if [ -z "$pivpnMTU" ]; then + # Using default Wireguard MTU + pivpnMTU="1420" + fi + CUSTOMIZE=0 installWireGuard @@ -1109,13 +1127,16 @@ installPiVPN(){ confNetwork echo "pivpnPROTO=${pivpnPROTO}" >> ${tempsetupVarsFile} + echo "pivpnMTU=${pivpnMTU}" >> ${tempsetupVarsFile} fi - echo "pivpnDEV=${pivpnDEV}" >> ${tempsetupVarsFile} - echo "pivpnNET=${pivpnNET}" >> ${tempsetupVarsFile} - echo "subnetClass=${subnetClass}" >> ${tempsetupVarsFile} - echo "ALLOWED_IPS=\"${ALLOWED_IPS}\"" >> ${tempsetupVarsFile} + { + echo "pivpnDEV=${pivpnDEV}" + echo "pivpnNET=${pivpnNET}" + echo "subnetClass=${subnetClass}" + echo "ALLOWED_IPS=\"${ALLOWED_IPS}\"" + } >> ${tempsetupVarsFile} } askWhichVPN(){ @@ -1243,11 +1264,15 @@ installWireGuard(){ exit 1 else if (whiptail --title "Install WireGuard" --yesno "Your Raspberry Pi is running kernel package ${INSTALLED_KERNEL}, however the latest version is ${CANDIDATE_KERNEL}.\n\nInstalling WireGuard requires the latest kernel, so to continue, first you need to upgrade all packages, then reboot, and then run the script again.\n\nProceed to the upgrade?" ${r} ${c}); then - if command -v debconf-apt-progress &> /dev/null; then - # shellcheck disable=SC2086 - $SUDO debconf-apt-progress -- ${PKG_MANAGER} upgrade -y - else + if [ "${runUnattended}" = 'true' ]; then $SUDO ${PKG_MANAGER} upgrade -y + else + if command -v debconf-apt-progress &> /dev/null; then + # shellcheck disable=SC2086 + $SUDO debconf-apt-progress -- ${PKG_MANAGER} upgrade -y + else + $SUDO ${PKG_MANAGER} upgrade -y + fi fi if (whiptail --title "Reboot" --yesno "You need to reboot after upgrading to run the new kernel.\n\nWould you like to reboot now?" ${r} ${c}); then whiptail --title "Rebooting" --msgbox "The system will now reboot.\n\nWhen you come back, just run the installation command again:\n\n curl -L https://install.pivpn.io | bash" ${r} ${c} @@ -1267,7 +1292,7 @@ installWireGuard(){ echo "::: Installing WireGuard from Debian package... " if [ -z "$AVAILABLE_WIREGUARD" ]; then - echo "::: Adding Raspbian repository... " + echo "::: Adding Raspbian Bullseye repository... " echo "deb http://raspbian.raspberrypi.org/raspbian/ bullseye main" | $SUDO tee /etc/apt/sources.list.d/pivpn-bullseye-repo.list > /dev/null # Do not upgrade packages from the bullseye repository except for wireguard @@ -1279,7 +1304,13 @@ installWireGuard(){ fi # qrencode is used to generate qrcodes from config file, for use with mobile clients - PIVPN_DEPS=(raspberrypi-kernel-headers wireguard-tools wireguard-dkms qrencode) + PIVPN_DEPS=(wireguard-tools qrencode) + + if [ "$WIREGUARD_BUILTIN" -eq 0 ]; then + # Explicitly install the module if not built-in + PIVPN_DEPS+=(raspberrypi-kernel-headers wireguard-dkms) + fi + installDependentPackages PIVPN_DEPS[@] elif [ "$PLAT" = "Debian" ]; then @@ -1287,7 +1318,7 @@ installWireGuard(){ echo "::: Installing WireGuard from Debian package... " if [ -z "$AVAILABLE_WIREGUARD" ]; then - echo "::: Adding Debian repository... " + echo "::: Adding Debian Bullseye repository... " echo "deb https://deb.debian.org/debian/ bullseye main" | $SUDO tee /etc/apt/sources.list.d/pivpn-bullseye-repo.list > /dev/null printf 'Package: *\nPin: release n=bullseye\nPin-Priority: -1\n\nPackage: wireguard wireguard-dkms wireguard-tools\nPin: release n=bullseye\nPin-Priority: 100\n' | $SUDO tee /etc/apt/preferences.d/pivpn-limit-bullseye > /dev/null @@ -1750,9 +1781,11 @@ askEncryption(){ fi fi - echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}" >> ${tempsetupVarsFile} - echo "pivpnENCRYPT=${pivpnENCRYPT}" >> ${tempsetupVarsFile} - echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}" >> ${tempsetupVarsFile} + { + echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}" + echo "pivpnENCRYPT=${pivpnENCRYPT}" + echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}" + } >> ${tempsetupVarsFile} return fi @@ -1760,9 +1793,11 @@ askEncryption(){ if [ "$VPN" = "openvpn" ]; then TWO_POINT_FOUR=1 pivpnENCRYPT=256 - echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}" >> ${tempsetupVarsFile} - echo "pivpnENCRYPT=${pivpnENCRYPT}" >> ${tempsetupVarsFile} - echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}" >> ${tempsetupVarsFile} + { + echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}" + echo "pivpnENCRYPT=${pivpnENCRYPT}" + echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}" + } >> ${tempsetupVarsFile} return fi fi @@ -1795,15 +1830,17 @@ askEncryption(){ USE_PREDEFINED_DH_PARAM=0 fi - echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}" >> ${tempsetupVarsFile} - echo "pivpnENCRYPT=${pivpnENCRYPT}" >> ${tempsetupVarsFile} - echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}" >> ${tempsetupVarsFile} + { + echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}" + echo "pivpnENCRYPT=${pivpnENCRYPT}" + echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}" + } >> ${tempsetupVarsFile} } 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 + shift $1 echo ${1-0}.${2-0}.${3-0}.${4-0} } @@ -2060,6 +2097,7 @@ confWireGuard(){ echo "[Interface] PrivateKey = $($SUDO cat /etc/wireguard/keys/server_priv) Address = ${vpnGw}/${subnetClass} +MTU = ${pivpnMTU} ListenPort = ${pivpnPORT}" | $SUDO tee /etc/wireguard/wg0.conf &> /dev/null echo "::: Server config generated." } @@ -2091,7 +2129,7 @@ confNetwork(){ $SUDO 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 fi # 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 insert 1 allow "${pivpnPORT}"/"${pivpnPROTO}" comment allow-${VPN} >/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 diff --git a/examples/unattended_wireguard_example.conf b/examples/unattended_wireguard_example.conf index 2fb67a8..c8e354e 100644 --- a/examples/unattended_wireguard_example.conf +++ b/examples/unattended_wireguard_example.conf @@ -4,6 +4,7 @@ VPN=wireguard pivpnNET=10.6.0.0 subnetClass=24 ALLOWED_IPS="0.0.0.0/0, ::0/0" +pivpnMTU=1420 pivpnPORT=51820 pivpnDNS1=9.9.9.9 pivpnDNS2=149.112.112.112 diff --git a/scripts/openvpn/bash-completion b/scripts/openvpn/bash-completion index 1b9ef7e..db7540e 100644 --- a/scripts/openvpn/bash-completion +++ b/scripts/openvpn/bash-completion @@ -1,3 +1,4 @@ +#!/bin/bash _pivpn() { local cur prev opts diff --git a/scripts/openvpn/makeOVPN.sh b/scripts/openvpn/makeOVPN.sh index b03af64..5734f66 100755 --- a/scripts/openvpn/makeOVPN.sh +++ b/scripts/openvpn/makeOVPN.sh @@ -25,7 +25,7 @@ helpFunc() { echo "::: Commands:" echo "::: [none] Interactive mode" echo "::: nopass Create a client without a password" - echo "::: -n,--name Name for the Client (default: '"$(hostname)"')" + echo "::: -n,--name Name for the Client (default: \"$(hostname)\")" echo "::: -p,--password Password for the Client (no default)" echo "::: -d,--days Expire the certificate after specified number of days (default: 1080)" echo "::: -b,--bitwarden Create and save a client through Bitwarden" @@ -133,7 +133,7 @@ function useBitwarden() { # login and unlock vault printf "****Bitwarden Login****" printf "\n" - SESSION_KEY=`bw login --raw` + SESSION_KEY=$(bw login --raw) export BW_SESSION=$SESSION_KEY printf "Successfully Logged in!" printf "\n" @@ -168,7 +168,7 @@ function useBitwarden() { printf "Creating a PiVPN item for your vault..." printf "\n" # create a new item for your PiVPN Password - PASSWD=`bw generate -usln --length $LENGTH` + PASSWD=$(bw generate -usln --length $LENGTH) bw get template item | jq '.login.type = "1"'| jq '.name = "PiVPN"' | jq -r --arg NAME "$NAME" '.login.username = $NAME' | jq -r --arg PASSWD "$PASSWD" '.login.password = $PASSWD' | bw encode | bw create item bw logout @@ -422,7 +422,7 @@ 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 + shift $1 echo ${1-0}.${2-0}.${3-0}.${4-0} } diff --git a/scripts/openvpn/removeOVPN.sh b/scripts/openvpn/removeOVPN.sh index a77333b..ef58cb1 100755 --- a/scripts/openvpn/removeOVPN.sh +++ b/scripts/openvpn/removeOVPN.sh @@ -60,7 +60,7 @@ if [[ -z "${CERTS_TO_REVOKE}" ]]; then # Prevent printing "server" certificate CERTS[$i]=$(echo -e "${NAME}") fi - let i=i+1 + ((i++)) fi done <${INDEX} @@ -82,7 +82,7 @@ if [[ -z "${CERTS_TO_REVOKE}" ]]; then re='^[0-9]+$' if [[ ${NAME} =~ $re ]] ; then - NAME=${CERTS[$(($NAME))]} + NAME=${CERTS[$((NAME))]} fi for((x=1;x<=i;++x)); do @@ -104,7 +104,7 @@ else if [[ "${STATUS}" = "V" ]]; then NAME=$(echo -e "$line" | sed -e 's:.*/CN=::') CERTS[$i]=${NAME} - let i=i+1 + ((i++)) fi done <${INDEX} diff --git a/scripts/wireguard/bash-completion b/scripts/wireguard/bash-completion index ae57b41..2c18f9d 100644 --- a/scripts/wireguard/bash-completion +++ b/scripts/wireguard/bash-completion @@ -1,9 +1,9 @@ +#!/bin/bash _pivpn() { - local cur prev opts + local cur opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" dashopts="-a -c -d -l -qr -r -h -u -up -bk -off -on" opts="add clients debug list qrcode remove help uninstall update backup (temp) off (temp) on" if [ "${#COMP_WORDS[@]}" -eq 2 ] diff --git a/scripts/wireguard/clientSTAT.sh b/scripts/wireguard/clientSTAT.sh index f47e800..139b09d 100755 --- a/scripts/wireguard/clientSTAT.sh +++ b/scripts/wireguard/clientSTAT.sh @@ -2,7 +2,6 @@ # PiVPN: client status script CLIENTS_FILE="/etc/wireguard/configs/clients.txt" -CONF_FILE="/etc/wireguard/wg0.conf" if [ ! -s "$CLIENTS_FILE" ]; then echo "::: There are no clients to list" diff --git a/scripts/wireguard/disableCONF.sh b/scripts/wireguard/disableCONF.sh index 7d3d682..7595110 100755 --- a/scripts/wireguard/disableCONF.sh +++ b/scripts/wireguard/disableCONF.sh @@ -44,7 +44,7 @@ do shift done -cd /etc/wireguard +cd /etc/wireguard || exit if [ ! -s configs/clients.txt ]; then echo "::: There are no clients to change" exit 1 @@ -81,7 +81,7 @@ for CLIENT_NAME in "${CLIENTS_TO_CHANGE[@]}"; do re='^[0-9]+$' if [[ ${CLIENT_NAME} =~ $re ]] ; then - CLIENT_NAME=${LIST[$(($CLIENT_NAME -1))]} + CLIENT_NAME=${LIST[$((CLIENT_NAME -1))]} fi if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then diff --git a/scripts/wireguard/enableCONF.sh b/scripts/wireguard/enableCONF.sh index 4ce0cf7..82331fd 100755 --- a/scripts/wireguard/enableCONF.sh +++ b/scripts/wireguard/enableCONF.sh @@ -44,7 +44,7 @@ do shift done -cd /etc/wireguard +cd /etc/wireguard || exit if [ ! -s configs/clients.txt ]; then echo "::: There are no clients to change" exit 1 @@ -79,7 +79,7 @@ for CLIENT_NAME in "${CLIENTS_TO_CHANGE[@]}"; do re='^[0-9]+$' if [[ ${CLIENT_NAME} =~ $re ]] ; then - CLIENT_NAME=${LIST[$(($CLIENT_NAME -1))]} + CLIENT_NAME=${LIST[$((CLIENT_NAME -1))]} fi if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then diff --git a/scripts/wireguard/listCONF.sh b/scripts/wireguard/listCONF.sh index 150eb5a..c89bae3 100755 --- a/scripts/wireguard/listCONF.sh +++ b/scripts/wireguard/listCONF.sh @@ -1,6 +1,6 @@ #!/bin/bash -cd /etc/wireguard/configs +cd /etc/wireguard/configs || exit if [ ! -s clients.txt ]; then echo "::: There are no clients to list" exit 1 diff --git a/scripts/wireguard/makeCONF.sh b/scripts/wireguard/makeCONF.sh index 73bfd9b..abff296 100755 --- a/scripts/wireguard/makeCONF.sh +++ b/scripts/wireguard/makeCONF.sh @@ -53,7 +53,7 @@ if [ ! -d "${install_home}/configs" ]; then chmod 0750 "${install_home}/configs" fi -cd /etc/wireguard +cd /etc/wireguard || exit if [ -z "${CLIENT_NAME}" ]; then read -r -p "Enter a Name for the Client: " CLIENT_NAME @@ -94,11 +94,15 @@ done NET_REDUCED="${pivpnNET::-2}" -echo -n "[Interface] +echo "[Interface] PrivateKey = $(cat "keys/${CLIENT_NAME}_priv") -Address = ${NET_REDUCED}.${COUNT}/${subnetClass} -DNS = ${pivpnDNS1}" > "configs/${CLIENT_NAME}.conf" +Address = ${NET_REDUCED}.${COUNT}/${subnetClass}" > "configs/${CLIENT_NAME}.conf" +if [ -n "${pivpnMTU}" ]; then + echo "MTU = ${pivpnMTU}" >> "configs/${CLIENT_NAME}.conf" +fi + +echo -n "DNS = ${pivpnDNS1}" >> "configs/${CLIENT_NAME}.conf" if [ -n "${pivpnDNS2}" ]; then echo ", ${pivpnDNS2}" >> "configs/${CLIENT_NAME}.conf" else diff --git a/scripts/wireguard/pivpnDEBUG.sh b/scripts/wireguard/pivpnDEBUG.sh index 5f59f3e..6d8dd64 100755 --- a/scripts/wireguard/pivpnDEBUG.sh +++ b/scripts/wireguard/pivpnDEBUG.sh @@ -19,7 +19,7 @@ echo -e "::::\t \e[4mInstallation settings\e[0m \t ::::" sed "s/$pivpnHOST/REDACTED/" < ${setupVars} printf "=============================================\n" echo -e ":::: \e[4mServer configuration shown below\e[0m ::::" -cd /etc/wireguard/keys +cd /etc/wireguard/keys || exit cp ../wg0.conf ../wg0.tmp # Replace every key in the server configuration with just its file name for k in *; do diff --git a/scripts/wireguard/qrcodeCONF.sh b/scripts/wireguard/qrcodeCONF.sh index 6d980fe..c114752 100755 --- a/scripts/wireguard/qrcodeCONF.sh +++ b/scripts/wireguard/qrcodeCONF.sh @@ -27,7 +27,7 @@ do shift done -cd /etc/wireguard/configs +cd /etc/wireguard/configs || exit if [ ! -s clients.txt ]; then echo "::: There are no clients to show" exit 1 @@ -55,7 +55,7 @@ fi for CLIENT_NAME in "${CLIENTS_TO_SHOW[@]}"; do re='^[0-9]+$' if [[ ${CLIENT_NAME} =~ $re ]] ; then - CLIENT_NAME=${LIST[$(($CLIENT_NAME -1))]} + CLIENT_NAME=${LIST[$((CLIENT_NAME -1))]} fi if grep -qw "${CLIENT_NAME}" clients.txt; then echo -e "::: Showing client \e[1m${CLIENT_NAME}\e[0m below" diff --git a/scripts/wireguard/removeCONF.sh b/scripts/wireguard/removeCONF.sh index 95c6ffa..0de7671 100755 --- a/scripts/wireguard/removeCONF.sh +++ b/scripts/wireguard/removeCONF.sh @@ -40,7 +40,7 @@ do shift done -cd /etc/wireguard +cd /etc/wireguard || exit if [ ! -s configs/clients.txt ]; then echo "::: There are no clients to remove" exit 1 @@ -70,7 +70,7 @@ for CLIENT_NAME in "${CLIENTS_TO_REMOVE[@]}"; do re='^[0-9]+$' if [[ ${CLIENT_NAME} =~ $re ]] ; then - CLIENT_NAME=${LIST[$(($CLIENT_NAME -1))]} + CLIENT_NAME=${LIST[$((CLIENT_NAME -1))]} fi if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then