安全加固从来不是“执行完脚本就结束”的工作。很多团队按照清单禁用了 root 远程登录、配置了防火墙、关闭了危险端口,却在几个月后因为一次配置漂移或一个遗漏的服务而重新暴露在风险中。本文从 Web 安全实践出发,结合 XSS 防御、SQL 注入防护与 Linux 加固要点,整理一份可落地的加固后验证与复查清单,帮助你把“一次性加固”变成“持续可控的安全状态”。
一、为什么加固后必须验证
加固操作本身可能带来三种问题:
- 配置未生效:修改了
sshd_config却没有重载服务,或防火墙规则被其他规则覆盖。 - 加固过度:关闭了业务依赖的端口或权限,导致服务异常,运维人员随后“临时放开”却忘记收回。
- 配置漂移:新上线的应用、新安装的软件包、自动化脚本重新打开了旧配置。
因此,验证的核心不是“我改了什么”,而是“系统当前实际状态是什么”。以下清单按“系统层 → 服务层 → 应用层”的顺序展开。
二、系统层验证清单
1. 账户与认证
- 确认 root 是否禁止 SSH 登录:
sshd -T | grep permitrootlogin,期望值为no。 - 检查是否存在空密码账户:
awk -F: '($2==""){print $1}' /etc/shadow。 - 确认仅允许密钥认证:
sshd -T | grep -E 'passwordauthentication|pubkeyauthentication'。 - 复查 sudo 权限:
grep -r 'NOPASSWD' /etc/sudoers /etc/sudoers.d/,确认没有过度授权。
2. 网络与防火墙
- 查看实际监听端口:
ss -tulnp,与业务白名单逐一比对。 - 确认防火墙规则已持久化:
iptables -L -n或firewall-cmd --list-all,并检查开机自启状态。 - 验证默认策略为 DROP:
iptables -L | head -5。
3. 文件权限与完整性
- 检查关键目录权限:
ls -ld /etc /root /home,确保无 world-writable 目录。 - 查找异常 SUID 文件:
find / -perm -4000 -type f 2>/dev/null,与基线对比。 - 确认日志服务正常:
systemctl status rsyslog或journalctl,避免“加固后没人知道被攻击”。
三、服务层验证清单
1. SSH 与远程管理
- 使用
ssh -v从外部实际尝试 root 登录,确认被拒绝。 - 检查是否限制了来源 IP:
sshd -T | grep allowusers或防火墙规则。 - 确认登录失败锁定策略生效:
faillock --user root或查看/var/log/auth.log。
2. Web 服务与中间件
- 确认版本信息未泄露:
curl -I http://target,检查Server头是否被隐藏。 - 复查目录遍历与敏感文件:尝试访问
/.git/config、/backup.zip、/phpinfo.php。 - 验证 TLS 配置:使用
testssl.sh或 SSL Labs,确认无弱协议与弱加密套件。
3. 数据库服务
- 确认数据库不对外监听:
ss -tulnp | grep 3306,期望仅绑定127.0.0.1。 - 检查账户权限最小化:
SHOW GRANTS FOR 'app'@'localhost';,避免ALL PRIVILEGES。 - 确认已关闭
LOAD DATA LOCAL INFILE等高风险功能。
四、应用层验证:XSS 与 SQL 注入的复查
系统加固解决不了应用层漏洞。加固后必须对 Web 应用做一次针对性复查。
1. XSS 的常见方式与前端防御验证
XSS 常见形式包括:
- 反射型:恶意脚本通过 URL 参数回显到页面。
- 存储型:脚本被存入数据库,在评论区、昵称等位置持久触发。
- DOM 型:前端 JavaScript 直接使用
location.hash、innerHTML等危险操作。
前端防御复查要点:
- 确认所有用户输入在输出时经过转义,优先使用框架默认转义(如 React 的 JSX、Vue 的插值)。
- 禁止直接使用
innerHTML、document.write、eval,如必须使用,需配合 DOMPurify 等库净化。 - 设置 CSP 响应头:
Content-Security-Policy: default-src 'self',并验证是否生效。 - 对富文本场景,复查白名单过滤是否覆盖
onerror、javascript:等向量。
验证方法:在输入框和 URL 参数中注入 <script>alert(1)</script> 与 <img src=x onerror=alert(1)>,观察是否被转义或拦截。
2. MySQL 防止 SQL 注入的几种写法
SQL 注入的根源是“用户输入被当作 SQL 代码执行”。防御复查应确认代码中采用以下写法:
- 预处理语句(首选):PHP 中使用 PDO 或 mysqli 的
prepare+bind_param;Java 使用PreparedStatement。 - 参数化查询:
SELECT * FROM users WHERE id = ?,而不是字符串拼接。 - ORM 框架:如 MyBatis 使用
#{}而非${},Django ORM、Hibernate 等默认参数化。 - 输入校验与类型转换:对 ID 等字段强制
intval(),但校验不能替代参数化。 - 最小权限账户:应用账户只授予必要表的
SELECT/INSERT/UPDATE,禁用DROP、FILE。 - 错误信息隐藏:生产环境关闭详细 SQL 报错,避免泄露表结构。
验证方法:在参数中提交 ' OR '1'='1、1' AND SLEEP(5)--,观察是否被拦截、是否出现延迟或报错。
五、建立复查节奏
一次验证只能证明“此刻安全”。建议:
- 每周:自动扫描监听端口、SUID 文件、账户变更。
- 每月:复查防火墙规则、数据库权限、Web 目录敏感文件。
- 每次上线后:对新接口做 XSS 与 SQL 注入回归测试。
- 每季度:完整走一遍本清单,并更新基线。
结语
Linux 服务器安全加固的价值,不在于执行了多少条命令,而在于加固后的状态是否可验证、可复查、可持续。把系统层的账户与网络、服务层的 SSH 与数据库、应用层的 XSS 与 SQL 注入防护统一纳入清单,用“实际状态”而非“操作记录”作为验收标准,才能真正降低被攻击的概率。安全不是一次性的项目,而是一条需要反复确认的基线。
未经允许不得转载:任鹏个人博客 » Linux 服务器安全加固后的验证与复查清单


朋友圈点赞图在线生成源码