Added Alpine Linux support (#1567)

This commit is contained in:
Giulio Coa 2022-07-26 15:20:35 +02:00 committed by GitHub
parent 718d3df573
commit edb36c08f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 852 additions and 459 deletions

View file

@ -25,7 +25,7 @@ piholeSetupVars="/etc/pihole/setupVars.conf"
dnsmasqConfig="/etc/dnsmasq.d/02-pivpn.conf"
dhcpcdFile="/etc/dhcpcd.conf"
debianOvpnUserGroup="openvpn:openvpn"
ovpnUserGroup="openvpn:openvpn"
######## PKG Vars ########
PKG_MANAGER="apt-get"
@ -33,10 +33,14 @@ PKG_MANAGER="apt-get"
UPDATE_PKG_CACHE="${PKG_MANAGER} update -y"
PKG_INSTALL="${PKG_MANAGER} --yes --no-install-recommends install"
PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
CHECK_PKG_INSTALLED='dpkg-query -s'
# Dependencies that are required by the script, regardless of the VPN protocol chosen
BASE_DEPS=(git tar curl grep dnsutils grepcidr whiptail net-tools bsdmainutils bash-completion)
BASE_DEPS_ALPINE=(git grep bind-tools newt net-tools bash-completion coreutils openssl)
BASE_DEPS_ALPINE+=(util-linux openrc iptables ip6tables coreutils sed perl)
# Dependencies that where actually installed by the script. For example if the script requires
# grep and dnsutils but dnsutils is already installed, we save grep here. This way when uninstalling
# PiVPN we won't prompt to remove packages that may have been installed by the user for other reasons
@ -95,11 +99,11 @@ export LC_ALL=C
main(){
# Pre install checks and configs
distroCheck
rootCheck
flagsCheck "$@"
unattendedCheck
checkExistingInstall "$@"
distroCheck
checkHostname
# Verify there is enough disk space for the install
if [[ "${skipSpaceCheck}" == true ]]; then
@ -110,7 +114,13 @@ main(){
updatePackageCache
notifyPackageUpdatesAvailable
preconfigurePackages
installDependentPackages BASE_DEPS[@]
if [ "${PLAT}" == 'Alpine' ]; then
installDependentPackages BASE_DEPS_ALPINE[@]
else
installDependentPackages BASE_DEPS[@]
fi
welcomeDialogs
if [ "$pivpnforceipv6" == "1" ]; then
@ -161,13 +171,13 @@ rootCheck(){
######## FIRST CHECK ########
# Must be root to install
echo ":::"
if [[ $EUID -eq 0 ]];then
if [[ $EUID -eq 0 ]]; then
echo "::: You are root."
else
echo "::: sudo will be used for the install."
# Check if it is actually installed
# If it isn't, exit because the install cannot complete
if [[ $(dpkg-query -s sudo) ]];then
if eval "${CHECK_PKG_INSTALLED} sudo" &> /dev/null; then
export SUDO="sudo"
export SUDOE="sudo -E"
else
@ -216,9 +226,9 @@ unattendedCheck(){
checkExistingInstall(){
# see which setup already exists
if [ -r "${setupConfigDir}/wireguard/${setupVarsFile}" ]; then
setupVars="${setupConfigDir}/wireguard/${setupVarsFile}"
setupVars="${setupConfigDir}/wireguard/${setupVarsFile}"
elif [ -r "${setupConfigDir}/openvpn/${setupVarsFile}" ]; then
setupVars="${setupConfigDir}/openvpn/${setupVarsFile}"
setupVars="${setupConfigDir}/openvpn/${setupVarsFile}"
fi
if [ -r "$setupVars" ]; then
@ -283,6 +293,11 @@ distroCheck(){
VER="$VERSION_ID"
declare -A VER_MAP=(["9"]="stretch" ["10"]="buster" ["11"]="bullseye" ["16.04"]="xenial" ["18.04"]="bionic" ["20.04"]="focal")
OSCN=${VER_MAP["${VER}"]}
# Alpine support
if [ -z "${OSCN}" ]; then
OSCN="${VER}"
fi
fi
case ${PLAT} in
@ -296,6 +311,13 @@ distroCheck(){
;;
esac
;;
Alpine)
PKG_MANAGER='apk'
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
PKG_INSTALL="${PKG_MANAGER} --no-cache add"
PKG_COUNT="${PKG_MANAGER} list -u | wc -l || true"
CHECK_PKG_INSTALLED="${PKG_MANAGER} --no-cache info -e"
;;
*)
noOSSupport
;;
@ -351,7 +373,7 @@ checkHostname(){
fi
until [[ ${#host_name} -le 28 && $host_name =~ ^[a-zA-Z0-9][a-zA-Z0-9-]{1,28}$ ]]; do
host_name=$(whiptail --inputbox "Your hostname is too long.\\nEnter new hostname with less then 28 characters\\nNo special characters allowed." \
--title "Hostname too long" ${r} ${c} 3>&1 1>&2 2>&3)
--title "Hostname too long" ${r} ${c} 3>&1 1>&2 2>&3)
$SUDO hostnamectl set-hostname "${host_name}"
if [[ ${#host_name} -le 28 && $host_name =~ ^[a-zA-Z0-9][a-zA-Z0-9-]{1,28}$ ]]; then
echo "::: Hostname valid and length OK, proceeding..."
@ -418,8 +440,9 @@ updatePackageCache(){
#update package lists
echo ":::"
echo -ne "::: Package Cache update is needed, running ${UPDATE_PKG_CACHE} ...\\n"
# shellcheck disable=SC2086
$SUDO ${UPDATE_PKG_CACHE} &> /dev/null & spinner $!
# shellcheck disable=SC2086
$SUDO ${UPDATE_PKG_CACHE} &> /dev/null &
spinner $!
echo " done!"
}
@ -444,7 +467,7 @@ preconfigurePackages(){
# Install packages used by this installation script
# If apt is older than 1.5 we need to install an additional package to add
# support for https repositories that will be used later on
if [[ -f /etc/apt/sources.list ]]; then
if [ "${PKG_MANAGER}" == 'apt-get' ] && [ -f /etc/apt/sources.list ]; then
INSTALLED_APT="$(apt-cache policy apt | grep -m1 'Installed: ' | grep -v '(none)' | awk '{print $2}')"
if dpkg --compare-versions "$INSTALLED_APT" lt 1.5; then
BASE_DEPS+=("apt-transport-https")
@ -456,31 +479,53 @@ preconfigurePackages(){
BASE_DEPS+=(dhcpcd5)
fi
DPKG_ARCH="$(dpkg --print-architecture)"
if [ "${PKG_MANAGER}" == 'apt-get' ]; then
DPKG_ARCH="$(dpkg --print-architecture)"
elif [ "${PKG_MANAGER}" == 'apk' ]; then
DPKG_ARCH="$(apk --print-arch)"
fi
if [ "${PKG_MANAGER}" == 'apt-get' ]; then
AVAILABLE_OPENVPN="$(apt-cache policy openvpn | grep -m1 'Candidate: ' | grep -v '(none)' | awk '{print $2}')"
elif [ "${PKG_MANAGER}" == 'apk' ]; then
AVAILABLE_OPENVPN="$(apk search -e openvpn | sed -E -e 's/openvpn\-(.*)/\1/')"
fi
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
# repositories but we are running x86 Debian or Ubuntu, add the official repo
# which provides the updated package.
if [ -n "$AVAILABLE_OPENVPN" ] && dpkg --compare-versions "$AVAILABLE_OPENVPN" ge 2.4; then
OPENVPN_SUPPORT=1
else
if [ "$PLAT" = "Debian" ] || [ "$PLAT" = "Ubuntu" ]; then
if [ "$DPKG_ARCH" = "amd64" ] || [ "$DPKG_ARCH" = "i386" ]; then
NEED_OPENVPN_REPO=1
OPENVPN_SUPPORT=1
if [ "${PKG_MANAGER}" == 'apt-get' ]; then
if [ -n "$AVAILABLE_OPENVPN" ] && dpkg --compare-versions "$AVAILABLE_OPENVPN" ge 2.4; then
OPENVPN_SUPPORT=1
else
if [ "$PLAT" = "Debian" ] || [ "$PLAT" = "Ubuntu" ]; then
if [ "$DPKG_ARCH" = "amd64" ] || [ "$DPKG_ARCH" = "i386" ]; then
NEED_OPENVPN_REPO=1
OPENVPN_SUPPORT=1
else
OPENVPN_SUPPORT=0
fi
else
OPENVPN_SUPPORT=0
fi
fi
elif [ "${PKG_MANAGER}" == 'apk' ]; then
if [ -n "${AVAILABLE_OPENVPN}" ] && [ "$(apk version -t "${AVAILABLE_OPENVPN}" 2.4)" == '>' ]; then
OPENVPN_SUPPORT=1
else
OPENVPN_SUPPORT=0
fi
fi
AVAILABLE_WIREGUARD="$(apt-cache policy wireguard | grep -m1 'Candidate: ' | grep -v '(none)' | awk '{print $2}')"
if [ "${PKG_MANAGER}" == 'apt-get' ]; then
AVAILABLE_WIREGUARD="$(apt-cache policy wireguard | grep -m1 'Candidate: ' | grep -v '(none)' | awk '{print $2}')"
elif [ "${PKG_MANAGER}" == 'apk' ]; then
AVAILABLE_WIREGUARD="$(apk search -e wireguard-tools | sed -E -e 's/wireguard\-tools\-(.*)/\1/')"
fi
WIREGUARD_SUPPORT=0
# If a wireguard kernel object is found and is part of any installed package, then
@ -489,8 +534,11 @@ preconfigurePackages(){
# and not part of the .deb).
# Source: https://github.com/MichaIng/DietPi/blob/7bf5e1041f3b2972d7827c48215069d1c90eee07/dietpi/dietpi-software#L1807-L1815
WIREGUARD_BUILTIN=0
if dpkg-query -S '/lib/modules/*/wireguard.ko*' &> /dev/null || modinfo wireguard 2> /dev/null | grep -q '^filename:[[:blank:]]*(builtin)$'; then
WIREGUARD_BUILTIN=1
if [ "${PKG_MANAGER}" == 'apt-get' ]; then
if dpkg-query -S '/lib/modules/*/wireguard.ko*' &> /dev/null || modinfo wireguard 2> /dev/null | grep -q '^filename:[[:blank:]]*(builtin)$'; then
WIREGUARD_BUILTIN=1
fi
fi
if
@ -500,13 +548,16 @@ preconfigurePackages(){
[[ $WIREGUARD_BUILTIN == 1 && ( $PLAT == 'Debian' || $PLAT == 'Raspbian' ) ]] ||
# If the module is not builtin, on Raspbian we know the headers package: raspberrypi-kernel-headers
[[ $PLAT == 'Raspbian' ]] ||
# On Alpine, the kernel must be linux-lts or linux-virt if we want to load the kernel module
[[ "${PLAT}" == 'Alpine' && ! -f /.dockerenv && "$(uname -mrs)" =~ ^Linux\ +[0-9\.\-]+\-((lts)|(virt))\ +.*$ ]] ||
# On Alpine Docker Container, the responsibility to have a WireGuard module on the host system is at user side
[[ "${PLAT}" == 'Alpine' && -f /.dockerenv ]] ||
# On Debian (and Ubuntu), we can only reliably assume the headers package for amd64: linux-image-amd64
[[ $PLAT == 'Debian' && $DPKG_ARCH == 'amd64' ]] ||
# On Ubuntu, additionally the WireGuard package needs to be available, since we didn't test mixing Ubuntu repositories.
[[ $PLAT == 'Ubuntu' && $DPKG_ARCH == 'amd64' && -n $AVAILABLE_WIREGUARD ]] ||
# Ubuntu focal has wireguard support
[[ $PLAT == 'Ubuntu' && $DPKG_ARCH == 'arm64' && $OSCN == 'focal' && -n $AVAILABLE_WIREGUARD ]]
then
[[ $PLAT == 'Ubuntu' && $DPKG_ARCH == 'arm64' && $OSCN == 'focal' && -n $AVAILABLE_WIREGUARD ]]; then
WIREGUARD_SUPPORT=1
fi
@ -518,7 +569,7 @@ preconfigurePackages(){
# if ufw is enabled, configure that.
# running as root because sometimes the executable is not in the user's $PATH
if $SUDO bash -c 'command -v ufw' > /dev/null; then
if $SUDO ufw status | grep -q inactive; then
if ! ${SUDO} ufw status || $SUDO ufw status | grep -q inactive; then
USING_UFW=0
else
USING_UFW=1
@ -527,12 +578,42 @@ preconfigurePackages(){
USING_UFW=0
fi
if [ "$USING_UFW" -eq 0 ]; then
if [ "${PKG_MANAGER}" == 'apt-get' ] && [ "$USING_UFW" -eq 0 ]; then
BASE_DEPS+=(iptables-persistent)
echo iptables-persistent iptables-persistent/autosave_v4 boolean true | $SUDO debconf-set-selections
echo iptables-persistent iptables-persistent/autosave_v6 boolean false | $SUDO debconf-set-selections
fi
if [[ "${PLAT}" == 'Alpine' ]] && ! command -v grepcidr &> /dev/null; then
## install dependencies
# shellcheck disable=SC2086
${SUDO} ${PKG_INSTALL} build-base make curl tar
## download binaeries
curl -fLo master.tar.gz https://github.com/pivpn/grepcidr/archive/master.tar.gz
tar -xzf master.tar.gz
cd grepcidr-master || exit 1
## personalize binaries
sed -i -E -e 's/^PREFIX\=.*/PREFIX\=\/usr\nCC\=gcc/' Makefile
## install
make
${SUDO} make install
if ! command -v grepcidr &> /dev/null; then
echo "::: Failed to compile and install grepcidr!"
exit 1
fi
cd ..
## remove useless files
rm master.tar.gz
rm -rf grepcidr-master
fi
echo "USING_UFW=${USING_UFW}" >> ${tempsetupVarsFile}
}
@ -547,12 +628,23 @@ installDependentPackages(){
for i in "${argArray1[@]}"; do
echo -n "::: Checking for $i..."
if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep -q "ok installed"; then
echo " already installed!"
else
echo " not installed!"
# Add this package to the list of packages in the argument array that need to be installed
TO_INSTALL+=("${i}")
if [ "${PKG_MANAGER}" == 'apt-get' ]; then
if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep -q "ok installed"; then
echo " already installed!"
else
echo " not installed!"
# Add this package to the list of packages in the argument array that need to be installed
TO_INSTALL+=("${i}")
fi
elif [ "${PKG_MANAGER}" == 'apk' ]; then
if eval "${SUDO} ${CHECK_PKG_INSTALLED} ${i}" &> /dev/null; then
echo " already installed!"
else
echo " not installed!"
# Add this package to the list of packages in the argument array that need to be installed
TO_INSTALL+=("${i}")
fi
fi
done
@ -570,13 +662,24 @@ installDependentPackages(){
local FAILED=0
for i in "${TO_INSTALL[@]}"; do
if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep -q "ok installed"; then
echo "::: Package $i successfully installed!"
# Add this package to the total list of packages that were actually installed by the script
INSTALLED_PACKAGES+=("${i}")
else
echo "::: Failed to install $i!"
((FAILED++))
if [ "${PKG_MANAGER}" == 'apt-get' ]; then
if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep -q "ok installed"; then
echo "::: Package $i successfully installed!"
# Add this package to the total list of packages that were actually installed by the script
INSTALLED_PACKAGES+=("${i}")
else
echo "::: Failed to install $i!"
((FAILED++))
fi
elif [ "${PKG_MANAGER}" == 'apk' ]; then
if eval "${SUDO} ${CHECK_PKG_INSTALLED} ${i}" &> /dev/null; then
echo "::: Package $i successfully installed!"
# Add this package to the total list of packages that were actually installed by the script
INSTALLED_PACKAGES+=("${i}")
else
echo "::: Failed to install $i!"
((FAILED++))
fi
fi
done
@ -627,38 +730,38 @@ else
fi
if [ -z "$availableInterfaces" ]; then
echo "::: Could not find any active network interface, exiting"
exit 1
echo "::: Could not find any active network interface, exiting"
exit 1
else
while read -r line; do
mode="OFF"
if [[ ${firstloop} -eq 1 ]]; then
firstloop=0
mode="ON"
fi
interfacesArray+=("${line}" "available" "${mode}")
((interfaceCount++))
done <<< "${availableInterfaces}"
while read -r line; do
mode="OFF"
if [[ ${firstloop} -eq 1 ]]; then
firstloop=0
mode="ON"
fi
interfacesArray+=("${line}" "available" "${mode}")
((interfaceCount++))
done <<< "${availableInterfaces}"
fi
if [ "${runUnattended}" = 'true' ]; then
if [ -z "$IPv4dev" ]; then
if [ "$interfaceCount" -eq 1 ]; then
IPv4dev="${availableInterfaces}"
echo "::: No interface specified for IPv4, but only ${IPv4dev} is available, using it"
else
echo "::: No interface specified for IPv4 and failed to determine one"
exit 1
fi
else
if ip -o link | grep -qw "${IPv4dev}"; then
echo "::: Using interface: ${IPv4dev} for IPv4"
else
echo "::: Interface ${IPv4dev} for IPv4 does not exist"
exit 1
fi
fi
echo "IPv4dev=${IPv4dev}" >> ${tempsetupVarsFile}
if [ -z "$IPv4dev" ]; then
if [ "$interfaceCount" -eq 1 ]; then
IPv4dev="${availableInterfaces}"
echo "::: No interface specified for IPv4, but only ${IPv4dev} is available, using it"
else
echo "::: No interface specified for IPv4 and failed to determine one"
exit 1
fi
else
if ip -o link | grep -qw "${IPv4dev}"; then
echo "::: Using interface: ${IPv4dev} for IPv4"
else
echo "::: Interface ${IPv4dev} for IPv4 does not exist"
exit 1
fi
fi
echo "IPv4dev=${IPv4dev}" >> ${tempsetupVarsFile}
if [ "$pivpnenableipv6" == "1" ]; then
if [ -z "$IPv6dev" ]; then
if [ "$interfaceCount" -eq 1 ]; then
@ -678,31 +781,31 @@ if [ "${runUnattended}" = 'true' ]; then
fi
fi
if [ "$pivpnenableipv6" == "1" ] && [ -z "$IPv6dev" ]; then
echo "IPv6dev=${IPv6dev}" >> ${tempsetupVarsFile}
echo "IPv6dev=${IPv6dev}" >> ${tempsetupVarsFile}
fi
return
return
else
if [ "$interfaceCount" -eq 1 ]; then
IPv4dev="${availableInterfaces}"
echo "IPv4dev=${IPv4dev}" >> ${tempsetupVarsFile}
if [ "$interfaceCount" -eq 1 ]; then
IPv4dev="${availableInterfaces}"
echo "IPv4dev=${IPv4dev}" >> ${tempsetupVarsFile}
if [ "$pivpnenableipv6" == "1" ]; then
IPv6dev="${availableInterfaces}"
echo "IPv6dev=${IPv6dev}" >> ${tempsetupVarsFile}
fi
fi
return
fi
fi
fi
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An interface for IPv4 (press space to select):" "${r}" "${c}" "${interfaceCount}")
if chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty) ; then
for desiredInterface in ${chooseInterfaceOptions}; do
IPv4dev=${desiredInterface}
echo "::: Using interface: $IPv4dev"
echo "IPv4dev=${IPv4dev}" >> ${tempsetupVarsFile}
done
for desiredInterface in ${chooseInterfaceOptions}; do
IPv4dev=${desiredInterface}
echo "::: Using interface: $IPv4dev"
echo "IPv4dev=${IPv4dev}" >> ${tempsetupVarsFile}
done
else
echo "::: Cancel selected, exiting...."
exit 1
echo "::: Cancel selected, exiting...."
exit 1
fi
if [ "$pivpnenableipv6" == "1" ]; then
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An interface for IPv6, usually the same as used by IPv4 (press space to select):" "${r}" "${c}" "${interfaceCount}")
@ -721,10 +824,10 @@ fi
checkStaticIpSupported(){
# Not really robust and correct, we should actually check for dhcpcd, not the distro, but works on Raspbian and Debian.
if [ "$PLAT" = "Raspbian" ]; then
if [ "${PLAT}" = "Raspbian" ]; then
return 0
# If we are on 'Debian' but the raspi.list file is present, then we actually are on 64-bit Raspberry Pi OS.
elif [ "$PLAT" = "Debian" ] && [ -s /etc/apt/sources.list.d/raspi.list ]; then
elif [ "${PLAT}" = "Debian" ] && [ -s /etc/apt/sources.list.d/raspi.list ]; then
return 0
else
return 1
@ -893,7 +996,7 @@ Yes: Keep using DHCP reservation
No: Setup static IP address
Don't know what DHCP Reservation is? Answer No." ${r} ${c}); then
dhcpReserv=1
# shellcheck disable=SC2129
# shellcheck disable=SC2129
echo "dhcpReserv=${dhcpReserv}" >> ${tempsetupVarsFile}
# We don't really need to save them as we won't set a static IP but they might be useful for debugging
echo "IPv4addr=${CurrentIPv4addr}" >> ${tempsetupVarsFile}
@ -1021,7 +1124,14 @@ chooseUser(){
echo "::: ${install_user} will hold your ovpn configurations."
else
echo "::: User ${install_user} does not exist, creating..."
$SUDO useradd -m -s /bin/bash "${install_user}"
if [ "${PLAT}" == 'Alpine' ]; then
${SUDO} adduser -s /bin/bash "${install_user}"
${SUDO} addgroup "${install_user}" wheel
else
${SUDO} useradd -ms /bin/bash "${install_user}"
fi
echo "::: User created without a password, please do sudo passwd $install_user to create one"
fi
fi
@ -1036,19 +1146,32 @@ chooseUser(){
whiptail --msgbox --backtitle "Parsing User List" --title "Local Users" "Choose a local user that will hold your ovpn configurations." ${r} ${c}
# First, let's check if there is a user available.
numUsers=$(awk -F':' 'BEGIN {count=0} $3>=1000 && $3<=60000 { count++ } END{ print count }' /etc/passwd)
if [ "$numUsers" -eq 0 ]
then
if [ "$numUsers" -eq 0 ]; then
# We don't have a user, let's ask to add one.
if userToAdd=$(whiptail --title "Choose A User" --inputbox "No non-root user account was found. Please type a new username." ${r} ${c} 3>&1 1>&2 2>&3)
then
if userToAdd=$(whiptail --title "Choose A User" --inputbox "No non-root user account was found. Please type a new username." ${r} ${c} 3>&1 1>&2 2>&3); then
# See https://askubuntu.com/a/667842/459815
PASSWORD=$(whiptail --title "password dialog" --passwordbox "Please enter the new user password" ${r} ${c} 3>&1 1>&2 2>&3)
CRYPT=$(perl -e 'printf("%s\n", crypt($ARGV[0], "password"))' "${PASSWORD}")
if $SUDO useradd -m -p "${CRYPT}" -s /bin/bash "${userToAdd}" ; then
echo "Succeeded"
((numUsers+=1))
if [ "${PLAT}" == 'Alpine' ]; then
if ${SUDO} adduser -Ds /bin/bash "${userToAdd}"; then
${SUDO} addgroup "${userToAdd}" wheel
${SUDO} chpasswd <<< "${userToAdd}:${PASSWORD}"
${SUDO} passwd -u "${userToAdd}"
echo "Succeeded"
((numUsers+=1))
else
exit 1
fi
else
exit 1
if ${SUDO} useradd -mp "${CRYPT}" -s /bin/bash "${userToAdd}"; then
echo "Succeeded"
((numUsers+=1))
else
exit 1
fi
fi
else
exit 1
@ -1058,8 +1181,7 @@ chooseUser(){
local userArray=()
local firstloop=1
while read -r line
do
while read -r line; do
mode="OFF"
if [[ $firstloop -eq 1 ]]; then
firstloop=0
@ -1105,7 +1227,8 @@ updateRepo(){
# Go back to /usr/local/src otherwise git will complain when the current working
# directory has just been deleted (/usr/local/src/pivpn).
cd /usr/local/src && \
$SUDO git clone -q --depth 1 --no-single-branch "${2}" "${1}" > /dev/null && spinner $!
$SUDO git clone -q --depth 1 --no-single-branch "${2}" "${1}" > /dev/null &
spinner $!
cd "${1}" || exit 1
echo " done!"
if [ -n "${pivpnGitBranch}" ]; then
@ -1133,7 +1256,8 @@ makeRepo(){
# Go back to /usr/local/src otherwhise git will complain when the current working
# directory has just been deleted (/usr/local/src/pivpn).
cd /usr/local/src && \
$SUDO git clone -q --depth 1 --no-single-branch "${2}" "${1}" > /dev/null & spinner $!
$SUDO git clone -q --depth 1 --no-single-branch "${2}" "${1}" > /dev/null &
spinner $!
cd "${1}" || exit 1
echo " done!"
if [ -n "${pivpnGitBranch}" ]; then
@ -1177,34 +1301,41 @@ installPiVPN(){
askWhichVPN
setVPNDefaultVars
if [ "$VPN" = "openvpn" ]; then
if [ "${VPN}" == 'openvpn' ]; then
setOpenVPNDefaultVars
askAboutCustomizing
installOpenVPN
askCustomProto
askCustomPort
askClientDNS
elif [ "${VPN}" == 'wireguard' ]; then
setWireguardDefaultVars
installWireGuard
fi
askCustomPort
askClientDNS
if [ "${VPN}" == 'openvpn' ]; then
askCustomDomain
askPublicIPOrDNS
fi
askPublicIPOrDNS
if [ "${VPN}" == 'openvpn' ]; then
askEncryption
confOpenVPN
confOVPN
confNetwork
confLogging
elif [ "$VPN" = "wireguard" ]; then
setWireguardDefaultVars
installWireGuard
askCustomPort
askClientDNS
askPublicIPOrDNS
elif [ "${VPN}" == 'wireguard' ]; then
confWireGuard
confNetwork
writeWireguardTempVarsFile
fi
confNetwork
if [ "${VPN}" == 'openvpn' ]; then
confLogging
elif [ "${VPN}" == 'wireguard' ]; then
writeWireguardTempVarsFile
fi
writeVPNTempVarsFile
}
@ -1220,7 +1351,19 @@ setVPNDefaultVars(){
generateRandomSubnet() {
# Source: https://community.openvpn.net/openvpn/wiki/AvoidRoutingConflicts
declare -a SUBNET_EXCLUDE_LIST=(10.0.0.0/24 10.0.1.0/24 10.1.1.0/24 10.1.10.0/24 10.2.0.0/24 10.8.0.0/24 10.10.1.0/24 10.90.90.0/24 10.100.1.0/24 10.255.255.0/24)
declare -a SUBNET_EXCLUDE_LIST
SUBNET_EXCLUDE_LIST=(10.0.0.0/24)
SUBNET_EXCLUDE_LIST+=(10.0.1.0/24)
SUBNET_EXCLUDE_LIST+=(10.1.1.0/24)
SUBNET_EXCLUDE_LIST+=(10.1.10.0/24)
SUBNET_EXCLUDE_LIST+=(10.2.0.0/24)
SUBNET_EXCLUDE_LIST+=(10.8.0.0/24)
SUBNET_EXCLUDE_LIST+=(10.10.1.0/24)
SUBNET_EXCLUDE_LIST+=(10.90.90.0/24)
SUBNET_EXCLUDE_LIST+=(10.100.1.0/24)
SUBNET_EXCLUDE_LIST+=(10.255.255.0/24)
readarray -t CURRENTLY_USED_SUBNETS <<< "$(ip route show | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,2}')"
SUBNET_EXCLUDE_LIST=("${SUBNET_EXCLUDE_LIST[@]}" "${CURRENTLY_USED_SUBNETS[@]}")
@ -1410,6 +1553,7 @@ installOpenVPN(){
# Expect is used to feed easy-rsa with passwords
PIVPN_DEPS=(openvpn expect)
installDependentPackages PIVPN_DEPS[@]
}
@ -1473,6 +1617,12 @@ installWireGuard(){
installDependentPackages PIVPN_DEPS[@]
elif [ "${PLAT}" == 'Alpine' ]; then
echo "::: Installing WireGuard... "
PIVPN_DEPS=(wireguard-tools libqrencode)
installDependentPackages PIVPN_DEPS[@]
fi
}
@ -1506,8 +1656,7 @@ askCustomProto(){
if pivpnPROTO=$(whiptail --title "Protocol" --radiolist \
"Choose a protocol (press space to select). Please only choose TCP if you know why you need TCP." ${r} ${c} 2 \
"UDP" "" ON \
"TCP" "" OFF 3>&1 1>&2 2>&3)
then
"TCP" "" OFF 3>&1 1>&2 2>&3); then
# Convert option into lowercase (UDP->udp)
pivpnPROTO="${pivpnPROTO,,}"
echo "::: Using protocol: $pivpnPROTO"
@ -1545,8 +1694,7 @@ askCustomPort(){
return
fi
until [[ $PORTNumCorrect = True ]]
do
until [[ $PORTNumCorrect = True ]]; do
portInvalid="Invalid"
if [ "$VPN" = "wireguard" ]; then
@ -1559,8 +1707,7 @@ askCustomPort(){
fi
fi
if pivpnPORT=$(whiptail --title "Default $VPN Port" --inputbox "You can modify the default $VPN port. \\nEnter a new value or hit 'Enter' to retain the default" ${r} ${c} $DEFAULT_PORT 3>&1 1>&2 2>&3)
then
if pivpnPORT=$(whiptail --title "Default $VPN Port" --inputbox "You can modify the default $VPN port. \\nEnter a new value or hit 'Enter' to retain the default" ${r} ${c} $DEFAULT_PORT 3>&1 1>&2 2>&3); then
if [[ "$pivpnPORT" =~ ^[0-9]+$ ]] && [ "$pivpnPORT" -ge 1 ] && [ "$pivpnPORT" -le 65535 ]; then
:
else
@ -1669,8 +1816,7 @@ askClientDNS(){
PiVPN-is-local-DNS "" off
Custom "" off)
if DNSchoices=$("${DNSChoseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
then
if DNSchoices=$("${DNSChoseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty); then
if [[ ${DNSchoices} != "Custom" ]]; then
@ -1693,8 +1839,7 @@ askClientDNS(){
until [[ $DNSSettingsCorrect = True ]]; do
strInvalid="Invalid"
if pivpnDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), separated by a comma.\\n\\nFor example '1.1.1.1, 9.9.9.9'" ${r} ${c} "" 3>&1 1>&2 2>&3)
then
if pivpnDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), separated by a comma.\\n\\nFor example '1.1.1.1, 9.9.9.9'" ${r} ${c} "" 3>&1 1>&2 2>&3); then
pivpnDNS1=$(echo "$pivpnDNS" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
pivpnDNS2=$(echo "$pivpnDNS" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
if ! validIP "$pivpnDNS1" || [ ! "$pivpnDNS1" ]; then
@ -1739,7 +1884,7 @@ askClientDNS(){
#Call this function to use a regex to check user input for a valid custom domain
validDomain(){
local domain="$1"
local domain="$1"
grep -qP '(?=^.{4,253}$)(^(?:[a-zA-Z0-9](?:(?:[a-zA-Z0-9\-]){0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$)' <<< "$domain"
}
@ -1771,8 +1916,7 @@ askCustomDomain(){
if (whiptail --backtitle "Custom Search Domain" --title "Custom Search Domain" --yesno --defaultno "Would you like to add a custom search domain? \\n (This is only for advanced users who have their own domain)\\n" ${r} ${c}); then
until [[ $DomainSettingsCorrect = True ]]
do
until [[ $DomainSettingsCorrect = True ]]; do
if pivpnSEARCHDOMAIN=$(whiptail --inputbox "Enter Custom Domain\\nFormat: mydomain.com" ${r} ${c} --title "Custom Domain" 3>&1 1>&2 2>&3); then
if validDomain "$pivpnSEARCHDOMAIN"; then
if (whiptail --backtitle "Custom Search Domain" --title "Custom Search Domain" --yesno "Are these settings correct?\\n Custom Search Domain: $pivpnSEARCHDOMAIN" ${r} ${c}); then
@ -2089,10 +2233,18 @@ confOpenVPN(){
# Generate an empty Certificate Revocation List
${SUDOE} ./easyrsa gen-crl
${SUDOE} cp pki/crl.pem /etc/openvpn/crl.pem
if ! getent passwd openvpn; then
${SUDOE} adduser --system --home /var/lib/openvpn/ --group --disabled-login ${debianOvpnUserGroup%:*}
fi
${SUDOE} chown "$debianOvpnUserGroup" /etc/openvpn/crl.pem
if [ "${PLAT}" == 'Alpine' ]; then
if ! getent passwd "${ovpnUserGroup%:*}"; then
${SUDOE} adduser -SDh /var/lib/openvpn/ -s /sbin/nologin "${ovpnUserGroup%:*}"
fi
else
if ! getent passwd "${ovpnUserGroup%:*}"; then
${SUDOE} useradd --system --home /var/lib/openvpn/ --shell /usr/sbin/nologin "${ovpnUserGroup%:*}"
fi
fi
${SUDOE} chown "${ovpnUserGroup}" /etc/openvpn/crl.pem
# Write config file for server using the template.txt file
$SUDO install -m 644 "$pivpnFilesDir"/files/etc/openvpn/server_config.txt /etc/openvpn/server.conf
@ -2149,6 +2301,12 @@ confOpenVPN(){
# write out server certs to conf file
$SUDO sed -i "s#\\(key /etc/openvpn/easy-rsa/pki/private/\\).*#\\1${SERVER_NAME}.key#" /etc/openvpn/server.conf
$SUDO sed -i "s#\\(cert /etc/openvpn/easy-rsa/pki/issued/\\).*#\\1${SERVER_NAME}.crt#" /etc/openvpn/server.conf
# On Alpine Linux, the default config file for OpenVPN is "/etc/openvpn/openvpn.conf"
# To avoid crash thorugh OpenRC, we symlink this file
if [[ "${PLAT}" == 'Alpine' ]]; then
${SUDO} ln -sfT /etc/openvpn/server.conf /etc/openvpn/openvpn.conf > /dev/null
fi
}
confOVPN(){
@ -2177,10 +2335,16 @@ confOVPN(){
confWireGuard(){
# Reload job type is not yet available in wireguard-tools shipped with Ubuntu 20.04
if ! grep -q 'ExecReload' /lib/systemd/system/wg-quick@.service; then
echo "::: Adding additional reload job type for wg-quick unit"
$SUDO install -D -m 644 "${pivpnFilesDir}"/files/etc/systemd/system/wg-quick@.service.d/override.conf /etc/systemd/system/wg-quick@.service.d/override.conf
$SUDO systemctl daemon-reload
if [ "${PLAT}" == 'Alpine' ]; then
echo '::: Adding wg-quick unit'
${SUDO} install -m 0755 "${pivpnFilesDir}/files/etc/init.d/wg-quick" /etc/init.d/wg-quick
else
if ! grep -q 'ExecReload' /lib/systemd/system/wg-quick@.service; then
echo "::: Adding additional reload job type for wg-quick unit"
$SUDO install -D -m 644 "${pivpnFilesDir}"/files/etc/systemd/system/wg-quick@.service.d/override.conf /etc/systemd/system/wg-quick@.service.d/override.conf
$SUDO systemctl daemon-reload
fi
fi
if [ -d /etc/wireguard ]; then
@ -2225,34 +2389,34 @@ confWireGuard(){
echo "::: Server Keys have been generated."
if [ "$pivpnenableipv6" == "1" ]; then
{
echo '[Interface]'
echo "PrivateKey = $(${SUDO} cat /etc/wireguard/keys/server_priv)"
echo -n "Address = ${vpnGw}/${subnetClass}"
echo "[Interface]
PrivateKey = $($SUDO cat /etc/wireguard/keys/server_priv)
Address = ${vpnGw}/${subnetClass},${vpnGwv6}/${subnetClassv6}
MTU = ${pivpnMTU}
ListenPort = ${pivpnPORT}" | $SUDO tee /etc/wireguard/wg0.conf &> /dev/null
if [ "$pivpnenableipv6" == "1" ]; then
echo ",${vpnGwv6}/${subnetClassv6}"
else
echo
fi
else
echo "MTU = ${pivpnMTU}"
echo "ListenPort = ${pivpnPORT}"
} | ${SUDO} tee /etc/wireguard/wg0.conf &> /dev/null
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
fi
echo "::: Server config generated."
}
confNetwork(){
# Enable forwarding of internet traffic
$SUDO sed -i '/net.ipv4.ip_forward=1/s/^#//g' /etc/sysctl.conf
echo 'net.ipv4.ip_forward=1' | $SUDO tee /etc/sysctl.d/99-pivpn.conf > /dev/null
if [ "$pivpnenableipv6" == "1" ]; then
$SUDO sed -i '/net.ipv6.conf.all.forwarding=1/s/^#//g' /etc/sysctl.conf
echo "net.ipv6.conf.${IPv6dev}.accept_ra=2" | $SUDO tee /etc/sysctl.d/99-pivpn.conf > /dev/null
echo "net.ipv6.conf.all.forwarding=1
net.ipv6.conf.${IPv6dev}.accept_ra=2" | $SUDO tee -a /etc/sysctl.d/99-pivpn.conf > /dev/null
fi
$SUDO sysctl -p > /dev/null
${SUDO} sysctl -p /etc/sysctl.d/99-pivpn.conf > /dev/null
if [ "$USING_UFW" -eq 1 ]; then
@ -2411,8 +2575,14 @@ confLogging() {
# Pre-create rsyslog/logrotate config directories if missing, to assure logs are handled as expected when those are installed at a later time
$SUDO mkdir -p /etc/{rsyslog,logrotate}.d
echo "if \$programname == 'ovpn-server' then /var/log/openvpn.log
if \$programname == 'ovpn-server' then stop" | $SUDO tee /etc/rsyslog.d/30-openvpn.conf > /dev/null
if [ "${PLAT}" == 'Alpine' ]; then
program_name='openvpn'
else
program_name='ovpn-server'
fi
echo "if \$programname == '${program_name}' then /var/log/openvpn.log
if \$programname == '${program_name}' then stop" | $SUDO tee /etc/rsyslog.d/30-openvpn.conf > /dev/null
echo "/var/log/openvpn.log
{
@ -2429,10 +2599,14 @@ if \$programname == 'ovpn-server' then stop" | $SUDO tee /etc/rsyslog.d/30-openv
}" | $SUDO tee /etc/logrotate.d/openvpn > /dev/null
# Restart the logging service
case ${PLAT} in
Debian|Raspbian|Ubuntu)
case "${PLAT}" in
Debian | Raspbian | Ubuntu)
$SUDO systemctl -q is-active rsyslog.service && $SUDO systemctl restart rsyslog.service
;;
Alpine)
${SUDO} rc-service -is rsyslog restart
${SUDO} rc-service -iN rsyslog start
;;
esac
}
@ -2450,6 +2624,17 @@ restartServices(){
$SUDO systemctl restart wg-quick@wg0.service
fi
;;
Alpine)
if [ "${VPN}" == 'openvpn' ]; then
${SUDO} rc-update add openvpn default &> /dev/null
${SUDO} rc-service -s openvpn restart
${SUDO} rc-service -N openvpn start
elif [ "${VPN}" == 'wireguard' ]; then
${SUDO} rc-update add wg-quick default &> /dev/null
${SUDO} rc-service -s wg-quick restart
${SUDO} rc-service -N wg-quick start
fi
;;
esac
}
@ -2482,52 +2667,63 @@ askUnattendedUpgrades(){
confUnattendedUpgrades(){
local PIVPN_DEPS
PIVPN_DEPS=(unattended-upgrades)
installDependentPackages PIVPN_DEPS[@]
aptConfDir="/etc/apt/apt.conf.d"
if [ "$PLAT" = "Ubuntu" ]; then
if [[ "${PKG_MANAGER}" == 'apt-get' ]]; then
PIVPN_DEPS=(unattended-upgrades)
installDependentPackages PIVPN_DEPS[@]
aptConfDir="/etc/apt/apt.conf.d"
# Ubuntu 50unattended-upgrades should already just have security enabled
# so we just need to configure the 10periodic file
echo "APT::Periodic::Update-Package-Lists \"1\";
APT::Periodic::Download-Upgradeable-Packages \"1\";
APT::Periodic::AutocleanInterval \"5\";
APT::Periodic::Unattended-Upgrade \"1\";" | $SUDO tee "${aptConfDir}/10periodic" > /dev/null
if [ "$PLAT" = "Ubuntu" ]; then
# Ubuntu 50unattended-upgrades should already just have security enabled
# so we just need to configure the 10periodic file
echo "APT::Periodic::Update-Package-Lists \"1\";
APT::Periodic::Download-Upgradeable-Packages \"1\";
APT::Periodic::AutocleanInterval \"5\";
APT::Periodic::Unattended-Upgrade \"1\";" | $SUDO tee "${aptConfDir}/10periodic" > /dev/null
else
else
# Raspbian's unattended-upgrades package downloads Debian's config, so we copy over the proper config
# Source: https://github.com/mvo5/unattended-upgrades/blob/master/data/50unattended-upgrades.Raspbian
if [ "$PLAT" = "Raspbian" ]; then
$SUDO install -m 644 "${pivpnFilesDir}/files${aptConfDir}/50unattended-upgrades.Raspbian" "${aptConfDir}/50unattended-upgrades"
fi
# Raspbian's unattended-upgrades package downloads Debian's config, so we copy over the proper config
# Source: https://github.com/mvo5/unattended-upgrades/blob/master/data/50unattended-upgrades.Raspbian
if [ "$PLAT" = "Raspbian" ]; then
$SUDO install -m 644 "${pivpnFilesDir}/files${aptConfDir}/50unattended-upgrades.Raspbian" "${aptConfDir}/50unattended-upgrades"
# Add the remaining settings for all other distributions
echo "APT::Periodic::Enable \"1\";
APT::Periodic::Update-Package-Lists \"1\";
APT::Periodic::Download-Upgradeable-Packages \"1\";
APT::Periodic::Unattended-Upgrade \"1\";
APT::Periodic::AutocleanInterval \"7\";
APT::Periodic::Verbose \"0\";" | $SUDO tee "${aptConfDir}/02periodic" > /dev/null
fi
# Add the remaining settings for all other distributions
echo "APT::Periodic::Enable \"1\";
APT::Periodic::Update-Package-Lists \"1\";
APT::Periodic::Download-Upgradeable-Packages \"1\";
APT::Periodic::Unattended-Upgrade \"1\";
APT::Periodic::AutocleanInterval \"7\";
APT::Periodic::Verbose \"0\";" | $SUDO tee "${aptConfDir}/02periodic" > /dev/null
fi
# Enable automatic updates via the bullseye repository when installing from debian package
if [ "$VPN" = "wireguard" ]; then
if [ -f /etc/apt/sources.list.d/pivpn-bullseye-repo.list ]; then
if ! grep -q "\"o=$PLAT,n=bullseye\";" "${aptConfDir}/50unattended-upgrades"; then
$SUDO sed -i "/Unattended-Upgrade::Origins-Pattern {/a\"o=$PLAT,n=bullseye\";" "${aptConfDir}/50unattended-upgrades"
# Enable automatic updates via the bullseye repository when installing from debian package
if [ "$VPN" = "wireguard" ]; then
if [ -f /etc/apt/sources.list.d/pivpn-bullseye-repo.list ]; then
if ! grep -q "\"o=$PLAT,n=bullseye\";" "${aptConfDir}/50unattended-upgrades"; then
$SUDO sed -i "/Unattended-Upgrade::Origins-Pattern {/a\"o=$PLAT,n=bullseye\";" "${aptConfDir}/50unattended-upgrades"
fi
fi
fi
elif [[ "${PKG_MANAGER}" == 'apk' ]]; then
echo 'https://dl-cdn.alpinelinux.org/alpine/edge/testing/' | ${SUDO} tee -a /etc/apk/repositories && ${SUDO} apk -q update
PIVPN_DEPS=(apk-autoupdate)
installDependentPackages PIVPN_DEPS[@]
${SUDO} sed -i -E -e '/^https:\/\/dl\-cdn\.alpinelinux\.org\/alpine\/edge\/testing\/$/d' /etc/apk/repositories && ${SUDO} apk -q update
${SUDO} install -m 0755 "${pivpnFilesDir}/files/etc/apk/personal_autoupdate.conf" /etc/apk/personal_autoupdate.conf
${SUDO} apk-autoupdate /etc/apk/personal_autoupdate.conf
fi
}
writeConfigFiles(){
# Save installation setting to the final location
echo "INSTALLED_PACKAGES=(${INSTALLED_PACKAGES[*]})" >> ${tempsetupVarsFile}
echo "::: Setupfiles copied to ${setupConfigDir}/${VPN}/${setupVarsFile}"
$SUDO mkdir -p "${setupConfigDir}/${VPN}/"
echo "::: Setupfiles copied to ${setupConfigDir}/${VPN}/${setupVarsFile}"
$SUDO mkdir -p "${setupConfigDir}/${VPN}/"
$SUDO cp ${tempsetupVarsFile} "${setupConfigDir}/${VPN}/${setupVarsFile}"
}
@ -2555,9 +2751,8 @@ installScripts(){
$SUDO ln -sf -T "${pivpnFilesDir}/scripts/pivpn" /usr/local/bin/pivpn
else
# Check if bash_completion scripts dir exists and creates it if not
if [ ! -d "/etc/bash_completion.d" ]; then
mkdir -p /etc/bash_copletion.d
fi
${SUDO} mkdir -p /etc/bash_completion.d
# Only one protocol is installed, symlink bash completion, the pivpn script
# and the script directory
$SUDO ln -sf -T "${pivpnFilesDir}/scripts/${VPN}/bash-completion" /etc/bash_completion.d/pivpn
@ -2597,7 +2792,8 @@ All incomplete posts or bug reports will be ignored or deleted.\\n\\nThank you f
whiptail --title "Rebooting" --msgbox "The system will now reboot." ${r} ${c}
printf "\\nRebooting system...\\n"
$SUDO sleep 3
$SUDO shutdown -r now
${SUDO} reboot
fi
}

View file

@ -1,6 +1,10 @@
#!/bin/bash
systemctl status openvpn
if command -v systemctl > /dev/null; then
systemctl status openvpn
elif command -v rc-service > /dev/null; then
rc-service openvpn status
fi
pivpn add -n foo
pivpn -qr foo
pivpn -bk

View file

@ -0,0 +1,25 @@
#############################################################################################
# Filename: files/etc/apk/personal_autoupdate.conf #
# Purpose: Configuration file for apk-autoupdate that override the default configs #
# Authors: Giulio Coa <34110430+giulioc008@users.noreply.github.com> #
# License: This file is licensed under the MIT. #
#############################################################################################
can_upgrade() {
case_match "${_packages_blacklist}" "$1" && return 1
case "$1" in
apk-tools)
_apk --quiet --no-cache --simulate upgrade --self-upgrade-only "$1"
;;
*)
_apk --quiet --no-cache --simulate add --upgrade "$1"
;;
esac
return 0
}
finalize() {
:
}

23
files/etc/init.d/wg-quick Executable file
View file

@ -0,0 +1,23 @@
#!/sbin/openrc-run
#################################################################################
# Filename: files/etc/init.d/wg-quick #
# Purpose: OpenRC service that starts WireGuard #
# Authors: Giulio Coa <34110430+giulioc008@users.noreply.github.com> #
# License: This file is licensed under the MIT. #
#################################################################################
description="WireGuard - Quick version"
depend() {
need localmount
need net
}
start() {
wg-quick up wg0
}
stop() {
wg-quick down wg0
}

View file

@ -18,6 +18,8 @@ date=$(date +%Y%m%d-%H%M%S)
setupVarsFile="setupVars.conf"
setupConfigDir="/etc/pivpn"
CHECK_PKG_INSTALLED='dpkg-query -s'
if [ -r "${setupConfigDir}/wireguard/${setupVarsFile}" ] && [ -r "${setupConfigDir}/openvpn/${setupVarsFile}" ]; then
# Two protocols have been installed, check if the script has passed
@ -57,6 +59,10 @@ fi
# shellcheck disable=SC1090
source "${setupVars}"
if [ "${PLAT}" == 'Alpine' ]; then
CHECK_PKG_INSTALLED='apk --no-cache info -e'
fi
checkbackupdir(){
# Disabling shellcheck error $install_home sourced from $setupVars
@ -90,8 +96,8 @@ backup_wireguard(){
}
if [[ ! $EUID -eq 0 ]];then
if [[ $(dpkg-query -s sudo) ]];then
if [[ ! $EUID -eq 0 ]]; then
if eval "${CHECK_PKG_INSTALLED} sudo" &> /dev/null; then
export SUDO="sudo"
else
echo "::: Please install sudo or run this as root."

View file

@ -7,15 +7,13 @@ _pivpn()
prev="${COMP_WORDS[COMP_CWORD-1]}"
dashopts="-a -c -d -l -r -h -u -up -bk"
opts="debug add clients list revoke uninstall help update backup"
if [ "${#COMP_WORDS[@]}" -eq 2 ]
then
if [ "${#COMP_WORDS[@]}" -eq 2 ]; then
if [[ ${cur} == -* ]] ; then
COMPREPLY=( "$(compgen -W "${dashopts}" -- "${cur}")" )
else
COMPREPLY=( "$(compgen -W "${opts}" -- "${cur}")" )
fi
elif [[ ( "$prev" == "add" || "$prev" == "-a" ) && "${#COMP_WORDS[@]}" -eq 3 ]]
then
elif [[ ( "$prev" == "add" || "$prev" == "-a" ) && "${#COMP_WORDS[@]}" -eq 3 ]]; then
COMPREPLY=( "$(compgen -W "nopass" -- "${cur}")" )
fi
return 0

View file

@ -42,14 +42,12 @@ if [ -z "$HELP_SHOWN" ]; then
fi
# Parse input arguments
while test $# -gt 0
do
while test $# -gt 0; do
_key="$1"
case "$_key" in
-n|--name|--name=*)
_val="${_key##--name=}"
if test "$_val" = "$_key"
then
if test "$_val" = "$_key"; then
test $# -lt 2 && echo "Missing value for the optional argument '$_key'." && exit 1
_val="$2"
shift
@ -58,8 +56,7 @@ do
;;
-p|--password|--password=*)
_val="${_key##--password=}"
if test "$_val" = "$_key"
then
if test "$_val" = "$_key"; then
test $# -lt 2 && echo "Missing value for the optional argument '$_key'." && exit 1
_val="$2"
shift
@ -68,8 +65,7 @@ do
;;
-d|--days|--days=*)
_val="${_key##--days=}"
if test "$_val" = "$_key"
then
if test "$_val" = "$_key"; then
test $# -lt 2 && echo "Missing value for the optional argument '$_key'." && exit 1
_val="$2"
shift
@ -96,8 +92,20 @@ do
if command -v bw > /dev/null; then
BITWARDEN="2"
else
echo "Bitwarden not found, please install bitwarden"
exit 1
echo 'Bitwarden not found, please install bitwarden'
if [ "${PLAT}" == 'Alpine' ]; then
echo 'You can download it through the following commands:'
echo $'\t' 'curl -fLo bitwarden.zip --no-cache https://github.com/bitwarden/clients/releases/download/cli-v2022.6.2/bw-linux-2022.6.2.zip'
echo $'\t' 'apk --no-cache -X https://dl-cdn.alpinelinux.org/alpine/edge/testing/ add atool'
echo $'\t' 'aunpack -F zip bitwarden.zip'
echo $'\t' 'mv bw /opt/bw'
echo $'\t' 'chmod 755 /opt/bw'
echo $'\t' 'rm bitwarden.zip'
echo $'\t' 'apk --no-cache --purge del -r atool'
fi
exit 1
fi
;;
@ -144,8 +152,7 @@ function useBitwarden() {
read -r NAME
# check name
until [[ "$NAME" =~ ^[a-zA-Z0-9.@_-]+$ && ${NAME::1} != "." && ${NAME::1} != "-" ]]
do
until [[ "$NAME" =~ ^[a-zA-Z0-9.@_-]+$ && ${NAME::1} != "." && ${NAME::1} != "-" ]]; do
echo "Name can only contain alphanumeric characters and these characters (.-@_). The name also cannot start with a dot (.) or a dash (-). Please try again."
# ask user for username again
printf "Enter the username: "
@ -158,8 +165,7 @@ function useBitwarden() {
read -r LENGTH
# check length
until [[ "$LENGTH" -gt 11 && "$LENGTH" -lt 129 ]]
do
until [[ "$LENGTH" -gt 11 && "$LENGTH" -lt 129 ]]; do
echo "Password must be between from 12 to 128 characters, please try again."
# ask user for length of password
printf "Enter the length of characters you want your password to be (minimum 12): "
@ -179,8 +185,7 @@ function keyPASS() {
if [[ -z "${PASSWD}" ]]; then
stty -echo
while true
do
while true; do
printf "Enter the password for the client: "
read -r PASSWD
printf "\n"
@ -198,15 +203,14 @@ function keyPASS() {
exit 1
fi
fi
if [ ${#PASSWD} -lt 4 ] || [ ${#PASSWD} -gt 1024 ]
then
if [ ${#PASSWD} -lt 4 ] || [ ${#PASSWD} -gt 1024 ]; then
echo "Password must be between from 4 to 1024 characters"
exit 1
fi
#Escape chars in PASSWD
PASSWD_UNESCAPED="${PASSWD}"
PASSWD=$(echo -n "${PASSWD}" | sed -e 's/\\/\\\\/g' -e 's/\//\\\//g' -e 's/\$/\\\$/g' -e 's/!/\\!/g' -e 's/\./\\\./g' -e "s/'/\\\'/g" -e 's/"/\\"/g' -e 's/\*/\\\*/g' -e 's/\@/\\\@/g' -e 's/\#/\\\#/g' -e 's/£/\\£/g' -e 's/%/\\%/g' -e 's/\^/\\\^/g' -e 's/\&/\\\&/g' -e 's/(/\\(/g' -e 's/)/\\)/g' -e 's/-/\\-/g' -e 's/_/\\_/g' -e 's/\+/\\\+/g' -e 's/=/\\=/g' -e 's/\[/\\\[/g' -e 's/\]/\\\]/g' -e 's/;/\\;/g' -e 's/:/\\:/g' -e 's/|/\\|/g' -e 's/</\\</g' -e 's/>/\\>/g' -e 's/,/\\,/g' -e 's/?/\\?/g' -e 's/~/\\~/g' -e 's/{/\\{/g' -e 's/}/\\}/g')
PASSWD=$(echo -n "${PASSWD}" | sed -E -e 's/\\/\\\\/g' -e 's/\//\\\//g' -e 's/\$/\\\$/g' -e 's/!/\\!/g' -e 's/\./\\\./g' -e "s/'/\\'/g" -e 's/"/\\"/g' -e 's/\*/\\\*/g' -e 's/@/\\@/g' -e 's/#/\\#/g' -e 's/£/\\£/g' -e 's/%/\\%/g' -e 's/\^/\\\^/g' -e 's/&/\\&/g' -e 's/\(/\\\(/g' -e 's/\)/\\\)/g' -e 's/\-/\\\-/g' -e 's/_/\\_/g' -e 's/\+/\\\+/g' -e 's/=/\\=/g' -e 's/\[/\\\[/g' -e 's/\]/\\\]/g' -e 's/;/\\;/g' -e 's/:/\\:/g' -e 's/\|/\\\|/g' -e 's/\</\\\</g' -e 's/\>/\\\>/g' -e 's/,/\\,/g' -e 's/\?/\\\?/g' -e 's/~/\\~/g' -e 's/\{/\\\{/g' -e 's/\}/\\\}/g')
#Build the client key and then encrypt the key
@ -362,7 +366,7 @@ if [ "$iOS" = "1" ]; then
#Next append the client Public Cert
echo "<cert>"
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' < "issued/${NAME}${CRT}"
sed -n -e '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' < "issued/${NAME}${CRT}"
echo "</cert>"
#Finally, append the tls Private Key
@ -401,7 +405,7 @@ else
#Next append the client Public Cert
echo "<cert>"
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' < "issued/${NAME}${CRT}"
sed -n -e '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' < "issued/${NAME}${CRT}"
echo "</cert>"
#Then, append the client Private Key

View file

@ -1,8 +1,14 @@
#!/bin/bash
CHECK_PKG_INSTALLED='dpkg-query -s'
if grep -qsEe "^NAME\=['\"]?Alpine[a-zA-Z ]*['\"]?$" /etc/os-release; then
CHECK_PKG_INSTALLED='apk --no-cache info -e'
fi
# Must be root to use this tool
if [[ ! $EUID -eq 0 ]];then
if [[ $(dpkg-query -s sudo) ]];then
if [[ ! $EUID -eq 0 ]]; then
if eval "${CHECK_PKG_INSTALLED} sudo" &> /dev/null; then
export SUDO="sudo"
else
echo "::: Please install sudo or run this as root."

View file

@ -37,16 +37,19 @@ printf "=============================================\n"
echo -e ":::: Having trouble connecting? Take a look at the FAQ:"
echo -e ":::: \e[1mhttps://docs.pivpn.io/faq\e[0m"
printf "=============================================\n"
echo -e ":::: \e[4mSnippet of the server log\e[0m ::::"
OVPNLOG="$(tail -n 20 /var/log/openvpn.log)"
# Regular expession taken from https://superuser.com/a/202835, it will match invalid IPs
# like 123.456.789.012 but it's fine since the log only contains valid ones.
declare -a IPS_TO_HIDE=("$(grepcidr -v 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 <<< "$OVPNLOG" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | uniq)")
for IP in "${IPS_TO_HIDE[@]}"; do
OVPNLOG="${OVPNLOG//"$IP"/REDACTED}"
done
if [ "${PLAT}" != 'Alpine' ]; then
echo -e ":::: \e[4mSnippet of the server log\e[0m ::::"
OVPNLOG="$(tail -n 20 /var/log/openvpn.log)"
echo "$OVPNLOG"
printf "=============================================\n"
# Regular expession taken from https://superuser.com/a/202835, it will match invalid IPs
# like 123.456.789.012 but it's fine since the log only contains valid ones.
declare -a IPS_TO_HIDE=("$(grepcidr -v 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 <<< "$OVPNLOG" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | uniq)")
for IP in "${IPS_TO_HIDE[@]}"; do
OVPNLOG="${OVPNLOG//"$IP"/REDACTED}"
done
echo "$OVPNLOG"
printf "=============================================\n"
fi
echo -e "::::\t\t\e[4mDebug complete\e[0m\t\t ::::"

View file

@ -25,8 +25,7 @@ helpFunc() {
}
# Parse input arguments
while test $# -gt 0
do
while test $# -gt 0; do
_key="$1"
case "$_key" in
-h|--help)

View file

@ -1,8 +1,14 @@
#!/bin/bash
CHECK_PKG_INSTALLED='dpkg-query -s'
if grep -qsEe "^NAME\=['\"]?Alpine[a-zA-Z ]*['\"]?$" /etc/os-release; then
CHECK_PKG_INSTALLED='apk --no-cache info -e'
fi
# Must be root to use this tool
if [ $EUID -ne 0 ];then
if dpkg-query -s sudo &> /dev/null; then
if [ $EUID -ne 0 ]; then
if eval "${CHECK_PKG_INSTALLED} sudo" &> /dev/null; then
export SUDO="sudo"
else
echo "::: Please install sudo or run this as root."

View file

@ -1,5 +1,7 @@
#!/bin/bash
PLAT=$(grep -sEe '^NAME\=' /etc/os-release | sed -E -e "s/NAME\=[\'\"]?([^ ]*).*/\1/")
# dual protocol, VPN type supplied as $1
VPN=$1
setupVars="/etc/pivpn/${VPN}/setupVars.conf"
@ -16,6 +18,11 @@ source "${setupVars}"
if [ "$VPN" = "wireguard" ]; then
VPN_SERVICE="wg-quick@wg0"
if [ "${PLAT}" == 'Alpine' ]; then
VPN_SERVICE='wg-quick'
fi
VPN_PRETTY_NAME="WireGuard"
elif [ "$VPN" = "openvpn" ]; then
VPN_SERVICE="openvpn"
@ -135,25 +142,54 @@ else
fi
if systemctl is-active -q "${VPN_SERVICE}"; then
echo ":: [OK] ${VPN_PRETTY_NAME} is running"
else
ERR=1
read -r -p ":: [ERR] ${VPN_PRETTY_NAME} is not running, try to start now? [Y/n] " REPLY
if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then
systemctl start "${VPN_SERVICE}"
echo "Done"
fi
fi
if [ "${PLAT}" == 'Alpine' ]; then
if [ "$(rc-service "${VPN_SERVICE}" status | sed -E -e 's/.*status\: (.*)/\1/')" == 'started' ]; then
echo ":: [OK] ${VPN_PRETTY_NAME} is running"
else
ERR=1
read -r -p ":: [ERR] ${VPN_PRETTY_NAME} is not running, try to start now? [Y/n] " REPLY
if systemctl is-enabled -q "${VPN_SERVICE}"; then
echo ":: [OK] ${VPN_PRETTY_NAME} is enabled (it will automatically start on reboot)"
if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then
rc-service -s "${VPN_SERVICE}" restart
rc-service -N "${VPN_SERVICE}" start
echo "Done"
fi
fi
if rc-update show default | grep -sEe "\s*${VPN_SERVICE} .*" &> /dev/null; then
echo ":: [OK] ${VPN_PRETTY_NAME} is enabled (it will automatically start on reboot)"
else
ERR=1
read -r -p ":: [ERR] ${VPN_PRETTY_NAME} is not enabled, try to enable now? [Y/n] " REPLY
if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then
rc-update add "${VPN_SERVICE}" default
echo "Done"
fi
fi
else
ERR=1
read -r -p ":: [ERR] ${VPN_PRETTY_NAME} is not enabled, try to enable now? [Y/n] " REPLY
if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then
systemctl enable "${VPN_SERVICE}"
echo "Done"
if systemctl is-active -q "${VPN_SERVICE}"; then
echo ":: [OK] ${VPN_PRETTY_NAME} is running"
else
ERR=1
read -r -p ":: [ERR] ${VPN_PRETTY_NAME} is not running, try to start now? [Y/n] " REPLY
if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then
systemctl start "${VPN_SERVICE}"
echo "Done"
fi
fi
if systemctl is-enabled -q "${VPN_SERVICE}"; then
echo ":: [OK] ${VPN_PRETTY_NAME} is enabled (it will automatically start on reboot)"
else
ERR=1
read -r -p ":: [ERR] ${VPN_PRETTY_NAME} is not enabled, try to enable now? [Y/n] " REPLY
if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then
systemctl enable "${VPN_SERVICE}"
echo "Done"
fi
fi
fi
@ -163,8 +199,15 @@ if netstat -antu | grep -wqE "${pivpnPROTO}.*${pivpnPORT}"; then
else
ERR=1
read -r -p ":: [ERR] ${VPN_PRETTY_NAME} is not listening, try to restart now? [Y/n] " REPLY
if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then
systemctl restart "${VPN_SERVICE}"
if [ "${PLAT}" == 'Alpine' ]; then
rc-service -s "${VPN_SERVICE}" restart
rc-service -N "${VPN_SERVICE}" start
else
systemctl restart "${VPN_SERVICE}"
fi
echo "Done"
fi
fi

View file

@ -17,13 +17,22 @@ r=$(( r < 20 ? 20 : r ))
c=$(( c < 70 ? 70 : c ))
PKG_MANAGER="apt-get"
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
PKG_REMOVE="${PKG_MANAGER} -y remove --purge"
dnsmasqConfig="/etc/dnsmasq.d/02-pivpn.conf"
setupVarsFile="setupVars.conf"
setupConfigDir="/etc/pivpn"
pivpnFilesDir="/usr/local/src/pivpn"
pivpnScriptDir="/opt/pivpn"
PLAT=$(grep -sEe '^NAME\=' /etc/os-release | sed -E -e "s/NAME\=[\'\"]?([^ ]*).*/\1/")
if [ "${PLAT}" == 'Alpine' ]; then
PKG_MANAGER='apk'
PKG_REMOVE="${PKG_MANAGER} --no-cache --purge del -r"
fi
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
if [ -r "${setupConfigDir}/wireguard/${setupVarsFile}" ] && [ -r "${setupConfigDir}/openvpn/${setupVarsFile}" ]; then
vpnStillExists=1
@ -84,12 +93,22 @@ removeAll(){
# Stopping and disabling services
echo "::: Stopping and disabling services..."
if [ "$VPN" = "wireguard" ]; then
systemctl stop wg-quick@wg0
systemctl disable wg-quick@wg0 &> /dev/null
elif [ "$VPN" = "openvpn" ]; then
systemctl stop openvpn
systemctl disable openvpn &> /dev/null
if [ "${PLAT}" == 'Alpine' ]; then
if [ "${VPN}" = "wireguard" ]; then
rc-service wg-quick stop
rc-update del wg-quick default &> /dev/null
elif [ "${VPN}" = "openvpn" ]; then
rc-service openvpn stop
rc-update del openvpn default &> /dev/null
fi
else
if [ "${VPN}" = "wireguard" ]; then
systemctl stop wg-quick@wg0
systemctl disable wg-quick@wg0 &> /dev/null
elif [ "${VPN}" = "openvpn" ]; then
systemctl stop openvpn
systemctl disable openvpn &> /dev/null
fi
fi
# Removing firewall rules.
@ -137,58 +156,85 @@ removeAll(){
while true; do
read -rp "::: Do you wish to remove $i from your system? [Y/n]: " yn
case $yn in
[Yy]* ) if [ "${i}" = "wireguard-tools" ]; then
[Yy]* )
if [ "${PLAT}" == 'Alpine' ]; then
if [ "${i}" == 'openvpn' ]; then
deluser openvpn
rm -f /etc/rsyslog.d/30-openvpn.conf /etc/logrotate.d/openvpn
fi
else
if [ "${i}" == "wireguard-tools" ]; then
# The bullseye repo may not exist if wireguard was available at the
# time of installation.
if [ -f /etc/apt/sources.list.d/pivpn-bullseye-repo.list ]; then
echo "::: Removing Debian Bullseye repo..."
rm -f /etc/apt/sources.list.d/pivpn-bullseye-repo.list
rm -f /etc/apt/preferences.d/pivpn-limit-bullseye
echo "::: Updating package cache..."
${UPDATE_PKG_CACHE} &> /dev/null & spinner $!
${UPDATE_PKG_CACHE} &> /dev/null &
spinner $!
fi
if [ -f /etc/systemd/system/wg-quick@.service.d/override.conf ]; then
rm -f /etc/systemd/system/wg-quick@.service.d/override.conf
fi
elif [ "${i}" = "unattended-upgrades" ]; then
rm -rf /var/log/unattended-upgrades
rm -rf /etc/apt/apt.conf.d/*periodic
rm -rf /var/log/unattended-upgrades /etc/apt/apt.conf.d/*periodic
rm -rf /etc/apt/apt.conf.d/*unattended-upgrades
elif [ "${i}" = "openvpn" ]; then
if [ -f /etc/apt/sources.list.d/pivpn-openvpn-repo.list ]; then
echo "::: Removing OpenVPN software repo..."
rm -f /etc/apt/sources.list.d/pivpn-openvpn-repo.list
echo "::: Updating package cache..."
${UPDATE_PKG_CACHE} &> /dev/null & spinner $!
fi
deluser openvpn
rm -f /etc/rsyslog.d/30-openvpn.conf
rm -f /etc/logrotate.d/openvpn
rm -f /etc/apt/sources.list.d/pivpn-openvpn-repo.list
echo "::: Updating package cache..."
${UPDATE_PKG_CACHE} &> /dev/null &
spinner $!
fi
deluser openvpn
rm -f /etc/rsyslog.d/30-openvpn.conf /etc/logrotate.d/openvpn
fi
printf ":::\\tRemoving %s..." "$i"; $PKG_MANAGER -y remove --purge "$i" &> /dev/null & spinner $!; printf "done!\\n";
break
;;
[Nn]* ) printf ":::\\tSkipping %s\\n" "$i";
break
;;
* ) printf "::: You must answer yes or no!\\n";;
fi
printf ":::\\tRemoving %s..." "$i"
"${PKG_REMOVE}" "$i" &> /dev/null &
spinner $!
printf "done!\\n";
break
;;
[Nn]* )
printf ":::\\tSkipping %s\\n" "$i";
break
;;
* )
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";
printf "::: Auto cleaning remaining dependencies..."
$PKG_MANAGER -y autoclean &> /dev/null & spinner $!; printf "done!\\n";
if [ "${PLAT}" != 'Alpine' ]; then
# Take care of any additional package cleaning
printf "::: Auto removing remaining dependencies..."
"${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";
fi
if [ -f "$dnsmasqConfig" ]; then
rm -f "$dnsmasqConfig"
@ -255,7 +301,7 @@ askreboot(){
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
printf "\\nRebooting system...\\n"
sleep 3
shutdown -r now
reboot
fi
}

View file

@ -6,8 +6,7 @@ _pivpn()
cur="${COMP_WORDS[COMP_CWORD]}"
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 ]
then
if [ "${#COMP_WORDS[@]}" -eq 2 ]; then
if [[ ${cur} == -* ]] ; then
COMPREPLY=( "$(compgen -W "${dashopts}" -- "${cur}")" )
else

View file

@ -3,119 +3,126 @@
setupVars="/etc/pivpn/wireguard/setupVars.conf"
if [ ! -f "${setupVars}" ]; then
echo "::: Missing setup vars file!"
exit 1
echo "::: Missing setup vars file!"
exit 1
fi
# shellcheck disable=SC1090
source "${setupVars}"
helpFunc(){
echo "::: Disable client conf profiles"
echo ":::"
echo "::: Usage: pivpn <-off|off> [-h|--help] [-v] [<client-1> ... [<client-2>] ...] "
echo ":::"
echo "::: Commands:"
echo "::: [none] Interactive mode"
echo "::: <client> Client"
echo "::: -y,--yes Disable client(s) without confirmation"
echo "::: -v Show disabled clients only"
echo "::: -h,--help Show this help dialog"
echo "::: Disable client conf profiles"
echo ":::"
echo "::: Usage: pivpn <-off|off> [-h|--help] [-v] [<client-1> ... [<client-2>] ...] "
echo ":::"
echo "::: Commands:"
echo "::: [none] Interactive mode"
echo "::: <client> Client"
echo "::: -y,--yes Disable client(s) without confirmation"
echo "::: -v Show disabled clients only"
echo "::: -h,--help Show this help dialog"
}
# Parse input arguments
while test $# -gt 0
do
_key="$1"
case "$_key" in
-h|--help)
helpFunc
exit 0
;;
-y|--yes)
CONFIRM=true
;;
-v)
DISPLAY_DISABLED=true
;;
while test $# -gt 0; do
_key="$1"
case "$_key" in
-h|--help)
helpFunc
exit 0
;;
-y|--yes)
CONFIRM=true
;;
-v)
DISPLAY_DISABLED=true
;;
*)
CLIENTS_TO_CHANGE+=("$1")
;;
esac
shift
CLIENTS_TO_CHANGE+=("$1")
;;
esac
shift
done
cd /etc/wireguard || exit
if [ ! -s configs/clients.txt ]; then
echo "::: There are no clients to change"
exit 1
echo "::: There are no clients to change"
exit 1
fi
if [ "$DISPLAY_DISABLED" ]; then
grep '\[disabled\] ### begin' wg0.conf | sed 's/#//g; s/begin//'
exit 1
grep '\[disabled\] ### begin' wg0.conf | sed 's/#//g; s/begin//'
exit 1
fi
mapfile -t LIST < <(awk '{print $1}' configs/clients.txt)
if [ "${#CLIENTS_TO_CHANGE[@]}" -eq 0 ]; then
echo -e "::\e[4m Client list \e[0m::"
len=${#LIST[@]}
COUNTER=1
while [ $COUNTER -le "${len}" ]; do
printf "%0${#len}s) %s\r\n" "${COUNTER}" "${LIST[(($COUNTER-1))]}"
((COUNTER++))
done
echo -e "::\e[4m Client list \e[0m::"
len=${#LIST[@]}
COUNTER=1
while [ $COUNTER -le "${len}" ]; do
printf "%0${#len}s) %s\r\n" "${COUNTER}" "${LIST[(($COUNTER-1))]}"
((COUNTER++))
done
read -r -p "Please enter the Index/Name of the Client to be removed from the list above: " CLIENTS_TO_CHANGE
read -r -p "Please enter the Index/Name of the Client to be removed from the list above: " CLIENTS_TO_CHANGE
if [ -z "${CLIENTS_TO_CHANGE}" ]; then
echo "::: You can not leave this blank!"
exit 1
fi
if [ -z "${CLIENTS_TO_CHANGE}" ]; then
echo "::: You can not leave this blank!"
exit 1
fi
fi
CHANGED_COUNT=0
for CLIENT_NAME in "${CLIENTS_TO_CHANGE[@]}"; do
re='^[0-9]+$'
if [[ ${CLIENT_NAME} =~ $re ]] ; then
CLIENT_NAME=${LIST[$((CLIENT_NAME -1))]}
fi
re='^[0-9]+$'
if [[ ${CLIENT_NAME} =~ $re ]] ; then
CLIENT_NAME=${LIST[$((CLIENT_NAME -1))]}
fi
if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then
echo -e "::: \e[1m${CLIENT_NAME}\e[0m does not exist"
elif grep -q "#\[disabled\] ### begin ${CLIENT_NAME}" wg0.conf; then
echo -e "::: \e[1m${CLIENT_NAME}\e[0m is already disabled"
else
if [ -n "$CONFIRM" ]; then
REPLY="y"
else
read -r -p "Confirm you want to disable $CLIENT_NAME? [Y/n] "
fi
if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then
echo -e "::: \e[1m${CLIENT_NAME}\e[0m does not exist"
elif grep -q "#\[disabled\] ### begin ${CLIENT_NAME}" wg0.conf; then
echo -e "::: \e[1m${CLIENT_NAME}\e[0m is already disabled"
else
if [ -n "$CONFIRM" ]; then
REPLY="y"
else
read -r -p "Confirm you want to disable $CLIENT_NAME? [Y/n] "
fi
if [[ $REPLY =~ ^[Yy]$ ]]; then
if [[ $REPLY =~ ^[Yy]$ ]]; then
# Disable the peer section from the server config
echo "${CLIENT_NAME}"
sed -e "/### begin ${CLIENT_NAME}/,/end ${CLIENT_NAME}/ s/^/#\[disabled\] /" -i wg0.conf
echo "::: Updated server config"
# Disable the peer section from the server config
echo "${CLIENT_NAME}"
sed -e "/### begin ${CLIENT_NAME}/,/end ${CLIENT_NAME}/ s/^/#\[disabled\] /" -i wg0.conf
echo "::: Updated server config"
((CHANGED_COUNT++))
echo "::: Successfully disabled ${CLIENT_NAME}"
((CHANGED_COUNT++))
echo "::: Successfully disabled ${CLIENT_NAME}"
fi
fi
fi
fi
done
# Restart WireGuard only if some clients were actually deleted
if [ "${CHANGED_COUNT}" -gt 0 ]; then
if systemctl reload wg-quick@wg0; then
echo "::: WireGuard reloaded"
else
echo "::: Failed to reload WireGuard"
fi
if [ "${PLAT}" == 'Alpine' ]; then
if rc-service wg-quick restart; then
echo "::: WireGuard reloaded"
else
echo "::: Failed to reload WireGuard"
fi
else
if systemctl reload wg-quick@wg0; then
echo "::: WireGuard reloaded"
else
echo "::: Failed to reload WireGuard"
fi
fi
fi

View file

@ -3,115 +3,122 @@
setupVars="/etc/pivpn/wireguard/setupVars.conf"
if [ ! -f "${setupVars}" ]; then
echo "::: Missing setup vars file!"
exit 1
echo "::: Missing setup vars file!"
exit 1
fi
# shellcheck disable=SC1090
source "${setupVars}"
helpFunc(){
echo "::: Enables client conf profiles"
echo ":::"
echo "::: Usage: pivpn <-on|on> [-h|--help] [-v] [<client-1> ... [<client-2>] ...] "
echo ":::"
echo "::: Commands:"
echo "::: [none] Interactive mode"
echo "::: <client> Client"
echo "::: -y,--yes Enable client(s) without confirmation"
echo "::: -v Show disabled clients only"
echo "::: -h,--help Show this help dialog"
echo "::: Enables client conf profiles"
echo ":::"
echo "::: Usage: pivpn <-on|on> [-h|--help] [-v] [<client-1> ... [<client-2>] ...] "
echo ":::"
echo "::: Commands:"
echo "::: [none] Interactive mode"
echo "::: <client> Client"
echo "::: -y,--yes Enable client(s) without confirmation"
echo "::: -v Show disabled clients only"
echo "::: -h,--help Show this help dialog"
}
# Parse input arguments
while test $# -gt 0
do
_key="$1"
case "$_key" in
-h|--help)
helpFunc
exit 0
;;
-y|--yes)
CONFIRM=true
;;
-v)
DISPLAY_DISABLED=true
;;
while test $# -gt 0; do
_key="$1"
case "$_key" in
-h|--help)
helpFunc
exit 0
;;
-y|--yes)
CONFIRM=true
;;
-v)
DISPLAY_DISABLED=true
;;
*)
CLIENTS_TO_CHANGE+=("$1")
;;
esac
shift
CLIENTS_TO_CHANGE+=("$1")
;;
esac
shift
done
cd /etc/wireguard || exit
if [ ! -s configs/clients.txt ]; then
echo "::: There are no clients to change"
exit 1
echo "::: There are no clients to change"
exit 1
fi
if [ "$DISPLAY_DISABLED" ]; then
grep '\[disabled\] ### begin' wg0.conf | sed 's/#//g; s/begin//'
exit 1
grep '\[disabled\] ### begin' wg0.conf | sed 's/#//g; s/begin//'
exit 1
fi
mapfile -t LIST < <(awk '{print $1}' configs/clients.txt)
if [ "${#CLIENTS_TO_CHANGE[@]}" -eq 0 ]; then
echo -e "::\e[4m Client list \e[0m::"
len=${#LIST[@]}
COUNTER=1
while [ $COUNTER -le "${len}" ]; do
printf "%0${#len}s) %s\r\n" "${COUNTER}" "${LIST[(($COUNTER-1))]}"
((COUNTER++))
done
echo -e "::\e[4m Client list \e[0m::"
len=${#LIST[@]}
COUNTER=1
while [ $COUNTER -le "${len}" ]; do
printf "%0${#len}s) %s\r\n" "${COUNTER}" "${LIST[(($COUNTER-1))]}"
((COUNTER++))
done
read -r -p "Please enter the Index/Name of the Client to be enabled from the list above: " CLIENTS_TO_CHANGE
read -r -p "Please enter the Index/Name of the Client to be enabled from the list above: " CLIENTS_TO_CHANGE
if [ -z "${CLIENTS_TO_CHANGE}" ]; then
echo "::: You can not leave this blank!"
exit 1
fi
if [ -z "${CLIENTS_TO_CHANGE}" ]; then
echo "::: You can not leave this blank!"
exit 1
fi
fi
CHANGED_COUNT=0
for CLIENT_NAME in "${CLIENTS_TO_CHANGE[@]}"; do
re='^[0-9]+$'
if [[ ${CLIENT_NAME} =~ $re ]] ; then
CLIENT_NAME=${LIST[$((CLIENT_NAME -1))]}
fi
re='^[0-9]+$'
if [[ ${CLIENT_NAME} =~ $re ]] ; then
CLIENT_NAME=${LIST[$((CLIENT_NAME -1))]}
fi
if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then
echo -e "::: \e[1m${CLIENT_NAME}\e[0m does not exist"
else
if [ -n "$CONFIRM" ]; then
REPLY="y"
else
read -r -p "Confirm you want to enable $CLIENT_NAME? [Y/n] "
fi
if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then
echo -e "::: \e[1m${CLIENT_NAME}\e[0m does not exist"
else
if [ -n "$CONFIRM" ]; then
REPLY="y"
else
read -r -p "Confirm you want to enable $CLIENT_NAME? [Y/n] "
fi
if [[ $REPLY =~ ^[Yy]$ ]]; then
if [[ $REPLY =~ ^[Yy]$ ]]; then
# Enable the peer section from the server config
echo "${CLIENT_NAME}"
sed -e "/begin ${CLIENT_NAME}/,/end ${CLIENT_NAME}/ s/#\[disabled\] //" -i wg0.conf
echo "::: Updated server config"
# Enable the peer section from the server config
echo "${CLIENT_NAME}"
sed -e "/begin ${CLIENT_NAME}/,/end ${CLIENT_NAME}/ s/#\[disabled\] //" -i wg0.conf
echo "::: Updated server config"
((CHANGED_COUNT++))
echo "::: Successfully enabled ${CLIENT_NAME}"
((CHANGED_COUNT++))
echo "::: Successfully enabled ${CLIENT_NAME}"
fi
fi
fi
fi
done
# Restart WireGuard only if some clients were actually deleted
if [ "${CHANGED_COUNT}" -gt 0 ]; then
if systemctl reload wg-quick@wg0; then
echo "::: WireGuard reloaded"
else
echo "::: Failed to reload WireGuard"
fi
if [ "${PLAT}" == 'Alpine' ]; then
if rc-service wg-quick restart; then
echo "::: WireGuard reloaded"
else
echo "::: Failed to reload WireGuard"
fi
else
if systemctl reload wg-quick@wg0; then
echo "::: WireGuard reloaded"
else
echo "::: Failed to reload WireGuard"
fi
fi
fi

View file

@ -171,10 +171,18 @@ if [ -f /etc/pivpn/hosts.wireguard ]; then
fi
fi
if systemctl reload wg-quick@wg0; then
echo "::: WireGuard reloaded"
if [ "${PLAT}" == 'Alpine' ]; then
if rc-service wg-quick restart; then
echo "::: WireGuard reloaded"
else
echo "::: Failed to reload WireGuard"
fi
else
echo "::: Failed to reload WireGuard"
if systemctl reload wg-quick@wg0; then
echo "::: WireGuard reloaded"
else
echo "::: Failed to reload WireGuard"
fi
fi
cp "configs/${CLIENT_NAME}.conf" "${install_home}/configs/${CLIENT_NAME}.conf"

View file

@ -1,8 +1,14 @@
#!/bin/bash
CHECK_PKG_INSTALLED='dpkg-query -s'
if grep -qsEe "^NAME\=['\"]?Alpine[a-zA-Z ]*['\"]?$" /etc/os-release; then
CHECK_PKG_INSTALLED='apk --no-cache info -e'
fi
# Must be root to use this tool
if [ $EUID -ne 0 ];then
if dpkg-query -s sudo &> /dev/null; then
if [ $EUID -ne 0 ]; then
if eval "${CHECK_PKG_INSTALLED} sudo" &> /dev/null; then
export SUDO="sudo"
else
echo "::: Please install sudo or run this as root."

View file

@ -15,8 +15,7 @@ helpFunc(){
# Parse input arguments
encoding="ansiutf8"
while test $# -gt 0
do
while test $# -gt 0; do
_key="$1"
case "$_key" in
-h|--help)

View file

@ -144,9 +144,17 @@ done
# Restart WireGuard only if some clients were actually deleted
if [ "${DELETED_COUNT}" -gt 0 ]; then
if systemctl reload wg-quick@wg0; then
echo "::: WireGuard reloaded"
if [ "${PLAT}" == 'Alpine' ]; then
if rc-service wg-quick restart; then
echo "::: WireGuard reloaded"
else
echo "::: Failed to reload WireGuard"
fi
else
echo "::: Failed to reload WireGuard"
if systemctl reload wg-quick@wg0; then
echo "::: WireGuard reloaded"
else
echo "::: Failed to reload WireGuard"
fi
fi
fi