
1. 慢HTTP攻击的本质与防御思路最近在排查线上服务异常时发现服务器频繁出现连接数耗尽的情况。经过抓包分析确认遭遇了Slow HTTP DOS攻击。这种攻击成本极低但危害巨大攻击者通过故意缓慢发送HTTP请求头或请求体长时间占用服务器连接资源导致正常用户无法访问。SpringBoot 2.7.18默认使用嵌入式Tomcat 9.0.x作为Web容器其默认配置对这类攻击几乎没有防御能力。经过多次实战测试和参数调优我总结出一套完整的防御方案核心思路是限制超时监控三位一体资源限制控制最大连接数、线程数等关键参数避免服务器资源被耗尽超时机制设置合理的读写超时及时释放被慢请求占用的连接主动监控通过指标监控及时发现异常动态调整防御策略2. 基础防御配置详解2.1 核心参数配置在SpringBoot中我们可以直接在application.yml中配置Tomcat参数。以下是经过生产验证的推荐配置server: tomcat: max-connections: 200 # 最大连接数(含活跃等待) max-threads: 200 # 最大工作线程数 min-spare-threads: 50 # 最小空闲线程数 connection-timeout: 3000 # TCP连接超时(ms) max-http-post-size: 10MB # 最大请求体大小 accept-count: 100 # 等待队列大小 connection-linger: -1 # 关闭连接延迟 port: 8080关键参数说明max-connections根据服务器配置设置4核8G建议200-500max-threads通常设置为CPU核心数*100左右connection-timeout建议3-5秒过短会影响正常用户2.2 慢请求专项防御针对Slow Headers和Slow Body攻击需要特别配置以下参数server: tomcat: connector: connectionTimeout: 5000 # 请求头/体读取超时(ms) async-timeout: 5000 # 异步请求超时这两个参数是防御慢HTTP攻击的关键connectionTimeout控制从建立连接到接收完整请求头的最大时间async-timeout控制请求体读取的超时时间生产环境建议设置为5-10秒可根据业务特点调整。过短可能导致移动端用户被误杀。3. 进阶防御方案实现3.1 自定义Tomcat连接器当基础配置无法满足需求时可以通过代码自定义Tomcat连接器Configuration public class TomcatConfig implements WebServerFactoryCustomizerTomcatServletWebServerFactory { Override public void customize(TomcatServletWebServerFactory factory) { factory.addConnectorCustomizers(connector - { Http11NioProtocol protocol (Http11NioProtocol) connector.getProtocolHandler(); // 设置关键防御参数 protocol.setConnectionTimeout(5000); protocol.setSoTimeout(3000); // Socket读写超时 protocol.setMaxConnections(200); protocol.setMaxThreads(200); // 其他优化参数 protocol.setTcpNoDelay(true); protocol.setSoKeepAlive(true); }); } }代码配置的优势在于可以设置更底层的Tomcat参数支持条件化配置不同环境便于实现动态参数调整3.2 慢请求拦截过滤器我们可以实现一个过滤器主动拦截可疑的慢请求Component Order(1) public class SlowRequestFilter implements Filter { private static final int MAX_HEADERS 50; private static final int MAX_HEADER_SIZE 2048; Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest (HttpServletRequest) request; // 检查请求头数量和大小 EnumerationString headers httpRequest.getHeaderNames(); int count 0; while(headers.hasMoreElements()) { String header headers.nextElement(); String value httpRequest.getHeader(header); if(count MAX_HEADERS || (value ! null value.length() MAX_HEADER_SIZE)) { response.setStatus(400); response.getWriter().write(Invalid request headers); return; } } chain.doFilter(request, response); } }这个过滤器会检查请求头数量是否异常检查单个请求头是否过大对可疑请求直接返回400错误4. 操作系统级优化除了应用层配置操作系统层面的优化也很重要4.1 Linux内核参数调整# /etc/sysctl.conf net.ipv4.tcp_keepalive_time 600 net.ipv4.tcp_keepalive_intvl 30 net.ipv4.tcp_keepalive_probes 3 net.ipv4.tcp_fin_timeout 30这些参数的作用是自动检测并关闭空闲连接加速TCP连接回收减少TIME_WAIT状态连接4.2 文件描述符限制# /etc/security/limits.conf * soft nofile 65535 * hard nofile 65535提高文件描述符限制可以防止连接数耗尽导致服务崩溃。5. 监控与告警体系5.1 SpringBoot Actuator集成首先添加依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency然后配置暴露监控端点management: endpoints: web: exposure: include: tomcat,metrics5.2 关键监控指标通过/actuator/tomcat端点可以获取以下关键指标指标名称正常范围异常表现connections.active max-connections*80%持续接近上限connections.pending accept-count*50%持续高位requestCount平稳波动突然激增errorCount低位稳定异常升高5.3 告警规则建议活跃连接数持续5分钟max-connections*80%等待队列持续5分钟accept-count*50%400/503错误率连续3分钟1%6. 实战测试与验证6.1 使用curl模拟攻击测试慢请求头攻击curl -v --limit-rate 1b/s http://localhost:8080/api预期结果5秒后连接被断开服务器日志显示超时关闭。6.2 使用siege压力测试siege -c 100 -t 1m --headerX-Slow: $(printf %*s 10000) http://localhost:8080/api这个测试会模拟100个并发连接每个请求携带10KB的冗余头持续测试1分钟正常防御情况下服务器应该保持稳定连接数不会持续增长。7. 性能优化建议线程池调优IO密集型业务max-threads CPU核心数 * 2-3CPU密集型业务max-threads CPU核心数 1连接数设置4核8G服务器max-connections 200-5008核16G服务器max-connections 500-1000超时时间内部APIconnectionTimeout 3-5秒外部APIconnectionTimeout 10-30秒在实际部署中建议先设置保守值然后根据监控数据逐步调整。每次调整后都要进行压力测试确保不会影响正常业务。