
简介这份文档面向中小学、幼儿园、职校及其他教育单位的信息安全负责人与网络管理员围绕教育系统网络与信息安全巡检的实际工作展开帮助读者理清巡检流程、检查要点与整改方向。内容涵盖巡检计划安排、重要设备日志备份、数据备份方式核查、应用服务器安全检测、终端安全抽查、运营商出口排查以及网络与安全硬件设备弱口令检查等模块并延伸至杀毒软件部署与堡垒机权限分配等附加安全措施涉及《网络安全法》日志留存要求、远程登录与高危端口管控、Webshell与勒索软件等入侵风险识别。资源包共1个docx文件约15KB以文字说明与检查条目为主结构清晰便于按模块对照执行。目前已有542人学习下载适合需要落实校园网络安全巡检、编制检查清单或开展自查整改的运维与安全管理人员参考使用。1. 网络与信息安全巡检到底在巡什么从一份文档标题说起很多人第一次看到「网络与信息安全巡检工作内容」这种文档标题第一反应是——这不就是运维例行公事吗登录几台机器看看 CPU、内存、磁盘截几张图填个表格交差。如果你也这么想那说明你还没被真正的安全检查拷打过。我见过太多团队平时巡检报告写得漂漂亮亮一出事翻日志发现三个月前的异常登录没人管数据库备份文件损坏了半年没人验应用服务器的中间件版本还停留在有公开漏洞的老版本上。网络与信息安全巡检的核心不是「看一眼」而是「留证据、能追溯、可验证」。它覆盖的范围比普通运维巡检大得多网络层要看边界设备策略、端口暴露面、流量异常主机层要看账号权限、补丁版本、进程服务应用层要看 Web 中间件配置、接口鉴权、错误日志数据层要看备份完整性、恢复可用性、存储加密。这四个层面缺一个巡检就是漏的。这份文档标题里的「(2)」暗示它大概率是一份系列文档的第二版说明巡检内容本身在迭代。我写这篇东西就是想把这四个层面拆成能直接抄的检查项、能跑起来的脚本、能填进表格的参数让新手照着做不漏项让老手看到边界和坑在哪。适合谁看安全运维、系统管理员、等保合规负责人以及被临时抓来写巡检报告但不知道从哪下手的工程师。2. 巡检清单怎么定四个层面拆成可执行检查项2.1 网络层巡检边界设备与暴露面网络层巡检最容易走过场因为很多人觉得「防火墙策略没改过就不用查」。但现实是业务上线时临时开的端口没人回收测试环境的策略同步到了生产这些才是真正的风险点。我一般按三个维度来查设备存活与配置基线、端口暴露面、流量异常。设备存活不是简单 ping 一下。核心交换机和防火墙要看 CPU、内存、会话数、接口错包率。配置基线要对比当前运行配置和上一次备份的差异任何非变更窗口内的改动都值得追问。端口暴露面用扫描工具定期跑重点看公网 IP 上开了哪些端口和资产台账是否一致。# 网络层巡检批量检查设备存活与关键指标 # 适用于 Cisco IOS / 华为 VRP 等支持 SSH 的设备 # 依赖sshpass或配置免密nmap # 1. 设备存活与基础指标采集 for ip in $(cat device_list.txt); do echo $ip sshpass -p $PASS ssh -o StrictHostKeyCheckingno admin$ip \ show processes cpu | include CPU; show memory | include Free; show interface | include error \ net_health_$(date %Y%m%d).log 21 done # 2. 公网暴露面扫描只扫常见高危端口避免全端口扫描触发告警 nmap -sT -p 22,23,80,443,3389,8080,3306,6379,27017 \ -iL public_ip_list.txt -oG port_scan_$(date %Y%m%d).txt这段脚本的逻辑很直接第一段循环登录每台设备抓 CPU、内存、接口错误计数输出到按日期命名的日志文件。第二段用 nmap 扫公网 IP 列表里的高危端口输出成 grep 可解析的格式。参数上注意两点-sT用 TCP 全连接扫描而不是 SYN 半开虽然慢但不会被部分 IPS 直接丢弃端口列表只列了九个最常见的高危端口实际使用时根据资产台账补充但别上来就-p 1-65535生产环境这么扫大概率触发告警甚至被封 IP。设备清单和 IP 列表怎么维护我习惯用 CSV 或 YAML字段包括 IP、设备类型、所属机房、负责人、上次变更时间。这样巡检脚本读同一个源报告里也能自动关联责任人。2.2 主机与应用层巡检账号、补丁、中间件主机层巡检的核心是「谁能在上面做什么」。账号方面重点查三类多余账号离职员工、测试账号未删、权限过大账号普通用户有 sudo 全权限、密码策略是否强制复杂度、是否定期更换。补丁方面不是看「有没有装补丁」而是看「关键补丁有没有装」——内核提权漏洞、OpenSSH 远程执行、sudo 绕过这些是高优先级。应用层巡检围绕中间件展开。Tomcat、Nginx、Apache、WebLogic 这些要查版本号、管理后台是否暴露、错误页面是否泄露堆栈信息、日志里有没有异常请求模式。我见过一个案例Tomcat 的管理后台用默认口令巡检时没人注意后来被上传了 webshell。所以应用层巡检必须包含「管理接口鉴权检查」这一项。# 主机与应用层巡检Linux 账号、补丁、中间件版本采集 # 输出为 Excel 表格方便直接贴进巡检报告 import subprocess import re import pandas as pd from datetime import datetime def check_accounts(): 检查 UID0 的账号、空密码账号、最近登录记录 results [] # 查 UID 为 0 的账号除了 root 都值得关注 with open(/etc/passwd, r) as f: for line in f: parts line.strip().split(:) if parts[2] 0 and parts[0] ! root: results.append({类型: UID为0账号, 详情: parts[0]}) # 查空密码账号 out subprocess.run([awk, -F:, ($2){print $1}, /etc/shadow], capture_outputTrue, textTrue) for user in out.stdout.strip().split(\n): if user: results.append({类型: 空密码账号, 详情: user}) return results def check_patches(): 检查关键补丁包版本 critical [kernel, openssh, sudo, glibc] results [] for pkg in critical: out subprocess.run([rpm, -q, pkg], capture_outputTrue, textTrue) results.append({类型: 补丁版本, 详情: out.stdout.strip()}) return results def check_middleware(): 检查常见中间件版本与配置 results [] # Tomcat 版本 out subprocess.run([find, /opt, -name, RELEASE-NOTES, -path, *tomcat*], capture_outputTrue, textTrue) for path in out.stdout.strip().split(\n): if path: with open(path, r) as f: version f.readline().strip() results.append({类型: Tomcat版本, 详情: version}) # Nginx 版本 out subprocess.run([nginx, -v], capture_outputTrue, textTrue) results.append({类型: Nginx版本, 详情: out.stderr.strip()}) return results # 汇总输出 all_results check_accounts() check_patches() check_middleware() df pd.DataFrame(all_results) df[巡检时间] datetime.now().strftime(%Y-%m-%d %H:%M:%S) df.to_excel(fhost_inspection_{datetime.now().strftime(%Y%m%d)}.xlsx, indexFalse) print(f巡检完成共 {len(df)} 条记录)这段 Python 脚本做了三件事账号检查、补丁版本采集、中间件版本采集最后汇总成 Excel。逻辑上注意check_accounts里读/etc/shadow需要 root 权限实际跑的时候要么用 sudo要么把脚本放在有权限的定时任务里。check_patches用的是 rpm 系命令如果是 Debian 系要换成dpkg -l。check_middleware里 Tomcat 版本从 RELEASE-NOTES 文件读Nginx 用-v参数输出到 stderr这些细节不处理的话采集会漏。参数方面critical列表里的包名根据实际系统调整比如 CentOS 7 和 Rocky Linux 9 的包名可能有差异。输出 Excel 用 pandas 的to_excel需要装openpyxl。如果巡检机器不能装 pandas可以改成 CSV 输出用标准库csv模块。2.3 数据层巡检备份不是「跑了就行」数据备份是巡检里最容易被糊弄的环节。很多人看到备份脚本昨天跑了、日志没报错就认为备份没问题。但备份文件能不能恢复、恢复出来数据完不完整这才是关键。我一般要求巡检必须包含三项备份任务执行状态、备份文件完整性校验、恢复演练记录。备份任务执行状态看 cron 或调度平台的日志重点看有没有「部分成功」的情况——比如数据库备份成功但 binlog 备份失败。备份文件完整性校验用 md5 或 sha256 对比有条件的话用mysqlcheck或pg_restore --list验证备份文件可读。恢复演练不用每次都做但巡检报告里要记录上次演练时间和结果。# 数据层巡检MySQL 备份完整性校验与恢复验证 # 假设备份目录为 /backup/mysql备份文件格式为 dbname_YYYYMMDD.sql.gz BACKUP_DIR/backup/mysql TODAY$(date %Y%m%d) REPORT/var/log/db_backup_check_${TODAY}.log echo 备份文件清单 $REPORT ls -lh $BACKUP_DIR/*_${TODAY}.sql.gz $REPORT 21 echo MD5 校验 $REPORT for f in $BACKUP_DIR/*_${TODAY}.sql.gz; do md5sum $f $REPORT done echo 恢复验证解压后检查 SQL 头部 $REPORT for f in $BACKUP_DIR/*_${TODAY}.sql.gz; do echo --- $f --- $REPORT zcat $f | head -20 $REPORT # 检查是否包含 CREATE TABLE 语句确认不是空备份 table_count$(zcat $f | grep -c CREATE TABLE) echo CREATE TABLE 语句数量: $table_count $REPORT done echo 备份任务日志检查 $REPORT grep -i error\|fail /var/log/mysql_backup.log | tail -20 $REPORT这段脚本的逻辑是先列出当天备份文件然后算 MD5再解压看 SQL 头部和 CREATE TABLE 数量最后检查备份任务日志里的错误。参数上BACKUP_DIR和日志路径根据实际环境改。grep -c CREATE TABLE这个检查很实用——如果备份文件是空的或者只有表结构没有数据CREATE TABLE 数量会异常。但注意这个数字要和上次巡检对比突然变少说明备份可能不完整。提示备份文件校验不要只算 MD5还要实际解压看内容。我踩过坑文件 MD5 正常但解压出来是空的因为备份脚本在 mysqldump 执行前就创建了 gzip 文件。3. 巡检脚本怎么落地从手动执行到定时任务3.1 脚本组织与参数化上面几段脚本如果散落在不同目录、硬编码路径和 IP维护起来会很痛苦。我一般把巡检脚本组织成一个目录配置文件单独放脚本读配置执行。这样换环境只需要改配置文件不用动代码。inspection/ ├── conf/ │ ├── devices.yaml # 网络设备清单 │ ├── hosts.yaml # 主机清单 │ └── backup.yaml # 备份路径与数据库连接信息 ├── scripts/ │ ├── net_check.sh # 网络层巡检 │ ├── host_check.py # 主机与应用层巡检 │ └── backup_check.sh # 数据层巡检 ├── output/ # 巡检结果输出目录 └── run_all.sh # 统一入口配置文件用 YAML 的好处是可读性好Python 和 Shell 都能解析。run_all.sh负责按顺序调用三个脚本最后把输出汇总到一个带日期的目录里。#!/bin/bash # run_all.sh - 巡检统一入口 # 用法./run_all.sh [日期默认今天] DATE${1:-$(date %Y%m%d)} BASE_DIR$(cd $(dirname $0) pwd) OUTPUT_DIR$BASE_DIR/output/$DATE mkdir -p $OUTPUT_DIR echo [$(date)] 开始网络层巡检... bash $BASE_DIR/scripts/net_check.sh $OUTPUT_DIR/net_check.log 21 echo [$(date)] 开始主机与应用层巡检... python3 $BASE_DIR/scripts/host_check.py $OUTPUT_DIR/host_check.log 21 echo [$(date)] 开始数据层巡检... bash $BASE_DIR/scripts/backup_check.sh $OUTPUT_DIR/backup_check.log 21 echo [$(date)] 巡检完成结果在 $OUTPUT_DIR这个入口脚本的关键点是DATE变量支持传入参数方便补跑历史巡检。OUTPUT_DIR按日期分目录避免文件覆盖。每个子脚本的输出重定向到独立日志排查问题时不会混在一起。3.2 定时任务与告警接入巡检脚本写完下一步是让它自动跑。cron 是最简单的方案但要注意几个坑环境变量和交互式 shell 不一样脚本里用的命令要写全路径cron 的邮件告警在很多环境里没配置跑了失败也没人知道。# crontab 配置示例 # 每天凌晨 2 点执行巡检输出追加到日志 0 2 * * * /opt/inspection/run_all.sh /var/log/inspection_cron.log 21 # 每周一凌晨 3 点做一次完整备份恢复验证 0 3 * * 1 /opt/inspection/scripts/backup_restore_test.sh /var/log/restore_test.log 21告警接入我一般用两种方式如果团队有 Prometheus Alertmanager巡检脚本输出成 metrics 格式用 pushgateway 推上去如果没有就在脚本最后判断关键指标异常时调用 webhook 发消息到内部沟通工具。# 巡检结果告警检查关键指标异常时发送 webhook import requests import json def send_alert(webhook_url, message): 发送告警到内部沟通工具 payload { msgtype: text, text: {content: message} } requests.post(webhook_url, jsonpayload, timeout5) def check_and_alert(df, webhook_url): 检查巡检结果中的异常项 alerts [] # 检查空密码账号 empty_pwd df[df[类型] 空密码账号] if not empty_pwd.empty: alerts.append(f发现空密码账号: {, .join(empty_pwd[详情].tolist())}) # 检查 UID 为 0 的非 root 账号 uid0 df[df[类型] UID为0账号] if not uid0.empty: alerts.append(f发现 UID 为 0 的异常账号: {, .join(uid0[详情].tolist())}) # 检查备份文件大小异常小于 1MB 视为可疑 # 这里需要结合备份检查的输出示例略 if alerts: send_alert(webhook_url, 安全巡检告警:\n \n.join(alerts)) return True return False这段代码的逻辑是从巡检结果 DataFrame 里筛选异常项拼成告警消息发送。参数上webhook_url根据团队用的工具填timeout5避免网络问题导致脚本卡住。注意告警要设置阈值和频率限制不然每天发同样的告警会被忽略。4. 巡检避坑那些年我翻过的车4.1 备份文件正常但恢复失败现象巡检报告显示备份任务每天成功执行文件大小正常MD5 校验通过。但真正需要恢复时发现备份文件里缺少某几张关键表的数据。原因备份脚本用了--ignore-table参数排除了大表但排除列表是半年前定的后来业务新增的表也被误排除了。或者 mysqldump 执行时数据库正在做 DDL 操作备份出来的表结构不一致。解决巡检必须包含「备份文件内容检查」不只是看文件大小和 MD5。用zcat backup.sql.gz | grep -c CREATE TABLE对比表数量和数据库实际表数量比对。有条件的话每月做一次恢复到测试库的演练用mysqlcheck验证数据完整性。4.2 巡检脚本在 cron 里跑失败但手动执行正常现象手动执行./run_all.sh一切正常放到 cron 里就报「command not found」或者输出为空。原因cron 的环境变量PATH和交互式 shell 不同脚本里用的python3、nmap、sshpass可能不在 cron 的 PATH 里。另外 cron 的工作目录是用户 home 目录脚本里的相对路径会找不到文件。解决脚本里所有命令写全路径或者在 crontab 开头设置PATH/usr/local/bin:/usr/bin:/bin。脚本内部用$(cd $(dirname $0) pwd)获取脚本所在目录所有路径基于这个目录拼接。cron 任务里重定向输出到日志文件方便排查。4.3 端口扫描触发 IPS 告警现象巡检脚本跑完安全团队找过来说「你们在扫什么IPS 告警刷屏了」。原因nmap 默认的 SYN 扫描和全端口扫描在生产环境很容易被 IPS 识别为扫描行为。即使只扫几个端口如果频率太高也会触发。解决扫描前和安全团队报备用-sT全连接扫描代替-sS加-T2降低扫描速度端口列表尽量精简。更好的做法是维护资产台账只扫描台账里登记的 IP 和端口不做全网段扫描。4.4 巡检报告数据对不上现象巡检报告里主机数量是 50 台但资产台账里是 55 台差的 5 台不知道是漏了还是下线了。原因巡检脚本的主机清单和资产台账是两份独立维护的数据时间一长就不同步。新上线的机器没加进巡检清单下线的机器没从清单里删。解决巡检清单从 CMDB 或资产管理系统自动生成不要手工维护。如果做不到自动同步至少每月做一次清单核对把差异项列出来人工确认。巡检报告里要包含「清单差异」这一项。4.5 日志备份占满磁盘现象巡检脚本每天把日志备份到本地一个月后磁盘满了导致数据库写入失败。原因日志备份没有清理策略只增不减。或者备份文件压缩率不够文本日志压缩后还是很大。解决日志备份设置保留周期比如保留最近 30 天用find /backup/logs -mtime 30 -delete定期清理。备份前先压缩用tar -czf或gzip。巡检脚本里加一项「备份目录磁盘使用率检查」超过 80% 就告警。5. 让巡检报告能说话从数据采集到可视化呈现巡检脚本跑完输出一堆日志和 Excel如果只是存档价值有限。我习惯把巡检结果做成一个简单的看板让非技术同事也能看懂「哪里有问题、严重程度、建议动作」。不需要复杂的 BI 工具用 Python 的jinja2生成 HTML 报告就够了。# 生成 HTML 巡检报告 from jinja2 import Template import pandas as pd from datetime import datetime # 读取巡检结果 df pd.read_excel(fhost_inspection_{datetime.now().strftime(%Y%m%d)}.xlsx) # 统计异常项 total len(df) abnormal df[df[类型].isin([空密码账号, UID为0账号])] abnormal_count len(abnormal) # HTML 模板 template Template( !DOCTYPE html html head meta charsetutf-8 title安全巡检报告 {{ date }}/title style body { font-family: sans-serif; margin: 40px; } .summary { background: #f5f5f5; padding: 20px; border-radius: 8px; } .abnormal { color: #d32f2f; font-weight: bold; } table { border-collapse: collapse; width: 100%; margin-top: 20px; } th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } th { background: #333; color: #fff; } /style /head body h1网络与信息安全巡检报告/h1 div classsummary p巡检时间{{ date }}/p p检查项总数{{ total }}/p p异常项数量span classabnormal{{ abnormal_count }}/span/p /div h2异常明细/h2 table trth类型/thth详情/thth建议动作/th/tr {% for _, row in abnormal.iterrows() %} tr td{{ row[类型] }}/td td{{ row[详情] }}/td td{{ 立即删除或锁定账号 if 账号 in row[类型] else 评估后更新 }}/td /tr {% endfor %} /table /body /html ) html template.render( datedatetime.now().strftime(%Y-%m-%d %H:%M), totaltotal, abnormal_countabnormal_count, abnormalabnormal ) with open(finspection_report_{datetime.now().strftime(%Y%m%d)}.html, w) as f: f.write(html)这段代码的逻辑是读巡检 Excel筛选异常项用 Jinja2 模板渲染 HTML。模板里包含了汇总信息和异常明细表格异常项用红色标注。参数上abnormal的筛选条件根据实际巡检项调整建议动作可以做成映射表不同异常类型对应不同建议。生成 HTML 报告的好处是可以直接发给领导或贴在内部 wiki 上比 Excel 直观。如果团队有 Grafana可以把巡检结果推到时序数据库做趋势图——比如「空密码账号数量」按周变化一眼看出整改有没有效果。最后一句话是我自己的习惯巡检报告不要只写「发现问题」要写「上次发现的问题这次还在不在」。如果同一个问题连续三次巡检都出现那就不是技术问题是流程问题。希望帮到你。本文还有配套的精品资源点击获取