当前位置: 首页 > news >正文

SSH 登录/退出实时监控脚本

ssh-monitor.sh

#!/bin/bashSCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
# 配置文件路径
CONFIG_FILE="${SCRIPT_DIR}/ssh-login-sessions.conf"
# 日志文件路径
LOG_FILE="/var/log/ssh-monitor.log"# ==================== 微信推送配置 ====================
WXPUSHER_APP_TOKEN="xxxxxx"
WXPUSHER_UID="xxxxxx"# 确保配置文件和日志文件存在
touch "$CONFIG_FILE" "$LOG_FILE"# 微信推送函数
send_wx_message() {local summary="$1"local content="$2"curl -s -H 'Content-Type: application/json' \-XPOST https://wxpusher.zjiecode.com/api/send/message \-d "{\"appToken\":\"${WXPUSHER_APP_TOKEN}\",\"content\":\"$content\",\"summary\":\"$summary\",\"contentType\":3,\"uids\":[\"${WXPUSHER_UID}\"]
}" > /dev/null 2>&1
}# 获取sessionid的函数
get_sessionid() {local pid=$1if [ -f "/proc/$pid/sessionid" ]; thencat "/proc/$pid/sessionid" 2>/dev/null || echo "unknown"elseecho "unknown"fi
}# 解析登录信息的函数
parse_login_info() {local json_line="$1"local pid=$(echo "$json_line" | jq -r '._PID')local message=$(echo "$json_line" | jq -r '.MESSAGE')# 从MESSAGE中提取用户名和IPif [[ "$message" == Accepted* ]]; then# Accepted publickey for root from 192.168.100.53 port 11105 ssh2: ...local username=$(echo "$message" | grep -oP 'for \K[^ ]+')local ip=$(echo "$message" | grep -oP 'from \K[^ ]+')# 提取登录方式 (publickey / password / keyboard-interactive 等)local auth_method=$(echo "$message" | grep -oP 'Accepted \K[^ ]+')# 获取当前时间local login_time=$(date '+%Y-%m-%d %H:%M:%S')# 获取sessionidlocal sessionid=$(get_sessionid "$pid")# 返回JSON格式的登录信息echo "{\"pid\":\"$pid\",\"username\":\"$username\",\"ip\":\"$ip\",\"login_time\":\"$login_time\",\"sessionid\":\"$sessionid\",\"auth_method\":\"$auth_method\"}"fi
}# 解析退出信息的函数
parse_logout_info() {local json_line="$1"local pid=$(echo "$json_line" | jq -r '._PID')local message=$(echo "$json_line" | jq -r '.MESSAGE')if [[ "$message" == "Disconnected from user"* ]]; then# Disconnected from user root 192.168.100.53 port 11105local username=$(echo "$message" | grep -oP 'user \K[^ ]+')local ip=$(echo "$message" | grep -oP '\K[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')echo "{\"pid\":\"$pid\",\"username\":\"$username\",\"ip\":\"$ip\"}"fi
}# 记录登录事件
handle_login() {local login_info="$1"local pid=$(echo "$login_info" | jq -r '.pid')local username=$(echo "$login_info" | jq -r '.username')local ip=$(echo "$login_info" | jq -r '.ip')local login_time=$(echo "$login_info" | jq -r '.login_time')local sessionid=$(echo "$login_info" | jq -r '.sessionid')local auth_method=$(echo "$login_info" | jq -r '.auth_method')echo "login_info: $login_info"# 写入配置文件echo "$pid|$login_info" >> "$CONFIG_FILE"# 写入日志文件echo "[LOGIN ] $login_time - User: $username, IP: $ip, PID: $pid, SessionID: $sessionid, AuthMethod: $auth_method" >> "$LOG_FILE"# 发送微信通知local summary="✅ SSH登录通知 - $ip"local content=""content+="| 字段 | 信息 |\n"content+="|------|------|\n"content+="| 用户名 | **$username** |\n"content+="| IP地址 | \`$ip\` |\n"content+="| 登录时间 | $login_time |\n"content+="| PID | \`$pid\` |\n"content+="| SessionID | \`$sessionid\` |\n"content+="| 认证方式 | \`$auth_method\` |\n"send_wx_message "$summary" "$content"echo "✅ 登录事件已记录 - PID: $pid, User: $username"
}# 处理退出事件
handle_logout() {local logout_info="$1"local pid=$(echo "$logout_info" | jq -r '.pid')local username=$(echo "$logout_info" | jq -r '.username')local ip=$(echo "$logout_info" | jq -r '.ip')# 从配置文件中查找对应的登录记录local login_line=$(grep "^$pid|" "$CONFIG_FILE" | tail -1)if [ -n "$login_line" ]; then# 提取登录信息local login_info=$(echo "$login_line" | cut -d'|' -f2-)local login_time=$(echo "$login_info" | jq -r '.login_time')local sessionid=$(echo "$login_info" | jq -r '.sessionid')# 计算连接时间local logout_time=$(date '+%Y-%m-%d %H:%M:%S')local login_epoch=$(date -d "$login_time" +%s)local logout_epoch=$(date -d "$logout_time" +%s)local duration=$((logout_epoch - login_epoch))local duration_str=""if [ $duration -ge 3600 ]; thenduration_str="$((duration/3600))小时$(((duration%3600)/60))分钟"elif [ $duration -ge 60 ]; thenduration_str="$((duration/60))分钟$((duration%60))秒"elseduration_str="${duration}秒"fi# 写入日志文件echo "[LOGOUT] $logout_time - User: $username, IP: $ip, PID: $pid, Login: $login_time, Duration: $duration_str" >> "$LOG_FILE"# 从配置文件中删除该记录sed -i "/^$pid|/d" "$CONFIG_FILE"# 发送微信通知local summary="❌ SSH退出通知 - $ip"local content=""content+="| 字段 | 信息 |\n"content+="|------|------|\n"content+="| 用户名 | **$username** |\n"content+="| IP地址 | \`$ip\` |\n"content+="| 登录时间 | $login_time |\n"content+="| 退出时间 | $logout_time |\n"content+="| 连接时长 | **$duration_str** |\n"content+="| PID | \`$pid\` |\n"content+="| SessionID | \`$sessionid\` |\n"send_wx_message "$summary" "$content"echo "❌ 退出事件已记录 - PID: $pid, User: $username, Duration: $duration_str"else# 如果没有找到登录记录,只记录退出信息echo "[LOGOUT] $(date '+%Y-%m-%d %H:%M:%S') - User: $username, IP: $ip, PID: $pid (no login record found)" >> "$LOG_FILE"echo "❌ 退出事件 - PID: $pid (未找到登录记录)"fi
}# 主循环
echo "开始监控SSH登录/退出事件..."
echo "配置文件: $CONFIG_FILE"
echo "日志文件: $LOG_FILE"journalctl _COMM=sshd -n 0 -f -o json | while read -r line; domessage=$(echo "$line" | jq -r '.MESSAGE')# 处理登录事件if [[ "$message" == Accepted* ]]; thenlogin_info=$(parse_login_info "$line")if [ -n "$login_info" ]; thenhandle_login "$login_info"fi# 处理退出事件elif [[ "$message" == "Disconnected from user"* ]]; thenlogout_info=$(parse_logout_info "$line")if [ -n "$logout_info" ]; thenhandle_logout "$logout_info"fifi
done

 

这是一个 SSH 登录/退出实时监控脚本,主要功能如下:

核心功能

表格
 
功能说明
实时监控 通过 journalctl 实时监听 sshd 服务的日志事件
登录检测 捕获 SSH 成功登录事件(Accepted 关键字)
退出检测 捕获 SSH 断开连接事件(Disconnected from user
会话追踪 通过 PID 和 SessionID 匹配登录和退出事件,计算连接时长
微信推送 使用 WxPusher 服务发送登录/退出通知到微信
日志记录 将事件记录到 /var/log/ssh-monitor.log

工作流程

  1. 登录时:提取用户名、IP、PID、SessionID → 写入配置文件 → 发送微信通知
  2. 退出时:通过 PID 查找对应登录记录 → 计算连接时长 → 发送微信通知(含时长统计)→ 清理配置记录

关键文件

  • ssh-login-sessions.conf - 存储活跃会话信息(PID 与登录详情映射)
  • /var/log/ssh-monitor.log - 持久化日志记录

使用场景

适合需要 实时掌握服务器 SSH 访问情况 的场景,如:
  • 云服务器安全监控
  • 运维审计追踪
  • 异常登录告警
http://www.jsqmd.com/news/443547/

相关文章:

  • 揭秘无人机通信链路两大攻击手段:姿态欺骗与电量伪造
  • 2026年投融资纠纷律师价格大揭秘,北京哪家收费合理? - 工业品网
  • 2026成都等地最新别墅装修品牌推荐:全场景覆盖,这家环保家装实力领跑 - 十大品牌榜
  • 2026成都等地最新房屋装修公司推荐:全场景适配,这家实力领跑 - 十大品牌榜
  • 长芯微LPA4112完全P2P替代ADA4522,是一款高精度双通道放大器,采用了自稳零和斩波技术
  • 2026年广州有机硅消泡剂厂家年度排名,哪家性价比高 - 工业品牌热点
  • 像素级清晰:2026战区地形三维成像无人机蜂群系统供应商洞察 - 品牌2026
  • 娱乐办公两不误,【虚拟屏】远程办公的隐私保护神器
  • 2026年牛饲料生产厂哪家技术强,为你揭秘靠谱品牌 - myqiye
  • 2026最新苏州婚纱摄影综合实力TOP10榜单正式发布 - charlieruizvin
  • 深度解析:如何在供应链黑盒中构建嵌入式系统的安全防线
  • ffplayer面试总结
  • 2026年变压器/箱式变电站/配电柜/电抗器/光伏一体机厂家推荐:陕西变压器全品类实力详解 - 深度智识库
  • 二次元影像测量仪什么牌子好
  • 2026年 太空舱厂家推荐排行榜:二手/民宿/景区/露营/酒店/户外/装配式/可移动/一体式/移动/预制/智能太空舱全方位解析 - 品牌企业推荐师(官方)
  • 帝国cms.5版的编辑器默认会清除多余的word代码,如果要保留word格式怎么修改?EmpireCMS
  • 盘点2026年上海口碑好的减震器冲击试验机生产厂家,解决选购难题 - 工业推荐榜
  • 光学动作捕捉技术:机器人科研领域的数据基石与NOKOV度量动捕的应用实践
  • 国内靠谱的https证书供应商有哪些?2026年https证书申请/https证书购买渠道推荐 - 麦麦唛
  • 阿里内部“SpringCloudAlibaba全彩版学习笔记”正式开源
  • 金三银四最全Java面试题:数据结构+算法+JVM+线程+finalize+GC
  • 用C++学解析几何_C++精灵库应用_萍乡风火轮少儿编程基地
  • 2026内外螺纹磨床厂家对比:从技术实力到售后服务的综合评估 - 品牌推荐大师
  • 时间的比较函数
  • 2026 年想转行网络安全?一篇带你了解真实的网安职场!
  • 帝国cms为什么用SQL调用不能加“checked=1”条件?EmpireCMS
  • 安徽GEO优化公司哪家强?这份高性价比榜单请收好 - 麦麦唛
  • 高效学挖漏洞!全网最全挖洞平台 + 零基础到精通实战指南
  • 基于杨中科老师的GC示例,写一个Benchmark
  • 公开课 | 软件测试行业的发展与思考