Linux PAM登录告警

1️⃣ 创建脚本目录

bash 复制代码
sudo mkdir -p /opt/monitor

2️⃣ 创建并编辑通知脚本

bash 复制代码
sudo vim /opt/monitor/pam/pam_wechat_alert.sh

将以下内容完整复制 进编辑器,然后按 Ctrl+O 保存,Ctrl+X 退出。

bash 复制代码
#!/bin/bash

# 只在会话建立时触发
[ "$PAM_TYPE" = "open_session" ] || exit 0

# --- 配置区域 ---
WEBHOOK_URL="xxxx"
LOG_FILE="/opt/monitor/pam/notify.log"   # 日志文件路径
# --- 配置结束 ---

# 获取服务器基础信息
HOST=$(hostname)
DATE=$(date '+%Y-%m-%d %H:%M:%S')

# 获取服务器本机 IPv4 地址(提取第一个 IPv4 地址)
SERVER_IP=$(hostname -I | awk '{for(i=1;i<=NF;i++) if($i~/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/) print $i}' | head -1)
[ -z "$SERVER_IP" ] && SERVER_IP="未获取到"

# 获取 PAM 传递的登录信息
USER="$PAM_USER"
CLIENT_IP="${PAM_RHOST:-未知}"        # 客户端来源 IP
SERVICE="${PAM_SERVICE:-未知}"
TTY="${PAM_TTY:-未知}"

# 美化客户端 IP 显示
[[ "$CLIENT_IP" == "::1" || "$CLIENT_IP" == "127.0.0.1" ]] && CLIENT_IP="本地终端 (Local)"

# --- 组装通知内容(新增了"服务器IP"行) ---
CONTENT="🔔 **Linux 登录告警**
> 主机名:${HOST}
> 服务器IP:${SERVER_IP}
> 登录用户:${USER}
> 客户端IP:${CLIENT_IP}
> 服务类型:${SERVICE}
> 终端设备:${TTY}
> 登录时间:${DATE}"

# --- 发送通知并记录日志 ---
# 构建 JSON 请求体
if command -v jq &> /dev/null; then
    PAYLOAD=$(jq -n --arg msg "$CONTENT" '{msgtype: "markdown", markdown: {content: $msg}}')
else
    SAFE_CONTENT=$(echo "$CONTENT" | sed 's/"/\\"/g')
    PAYLOAD="{\"msgtype\": \"markdown\", \"markdown\": {\"content\": \"${SAFE_CONTENT}\"}}"
fi

# 执行 curl 并捕获状态
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
    -X POST -H "Content-Type: application/json" \
    --connect-timeout 3 --max-time 5 \
    -d "$PAYLOAD" "$WEBHOOK_URL" 2>/dev/null)

CURL_EXIT=$?

# 判断结果
if [ $CURL_EXIT -eq 0 ] && [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
    RESULT="成功 (HTTP $HTTP_CODE)"
else
    RESULT="失败 (curl退出码=$CURL_EXIT, HTTP $HTTP_CODE)"
fi

# 写入日志(追加)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 用户=$USER 客户端IP=$CLIENT_IP 服务=$SERVICE TTY=$TTY 结果=$RESULT" >> "$LOG_FILE"

exit 0

3️⃣ 赋予脚本执行权限

bash 复制代码
sudo chmod +x /opt/monitor/pam/pam_wechat_alert.sh

4️⃣ 配置 PAM 以调用脚本

编辑 SSH 服务的 PAM 配置文件:

bash 复制代码
cp /etc/pam.d/sshd /etc/pam.d/sshd.bak
sudo vim /etc/pam.d/sshd

在文件末尾 添加下面一行(注意路径是 /opt/monitor/pam/...):

plain 复制代码
session optional pam_exec.so /opt/monitor/pam/pam_wechat_alert.sh

保存退出(Ctrl+O,Ctrl+X)。

配置立即生效,无需重启 SSH 服务。

5️⃣ 测试与验证

5.1 新开一个 SSH 会话登录

⚠️ 重要:一定要保留当前已登录的会话窗口,以防配置错误导致无法再登录。

使用另一台机器或新的终端窗口,通过 SSH 登录到这台服务器。

5.2 检查企业微信群

登录成功后,企业微信群里对应的机器人应该会发送一条 Markdown 格式的告警消息。

5.3 查看本地日志文件
bash 复制代码
cat /opt/monitor/pam/login_notify.log

你应该会看到类似下面的记录:

plain 复制代码
[2026-08-26 15:30:22] 用户=root 来源IP=192.168.1.100 服务=sshd TTY=pts/0 结果=成功 (HTTP 200)

如果看到 失败 状态,请检查网络连通性和 Webhook 地址是否正确。

6️⃣(可选)日志轮转

如果担心日志文件过大,可以配置 logrotate:

bash 复制代码
sudo vim /etc/logrotate.d/pam_notify

内容:

plain 复制代码
/opt/monitor/pam/login_notify.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
}

保存后,系统会自动轮转日志。

✅ 全部完成!现在每次用户通过 SSH(或其他 PAM 认证的服务)登录时,都会触发脚本,发送企业微信通知并记录日志。

相关推荐
阳光九叶草LXGZXJ2 小时前
达梦数据库-报错-15-列【XXX】长度超出定义
linux·运维·数据库·sql·学习
奔跑的大白啊2 小时前
多容器共享目录权限踩坑记
linux·ubuntu·共享目录·linux权限·docker 容器化部署
黄大刀3 小时前
DataPulse一款开箱即用的SCADA(四)-历史记录
运维·scada·动环
归秋1425 小时前
2026 企业 AI 办公工具选型指南:从评估框架到产品适配
大数据·运维·人工智能
Android系统攻城狮5 小时前
Linux Gstreamer深度解析之gst_audio_encoder_set_frame_max调用流程与实战(六十一)
android·linux·运维·音视频·gstreamer音视频·音视频进阶·gstreamer音视频进阶
H.莓飛6 小时前
【C++】命名空间、缺省参数、函数重载与引用
linux·开发语言·c++·visual studio
91刘仁德6 小时前
IP协议详解:从IP协议头到网段划分、路由与NAT
linux·服务器·网络·网络协议·tcp/ip
硅基手札7 小时前
【Linux内核专栏 14】网络协议栈
linux·运维·网络协议
沫璃染墨8 小时前
《Linux工程实践篇(一):认识设计模式——从日志系统看策略模式》
linux·c++·安全·设计模式·策略模式
工作10年+,存储芯片行业9 小时前
Linux NVMe 中断排查与性能优化:CPU 亲和性
linux·运维·服务器·windows·性能优化·ssd·pcie