6.1 安全加固:最小暴露与防攻击 本节摘要:Web 服务器是公网上被扫描最多的目标之一。本节交付一套分层的加固方案:系统层(用户、端口、进程隔离)、配置层(最小暴露——信息泄露治理、目录穿越封堵、请求方法收敛)、应用层(认证组合与访问控制套路),以及针对慢速攻击、目录遍历等真实攻击手段的服务器侧防御。每一条都附配置片段,可直接落成检查单。 学习目标 阅读完本节,你应当能够: 执行系统层加固:运行用户、端口收敛、文件权限模型; 治理信息泄露:版本号、索引页、错误页细节; 封堵目录穿越与点文件访问; 收敛不必要的 HTTP 方法与请求特征; 配置针对慢速攻击与暴力破解的防御。 系统层:先守住地基 Web 攻防的败笔常在 Web 之外。四条地基规则: 独立运行用户。
本节摘要:Web 服务器是公网上被扫描最多的目标之一。本节交付一套分层的加固方案:系统层(用户、端口、进程隔离)、配置层(最小暴露——信息泄露治理、目录穿越封堵、请求方法收敛)、应用层(认证组合与访问控制套路),以及针对慢速攻击、目录遍历等真实攻击手段的服务器侧防御。每一条都附配置片段,可直接落成检查单。
阅读完本节,你应当能够:
Web 攻防的败笔常在 Web 之外。四条地基规则:
独立运行用户。httpd 工作进程用自己的低权账号跑(发行版默认 www-data 或 apache),绝不给 root,也绝不复用其他服务的账号——第 2 章进程树里已经见过这个设计。要检查的是内容目录属主:文档根归 root 所有、运行用户只读,Web 内容就写不了;运行用户可写的目录(上传目录)单独划出。这条"读写分离"直接决定了后面上传漏洞的杀伤半径。
端口收敛。只监听业务端口,管理类端口只绑内网或干脆走本机套接字。Listen 指令写内网地址就是最朴素的访问控制。
文件权限。私钥文件 600 且属 root(父进程以 root 读钥后传给子进程内存,工作进程不需要碰磁盘上的私钥);配置目录禁止运行用户写;上传目录禁执行(配置段里去掉处理器并关闭 CGI)。
进程隔离。多站点共享一台机时,FPM 池按站点拆独立用户(第 4 章),配合目录属主把"一个站点沦陷"限制在自家院子里。
暴露的每一比特信息都是攻击者的侦察情报。信息泄露治理清单:
# 1 隐藏版本号:Server 头只报 Apache,ServerSignature 关掉页脚 ServerTokens Prod ServerSignature Off # 2 关目录索引:没有入口文件的目录返回 403 而不是文件清单 <Directory /var/www> Options -Indexes </Directory> # 3 错误页不泄细节:自定义错误文档,关掉多语言错误页的版本信息 ErrorDocument 404 /404.html ErrorDocument 403 /403.html # 4 封点文件与备份文件:.git 配置目录、.env 环境文件、编辑器备份 <FilesMatch "^\."> Require all denied </FilesMatch> <FilesMatch "~$|\.bak$|\.old$|\.ini$"> Require all denied </FilesMatch> # 5 封版本控制目录:目录穿越进 .git 能拖走整个仓库历史 <DirectoryMatch "/\.git"> Require all denied </DirectoryMatch>
第 4、5 条针对的是真实高频事故:部署时把 .git 目录或 .env(数据库密码)带上网页根目录,攻击者直接下载源码与凭据。服务器侧的默认拒绝是最后一道网——工程上当然该在构建流程里排除它们,但防线要有冗余。
方法收敛。WebDAV 相关方法(PROPFIND、TRACE 等)对 99% 的站点毫无用处,却是老漏洞利用脚本的常客:
# TRACE 反射是跨站追踪的老根基,直接禁 TraceEnable Off # 只放行业务需要的方法,其余拒绝 <Location /> <LimitExcept GET POST HEAD OPTIONS> Require all denied </LimitExcept> </Location>
头部治理(配合第 4 章的 mod_headers):安全响应头是纵深防御的一环,在生产基线里统一注入:
Header always set X-Content-Type-Options "nosniff" Header always set X-Frame-Options "SAMEORIGIN" Header always set Referrer-Policy "strict-origin-when-cross-origin" Header always set Content-Security-Policy "default-src 'self'"
每条头的防御对象不同:nosniff 防 MIME 嗅探利用,X-Frame-Options 防点击劫持,CSP 从源头约束脚本加载。CSP 上线前要在测试环境观察告警报告——约束过紧会砍断合法的第三方脚本。
慢速攻击。原理:攻击者用极慢的速度发请求头或请求体,把连接占满而不发完,工作线程全部"陪等",正常用户进不来。它专打连接处理模型的软肋,防御主力是 mod_reqtimeout 与连接限额:
# 请求头必须在 20-40 秒内到达完毕,请求体给 10 秒加速率下限 RequestReadTimeout header=20-40,minrate=500 body=10,minrate=500 # KeepAliveTimeout 别太长(第2章),闲连接快速回收
配套的 IP 级限频可以用第 4 章介绍过的思路:前置一层带限速能力的组件,或在应用层做令牌桶。
目录穿越与路径注入。URL 里带 ../ 企图逃出文档根。httpd 对规范化路径有防护,但重写规则自己拼路径时可能把漏洞写出来——凡是把请求参数拼进文件路径的重写,都要审视。服务器侧再封一刀:
<DirectoryMatch "\.\."> Require all denied </DirectoryMatch>
管理入口爆破。后台路径(典型如登录页)暴露在公网被脚本日夜爆破。两层防护:网络层限定来源,加一层 HTTP Basic 当外门:
<Location /admin> # 只允许公司出口IP Require ip 203.0.113.0/24 # 内部员工再过一道Basic认证 AuthType Basic AuthName "Admin" AuthUserFile /etc/httpd/.htadmin Require valid-user </Location>
Require ip 与 Require valid-user 并列书写是"满足任一"的语义,要"两者都要"得用指令嵌套显式表达——这是访问控制里最常见的语义误解,写错等于把后台对全网开放。
⚠️ 常见坑:测试加固效果时只用浏览器。加固配置的效果要用"攻击者视角"验证——curl 伪造方法、伪造头、直接请求点文件,逐一确认返回的都是 403/404,而不是"看起来页面正常"。

加固完成后做一次"演练":按攻击者视角逐项测(直接请求 .git/config、发 TRACE、慢速发头、对后台发爆破流量),每项确认被 403/超时/限频挡下,并记录在案。安全工作没有"完成"状态,只有"最近一次验证"状态——清单要随版本升级与新威胁定期重跑。
💡 一句话记住本节:加固的本质是做减法——权限减到最小、暴露减到最少、方法减到刚好够用。