From dd618a626057e59f43e9b5c0b2a2e6bf4dc9370a Mon Sep 17 00:00:00 2001 From: Pavel Muhortov Date: Sun, 16 Apr 2023 10:28:28 +0300 Subject: [PATCH] add wg-connect-handling.sh --- README.md | 52 ++++++++++- wg-connect-handling.sh | 208 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 wg-connect-handling.sh diff --git a/README.md b/README.md index 60d4a93..b1d65b4 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Small tools needed to solve immediate tasks independently or as part of a projec * [`simplewc`.py](https://git.hmp.today/pavel.muhortov/utils#simplewc-py) * [`ovpn-client-management`.sh](https://git.hmp.today/pavel.muhortov/utils#ovpn-client-management-sh) * [`ovpn-connect-handling`.sh](https://git.hmp.today/pavel.muhortov/utils#ovpn-connect-handling-sh) +* [`wg-connect-handling`.sh](https://git.hmp.today/pavel.muhortov/utils#wg-connect-handling-sh) ____ @@ -313,7 +314,56 @@ sudo systemctl restart openvpn@server ```bash # check counter and names -cat /var/log/openvpn/openvpn-counts.log +watch cat /var/log/openvpn/openvpn-counts.log # check journal tail -f /var/log/openvpn/ovpn-connect-handling.log ``` + +____ + +## `wg-connect-handling`.sh + +**Description:** +> Handling client connection and preparing stats for monitoring. + +**Dependencies:** +> +> * privileged rights +> * [jq](https://github.com/stedolan/jq) (tested version 1.6 on [Debian GNU/Linux 11](http://ftp.debian.org/debian/dists/bullseye/)) +> [grepcidr](https://github.com/ryantig/grepcidr) (tested version 2.0 on [Debian GNU/Linux 11](http://ftp.debian.org/debian/dists/bullseye/)) +> * [Python 3](https://www.python.org/downloads/) (tested version 3.9.5 on [Debian GNU/Linux 11](http://ftp.debian.org/debian/dists/bullseye/)) +> * existing [/usr/local/bin/sendmail.py](http://git.hmp.today/pavel.muhortov/utils/raw/branch/master/sendmail.py) +> * [bash](https://www.gnu.org/software/bash/) (tested versions: 5.1.4 on [Debian GNU/Linux 11](http://ftp.debian.org/debian/dists/bullseye/), 5.0.17 on [Ubuntu 20](https://wiki.ubuntu.com/FocalFossa/ReleaseNotes), 4.2.46 on [CentOS 7](https://wiki.centos.org/Manuals/ReleaseNotes/CentOS7.2009)) + +| POSITION | PARAMETERS | DESCRIPTION | DEFAULT | +|-----------|--------------|------------------------|---------------| +| 1 |****|root path for counter, names, log|**REQUIRED**| +| 2 |**[mail]**|send email notification|| +| 3 |**[geo]**|check client address geolocation|| + +Example usage: + +```bash +# download +sudo wget https://git.hmp.today/pavel.muhortov/utils/src/branch/master/wg-connect-handling.sh -O /etc/wireguard/wg-connect-handling.sh +sudo chmod +x /etc/wireguard/wg-connect-handling.sh +``` + +```bash +# create root path for counter, names, log +sudo mkdir /var/log/wireguard +sudo chown -R root:root /var/log/wireguard +sudo chmod -R 755 /var/log/wireguard +``` + +```bash +# sudo crontab -e +* * * * * bash /etc/wireguard/wg-connect-handling.sh /var/log/wireguard mail geo +``` + +```bash +# check counter and names +watch cat /var/log/wireguard/wg-counts.log +# check journal +tail -f /var/log/wireguard/wg-connect-handling.log +``` diff --git a/wg-connect-handling.sh b/wg-connect-handling.sh new file mode 100644 index 0000000..4de263a --- /dev/null +++ b/wg-connect-handling.sh @@ -0,0 +1,208 @@ +#! /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