我希望有人知道如何获得它,以便每当有人与我的网络建立 VPN 连接时,我都会收到有关它的电子邮件。
我可以通过运行脚本并检查 openvpn 日志来做到这一点吗?我使用 pivpn 脚本来设置 openvpn 服务器。那么可以通过检查 pivpn -c 选项来完成吗?
我想我可以使用 openvpn 日志上的 if than 语句来实现这一点,但我怎样才能让它只显示新连接呢?
答案1
OpenVPN 命令具有--client-connect
和--client-disconnect
选项,允许您为这些(和其他)事件运行脚本。
然后,您可以创建一个脚本,通过电子邮件向您发送有关连接的信息。
OpenVPN 在执行这些脚本时将提供许多环境变量,允许您将连接信息附加到这些电子邮件中。
在我的配置中,/etc/openvpn/server.conf 中有以下几行:
script-security 2
client-connect /etc/openvpn/server/connect-disconnect.sh
client-disconnect /etc/openvpn/server/connect-disconnect.sh
我的/etc/openvpn/server/connect-disconnect.sh
归其所有nobody
(因为这是我的系统执行 OpenVPN 的用户)并包含以下内容(警告!长而丑陋的 shell 脚本即将到来!):
#!/bin/bash
# Connect/disconnect script for OpenVPN clients
# For all available variables, see the "Environmental Variables" section
# at https://openvpn.net/community-resources/reference-manual-for-openvpn-2-4/
from_address="openvpn@$HOSTNAME"
from_name="openvpn@$HOSTNAME"
to_address="my-email-address"
function unitify_bytes {
bytes=$1
if [ "$bytes" -gt "1073741824" ]; then
echo $(( $bytes / 1073741824 )) GiB
elif [ "$bytes" -gt "1048576" ]; then
echo $(( $bytes / 1048576 )) MiB
elif [ "$bytes" -gt "1024" ]; then
echo $(( $bytes / 1024 )) KiB
else
echo $bytes B
fi
}
function unitify_seconds {
local SS=$1
if [ "$SS" -ge "60" ]; then
local MM=$(($SS / 60))
local SS=$(($SS - 60 * $MM))
if [ "$MM" -ge "60" ]; then
local HH=$(($MM / 60))
local MM=$(($MM - 60 * $HH))
if [ "$HH" -ge "24" ]; then
local DD=$(($HH / 24))
local HH=$(($HH - 24 * $DD))
local time_string="$DD days, $HH hours, $MM minutes and $SS seconds"
else
local time_string="$HH hours, $MM minutes and $SS seconds"
fi
else
local time_string="$MM minutes and $SS seconds"
fi
else
local time_string="$SS seconds"
fi
echo "$time_string"
}
if [ "$script_type" == "client-connect" ]; then
action="connected to"
else
action="disconnected from"
action_specific_info=" \
<dt>Session Duration</dt> <dd>$(unitify_seconds $time_duration)</dd> \
<dt>Received</dt> <dd>$(unitify_bytes $bytes_received)</dd> \
<dt>Sent</dt> <dd>$(unitify_bytes $bytes_sent)</dd> \
"
fi
now=$(echo $(date +"%c"))
cat <<EOF | /usr/sbin/sendmail -f "$from_address" $to_address
Subject: OpenVPN: $common_name $action $HOSTNAME
Content-Type: text/html
From: $from_name<$from_address>
Date: `date -R`
<html>
<head>
<style>
dt {
float: left;
width: 30%;
text-align: right;
padding: .25em;
clear: left;
font-weight: bold;
}
dd {
float: left;
width: 60%;
padding: .25em 0;
}
dl:after {
content: "";
display: table;
clear: both;
}
</style>
</head>
<body>
<h1>Client <i>$common_name</i> has $action OpenVPN</h1>
<h2>Connection Details</h2>
<dl>
<dt>Client Common Name</dt> <dd>$common_name</dd>
<dt>Connection Start</dt> <dd>$time_ascii</dd>
<dt>Client WAN IP</dt> <dd>$untrusted_ip</dd>
<dt>Client LAN IP</dt> <dd>$ifconfig_pool_remote_ip</dd>
${action_specific_info}
</dl>
<hr/>
<p>OpenVPN at $HOSTNAME.</p>
</body>
</html>
EOF
请注意,您应该更新顶部的变量以匹配您的环境。我已sendmail
配置为将所有邮件转发到我的邮件帐户,因此您可能需要在该区域进行更多配置/脚本更改...
答案2
你可以使用 tail -f 命令查看日志文件,这样你就只能看到脚本中最近添加的内容,当新内容符合你的条件时,该脚本会发送电子邮件
可能使用的代码。
- 此代码使用 mutt 发送电子邮件。
- 设置要在变量中监视的日志文件:logfile
- 在变量中设置你的电子邮件地址:emailaddress
- 有一个硬编码的永久 while 循环。
tail -f 跟在文件中添加行时跟随,而 -c 0 告诉 tail 在重新启动时仅查找最后 0 个字节,这样它就不会重新读取最后 10 行并向您发送额外的旧警报。
#!/bin/sh words_to_match="Connection established" logfile=~/test.log emailaddress="[email protected]" tail -f -c 0 ${logfile} | (while true ; do read -r line_to_check echo ${line_to_check} | grep -q ${words_to_match} if [ "$?" = "0" ] ; then echo "${line_to_check}" | mutt -s "VPN Login" ${emailaddress} fi done )
答案3
您还可以使用在 python3 上编写的这个脚本: https://github.com/fernandocastrovilar/openvpn_connection_notifier
它使用本机的 OpenVPN 状态来检索过去 5 分钟内连接的用户并通过电子邮件通知他们。