apache无法实现真正的sni级限流,因sni仅存在于tls握手阶段且模块无法访问未解密的sni字段;实际可行方案是基于host头配合mod_qos或mod_evasive实现子域名级限流。
apache 本身不支持基于 sni 的独立限流策略。sni(server name indication)仅在 tls 握手阶段起作用,用于让服务器选择对应域名的证书;而 apache 的请求处理流程中,sni 信息在 ssl 解密后即不可见,模块如 mod_evasive、mod_qos 或 mod_ratelimit 均无法直接读取或匹配原始 sni 字段做策略分流。
真正生效的是解密后的 Host 请求头(HTTP/1.1)或 :authority 伪头(HTTP/2),但这是应用层数据,不是 TLS 层的 SNI。因此所谓“SNI 级限流”,实际只能退而求其次:基于 Host 头做条件判断 + 第三方限流模块配合实现近似效果。
为什么不能真正在 SNI 阶段限流?
- SNI 发生在 TCP 连接建立后的 TLS ClientHello 中,此时 HTTP 请求尚未发送;
- Apache 模块运行在 HTTP 请求解析之后,无法访问未解密的 TLS 数据;
-
mod_ssl不暴露 SNI 值为环境变量或可匹配字段,%{SSL:SSL_SERVER_S_NAME}等变量仅在 SSL 环境下可用,但限流模块(如mod_evasive)不支持在其规则中引用 SSL 变量。
可行的替代方案:按 Host 头做子域名级限流
虽然不是“SNI 原生限流”,但在绝大多数生产场景中,用 Host 头模拟 SNI 分流是可靠且实用的做法。关键在于确保:
- 客户端真实发送了正确的
Host头(现代浏览器和 curl 默认都支持); - 服务器未被恶意构造 Host 头绕过(可通过
StrictHostCheck或反向代理前置校验增强); - 使用支持 Host 匹配的模块,如
mod_qos(推荐)或组合SetEnvIf + mod_evasive。
✅ 推荐方式一:用 mod_qos 实现 Host 精确限流(需手动编译)
LoadModule qos_module modules/mod_qos.so
<if>
QS_LocRequestLimit 20 60
QS_SrvRequestLimit 1000 60
</if><if>
QS_LocRequestLimit 5 60
</if>
说明:
-
QS_LocRequestLimit 20 60:对该 Host 下所有请求,每 60 秒最多 20 次; - 规则写在
<virtualhost></virtualhost>内或全局配置中均可,但必须启用mod_qos; - 注意:
mod_qos不支持 TLS 握手阶段,但能准确捕获解密后的 Host 头。
✅ 推荐方式二:用 SetEnvIf + mod_evasive 控制特定子域名接口
适用于只保护某类高危路径(如登录、提交):
Apache 2.4.62 官方 tar.gz 源码包是 Linux 及类 Unix 系统构建 Web 服务器的核心基础。通过源码编译安装,开发者能够灵活定制模块、优化性能并精准控制安装路径,满足多样化的业务需求。
SetEnvIf Host "^api\.example\.com$" evasive_api_host
SetEnvIf Host "^admin\.example\.com$" evasive_admin_host
<location>
SetEnvIf Host "^admin\.example\.com$" evasive_target
</location><ifmodule mod_evasive20.c>
DOSEnabled on
DOSPageCount 3
DOSPageInterval 10
DOSBlockingPeriod 600
<ifmodule mod_setenvif.c>
SetEnvIf evasive_target 1 DOS_ENABLED
</ifmodule></ifmodule>
说明:
- 只有
admin.example.com/login的 POST 请求会被mod_evasive统计; - 其他子域名或路径完全不受影响;
-
mod_evasive无 QPS 精确控制能力,适合防简单刷量,非硬性配额。
❌ 不推荐方式:试图用 LimitRequestRate 或 MaxConnectionsPerIP 绑定 Host
-
LimitRequestRate是连接级带宽限制,不识别 Host; -
MaxConnectionsPerIP只能在<virtualhost></virtualhost>内配置,但它是并发连接数限制,不是请求频次; - 二者均无法区分
a.example.com和b.example.com的同一 IP 请求。
更合理的架构建议
若业务对子域名限流要求严格(如 API 计费、多租户配额),不建议强依赖 Apache 做核心限流:
- Apache 应定位为静态资源服务或反向代理;
- 将限流逻辑下沉到专业网关:Nginx(
limit_req+$host)、APISIX(原生支持host路由+limit-count插件)、Envoy(基于virtual_host的 rate limit service); - 这些组件在 L7 层具备完整 Host/SNI/Path/Method 上下文,支持令牌桶、滑动窗口、Redis 分布式计数等企业级能力。
例如 APISIX 中可直接按 snis 或 hosts 配置不同限流规则:
{
"uri": "/api/*",
"hosts": ["api.example.com"],
"plugins": {
"limit-count": {
"count": 100,
"time_window": 60,
"key": "remote_addr"
}
}
}
不复杂但容易忽略:SNI 是 TLS 协议特性,限流是应用层行为——它们天然不在同一处理阶段。真正要落地多域名独立限流,得接受“用 Host 头代替 SNI”这个事实,并选对模块与架构层级。










