VPN 连接时的电子邮件警报

VPN 连接时的电子邮件警报

我希望有人知道如何获得它,以便每当有人与我的网络建立 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 分钟内连接的用户并通过电子邮件通知他们。

相关内容