Refactoring + WireGuard support

This commit is contained in:
Orazio 2019-10-14 12:11:16 +02:00
parent 9f20f50e61
commit 24a1a00d37
11 changed files with 1103 additions and 2522 deletions

File diff suppressed because it is too large Load diff

106
pivpn
View file

@ -1,106 +0,0 @@
#!/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

View file

@ -1,31 +0,0 @@
#!/bin/bash
install_user=$(</etc/pivpn/INSTALL_USER)
install_home=$(grep -m1 "^${install_user}:" /etc/passwd | cut -d: -f6)
install_home=${install_home%/} # remove possible trailing slash
backupdir=pivpnbackup
openvpndir=/etc/openvpn
ovpnsdir=${install_home}/ovpns
date=$(date +%Y-%m-%d-%H%M%S)
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

View file

@ -1,22 +0,0 @@
_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

View file

@ -1,35 +0,0 @@
#!/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"

View file

@ -1,27 +0,0 @@
#!/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"

View file

@ -1,415 +0,0 @@
#!/bin/bash
# Create OVPN Client
# Default Variable Declarations
DEFAULT="Default.txt"
FILEEXT=".ovpn"
CRT=".crt"
KEY=".key"
CA="ca.crt"
TA="ta.key"
INDEX="/etc/openvpn/easy-rsa/pki/index.txt"
INSTALL_USER=$(</etc/pivpn/INSTALL_USER)
INSTALL_HOME=$(grep -m1 "^${INSTALL_USER}:" /etc/passwd | cut -d: -f6)
INSTALL_HOME=${INSTALL_HOME%/} # remove possible trailing slash
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 [ ! -f /etc/pivpn/HELP_SHOWN ]; then
helpFunc
echo
touch /etc/pivpn/HELP_SHOWN
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 "/home/$INSTALL_USER/ovpns/$NAME.ovpn12"
chown "$INSTALL_USER" "/home/$INSTALL_USER/ovpns/$NAME.ovpn12"
chmod 600 "/home/$INSTALL_USER/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
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}"
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"

View file

@ -1,230 +0,0 @@
#!/usr/bin/env bash
# This scripts runs as root
PORT=$(cat /etc/pivpn/INSTALL_PORT)
PROTO=$(cat /etc/pivpn/INSTALL_PROTO)
IPv4dev="$(cat /etc/pivpn/pivpnINTERFACE)"
REMOTE="$(grep 'remote ' /etc/openvpn/easy-rsa/pki/Default.txt | awk '{print $2}')"
NO_UFW=$(cat /etc/pivpn/NO_UFW)
OLD_UFW=$(cat /etc/pivpn/NO_UFW)
INPUT_CHAIN_EDITED="$(cat /etc/pivpn/INPUT_CHAIN_EDITED)"
FORWARD_CHAIN_EDITED="$(cat /etc/pivpn/FORWARD_CHAIN_EDITED)"
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 ::::"
# 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/$REMOTE/REMOTE/" < /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/$REMOTE/REMOTE/" < /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 [ "$NO_UFW" -eq 1 ]; then
if iptables -t nat -C POSTROUTING -s 10.8.0.0/24 -o "${IPv4dev}" -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 "${IPv4dev}" -j MASQUERADE
iptables-save > /etc/iptables/rules.v4
echo "Done"
fi
fi
if [ "$INPUT_CHAIN_EDITED" -eq 1 ]; then
if iptables -C INPUT -i "$IPv4dev" -p "$PROTO" --dport "$PORT" -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 "$IPv4dev" -p "$PROTO" --dport "$PORT" -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 "$IPv4dev" -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 "$IPv4dev" -o tun0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -I FORWARD 2 -s 10.8.0.0/24 -i tun0 -o "$IPv4dev" -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 "${IPv4dev}" -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 $IPv4dev -j MASQUERADE\nCOMMIT\n" -i /etc/ufw/before.rules
ufw reload
echo "Done"
fi
fi
if iptables -C ufw-user-input -p "${PROTO}" --dport "${PORT}" -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 "$PORT"/"$PROTO"
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 "${IPv4dev}" -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 "$IPv4dev" 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 "${PORT}" | grep -q "${PROTO}"; then
echo ":: [OK] OpenVPN is listening on port ${PORT}/${PROTO}"
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

View file

@ -1,123 +0,0 @@
#!/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"

View file

@ -1,153 +0,0 @@
#!/usr/bin/env bash
# PiVPN: Uninstall Script
PKG_MANAGER="apt-get"
INSTALL_USER=$(cat /etc/pivpn/INSTALL_USER)
INSTALL_HOME=$(grep -m1 "^${INSTALL_USER}:" /etc/passwd | cut -d: -f6)
INSTALL_HOME=${INSTALL_HOME%/} # remove possible trailing slash
PLAT=$(cat /etc/pivpn/DET_PLATFORM)
NO_UFW=$(cat /etc/pivpn/NO_UFW)
OLD_UFW=$(cat /etc/pivpn/NO_UFW)
PORT=$(cat /etc/pivpn/INSTALL_PORT)
PROTO=$(cat /etc/pivpn/INSTALL_PROTO)
IPv4dev="$(cat /etc/pivpn/pivpnINTERFACE)"
INPUT_CHAIN_EDITED="$(cat /etc/pivpn/INPUT_CHAIN_EDITED)"
FORWARD_CHAIN_EDITED="$(cat /etc/pivpn/FORWARD_CHAIN_EDITED)"
# Find the rows and columns. Will default to 80x24 if it can not be detected.
screen_size=$(stty size 2>/dev/null || echo 24 80)
rows=$(echo $screen_size | awk '{print $1}')
columns=$(echo $screen_size | awk '{print $2}')
# Divide by two so the dialogs take up half of the screen, which looks nice.
r=$(( rows / 2 ))
c=$(( columns / 2 ))
# Unless the screen is tiny
r=$(( r < 20 ? 20 : r ))
c=$(( c < 70 ? 70 : c ))
spinner()
{
local pid=$1
local delay=0.50
local spinstr='/-\|'
while [ "$(ps a | awk '{print $1}' | grep "$pid")" ]; do
local temp=${spinstr#?}
printf " [%c] " "$spinstr"
local spinstr=$temp${spinstr%"$temp"}
sleep $delay
printf "\b\b\b\b\b\b"
done
printf " \b\b\b\b"
}
function removeAll {
# Purge dependencies
echo ":::"
dependencies=( openvpn easy-rsa git iptables-persistent dnsutils expect unattended-upgrades )
for i in "${dependencies[@]}"; do
if [ "$(dpkg-query -W --showformat='${Status}\n' "$i" 2> /dev/null | grep -c "ok installed")" -eq 1 ]; then
while true; do
read -rp "::: Do you wish to remove $i from your system? [y/n]: " yn
case $yn in
[Yy]* ) printf ":::\tRemoving %s..." "$i"; $PKG_MANAGER -y remove --purge "$i" &> /dev/null & spinner $!; printf "done!\n";
if [ "$i" == "openvpn" ]; then UINST_OVPN=1 ; fi
if [ "$i" == "unattended-upgrades" ]; then UINST_UNATTUPG=1 ; fi
break;;
[Nn]* ) printf ":::\tSkipping %s\n" "$i"; break;;
* ) printf "::: You must answer yes or no!\n";;
esac
done
else
printf ":::\tPackage %s not installed... Not removing.\n" "$i"
fi
done
# Take care of any additional package cleaning
printf "::: Auto removing remaining dependencies..."
$PKG_MANAGER -y autoremove &> /dev/null & spinner $!; printf "done!\n";
printf "::: Auto cleaning remaining dependencies..."
$PKG_MANAGER -y autoclean &> /dev/null & spinner $!; printf "done!\n";
echo ":::"
# Removing pivpn files
echo "::: Removing pivpn system files..."
$SUDO rm -rf /opt/pivpn &> /dev/null
$SUDO rm -rf /etc/.pivpn &> /dev/null
$SUDO rm -rf $INSTALL_HOME/ovpns &> /dev/null
rm -rf /var/log/*pivpn* &> /dev/null
rm -rf /var/log/*openvpn* &> /dev/null
if [[ $UINST_OVPN = 1 ]]; then
rm -rf /etc/openvpn &> /dev/null
if [[ $PLAT == "Ubuntu" || $PLAT == "Debian" ]]; then
printf "::: Removing openvpn apt source..."
rm -rf /etc/apt/sources.list.d/swupdate.openvpn.net.list &> /dev/null
$PKG_MANAGER -qq update & spinner $!; printf "done!\n";
fi
fi
if [[ $UINST_UNATTUPG = 1 ]]; then
rm -rf /var/log/unattended-upgrades
rm -rf /etc/apt/apt.conf.d/*periodic
fi
rm -rf /etc/pivpn &> /dev/null
rm /usr/local/bin/pivpn &> /dev/null
rm /etc/bash_completion.d/pivpn
# Disable IPv4 forwarding
sed -i '/net.ipv4.ip_forward=1/c\#net.ipv4.ip_forward=1' /etc/sysctl.conf
sysctl -p
if [[ $NO_UFW -eq 0 ]]; then
sed -z "s/*nat\n:POSTROUTING ACCEPT \[0:0\]\n-I POSTROUTING -s 10.8.0.0\/24 -o $IPv4dev -j MASQUERADE\nCOMMIT\n\n//" -i /etc/ufw/before.rules
ufw delete allow "$PORT"/"$PROTO" >/dev/null
if [ "$OLD_UFW" -eq 1 ]; then
sed -i "s/\(DEFAULT_FORWARD_POLICY=\).*/\1\"DROP\"/" /etc/default/ufw
else
ufw route delete allow in on tun0 from 10.8.0.0/24 out on "$IPv4dev" to any >/dev/null
fi
ufw reload >/dev/null
else
iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o "${IPv4dev}" -j MASQUERADE
if [ "$INPUT_CHAIN_EDITED" -eq 1 ]; then
iptables -D INPUT -i "$IPv4dev" -p "$PROTO" --dport "$PORT" -j ACCEPT
fi
if [ "$FORWARD_CHAIN_EDITED" -eq 1 ]; then
iptables -D FORWARD -d 10.8.0.0/24 -i "$IPv4dev" -o tun0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -D FORWARD -s 10.8.0.0/24 -i tun0 -o "$IPv4dev" -j ACCEPT
fi
iptables-save > /etc/iptables/rules.v4
fi
echo ":::"
printf "::: Finished removing PiVPN from your system.\n"
printf "::: Reinstall by simpling running\n:::\n:::\tcurl -L https://install.pivpn.io | bash\n:::\n::: at any time!\n:::\n"
}
function askreboot() {
printf "It is \e[1mstrongly\e[0m recommended to reboot after un-installation.\n"
read -p "Would you like to reboot now? [y/n]: " -n 1 -r
echo
if [[ ${REPLY} =~ ^[Yy]$ ]]; then
printf "\nRebooting system...\n"
sleep 3
shutdown -r now
fi
}
######### SCRIPT ###########
echo "::: Preparing to remove packages, be sure that each may be safely removed depending on your operating system."
echo "::: (SAFE TO REMOVE ALL ON RASPBIAN)"
while true; do
read -rp "::: Do you wish to completely remove PiVPN configuration and installed packages from your system? (You will be prompted for each package) [y/n]: " yn
case $yn in
[Yy]* ) removeAll; askreboot; break;;
[Nn]* ) printf "::: Not removing anything, exiting...\n"; break;;
esac
done

View file

@ -1,99 +0,0 @@
#/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