FreeBSD环境下SSH客户端断开后执行脚本的方案咨询
可行方案汇总
方案1:SSH ExitCommand 配置(针对指定用户)
FreeBSD的sshd支持ExitCommand指令,可在用户SSH会话终止后触发脚本执行,无需依赖PAM。
- 编辑
/etc/ssh/sshd_config,添加针对目标用户的匹配块:
其中Match User user1,user2 ExitCommand /usr/local/bin/post_ssh_cleanup.sh "%u"user1,user2是你需要监控的用户列表,%u会传递当前用户名给脚本。 - 确保脚本
/usr/local/bin/post_ssh_cleanup.sh拥有可执行权限,sshd执行ExitCommand时默认以root身份运行,脚本内可通过传入的用户名定位用户目录,执行SHA256哈希对比、邮件发送逻辑。 - 重启sshd生效:
service sshd restart
方案2:Cron定时检测会话终止
按你提到的思路,通过cron定期检查SSH会话结束记录,触发脚本:
- 编写检测脚本
/usr/local/bin/check_ssh_exit.sh,逻辑如下:#!/bin/sh TARGET_USERS="user1 user2" LAST_CHECK_FILE="/var/log/ssh_session_last_check" CURRENT_TIME=$(date +%s) # 初始化上次检查时间 if [ ! -f "$LAST_CHECK_FILE" ]; then echo "$CURRENT_TIME" > "$LAST_CHECK_FILE" exit 0 fi LAST_TIME=$(cat "$LAST_CHECK_FILE") # 遍历目标用户,检查最近结束的SSH会话 for USER in $TARGET_USERS; do # 用last命令筛选该用户的SSH会话,且排除未结束的会话 last -F -u "$USER" ssh | grep -v "still logged in" | while read LINE; do # 解析会话结束时间转为时间戳 EXIT_DATE=$(echo "$LINE" | awk '{print $4,$5,$6,$7}') EXIT_TIMESTAMP=$(date -j -f "%b %d %Y %H:%M" "$EXIT_DATE" +%s) if [ "$EXIT_TIMESTAMP" -gt "$LAST_TIME" ]; then # 触发哈希对比脚本 /usr/local/bin/sha256_check_and_mail.sh "$USER" fi done done # 更新上次检查时间 echo "$CURRENT_TIME" > "$LAST_CHECK_FILE" - 给脚本添加可执行权限:
chmod +x /usr/local/bin/check_ssh_exit.sh /usr/local/bin/sha256_check_and_mail.sh - 配置cron每15分钟运行一次:
执行crontab -e(root用户),添加:*/15 * * * * /usr/local/bin/check_ssh_exit.sh >> /var/log/ssh_exit_check.log 2>&1
方案3:用户Shell退出脚本(依赖用户配合)
针对配合的用户,修改其shell的退出配置文件,在用户退出Shell时触发脚本:
- 若用户使用Bash:编辑用户主目录下的
~/.bash_logout,添加:/usr/local/bin/sha256_check_and_mail.sh "$USER" - 若用户使用FreeBSD默认sh:编辑用户主目录下的
~/.logout,添加相同命令。 - 若用户使用Zsh:编辑
~/.zlogout。 - 确保脚本对普通用户有执行权限,脚本内仅处理用户自身目录的哈希对比逻辑即可,无需root权限。
注意事项
- 方案1需确保sshd配置正确,ExitCommand不会被用户环境干扰;
- 方案2需注意FreeBSD的
date命令参数与Linux不同,需用date -j -f指定时间格式解析; - 方案3依赖用户不修改自己的logout配置文件,适合用户完全配合的场景。
内容的提问来源于stack exchange,提问作者pepak
相关产品推荐
相关产品推荐

