From 0c5cc93d0256fb032f75dd19ef5aee07d46f5d5b Mon Sep 17 00:00:00 2001 From: Christoph Date: Tue, 25 Sep 2018 03:33:03 +0200 Subject: [PATCH] Initial commit --- .gitignore | 3 + conf/ovpn.conf.sample | 14 ++ ovpn-wipe.so36.net | 136 ++++++++++++++ ovpn.sh | 399 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 552 insertions(+) create mode 100644 .gitignore create mode 100644 conf/ovpn.conf.sample create mode 100755 ovpn-wipe.so36.net create mode 100755 ovpn.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a3b58e5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.swp +/conf/*.conf +/BAK/* diff --git a/conf/ovpn.conf.sample b/conf/ovpn.conf.sample new file mode 100644 index 0000000..5b27899 --- /dev/null +++ b/conf/ovpn.conf.sample @@ -0,0 +1,14 @@ +# ----------------------------------- +# - Settings for script pcs_online.sh +# ----------------------------------- + +# - BASE_OPENVPN_CLIENT_DIR +# - +# - Directory containing the openvpn client configurations, +# - each in a seperate directors +# - +# - Defaults to: BASE_OPENVPN_CLIENT_DIR="/etc/openvpn/client-confs" +# - +#BASE_OPENVPN_CLIENT_DIR="" + + diff --git a/ovpn-wipe.so36.net b/ovpn-wipe.so36.net new file mode 100755 index 0000000..e52c8a4 --- /dev/null +++ b/ovpn-wipe.so36.net @@ -0,0 +1,136 @@ +#!/usr/bin/env bash + +VPN_Network="VPN-SO36-wipe" + +PID_FILE="/var/run/${VPN_Network}" + + +# ---------- +# Base Function(s) +# ---------- + +clean_up() { + + # - Terminate connection + # - + if ps -p "$_pid" > /dev/null 2>&1; then + sudo kill $_pid > /dev/null 2>&1 + fi + + # - Remove PID file + # - + sudo rm -f "$PID_FILE" + + if $terminal ; then + echo -en "\033[1G" + if [[ "$1" -gt 0 ]]; then + blank_line + echo -e " \033[41m Connection to \033[1m${VPN_Network}\033[m\033[41m was terminated! \033[m" + else + echononl "Terminate VPN connection to \033[32m\033[1m${VPN_Network}\033[m" + echo_done + fi + blank_line + fi + + exit $1 +} + +echononl(){ + if $terminal ; then + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n " $*\\c" 1>&2 + else + echo -e -n " $*" 1>&2 + fi + rm /tmp/shprompt$$ + fi +} + + +echo_done() { + if $terminal ; then + echo -e "\033[75G[ \033[32mdone\033[m ]" + fi +} +echo_failed(){ + if $terminal ; then + echo -e "\033[75G[ \033[1;31mfailed\033[m ]" + fi +} +echo_wait(){ + if $terminal ; then + echo -en "\033[75G[ \033[5m\033[1m..\033[m ]" + fi +} + + +blank_line() { + if $terminal ; then + echo "" + fi +} + + +# ---------- +# - Jobhandling +# ---------- + +# - Run 'clean_up' for signals SIGHUP SIGINT SIGTERM +# - +trap clean_up SIGHUP SIGINT SIGTERM + + +# ---------- +# - Some checks .. +# ---------- + +# - Running in a terminal? +# - +if [[ -t 1 ]] ; then + terminal=true +else + terminal=false +fi + + +# ---------- +# - Main part of script +# ---------- + +blank_line +echononl "Establish VPN connection to \033[32m\033[1m${VPN_Network}\033[m" +echo_wait + +sudo /usr/sbin/openvpn \ + --config /etc/openvpn/client-confs/VPN-SO36-wipe/client.conf \ + --writepid /var/run/openvpn-wipe-so36.pid \ + --log /var/log/openvpn/wipe-so36.log \ + --status /var/log/openvpn/status-wipe-so36.log > /dev/null 2>&1 & + +_pid="$!" +declare -i time=0 + +if ps -p "$_pid" > /dev/null 2>&1; then + while ! ip a | grep -q -E "tun[0-9]{1,2}" 2> /dev/null && [[ $time -lt 60 ]] ; do + sleep 1 + ((time++)) + done + if [[ $time -ge 60 ]]; then + echo_failed + clean_up 1 + else + echo_done + fi +else + echo_failed + clean_up 1 +fi + +#while ps -p "$_pid" > /dev/null 2>&1 ; do +while ip a | grep -q -E "tun[0-9]{1,2}" 2> /dev/null ; do + sleep 3 +done + +clean_up 0 diff --git a/ovpn.sh b/ovpn.sh new file mode 100755 index 0000000..b57d766 --- /dev/null +++ b/ovpn.sh @@ -0,0 +1,399 @@ +#!/usr/bin/env bash + +# ----- +# - You need the the following sudo permissions (visudo) for that user, +# - who starts this script +# - +# - chris ALL=(root)NOPASSWD:/usr/sbin/openvpn +# - chris ALL=(root)NOPASSWD:/bin/rm -f /var/run/* +# - chris ALL=(root)NOPASSWD:/bin/kill +# ----- + + +script_name="$(basename $(realpath $0))" +working_dir="$(dirname $(realpath $0))" + +log_file="$(mktemp)" + +conf_file="${working_dir}/conf/${script_name%%.*}.conf" + + + +DEFAULT_BASE_OPENVPN_CLIENT_DIR="/etc/openvpn/client-confs" +DEFAULT_VPN_User="chris" + +VPN_Network="" + +declare -a openvpn_connection_arr=() + +# ---------- +# Base Function(s) +# ---------- + +clean_up() { + + + + # - Terminate connection + # - + if ps -p "$_pid" > /dev/null 2>&1; then + sudo kill $_pid > /dev/null 2>&1 + fi + + # - Remove PID file + # - + sudo rm -f "$PID_FILE" + + if $terminal ; then + echo -en "\033[1G" + if [[ "$1" -gt 0 ]]; then + blank_line + echo -e " \033[41m Connection to \033[1m${VPN_Network}\033[m\033[41m was terminated! \033[m" + else + echononl "Terminate VPN connection to \033[32m\033[1m${VPN_Network}\033[m" + echo_done + fi + blank_line + fi + + rm -f $log_file + + exit $1 +} + +echononl(){ + if $terminal ; then + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n " $*\\c" 1>&2 + else + echo -e -n " $*" 1>&2 + fi + rm /tmp/shprompt$$ + fi +} + +fatal(){ + echo "" + if $terminal ; then + echo -e " [ \033[31m\033[1mFatal\033[m ] $*" + else + echo -e " [ Fatal ] $*" + fi + echo "" + if $terminal ; then + echo -e " \033[1mScript terminated\033[m.." + else + echo -e " Script terminated.." + fi + echo "" + + rm -f $log_file + exit 1 + +} + +error (){ + echo "" + if $terminal ; then + echo -e " [ \033[31m\033[1mError\033[m ] $*" + else + echo " [ Error ] $*" + fi + echo "" +} + + +warn (){ + if $terminal ; then + echo "" + if $terminal ; then + echo -e " [ \033[33m\033[1mWarn\033[m ] $*" + else + echo " [ Warn ] $*" + fi + echo "" + fi +} + + + + +echo_done() { + if $terminal ; then + echo -e "\033[75G[ \033[32mdone\033[m ]" + fi +} +echo_failed(){ + if $terminal ; then + echo -e "\033[75G[ \033[1;31mfailed\033[m ]" + fi +} +echo_wait(){ + if $terminal ; then + echo -en "\033[75G[ \033[5m\033[1m..\033[m ]" + fi +} +echo_skipped() { + if $terminal ; then + echo -e "\033[75G[ \033[33m\033[1mskipped\033[m ]" + fi +} + + + +blank_line() { + if $terminal ; then + echo "" + fi +} + +is_valid_ipv4() { + local -a octets=( ${1//\./ } ) + local RETURNVALUE=0 + + # return an error if the IP doesn't have exactly 4 octets + [[ ${#octets[@]} -ne 4 ]] && return 1 + + for octet in ${octets[@]} + do + if [[ ${octet} =~ ^[0-9]{1,3}$ ]] + then # shift number by 8 bits, anything larger than 255 will be > 0 + ((RETURNVALUE += octet>>8 )) + else # octet wasn't numeric, return error + return 1 + fi + done + return ${RETURNVALUE} +} + +# - Test if given argument is a valid IPv6 Address +# - +is_valid_ipv6() { + local _ipv6="$1" + + _regex_ipv6='^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$' + + + if [[ "$_ipv6" =~ ${_regex_ipv6} ]]; then + return 0 + else + return 1 + fi +} + + +is_number() { + + return $(test ! -z "${1##*[!0-9]*}" > /dev/null 2>&1); + + # - also possible + # - + #[[ ! -z "${1##*[!0-9]*}" ]] && return 0 || return 1 + #return $([[ ! -z "${1##*[!0-9]*}" ]]) +} + +is_int() { + return $(test "$@" -eq "$@" > /dev/null 2>&1); +} + + + +# ---------- +# - Jobhandling +# ---------- + +# - Run 'clean_up' for signals SIGHUP SIGINT SIGTERM +# - +trap clean_up SIGHUP SIGINT SIGTERM + + +# ---------- +# - Some checks .. +# ---------- + +# - Running in a terminal? +# - +if [[ -t 1 ]] ; then + terminal=true +else + terminal=false +fi + +[[ -n "$BASE_OPENVPN_CLIENT_DIR" ]] || BASE_OPENVPN_CLIENT_DIR="$DEFAULT_BASE_OPENVPN_CLIENT_DIR" +[[ -n "$VPN_User" ]] || VPN_User="$DEFAULT_VPN_User" + + +# ---------- +# - Headline +# ---------- + +if $terminal ; then + echo "" + echo -e "\033[1m----------\033[m" + echo -e "\033[32m\033[1mRunning script \033[m\033[1m$script_name\033[32m .. \033[m" + echo -e "\033[1m----------\033[m" +fi + +blank_line +echononl "Load Configuration File $(basename ${conf_file}).." +if [[ -f "$conf_file" ]]; then + source "$conf_file" > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_done + else + echo_failed + fatal "$(cat $log_file)" + fi + +else + echo_skipped +fi + + + + +# ---------- +# - Main part of script +# ---------- + +if $terminal ; then + # - Get available OpenVPN connections + # - + while IFS='' read -r -d '' _dir_name ; do + + [[ "$_dir_name" = ".." ]] && continue + [[ "$_dir_name" = "." ]] && continue + + openvpn_connection_arr+=("$(basename "$_dir_name")") + + done < <(find "$BASE_OPENVPN_CLIENT_DIR" -mindepth 1 -maxdepth 1 -type d -print0 | sort -z) + + echo "" + echo -e " \033[1mWhich Configuration should be loaded?\033[m" + echo "" + + + for i in ${!openvpn_connection_arr[@]}; do + echo -e " [$i]\033[9G${openvpn_connection_arr[$i]}" + done + echo "" + echo -e " [99]\033[9G\033[33mExit programm\033[m" + + echo "" + echononl "Choose: " + + _OK=false + while ! $_OK ; do + read _IN + if is_number "$_IN" && [[ -n ${openvpn_connection_arr[$_IN]} ]]; then + VPN_Network="${openvpn_connection_arr[$_IN]}" + _OK=true + elif is_number "$_IN" && [[ $_IN -eq 99 ]] ;then + echo"" + exit 0 + else + echo "" + echo -e "\tWrong value !" + echo "" + echononl "Choose again: " + fi + done +fi + + + +[[ -n "$VPN_Network" ]] || fatal "No VPN Network was given." +PID_FILE="/var/run/${VPN_Network}" + +ovpn_config_file="$(realpath $(ls ${BASE_OPENVPN_CLIENT_DIR}/${VPN_Network}/client-*.conf 2>/dev/null) 2> /dev/null )" + +if [[ ! -f "$ovpn_config_file" ]] ; then + fatal "Configurationfile for ${VPN_Network}' not found." +fi + +# - Get hostname and port +# - +_hostname="$(grep -E "^\s*remote\s+" $ovpn_config_file | awk '{print$2}')" + +if grep -q -E "^\s*rport\s+" $ovpn_config_file 2> /dev/null ; then + remote_port="$(grep -E "^\s*rport\s+" $ovpn_config_file | awk '{print$2}')" +else + remote_port="$(grep -E "^\s*remote\s+" $ovpn_config_file | awk '{print$3}')" +fi + +if is_valid_ipv4 $_hostname || is_valid_ipv6 $_hostname ; then + remote_address="$_hostname" +else + # - We need '| tail -1' becaus output prints at first line the + # - the CNAME of given hostname. + remote_address="$(dig +short $_hostname | tail -1)" +fi + +if [[ -f "${BASE_OPENVPN_CLIENT_DIR}/${VPN_Network}/ovpn_pass" ]]; then + OVPN_ASKPASS="${BASE_OPENVPN_CLIENT_DIR}/${VPN_Network}/ovpn_pass" +elif [[ -f "${BASE_OPENVPN_CLIENT_DIR}/${VPN_Network}/passwd.txt" ]] ; then + ovpn_pass="$(grep -E "passw" "${BASE_OPENVPN_CLIENT_DIR}/${VPN_Network}/passwd.txt" | awk '{print$2}')" + cat < "${BASE_OPENVPN_CLIENT_DIR}/${VPN_Network}/ovpn_pass" +$ovpn_pass +EOF + chmod 600 "${BASE_OPENVPN_CLIENT_DIR}/${VPN_Network}/ovpn_pass" + OVPN_ASKPASS="${BASE_OPENVPN_CLIENT_DIR}/${VPN_Network}/ovpn_pass" +elif [[ -f "${BASE_OPENVPN_CLIENT_DIR}/${VPN_Network}/password.txt" ]] ; then + ovpn_pass="$(grep -E "passw" "${BASE_OPENVPN_CLIENT_DIR}/${VPN_Network}/password.txt" | awk '{print$2}')" + cat < "${BASE_OPENVPN_CLIENT_DIR}/${VPN_Network}/ovpn_pass" +$ovpn_pass +EOF + OVPN_ASKPASS="${BASE_OPENVPN_CLIENT_DIR}/${VPN_Network}/ovpn_pass" +else + OVPN_ASKPASS="/root/.openvpn/${VPN_Network}" +fi + +echo "" +echo "${BASE_OPENVPN_CLIENT_DIR}/${VPN_Network}/ovpn_pass" +echo "${BASE_OPENVPN_CLIENT_DIR}/${VPN_Network}/password.txt" +echo "" +echo "" + + +blank_line +echononl "Establish VPN connection to \033[32m\033[1m${VPN_Network}\033[m" +echo_wait + +sudo /usr/sbin/openvpn \ + --config $ovpn_config_file \ + --proto udp4 \ + --remote $remote_address $remote_port \ + --writepid "$PID_FILE" \ + --log /var/log/openvpn/${VPN_Network}.log \ + --status /var/log/openvpn/status-${VPN_Network}.log \ + --askpass "$OVPN_ASKPASS" > $log_file 2>&1 & + + +_pid="$!" +declare -i time=0 + +if ps -p "$_pid" > /dev/null 2>&1; then + while ! ip a | grep -q -E "tun[0-9]{1,2}" 2> /dev/null && [[ $time -lt 60 ]] ; do + sleep 1 + ((time++)) + done + if [[ $time -ge 60 ]]; then + echo_failed + clean_up 1 + else + echo_done + fi +else + echo_failed + [[ -s "$log_file" ]] && error "$(cat $log_file)" + clean_up 1 +fi + + +#while ps -p "$_pid" > /dev/null 2>&1 ; do +while ip a | grep -q -E "tun[0-9]{1,2}" 2> /dev/null ; do + sleep 3 +done + +clean_up 0