简介
本指南面向在 DouPHP 中部署“防火墙防护”的运维与开发人员,聚焦以下目标:
- IP 白名单与黑名单:如何在反向代理/负载均衡层管理单个 IP 与 CIDR 范围。
- 访问频率限制(限流):基于路由的定向限流,防止暴力破解与滥用。
- WAF 集成:SQL 注入、XSS 等攻击的检测与防护策略。
- 负载均衡环境注意事项:可信代理、Host 校验与日志一致性。
- 监控与日志:如何采集、分析与告警。
- 常见攻击防护策略与应急响应流程。
说明:DouPHP 内置了安全响应头、CSRF 保护、定向限流与日志能力;IP 白/黑名单与 WAF 规则通常由前置的反向代理或云 WAF 提供,应用侧通过可信代理与 Host 白名单配合使用。
项目结构
与安全相关的关键位置如下:
- 安全配置:config/security.php(可信代理、可信 Host、安全响应头、限流存储路径、会话 Cookie 硬化)。
- 中间件:
- 限流:API/前台/后台均提供 ThrottleMiddleware,继承抽象基类实现按路由配额限流。
- 安全头:三端薄壳子类统一行为,下发 X-Frame-Options、Referrer-Policy、Permissions-Policy、HSTS 等。
- CSRF:前后端分别实现,自动校验表单令牌,防重放。
- 限流存储:core/infra/security/ThrottleStore(文件后端,JSON 计数,窗口过期清理)。
- 日志:core/infra/log/Log(分级、采样、敏感信息脱敏、自动上下文)。
- 预约黑名单:admin 模块提供预约场景的黑名单数据模型与服务(用于业务层面的封禁/限制)。
graph TB
A["请求进入"] --> B["安全响应头中间件<br/>AbstractSecurityHeadersMiddleware"]
A --> C["CSRF 中间件<br/>Admin/Front CsrfMiddleware"]
A --> D["定向限流中间件<br/>ThrottleMiddleware"]
D --> E["限流存储<br/>ThrottleStore(文件)"]
B --> F["业务控制器/服务"]
C --> F
D --> F
F --> G["日志记录<br/>Log"]
核心组件
- 安全配置(config/security.php)
- trusted_proxies:可信反向代理名单(支持精确 IP 与 CIDR),启用后 Request::ip() 才会采信转发头。
- trusted_hosts:可信 Host 白名单,防止 Host 头污染对外 URL。
- headers:基线安全响应头(X-Frame-Options、X-Content-Type-Options、Referrer-Policy、Permissions-Policy、HSTS)。
- throttle.store:限流计数文件目录。
- session:Cookie 硬化(HttpOnly、Secure、SameSite、Strict Mode)。
- 限流中间件(AbstractThrottleMiddleware + 各端 ThrottleMiddleware)
- 仅对显式配额的敏感路由进行限流,未配额直接放行。
- 默认限流键为 module.action.ip,需置于可信代理之后以保证 IP 可信。
- 超限返回 429(API 端)或终止处理(前端/后台)。
- 安全响应头中间件(AbstractSecurityHeadersMiddleware)
- 根据配置下发安全头;HSTS 仅在 HTTPS 且开启时下发。
- CSRF 中间件(Admin/Front)
- 自动校验表单令牌,匿名敏感路由使用一次性令牌,降低重放风险。
- 限流存储(ThrottleStore)
- 文件后端 JSON 计数,窗口到期自动重置,支持机会式清理过期文件。
- 日志(Log)
- 分级、采样、每分钟同 key 限流、敏感字段脱敏、自动附加请求上下文(IP、路由、方法等)。
架构总览
下图展示请求从进入 Web 服务器到应用层的防护链路:前置 WAF/反代负责 IP 白/黑名单与 WAF 规则;应用层通过可信代理与 Host 白名单确保 IP/Host 可信;中间件层提供 CSRF、安全头、定向限流;日志记录全链路上下文。
sequenceDiagram
participant Client as "客户端"
participant Proxy as "反向代理/WAF"
participant App as "DouPHP 应用"
participant MW1 as "安全头中间件"
participant MW2 as "CSRF 中间件"
participant MW3 as "限流中间件"
participant Store as "限流存储"
participant Log as "日志"
Client->>Proxy : HTTP 请求
Proxy-->>Client : 拦截/放行WAF/黑白名单
Proxy->>App : 透传请求含可信代理头
App->>MW1 : 下发安全响应头
App->>MW2 : 校验 CSRF 令牌
App->>MW3 : 检查是否命中限流路由
MW3->>Store : tooMany/hit
Store-->>MW3 : 计数结果
MW3-->>App : 放行或拒绝429/终止
App->>Log : 记录请求上下文
App-->>Client : 响应
详细组件分析
限流组件(ThrottleMiddleware + AbstractThrottleMiddleware + ThrottleStore)
- 工作原理
- 中间件读取当前路由的 module/action/sub,结合 IP 生成限流键。
- 若该路由在 $limits 表中有配额,则调用 ThrottleStore 判断是否超限。
- 超限:API 端返回 429 并设置 Retry-After;其他端终止处理。
- 未超限:写入一次计数,继续后续处理。
- 关键要点
- 必须将限流中间件置于可信代理之后,否则 IP 可能不可信。
- 可通过路由参数覆盖 routeLimit(max/window)。
- 限流存储为文件 JSON,适合单机或小规模集群;大规模可替换为 Redis。
- 典型路由配额(示例)
- 登录/注册/找回密码/短信验证码/公共写接口/聊天流等均有独立配额。
flowchart TD
Start(["进入限流中间件"]) --> ReadRoute["解析 module/action/sub"]
ReadRoute --> HasLimit{"是否命中配额?"}
HasLimit -- 否 --> Next["放行至下一中间件"]
HasLimit -- 是 --> CheckTooMany["查询 ThrottleStore::tooMany(key,max,window)"]
CheckTooMany -- 已超限 --> Reject["拒绝: 429/终止"]
CheckTooMany -- 未超限 --> Hit["ThrottleStore::hit(key,window)"]
Hit --> Next
Reject --> End(["结束"])
Next --> End
安全响应头中间件(AbstractSecurityHeadersMiddleware)
- 功能
- 根据 config/security.php 的 security.headers 下发安全头:X-Content-Type-Options、X-Frame-Options、Referrer-Policy、Permissions-Policy。
- HSTS 仅在 HTTPS 且 enabled 时下发,可配置 max_age 与 includeSubDomains。
- 建议
- 生产环境务必开启 content_type_options 与 frame_options。
- 仅在全站 HTTPS 且稳定后开启 HSTS。
CSRF 中间件(Admin/Front)
- 功能
- 后台:登录后共享静态令牌 static_admin,部分匿名流程使用一次性令牌。
- 前台:会员共享静态令牌 static_user;匿名敏感路由使用一次性令牌。
- 外部回调(如支付通知)通过路由级声明豁免,避免误拦截。
- 建议
- 所有写操作表单必须渲染并提交 CSRF 令牌。
- 第三方回调接口保持豁免,避免破坏业务流程。
日志系统(Log)
- 功能
- 分级日志(emergency/alert/critical/error/warning/notice/info/debug)。
- 自动上下文:request_id、scene、ip、route、method、module、action、user/admin/work id。
- 敏感字段脱敏:URL 查询串中的敏感参数会被掩码。
- 采样与每分钟同 key 限流:控制高频日志量。
- 建议
- 生产环境关闭 debug,设置合适的 minLevel。
- 合理配置采样率与每分钟上限,避免磁盘打满。
- 将日志输出到集中式日志平台以便检索与告警。
预约黑名单(业务层面)
- 功能
- 后台提供预约黑名单的数据模型与服务,支持列表、新增、删除等操作。
- 可用于特定业务场景(如预约资源)的封禁与限制。
- 建议
- 与网络层黑白名单互补:网络层阻断恶意 IP,业务层针对账号/资源维度做细粒度限制。
依赖关系分析
- 限流中间件依赖:
- Config(读取 throttle.store 路径)。
- ThrottleStore(文件计数与窗口管理)。
- Request(获取 module/action/sub/ip)。
- 安全头中间件依赖:
- Config(读取 security.headers)。
- Request(判断是否 HTTPS)。
- CSRF 中间件依赖:
- Session(令牌存储/校验)。
- 路由元信息(判定豁免与令牌类型)。
- 日志依赖:
- Session(探测用户身份)。
- Request(提取路由与方法)。
- 文件系统(写入日志)。
classDiagram
class AbstractThrottleMiddleware {
+handle(next)
+throttleFor(module, action, sub) array|null
+reject(retryAfter) void
+resolveKey(module, action, sub, ip) string
+store() ThrottleStore
+candidates(module, action, sub) array
}
class ThrottleStore {
+hit(key, window) int
+tooMany(key, max, window) bool
+availableIn(key) int
+clear(key) void
+purgeExpired() void
}
class AbstractSecurityHeadersMiddleware {
+handle(next) mixed
}
class CsrfMiddleware_Admin
class CsrfMiddleware_Front
class Log {
+write(level, message, context) void
+setMinLevel(level) void
+setSampleRate(rate) void
+setMaxPerMinutePerKey(max) void
}
AbstractThrottleMiddleware --> ThrottleStore : "使用"
CsrfMiddleware_Admin <|-- AbstractSecurityHeadersMiddleware : "无直接依赖"
CsrfMiddleware_Front <|-- AbstractSecurityHeadersMiddleware : "无直接依赖"
Log --> Request : "读取上下文"
Log --> Session : "读取身份"
性能与限流考量
- 限流存储
- 文件后端适合单机或小集群;高并发场景建议替换为 Redis 以减轻 I/O 压力。
- 定期执行 purgeExpired 清理过期文件,避免磁盘膨胀。
- 日志
- 合理设置最小级别与采样率,避免高频日志影响性能。
- 对同一 key 的日志启用每分钟上限,抑制风暴。
- 安全头
- 安全头开销极低,建议始终开启。
- 可信代理与 Host
- 正确配置 trusted_proxies 与 trusted_hosts,避免错误信任导致 IP/Host 被伪造。
故障排查指南
- 限流误拦截
- 检查 trusted_proxies 是否正确配置,确保 Request::ip() 取到真实客户端 IP。
- 查看对应路由是否在 $limits 表中,确认 max/window 是否过严。
- 检查 ThrottleStore 目录是否存在且可写,文件权限是否正确。
- 安全头未生效
- 确认 security.headers 配置项是否启用,HSTS 仅在 HTTPS 且 enabled 时下发。
- 检查中间件管道顺序,确保安全头中间件在响应前执行。
- CSRF 校验失败
- 确认表单已渲染并提交 CSRF 令牌。
- 第三方回调接口是否被豁免,避免误拦截。
- 日志缺失或过多
- 检查 Log::setMinLevel、setSampleRate、setMaxPerMinutePerKey 配置。
- 确认 storage/log 目录存在且可写。
- 关注敏感字段是否被脱敏,必要时调整敏感键匹配规则。
结论
- 应用层防护:通过安全头、CSRF、定向限流与日志,构建基础的安全与稳定性保障。
- 网络层防护:在反向代理/WAF 层实施 IP 白/黑名单与 WAF 规则,与应用层形成纵深防御。
- 负载均衡:正确配置可信代理与 Host 白名单,确保 IP/Host 可信与日志一致。
- 持续优化:根据监控与日志反馈,动态调整限流阈值与 WAF 规则,完善应急响应流程。
附录:配置清单与最佳实践
-
IP 白名单与黑名单(建议在反向代理/WAF 层配置)
- 白名单:允许内部网段、CDN 出口、合作伙伴 IP/CIDR 访问管理端或 API。
- 黑名单:封禁已知恶意 IP、扫描器、僵尸网络段。
- 注意:在负载均衡环境下,务必配置 trusted_proxies,使应用能正确识别真实 IP。
-
访问频率限制(限流)
- 敏感路由:登录、注册、找回密码、短信验证码、公共写接口(留言/咨询/邮件订阅)等。
- 配额建议:短窗口低配额(如 60 秒 5 次),长窗口更严格(如 300 秒 5 次)。
- 存储:单机可用文件后端;多机/高并发建议使用 Redis 替代 ThrottleStore。
-
WAF 集成(SQL 注入、XSS 等)
- 在反向代理/WAF 层启用 OWASP 规则集,拦截常见攻击载荷。
- 应用层配合:安全头(X-Content-Type-Options、X-Frame-Options)、CSRF、输入输出编码与校验。
- 日志:记录被拦截的请求上下文,便于溯源与规则调优。
-
负载均衡注意事项
- 配置 trusted_proxies 为可信代理出口 IP/CIDR。
- 配置 trusted_hosts 为站点域名与子域通配,防止 Host 头注入。
- 确保各节点限流与日志一致,避免单点误判。
-
监控与日志分析
- 关注 429 次数、登录失败次数、异常 URI、敏感参数命中情况。
- 使用集中式日志平台建立告警:如短时间内大量 429、错误级别日志突增。
- 定期清理过期限流文件与历史日志,避免磁盘占满。
-
常见攻击防护策略
- 暴力破解:限流 + 验证码 + 账户锁定策略。
- DDoS:WAF 层速率限制、连接数限制、IP 信誉库。
- SQL 注入/XSS:WAF 规则 + 参数化查询 + 输出编码。
- CSRF:全站启用 CSRF 校验,第三方回调豁免。
-
应急响应流程
- 发现异常:监控告警 → 快速定位(日志/限流统计)。
- 临时处置:WAF 封禁 IP/CIDR、收紧限流阈值、关闭高风险入口。
- 根因分析:复盘攻击路径、调整规则与代码。
- 恢复验证:逐步放开限制,观察指标回归正常。