mirror of
https://github.com/pivpn/pivpn.git
synced 2024-12-18 19:00:15 +00:00
commit
96102d009c
18 changed files with 161 additions and 75 deletions
|
@ -28,7 +28,7 @@ jobs:
|
||||||
name: "Shellcheck lint"
|
name: "Shellcheck lint"
|
||||||
dist: linux
|
dist: linux
|
||||||
script:
|
script:
|
||||||
- shellcheck autoinstall/install.sh
|
- shellcheck auto_install/install.sh
|
||||||
- find scripts/ -type f -exec shellcheck {} \;
|
- find scripts/ -type f -exec shellcheck {} \;
|
||||||
|
|
||||||
- stage: test
|
- stage: test
|
||||||
|
|
|
@ -4,6 +4,19 @@ This file has the objective of describing the major changes for each merge from
|
||||||
|
|
||||||
Everytime Test branch is merged into master, a new entry should be created with the date and changes being merged.
|
Everytime Test branch is merged into master, a new entry should be created with the date and changes being merged.
|
||||||
|
|
||||||
|
## May 7th 2021
|
||||||
|
|
||||||
|
General code quality fixes
|
||||||
|
- #1253, #1254, #1256, #1272
|
||||||
|
Disabled progress bar when running unattended
|
||||||
|
- #1276
|
||||||
|
Added wireguard MTU support when setting up unattended
|
||||||
|
- #1278
|
||||||
|
Support for multiple setupVars while via unattended setup
|
||||||
|
- #1279
|
||||||
|
Fix for currupted QR code display in multiple fonts
|
||||||
|
- #1305
|
||||||
|
|
||||||
## Jan 26th 2021
|
## Jan 26th 2021
|
||||||
|
|
||||||
Fixed:
|
Fixed:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
![WireGuard + OpenVPN logo](logos.jpg)
|
![WireGuard + OpenVPN logo](logos.jpg)
|
||||||
|
|
||||||
**[Is pivpn.io down?](https://status.pivpn.io)** |
|
**[Is pivpn.io down?](https://stats.uptimerobot.com/8X64yTjrJO)** |
|
||||||
|
[![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) |
|
**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)
|
**Master:** [![Build Status](https://travis-ci.com/pivpn/pivpn.svg?branch=master)](https://travis-ci.com/pivpn/pivpn)
|
||||||
|
|
||||||
|
@ -107,7 +108,7 @@ Please be respectful and be aware that this is maintained with our free time!
|
||||||
|
|
||||||
for community support or general questions.
|
for community support or general questions.
|
||||||
Feel free to post on our subreddit <https://www.reddit.com/r/pivpn/>
|
Feel free to post on our subreddit <https://www.reddit.com/r/pivpn/>
|
||||||
You can also join #pivpn <ircs://freenode/pivpn> on freenode in IRC
|
You can also join #pivpn on [libera.chat](https://libera.chat) IRC network
|
||||||
|
|
||||||
For code related issues, code contributions, feature requests, feel free to open an issue here at github.
|
For code related issues, code contributions, feature requests, feel free to open an issue here at github.
|
||||||
We will classify the issues the best we can to keep things sorted.
|
We will classify the issues the best we can to keep things sorted.
|
||||||
|
|
|
@ -24,12 +24,10 @@ piholeSetupVars="/etc/pihole/setupVars.conf"
|
||||||
dnsmasqConfig="/etc/dnsmasq.d/02-pivpn.conf"
|
dnsmasqConfig="/etc/dnsmasq.d/02-pivpn.conf"
|
||||||
|
|
||||||
dhcpcdFile="/etc/dhcpcd.conf"
|
dhcpcdFile="/etc/dhcpcd.conf"
|
||||||
subnetClass="24"
|
|
||||||
debianOvpnUserGroup="openvpn:openvpn"
|
debianOvpnUserGroup="openvpn:openvpn"
|
||||||
|
|
||||||
######## PKG Vars ########
|
######## PKG Vars ########
|
||||||
PKG_MANAGER="apt-get"
|
PKG_MANAGER="apt-get"
|
||||||
PKG_CACHE="/var/lib/apt/lists/"
|
|
||||||
### FIXME: quoting UPDATE_PKG_CACHE and PKG_INSTALL hangs the script, shellcheck SC2086
|
### FIXME: quoting UPDATE_PKG_CACHE and PKG_INSTALL hangs the script, shellcheck SC2086
|
||||||
UPDATE_PKG_CACHE="${PKG_MANAGER} update -y"
|
UPDATE_PKG_CACHE="${PKG_MANAGER} update -y"
|
||||||
PKG_INSTALL="${PKG_MANAGER} --yes --no-install-recommends install"
|
PKG_INSTALL="${PKG_MANAGER} --yes --no-install-recommends install"
|
||||||
|
@ -439,8 +437,10 @@ preconfigurePackages(){
|
||||||
BASE_DEPS+=(dhcpcd5)
|
BASE_DEPS+=(dhcpcd5)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AVAILABLE_OPENVPN="$(apt-cache policy openvpn | grep -m1 'Candidate: ' | grep -v '(none)' | awk '{print $2}')"
|
|
||||||
DPKG_ARCH="$(dpkg --print-architecture)"
|
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
|
NEED_OPENVPN_REPO=0
|
||||||
|
|
||||||
# We require OpenVPN 2.4 or later for ECC support. If not available in the
|
# We require OpenVPN 2.4 or later for ECC support. If not available in the
|
||||||
|
@ -462,6 +462,7 @@ preconfigurePackages(){
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AVAILABLE_WIREGUARD="$(apt-cache policy wireguard | grep -m1 'Candidate: ' | grep -v '(none)' | awk '{print $2}')"
|
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
|
# 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
|
# it has not been build via DKMS or manually (installing via wireguard-dkms does not
|
||||||
|
@ -535,8 +536,13 @@ installDependentPackages(){
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
local APTLOGFILE="$($SUDO mktemp)"
|
local APTLOGFILE
|
||||||
|
APTLOGFILE="$($SUDO mktemp)"
|
||||||
|
|
||||||
|
if [ "${runUnattended}" = 'true' ]; then
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
$SUDO ${PKG_INSTALL} "${TO_INSTALL[@]}"
|
||||||
|
else
|
||||||
if command -v debconf-apt-progress > /dev/null; then
|
if command -v debconf-apt-progress > /dev/null; then
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
$SUDO debconf-apt-progress --logfile "${APTLOGFILE}" -- ${PKG_INSTALL} "${TO_INSTALL[@]}"
|
$SUDO debconf-apt-progress --logfile "${APTLOGFILE}" -- ${PKG_INSTALL} "${TO_INSTALL[@]}"
|
||||||
|
@ -544,6 +550,7 @@ installDependentPackages(){
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
$SUDO ${PKG_INSTALL} "${TO_INSTALL[@]}"
|
$SUDO ${PKG_INSTALL} "${TO_INSTALL[@]}"
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
local FAILED=0
|
local FAILED=0
|
||||||
|
|
||||||
|
@ -685,7 +692,8 @@ validIP(){
|
||||||
}
|
}
|
||||||
|
|
||||||
validIPAndNetmask(){
|
validIPAndNetmask(){
|
||||||
local ip=$1
|
local ip
|
||||||
|
ip=$1
|
||||||
local stat=1
|
local stat=1
|
||||||
ip="${ip/\//.}"
|
ip="${ip/\//.}"
|
||||||
|
|
||||||
|
@ -764,9 +772,11 @@ getStaticIPv4Settings() {
|
||||||
echo "::: Skipping setting static IP address"
|
echo "::: Skipping setting static IP address"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "dhcpReserv=${dhcpReserv}" >> ${tempsetupVarsFile}
|
{
|
||||||
echo "IPv4addr=${IPv4addr}" >> ${tempsetupVarsFile}
|
echo "dhcpReserv=${dhcpReserv}"
|
||||||
echo "IPv4gw=${IPv4gw}" >> ${tempsetupVarsFile}
|
echo "IPv4addr=${IPv4addr}"
|
||||||
|
echo "IPv4gw=${IPv4gw}"
|
||||||
|
} >> ${tempsetupVarsFile}
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -1056,10 +1066,18 @@ installPiVPN(){
|
||||||
$SUDO mkdir -p /etc/pivpn/
|
$SUDO mkdir -p /etc/pivpn/
|
||||||
askWhichVPN
|
askWhichVPN
|
||||||
|
|
||||||
|
# Allow custom subnetClass via unattend setupVARs file. Use default if not provided.
|
||||||
|
if [ -z "$subnetClass" ]; then
|
||||||
|
subnetClass="24"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$VPN" = "openvpn" ]; then
|
if [ "$VPN" = "openvpn" ]; then
|
||||||
|
|
||||||
pivpnDEV="tun0"
|
pivpnDEV="tun0"
|
||||||
|
# Allow custom NET via unattend setupVARs file. Use default if not provided.
|
||||||
|
if [ -z "$pivpnNET" ]; then
|
||||||
pivpnNET="10.8.0.0"
|
pivpnNET="10.8.0.0"
|
||||||
|
fi
|
||||||
vpnGw="${pivpnNET/.0.0/.0.1}"
|
vpnGw="${pivpnNET/.0.0/.0.1}"
|
||||||
|
|
||||||
askAboutCustomizing
|
askAboutCustomizing
|
||||||
|
@ -1081,11 +1099,24 @@ installPiVPN(){
|
||||||
# set the protocol here.
|
# set the protocol here.
|
||||||
pivpnPROTO="udp"
|
pivpnPROTO="udp"
|
||||||
pivpnDEV="wg0"
|
pivpnDEV="wg0"
|
||||||
|
# Allow custom NET via unattend setupVARs file. Use default if not provided.
|
||||||
|
if [ -z "$pivpnNET" ]; then
|
||||||
pivpnNET="10.6.0.0"
|
pivpnNET="10.6.0.0"
|
||||||
|
fi
|
||||||
vpnGw="${pivpnNET/.0.0/.0.1}"
|
vpnGw="${pivpnNET/.0.0/.0.1}"
|
||||||
|
# Allow custom allowed IPs via unattend setupVARs file. Use default if not provided.
|
||||||
|
if [ -z "$ALLOWED_IPS" ]; then
|
||||||
# Forward all traffic through PiVPN (i.e. full-tunnel), may be modified by
|
# Forward all traffic through PiVPN (i.e. full-tunnel), may be modified by
|
||||||
# the user after the installation.
|
# the user after the installation.
|
||||||
ALLOWED_IPS="0.0.0.0/0, ::0/0"
|
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
|
CUSTOMIZE=0
|
||||||
|
|
||||||
installWireGuard
|
installWireGuard
|
||||||
|
@ -1096,13 +1127,16 @@ installPiVPN(){
|
||||||
confNetwork
|
confNetwork
|
||||||
|
|
||||||
echo "pivpnPROTO=${pivpnPROTO}" >> ${tempsetupVarsFile}
|
echo "pivpnPROTO=${pivpnPROTO}" >> ${tempsetupVarsFile}
|
||||||
|
echo "pivpnMTU=${pivpnMTU}" >> ${tempsetupVarsFile}
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "pivpnDEV=${pivpnDEV}" >> ${tempsetupVarsFile}
|
{
|
||||||
echo "pivpnNET=${pivpnNET}" >> ${tempsetupVarsFile}
|
echo "pivpnDEV=${pivpnDEV}"
|
||||||
echo "subnetClass=${subnetClass}" >> ${tempsetupVarsFile}
|
echo "pivpnNET=${pivpnNET}"
|
||||||
echo "ALLOWED_IPS=\"${ALLOWED_IPS}\"" >> ${tempsetupVarsFile}
|
echo "subnetClass=${subnetClass}"
|
||||||
|
echo "ALLOWED_IPS=\"${ALLOWED_IPS}\""
|
||||||
|
} >> ${tempsetupVarsFile}
|
||||||
}
|
}
|
||||||
|
|
||||||
askWhichVPN(){
|
askWhichVPN(){
|
||||||
|
@ -1230,12 +1264,16 @@ installWireGuard(){
|
||||||
exit 1
|
exit 1
|
||||||
else
|
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 (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 [ "${runUnattended}" = 'true' ]; then
|
||||||
|
$SUDO ${PKG_MANAGER} upgrade -y
|
||||||
|
else
|
||||||
if command -v debconf-apt-progress &> /dev/null; then
|
if command -v debconf-apt-progress &> /dev/null; then
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
$SUDO debconf-apt-progress -- ${PKG_MANAGER} upgrade -y
|
$SUDO debconf-apt-progress -- ${PKG_MANAGER} upgrade -y
|
||||||
else
|
else
|
||||||
$SUDO ${PKG_MANAGER} upgrade -y
|
$SUDO ${PKG_MANAGER} upgrade -y
|
||||||
fi
|
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
|
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}
|
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}
|
||||||
printf "\\nRebooting system...\\n"
|
printf "\\nRebooting system...\\n"
|
||||||
|
@ -1254,7 +1292,7 @@ installWireGuard(){
|
||||||
echo "::: Installing WireGuard from Debian package... "
|
echo "::: Installing WireGuard from Debian package... "
|
||||||
|
|
||||||
if [ -z "$AVAILABLE_WIREGUARD" ]; then
|
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
|
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
|
# Do not upgrade packages from the bullseye repository except for wireguard
|
||||||
|
@ -1266,7 +1304,13 @@ installWireGuard(){
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# qrencode is used to generate qrcodes from config file, for use with mobile clients
|
# 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[@]
|
installDependentPackages PIVPN_DEPS[@]
|
||||||
|
|
||||||
elif [ "$PLAT" = "Debian" ]; then
|
elif [ "$PLAT" = "Debian" ]; then
|
||||||
|
@ -1274,7 +1318,7 @@ installWireGuard(){
|
||||||
echo "::: Installing WireGuard from Debian package... "
|
echo "::: Installing WireGuard from Debian package... "
|
||||||
|
|
||||||
if [ -z "$AVAILABLE_WIREGUARD" ]; then
|
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
|
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
|
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
|
||||||
|
@ -1737,9 +1781,11 @@ askEncryption(){
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}" >> ${tempsetupVarsFile}
|
{
|
||||||
echo "pivpnENCRYPT=${pivpnENCRYPT}" >> ${tempsetupVarsFile}
|
echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}"
|
||||||
echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}" >> ${tempsetupVarsFile}
|
echo "pivpnENCRYPT=${pivpnENCRYPT}"
|
||||||
|
echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}"
|
||||||
|
} >> ${tempsetupVarsFile}
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -1747,9 +1793,11 @@ askEncryption(){
|
||||||
if [ "$VPN" = "openvpn" ]; then
|
if [ "$VPN" = "openvpn" ]; then
|
||||||
TWO_POINT_FOUR=1
|
TWO_POINT_FOUR=1
|
||||||
pivpnENCRYPT=256
|
pivpnENCRYPT=256
|
||||||
echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}" >> ${tempsetupVarsFile}
|
{
|
||||||
echo "pivpnENCRYPT=${pivpnENCRYPT}" >> ${tempsetupVarsFile}
|
echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}"
|
||||||
echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}" >> ${tempsetupVarsFile}
|
echo "pivpnENCRYPT=${pivpnENCRYPT}"
|
||||||
|
echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}"
|
||||||
|
} >> ${tempsetupVarsFile}
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -1782,15 +1830,17 @@ askEncryption(){
|
||||||
USE_PREDEFINED_DH_PARAM=0
|
USE_PREDEFINED_DH_PARAM=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}" >> ${tempsetupVarsFile}
|
{
|
||||||
echo "pivpnENCRYPT=${pivpnENCRYPT}" >> ${tempsetupVarsFile}
|
echo "TWO_POINT_FOUR=${TWO_POINT_FOUR}"
|
||||||
echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}" >> ${tempsetupVarsFile}
|
echo "pivpnENCRYPT=${pivpnENCRYPT}"
|
||||||
|
echo "USE_PREDEFINED_DH_PARAM=${USE_PREDEFINED_DH_PARAM}"
|
||||||
|
} >> ${tempsetupVarsFile}
|
||||||
}
|
}
|
||||||
|
|
||||||
cidrToMask(){
|
cidrToMask(){
|
||||||
# Source: https://stackoverflow.com/a/20767392
|
# Source: https://stackoverflow.com/a/20767392
|
||||||
set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
|
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}
|
echo ${1-0}.${2-0}.${3-0}.${4-0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2047,6 +2097,7 @@ confWireGuard(){
|
||||||
echo "[Interface]
|
echo "[Interface]
|
||||||
PrivateKey = $($SUDO cat /etc/wireguard/keys/server_priv)
|
PrivateKey = $($SUDO cat /etc/wireguard/keys/server_priv)
|
||||||
Address = ${vpnGw}/${subnetClass}
|
Address = ${vpnGw}/${subnetClass}
|
||||||
|
MTU = ${pivpnMTU}
|
||||||
ListenPort = ${pivpnPORT}" | $SUDO tee /etc/wireguard/wg0.conf &> /dev/null
|
ListenPort = ${pivpnPORT}" | $SUDO tee /etc/wireguard/wg0.conf &> /dev/null
|
||||||
echo "::: Server config generated."
|
echo "::: Server config generated."
|
||||||
}
|
}
|
||||||
|
@ -2078,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
|
$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
|
fi
|
||||||
# Insert rules at the beginning of the chain (in case there are other rules that may drop the traffic)
|
# 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 route insert 1 allow in on "${pivpnDEV}" from "${pivpnNET}/${subnetClass}" out on "${IPv4dev}" to any >/dev/null
|
||||||
|
|
||||||
$SUDO ufw reload >/dev/null
|
$SUDO ufw reload >/dev/null
|
||||||
|
|
|
@ -4,6 +4,8 @@ IPv4gw=192.168.23.1
|
||||||
dhcpReserv=0
|
dhcpReserv=0
|
||||||
install_user=pi
|
install_user=pi
|
||||||
VPN=openvpn
|
VPN=openvpn
|
||||||
|
pivpnNET=10.8.0.0
|
||||||
|
subnetClass=24
|
||||||
pivpnPROTO=udp
|
pivpnPROTO=udp
|
||||||
pivpnPORT=1194
|
pivpnPORT=1194
|
||||||
pivpnDNS1=9.9.9.9
|
pivpnDNS1=9.9.9.9
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
IPv4dev=eth0
|
IPv4dev=eth0
|
||||||
IPv4addr=192.168.23.211/24
|
|
||||||
IPv4gw=192.168.23.1
|
|
||||||
dhcpReserv=0
|
|
||||||
install_user=pi
|
install_user=pi
|
||||||
VPN=wireguard
|
VPN=wireguard
|
||||||
|
pivpnNET=10.6.0.0
|
||||||
|
subnetClass=24
|
||||||
|
ALLOWED_IPS="0.0.0.0/0, ::0/0"
|
||||||
|
pivpnMTU=1420
|
||||||
pivpnPORT=51820
|
pivpnPORT=51820
|
||||||
pivpnDNS1=9.9.9.9
|
pivpnDNS1=9.9.9.9
|
||||||
pivpnDNS2=149.112.112.112
|
pivpnDNS2=149.112.112.112
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
_pivpn()
|
_pivpn()
|
||||||
{
|
{
|
||||||
local cur prev opts
|
local cur prev opts
|
||||||
|
|
|
@ -25,7 +25,7 @@ helpFunc() {
|
||||||
echo "::: Commands:"
|
echo "::: Commands:"
|
||||||
echo "::: [none] Interactive mode"
|
echo "::: [none] Interactive mode"
|
||||||
echo "::: nopass Create a client without a password"
|
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 "::: -p,--password Password for the Client (no default)"
|
||||||
echo "::: -d,--days Expire the certificate after specified number of days (default: 1080)"
|
echo "::: -d,--days Expire the certificate after specified number of days (default: 1080)"
|
||||||
echo "::: -b,--bitwarden Create and save a client through Bitwarden"
|
echo "::: -b,--bitwarden Create and save a client through Bitwarden"
|
||||||
|
@ -133,7 +133,7 @@ function useBitwarden() {
|
||||||
# login and unlock vault
|
# login and unlock vault
|
||||||
printf "****Bitwarden Login****"
|
printf "****Bitwarden Login****"
|
||||||
printf "\n"
|
printf "\n"
|
||||||
SESSION_KEY=`bw login --raw`
|
SESSION_KEY=$(bw login --raw)
|
||||||
export BW_SESSION=$SESSION_KEY
|
export BW_SESSION=$SESSION_KEY
|
||||||
printf "Successfully Logged in!"
|
printf "Successfully Logged in!"
|
||||||
printf "\n"
|
printf "\n"
|
||||||
|
@ -168,7 +168,7 @@ function useBitwarden() {
|
||||||
printf "Creating a PiVPN item for your vault..."
|
printf "Creating a PiVPN item for your vault..."
|
||||||
printf "\n"
|
printf "\n"
|
||||||
# create a new item for your PiVPN Password
|
# 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 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
|
bw logout
|
||||||
|
|
||||||
|
@ -422,7 +422,7 @@ fi
|
||||||
cidrToMask(){
|
cidrToMask(){
|
||||||
# Source: https://stackoverflow.com/a/20767392
|
# Source: https://stackoverflow.com/a/20767392
|
||||||
set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
|
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}
|
echo ${1-0}.${2-0}.${3-0}.${4-0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ if [[ -z "${CERTS_TO_REVOKE}" ]]; then
|
||||||
# Prevent printing "server" certificate
|
# Prevent printing "server" certificate
|
||||||
CERTS[$i]=$(echo -e "${NAME}")
|
CERTS[$i]=$(echo -e "${NAME}")
|
||||||
fi
|
fi
|
||||||
let i=i+1
|
((i++))
|
||||||
fi
|
fi
|
||||||
done <${INDEX}
|
done <${INDEX}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ if [[ -z "${CERTS_TO_REVOKE}" ]]; then
|
||||||
|
|
||||||
re='^[0-9]+$'
|
re='^[0-9]+$'
|
||||||
if [[ ${NAME} =~ $re ]] ; then
|
if [[ ${NAME} =~ $re ]] ; then
|
||||||
NAME=${CERTS[$(($NAME))]}
|
NAME=${CERTS[$((NAME))]}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for((x=1;x<=i;++x)); do
|
for((x=1;x<=i;++x)); do
|
||||||
|
@ -104,7 +104,7 @@ else
|
||||||
if [[ "${STATUS}" = "V" ]]; then
|
if [[ "${STATUS}" = "V" ]]; then
|
||||||
NAME=$(echo -e "$line" | sed -e 's:.*/CN=::')
|
NAME=$(echo -e "$line" | sed -e 's:.*/CN=::')
|
||||||
CERTS[$i]=${NAME}
|
CERTS[$i]=${NAME}
|
||||||
let i=i+1
|
((i++))
|
||||||
fi
|
fi
|
||||||
done <${INDEX}
|
done <${INDEX}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
#!/bin/bash
|
||||||
_pivpn()
|
_pivpn()
|
||||||
{
|
{
|
||||||
local cur prev opts
|
local cur opts
|
||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
|
||||||
dashopts="-a -c -d -l -qr -r -h -u -up -bk -off -on"
|
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"
|
opts="add clients debug list qrcode remove help uninstall update backup (temp) off (temp) on"
|
||||||
if [ "${#COMP_WORDS[@]}" -eq 2 ]
|
if [ "${#COMP_WORDS[@]}" -eq 2 ]
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
# PiVPN: client status script
|
# PiVPN: client status script
|
||||||
|
|
||||||
CLIENTS_FILE="/etc/wireguard/configs/clients.txt"
|
CLIENTS_FILE="/etc/wireguard/configs/clients.txt"
|
||||||
CONF_FILE="/etc/wireguard/wg0.conf"
|
|
||||||
|
|
||||||
if [ ! -s "$CLIENTS_FILE" ]; then
|
if [ ! -s "$CLIENTS_FILE" ]; then
|
||||||
echo "::: There are no clients to list"
|
echo "::: There are no clients to list"
|
||||||
|
|
|
@ -44,7 +44,7 @@ do
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
cd /etc/wireguard
|
cd /etc/wireguard || exit
|
||||||
if [ ! -s configs/clients.txt ]; then
|
if [ ! -s configs/clients.txt ]; then
|
||||||
echo "::: There are no clients to change"
|
echo "::: There are no clients to change"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -81,7 +81,7 @@ for CLIENT_NAME in "${CLIENTS_TO_CHANGE[@]}"; do
|
||||||
|
|
||||||
re='^[0-9]+$'
|
re='^[0-9]+$'
|
||||||
if [[ ${CLIENT_NAME} =~ $re ]] ; then
|
if [[ ${CLIENT_NAME} =~ $re ]] ; then
|
||||||
CLIENT_NAME=${LIST[$(($CLIENT_NAME -1))]}
|
CLIENT_NAME=${LIST[$((CLIENT_NAME -1))]}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then
|
if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then
|
||||||
|
|
|
@ -44,7 +44,7 @@ do
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
cd /etc/wireguard
|
cd /etc/wireguard || exit
|
||||||
if [ ! -s configs/clients.txt ]; then
|
if [ ! -s configs/clients.txt ]; then
|
||||||
echo "::: There are no clients to change"
|
echo "::: There are no clients to change"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -79,7 +79,7 @@ for CLIENT_NAME in "${CLIENTS_TO_CHANGE[@]}"; do
|
||||||
|
|
||||||
re='^[0-9]+$'
|
re='^[0-9]+$'
|
||||||
if [[ ${CLIENT_NAME} =~ $re ]] ; then
|
if [[ ${CLIENT_NAME} =~ $re ]] ; then
|
||||||
CLIENT_NAME=${LIST[$(($CLIENT_NAME -1))]}
|
CLIENT_NAME=${LIST[$((CLIENT_NAME -1))]}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then
|
if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
cd /etc/wireguard/configs
|
cd /etc/wireguard/configs || exit
|
||||||
if [ ! -s clients.txt ]; then
|
if [ ! -s clients.txt ]; then
|
||||||
echo "::: There are no clients to list"
|
echo "::: There are no clients to list"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
@ -53,7 +53,7 @@ if [ ! -d "${install_home}/configs" ]; then
|
||||||
chmod 0750 "${install_home}/configs"
|
chmod 0750 "${install_home}/configs"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd /etc/wireguard
|
cd /etc/wireguard || exit
|
||||||
|
|
||||||
if [ -z "${CLIENT_NAME}" ]; then
|
if [ -z "${CLIENT_NAME}" ]; then
|
||||||
read -r -p "Enter a Name for the Client: " CLIENT_NAME
|
read -r -p "Enter a Name for the Client: " CLIENT_NAME
|
||||||
|
@ -64,6 +64,11 @@ if [[ "${CLIENT_NAME}" =~ [^a-zA-Z0-9.@_-] ]]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "${CLIENT_NAME:0:1}" == "-" ]]; then
|
||||||
|
echo "Name cannot start with -"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ "${CLIENT_NAME}" =~ ^[0-9]+$ ]]; then
|
if [[ "${CLIENT_NAME}" =~ ^[0-9]+$ ]]; then
|
||||||
echo "Names cannot be integers."
|
echo "Names cannot be integers."
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -94,11 +99,15 @@ done
|
||||||
|
|
||||||
NET_REDUCED="${pivpnNET::-2}"
|
NET_REDUCED="${pivpnNET::-2}"
|
||||||
|
|
||||||
echo -n "[Interface]
|
echo "[Interface]
|
||||||
PrivateKey = $(cat "keys/${CLIENT_NAME}_priv")
|
PrivateKey = $(cat "keys/${CLIENT_NAME}_priv")
|
||||||
Address = ${NET_REDUCED}.${COUNT}/${subnetClass}
|
Address = ${NET_REDUCED}.${COUNT}/${subnetClass}" > "configs/${CLIENT_NAME}.conf"
|
||||||
DNS = ${pivpnDNS1}" > "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
|
if [ -n "${pivpnDNS2}" ]; then
|
||||||
echo ", ${pivpnDNS2}" >> "configs/${CLIENT_NAME}.conf"
|
echo ", ${pivpnDNS2}" >> "configs/${CLIENT_NAME}.conf"
|
||||||
else
|
else
|
||||||
|
|
|
@ -19,7 +19,7 @@ echo -e "::::\t \e[4mInstallation settings\e[0m \t ::::"
|
||||||
sed "s/$pivpnHOST/REDACTED/" < ${setupVars}
|
sed "s/$pivpnHOST/REDACTED/" < ${setupVars}
|
||||||
printf "=============================================\n"
|
printf "=============================================\n"
|
||||||
echo -e ":::: \e[4mServer configuration shown below\e[0m ::::"
|
echo -e ":::: \e[4mServer configuration shown below\e[0m ::::"
|
||||||
cd /etc/wireguard/keys
|
cd /etc/wireguard/keys || exit
|
||||||
cp ../wg0.conf ../wg0.tmp
|
cp ../wg0.conf ../wg0.tmp
|
||||||
# Replace every key in the server configuration with just its file name
|
# Replace every key in the server configuration with just its file name
|
||||||
for k in *; do
|
for k in *; do
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
helpFunc(){
|
helpFunc(){
|
||||||
echo "::: Show the qrcode of a client for use with the mobile app"
|
echo "::: Show the qrcode of a client for use with the mobile app"
|
||||||
echo ":::"
|
echo ":::"
|
||||||
echo "::: Usage: pivpn <-qr|qrcode> [-h|--help] [<client-1>] ... [<client-n>] ..."
|
echo "::: Usage: pivpn <-qr|qrcode> [-h|--help] [Options] [<client-1>] ... [<client-n>] ..."
|
||||||
echo ":::"
|
echo ":::"
|
||||||
|
echo "::: Options:"
|
||||||
|
echo "::: -a256|ansi256 Shows QR Code in ansi256 characters"
|
||||||
echo "::: Commands:"
|
echo "::: Commands:"
|
||||||
echo "::: [none] Interactive mode"
|
echo "::: [none] Interactive mode"
|
||||||
echo "::: <client> Client(s) to show"
|
echo "::: <client> Client(s) to show"
|
||||||
|
@ -12,6 +14,7 @@ helpFunc(){
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse input arguments
|
# Parse input arguments
|
||||||
|
encoding="ansiutf8"
|
||||||
while test $# -gt 0
|
while test $# -gt 0
|
||||||
do
|
do
|
||||||
_key="$1"
|
_key="$1"
|
||||||
|
@ -20,6 +23,9 @@ do
|
||||||
helpFunc
|
helpFunc
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
|
-a256|--ansi256)
|
||||||
|
encoding="ansi256"
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
CLIENTS_TO_SHOW+=("$1")
|
CLIENTS_TO_SHOW+=("$1")
|
||||||
;;
|
;;
|
||||||
|
@ -27,20 +33,20 @@ do
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
cd /etc/wireguard/configs
|
cd /etc/wireguard/configs || exit
|
||||||
if [ ! -s clients.txt ]; then
|
if [ ! -s clients.txt ]; then
|
||||||
echo "::: There are no clients to show"
|
echo "::: There are no clients to show"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
LIST=($(awk '{print $1}' clients.txt))
|
mapfile -t LIST < <(awk '{print $1}' clients.txt)
|
||||||
if [ "${#CLIENTS_TO_SHOW[@]}" -eq 0 ]; then
|
if [ "${#CLIENTS_TO_SHOW[@]}" -eq 0 ]; then
|
||||||
|
|
||||||
echo -e "::\e[4m Client list \e[0m::"
|
echo -e "::\e[4m Client list \e[0m::"
|
||||||
len=${#LIST[@]}
|
len=${#LIST[@]}
|
||||||
COUNTER=1
|
COUNTER=1
|
||||||
while [ $COUNTER -le ${len} ]; do
|
while [ $COUNTER -le "${len}" ]; do
|
||||||
printf "%0${#len}s) %s\r\n" ${COUNTER} ${LIST[(($COUNTER-1))]}
|
printf "%0${#len}s) %s\r\n" "${COUNTER}" "${LIST[(($COUNTER-1))]}"
|
||||||
((COUNTER++))
|
((COUNTER++))
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@ -54,13 +60,16 @@ fi
|
||||||
|
|
||||||
for CLIENT_NAME in "${CLIENTS_TO_SHOW[@]}"; do
|
for CLIENT_NAME in "${CLIENTS_TO_SHOW[@]}"; do
|
||||||
re='^[0-9]+$'
|
re='^[0-9]+$'
|
||||||
if [[ ${CLIENT_NAME} =~ $re ]] ; then
|
if [[ ${CLIENT_NAME:0:1} == "-" ]]; then
|
||||||
CLIENT_NAME=${LIST[$(($CLIENT_NAME -1))]}
|
echo "${CLIENT_NAME} is not a valid client name or option"
|
||||||
|
exit 1
|
||||||
|
elif [[ ${CLIENT_NAME} =~ $re ]] ; then
|
||||||
|
CLIENT_NAME=${LIST[$((CLIENT_NAME -1))]}
|
||||||
fi
|
fi
|
||||||
if grep -qw "${CLIENT_NAME}" clients.txt; then
|
if grep -qw "${CLIENT_NAME}" clients.txt; then
|
||||||
echo -e "::: Showing client \e[1m${CLIENT_NAME}\e[0m below"
|
echo -e "::: Showing client \e[1m${CLIENT_NAME}\e[0m below"
|
||||||
echo "====================================================================="
|
echo "====================================================================="
|
||||||
qrencode -t ansiutf8 < "${CLIENT_NAME}.conf"
|
qrencode -t "${encoding}" < "${CLIENT_NAME}.conf"
|
||||||
echo "====================================================================="
|
echo "====================================================================="
|
||||||
else
|
else
|
||||||
echo -e "::: \e[1m${CLIENT_NAME}\e[0m does not exist"
|
echo -e "::: \e[1m${CLIENT_NAME}\e[0m does not exist"
|
||||||
|
|
|
@ -40,7 +40,7 @@ do
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
cd /etc/wireguard
|
cd /etc/wireguard || exit
|
||||||
if [ ! -s configs/clients.txt ]; then
|
if [ ! -s configs/clients.txt ]; then
|
||||||
echo "::: There are no clients to remove"
|
echo "::: There are no clients to remove"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -70,7 +70,7 @@ for CLIENT_NAME in "${CLIENTS_TO_REMOVE[@]}"; do
|
||||||
|
|
||||||
re='^[0-9]+$'
|
re='^[0-9]+$'
|
||||||
if [[ ${CLIENT_NAME} =~ $re ]] ; then
|
if [[ ${CLIENT_NAME} =~ $re ]] ; then
|
||||||
CLIENT_NAME=${LIST[$(($CLIENT_NAME -1))]}
|
CLIENT_NAME=${LIST[$((CLIENT_NAME -1))]}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then
|
if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then
|
||||||
|
|
Loading…
Reference in a new issue