不能靠限制并发解析空间规避正则CPU锁死,因其本质是单次灾难性回溯导致单线程卡死;需从正则引擎行为、调用上下文和频率三方面干预,如禁用高危正则、改用map预编译、锚定匹配、启用超时熔断等。
不能靠“限制并发解析空间”来规避恶意正则导致的 CPU 锁死——因为 Apache 和 Nginx 本身没有“单个虚拟主机并发解析空间”这个配置维度。真正需要干预的是正则引擎行为本身,以及它被调用的上下文和频率。
当一个正则表达式含嵌套量词(如 (a+)+)、可选字符与边界模糊组合(如 ^([a-z]+[-.'s]?)+$),且匹配长输入时,引擎会指数级尝试所有可能路径,最终卡死在单线程里。这不是并发太多,而是单次匹配就耗尽 CPU 时间片。
regexec、Pattern$Curly.match0 等底层匹配函数RewriteCond、LocationMatch;Nginx 中:if ($host ~ ...)、location ~*、map 块Apache 不提供 per-VirtualHost 的正则执行时限或栈深度限制,但可通过以下方式切断风险链路:
RewriteCond 中的复杂正则,改用精确字符串判断或 mod_alias 的 Redirect / Alias
SetEnvIf 预判并设环境变量,VirtualHost 内只做简单 Require env 判断<Directory> 或 <Location> 中的 AllowOverride All,防止 .htaccess 注入恶意 RewriteRuleLimitInternalRecursion 10(仅 VirtualHost 内有效)——它不防正则锁死,但能快速暴露重写循环,避免因误配导致无限递归叠加正则开销Nginx 提供了更明确的运行时约束,可直接压制正则滥用:
if 块中的正则:全部改用 map 提前映射,且 map 必须定义在 http 块顶层,避免每次请求重复编译map 设置 default 值,杜绝 fallback 到慢路径;对无法预知的域名,统一指向空响应或 444location ~ .php$ 改为 location = /index.php + try_files $uri =404,消除匹配扫描开销server_names_hash_bucket_size 和 server_names_hash_max_size 优化 Host 匹配性能,减少因大量域名触发的线性查找放大正则压力无论 Apache 还是 Nginx,真正起效的不是“限并发”,而是“减触发、降复杂、早熔断”:
RewriteRule;Nginx 中避免 if ($arg_x ~ ...),改用 map $arg_x $flag { ... }
return 400
Timeout 10(Apache)、client_header_timeout 10s(Nginx),让卡死请求尽早释放连接rewrite_time(Apache mod_status)或 nginx_http_request_time(Prometheus),设置阈值告警