#! /bin/bash # DESCRIPTION: # handling client connection # and # preparing stats for monitoring # # DEPENDENCIES: # - privileged rights # - jq # - grepcidr # - Python 3 # - existing /usr/local/bin/sendmail.py # # PARAMETERS: # 1: root path for counter, names, log # 2: "mail" - send email notification # 3: "geo" - check client address geolocation # # FUNCTIONS: # ####################################### # Print message and add to log. # Globals: # logs # Arguments: # 1: message to print and logging ####################################### addtologs() { echo "$(date +'%Y.%m.%d-%H:%M:%S') $1" | tee -a "${logs}" } ####################################### # Exit procedure. # Globals: # show # Arguments: # None ####################################### execquite() { addtologs "execution time is $(($(date +%s)-time)) seconds, exit" exit } ####################################### # Error exit procedure # Globals: # None # Arguments: # 1: message to print and logging ####################################### execerror() { addtologs "error: $1" execquite } ####################################### # Checking user rights. # Globals: # None # Arguments: # None # return: # 0 - if privileged rights, 1 - if not privileged rights ####################################### checkroot() { if [ "${EUID}" -ne 0 ]; then return 1 # false else return 0 # true fi } ####################################### # Get information about client address # Globals: # flaggeol # show_from_addr # conf_client_nm # Arguments: # None ####################################### # shellcheck disable=SC2154 expandaddress() { ipinfo="Source address is ${show_from_addr}" localnetworks="10.0.0.0/8 100.64.0.0/10 127.0.0.1/8 172.16.0.0/12 192.168.0.0/16 " if ! grepcidr "${localnetworks}" <(echo "${show_from_addr}") >/dev/null; then if [ "${flaggeol}" == "geo" ]; then ipinfo=$(curl "https://api.ipbase.com/v1/json/${show_from_addr}") if [ "$(jq -r '.country_name' <<< "$ipinfo")" != "" ]; then z=$(jq -r '.zip_code' <<< "$ipinfo") c=$(jq -r '.country_name' <<< "$ipinfo") r=$(jq -r '.region_name' <<< "$ipinfo") t=$(jq -r '.city' <<< "$ipinfo") ipinfo="Source address ${show_from_addr} is from ${z}, ${c}, ${r}, ${t}" fi fi fi addtologs "client ${conf_client_nm} checked. ${ipinfo}" } ####################################### # Send email notification about client connect # Globals: # ipinfo # conf_client_nm # conf_ipaddress # Arguments: # None ####################################### startsendmail() { subj="[VPN Connected] $(cat /etc/hostname): ${conf_client_nm} connect to ${conf_ipaddress}" ( python3 /usr/local/bin/sendmail.py \ -u "$(grep "from=" /usr/local/bin/sendmail.config | cut -d= -f2)" \ -p "$(grep "pass=" /usr/local/bin/sendmail.config | cut -d= -f2)" \ -d "$(grep "dest=" /usr/local/bin/sendmail.config | cut -d= -f2)" \ --smtp "$(grep "smtp=" /usr/local/bin/sendmail.config | cut -d= -f2)" \ --port "$(grep "port=" /usr/local/bin/sendmail.config | cut -d= -f2)" \ --stls "True" \ --subj "${subj}" \ --text "${ipinfo}" \ >> /dev/null 2>&1 & ) addtologs "sent mail with subject '${subj}'" } # # VARIABLES: # pathroot=$1 flagmail=$2 flaggeol=$3 time=$(date +%s) logs="${pathroot}/$(basename -s .sh "$0").log" counts_file="${pathroot}/wg-counts.log" counts_temp=$(cat "${counts_file}") if [ -z "${pathroot}" ]; then logs=/dev/null execerror "Usage example: $0 '/var/log/wireguard' '-' '-'" elif [ ! -e "${logs}" ]; then touch "${logs}" fi if ! command -v curl &> /dev/null || \ ! command -v /usr/local/bin/sendmail.py &> /dev/null || \ ! command -v python3 &> /dev/null || \ ! command -v grepcidr &> /dev/null || \ ! command -v jq &> /dev/null; then execerror "Not found dependencies" fi # # MAIN: # if checkroot; then allowed_cfg=$(find /etc/wireguard/ -name "*.conf" | grep -v "wg0.conf") counter_now=0 clients_now="" while read -r file; do conf_keepalive=$(grep "PersistentKeepalive" "${file}" |cut -d"=" -f2 |tr -d " ") conf_ipaddress=$(grep "Address" "${file}" |cut -d"=" -f2 |cut -d"/" -f1 |tr -d " ") conf_client_nm=$(basename -s .conf "${file}") show_handshake=$(wg show all dump |grep "${conf_ipaddress}" |cut -f6) show_from_addr=$(wg show all dump |grep "${conf_ipaddress}" |cut -f4 |cut -d":" -f1) if [ "${show_handshake}" -ne 0 ]; then calc_handshake="$(date -d "-${conf_keepalive} min" +"%s")" if [ "${show_handshake}" -ge "${calc_handshake}" ]; then (( counter_now ++)) connect_status="connected" if ping -q -c 1 -W 1 "${conf_ipaddress}" > /dev/null; then connect_status="connected, ping responded" else connect_status="connected, ping loss" fi clients_now+=$(printf "%s\n\r" "${conf_client_nm}_${conf_ipaddress}") if ! grep -q "${conf_client_nm}_${conf_ipaddress}" <<< "${counts_temp}"; then addtologs "client ${conf_client_nm} ${connect_status}" expandaddress if [ "${flagmail}" == "mail" ]; then startsendmail fi fi else connect_status="disconnected" if grep -q "${conf_client_nm}_${conf_ipaddress}" <<< "${counts_temp}"; then addtologs "client ${conf_client_nm} ${connect_status}" fi fi else connect_status="never connected" fi done <<< "$allowed_cfg" printf "%s\n" "total=${counter_now}=" > "${counts_file}" printf "%s\n" "${clients_now}" >> "${counts_file}" else execerror "Restart this as root!" fi execquite