mirror of
https://github.com/pivpn/pivpn.git
synced 2024-12-28 07:42:19 +00:00
Added missing script folder
This commit is contained in:
parent
24a1a00d37
commit
5e16322f9e
15 changed files with 1681 additions and 0 deletions
36
scripts/openvpn/backup.sh
Executable file
36
scripts/openvpn/backup.sh
Executable file
|
@ -0,0 +1,36 @@
|
||||||
|
#!/bin/bash
|
||||||
|
setupVars="/etc/pivpn/setupVars.conf"
|
||||||
|
backupdir=pivpnbackup
|
||||||
|
openvpndir=/etc/openvpn
|
||||||
|
ovpnsdir=${install_home}/ovpns
|
||||||
|
date=$(date +%Y-%m-%d-%H%M%S)
|
||||||
|
|
||||||
|
if [ ! -f "${setupVars}" ]; then
|
||||||
|
echo "::: Missing setup vars file!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
source "${setupVars}"
|
||||||
|
|
||||||
|
backup_openvpn(){
|
||||||
|
if [[ ! -d $install_home/$backupdir ]]; then
|
||||||
|
mkdir $install_home/$backupdir
|
||||||
|
fi
|
||||||
|
cp -r $openvpndir $ovpnsdir $backupdir 2&>1
|
||||||
|
backupzip=$date-pivpnbackup.tgz
|
||||||
|
tar -czf $backupzip -C ${install_home} $backupdir 2&>1
|
||||||
|
echo -e "Backup crated to $install_home/$backupdir/$backupzip \nTo restore the backup, follow instructions at:\nhttps://github.com/pivpn/pivpn/wiki/FAQ#how-can-i-migrate-my-configs-to-another-pivpn-instance"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if [[ ! $EUID -eq 0 ]];then
|
||||||
|
if [[ $(dpkg-query -s sudo) ]];then
|
||||||
|
export SUDO="sudo"
|
||||||
|
else
|
||||||
|
echo "::: Please install sudo or run this as root."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
backup_openvpn
|
||||||
|
|
22
scripts/openvpn/bash-completion
Normal file
22
scripts/openvpn/bash-completion
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
_pivpn()
|
||||||
|
{
|
||||||
|
local cur prev opts
|
||||||
|
COMPREPLY=()
|
||||||
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
|
dashopts="-a -c -d -l -r -h -u -up"
|
||||||
|
opts="debug add clients list revoke uninstall help update"
|
||||||
|
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
|
||||||
|
COMPREPLY=( $(compgen -W "nopass" -- "${cur}") )
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
complete -F _pivpn pivpn
|
35
scripts/openvpn/clientStat.sh
Executable file
35
scripts/openvpn/clientStat.sh
Executable file
|
@ -0,0 +1,35 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# PiVPN: client status script
|
||||||
|
|
||||||
|
STATUS_LOG="/var/log/openvpn-status.log"
|
||||||
|
|
||||||
|
function hr() {
|
||||||
|
numfmt --to=iec-i --suffix=B "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
printf "\n"
|
||||||
|
if [ ! -f "${STATUS_LOG}" ]; then
|
||||||
|
echo "The file: $STATUS_LOG was not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf ": NOTE : The output below is NOT real-time!\n"
|
||||||
|
printf ": : It may be off by a few minutes.\n"
|
||||||
|
printf "\n"
|
||||||
|
printf "\e[1m::: Client Status List :::\e[0m\n"
|
||||||
|
printf "\t\t\t\t\t\t\t\tBytes\t\tBytes\t\n"
|
||||||
|
printf "\e[4mName\e[0m\t\t\t\e[4mRemote IP\e[0m\t\t\e[4mVirtual IP\e[0m\t\e[4mReceived\e[0m\t\e[4mSent\e[0m\t\t\e[4mConnected Since\e[0m \n"
|
||||||
|
if grep -q "^CLIENT_LIST" "${STATUS_LOG}"; then
|
||||||
|
if [ -n "$(type -t numfmt)" ]; then
|
||||||
|
while read -r line; do
|
||||||
|
read -r -a array <<< $line
|
||||||
|
[[ ${array[0]} = CLIENT_LIST ]] || continue
|
||||||
|
printf "%s\t\t%s\t%s\t%s\t\t%s\t\t%s %s %s - %s\n" ${array[1]} ${array[2]} ${array[3]} $(hr ${array[4]}) $(hr ${array[5]}) ${array[7]} ${array[8]} ${array[10]} ${array[9]}
|
||||||
|
done <$STATUS_LOG
|
||||||
|
else
|
||||||
|
awk -F' ' -v s='CLIENT_LIST' '$1 == s {print $2"\t\t"$3"\t"$4"\t"$5"\t\t"$6"\t\t"$8" "$9" "$11" - "$10"\n"}' ${STATUS_LOG}
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
printf "\nNo Clients Connected!\n"
|
||||||
|
fi
|
||||||
|
printf "\n"
|
27
scripts/openvpn/listOVPN.sh
Executable file
27
scripts/openvpn/listOVPN.sh
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# PiVPN: list clients script
|
||||||
|
|
||||||
|
INDEX="/etc/openvpn/easy-rsa/pki/index.txt"
|
||||||
|
printf "\n"
|
||||||
|
if [ ! -f "${INDEX}" ]; then
|
||||||
|
echo "The file: $INDEX was not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf ": NOTE : The first entry should always be your valid server!\n"
|
||||||
|
printf "\n"
|
||||||
|
printf "\e[1m::: Certificate Status List :::\e[0m\n"
|
||||||
|
printf " ::\e[4m Status \e[0m||\e[4m Name \e[0m:: \n"
|
||||||
|
|
||||||
|
while read -r line || [ -n "$line" ]; do
|
||||||
|
STATUS=$(echo "$line" | awk '{print $1}')
|
||||||
|
NAME=$(echo "$line" | sed -e 's:.*/CN=::')
|
||||||
|
if [ "${STATUS}" == "V" ]; then
|
||||||
|
printf " Valid :: %s\n" "$NAME"
|
||||||
|
elif [ "${STATUS}" == "R" ]; then
|
||||||
|
printf " Revoked :: %s\n" "$NAME"
|
||||||
|
else
|
||||||
|
printf " Unknown :: %s\n" "$NAME"
|
||||||
|
fi
|
||||||
|
done <${INDEX}
|
||||||
|
printf "\n"
|
414
scripts/openvpn/makeOVPN.sh
Executable file
414
scripts/openvpn/makeOVPN.sh
Executable file
|
@ -0,0 +1,414 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Create OVPN Client
|
||||||
|
# Default Variable Declarations
|
||||||
|
setupVars="/etc/pivpn/setupVars.conf"
|
||||||
|
DEFAULT="Default.txt"
|
||||||
|
FILEEXT=".ovpn"
|
||||||
|
CRT=".crt"
|
||||||
|
KEY=".key"
|
||||||
|
CA="ca.crt"
|
||||||
|
TA="ta.key"
|
||||||
|
INDEX="/etc/openvpn/easy-rsa/pki/index.txt"
|
||||||
|
|
||||||
|
if [ ! -f "${setupVars}" ]; then
|
||||||
|
echo "::: Missing setup vars file!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
source "${setupVars}"
|
||||||
|
|
||||||
|
helpFunc() {
|
||||||
|
echo "::: Create a client ovpn profile, optional nopass"
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Usage: pivpn <-a|add> [-n|--name <arg>] [-p|--password <arg>]|[nopass] [-d|--days <number>] [-b|--bitwarden] [-i|--iOS] [-h|--help]"
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Commands:"
|
||||||
|
echo "::: [none] Interactive mode"
|
||||||
|
echo "::: nopass Create a client without a password"
|
||||||
|
echo "::: -n,--name Name for the Client (default: '"$(hostname)"')"
|
||||||
|
echo "::: -p,--password Password for the Client (no default)"
|
||||||
|
echo "::: -d,--days Expire the certificate after specified number of days (default: 1080)"
|
||||||
|
echo "::: -b,--bitwarden Create and save a client through Bitwarden"
|
||||||
|
echo "::: -i,--iOS Generate a certificate that leverages iOS keychain"
|
||||||
|
echo "::: -h,--help Show this help dialog"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -z "$HELP_SHOWN" ]; then
|
||||||
|
helpFunc
|
||||||
|
echo
|
||||||
|
echo "HELP_SHOWN=1" >> "$setupVars"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse input arguments
|
||||||
|
while test $# -gt 0
|
||||||
|
do
|
||||||
|
_key="$1"
|
||||||
|
case "$_key" in
|
||||||
|
-n|--name|--name=*)
|
||||||
|
_val="${_key##--name=}"
|
||||||
|
if test "$_val" = "$_key"
|
||||||
|
then
|
||||||
|
test $# -lt 2 && echo "Missing value for the optional argument '$_key'." && exit 1
|
||||||
|
_val="$2"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
NAME="$_val"
|
||||||
|
;;
|
||||||
|
-p|--password|--password=*)
|
||||||
|
_val="${_key##--password=}"
|
||||||
|
if test "$_val" = "$_key"
|
||||||
|
then
|
||||||
|
test $# -lt 2 && echo "Missing value for the optional argument '$_key'." && exit 1
|
||||||
|
_val="$2"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
PASSWD="$_val"
|
||||||
|
;;
|
||||||
|
-d|--days|--days=*)
|
||||||
|
_val="${_key##--days=}"
|
||||||
|
if test "$_val" = "$_key"
|
||||||
|
then
|
||||||
|
test $# -lt 2 && echo "Missing value for the optional argument '$_key'." && exit 1
|
||||||
|
_val="$2"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
DAYS="$_val"
|
||||||
|
;;
|
||||||
|
-i|--iOS)
|
||||||
|
iOS=1
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
helpFunc
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
nopass)
|
||||||
|
NO_PASS="1"
|
||||||
|
;;
|
||||||
|
-b|--bitwarden)
|
||||||
|
if which bw; then
|
||||||
|
BITWARDEN="2"
|
||||||
|
else
|
||||||
|
echo "Bitwarden not found, please install bitwarden"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Error: Got an unexpected argument '$1'"
|
||||||
|
helpFunc
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
# Functions def
|
||||||
|
|
||||||
|
function keynoPASS() {
|
||||||
|
|
||||||
|
#Build the client key
|
||||||
|
expect << EOF
|
||||||
|
set timeout -1
|
||||||
|
set env(EASYRSA_CERT_EXPIRE) "${DAYS}"
|
||||||
|
spawn ./easyrsa build-client-full "${NAME}" nopass
|
||||||
|
expect eof
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cd pki || exit
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function useBitwarden() {
|
||||||
|
|
||||||
|
# login and unlock vault
|
||||||
|
printf "****Bitwarden Login****"
|
||||||
|
printf "\n"
|
||||||
|
SESSION_KEY=`bw login --raw`
|
||||||
|
export BW_SESSION=$SESSION_KEY
|
||||||
|
printf "Successfully Logged in!"
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
|
# ask user for username
|
||||||
|
printf "Enter the username: "
|
||||||
|
read -r NAME
|
||||||
|
|
||||||
|
# check name
|
||||||
|
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: "
|
||||||
|
read -r NAME
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# ask user for length of password
|
||||||
|
printf "Please enter the length of characters you want your password to be (minimum 12): "
|
||||||
|
read -r LENGTH
|
||||||
|
|
||||||
|
# check length
|
||||||
|
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): "
|
||||||
|
read -r LENGTH
|
||||||
|
done
|
||||||
|
|
||||||
|
printf "Creating a PiVPN item for your vault..."
|
||||||
|
printf "\n"
|
||||||
|
# create a new item for your PiVPN Password
|
||||||
|
PASSWD=`bw generate -usln --length $LENGTH`
|
||||||
|
bw get template item | jq '.login.type = "1"'| jq '.name = "PiVPN"' | jq -r --arg NAME "$NAME" '.login.username = $NAME' | jq -r --arg PASSWD "$PASSWD" '.login.password = $PASSWD' | bw encode | bw create item
|
||||||
|
bw logout
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyPASS() {
|
||||||
|
|
||||||
|
if [[ -z "${PASSWD}" ]]; then
|
||||||
|
stty -echo
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
printf "Enter the password for the client: "
|
||||||
|
read -r PASSWD
|
||||||
|
printf "\n"
|
||||||
|
printf "Enter the password again to verify: "
|
||||||
|
read -r PASSWD2
|
||||||
|
printf "\n"
|
||||||
|
[ "${PASSWD}" = "${PASSWD2}" ] && break
|
||||||
|
printf "Passwords do not match! Please try again.\n"
|
||||||
|
done
|
||||||
|
stty echo
|
||||||
|
if [[ -z "${PASSWD}" ]]; then
|
||||||
|
echo "You left the password blank"
|
||||||
|
echo "If you don't want a password, please run:"
|
||||||
|
echo "pivpn add nopass"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
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=$(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')
|
||||||
|
|
||||||
|
#Build the client key and then encrypt the key
|
||||||
|
|
||||||
|
expect << EOF
|
||||||
|
set timeout -1
|
||||||
|
set env(EASYRSA_CERT_EXPIRE) "${DAYS}"
|
||||||
|
spawn ./easyrsa build-client-full "${NAME}"
|
||||||
|
expect "Enter PEM pass phrase" { send -- "${PASSWD}\r" }
|
||||||
|
expect "Verifying - Enter PEM pass phrase" { send -- "${PASSWD}\r" }
|
||||||
|
expect eof
|
||||||
|
EOF
|
||||||
|
cd pki || exit
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#make sure ovpns dir exists
|
||||||
|
if [ ! -d "$install_home/ovpns" ]; then
|
||||||
|
mkdir "$install_home/ovpns"
|
||||||
|
chmod 0750 "$install_home/ovpns"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#bitWarden
|
||||||
|
if [[ "${BITWARDEN}" =~ "2" ]]; then
|
||||||
|
useBitwarden
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${NAME}" ]; then
|
||||||
|
printf "Enter a Name for the Client: "
|
||||||
|
read -r NAME
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${NAME::1} == "." ]] || [[ ${NAME::1} == "-" ]]; then
|
||||||
|
echo "Names cannot start with a dot (.) or a dash (-)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${NAME}" =~ [^a-zA-Z0-9.@_-] ]]; then
|
||||||
|
echo "Name can only contain alphanumeric characters and these characters (.-@_)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${NAME}" ]]; then
|
||||||
|
echo "You cannot leave the name blank."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if name is already in use
|
||||||
|
while read -r line || [ -n "${line}" ]; do
|
||||||
|
STATUS=$(echo "$line" | awk '{print $1}')
|
||||||
|
|
||||||
|
if [ "${STATUS}" == "V" ]; then
|
||||||
|
CERT=$(echo "$line" | sed -e 's:.*/CN=::')
|
||||||
|
if [ "${CERT}" == "${NAME}" ]; then
|
||||||
|
INUSE="1"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done <${INDEX}
|
||||||
|
|
||||||
|
if [ "${INUSE}" == "1" ]; then
|
||||||
|
printf "\n!! This name is already in use by a Valid Certificate."
|
||||||
|
printf "\nPlease choose another name or revoke this certificate first.\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if name is reserved
|
||||||
|
if [ "${NAME}" == "ta" ] || [ "${NAME}" == "server" ] || [ "${NAME}" == "ca" ]; then
|
||||||
|
echo "Sorry, this is in use by the server and cannot be used by clients."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#As of EasyRSA 3.0.6, by default certificates last 1080 days, see https://github.com/OpenVPN/easy-rsa/blob/6b7b6bf1f0d3c9362b5618ad18c66677351cacd1/easyrsa3/vars.example
|
||||||
|
if [ -z "${DAYS}" ]; then
|
||||||
|
read -r -e -p "How many days should the certificate last? " -i 1080 DAYS
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! "$DAYS" =~ ^[0-9]+$ ]] || [ "$DAYS" -lt 1 ] || [ "$DAYS" -gt 3650 ]; then
|
||||||
|
#The CRL lasts 3650 days so it doesn't make much sense that certificates would last longer
|
||||||
|
echo "Please input a valid number of days, between 1 and 3650 inclusive."
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd /etc/openvpn/easy-rsa || exit
|
||||||
|
|
||||||
|
if [[ "${NO_PASS}" =~ "1" ]]; then
|
||||||
|
if [[ -n "${PASSWD}" ]]; then
|
||||||
|
echo "Both nopass and password arguments passed to the script. Please use either one."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
keynoPASS
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
keyPASS
|
||||||
|
fi
|
||||||
|
|
||||||
|
#1st Verify that clients Public Key Exists
|
||||||
|
if [ ! -f "issued/${NAME}${CRT}" ]; then
|
||||||
|
echo "[ERROR]: Client Public Key Certificate not found: $NAME$CRT"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
echo "Client's cert found: $NAME$CRT"
|
||||||
|
|
||||||
|
#Then, verify that there is a private key for that client
|
||||||
|
if [ ! -f "private/${NAME}${KEY}" ]; then
|
||||||
|
echo "[ERROR]: Client Private Key not found: $NAME$KEY"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
echo "Client's Private Key found: $NAME$KEY"
|
||||||
|
|
||||||
|
#Confirm the CA public key exists
|
||||||
|
if [ ! -f "${CA}" ]; then
|
||||||
|
echo "[ERROR]: CA Public Key not found: $CA"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
echo "CA public Key found: $CA"
|
||||||
|
|
||||||
|
#Confirm the tls key file exists
|
||||||
|
if [ ! -f "${TA}" ]; then
|
||||||
|
echo "[ERROR]: tls Private Key not found: $TA"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
echo "tls Private Key found: $TA"
|
||||||
|
|
||||||
|
|
||||||
|
## Added new step to create an .ovpn12 file that can be stored on iOS keychain
|
||||||
|
## This step is more secure method and does not require the end-user to keep entering passwords, or storing the client private cert where it can be easily tampered
|
||||||
|
## https://openvpn.net/faq/how-do-i-use-a-client-certificate-and-private-key-from-the-ios-keychain/
|
||||||
|
if [ "$iOS" = "1" ]; then
|
||||||
|
#Generates the .ovpn file WITHOUT the client private key
|
||||||
|
{
|
||||||
|
# Start by populating with the default file
|
||||||
|
cat "${DEFAULT}"
|
||||||
|
|
||||||
|
#Now, append the CA Public Cert
|
||||||
|
echo "<ca>"
|
||||||
|
cat "${CA}"
|
||||||
|
echo "</ca>"
|
||||||
|
|
||||||
|
#Next append the client Public Cert
|
||||||
|
echo "<cert>"
|
||||||
|
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' < "issued/${NAME}${CRT}"
|
||||||
|
echo "</cert>"
|
||||||
|
|
||||||
|
#Finally, append the TA Private Key
|
||||||
|
if [ -f /etc/pivpn/TWO_POINT_FOUR ]; then
|
||||||
|
echo "<tls-crypt>"
|
||||||
|
cat "${TA}"
|
||||||
|
echo "</tls-crypt>"
|
||||||
|
else
|
||||||
|
echo "<tls-auth>"
|
||||||
|
cat "${TA}"
|
||||||
|
echo "</tls-auth>"
|
||||||
|
fi
|
||||||
|
|
||||||
|
} > "${NAME}${FILEEXT}"
|
||||||
|
|
||||||
|
# Copy the .ovpn profile to the home directory for convenient remote access
|
||||||
|
|
||||||
|
printf "========================================================\n"
|
||||||
|
printf "Generating an .ovpn12 file for use with iOS devices\n"
|
||||||
|
printf "Please remember the export password\n"
|
||||||
|
printf "as you will need this import the certificate on your iOS device\n"
|
||||||
|
printf "========================================================\n"
|
||||||
|
openssl pkcs12 -passin pass:"$PASSWD" -export -in "issued/${NAME}${CRT}" -inkey "private/${NAME}${KEY}" -certfile ${CA} -name "${NAME}" -out "$install_home/ovpns/$NAME.ovpn12"
|
||||||
|
chown "$install_user" "$install_home/ovpns/$NAME.ovpn12"
|
||||||
|
chmod 600 "$install_home/ovpns/$NAME.ovpn12"
|
||||||
|
printf "========================================================\n"
|
||||||
|
printf "\e[1mDone! %s successfully created!\e[0m \n" "$NAME.ovpn12"
|
||||||
|
printf "You will need to transfer both the .ovpn and .ovpn12 files\n"
|
||||||
|
printf "to your iOS device.\n"
|
||||||
|
printf "========================================================\n\n"
|
||||||
|
else
|
||||||
|
#This is the standard non-iOS configuration
|
||||||
|
#Ready to make a new .ovpn file
|
||||||
|
{
|
||||||
|
# Start by populating with the default file
|
||||||
|
cat "${DEFAULT}"
|
||||||
|
|
||||||
|
#Now, append the CA Public Cert
|
||||||
|
echo "<ca>"
|
||||||
|
cat "${CA}"
|
||||||
|
echo "</ca>"
|
||||||
|
|
||||||
|
#Next append the client Public Cert
|
||||||
|
echo "<cert>"
|
||||||
|
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' < "issued/${NAME}${CRT}"
|
||||||
|
echo "</cert>"
|
||||||
|
|
||||||
|
#Then, append the client Private Key
|
||||||
|
echo "<key>"
|
||||||
|
cat "private/${NAME}${KEY}"
|
||||||
|
echo "</key>"
|
||||||
|
|
||||||
|
#Finally, append the tls Private Key
|
||||||
|
echo "<tls-auth>"
|
||||||
|
cat "${TA}"
|
||||||
|
echo "</tls-auth>"
|
||||||
|
|
||||||
|
} > "${NAME}${FILEEXT}"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Copy the .ovpn profile to the home directory for convenient remote access
|
||||||
|
cp "/etc/openvpn/easy-rsa/pki/$NAME$FILEEXT" "$install_home/ovpns/$NAME$FILEEXT"
|
||||||
|
chown "$install_user" "$install_home/ovpns/$NAME$FILEEXT"
|
||||||
|
chmod 640 "/etc/openvpn/easy-rsa/pki/$NAME$FILEEXT"
|
||||||
|
chmod 640 "$install_home/ovpns/$NAME$FILEEXT"
|
||||||
|
printf "\n\n"
|
||||||
|
printf "========================================================\n"
|
||||||
|
printf "\e[1mDone! %s successfully created!\e[0m \n" "$NAME$FILEEXT"
|
||||||
|
printf "%s was copied to:\n" "$NAME$FILEEXT"
|
||||||
|
printf " %s/ovpns\n" "$install_home"
|
||||||
|
printf "for easy transfer. Please use this profile only on one\n"
|
||||||
|
printf "device and create additional profiles for other devices.\n"
|
||||||
|
printf "========================================================\n\n"
|
106
scripts/openvpn/pivpn
Executable file
106
scripts/openvpn/pivpn
Executable file
|
@ -0,0 +1,106 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Must be root to use this tool
|
||||||
|
if [[ ! $EUID -eq 0 ]];then
|
||||||
|
if [[ $(dpkg-query -s sudo) ]];then
|
||||||
|
export SUDO="sudo"
|
||||||
|
else
|
||||||
|
echo "::: Please install sudo or run this as root."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
function makeOVPNFunc {
|
||||||
|
shift
|
||||||
|
$SUDO /opt/pivpn/makeOVPN.sh "$@"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function listClientsFunc {
|
||||||
|
$SUDO /opt/pivpn/clientStat.sh
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function listOVPNFunc {
|
||||||
|
$SUDO /opt/pivpn/listOVPN.sh
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function debugFunc {
|
||||||
|
echo "::: Generating Debug Output"
|
||||||
|
$SUDO /opt/pivpn/pivpnDebug.sh | tee /tmp/debug.txt
|
||||||
|
echo "::: "
|
||||||
|
echo "::: Debug output completed above."
|
||||||
|
echo "::: Copy saved to /tmp/debug.txt"
|
||||||
|
echo "::: "
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeOVPNFunc {
|
||||||
|
shift
|
||||||
|
$SUDO /opt/pivpn/removeOVPN.sh "$@"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function uninstallFunc {
|
||||||
|
$SUDO /opt/pivpn/uninstall.sh
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function versionFunc {
|
||||||
|
printf "\e[1mVersion 1.9\e[0m\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
function update {
|
||||||
|
|
||||||
|
shift
|
||||||
|
$SUDO /opt/pivpn/update.sh "$@"
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function backup {
|
||||||
|
|
||||||
|
$SUDO /opt/pivpn/backup.sh
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function helpFunc {
|
||||||
|
echo "::: Control all PiVPN specific functions!"
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Usage: pivpn <command> [option]"
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Commands:"
|
||||||
|
echo "::: -a, add [nopass] Create a client ovpn profile, optional nopass"
|
||||||
|
echo "::: -c, clients List any connected clients to the server"
|
||||||
|
echo "::: -d, debug Start a debugging session if having trouble"
|
||||||
|
echo "::: -l, list List all valid and revoked certificates"
|
||||||
|
echo "::: -r, revoke Revoke a client ovpn profile"
|
||||||
|
echo "::: -h, help Show this help dialog"
|
||||||
|
echo "::: -u, uninstall Uninstall PiVPN from your system!"
|
||||||
|
echo "::: -up, update Updates PiVPN Scripts"
|
||||||
|
echo "::: -bk, backup Backup Openvpn and ovpns dir"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $# = 0 ]]; then
|
||||||
|
helpFunc
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Handle redirecting to specific functions based on arguments
|
||||||
|
case "$1" in
|
||||||
|
"-a" | "add" ) makeOVPNFunc "$@";;
|
||||||
|
"-c" | "clients" ) listClientsFunc;;
|
||||||
|
"-d" | "debug" ) debugFunc;;
|
||||||
|
"-l" | "list" ) listOVPNFunc;;
|
||||||
|
"-r" | "revoke" ) removeOVPNFunc "$@";;
|
||||||
|
"-h" | "help" ) helpFunc;;
|
||||||
|
"-u" | "uninstall" ) uninstallFunc;;
|
||||||
|
"-v" ) versionFunc;;
|
||||||
|
"-up"| "update" ) update "$@" ;;
|
||||||
|
"-bk"| "backup" ) backup;;
|
||||||
|
* ) helpFunc;;
|
||||||
|
esac
|
230
scripts/openvpn/pivpnDebug.sh
Executable file
230
scripts/openvpn/pivpnDebug.sh
Executable file
|
@ -0,0 +1,230 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# This scripts runs as root
|
||||||
|
|
||||||
|
setupVars="/etc/pivpn/setupVars.conf"
|
||||||
|
ERR=0
|
||||||
|
|
||||||
|
if [ ! -f "${setupVars}" ]; then
|
||||||
|
echo "::: Missing setup vars file!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
source "${setupVars}"
|
||||||
|
|
||||||
|
echo -e "::::\t\t\e[4mPiVPN debug\e[0m\t\t ::::"
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e "::::\t\t\e[4mLatest commit\e[0m\t\t ::::"
|
||||||
|
git --git-dir /etc/.pivpn/.git log -n 1
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e "::::\t \e[4mInstallation settings\e[0m \t ::::"
|
||||||
|
# Use the wildcard so setupVars.conf.update.bak from the previous install is not shown
|
||||||
|
for filename in /etc/pivpn/*; do
|
||||||
|
if [[ "$filename" != "/etc/pivpn/setupVars.conf"* ]]; then
|
||||||
|
echo "$filename -> $(cat "$filename")"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e "::::\t\e[4msetupVars file shown below\e[0m\t ::::"
|
||||||
|
sed "s/$pivpnHOST/REDACTED/" < /etc/pivpn/setupVars.conf
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e ":::: \e[4mServer configuration shown below\e[0m ::::"
|
||||||
|
cat /etc/openvpn/server.conf
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e ":::: \e[4mClient template file shown below\e[0m ::::"
|
||||||
|
sed "s/$pivpnHOST/REDACTED/" < /etc/openvpn/easy-rsa/pki/Default.txt
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e ":::: \t\e[4mRecursive list of files in\e[0m\t ::::\n::: \e[4m/etc/openvpn/easy-rsa/pki shows below\e[0m :::"
|
||||||
|
ls -LR /etc/openvpn/easy-rsa/pki/ -Ireqs -Icerts_by_serial
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e "::::\t\t\e[4mSelf check\e[0m\t\t ::::"
|
||||||
|
|
||||||
|
if [ "$(cat /proc/sys/net/ipv4/ip_forward)" -eq 1 ]; then
|
||||||
|
echo ":: [OK] IP forwarding is enabled"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] IP forwarding is not enabled, attempt fix now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
sed -i '/net.ipv4.ip_forward=1/s/^#//g' /etc/sysctl.conf
|
||||||
|
sysctl -p
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$USING_UFW" -eq 0 ]; then
|
||||||
|
|
||||||
|
if iptables -t nat -C POSTROUTING -s 10.8.0.0/24 -o "${PHYS_INT}" -j MASQUERADE &> /dev/null; then
|
||||||
|
echo ":: [OK] Iptables MASQUERADE rule set"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
iptables -t nat -F
|
||||||
|
iptables -t nat -I POSTROUTING -s 10.8.0.0/24 -o "${PHYS_INT}" -j MASQUERADE
|
||||||
|
iptables-save > /etc/iptables/rules.v4
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$INPUT_CHAIN_EDITED" -eq 1 ]; then
|
||||||
|
|
||||||
|
if iptables -C INPUT -i "$PHYS_INT" -p "$pivpnPROTO" --dport "$pivpnPORT" -j ACCEPT &> /dev/null; then
|
||||||
|
echo ":: [OK] Iptables INPUT rule set"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] Iptables INPUT rule is not set, attempt fix now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
iptables -I INPUT 1 -i "$PHYS_INT" -p "$pivpnPROTO" --dport "$pivpnPORT" -j ACCEPT
|
||||||
|
iptables-save > /etc/iptables/rules.v4
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$FORWARD_CHAIN_EDITED" -eq 1 ]; then
|
||||||
|
|
||||||
|
if iptables -C FORWARD -s 10.8.0.0/24 -i tun0 -o "$PHYS_INT" -j ACCEPT &> /dev/null; then
|
||||||
|
echo ":: [OK] Iptables FORWARD rule set"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] Iptables FORWARD rule is not set, attempt fix now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
iptables -I FORWARD 1 -d 10.8.0.0/24 -i "$PHYS_INT" -o tun0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||||
|
iptables -I FORWARD 2 -s 10.8.0.0/24 -i tun0 -o "$PHYS_INT" -j ACCEPT
|
||||||
|
iptables-save > /etc/iptables/rules.v4
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
if LANG="en_US.UTF-8" ufw status | grep -qw 'active'; then
|
||||||
|
echo ":: [OK] Ufw is enabled"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] Ufw is not enabled, try to enable now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
ufw enable
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if iptables -t nat -C POSTROUTING -s 10.8.0.0/24 -o "${PHYS_INT}" -j MASQUERADE &> /dev/null; then
|
||||||
|
echo ":: [OK] Iptables MASQUERADE rule set"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
sed "/delete these required/i *nat\n:POSTROUTING ACCEPT [0:0]\n-I POSTROUTING -s 10.8.0.0/24 -o $PHYS_INT -j MASQUERADE\nCOMMIT\n" -i /etc/ufw/before.rules
|
||||||
|
ufw reload
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if iptables -C ufw-user-input -p "${pivpnPROTO}" --dport "${pivpnPORT}" -j ACCEPT &> /dev/null; then
|
||||||
|
echo ":: [OK] Ufw input rule set"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] Ufw input rule is not set, attempt fix now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
ufw insert 1 allow "$pivpnPORT"/"$pivpnPROTO"
|
||||||
|
ufw reload
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$OLD_UFW" -eq 1 ]; then
|
||||||
|
FORWARD_POLICY="$(iptables -S FORWARD | grep '^-P' | awk '{print $3}')"
|
||||||
|
if [ "$FORWARD_POLICY" = "ACCEPT" ]; then
|
||||||
|
echo ":: [OK] Ufw forwarding policy is accept"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] Ufw forwarding policy is not 'ACCEPT', attempt fix now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
sed -i "s/\(DEFAULT_FORWARD_POLICY=\).*/\1\"ACCEPT\"/" /etc/default/ufw
|
||||||
|
ufw reload > /dev/null
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if iptables -C ufw-user-forward -i tun0 -o "${PHYS_INT}" -s 10.8.0.0/24 -j ACCEPT &> /dev/null; then
|
||||||
|
echo ":: [OK] Ufw forwarding rule set"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] Ufw forwarding rule is not set, attempt fix now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
ufw route insert 1 allow in on tun0 from 10.8.0.0/24 out on "$PHYS_INT" to any
|
||||||
|
ufw reload
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if systemctl is-active -q openvpn; then
|
||||||
|
echo ":: [OK] OpenVPN is running"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] OpenVPN is not running, try to start now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
systemctl start openvpn
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if systemctl is-enabled -q openvpn; then
|
||||||
|
echo ":: [OK] OpenVPN is enabled (it will automatically start on reboot)"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] OpenVPN is not enabled, try to enable now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
systemctl enable openvpn
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# grep -w (whole word) is used so port 111940 with now match when looking for 1194
|
||||||
|
if netstat -uanpt | grep openvpn | grep -w "${pivpnPORT}" | grep -q "${pivpnPROTO}"; then
|
||||||
|
echo ":: [OK] OpenVPN is listening on port ${pivpnPORT}/${pivpnPROTO}"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] OpenVPN is not listening, try to restart now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
systemctl restart openvpn
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ERR" -eq 1 ]; then
|
||||||
|
echo -e "[INFO] Run \e[1mpivpn -d\e[0m again to see if we detect issues"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e ":::: \e[4mSnippet of the server log\e[0m ::::"
|
||||||
|
tail -20 /var/log/openvpn.log > /tmp/snippet
|
||||||
|
|
||||||
|
# Regular expession taken from https://superuser.com/a/202835, it will match invalid IPs
|
||||||
|
# like 123.456.789.012 but it's fine because 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 /tmp/snippet | 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
|
||||||
|
sed -i "s/$IP/REDACTED/g" /tmp/snippet
|
||||||
|
done
|
||||||
|
|
||||||
|
cat /tmp/snippet
|
||||||
|
rm /tmp/snippet
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e "::::\t\t\e[4mDebug complete\e[0m\t\t ::::"
|
||||||
|
|
||||||
|
# Telekom Hybrid Check
|
||||||
|
wget -O /tmp/hybcheck http://speedport.ip &>/dev/null
|
||||||
|
if grep -Fq "Speedport Pro" /tmp/hybcheck || grep -Fq "Speedport Hybrid" /tmp/hybcheck
|
||||||
|
then
|
||||||
|
printf ":::\t\t\t\t\t:::\n::\tTelekom Hybrid Check\t\t ::\n:::\t\t\t\t\t:::\n"
|
||||||
|
echo "Are you using Telekom Hybrid (found a hybrid compatible router)?"
|
||||||
|
echo "If yes and you have problems with the connections you can test the following:"
|
||||||
|
echo "Add 'tun-mtu 1316' in /etc/openvpn/easy-rsa/pki/Default.txt to set a hybrid compatible MTU size (new .ovpn files)."
|
||||||
|
echo "For already existing .ovpn files 'tun-mtu 1316' can also be inserted there manually."
|
||||||
|
echo "With Telekom hybrid connections, you may have to experiment a little with MTU (tun-mtu, link-mtu and mssfix)."
|
||||||
|
fi
|
||||||
|
rm /tmp/hybcheck
|
123
scripts/openvpn/removeOVPN.sh
Executable file
123
scripts/openvpn/removeOVPN.sh
Executable file
|
@ -0,0 +1,123 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# PiVPN: revoke client script
|
||||||
|
|
||||||
|
install_user=$(</etc/pivpn/install_user)
|
||||||
|
PLAT=$(</etc/pivpn/DET_PLATFORM)
|
||||||
|
INDEX="/etc/openvpn/easy-rsa/pki/index.txt"
|
||||||
|
|
||||||
|
helpFunc() {
|
||||||
|
echo "::: Revoke a client ovpn profile"
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Usage: pivpn <-r|revoke> [-h|--help] [<client-1>] ... [<client-n>] ..."
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Commands:"
|
||||||
|
echo "::: [none] Interactive mode"
|
||||||
|
echo "::: <client> Client(s) to to revoke"
|
||||||
|
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
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
CERTS_TO_REVOKE+=("$1")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -f "${INDEX}" ]; then
|
||||||
|
printf "The file: %s was not found\n" "$INDEX"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${CERTS_TO_REVOKE}" ]]; then
|
||||||
|
printf "\n"
|
||||||
|
printf " ::\e[4m Certificate List \e[0m:: \n"
|
||||||
|
|
||||||
|
i=0
|
||||||
|
while read -r line || [ -n "$line" ]; do
|
||||||
|
STATUS=$(echo "$line" | awk '{print $1}')
|
||||||
|
if [[ "${STATUS}" = "V" ]]; then
|
||||||
|
NAME=$(echo "$line" | sed -e 's:.*/CN=::')
|
||||||
|
CERTS[$i]=${NAME}
|
||||||
|
if [ "$i" != 0 ]; then
|
||||||
|
# Prevent printing "server" certificate
|
||||||
|
printf " %s\n" "$NAME"
|
||||||
|
fi
|
||||||
|
let i=i+1
|
||||||
|
fi
|
||||||
|
done <${INDEX}
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
|
echo "::: Please enter the Name of the client to be revoked from the list above:"
|
||||||
|
read -r NAME
|
||||||
|
|
||||||
|
if [[ -z "${NAME}" ]]; then
|
||||||
|
echo "You can not leave this blank!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for((x=1;x<=i;++x)); do
|
||||||
|
if [ "${CERTS[$x]}" = "${NAME}" ]; then
|
||||||
|
VALID=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "${VALID}" ]; then
|
||||||
|
printf "You didn't enter a valid cert name!\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
CERTS_TO_REVOKE=( "${NAME}" )
|
||||||
|
else
|
||||||
|
i=0
|
||||||
|
while read -r line || [ -n "$line" ]; do
|
||||||
|
STATUS=$(echo "$line" | awk '{print $1}')
|
||||||
|
if [[ "${STATUS}" = "V" ]]; then
|
||||||
|
NAME=$(echo "$line" | sed -e 's:.*/CN=::')
|
||||||
|
CERTS[$i]=${NAME}
|
||||||
|
let i=i+1
|
||||||
|
fi
|
||||||
|
done <${INDEX}
|
||||||
|
|
||||||
|
for (( ii = 0; ii < ${#CERTS_TO_REVOKE[@]}; ii++)); do
|
||||||
|
VALID=0
|
||||||
|
for((x=1;x<=i;++x)); do
|
||||||
|
if [ "${CERTS[$x]}" = "${CERTS_TO_REVOKE[ii]}" ]; then
|
||||||
|
VALID=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${VALID}" != 1 ]; then
|
||||||
|
printf "You passed an invalid cert name: '"%s"'!\n" "${CERTS_TO_REVOKE[ii]}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd /etc/openvpn/easy-rsa || exit
|
||||||
|
|
||||||
|
install_home=$(grep -m1 "^${install_user}:" /etc/passwd | cut -d: -f6)
|
||||||
|
install_home=${install_home%/} # remove possible trailing slash
|
||||||
|
for (( ii = 0; ii < ${#CERTS_TO_REVOKE[@]}; ii++)); do
|
||||||
|
printf "\n::: Revoking certificate '"%s"'.\n" "${CERTS_TO_REVOKE[ii]}"
|
||||||
|
./easyrsa --batch revoke "${CERTS_TO_REVOKE[ii]}"
|
||||||
|
./easyrsa gen-crl
|
||||||
|
printf "\n::: Certificate revoked, and CRL file updated.\n"
|
||||||
|
printf "::: Removing certs and client configuration for this profile.\n"
|
||||||
|
rm -rf "pki/reqs/${CERTS_TO_REVOKE[ii]}.req"
|
||||||
|
rm -rf "pki/private/${CERTS_TO_REVOKE[ii]}.key"
|
||||||
|
rm -rf "pki/issued/${CERTS_TO_REVOKE[ii]}.crt"
|
||||||
|
|
||||||
|
rm -rf "${install_home}/ovpns/${CERTS_TO_REVOKE[ii]}.ovpn"
|
||||||
|
rm -rf "/etc/openvpn/easy-rsa/pki/${CERTS_TO_REVOKE[ii]}.ovpn"
|
||||||
|
cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem
|
||||||
|
done
|
||||||
|
printf "::: Completed!\n"
|
99
scripts/openvpn/update.sh
Executable file
99
scripts/openvpn/update.sh
Executable file
|
@ -0,0 +1,99 @@
|
||||||
|
#/bin/bash
|
||||||
|
|
||||||
|
###Updates pivpn scripts (Not PiVPN)
|
||||||
|
###Main Vars
|
||||||
|
pivpnrepo="https://github.com/pivpn/pivpn.git"
|
||||||
|
pivpnlocalpath="/etc/.pivpn"
|
||||||
|
pivpnscripts="/opt/pivpn/scripts"
|
||||||
|
bashcompletiondir="/etc/bash_completion.d/pivpn"
|
||||||
|
|
||||||
|
|
||||||
|
###Functions
|
||||||
|
##Updates scripts
|
||||||
|
updatepivpnscripts(){
|
||||||
|
##We don't know what sort of changes users have made.
|
||||||
|
##Lets remove first /etc/.pivpn dir then clone it back again
|
||||||
|
echo "going do update PiVPN Scripts"
|
||||||
|
if [[ -d $pivpnlocalpath ]]; then
|
||||||
|
|
||||||
|
sudo rm -rf $pivpnlocalpath
|
||||||
|
cloneandupdate
|
||||||
|
|
||||||
|
else
|
||||||
|
cloneandupdate
|
||||||
|
fi
|
||||||
|
echo "PiVPN Scripts have been updated"
|
||||||
|
}
|
||||||
|
|
||||||
|
##Updates scripts using test branch
|
||||||
|
updatefromtest(){
|
||||||
|
##We don't know what sort of changes users have made.
|
||||||
|
##Lets remove first /etc/.pivpn dir then clone it back again
|
||||||
|
echo "PiVPN Scripts updating from test branch"
|
||||||
|
if [[ -d /etc/.pivpn ]]; then
|
||||||
|
|
||||||
|
rm -rf /etc/.pivpn
|
||||||
|
cloneupdttest
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
cloneupdttest
|
||||||
|
|
||||||
|
fi
|
||||||
|
echo "PiVPN Scripts updated have been updated from test branch"
|
||||||
|
}
|
||||||
|
|
||||||
|
##Clone and copy pivpn scripts to /op/
|
||||||
|
cloneandupdate(){
|
||||||
|
|
||||||
|
sudo git clone $pivpnrepo $pivpnlocalpath
|
||||||
|
sudo cp -r $pivpnlocalpath/scripts $pivpnscripts
|
||||||
|
sudo cp $pivpnlocalpath/scripts/bash-completion $bashcompletiondir
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
##same as cloneandupdate() but from test branch
|
||||||
|
##and falls back to master branch again after updating
|
||||||
|
cloneupdttest(){
|
||||||
|
|
||||||
|
sudo git clone $pivpnrepo $pivpnlocalpath
|
||||||
|
sudo git -C $pivpnlocalpath checkout test
|
||||||
|
sudo git -C $pivpnlocalpath pull origin test
|
||||||
|
sudo cp -r $pivpnlocalpath/scripts $pivpnscripts
|
||||||
|
sudo cp $pivpnlocalpath/scripts/bash-completion $bashcompletiondir
|
||||||
|
sudo git -C $pivpnlocalpath checkout master
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
scriptusage(){
|
||||||
|
echo -e "Updates pivpn scripts,\n
|
||||||
|
Usage:
|
||||||
|
pivpn update | updates from master branch
|
||||||
|
pivpn update -t or --test | updates from test branch"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
## SCRIPT
|
||||||
|
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
updatepivpnscripts
|
||||||
|
|
||||||
|
else
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-t | --test | test )
|
||||||
|
updatefromtest
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-h | --help | help )
|
||||||
|
scriptusage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
updatepivpnscripts
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
23
scripts/wireguard/listCONF.sh
Executable file
23
scripts/wireguard/listCONF.sh
Executable file
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd /etc/wireguard/configs
|
||||||
|
if [ ! -s clients.txt ]; then
|
||||||
|
echo "::: There are no clients to list"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Present the user with a summary of the clients, fetching info from dates.
|
||||||
|
FORMATTED+=": \e[4mClient\e[0m&\e[4mCreation date\e[0m :\n"
|
||||||
|
|
||||||
|
while read -r LINE; do
|
||||||
|
CLIENT_NAME="$(awk '{print $1}' <<< "$LINE")"
|
||||||
|
|
||||||
|
CREATION_DATE="$(awk '{print $2}' <<< "$LINE")"
|
||||||
|
|
||||||
|
# Dates are converted from UNIX time to human readable.
|
||||||
|
CD_FORMAT="$(date -d @"$CREATION_DATE" +'%d %b %Y, %H:%M, %Z')"
|
||||||
|
|
||||||
|
FORMATTED+="• $CLIENT_NAME&$CD_FORMAT\n"
|
||||||
|
done < clients.txt
|
||||||
|
|
||||||
|
echo -e "$FORMATTED" | column -t -s '&'
|
130
scripts/wireguard/makeCONF.sh
Executable file
130
scripts/wireguard/makeCONF.sh
Executable file
|
@ -0,0 +1,130 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
setupVars="/etc/pivpn/setupVars.conf"
|
||||||
|
|
||||||
|
helpFunc(){
|
||||||
|
echo "::: Create a client conf profile"
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Usage: pivpn <-a|add> [-n|--name <arg>] [-h|--help]"
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Commands:"
|
||||||
|
echo "::: [none] Interactive mode"
|
||||||
|
echo "::: -n,--name Name for the Client (default: '$HOSTNAME')"
|
||||||
|
echo "::: -h,--help Show this help dialog"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse input arguments
|
||||||
|
while test $# -gt 0; do
|
||||||
|
_key="$1"
|
||||||
|
case "$_key" in
|
||||||
|
-n|--name|--name=*)
|
||||||
|
_val="${_key##--name=}"
|
||||||
|
if test "$_val" = "$_key"; then
|
||||||
|
test $# -lt 2 && echo "::: Missing value for the optional argument '$_key'." && exit 1
|
||||||
|
_val="$2"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
CLIENT_NAME="$_val"
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
helpFunc
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "::: Error: Got an unexpected argument '$1'"
|
||||||
|
helpFunc
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -f "${setupVars}" ]; then
|
||||||
|
echo "::: Missing setup vars file!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
source "${setupVars}"
|
||||||
|
|
||||||
|
# The home folder variable was sourced from the settings file.
|
||||||
|
if [ ! -d "${install_home}/configs" ]; then
|
||||||
|
mkdir "${install_home}/configs"
|
||||||
|
chown "${install_user}":"${install_user}" "${install_home}/configs"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd /etc/wireguard
|
||||||
|
|
||||||
|
if [ -z "${CLIENT_NAME}" ]; then
|
||||||
|
read -r -p "Enter a Name for the Client: " CLIENT_NAME
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${CLIENT_NAME}" =~ [^a-zA-Z0-9.@_-] ]]; then
|
||||||
|
echo "Name can only contain alphanumeric characters and these characters (.-@_)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${CLIENT_NAME}" ]; then
|
||||||
|
echo "::: You cannot leave the name blank."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "configs/${CLIENT_NAME}.conf" ]; then
|
||||||
|
echo "::: A client with this name already exists"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
wg genkey | tee "keys/${CLIENT_NAME}_priv" | wg pubkey > "keys/${CLIENT_NAME}_pub"
|
||||||
|
echo "::: Client Keys generated"
|
||||||
|
|
||||||
|
# Find an unused number for the last octet of the client IP
|
||||||
|
for i in {2..254}; do
|
||||||
|
if ! grep -q " $i" configs/clients.txt; then
|
||||||
|
COUNT="$i"
|
||||||
|
echo "${CLIENT_NAME} $(date +%s) ${COUNT}" >> configs/clients.txt
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -n "[Interface]
|
||||||
|
PrivateKey = $(cat "keys/${CLIENT_NAME}_priv")
|
||||||
|
Address = 10.6.0.${COUNT}/24
|
||||||
|
DNS = ${pivpnDNS1}" > "configs/${CLIENT_NAME}.conf"
|
||||||
|
|
||||||
|
if [ -n "${pivpnDNS2}" ]; then
|
||||||
|
echo ", ${pivpnDNS2}" >> "configs/${CLIENT_NAME}.conf"
|
||||||
|
else
|
||||||
|
echo >> "configs/${CLIENT_NAME}.conf"
|
||||||
|
fi
|
||||||
|
echo >> "configs/${CLIENT_NAME}.conf"
|
||||||
|
|
||||||
|
echo "[Peer]
|
||||||
|
PublicKey = $(cat keys/server_pub)
|
||||||
|
PresharedKey = $(cat keys/psk)
|
||||||
|
Endpoint = ${pivpnHOST}:${pivpnPORT}
|
||||||
|
AllowedIPs = 0.0.0.0/0" >> "configs/${CLIENT_NAME}.conf"
|
||||||
|
echo "::: Client config generated"
|
||||||
|
|
||||||
|
echo "# begin ${CLIENT_NAME}
|
||||||
|
[Peer]
|
||||||
|
PublicKey = $(cat "keys/${CLIENT_NAME}_pub")
|
||||||
|
PresharedKey = $(cat keys/psk)
|
||||||
|
AllowedIPs = 10.6.0.${COUNT}/32
|
||||||
|
# end ${CLIENT_NAME}" >> wg0.conf
|
||||||
|
echo "::: Updated server config"
|
||||||
|
|
||||||
|
if systemctl restart wg-quick@wg0; then
|
||||||
|
echo "::: WireGuard restarted"
|
||||||
|
else
|
||||||
|
echo "::: Failed to restart WireGuard"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp "configs/${CLIENT_NAME}.conf" "${install_home}/configs/${CLIENT_NAME}.conf"
|
||||||
|
chown "${install_user}":"${install_user}" "${install_home}/configs/${CLIENT_NAME}.conf"
|
||||||
|
|
||||||
|
echo "======================================================================"
|
||||||
|
echo -e "::: Done! \e[1m${CLIENT_NAME}.conf successfully created!\e[0m"
|
||||||
|
echo "::: ${CLIENT_NAME}.conf was copied to ${install_home}/configs for easy transfer."
|
||||||
|
echo "::: Please use this profile only on one device and create additional"
|
||||||
|
echo -e "::: profiles for other devices. You can also use \e[1mpivpn -qr\e[0m"
|
||||||
|
echo "::: to generate a QR Code you can scan with the mobile app."
|
||||||
|
echo "======================================================================"
|
83
scripts/wireguard/pivpn
Executable file
83
scripts/wireguard/pivpn
Executable file
|
@ -0,0 +1,83 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Must be root to use this tool
|
||||||
|
if [ $EUID -ne 0 ];then
|
||||||
|
if dpkg-query -s sudo &> /dev/null; then
|
||||||
|
export SUDO="sudo"
|
||||||
|
else
|
||||||
|
echo "::: Please install sudo or run this as root."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
makeConf(){
|
||||||
|
shift
|
||||||
|
$SUDO /opt/pivpn/makeCONF.sh "$@"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
listConnected(){
|
||||||
|
$SUDO wg show
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(){
|
||||||
|
$SUDO /opt/pivpn/pivpnDEBUG.sh
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
listClients(){
|
||||||
|
$SUDO /opt/pivpn/listCONF.sh
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
showQrcode(){
|
||||||
|
shift
|
||||||
|
$SUDO /opt/pivpn/qrcodeCONF.sh "$@"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
removeClient(){
|
||||||
|
shift
|
||||||
|
$SUDO /opt/pivpn/removeCONF.sh "$@"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstallServer(){
|
||||||
|
$SUDO /opt/pivpn/uninstall.sh
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
showHelp(){
|
||||||
|
echo "::: Control all PiVPN specific functions!"
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Usage: pivpn <command> [option]"
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Commands:"
|
||||||
|
echo "::: -a, add Create a client conf profile"
|
||||||
|
echo "::: -c, clients List any connected clients to the server"
|
||||||
|
echo "::: -d, debug Start a debugging session if having trouble"
|
||||||
|
echo "::: -l, list List all clients"
|
||||||
|
echo "::: -qr, qrcode Show the qrcode of a client for use with the mobile app"
|
||||||
|
echo "::: -r, remove Remove a client"
|
||||||
|
echo "::: -h, help Show this help dialog"
|
||||||
|
echo "::: -u, uninstall Uninstall pivpn from your system!"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $# = 0 ]; then
|
||||||
|
showHelp
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Handle redirecting to specific functions based on arguments
|
||||||
|
case "$1" in
|
||||||
|
"-a" | "add" ) makeConf "$@";;
|
||||||
|
"-c" | "clients" ) listConnected;;
|
||||||
|
"-d" | "debug" ) debug;;
|
||||||
|
"-l" | "list" ) listClients;;
|
||||||
|
"-qr" | "qrcode" ) showQrcode "$@";;
|
||||||
|
"-r" | "remove" ) removeClient "$@";;
|
||||||
|
"-h" | "help" ) showHelp;;
|
||||||
|
"-u" | "uninstall" ) uninstallServer;;
|
||||||
|
* ) showHelp;;
|
||||||
|
esac
|
173
scripts/wireguard/pivpnDEBUG.sh
Executable file
173
scripts/wireguard/pivpnDEBUG.sh
Executable file
|
@ -0,0 +1,173 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# This scripts runs as root
|
||||||
|
|
||||||
|
setupVars="/etc/pivpn/setupVars.conf"
|
||||||
|
|
||||||
|
if [ ! -f "${setupVars}" ]; then
|
||||||
|
echo "::: Missing setup vars file!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
source "${setupVars}"
|
||||||
|
|
||||||
|
EXAMPLE="$(head -1 /etc/wireguard/configs/clients.txt | awk '{print $1}')"
|
||||||
|
ERR=0
|
||||||
|
|
||||||
|
echo -e "::::\t\t\e[4mPiVPN debug\e[0m\t\t ::::"
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e "::::\t\t\e[4mLatest commit\e[0m\t\t ::::"
|
||||||
|
git --git-dir /etc/.pivpn/.git log -n 1
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e "::::\t \e[4mInstallation settings\e[0m \t ::::"
|
||||||
|
sed "s/$pivpnHOST/REDACTED/" < /etc/pivpn/setupVars.conf
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e ":::: \e[4mServer configuration shown below\e[0m ::::"
|
||||||
|
cd /etc/wireguard/keys
|
||||||
|
cp ../wg0.conf ../wg0.tmp
|
||||||
|
for k in *; do
|
||||||
|
sed "s#$(cat "$k")#$k#" -i ../wg0.tmp
|
||||||
|
done
|
||||||
|
cat ../wg0.tmp
|
||||||
|
rm ../wg0.tmp
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e ":::: \e[4mClient configuration shown below\e[0m ::::"
|
||||||
|
if [ -n "$EXAMPLE" ]; then
|
||||||
|
cp ../configs/"$EXAMPLE".conf ../configs/"$EXAMPLE".tmp
|
||||||
|
for k in *; do
|
||||||
|
sed "s#$(cat "$k")#$k#" -i ../configs/"$EXAMPLE".tmp
|
||||||
|
done
|
||||||
|
sed "s/$pivpnHOST/REDACTED/" < ../configs/"$EXAMPLE".tmp
|
||||||
|
rm ../configs/"$EXAMPLE".tmp
|
||||||
|
else
|
||||||
|
echo "::: There are no clients yet"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e ":::: \t\e[4mRecursive list of files in\e[0m\t ::::\n::::\e\t[4m/etc/wireguard shown below\e[0m\t ::::"
|
||||||
|
ls -LR /etc/wireguard
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e "::::\t\t\e[4mSelf check\e[0m\t\t ::::"
|
||||||
|
|
||||||
|
if [ "$(cat /proc/sys/net/ipv4/ip_forward)" -eq 1 ]; then
|
||||||
|
echo ":: [OK] IP forwarding is enabled"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] IP forwarding is not enabled, attempt fix now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
sed -i '/net.ipv4.ip_forward=1/s/^#//g' /etc/sysctl.conf
|
||||||
|
sysctl -p
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$USING_UFW" -eq 0 ]; then
|
||||||
|
|
||||||
|
if iptables -t nat -C POSTROUTING -s 10.6.0.0/24 -o "${PHYS_INT}" -j MASQUERADE &> /dev/null; then
|
||||||
|
echo ":: [OK] Iptables MASQUERADE rule set"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
iptables -t nat -F
|
||||||
|
iptables -t nat -I POSTROUTING -s 10.6.0.0/24 -o "${PHYS_INT}" -j MASQUERADE
|
||||||
|
iptables-save > /etc/iptables/rules.v4
|
||||||
|
iptables-restore < /etc/iptables/rules.v4
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
if LANG="en_US.UTF-8" ufw status | grep -qw 'active'; then
|
||||||
|
echo ":: [OK] Ufw is enabled"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] Ufw is not enabled, try to enable now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
ufw enable
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if iptables -t nat -C POSTROUTING -s 10.6.0.0/24 -o "${PHYS_INT}" -j MASQUERADE &> /dev/null; then
|
||||||
|
echo ":: [OK] Iptables MASQUERADE rule set"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] Iptables MASQUERADE rule is not set, attempt fix now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
sed "/delete these required/i *nat\n:POSTROUTING ACCEPT [0:0]\n-I POSTROUTING -s 10.6.0.0/24 -o $PHYS_INT -j MASQUERADE\nCOMMIT\n" -i /etc/ufw/before.rules
|
||||||
|
ufw reload
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if iptables -C ufw-user-input -p udp --dport "${pivpnPORT}" -j ACCEPT &> /dev/null; then
|
||||||
|
echo ":: [OK] Ufw input rule set"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] Ufw input rule is not set, attempt fix now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
ufw insert 1 allow "$pivpnPORT"/udp
|
||||||
|
ufw reload
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if iptables -C ufw-user-forward -i wg0 -o "${PHYS_INT}" -s 10.6.0.0/24 -j ACCEPT &> /dev/null; then
|
||||||
|
echo ":: [OK] Ufw forwarding rule set"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] Ufw forwarding rule is not set, attempt fix now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
ufw route insert 1 allow in on wg0 from 10.6.0.0/24 out on "$PHYS_INT" to any
|
||||||
|
ufw reload
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if systemctl is-active -q wg-quick@wg0; then
|
||||||
|
echo ":: [OK] WireGuard is running"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] WireGuard is not running, try to start now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
systemctl start wg-quick@wg0
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if systemctl is-enabled -q wg-quick@wg0; then
|
||||||
|
echo ":: [OK] WireGuard is enabled (it will automatically start on reboot)"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] WireGuard is not enabled, try to enable now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
systemctl enable wg-quick@wg0
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# grep -w (whole word) is used so port 111940 with now match when looking for 1194
|
||||||
|
if netstat -uanp | grep -w "${pivpnPORT}" | grep -q 'udp'; then
|
||||||
|
echo ":: [OK] WireGuard is listening on port ${pivpnPORT}/udp"
|
||||||
|
else
|
||||||
|
ERR=1
|
||||||
|
read -r -p ":: [ERR] WireGuard is not listening, try to restart now? [Y/n] " REPLY
|
||||||
|
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
|
||||||
|
systemctl restart wg-quick@wg0
|
||||||
|
echo "Done"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ERR" -eq 1 ]; then
|
||||||
|
echo -e "[INFO] Run \e[1mpivpn -d\e[0m again to see if we detect issues"
|
||||||
|
fi
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e ":::: \e[1mWARNING\e[0m: This script should have automatically masked sensitive ::::"
|
||||||
|
echo -e ":::: information, however, still make sure that \e[4mPrivateKey\e[0m, \e[4mPublicKey\e[0m ::::"
|
||||||
|
echo -e ":::: and \e[4mPresharedKey\e[0m are masked before reporting an issue. An example key ::::"
|
||||||
|
echo ":::: that you should NOT see in this log looks like this: ::::"
|
||||||
|
echo ":::: WJhKKx+Uk1l1TxaH2KcEGeBdPBTp/k/Qy4EpBig5UnI= ::::"
|
||||||
|
printf "=============================================\n"
|
||||||
|
echo -e "::::\t\t\e[4mDebug complete\e[0m\t\t ::::"
|
63
scripts/wireguard/qrcodeCONF.sh
Executable file
63
scripts/wireguard/qrcodeCONF.sh
Executable file
|
@ -0,0 +1,63 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
helpFunc(){
|
||||||
|
echo "::: Show the qrcode of a client for use with the mobile app"
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Usage: pivpn <-qr|qrcode> [-h|--help] [<client-1>] ... [<client-n>] ..."
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Commands:"
|
||||||
|
echo "::: [none] Interactive mode"
|
||||||
|
echo "::: <client> Client(s) to show"
|
||||||
|
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
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
CLIENTS_TO_SHOW+=("$1")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
cd /etc/wireguard/configs
|
||||||
|
if [ ! -s clients.txt ]; then
|
||||||
|
echo "::: There are no clients to remove"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${#CLIENTS_TO_SHOW[@]}" -eq 0 ]; then
|
||||||
|
|
||||||
|
echo -e "::\e[4m Client list \e[0m::"
|
||||||
|
LIST=($(awk '{print $1}' clients.txt))
|
||||||
|
COUNTER=1
|
||||||
|
while [ $COUNTER -le ${#LIST[@]} ]; do
|
||||||
|
echo "• ${LIST[(($COUNTER-1))]}"
|
||||||
|
((COUNTER++))
|
||||||
|
done
|
||||||
|
|
||||||
|
read -r -p "Please enter the Name of the Client to show: " CLIENTS_TO_SHOW
|
||||||
|
|
||||||
|
if [ -z "${CLIENTS_TO_SHOW}" ]; then
|
||||||
|
echo "::: You can not leave this blank!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
for CLIENT_NAME in "${CLIENTS_TO_SHOW[@]}"; do
|
||||||
|
if grep -qw "${CLIENT_NAME}" clients.txt; then
|
||||||
|
echo -e "::: Showing client \e[1m${CLIENT_NAME}\e[0m below"
|
||||||
|
echo "====================================================================="
|
||||||
|
qrencode -t ansiutf8 < "${CLIENT_NAME}.conf"
|
||||||
|
echo "====================================================================="
|
||||||
|
else
|
||||||
|
echo -e "::: \e[1m${CLIENT_NAME}\e[0m does not exist"
|
||||||
|
fi
|
||||||
|
done
|
117
scripts/wireguard/removeCONF.sh
Executable file
117
scripts/wireguard/removeCONF.sh
Executable file
|
@ -0,0 +1,117 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
setupVars="/etc/pivpn/setupVars.conf"
|
||||||
|
|
||||||
|
helpFunc(){
|
||||||
|
echo "::: Remove a client conf profile"
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Usage: pivpn <-r|remove> [-h|--help] [<client-1>] ... [<client-n>] ..."
|
||||||
|
echo ":::"
|
||||||
|
echo "::: Commands:"
|
||||||
|
echo "::: [none] Interactive mode"
|
||||||
|
echo "::: <client> Client(s) to remove"
|
||||||
|
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
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
CLIENTS_TO_REMOVE+=("$1")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -f "${setupVars}" ]; then
|
||||||
|
echo "::: Missing setup vars file!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
source "${setupVars}"
|
||||||
|
|
||||||
|
cd /etc/wireguard
|
||||||
|
if [ ! -s configs/clients.txt ]; then
|
||||||
|
echo "::: There are no clients to remove"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${#CLIENTS_TO_REMOVE[@]}" -eq 0 ]; then
|
||||||
|
|
||||||
|
echo -e "::\e[4m Client list \e[0m::"
|
||||||
|
LIST=($(awk '{print $1}' configs/clients.txt))
|
||||||
|
COUNTER=1
|
||||||
|
while [ $COUNTER -le ${#LIST[@]} ]; do
|
||||||
|
echo "• ${LIST[(($COUNTER-1))]}"
|
||||||
|
((COUNTER++))
|
||||||
|
done
|
||||||
|
|
||||||
|
read -r -p "Please enter the Name of the Client to be removed from the list above: " CLIENTS_TO_REMOVE
|
||||||
|
|
||||||
|
if [ -z "${CLIENTS_TO_REMOVE}" ]; then
|
||||||
|
echo "::: You can not leave this blank!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
DELETED_COUNT=0
|
||||||
|
|
||||||
|
for CLIENT_NAME in "${CLIENTS_TO_REMOVE[@]}"; do
|
||||||
|
|
||||||
|
if ! grep -qw "${CLIENT_NAME}" configs/clients.txt; then
|
||||||
|
echo -e "::: \e[1m${CLIENT_NAME}\e[0m does not exist"
|
||||||
|
else
|
||||||
|
REQUESTED="$(sha256sum "configs/${CLIENT_NAME}.conf" | cut -c 1-64)"
|
||||||
|
read -r -p "Do you really want to delete $CLIENT_NAME? [Y/n] "
|
||||||
|
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
|
||||||
|
# Grab the least significant octed of the client IP address
|
||||||
|
COUNT=$(grep "${CLIENT_NAME}" configs/clients.txt | awk '{print $3}')
|
||||||
|
# And the creation date of the client
|
||||||
|
CREATION_DATE="$(grep "${CLIENT_NAME}" configs/clients.txt | awk '{print $2}')"
|
||||||
|
|
||||||
|
# Then remove the client matching the variables above
|
||||||
|
sed "/${CLIENT_NAME} ${CREATION_DATE} ${COUNT}/d" -i configs/clients.txt
|
||||||
|
|
||||||
|
# Remove the peer section from the server config
|
||||||
|
sed "/# begin ${CLIENT_NAME}/,/# end ${CLIENT_NAME}/d" -i wg0.conf
|
||||||
|
echo "::: Updated server config"
|
||||||
|
|
||||||
|
rm "configs/${CLIENT_NAME}.conf"
|
||||||
|
echo "::: Client config for ${CLIENT_NAME} removed"
|
||||||
|
|
||||||
|
rm "keys/${CLIENT_NAME}_priv"
|
||||||
|
rm "keys/${CLIENT_NAME}_pub"
|
||||||
|
echo "::: Client Keys for ${CLIENT_NAME} removed"
|
||||||
|
|
||||||
|
# Find all .conf files in the home folder of the user matching the checksum of the
|
||||||
|
# config and delete them. '-maxdepth 3' is used to avoid traversing too many folders.
|
||||||
|
find "${install_home}" -maxdepth 3 -type f -name '*.conf' -print0 | while IFS= read -r -d '' CONFIG; do
|
||||||
|
if sha256sum -c <<< "${REQUESTED} ${CONFIG}" &> /dev/null; then
|
||||||
|
rm "${CONFIG}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "::: Successfully deleted ${CLIENT_NAME}"
|
||||||
|
|
||||||
|
((DELETED_COUNT++))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
# Restart WireGuard only if some clients were actually deleted
|
||||||
|
if [ "${DELETED_COUNT}" -gt 0 ]; then
|
||||||
|
if systemctl restart wg-quick@wg0; then
|
||||||
|
echo "::: WireGuard restarted"
|
||||||
|
else
|
||||||
|
echo "::: Failed to restart WireGuard"
|
||||||
|
fi
|
||||||
|
fi
|
Loading…
Reference in a new issue