【系统安全】DDoS攻击

【系统安全】DDoS攻击

【一】什么是DDoS攻击

【1】DDoS攻击的概念

DDoS​ 的全称是 ​Distributed Denial-of-Service,即 ​分布式拒绝服务攻击。

(1)拒绝服务(DoS)​​:

目标​:攻击者的目的不是窃取数据或入侵系统,而是让正常的用户无法访问目标服务,也就是"拒绝"提供"服务"。

​比喻​:这就像你开了一家商店,攻击者不是来偷东西,而是雇了成百上千人堵在你的店门口。真正的顾客根本无法进门,你的生意也就瘫痪了。

(2)​分布式(D)​​:

​手段​:攻击不是来自一个源头,而是来自分布在全世界成千上万台被黑客控制的设备(如电脑、服务器、物联网摄像头、智能家居设备等)。这些设备组成了一个"僵尸网络"。

比喻​:堵门的不是一伙人,而是从全国各地雇来的人,让你根本无法通过拦住一两个人来解决问题。

(3)简单总结

DDoS攻击就是攻击者指挥一个由大量计算机组成的"僵尸网络",向一个特定的目标(如网站、服务器、网络设备)发动洪水般的垃圾请求,耗尽其所有资源(如网络带宽、系统CPU/内存、应用处理能力),从而导致合法用户无法获得服务的攻击方式。

【2】DDoS攻击的主要类型

(1)流量型攻击​

网络层/传输层

用巨大的垃圾数据流堵塞目标服务器的网络管道(带宽)。

(2)协议型攻击​

网络层/传输层

利用网络协议(如TCP三次握手)的缺陷,耗尽服务器的连接资源。

(3)应用层攻击​

应用层

模仿正常用户行为,向消耗大的网页(如搜索、登录)发起频繁请求,耗尽CPU/内存资源。

【3】DDoS攻击的常见表现

(1)网络和系统层面表现

(1)网络严重拥塞,带宽耗尽​:

表现​:服务器的入口带宽使用率突然飙升到95%甚至100%,而出站带宽可能正常。监控图表会显示一个极高的峰值。

结果​:服务器与外部网络的连接变得极慢或完全中断,SSH远程连接都可能卡顿或断开。

(2)服务器资源耗尽​:

1-CPU使用率100%​​:尤其是应用层攻击,大量请求需要服务器进行业务逻辑处理,导致CPU不堪重负。

2-内存耗尽​:每个请求都会占用一定的内存,海量并发请求会快速吃光所有可用内存。

3-连接数耗尽​:服务器操作系统或Web容器(如Tomcat、Nginx)的最大连接数被占满,无法再建立新的连接。查看网络连接会看到成千上万的ESTABLISHED、SYN_RECV状态的连接(尤其是协议攻击)。

(2)应用和服务层面表现

(1)​服务响应极其缓慢或完全无响应​:

1-表现​:网站、API接口的响应时间从几十毫秒飙升到几秒、几十秒,甚至直接超时。

2-结果​:前端页面一直处于"加载中",移动App无法刷新内容,用户体验极差。

(2)大量错误和异常​:

1-5xx错误激增​:如 502 Bad Gateway(网关后端服务无响应)、503 Service Unavailable(服务不可用)、504 Gateway Timeout(网关超时)。

2-4xx错误激增​:在网关层或防护设备启动防护后,会返回大量 429 Too Many Requests(请求过快)或 403 Forbidden(IP被禁止)。

(3)​微服务架构中的连锁反应​:

1-​表现​:在Spring Cloud微服务体系中,一个服务(如网关或用户服务)被攻击瘫痪,可能通过依赖关系引发雪崩效应。

2-​示例​:网关被压垮 → 所有服务不可用;用户服务被压垮 → 依赖用户认证的订单、支付等服务全部报错;数据库连接池被占满 → 所有需要数据库的服务全部瘫痪。

(4)日志中出现异常模式​:

1-来自少量IP的海量请求​:在应用日志中,你会发现同一个IP地址在极短时间内对同一个接口(特别是耗时的接口,如搜索、导出)发起成千上万次请求。

2-User-Agent异常​:大量请求使用奇怪或统一的恶意User-Agent。

3-无Referer或异常Referer​:请求缺乏来源页信息或来源页是伪造的。

(3)监控告警系统的表现

一个健全的监控系统会在攻击发生时发出明确的警报:

(1)​流量告警​:网络流量超过预设阈值。

(2)QPS(每秒查询率)告警​:API请求量异常飙升。

(3)错误率告警​:HTTP 5xx/4xx错误率大幅上升。

(4)资源告警​:CPU、内存、磁盘I/O使用率告警。

(5)健康检查失败​:服务注册中心(如Eureka、Nacos)连续收到某个服务下线的心跳,导致该服务从服务列表中剔除。

【4】总结

DDoS攻击的核心表现可以概括为:在没有任何明显业务增长的情况下,系统各项资源指标(带宽、CPU、内存、连接数)突然达到极限,导致服务对正常用户变得极慢或完全不可用,并伴随大量错误日志和监控告警。

【二】DDoS 攻击类型与防护架构

【1】攻击类型识别

【2】防护体系架构

【三】基础设施层防护

【1】云服务商防护配置

yml 复制代码
# 阿里云DDoS高防配置示例
aliyun:
  ddos:
    basic:
      enable: true
      threshold: 5000  # 5Gbps触发清洗
    bgp:
      enable: true     # 启用BGP高防IP
    waf:
      enable: true
      rules:
        cc-protection: 
          enable: true
          threshold: 1000  # 单IP每秒请求阈值

【2】CDN 动态加速配置

java 复制代码
@Configuration
public class CdnConfig {
    
    @Bean
    public FilterRegistrationBean<CdnFilter> cdnFilter() {
        FilterRegistrationBean<CdnFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new CdnFilter());
        registration.addUrlPatterns("/*");
        registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return registration;
    }
}

// CDN头验证过滤器
public class CdnFilter implements Filter {
    private final Set<String> cdnIps = Set.of("1.1.1.1", "2.2.2.2"); // CDN IP段
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String clientIp = getRealClientIp(httpRequest);
        
        // 验证CDN头部
        if (!isFromCdn(httpRequest, clientIp)) {
            ((HttpServletResponse) response).setStatus(403);
            return;
        }
        
        chain.doFilter(request, response);
    }
    
    private String getRealClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        return ip != null ? ip : request.getRemoteAddr();
    }
    
    private boolean isFromCdn(HttpServletRequest request, String clientIp) {
        // 验证CDN特定头部
        String cdnSecret = request.getHeader("X-CDN-Secret");
        return "valid-secret".equals(cdnSecret) && cdnIps.contains(clientIp);
    }
}

【四】Nginx流量网关

【五】API 网关层防护(Spring Cloud Gateway)

【1】限流配置:对服务限流

对服务配置限流

yml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user_service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 100    # 每秒令牌数
                redis-rate-limiter.burstCapacity: 200    # 令牌桶容量
                key-resolver: "#{@ipKeyResolver}"
            - name: RequestSize
              args:
                maxSize: 10MB
            - StripPrefix=1

    redis:
      host: localhost
      port: 6379

【2】自定义限流策略

java 复制代码
@Configuration
public class RateLimitConfig {
    
    @Bean
    public KeyResolver ipKeyResolver() {
        return exchange -> {
            String ip = Objects.requireNonNull(exchange.getRequest()
                .getRemoteAddress()).getAddress().getHostAddress();
            return Mono.just(ip);
        };
    }
    
    @Bean
    public KeyResolver apiKeyResolver() {
        return exchange -> {
            String apiKey = exchange.getRequest()
                .getHeaders().getFirst("X-API-Key");
            return Mono.just(apiKey != null ? apiKey : "anonymous");
        };
    }
    
    @Bean
    public KeyResolver userKeyResolver() {
        return exchange -> {
            String token = exchange.getRequest()
                .getHeaders().getFirst("Authorization");
            if (token != null && token.startsWith("Bearer ")) {
                String username = JwtUtil.extractUsername(token.substring(7));
                return Mono.just(username != null ? username : "anonymous");
            }
            return Mono.just("anonymous");
        };
    }
}

【3】全局过滤器防护:DDoS保护过滤器

(1)限制全局QPS,登录接口限制10,普通接口限制100,其他静态资源限制1000

(2)检查全局请求速率

(3)检查IP黑白名单

(4)用户代理检查

(5)路径防护,判断是否敏感路径,判断是否是无效请求

(6)请求频率检查

java 复制代码
@Component
public class DdosProtectionFilter implements GlobalFilter, Ordered {
    
    private final RedisTemplate<String, String> redisTemplate;
    private final RateLimiter rateLimiter = RateLimiter.create(1000); // 全局QPS限制
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String clientIp = getClientIp(request);
        String path = request.getPath().value();
        
        // 1. 全局速率限制
        if (!rateLimiter.tryAcquire()) {
            return tooManyRequests(exchange);
        }
        
        // 2. IP黑白名单检查
        if (isBlacklistedIp(clientIp)) {
            return forbidden(exchange);
        }
        
        // 3. 用户代理检查
        if (isSuspiciousUserAgent(request)) {
            return forbidden(exchange);
        }
        
        // 4. 路径防护
        if (isSensitivePath(path) && !isValidRequest(request)) {
            return forbidden(exchange);
        }
        
        // 5. 请求频率检查
        if (exceedsRateLimit(clientIp, path)) {
            return tooManyRequests(exchange);
        }
        
        return chain.filter(exchange);
    }
    
    private boolean exceedsRateLimit(String clientIp, String path) {
        String key = "rate_limit:" + clientIp + ":" + path;
        Long count = redisTemplate.opsForValue().increment(key);
        redisTemplate.expire(key, 1, TimeUnit.SECONDS);
        return count != null && count > getPathLimit(path);
    }
    
    private int getPathLimit(String path) {
        if (path.contains("/api/login")) return 10;    // 登录接口严格限制
        if (path.contains("/api/")) return 100;         // 普通API
        return 1000;                                    // 静态资源
    }
}

【4】Gateway的配置案例

(1)HTTPS强制跳转与证书配置

yml 复制代码
spring:
  cloud:
    gateway:
      httpclient:
        ssl:
          use-insecure-trust-manager: false # 禁用不安全证书
          trustedX509Certificates: 
            - classpath:server.crt
      routes:
        - id: https_redirect
          uri: https://example.com
          predicates:
            - Path=/**
          filters:
            - RedirectTo=302, https://${host}:${server.port}${path} # HTTP自动跳HTTPS
server:
  ssl:
    key-store: classpath:keystore.p12
    key-store-password: changeit
    key-store-type: PKCS12
    key-alias: gateway

(2)CORS跨域安全配置

(1)跨域安全问题​

跨域安全问题​(Cross-Origin Resource Sharing Security)源于浏览器的同源策略​(Same-Origin Policy),这是浏览器最基本的安全机制。当网页尝试访问与其自身源(协议+域名+端口)不同的资源时,浏览器会阻止这种跨域请求。

(2)跨域攻击场景一:CSRF(跨站请求伪造)

攻击者诱导用户访问恶意网站,该网站自动向目标网站发起请求(携带用户凭证Cookie),执行用户不知情的操作(转账、修改密码等)

(3)跨域攻击场景二:XSSI(跨站脚本包含)​​

通过

(4)配置的逻辑

1-config.addAllowedOrigin("https://trusted-domain.com");

精确指定可信域名,不允许任意源访问

2-config.setExposedHeaders("Authorization");

仅暴露必要头信息,用来传token令牌

3-config.addAllowedHeader(List.of("Content-Type","Accept"));

java 复制代码
@Bean
public CorsWebFilter corsFilter() {
    return new CorsWebFilter(source -> {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);// 允许凭证
        config.addAllowedOrigin("https://trusted-domain.com");// 允许的源
        config.addAllowedMethod("*");// 允许所有HTTP方法
        config.addAllowedHeader("*");// 允许所有头
        config.setExposedHeaders(List.of("Authorization"));// 暴露的响应头
        config.setMaxAge(3600L);// 预检缓存时间(秒)
        return config;
    });
}

(3)请求限流防护(Redis令牌桶)

yml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: api_route
          uri: lb://user-service
          predicates:
            - Path=/api/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 100 # 每秒令牌数
                redis-rate-limiter.burstCapacity: 200 # 突发容量
                key-resolver: "#{@ipKeyResolver}"
java 复制代码
@Bean
public KeyResolver ipKeyResolver() {
    return exchange -> 
        Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}

(4)JWT认证过滤器

【一】执行流程

(1)拦截所有需要认证的请求

跳过不需要认证的路径(如登录、公开API)

(2)验证JWT令牌的签名、有效期和结构

1-从Authorization头提取Bearer Token

2-使用公钥验证令牌签名

3-验证exp声明,判断是否过期

4-验证令牌是否已被撤销

(3)将认证信息传递给下游服务

1-解析令牌中的用户信息(如用户ID、角色)

2-将用户信息添加到请求头,传递给下游服务

(4)处理无效令牌的请求

无效令牌:返回401 Unauthorizen

过期令牌:返回403 Forbidden

缺失令牌:返回400 Bad Request

【二】配置重点

(1)密钥管理

使用非对称加密(RS256)

使用强密钥,定期轮换密钥(通过JWKS端点)

(2)令牌撤销

实现令牌黑名单(Redis存储)

短期令牌+刷新令牌机制

(3)防御措施

防止令牌泄露:强制HTTPS,设置HttpOnly Cookie

限制令牌有效期:设置合理的exp时间(通常30分钟-2小时)

敏感操作要求重新认证

添加必要的安全头Authorization

结合API网关的限流功能防止暴力破解

【三】RS256算法优点

(1)非对称加密,性能相对较差

(2)公钥和私钥是分离的,用公钥加密,用私钥解密,保证私钥安全即可,前端可以用公钥验证而无需接触私钥,私钥可以集中保管在安全环境,即使公钥泄露也不影响整体安全

(3)秘钥长度256字节,保密性更高

(4)适用于多租户和开放平台

【四】token生成的原理

JWT由Header(头信息),PayLoad (用户信息),Signature(签名)三个部分组成

(1)Header:头信息

Header头信息主要声明加密算法

HS256:对称加密

RS256:非对称加密

(2)PayLoad:用户信息

指定了七个默认字段供选择

也可以自定义私有字段,但是不建议在此存放密码之类的敏感信息,因为此部分可以解码还原出原始内容。虽然它可以解码,但是也不能修改这个内容。

java 复制代码
iss:发行人
exp:到期时间
sub:主体
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT

对其进行base64加密,得到Jwt的第二部分

(3)Signature:签名

此部分用于防止jwt内容被篡改。这个签证信息由三部分组成(由加密后的Header,加密后的PayLoad,加密后的签名三部分组成)。base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐加密,然后就构成了jwt的第三部分,每个部分直接使用"."来进行拼接

【五】token校验的原理

通过秘钥解析token,得到用户信息、头信息等,根据用户信息查询到对应库里的用户信息,然后用同样的加密算法加密,然后判断加密后的信息是否一致

java 复制代码
@Component
public class JwtAuthFilter implements GlobalFilter {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 从头信息获取token令牌
        String token = exchange.getRequest()
            .getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
        // 缺失令牌
        if (token == null || !token.startsWith("Bearer ")) {
            return unauthorized(exchange, "Missing token");
        }
        
        try {
            // 
            Claims claims = Jwts.parserBuilder()
                .setSigningKey(Keys.hmacShaKeyFor(secret.getBytes()))
                .build()
                .parseClaimsJws(token.substring(7))
                .getBody();
            
            exchange.getAttributes().put("user", claims.getSubject());
            return chain.filter(exchange);
        } catch (JwtException e) {
            return unauthorized(exchange, "Invalid token");
        }
    }
    
    private Mono<Void> unauthorized(ServerWebExchange exchange, String msg) {
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return exchange.getResponse().writeWith(
            Mono.just(exchange.getResponse().bufferFactory().wrap(msg.getBytes()))
        );
    }
}

(5)IP黑白名单控制

yml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: secure_route
          uri: lb://core-service
          predicates:
            - Path=/v1/**
          filters:
            - name: RemoteAddr
              args:
                sources: 
                  - 192.168.1.0/24
                  - 10.0.0.1
                deny: 0.0.0.0/0 # 默认拒绝所有

(6)敏感头信息过滤

yml 复制代码
spring:
  cloud:
    gateway:
      default-filters:
        - RemoveRequestHeader=Cookie,Set-Cookie # 移除敏感头
        - AddResponseHeader=X-Content-Type-Options, nosniff
        - AddResponseHeader=X-Frame-Options, DENY
      routes:
        - id: proxy_route
          uri: lb://internal-service
          filters:
            - StripPrefix=1
            - RemoveRequestHeader=Authorization # 特定路由移除

(7)请求大小限制

yml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: upload_route
          uri: lb://file-service
          predicates:
            - Path=/upload
          filters:
            - name: RequestSize
              args:
                maxSize: 10MB # 最大请求体限制

(8)WAF集成(Web应用防火墙)

【一】sql注入检查

攻击者通过在应用程序的输入字段中插入恶意的SQL代码,从而欺骗数据库执行非法的SQL命令。这可能导致数据泄露、数据篡改、甚至数据库服务器被完全控制。

(1)检查请求参数(包括查询参数、请求体、路径变量等)中是否包含可疑的SQL关键字或特殊字符。

(2)使用正则表达式或字符串匹配来检测常见的SQL注入模式。

复杂的SQL注入攻击可能使用编码、注释等方式绕过简单的关键字匹配。因此,网关层的SQL注入防护通常作为一道基础防线,更深入的防护应该在应用层(如使用预编译语句、ORM框架等)实现。

【二】检查XSS攻击

XSS(跨站脚本攻击)是一种常见的网络安全漏洞,攻击者通过在网页中注入恶意脚本,当其他用户浏览该网页时,脚本执行,从而窃取用户信息、会话令牌或进行其他恶意操作。

(1)检查输入中是否包含可疑的HTML标签(如

java 复制代码
@Component
public class WafFilter implements GlobalFilter {
    
    private final WafClient wafClient;
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        
        // 1. 检查SQL注入
        if (wafClient.detectSqlInjection(request.getQueryParams().toString())) {
            return blockRequest(exchange, "SQLi detected");
        }
        
        // 2. 检查XSS攻击
        if (request.getHeaders().values().stream()
            .anyMatch(header -> wafClient.detectXss(header.toString()))) {
            return blockRequest(exchange, "XSS detected");
        }
        
        return chain.filter(exchange);
    }
}

(9)OAuth2资源服务器配置

yml 复制代码
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://auth-server.com
          jwk-set-uri: https://auth-server.com/.well-known/jwks.json
java 复制代码
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
    return http
        .authorizeExchange(exchanges -> exchanges
            .pathMatchers("/public/**").permitAll()
            .pathMatchers("/admin/**").hasAuthority("ROLE_ADMIN")
            .anyExchange().authenticated()
        )
        .oauth2ResourceServer(ServerHttpSecurity.OAuth2ResourceServerSpec::jwt)
        .csrf().disable() // 在网关层禁用CSRF
        .build();
}

【六】应用层防护(Spring Boot)

【1】自定义限流注解:对接口限流

java 复制代码
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
    int value() default 100;           // 请求次数
    int time() default 60;              // 时间窗口(秒)
    RateLimitType type() default RateLimitType.IP;
}

public enum RateLimitType {
    IP,        // 按IP限制
    USER,      // 按用户限制
    METHOD,    // 按方法限制
    GLOBAL     // 全局限制
}

// AOP限流实现
@Aspect
@Component
public class RateLimitAspect {
    
    private final RedisTemplate<String, Object> redisTemplate;
    
    @Around("@annotation(rateLimit)")
    public Object around(ProceedingJoinPoint joinPoint, RateLimit rateLimit) throws Throwable {
        String key = generateKey(joinPoint, rateLimit);
        
        if (!tryAcquire(key, rateLimit)) {
            throw new RateLimitExceededException("请求过于频繁");
        }
        
        try {
            return joinPoint.proceed();
        } finally {
            // 清理资源
        }
    }
    
    private boolean tryAcquire(String key, RateLimit rateLimit) {
        String redisKey = "rate_limit:" + key;
        Long count = redisTemplate.opsForValue().increment(redisKey);
        
        if (count == 1) {
            redisTemplate.expire(redisKey, rateLimit.time(), TimeUnit.SECONDS);
        }
        
        return count <= rateLimit.value();
    }
}

【2】请求指纹识别

java 复制代码
@Component
public class RequestFingerprint {
    
    public String generate(HttpServletRequest request) {
        String fingerprint = String.join("|",
            request.getRemoteAddr(),
            request.getHeader("User-Agent"),
            getBrowserFingerprint(request),
            getDeviceFingerprint(request)
        );
        return DigestUtils.md5DigestAsHex(fingerprint.getBytes());
    }
    
    private String getBrowserFingerprint(HttpServletRequest request) {
        // 基于浏览器特性生成指纹
        return String.join(",",
            request.getHeader("Accept-Language"),
            request.getHeader("Accept-Encoding"),
            request.getHeader("Accept")
        );
    }
}

【3】人机验证集成

java 复制代码
@Service
public class CaptchaService {
    
    public boolean verifyCaptcha(String captcha, String clientIp) {
        // 1. 基础验证
        if (StringUtils.isEmpty(captcha)) {
            return false;
        }
        
        // 2. 验证码服务调用
        CaptchaResult result = captchaClient.verify(captcha, clientIp);
        
        // 3. 风险评估
        RiskAssessment risk = assessRisk(clientIp, result.getScore());
        
        return risk.isAllowed();
    }
    
    @RateLimit(value = 5, time = 300, type = RateLimitType.IP)
    public String generateCaptcha(String clientIp) {
        // 生成验证码逻辑
        return captchaClient.generate(clientIp);
    }
}

【4】使用Spring Security

java 复制代码
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .addFilterBefore(new RateLimitFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}

public class RateLimitFilter extends OncePerRequestFilter {
    private final RateLimiter rateLimiter = RateLimiter.create(100); // 每秒100个请求

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (!rateLimiter.tryAcquire()) {
            response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
            response.getWriter().write("Too many requests");
            return;
        }
        filterChain.doFilter(request, response);
    }
}

【5】数据脱敏

【七】微服务间防护

【1】Feign 客户端防护

java 复制代码
@FeignClient(name = "user-service", 
             configuration = FeignSecurityConfig.class,
             fallbackFactory = UserServiceFallbackFactory.class)
public interface UserServiceClient {
    
    @RateLimit(value = 50, time = 60)
    @GetMapping("/users/{id}")
    ResponseEntity<User> getUser(@PathVariable Long id);
    
    @PostMapping("/users")
    ResponseEntity<User> createUser(@RequestBody User user);
}

// Feign配置
@Configuration
public class FeignSecurityConfig {
    
    @Bean
    public RequestInterceptor rateLimitInterceptor() {
        return template -> {
            // 添加限流头信息
            template.header("X-RateLimit-Service", "user-service");
        };
    }
    
    @Bean
    public Retryer feignRetryer() {
        // 防止重放攻击,限制重试次数
        return new Retryer.Default(100, 1000, 3);
    }
}

// 降级处理
@Component
public class UserServiceFallbackFactory implements FallbackFactory<UserServiceClient> {
    
    @Override
    public UserServiceClient create(Throwable cause) {
        return new UserServiceClient() {
            @Override
            public ResponseEntity<User> getUser(Long id) {
                // 记录攻击日志
                log.warn("User service fallback triggered by: {}", cause.getMessage());
                return ResponseEntity.status(503).build();
            }
        };
    }
}

【八】缓存层防护

【1】Redis 缓存击穿防护

java 复制代码
@Service
public class CacheProtectionService {
    
    public <T> T getWithProtection(String key, Class<T> type, 
                                  Supplier<T> loader, Duration timeout) {
        // 1. 布隆过滤器检查
        if (!bloomFilter.mightContain(key)) {
            return null;
        }
        
        // 2. 缓存获取
        T value = redisTemplate.opsForValue().get(key);
        if (value != null) {
            return value;
        }
        
        // 3. 分布式锁防止缓存击穿
        String lockKey = "lock:" + key;
        boolean locked = tryLock(lockKey, timeout);
        if (!locked) {
            // 等待其他线程加载
            return waitForCache(key, type, timeout);
        }
        
        try {
            // 双重检查
            value = redisTemplate.opsForValue().get(key);
            if (value != null) {
                return value;
            }
            
            // 加载数据
            value = loader.get();
            if (value != null) {
                redisTemplate.opsForValue().set(key, value, timeout);
                bloomFilter.put(key); // 更新布隆过滤器
            }
            
            return value;
        } finally {
            releaseLock(lockKey);
        }
    }
}

【2】热点数据保护

java 复制代码
@Component
public class HotKeyProtection {
    
    private final Map<String, AtomicLong> accessCounters = new ConcurrentHashMap<>();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    
    @PostConstruct
    public void init() {
        // 定期清理计数器
        scheduler.scheduleAtFixedRate(this::cleanupCounters, 1, 1, TimeUnit.MINUTES);
    }
    
    public boolean isHotKey(String key) {
        AtomicLong counter = accessCounters.computeIfAbsent(key, k -> new AtomicLong());
        long count = counter.incrementAndGet();
        
        // 阈值判断
        return count > 1000; // 每分钟超过1000次访问
    }
    
    public void handleHotKey(String key, Runnable fallback) {
        if (isHotKey(key)) {
            // 热点Key降级处理
            fallback.run();
            log.warn("Hot key detected: {}", key);
        }
    }
}

【八】监控与告警体系

【1】Micrometer 监控指标

java 复制代码
@Component
public class DdosMetrics {
    
    private final MeterRegistry meterRegistry;
    private final Counter requestCounter;
    private final DistributionSummary requestSizeSummary;
    
    public DdosMetrics(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        this.requestCounter = Counter.builder("http.requests")
            .tag("type", "ddos_protection")
            .register(meterRegistry);
            
        this.requestSizeSummary = DistributionSummary.builder("http.request.size")
            .register(meterRegistry);
    }
    
    public void recordRequest(HttpServletRequest request, boolean blocked) {
        requestCounter.increment();
        
        if (blocked) {
            meterRegistry.counter("http.requests.blocked").increment();
        }
        
        // 记录请求大小
        int contentLength = request.getContentLength();
        if (contentLength > 0) {
            requestSizeSummary.record(contentLength);
        }
        
        // 记录IP频率
        String ip = request.getRemoteAddr();
        meterRegistry.counter("ip.requests", "ip", ip).increment();
    }
}

【2】自定义健康检查

java 复制代码
@Component
public class DdosHealthIndicator implements HealthIndicator {
    
    private final RedisTemplate<String, String> redisTemplate;
    
    @Override
    public Health health() {
        Map<String, Object> details = new HashMap<>();
        
        // 检查请求频率
        long totalRequests = getTotalRequestsLastMinute();
        details.put("totalRequestsLastMinute", totalRequests);
        
        // 检查阻塞请求数
        long blockedRequests = getBlockedRequestsLastMinute();
        details.put("blockedRequestsLastMinute", blockedRequests);
        
        // 风险评估
        if (totalRequests > 10000 || blockedRequests > 1000) {
            return Health.down()
                .withDetails(details)
                .withDetail("error", "Possible DDoS attack detected")
                .build();
        }
        
        return Health.up().withDetails(details).build();
    }
}

【3】告警规则配置

yml 复制代码
# Prometheus告警规则
groups:
- name: ddos_alerts
  rules:
  - alert: HighRequestRate
    expr: rate(http_requests_total[5m]) > 1000
    for: 2m
    labels:
      severity: critical
    annotations:
      summary: "高请求率告警"
      description: "当前请求率: {{ $value }} req/s"
  
  - alert: ManyBlockedRequests
    expr: rate(http_requests_blocked_total[5m]) > 100
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "大量请求被拦截"
      
  - alert: SuspiciousIP
    expr: sum by (ip) (rate(ip_requests_total[1m])) > 500
    for: 1m
    labels:
      severity: critical

【4】使用Spring Boot Actuator

(1)应用健康检查​

实时暴露应用健康状态(数据库、磁盘、服务依赖等)

json 复制代码
// 访问 /actuator/health 返回示例
{
  "status": "UP",
  "components": {
    "db": { "status": "UP", "details": { "database": "H2" } },
    "diskSpace": { "status": "UP", "details": { "free": 100GB } }
  }
}

(2)指标监控​

集成 Micrometer 收集 JVM/HTTP/缓存等 500+ 指标

(3)运行时洞察​

动态查看日志级别、线程堆栈、环境变量等

(4)审计跟踪​

记录用户操作事件(登录、数据修改等)

java 复制代码
@Bean
public AuditEventRepository auditEventRepository() {
    return new InMemoryAuditEventRepository(); // 可替换为JDBC实现
}

(5)优雅停机

确保服务关闭时不中断进行中的请求

yml 复制代码
server:
  shutdown: graceful # 开启优雅停机
spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s # 最长等待时间

【九】应急响应机制

【1】自动封禁策略

java 复制代码
@Service
public class AutoBlockService {
    
    @Scheduled(fixedRate = 60000) // 每分钟检查
    public void autoBlockMaliciousIps() {
        Map<String, Long> ipStats = getIpRequestStats();
        
        ipStats.entrySet().stream()
            .filter(entry -> entry.getValue() > 1000) // 每分钟超过1000次
            .forEach(entry -> {
                String ip = entry.getKey();
                blockIp(ip, Duration.ofHours(1)); // 封禁1小时
                log.warn("Auto blocked IP: {} for excessive requests: {}", ip, entry.getValue());
                
                // 发送告警
                alertService.sendAlert("IP自动封禁", 
                    "IP: " + ip + " 请求数: " + entry.getValue());
            });
    }
    
    public void blockIp(String ip, Duration duration) {
        String key = "blocked_ip:" + ip;
        redisTemplate.opsForValue().set(key, "1", duration);
    }
}

【2】降级策略

java 复制代码
@Component
public class DegradationStrategy {
    
    public void activateEmergencyMode() {
        // 1. 关闭非核心服务
        feignConfig.disableNonCriticalServices();
        
        // 2. 启用静态降级页面
        staticModeService.enable();
        
        // 3. 限制API速率
        rateLimitConfig.setStrictMode(true);
        
        // 4. 发送通知
        notificationService.sendEmergencyAlert("DDoS攻击防护已激活");
    }
    
    @EventListener
    public void handleDdosEvent(DdosDetectedEvent event) {
        if (event.getSeverity() == Severity.CRITICAL) {
            activateEmergencyMode();
        }
    }
}

【十】测试与演练

【1】压力测试配置

java 复制代码
@SpringBootTest
@TestPropertySource(properties = {
    "spring.redis.embedded=true",
    "resilience4j.ratelimiter.enabled=true"
})
public class DdosProtectionTest {
    
    @Autowired
    private TestRestTemplate restTemplate;
    
    @Test
    public void testRateLimiting() {
        // 模拟高并发请求
        List<CompletableFuture<ResponseEntity<String>>> futures = new ArrayList<>();
        
        for (int i = 0; i < 1000; i++) {
            futures.add(CompletableFuture.supplyAsync(() ->
                restTemplate.getForEntity("/api/users/1", String.class)
            ));
        }
        
        // 统计429响应数量
        long blockedCount = futures.stream()
            .map(CompletableFuture::join)
            .filter(response -> response.getStatusCode() == HttpStatus.TOO_MANY_REQUESTS)
            .count();
            
        assertThat(blockedCount).isGreaterThan(800); // 80%请求应被限流
    }
}

【2】混沌工程测试

java 复制代码
@Component
public class ChaosTestService {
    
    public void simulateDdosAttack() {
        // 1. 生成大量请求
        IntStream.range(0, 10000).parallel().forEach(i -> {
            restTemplate.getForObject("/api/data", String.class);
        });
        
        // 2. 验证防护效果
        Health health = healthEndpoint.health();
        assertThat(health.getStatus()).isEqualTo(Status.UP);
    }
}

【十一】总结

【1】网络层

云防护、防火墙进行DDoS清洗、IP封禁

【2】Nginx流量网管层

【3】Gateway业务网关层

(1)https强制跳转和证书配置

(2)全局过滤器请求限流防护(对服务)

令牌桶限流,例如100-1000,根据业务需求来配置

(3)CORS跨域安全过滤器

1-config.addAllowedOrigin("https://trusted-domain.com");

精确指定可信域名,不允许任意源访问

2-config.setExposedHeaders("Authorization");

仅暴露必要头信息,用来传token令牌

3-config.addAllowedHeader(List.of("Content-Type","Accept"));

(4)sql注入检查和XSS攻击过滤器

sql注入检查

攻击者通过在应用程序的输入字段中插入恶意的SQL代码,从而欺骗数据库执行非法的SQL命令。这可能导致数据泄露、数据篡改、甚至数据库服务器被完全控制。

1-检查请求参数(包括查询参数、请求体、路径变量等)中是否包含可疑的SQL关键字或特殊字符。

2-使用正则表达式或字符串匹配来检测常见的SQL注入模式。

复杂的SQL注入攻击可能使用编码、注释等方式绕过简单的关键字匹配。因此,网关层的SQL注入防护通常作为一道基础防线,更深入的防护应该在应用层(如使用预编译语句、ORM框架等)实现。

检查XSS攻击

XSS(跨站脚本攻击)是一种常见的网络安全漏洞,攻击者通过在网页中注入恶意脚本,当其他用户浏览该网页时,脚本执行,从而窃取用户信息、会话令牌或进行其他恶意操作。

1-检查输入中是否包含可疑的HTML标签(如

(5)JWT认证过滤器

1-使用非对称加密(RS256),秘钥公钥分离,秘钥做好安全存放

2-使用强密钥,定期轮换密钥(通过JWKS端点)

3-防止令牌泄露:强制HTTPS,设置HttpOnly Cookie

4-限制令牌有效期:设置合理的exp时间(通常30分钟-2小时)

5-敏感操作要求重新认证

6-添加必要的安全头Authorization

7-结合API网关的限流功能防止暴力破解

8-令牌token里不要放敏感信息

(6)IP黑白名单控制

(7)敏感头信息过滤

(8)请求大小限制

(9)OAuth2资源服务器配置

1-有些高密的接口配置高级访问权限的限制

【4】应用层

(1)人机验证

1-登录或者注册接口,使用输入编码或点击图片等实现人机验证和机器人过滤

(2)token令牌

1-登录成功后,通过秘钥生成token令牌,设置令牌的过期时间,返回给前端放进cookie,下次请求带token

2-请求达到gateway会经过SpringSecurity的过滤器,对token进行解密和校验,如果token不存在或者已过期,则跳转到登录页面

(3)业务限流

1-根据业务的实际情况对某些接口进行限流,例如登录注册接口和其他业务接口,使用不同的限流配置

(4)服务监控报警

1-自定义健康检查

(5)自动封禁和降级

1-对于访问频率异常的ip可以放进redis黑名单缓存里1小时,gateway黑名单过滤的时候进行过滤

(6)人工干预降级

(7)数据脱敏存储

【5】服务层

(1)Hystrix熔断降级

(2)Feign容错

(3)传递token校验

【6】Redis、布隆过滤器

热点保护、击穿防护

相关推荐
GIS数据转换器3 小时前
基于GIS的智慧畜牧数据可视化监控平台
人工智能·安全·信息可视化·无人机·智慧城市·制造
我叫汪枫4 小时前
《HTTP 安全与性能优化全攻略》
安全·http·性能优化
Swift社区5 小时前
Foundation Model 在 Swift 中的类型安全生成实践
开发语言·安全·swift
货拉拉技术5 小时前
大模型音频水印技术:用AI守护音频数据的“身份指纹”
人工智能·算法·安全
帅次6 小时前
系统分析师-信息安全-信息系统安全体系&数据安全与保密
安全·web安全·网络安全·系统安全·密码学·安全威胁分析·安全架构
Web3_Daisy7 小时前
从冷换仓到热追踪:项目方如何在不暴露风险的前提下守住主动权
大数据·人工智能·安全·区块链
NOVAnet20237 小时前
为迎战双十一,南凌科技发布「大促网络保障解决方案」,以确定性网络抵御不确定流量洪峰
网络·科技·安全·网络安全
RustCoder7 小时前
基于 Rust 的 Rustls 性能优于 OpenSSL 和 BoringSSL
物联网·安全·rust
三无少女指南16 小时前
深入理解JVM的安全点与安全区域
jvm·安全