每日自动化安全巡检脚本运行住宅Linux
住宅Linux服务器(比如用来跑个人网站、NAS或开发环境的机器)往往没有专职运维人员,但同样面临漏扫、暴力破解和系统漏洞风险。
通过编写一个轻量级安全巡检脚本并利用Linux内置的cron实现每日自动运行,你可以用不到10分钟完成配置,每天收到一份安全报告,及时发现异常登录、开放端口变化和待更新软件。
这份方案适合谁用
- 在家用旧PC或树莓派跑的Linux服务器(Ubuntu/Debian/CentOS均可)
- 想学自动化运维但又怕复杂的新手站长
- 需要满足基础安全合规(如等保、个人数据保护)的家庭服务器使用者
开始前你需要准备什么
- 一台已经装好系统的 Linux 机器(建议 Ubuntu 20.04 及以上),有 sudo 权限。
- 能通过 SSH 登录(或直接在图形界面打开终端)。
- 一个用来接收日报的邮箱(可选,脚本里可以配置邮件发送)。如果不想用邮件,也可以把报告写入日志文件,第二天手动查看。
第一步:编写安全巡检脚本
创建一个脚本文件,例如 /usr/local/bin/security_check.sh,内容如下:
#!/bin/bash
# 每日安全巡检脚本 - 住宅Linux版
REPORT_DIR="/var/log/security_reports"
DATE=$(date "+%Y-%m-%d")
REPORT_FILE="$REPORT_DIR/report_$DATE.txt"
mkdir -p $REPORT_DIR
echo "=== 安全巡检报告 $(date) ===" > $REPORT_FILE
# 1. 检查对外开放端口(排除SSH和常见服务)
echo "" >> $REPORT_FILE
echo "[端口状态]" >> $REPORT_FILE
ss -tlnp4 | awk '{print $4, $5}' | sort -u >> $REPORT_FILE
# 2. 检查失败登录尝试(过去24小时)
echo "" >> $REPORT_FILE
echo "[失败登录]" >> $REPORT_FILE
lastb --since "$(date -d 'yesterday' '+%Y-%m-%d')" | head -20 >> $REPORT_FILE
# 3. 检查系统更新(仅列出可更新包数量)
echo "" >> $REPORT_FILE
echo "[待更新软件]" >> $REPORT_FILE
if command -v apt &>/dev/null; then
apt list --upgradable 2>/dev/null | grep -v 'List|Done' | wc -l >> $REPORT_FILE
apt list --upgradable 2>/dev/null | head -10 >> $REPORT_FILE
elif command -v yum &>/dev/null; then
yum check-update -q | wc -l >> $REPORT_FILE
fi
# 4. 检查异常SUID文件(权限异常)
echo "" >> $REPORT_FILE
echo "[异常特权文件]" >> $REPORT_FILE
find /usr/bin /usr/sbin /bin /sbin -perm -4000 2>/dev/null | head -30 >> $REPORT_FILE
echo "巡检完成,报告已保存至 $REPORT_FILE"
保存后赋予执行权限:
sudo chmod +x /usr/local/bin/security_check.sh
然后手动执行一次看看是否报错:
sudo /usr/local/bin/security_check.sh
执行后检查 /var/log/security_reports/ 下是否生成了当日报告文件。
第二步:设置每日定时自动运行
使用 crontab 将脚本加入计划任务。
运行:
sudo crontab -e
如果第一次运行,系统会提示选择编辑器(选 nano 或 vim)。
在文件末尾添加一行:
0 6 * * * /usr/local/bin/security_check.sh
这表示每天早上6:00执行一次。
如果你希望同时将报告发送到邮箱,可以加入邮件命令(如 mail),但新手建议先手动查看日志文件,降低复杂度。
保存后,可通过以下命令查看定时任务是否生效:
sudo crontab -l
避坑指南(新手最容易踩的坑)
- 权限问题:
lastb需要root权限读取/var/log/btmp,所以脚本必须用sudo crontab添加,不要用普通用户。普通用户的crontab无法读取安全日志。 - 路径问题:脚本中所有命令都使用绝对路径或全称(如
ss、find),如果某些命令不在默认PATH中,建议在脚本开头加上export PATH="/usr/sbin:/usr/bin:/sbin:/bin"。 - 邮件配置:千万别在crontab里直接加
| mail命令但没装邮件服务器,会导致cron报错。若需邮件,先装mailutils或sendmail,并测试本地发信。 - 磁盘空间:如果报告积累太多,记得在脚本末尾添加保留策略,比如只保留最近7天的报告:
find $REPORT_DIR -name "*.txt" -mtime +7 -delete
如何验证脚本是否真正每日运行
第二天早上查看报告文件是否存在且内容更新:
ls -la /var/log/security_reports/
cat /var/log/security_reports/report_$(date "+%Y-%m-%d").txt
也可以手动检查cron日志:
sudo grep security_check /var/log/syslog
如果看到类似 (root) CMD (/usr/local/bin/security_check.sh) 的内容,说明定时任务已执行。
常见问题解答
Q1:我的系统是CentOS,上面的脚本能用吗?
大部分通用,但需要注意两个差异:
- 更新检查部分:
yum check-update返回结果格式不同,建议改成yum list updates -q 2>/dev/null | wc -l。 - 包管理器路径:CentOS默认没有
apt,脚本会自动判断用yum,所以无需手动修改。
Q2:脚本执行报错 lastb: /var/log/btmp: No such file or directory 怎么办?
说明系统没有启用登录失败记录。执行 sudo touch /var/log/btmp 创建文件,然后重启 rsyslog 服务(sudo systemctl restart rsyslog),下次登录失败就会写入日志。
Q3:报告文件太大怎么办?
可以在脚本末尾增加清理逻辑,只保留最近7天的文件(代码见避坑部分),或者只保留最近10条异常记录,用 head -10 限制输出行数。
Q4:我不想每天检查报告,能不能让脚本在发现异常时发警报?
可以扩展脚本:当检测到失败登录超过阈值(例如5次)时,通过 curl 调用企业微信或钉钉机器人webhook发送通知。具体代码可参考后续教程《Linux安全告警:无邮箱也能秒收通知》。
总结与延伸
至此你已经在住宅Linux上搭建了每日自动化安全巡检脚本,每天凌晨自动运行并生成报告。
建议先照做一遍,确认脚本无报错后再加入cron。
如果后续需要更全面(比如文件完整性检查、防火墙规则校验),可以在此基础上逐步扩展。
遇到异常时优先回看报告文件确认时间是否更新,并检查cron服务是否正常运行。
如果你正在准备将多台住宅Linux统一管理,或需要更专业的异常告警功能,欢迎继续阅读本站《Linux安全监控进阶:Prometheus+Grafana》系列教程。