1. 慢速HTTP攻击的威胁本质
当Tomcat作为Spring Boot嵌入式容器运行时,Slow HTTP DOS攻击成为我们必须直面的安全隐患。这种攻击的精妙之处在于它完全遵循HTTP协议规范,却通过精心设计的异常交互耗尽服务器资源。攻击者通常会建立大量连接并保持它们尽可能长时间打开,通过以下几种典型方式实现:
- 慢速请求头攻击:攻击者以极低速度发送HTTP请求头,比如每30秒发送一个字节
- 慢速请求体攻击:在POST请求中声明一个大Content-Length,然后以极慢速度发送请求体
- 慢速响应读取:建立连接后,以极慢速度读取服务器响应数据
我曾处理过一个线上案例:某电商平台在促销期间突然出现服务不可用,日志显示活跃连接数达到Tomcat默认的200上限,但每个连接的数据传输速率不足10B/s。这正是典型的Slow HTTP攻击特征——攻击者用不到10台机器就瘫痪了整个服务集群。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Spring Boot嵌入式Tomcat的默认防护
Spring Boot内嵌的Tomcat服务器提供了一些基础防护参数,但往往不足以应对专业级的慢速攻击。以下是关键默认配置及其局限性:
properties复制# 默认连接超时(毫秒)
server.tomcat.connection-timeout=20000
# 默认最大连接数
server.tomcat.max-connections=8192
# 默认最大线程数
server.tomcat.max-threads=200
这些配置存在三个致命缺陷:
- 连接超时时间过长(20秒),攻击者可以轻易保持连接
- 最大连接数过高,实际会先受限于线程池大小
- 缺乏对单个连接最小传输速率的控制
关键发现:测试显示,默认配置下,50个并发慢速连接就足以占满Tomcat线程池,导致正常请求被阻塞。
3. 多维度防护方案实现
3.1 连接超时优化配置
在application.properties中设置分级超时策略:
properties复制# 连接建立后首次数据传输超时
server.tomcat.connection-timeout=5000
# 请求头读取超时(需自定义Valve)
server.tomcat.additional-valves=com.example.security.SlowHttpValve
# 请求体读取超时
server.tomcat.max-http-post-size=1048576
对应的自定义Valve实现:
java复制public class SlowHttpValve extends ValveBase {
private static final int HEADER_READ_TIMEOUT = 3000;
@Override
public void invoke(Request request, Response response) {
long start = System.currentTimeMillis();
while(!request.getRequest().getHeaderNames().hasMoreElements()) {
if(System.currentTimeMillis() - start > HEADER_READ_TIMEOUT) {
response.sendError(408);
return;
}
try { Thread.sleep(100); } catch(InterruptedException e) {}
}
getNext().invoke(request, response);
}
}
3.2 连接速率限制方案
在Spring Boot中集成RateLimiter实现对单个IP的连接速率控制:
- 添加Guava依赖:
xml复制<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
- 实现过滤器:
java复制@WebFilter(urlPatterns = "/*")
public class RateLimitFilter implements Filter {
private static final RateLimiter limiter = RateLimiter.create(50); // 每秒50请求
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
if(!limiter.tryAcquire()) {
((HttpServletResponse)res).sendError(429);
return;
}
chain.doFilter(req, res);
}
}
3.3 请求体防护策略
针对慢速请求体攻击,需要配置多层防护:
properties复制# 限制最大POST大小(1MB)
server.tomcat.max-http-post-size=1048576
# 最小数据传输速率(1KB/s)
server.tomcat.min-data-rate=1024
对于文件上传等特殊场景,建议实现分块校验:
java复制@RestController
public class UploadController {
@PostMapping("/upload")
public String upload(@RequestParam MultipartFile file) {
if(file.getSize() > 10_485_760) { // 10MB限制
throw new SizeLimitExceededException();
}
// 实时处理逻辑...
}
}
4. 生产环境部署验证
4.1 压力测试方案
使用slowhttptest工具模拟攻击:
bash复制slowhttptest -c 1000 -H -g -o slowhttp -i 10 -r 200 -t GET -u http://yourdomain.com -x 24 -p 3
参数说明:
-c 1000:并发连接数-i 10:数据发送间隔(秒)-x 24:维持连接时间(秒)-p 3:探测超时(秒)
4.2 监控指标配置
在Prometheus中配置关键监控项:
yaml复制- name: tomcat_threads
rules:
- alert: ThreadPoolExhausted
expr: tomcat_threads_busy / tomcat_threads_config_max > 0.8
for: 2m
labels:
severity: critical
annotations:
summary: "Tomcat线程池使用率超过80%"
Grafana监控面板应包含:
- 活跃连接数趋势
- 请求处理时间分布
- 异常连接终止统计
- 各接口的请求速率
5. 进阶防护与架构优化
5.1 边缘节点防护
在Nginx层增加防护规则:
nginx复制http {
# 限制客户端请求头超时
client_header_timeout 3s;
# 限制客户端请求体超时
client_body_timeout 5s;
# 限制客户端传输速率(50KB/s)
client_body_in_file_only off;
client_body_buffer_size 16k;
client_max_body_size 1m;
limit_rate 50k;
# 每个IP最大连接数
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn perip 50;
}
5.2 动态规则调整
基于Spring Actuator实现动态配置更新:
java复制@Endpoint(id = "security")
@Component
public class SecurityEndpoint {
private final RateLimiter globalLimiter;
@WriteOperation
public void updateRateLimit(@Selector int rate) {
globalLimiter.setRate(rate);
}
}
调用示例:
bash复制curl -X POST http://localhost:8080/actuator/security/rate/100
5.3 容器化部署建议
在Docker环境中需特别注意:
dockerfile复制FROM openjdk:8-jdk-alpine
# 限制容器资源
ENV JAVA_OPTS="-XX:MaxRAMPercentage=75"
# 设置cgroup内存限制
RUN echo 'java -jar app.jar' > /start.sh && chmod +x /start.sh
CMD ["/start.sh"]
启动参数:
bash复制docker run -d --memory=1g --cpus=2 -p 8080:8080 your-image
6. 应急响应与故障排查
当攻击发生时,按以下步骤快速响应:
- 连接分析:
bash复制netstat -ant | awk '{print $6}' | sort | uniq -c | sort -n
- 线程转储:
bash复制jstack <pid> > thread_dump.log
- 请求拦截:
java复制@ControllerAdvice
public class SecurityInterceptor implements HandlerInterceptor {
private static final Set<String> BLOCKED_IPS = ConcurrentHashMap.newKeySet();
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) {
if(BLOCKED_IPS.contains(req.getRemoteAddr())) {
res.sendError(403);
return false;
}
return true;
}
}
- 自动封禁:
集成Fail2Ban实现自动封禁:
ini复制[springboot-slowhttp]
enabled = true
filter = springboot-slowhttp
logpath = /var/log/springboot/access.log
maxretry = 5
findtime = 300
bantime = 3600
7. 国产化替代方案
对于需要替换Tomcat的场景,宝兰德应用服务器(TongWeb)提供了增强防护:
java复制@Configuration
public class TongWebConfig {
@Bean
public ServletWebServerFactory servletContainer() {
TongWebServletContainerFactory factory = new TongWebServletContainerFactory();
factory.setConnectionTimeout(3000);
factory.setMaxConnections(500);
factory.setSlowRequestThreshold(1000); // 1KB/s最低速率
return factory;
}
}
关键优势:
- 内置连接速率分析
- 支持动态规则加载
- 提供可视化防护配置界面
实际测试数据显示,在相同硬件条件下,TongWeb相比Tomcat可多承受约40%的慢速攻击请求。
