路虽弥,不行不至;事虽小,不做不成
摘要
本文介绍如何在 Linux 服务器(以 CentOS 7.9 为例)上实现 SSH 命令审计,通过 Bash 脚本记录用户执行的命令到指定日志文件,并使用 logrotate 实现按天轮转。工具适用于运维人员和系统管理员,能够监控用户操作、便于审计和问题排查。日志文件权限设置为 666,以支持多用户写入,适合测试或受控环境。配置简单,代码可一键复制。
前置条件
- 系统:CentOS 7.9 或其他支持 Bash 和 logrotate 的 Linux 系统
- 权限:root 用户或具有 sudo 权限
- 环境:已启用 SSH 服务,具备 Bash 环境
- 工具:确保 logrotate 已安装(默认包含在 CentOS 中)
一、创建日志文件并设置权限
创建用于存储 SSH 命令的日志文件,并设置权限为 666,允许所有用户写入。
# 创建日志文件
sudo touch /var/log/ssh_command.log
# 设置权限为 666,确保所有用户可写入
sudo chmod 666 /var/log/ssh_command.log
# 设置文件归属为 root:root
sudo chown root:root /var/log/ssh_command.log
安全提示:权限 666 允许任意用户读写日志文件,适合测试或受控环境。在生产环境中,建议将日志文件放入受限目录(如 /var/log/audit/,目录权限为 750),或使用 660 权限并将用户加入特定组(如 adm)。
二、创建命令记录脚本
在 /etc/profile.d/ 下创建脚本,捕获并记录 SSH 命令。
# 创建脚本
cat <<EOF > /etc/profile.d/command_log.sh
#!/bin/bash
log_command() {
# 跳过空命令或无关命令(如 PS1、PS2 等)
if [[ -z "\\$BASH_COMMAND" || "\\$BASH_COMMAND" =~ ^(printf\\\\ \\"\\\\033|PS1=|PS2=|PS4=|trap\\\\ ) ]]; then
return 0
fi
# 仅在交互式 shell 中记录
if [[ "\\$-" != *i* ]]; then
return 0
fi
# 获取客户端 IP 和端口,处理 SSH_CLIENT 未定义的情况
if [[ -n "\\$SSH_CLIENT" ]]; then
client_ip=\\$(echo "\\$SSH_CLIENT" | awk '{print \\$1}' || echo "UNKNOWN")
client_port=\\$(echo "\\$SSH_CLIENT" | awk '{print \\$2}' || echo "-")
else
client_ip="LOCAL"
client_port="-"
fi
# 记录命令到日志文件
log_file="/var/log/ssh_command.log"
echo "[ \\$(date '+%F %T') \\$client_ip \\$client_port \\$(whoami) ] \\$BASH_COMMAND" >> "\\$log_file"
}
# 设置 DEBUG 陷阱捕获命令
trap log_command DEBUG
EOF
# 设置脚本执行权限
chmod +x /etc/profile.d/command_log.sh
日志格式说明:
日志文件 /var/log/ssh_command.log 的记录格式如下:
[ 2025-05-21 15:45:05 192.168.10.1 61275 root ] ps aux
- 包含时间戳、客户端 IP、端口、用户名和执行的命令。
注意:
- 脚本通过 /etc/profile.d/ 加载,适用于所有 Bash 用户。新登录的会话会自动应用脚本。
- 已添加空命令检查和 SSH_CLIENT ప
三、配置日志轮转
使用 logrotate 实现日志文件的按天轮转,防止文件过大。
# 创建轮转配置文件
cat <<EOF > /etc/logrotate.d/ssh_command
/var/log/ssh_command.log {
daily
rotate 7
compress
missingok
notifempty
copytruncate
dateext
dateformat -%Y%m%d
create 0666 root root
maxsize 100M
}
EOF
# 检查配置文件语法
logrotate -d /etc/logrotate.d/ssh_command
配置说明:
- daily:按天轮转。
- rotate 7:保留 7 天的日志。
- compress:压缩旧日志文件。
- missingok:忽略日志文件缺失的错误。
- notifempty:不轮转空文件。
- copytruncate:复制并截断日志文件,避免中断写入。
- dateext 和 dateformat:轮转文件以日期命名(如 ssh_command.log-20250521)。
- create 0666 root root:轮转后创建新文件,权限为 666。
- maxsize 100M:单日日志超过 100MB 时触发轮转。
测试轮转:
# 调试轮转(不会实际执行)
logrotate -d /etc/logrotate.d/ssh_command
# 强制执行轮转
logrotate -f /etc/logrotate.d/ssh_command
四、验证与排查
4.1 验证日志记录
执行任意命令(如 ls),然后检查日志文件:
cat /var/log/ssh_command.log
确认是否记录了类似以下内容:
[ 2025-05-21 15:45:05 192.168.10.1 61275 root ] ls
4.2 常见问题排查
-
日志未记录
:
- 检查 /etc/profile.d/command_log.sh 是否有执行权限(chmod +x)。
- 确认是否以 Bash 登录(echo $SHELL 应为 /bin/bash)。
- 新会话未加载脚本,可执行 source /etc/profile.d/command_log.sh。
-
轮转失败
:
- 检查 /etc/logrotate.d/ssh_command 语法:logrotate -d /etc/logrotate.d/ssh_command。
- 确保 logrotate 服务正常运行(通常由 cron 定时执行)。
-
权限错误
:
- 确认 /var/log/ssh_command.log 权限为 666,归属为 root:root。
- 若非 root 用户无法写入,检查是否误将权限设为 644 或 600。
五、总结
通过以上步骤,你已成功在 Linux 服务器上实现 SSH 命令审计和日志轮转功能。该工具轻量高效,适合企业级服务器的运维审计场景。后续可扩展功能,如将日志推送到远程服务器。
欢迎在评论区分享你的使用经验或问题,我们一起探讨!
声明:本人原创,欢迎转载,请注明出处。
评论前必须登录!
注册