悦书阁 悦书阁
首页
学习笔记
技术文档
AI技术
更多
  • 分类
  • 标签
  • 归档

Felix

大道至简 知易行难
首页
学习笔记
技术文档
AI技术
更多
  • 分类
  • 标签
  • 归档
  • 部署文档

    • 博客搭建
    • Jenkins教程
    • Docker安装和简单使用
    • minio安装
    • Mysql安装
    • Redis安装
    • Docker部署服务
    • IKEv2 VPN 部署教程
    • Windows开发环境配置指南
    • VPN 连接监控与 Telegram 实时通知
      • 背景
      • 一、最初方案:定时检查
        • 1.1 思路
        • 1.2 问题
      • 二、进阶方案:实时日志监控
        • 2.1 思路
        • 2.2 新问题:重复通知
        • 2.3 解决方案:SA ID 去重
      • 三、通知方案演进
        • 3.1 方案一:Cron + Agent
        • 3.2 方案二:直接调用 CLI
      • 四、最终方案
        • 4.1 监控脚本
        • 4.2 Systemd 服务
        • 4.3 启用服务
      • 五、效果展示
      • 六、技术要点总结
      • 七、扩展思路
      • 八、参考链接
  • 开发工具

  • 经验技巧

  • 技术文档
  • 部署文档
moyin
2026-06-06
目录

VPN 连接监控与 Telegram 实时通知

# 背景

之前部署了 IKEv2 VPN 供个人使用,但一直不知道有没有其他人在使用。每次想查看连接状态都要手动登录服务器执行命令,非常麻烦。

需求很简单:

  • 有人连接 VPN 时收到通知
  • 有人断开 VPN 时收到通知
  • 通知要推送到手机,方便随时查看

本文记录从零到完成 VPN 监控通知系统的完整过程,包括踩过的坑和最终方案。

# 一、最初方案:定时检查

# 1.1 思路

最直观的想法:写个脚本定时检查 VPN 连接数,有变化就发通知。

#!/bin/bash
# 获取当前 VPN 连接数
get_connections() {
    ip xfrm state list 2>/dev/null | grep "proto esp" | wc -l
}

current_count=$(get_connections)
actual_count=$((current_count / 2))  # 每个 VPN 连接有 2 个 SA
1
2
3
4
5
6
7
8

# 1.2 问题

实际测试发现,VPN 连接时长如果很短(比如 1-2 分钟),而检查间隔是 1 分钟,很容易漏掉:

时间轴:
22:03:00 - 用户连接 VPN
22:04:00 - 脚本检查(检测到连接,发送通知)
22:04:30 - 用户断开 VPN
22:05:00 - 脚本检查(SA 已删除,检测不到变化)
1
2
3
4
5

结果就是:连接通知发出了,但断开通知永远发不出。

# 二、进阶方案:实时日志监控

# 2.1 思路

既然轮询会漏事件,那就改成实时监控 strongswan 日志:

journalctl -u strongswan-starter -f | while read -r line; do
    # 检测连接
    if echo "$line" | grep -q "IKE_SA.*established"; then
        # 发送通知
    fi
    
    # 检测断开
    if echo "$line" | grep -q "deleting IKE_SA"; then
        # 发送通知
    fi
done
1
2
3
4
5
6
7
8
9
10
11

# 2.2 新问题:重复通知

测试时发现,同一条断开日志在 journalctl 里出现了多次:

Jun 06 22:19:54 charon[12345]: 10[IKE] deleting IKE_SA ikev2-vpn[1343] between...
Jun 06 22:19:54 charon[12345]: 10[IKE] deleting IKE_SA ikev2-vpn[1343] between...
1
2

结果就是断开时收到了多条重复通知。

# 2.3 解决方案:SA ID 去重

从日志中提取 SA 编号,用变量记录已处理的 SA:

processed_connected=""
processed_disconnected=""

# 连接时
if echo "$line" | grep -q "IKE_SA.*established between"; then
    sa_id=$(echo "$line" | grep -oP 'IKE_SA[^[]+\[\K[0-9]+')
    
    if [ -n "$sa_id" ] && ! echo "$processed_connected" | grep -q ":$sa_id:"; then
        processed_connected="$processed_connected:$sa_id:"
        send_notify "CONNECTED" "$remote_ip" "$timestamp"
    fi
fi

# 断开时(同理)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 三、通知方案演进

# 3.1 方案一:Cron + Agent

最初尝试用 OpenClaw 的 cron 任务:

  1. systemd 服务监控日志,检测到事件时写入通知文件
  2. cron 任务每分钟检查通知文件
  3. 如果文件存在,调用 agent 发送 Telegram 消息

问题:

  • agent 启动慢(15-30 秒),经常超时
  • 文件不存在时 agent 直接报错
  • 每次执行都要加载大量上下文,浪费资源

# 3.2 方案二:直接调用 CLI

最终发现 OpenClaw 提供了直接的命令行发送消息功能:

openclaw message send --channel telegram --target YOUR_CHAT_ID --message "通知内容"
1

这个命令执行只需 1-2 秒,完美解决问题!

# 四、最终方案

# 4.1 监控脚本

创建 /home/moyin/vpn-monitor/vpn-monitor.sh:

#!/bin/bash
# VPN 实时日志监控 - 直接发送 Telegram 通知

# 记录已处理的 SA,避免重复通知
processed_connected=""
processed_disconnected=""

# 发送 Telegram 通知
send_notify() {
    local event="$1"
    local ip="$2"
    local timestamp="$3"
    
    if [ "$event" = "CONNECTED" ]; then
        local msg="🔒 VPN 连接通知

✅ 新设备已连接
📍 IP: ${ip}
🕐 时间: ${timestamp}"
    else
        local msg="🔒 VPN 连接通知

❌ 设备已断开
📍 IP: ${ip}
🕐 时间: ${timestamp}"
    fi
    
    # 使用 OpenClaw CLI 发送消息
    openclaw message send --channel telegram --target YOUR_CHAT_ID --message "$msg" 2>/dev/null
}

# 监控 strongswan 日志
journalctl -u strongswan-starter -f --no-pager 2>/dev/null | while read -r line; do
    timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    # 新连接建立
    if echo "$line" | grep -q "IKE_SA.*established between"; then
        sa_id=$(echo "$line" | grep -oP 'IKE_SA[^[]+\[\K[0-9]+')
        remote_ip=$(echo "$line" | grep -oP '\.\.\.([0-9.]+)' | sed 's/\.\.\.//')
        
        if [ -n "$sa_id" ] && ! echo "$processed_connected" | grep -q ":$sa_id:"; then
            processed_connected="$processed_connected:$sa_id:"
            processed_disconnected=$(echo "$processed_disconnected" | sed "s/:$sa_id://g")
            send_notify "CONNECTED" "$remote_ip" "$timestamp"
        fi
    fi
    
    # 连接断开
    if echo "$line" | grep -q "deleting IKE_SA"; then
        sa_id=$(echo "$line" | grep -oP 'IKE_SA[^[]+\[\K[0-9]+')
        remote_ip=$(echo "$line" | grep -oP '\.\.\.([0-9.]+)' | sed 's/\.\.\.//')
        
        if [ -n "$sa_id" ] && ! echo "$processed_disconnected" | grep -q ":$sa_id:"; then
            processed_disconnected="$processed_disconnected:$sa_id:"
            send_notify "DISCONNECTED" "$remote_ip" "$timestamp"
        fi
    fi
done
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

# 4.2 Systemd 服务

创建 /etc/systemd/system/vpn-monitor.service:

[Unit]
Description=VPN Real-time Log Monitor
After=network.target strongswan-starter.service
Requires=strongswan-starter.service

[Service]
Type=simple
ExecStart=/home/moyin/vpn-monitor/vpn-monitor.sh
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
1
2
3
4
5
6
7
8
9
10
11
12
13

# 4.3 启用服务

chmod +x /home/moyin/vpn-monitor/vpn-monitor.sh
systemctl daemon-reload
systemctl enable vpn-monitor
systemctl start vpn-monitor
1
2
3
4

# 五、效果展示

连接 VPN 时收到通知:

🔒 VPN 连接通知

✅ 新设备已连接
📍 IP: 203.0.113.50 (文档示例 IP)
🕐 时间: 2026-06-06 22:25:30
1
2
3
4
5

断开 VPN 时收到通知:

🔒 VPN 连接通知

❌ 设备已断开
📍 IP: 203.0.113.50 (文档示例 IP)
🕐 时间: 2026-06-06 22:26:15
1
2
3
4
5

# 六、技术要点总结

问题 解决方案
轮询漏事件 改用实时日志监控(journalctl -f)
重复通知 SA ID 去重
Agent 超时 直接用 CLI 发送消息
服务自动启动 Systemd 服务管理

# 七、扩展思路

这个方案还可以扩展:

  1. 多渠道通知:除了 Telegram,还可以发送到企业微信、钉钉、邮件等
  2. 连接统计:记录连接时长、频率,生成使用报告
  3. 异常检测:比如短时间内频繁连接/断开,可能有问题
  4. IP 地理位置查询:通知中显示连接者的地理位置

# 八、参考链接

  • IKEv2 VPN 部署教程
  • OpenClaw 文档 (opens new window)
  • strongSwan Wiki (opens new window)
#VPN#strongSwan#监控#Telegram#OpenClaw
Windows开发环境配置指南
Claude Code Java 开发常用插件指南

← Windows开发环境配置指南 Claude Code Java 开发常用插件指南→

最近更新
01
Claude Code 接入 DeepSeek 教程(CC Switch)
06-05
02
Claude Code Java 开发常用插件指南
06-02
03
Windows开发环境配置指南
05-28
更多文章>
Theme by Vdoing | Copyright © 2022-2026 Felix
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式