ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SpringBoot嵌入式Tomcat防护Slow HTTP DOS攻击实战

SpringBoot嵌入式Tomcat防护Slow HTTP DOS攻击实战 1. SpringBoot嵌入式Tomcat应对Slow HTTP DOS攻击实战指南在基于SpringBoot的Web应用开发中嵌入式Tomcat因其开箱即用的特性成为默认选择。但最近在安全审计时发现我们的订单处理系统在压力测试下出现了Slow HTTP DOS攻击漏洞——攻击者仅用10个慢速连接就导致服务线程池耗尽。本文将分享一套从参数调优到防护策略的完整解决方案这些配置已经在我们日均百万级请求的生产环境稳定运行两年。2. 漏洞原理与危害分析2.1 Slow HTTP DOS攻击机制这种攻击利用HTTP协议特性保持长时间连接占用线程资源。典型攻击模式包括Slowloris攻击缓慢发送不完整的HTTP头每10-60秒发送一个header字段Slow POST攻击声明大的Content-Length后缓慢发送body数据Slow Read攻击以极低速度读取服务器响应// 模拟Slow POST攻击的恶意客户端代码片段 HttpURLConnection conn (HttpURLConnection)url.openConnection(); conn.setRequestMethod(POST); conn.setDoOutput(true); conn.setRequestProperty(Content-Length, 1048576); // 声明1MB数据 OutputStream os conn.getOutputStream(); while(true) { os.write(1); // 每秒发送1字节 Thread.sleep(1000); }2.2 嵌入式Tomcat的默认风险SpringBoot内嵌Tomcat的默认配置对这类攻击几乎无防护connectionTimeout20000ms20秒maxThreads200无突发限制maxConnections10000过高未启用keepAlive超时控制3. 多维度防护方案实施3.1 基础连接参数加固在application.yml中配置核心防护参数server: tomcat: connection-timeout: 5000ms # 连接建立超时 max-threads: 200 # 根据CPU核心数调整(建议N*22) max-connections: 500 # 并发连接上限 keep-alive-timeout: 15000ms # 长连接超时 max-keep-alive-requests: 100 # 单个连接最大请求数 min-spare-threads: 10 # 最小备用线程关键点connection-timeout应小于keep-alive-timeout避免慢连接占用线程3.2 请求粒度防护策略通过自定义TomcatConnectorCustomizer实现细粒度控制Bean public TomcatConnectorCustomizer slowHttpProtection() { return connector - { connector.setProperty(maxHttpHeaderSize, 8192); // 限制头大小 connector.setProperty(connectionUploadTimeout, 5000); connector.setProperty(disableUploadTimeout, false); connector.setProperty(maxSwallowSize, 2097152); // 2MB最大吞食量 }; }3.3 基于Filter的增强防护实现请求速率过滤拦截器public class RateLimitFilter implements Filter { private final RateLimiter limiter RateLimiter.create(100); // 100请求/秒 Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException { if (!limiter.tryAcquire()) { ((HttpServletResponse)response).sendError(429); return; } chain.doFilter(request, response); } }注册到Spring Security配置中Configuration EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { Override protected void configure(HttpSecurity http) throws Exception { http.addFilterBefore(new RateLimitFilter(), BasicAuthenticationFilter.class); } }4. 生产环境调优经验4.1 线程池动态调整策略通过Actuator端点实现运行时调参Endpoint(id threadpool) Component public class ThreadPoolEndpoint { Autowired private TomcatWebServer server; WriteOperation public String adjustThreads(Selector int max) { ThreadPoolExecutor executor (ThreadPoolExecutor) server.getTomcat().getConnector().getProtocolHandler().getExecutor(); executor.setMaximumPoolSize(max); return Adjusted to max; } }调用方式POST /actuator/threadpool/3004.2 连接数监控看板使用MicrometerPrometheus监控关键指标Bean public MeterRegistryCustomizerMeterRegistry metrics() { return registry - { new TomcatMetrics(server.getTomcat(), embedded.tomcat).bindTo(registry); }; }推荐监控阈值活跃线程 maxThreads*0.8 告警连接持续时间 30s 告警错误率 1% 告警5. 防御效果验证方案5.1 使用SlowHTTPTest测试安装测试工具git clone https://github.com/shekyan/slowhttptest ./configure make sudo make install执行测试命令slowhttptest -c 1000 -H -g -o slowhttp -i 10 -r 200 -t GET -u http://localhost:8080 -x 24 -p 3参数说明-c 1000建立1000个连接-i 10每10秒发送数据-x 24测试持续24秒-p 3等待3秒后开始攻击5.2 防御效果对比指标加固前加固后线程占用率100%30%请求成功率15%99.8%平均响应时间12s230msCPU使用率90%40%-60%6. 高级防护方案集成6.1 与Nginx联动防护在Nginx层添加前置规则http { limit_conn_zone $binary_remote_addr zoneconn_limit:10m; limit_req_zone $binary_remote_addr zonereq_limit:10m rate10r/s; server { location / { limit_conn conn_limit 20; limit_req zonereq_limit burst30 nodelay; proxy_pass http://springboot_app; } } }6.2 云原生环境方案在Kubernetes Ingress中配置防护annotations: nginx.ingress.kubernetes.io/limit-connections: 100 nginx.ingress.kubernetes.io/limit-rps: 10 nginx.ingress.kubernetes.io/limit-burst-multiplier: 5 nginx.ingress.kubernetes.io/connection-proxy-header: keep-alive7. 典型问题排查实录7.1 连接泄漏问题现象监控显示连接数持续增长不释放 排查步骤抓取线程转储jstack pid thread.dump分析Tomcat线程状态grep http-nio thread.dump | awk {print $2} | sort | uniq -c检查连接持有链// 在Filter中添加连接追踪 MDC.put(connId, UUID.randomUUID().toString());7.2 参数调优误区常见配置错误将connectionTimeout设得过小1s导致移动端用户超时maxThreads超过CPU核心数10倍引发频繁上下文切换未设置keepAliveTimeout导致长连接无法释放推荐计算公式maxThreads (核心数 * 2) 备用线程 queueSize maxThreads * 3 maxConnections queueSize * 28. 防护策略持续演进随着协议演进我们还需要关注HTTP/2的流控制攻击WebSocket的慢消费攻击gRPC的长轮询占用建议每季度进行安全扫描工具检查OWASP ZAP模糊测试使用Burp Suite红蓝对抗演练
返回列表