wireguard/create_wireguard_config.sh

1325 lines
34 KiB
Bash
Executable File

#!/usr/bin/env bash
script_name="$(basename $(realpath $0))"
script_dir="$(dirname $(realpath $0))"
conf_file="${script_dir}/conf/${script_name%%.*}.conf"
LOCK_DIR="/tmp/${script_name%%.*}.LOCK"
log_file="${LOCK_DIR}/${script_name%%.*}.log"
backup_date="$(date +%Y-%m-%d-%H%M)"
_needed_debian_packages="wireguard"
declare -a needed_debian_package_arr=()
# -------------
# - Default values
# -------------
# - Give your default values here
# -
DEFAULT_WG_LISTEN_PORT=51820
DEFAULT_WG_SERVER_DIR="/etc/wireguard"
# ----------
# Base Function(s)
# ----------
clean_up() {
# Perform program exit housekeeping
rm -rf "${LOCK_DIR}"
blank_line
exit $1
}
echononl(){
if $terminal ; then
echo X\\c > /tmp/shprompt$$
if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then
echo -e -n " $*\\c" 1>&2
else
echo -e -n " $*" 1>&2
fi
rm /tmp/shprompt$$
fi
}
fatal(){
echo ""
if $terminal ; then
echo -e " [ \033[31m\033[1mFatal\033[m ]: $*"
echo ""
echo -e " \033[31m\033[1mScript was interupted\033[m!"
else
echo " [ Fatal ]: $*"
echo ""
echo " Script was terminated...."
fi
echo ""
clean_up 1
}
error (){
echo ""
if $terminal ; then
echo -e " [ \033[31m\033[1mError\033[m ]: $*"
else
echo " [ Error ]: $*"
fi
echo ""
}
warn (){
if $terminal ; then
echo ""
echo -e " [ \033[33m\033[1mWarning\033[m ]: $*"
echo ""
fi
}
info (){
if $terminal ; then
echo ""
echo -e " [ \033[32m\033[1mInfo\033[m ]: $*"
echo ""
fi
}
ok (){
if $terminal ; then
echo ""
echo -e " [ \033[32m\033[1mOk\033[m ] $*"
echo ""
fi
}
echo_done() {
if $terminal ; then
echo -e "\033[75G[ \033[32mdone\033[m ]"
fi
}
echo_ok() {
if $terminal ; then
echo -e "\033[75G[ \033[32mok\033[m ]"
fi
}
echo_warn() {
if $terminal ; then
echo -e "\033[75G[ \033[33mwarn\033[m ]"
fi
}
echo_failed(){
if $terminal ; then
echo -e "\033[75G[ \033[1;31mfailed\033[m ]"
fi
}
echo_skipped() {
if $terminal ; then
echo -e "\033[75G[ \033[90m\033[1mskipped\033[m ]"
fi
}
echo_wait(){
if $terminal ; then
echo -en "\033[75G[ \033[5m\033[1m...\033[m ]"
fi
}
trim() {
local var="$*"
var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters
var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters
echo -n "$var"
}
blank_line() {
if $terminal ; then
echo ""
fi
}
is_number() {
return $(test ! -z "${1##*[!0-9]*}" > /dev/null 2>&1);
# - also possible
# -
#[[ ! -z "${1##*[!0-9]*}" ]] && return 0 || return 1
#return $([[ ! -z "${1##*[!0-9]*}" ]])
}
is_int() {
return $(test "$@" -eq "$@" > /dev/null 2>&1);
}
# ----------
# - Jobhandling
# ----------
# - Run 'clean_up' for signals SIGHUP SIGINT SIGTERM
# -
trap clean_up SIGHUP SIGINT SIGTERM
# - Create lock directory '$LOCK_DIR"
#
mkdir "$LOCK_DIR"
# ----------
# - Some checks ..
# ----------
# - Running in a terminal?
# -
if [[ -t 1 ]] ; then
terminal=true
else
terminal=false
fi
declare -a conf_file_arr=()
declare -a conf_name_arr=()
for _conf_file in `ls ${script_dir}/conf/wireguard-*.conf 2>/dev/null` ; do
conf_file_arr+=("${_conf_file}")
_basename=$(basename $_conf_file)
_tmp_name=${_basename%%.*}
_tmp_name=${_tmp_name#*-}
conf_name_arr+=("$_tmp_name")
done
if [[ ${#conf_file_arr[@]} -lt 1 ]] ; then
fatal "NO Configuration found!"
fi
echo ""
declare -i i=0
if [[ ${#conf_file_arr[@]} -gt 1 ]] ; then
echo ""
echo "Which Configuration should be loaded?"
echo ""
for _conf_file in ${conf_file_arr[@]} ; do
echo " [${i}] ${conf_name_arr[${i}]}"
(( i++ ))
done
_OK=false
echo
echononl "Eingabe: "
while ! $_OK ; do
read _IN
if is_number "$_IN" && [[ -n ${conf_file_arr[$_IN]} ]]; then
conf_file=${conf_file_arr[$_IN]}
WG_INSTANCE_NAME=${conf_name_arr[$_IN]}
_OK=true
else
echo ""
echo -e "\tFalsche Eingabe !"
echo ""
echononl "Eingabe: "
fi
done
else
conf_file=${conf_file_arr[0]}
WG_INSTANCE_NAME=${conf_name_arr[0]}
fi
echononl " Load Configuration File $(basename ${conf_file}).."
if [[ ! -f "$conf_file" ]]; then
echo_failed
fatal "Configuration file \033[37m\033[1m$(basename ${conf_file})\033[m not found!"
else
source "${conf_file}" > $log_file 2>&1
if [[ $? -eq 0 ]]; then
echo_ok
else
echo_failed
fatal "$(cat $log_file)"
fi
fi
[[ -z "$COMPANY_TOKEN" ]] && fatal "No value for parameter \033[1mCOMPANY_TOKEN\033[m was given"
[[ -z "$WG_SERVER_ENDPOINT" ]] && fatal "No value for parameter \033[1mWG_SERVER_ENDPOINT\033[m was given"
[[ -z "${WG_ALLOWED_IPS}" ]] && fatal "No IP range for WG service was given (variable \033[1mWG_ALLOWED_IPS\033[m).."
declare -i index=1
for _ip in ${WG_ALLOWED_IPS}; do
if [[ $index -eq 1 ]]; then
WG_ALLOWED_IP_LIST="$_ip"
else
WG_ALLOWED_IP_LIST="$WG_ALLOWED_IP_LIST, $_ip"
fi
(( index++ ))
done
[[ -z "${WG_LISTEN_PORT}" ]] && WG_LISTEN_PORT="${DEFAULT_WG_LISTEN_PORT}"
[[ -z "${WG_SERVER_DIR}" ]] && WG_SERVER_DIR="${DEFAULT_WG_SERVER_DIR}"
WG_SERVER_KEY_DIR="${WG_SERVER_DIR}/Server"
[[ -z "${WG_CLIENT_BASE_DIR}" ]] && WG_CLIENT_BASE_DIR="${WG_SERVER_DIR}/Clients"
[[ -z "${WG_SERVER_CONFIG}" ]] && WG_SERVER_CONFIG="${WG_SERVER_DIR}/wg-${COMPANY_TOKEN}-${WG_INSTANCE_NAME}.conf"
_basename_server_config="$(basename "${WG_SERVER_CONFIG}")"
WG_SERVICE_NAME="${_basename_server_config%%.*}"
WG_SYSTEMD_SERVICE="wg-quick@${WG_SERVICE_NAME}"
if $terminal ; then
echo ""
echo ""
echo -e " \033[32mGoing to install WireGuard\033[m"
echo ""
fi
# Check if needed debian package(s) are installed
#
_error=false
: > $log_file
blank_line
echononl "Check if needed packages are installed.."
for _pkg in $_needed_debian_packages ; do
if aptitude search "$_pkg" | grep " $_pkg " | grep -e "^i" >> "$log_file" 2>&1 ; then
continue
else
needed_debian_package_arr+=("$_pkg")
fi
[[ $? -gt 0 ]] && _error=true
done
if $_error ; then
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
else
echo_ok
fi
if [[ ${#needed_debian_package_arr[@]} -gt 0 ]]; then
# Download package information from all configured sources.
#
echononl "Download package information from all configured sources.."
apt-get update > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
# Upgrade Packages
#
echononl "Upgrade Packages.."
apt-get full-upgrade > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
for _debian_pkg in ${needed_debian_package_arr[@]} ; do
if [[ "$_debian_pkg" = "wireguard" ]]; then
echononl "Backup directory '/etc/wireguard'.."
if [[ -d "/etc/wireguard" ]] || [[ -f "/etc/wireguard" ]] ; then
mv "/etc/wireguard" "/etc/wireguard.${backup_date}" > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
else
echo_skipped
fi
fi
echononl "Installing $_debian_pkg .."
DEBIAN_FRONTEND=noninteractive apt-get -y install $_debian_pkg > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
done
else
echononl "Installing needed debian packages.."
echo_skipped
fi
blank_line
if [[ ! -d "$WG_SERVER_DIR" ]] ; then
echononl "Directory '$WG_SERVER_DIR' does not exist. Create it.."
mkdir "$WG_SERVER_DIR" > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
fi
echo ""
echo -e "\033[32m--\033[m"
echo ""
WG_NEW_CLIENT_NAME=""
if [ -z "$WG_NEW_CLIENT_NAME" ]; then
echo "Insert key name."
echo ""
echo ""
echononl "key name: "
read WG_NEW_CLIENT_NAME
while [ "X$WG_NEW_CLIENT_NAME" = "X" ] ; do
echo -e "\n\t\033[33m\033[1mKey name is required!\033[m\n"
echononl "key name: "
read WG_NEW_CLIENT_NAME
done
fi
WG_CLIENT_DIR="${WG_CLIENT_BASE_DIR}/${WG_NEW_CLIENT_NAME}"
WG_CLIENT_CONFIG="${WG_CLIENT_DIR}/wg-${COMPANY_TOKEN}-${WG_NEW_CLIENT_NAME}.conf"
blank_line
echononl "Generate a preshared key (using command: \033[1mwg genpsk\033[m.."
WG_CLIENT_PESHARED_KEY="$(wg genpsk 2> "$log_file")"
if [[ -s "$log_file" ]] ; then
echo_failed
error "Command was:
\033[1mWG_CLIENT_PESHARED_KEY=\"\$(wg genpsk 2> \"$log_file\")\033[m
$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
else
echo_ok
fi
declare -a octets=()
octets=( ${WG_NETWORK//\./ } )
if [[ -f "${WG_SERVER_CONFIG}" ]]; then
WG_SERVER_CONFIG_PRESENT=true
_found=false
while IFS='' read -r _line || [[ -n $_line ]] ; do
if $(echo "$_line" | grep -i -E "^\[Interface\]" > /dev/null 2>&1) ; then
_found=true
fi
if $_found ; then
if $(echo "$_line" | grep -q -e "^[[:space:]]*$" > /dev/null 2>&1) ; then
_found=false
fi
fi
if $_found ; then
if $(echo "$_line" | grep -i -E "^\s*PrivateKey" > /dev/null 2>&1) ; then
WG_SERVER_PRIV_KEY="$(trim "${_line#*=}")"
WG_SERVER_PUB_KEY="$(echo ${WG_SERVER_PRIV_KEY} | wg pubkey)"
fi
if $(echo "$_line" | grep -i -E "^\s*Address" > /dev/null 2>&1) ; then
WG_SERVER_IPv4="$(trim "${_line#*=}")"
WG_SERVER_IPv4="${WG_SERVER_IPv4%/*}"
fi
fi
done < "${WG_SERVER_CONFIG}"
octets=( ${WG_SERVER_IPv4//\./ } )
if [[ ${octets[3]} -eq 101 ]] ; then
WG_CLIENT_FIRST_IPv4="${octets[0]}.${octets[1]}.${octets[2]}.102"
else
WG_CLIENT_FIRST_IPv4="${octets[0]}.${octets[1]}.${octets[2]}.101"
fi
WG_CLIENT_IPv4="${WG_CLIENT_FIRST_IPv4}"
while grep -E -i -q "^\s*AllowedIPs\s*=\s*${WG_CLIENT_IPv4}" "${WG_SERVER_CONFIG}" 2> "/dev/null" ; do
octets=()
octets=( ${WG_CLIENT_IPv4//\./ } )
WG_CLIENT_IPv4="${octets[0]}.${octets[1]}.${octets[2]}.$(expr ${octets[3]} + 1)"
done
else
WG_SERVER_CONFIG_PRESENT=false
octets=( ${WG_NETWORK//\./ } )
WG_SERVER_IPv4="${octets[0]}.${octets[1]}.${octets[2]}.1/32"
WG_CLIENT_IPv4="${octets[0]}.${octets[1]}.${octets[2]}.101"
fi
WG_ALLOWED_IP_LIST="$WG_ALLOWED_IP_LIST, $WG_SERVER_IPv4"
if $terminal ; then
echo ""
echo ""
echo -e " \033[1m----------\033[m"
echo ""
echo " Wireguard Server directory.......: $WG_SERVER_DIR"
echo " Wireguard Server Configuration...: $WG_SERVER_CONFIG"
echo ""
echo " Wireguard Server IPv4 Address....: $WG_SERVER_IPv4"
echo " Wireguard Server Listen Port.....: $WG_LISTEN_PORT"
echo ""
echo -e " Wireguard service name...........: \033[33m${WG_SERVICE_NAME}\033[m"
echo -e " Wireguard systemd service........: \033[33m${WG_SYSTEMD_SERVICE}\033[m"
if $WG_SERVER_CONFIG_PRESENT ; then
echo ""
echo -e " Wireguard Server Private Key.....: \033[33m${WG_SERVER_PRIV_KEY}\033[m"
echo -e " Wireguard Server Public Key......: \033[33m${WG_SERVER_PUB_KEY}\033[m"
fi
echo ""
echo " Wireguard Client Base dir........: $WG_CLIENT_BASE_DIR"
echo " Wireguard Client dir.............: $WG_CLIENT_DIR"
echo ""
echo " Wireguard Client Configuration...: $WG_CLIENT_CONFIG"
echo ""
echo " Wireguard Instance Name..........: $WG_INSTANCE_NAME"
echo ""
echo " Company token....................: $COMPANY_TOKEN"
echo ""
echo " New Client Name..................: $WG_NEW_CLIENT_NAME"
echo " Client IPv4 Address..............: $WG_CLIENT_IPv4"
echo " Client Allowed IPv4 Address......: $WG_ALLOWED_IP_LIST"
echo ""
echo " Clients preshared key............: $WG_CLIENT_PESHARED_KEY"
echo ""
echo -e " \033[1m----------\033[m"
if [ "$(id -u)" -ne 0 ]; then
warn "You may want to run this script with root privileges. Then stop here and
start again with the following command::
\033[1msudo $0\033[m"
fi
echo ""
echo -n " Type upper case 'YES' to start: "
read OK
if [[ "$OK" != "YES" ]] ; then
fatal "Abort by user request - Answer iwas not 'YES'"
fi
echo ""
fi
# ----------
# Installing WireGuard and Generating a (Server) Key Pair
# ----------
if $terminal ; then
echo ""
echo ""
echo -e " \033[32mGenerating a Server Configuraation\033[m"
echo ""
fi
if $WG_SERVER_CONFIG_PRESENT ; then
info "Server Configuration for WireGuard already exists"
else
echononl "Create directory, where this script saves server keys and server configuration."
if [[ ! -d "${WG_SERVER_KEY_DIR}" ]]; then
mkdir "${WG_SERVER_KEY_DIR}" > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
else
echo_skipped
fi
echononl "Place a README file in directory '${WG_SERVER_KEY_DIR}'.."
if [[ ! -d "${WG_SERVER_KEY_DIR}/README" ]] ; then
cat <<EOF > "${WG_SERVER_KEY_DIR}/README" 2> "$log_file"
# Directory: ${WG_SERVER_KEY_DIR}
#
# *********************************************************************************************
# This directory is NOT part of wireguard distribution and is NOT needed for running wireguard.
# *********************************************************************************************
#
# This directory holds configuration history and also servers private and public key
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
else
echo_skipped
fi
blank_line
echononl "Generate servers private key.."
WG_SERVER_PRIV_KEY="$(wg genkey | tee "${WG_SERVER_KEY_DIR}/wg-${COMPANY_TOKEN}-${WG_INSTANCE_NAME}-private.key" 2> "$log_file")"
if [[ -s "$log_file" ]] ; then
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
else
echo_ok
fi
echononl "Change permissions (ugo= ) on newly created private key.."
chmod go= "${WG_SERVER_KEY_DIR}/wg-${COMPANY_TOKEN}-${WG_INSTANCE_NAME}-private.key" > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
echononl "Get servers concerning public key.."
WG_SERVER_PUB_KEY="$(echo "${WG_SERVER_PRIV_KEY}" | wg pubkey | tee "${WG_SERVER_KEY_DIR}/wg-${COMPANY_TOKEN}-${WG_INSTANCE_NAME}-public.key" 2> "$log_file")"
if [[ -s "$log_file" ]] ; then
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
else
echo_ok
fi
echononl "Create WireGuard Server Configuration"
cat <<EOF > ${WG_SERVER_CONFIG} 2> "$log_file"
[Interface]
Address = ${WG_SERVER_IPv4}
#SaveConfig = true
ListenPort = ${WG_LISTEN_PORT}
PrivateKey = ${WG_SERVER_PRIV_KEY}
EOF
if [[ -s "$log_file" ]] ; then
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
else
echo_ok
fi
echononl "Save a copy of server Configuration at '${WG_SERVER_PRIV_KEY}'.."
cp -a "${WG_SERVER_CONFIG}" "${WG_SERVER_DIR}/" > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
fi
if $terminal ; then
echo ""
echo ""
echo -e " \033[32mConfigure a WireGuard Peer\033[m"
echo ""
fi
# Backup existing client configuration file
#
echononl "Backup existing client configuration file.."
if [[ -f "${WG_CLIENT_CONFIG}" ]]; then
mv "${WG_CLIENT_CONFIG}" "${WG_CLIENT_CONFIG}.${backup_date}" > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
else
echo_skipped
fi
# Backup existing private key ...
#
echononl "Backup existing (Cient) private key.."
if [[ -f "${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-private.key" ]]; then
mv "${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-private.key" \
"${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-private.key.${backup_date}" > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
else
echo_skipped
fi
# Backup existing public key ...
#
_client_key_already_present=false
echononl "Backup existing (Cient) public key.."
if [[ -f "${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-public.key" ]]; then
_client_key_already_present=true
mv "${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-public.key" \
"${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-public.key.${backup_date}" > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
else
echo_skipped
fi
# Backup existing preshared key ...
#
echononl "Backup existing preshared key.."
if [[ -f "${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-preshared.key" ]]; then
mv "${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-preshared.key" \
"${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-preshared.key.${backup_date}" > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
else
echo_skipped
fi
if $_client_key_already_present ; then
WG_CLIENT_OLD_PUBLIC_KEY="$(trim $(cat "${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-public.key.${backup_date}"))"
else
WG_CLIENT_OLD_PUBLIC_KEY=""
fi
# '+' sign breaks regexp in grep-statement.
# We need to replace '+' with '\+'
#
_CHECK_WG_CLIENT_OLD_PUBLIC_KEY="${WG_CLIENT_OLD_PUBLIC_KEY//+/\\+}"
blank_line
echononl "Delete existing configuration for \033[1m${WG_NEW_CLIENT_NAME}\033[m"
echo_wait
if $WG_SERVER_CONFIG_PRESENT && [[ -n "${WG_CLIENT_OLD_PUBLIC_KEY}" ]]; then
_server_configfile_name="$(basename "${WG_SERVER_CONFIG}")"
_tmp_server_configfile_name="_$(basename "${WG_SERVER_CONFIG}")"
if $(grep -q -E "^\s*PublicKey\s*=\s*${_CHECK_WG_CLIENT_OLD_PUBLIC_KEY}" "${WG_SERVER_CONFIG}" 2> "/dev/null") ; then
_found=false
_last_line="X"
declare -i index=1
_number_of_lines="$(wc -l < ${WG_SERVER_CONFIG})"
: > "${LOCK_DIR}/${_server_configfile_name}"
while IFS='' read -r _line || [[ -n $_line ]] ; do
(( index++ ))
if $(echo "$_line" | grep -q -e "^[[:space:]]*$" > /dev/null 2>&1) \
&& $(echo "$_last_line" | grep -q -e "^[[:space:]]*$" > /dev/null 2>&1) ; then
continue
else
echo "${_line}" >> "${LOCK_DIR}/${_tmp_server_configfile_name}"
fi
if $(echo "$_line" | grep -q -e "^[[:space:]]*$" > /dev/null 2>&1) \
|| [[ $index -gt $_number_of_lines ]]; then
if ! $_found ; then
cat "${LOCK_DIR}/${_tmp_server_configfile_name}" >> "${LOCK_DIR}/${_server_configfile_name}" 2> "$log_file"
else
_found=false
fi
: > "${LOCK_DIR}/${_tmp_server_configfile_name}"
else
if $(echo "$_line" | grep -q -E "^\s*PublicKey\s*=\s*${_CHECK_WG_CLIENT_OLD_PUBLIC_KEY}" 2> "/dev/null") ; then
_found=true
fi
fi
_last_line="${_line}"
done < "${WG_SERVER_CONFIG}"
if [[ -s "$log_file" ]] ; then
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
else
echo_ok
fi
echononl "Write back WireGuard Server configuration.."
mv "${LOCK_DIR}/${_server_configfile_name}" "${WG_SERVER_CONFIG}" > "$log_file" 2>&1
if [[ $? -eq 0 ]]; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
else
echo_skipped
fi
else
echo_skipped
fi
# Create client base directory if not exists
#
echononl "Create client base directory if not exists .."
if [[ ! -d "${WG_CLIENT_BASE_DIR}" ]] ; then
mkdir "${WG_CLIENT_BASE_DIR}" > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
else
echo_skipped
fi
echononl "Place a README file in directory '${WG_CLIENT_BASE_DIR}'.."
if [[ ! -d "${WG_CLIENT_BASE_DIR}/README" ]] ; then
cat <<EOF > "${WG_CLIENT_BASE_DIR}/README" 2> "$log_file"
# Directory: ${WG_CLIENT_BASE_DIR}
#
# *********************************************************************************************
# This directory is NOT part of wireguard distribution and is NOT needed for running wireguard.
# *********************************************************************************************
#
# This directory holds client configurations and also clients private and public key
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
else
echo_skipped
fi
# Create client directory if not exists
#
echononl "Create client directory if not exists .."
if [[ ! -d "${WG_CLIENT_BASE_DIR}/${WG_NEW_CLIENT_NAME}" ]] ; then
mkdir "${WG_CLIENT_BASE_DIR}/${WG_NEW_CLIENT_NAME}" > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
else
echo_skipped
fi
blank_line
# Create the private key for new WireGuard Client
#
echononl "Create the private key for new WireGuard Client '${WG_NEW_CLIENT_NAME}'.."
wg genkey > "${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-private.key" 2> "$log_file"
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "Command was:
\033[1mwg genkey > \"${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-private.key\"\033[m
$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
# Change permissions on newly created key
#
echononl "Change permissions (ugo= ) on newly created key.."
chmod go= "${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-private.key" 2> "$log_file"
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "Command was:
\033[1mchmod go= \"${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-private.key\"\033[m
$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
# Create corresponding public key
#
echononl "Create corresponding public key for Client '${WG_NEW_CLIENT_NAME}'.."
cat "${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-private.key" \
| wg pubkey > "${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-public.key" 2> "$log_file"
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "Command was:
\033[1mcat \"${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-private.key\" \\
| wg pubkey > \"${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-public.key\"\033[m
$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
echononl "Save preshared key into file '${WG_NEW_CLIENT_NAME}-preshared.key'.."
echo "${WG_CLIENT_PESHARED_KEY}" > ""${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-preshared.key"" 2> "$log_file"
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
fi
echononl "Backup server configuration at '${WG_SERVER_CONFIG}'.."
if [[ -f "${WG_SERVER_CONFIG}" ]]; then
cp -a "${WG_SERVER_CONFIG}" \
"${WG_SERVER_KEY_DIR}/$(basename "${WG_SERVER_CONFIG}").${backup_date}" > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
else
echo_skipped
fi
echononl "Create client configuration file.."
cat <<EOF > "${WG_CLIENT_CONFIG}" 2> "$log_file"
[Interface]
Address = ${WG_CLIENT_IPv4}
PrivateKey = $(cat "${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-private.key")
ListenPort = ${WG_LISTEN_PORT}
DNS = ${WG_DNS}
[Peer]
PublicKey = ${WG_SERVER_PUB_KEY}
PresharedKey = ${WG_CLIENT_PESHARED_KEY}
AllowedIPs = ${WG_ALLOWED_IP_LIST}
Endpoint = ${WG_SERVER_ENDPOINT}:${WG_LISTEN_PORT}
EOF
if [[ -s "$log_file" ]] ; then
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
else
echo_ok
fi
echononl "Add client configuration to server configuration file.."
cat <<EOF >> ${WG_SERVER_CONFIG} 2> "$log_file"
# ${WG_NEW_CLIENT_NAME}
[Peer]
PublicKey = $(cat "${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-public.key")
PresharedKey = ${WG_CLIENT_PESHARED_KEY}
AllowedIPs = ${WG_CLIENT_IPv4}
EOF
if [[ -s "$log_file" ]] ; then
echo_failed
error "Command was:
\033[1mwg genkey > \"${WG_CLIENT_DIR}/${WG_NEW_CLIENT_NAME}-private.key\"\033[m
$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
else
echo_ok
fi
echononl "Save a copy of server configuration at '${WG_SERVER_PRIV_KEY}'.."
cp -a "${WG_SERVER_CONFIG}" "${WG_SERVER_KEY_DIR}/" > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
blank_line
if $WG_SERVER_CONFIG_PRESENT ; then
echononl "Reload WireGuard Service"
systemctl reload ${WG_SYSTEMD_SERVICE} > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "Command was:
\033[1msystemctl reload ${WG_SYSTEMD_SERVICE}\033[m
$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
else
echononl "Enable Wireguard Service at boottime and start service now.."
systemctl enable --now ${WG_SYSTEMD_SERVICE} > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "Command was:
\033[1msystemctl enable --now ${WG_SYSTEMD_SERVICE}\033[m
$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Interrupted by user."
fi
fi
blank_line
warn "Please do not forget to set up port forwarding (${ListenPort}) in the DSL router."
blank_line
clean_up 0