Skip to content

PostgreSQL DDoS 攻击防范

核心概念

1. DDoS 攻击定义

DDoS(分布式拒绝服务)攻击是指攻击者通过控制大量傀儡机(Botnet)向目标系统发送大量请求,耗尽目标系统的网络带宽、CPU、内存或其他资源,导致合法用户无法正常访问服务。

2. DDoS 攻击类型

  • 网络层攻击:如 SYN Flood、UDP Flood、ICMP Flood 等,消耗目标网络带宽和系统资源
  • 应用层攻击:如 HTTP Flood、SQL 注入攻击等,针对应用程序的漏洞发起攻击
  • 数据库层攻击:针对 PostgreSQL 数据库的攻击,如大量连接请求、复杂查询攻击等

3. PostgreSQL 面临的 DDoS 威胁

  • 连接耗尽攻击:攻击者发起大量连接请求,耗尽 PostgreSQL 的 max_connections 限制
  • 查询风暴攻击:攻击者发送大量复杂查询,消耗数据库 CPU 和内存资源
  • WAL 日志攻击:攻击者通过大量写操作,导致 WAL 日志快速增长,耗尽磁盘空间
  • 复制延迟攻击:针对主从复制架构,通过大量写操作导致从库延迟增大

防范措施

1. 网络层防范

1.1 配置防火墙规则

bash
# 使用 iptables 限制每个 IP 的连接数
iptables -A INPUT -p tcp --dport 5432 -m connlimit --connlimit-above 10 -j DROP

# 限制新连接的速率
iptables -A INPUT -p tcp --dport 5432 -m limit --limit 10/min --limit-burst 20 -j ACCEPT

# 只允许特定 IP 访问 PostgreSQL
iptables -A INPUT -p tcp --dport 5432 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 5432 -j DROP

1.2 使用 CDN 和 WAF

  • CDN(内容分发网络):分散流量,过滤恶意请求
  • WAF(Web 应用防火墙):检测和拦截应用层攻击
  • DDoS 清洗服务:专业的 DDoS 防护服务,清洗恶意流量

2. 操作系统层防范

2.1 优化 TCP/IP 内核参数

bash
# /etc/sysctl.conf
# 启用 SYN cookies,防止 SYN Flood 攻击
net.ipv4.tcp_syncookies = 1

# 减小 SYN_RECV 状态的超时时间
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2

# 增大 TCP 连接跟踪表大小
net.netfilter.nf_conntrack_max = 1000000

# 减小连接跟踪超时时间
net.netfilter.nf_conntrack_tcp_timeout_established = 3600

# 应用配置
sysctl -p

2.2 限制进程资源

bash
# 使用 ulimit 限制 PostgreSQL 进程的资源
# /etc/security/limits.conf
postgres soft nofile 65535
postgres hard nofile 65535
postgres soft nproc 1024
postgres hard nproc 2048

3. PostgreSQL 配置优化

3.1 连接限制配置

sql
-- postgresql.conf
-- 设置最大连接数(根据实际硬件配置调整)
max_connections = 100

-- 设置超级用户预留连接数
superuser_reserved_connections = 10

-- 设置连接超时时间
connect_timeout = 10

-- 设置空闲连接超时时间
idle_in_transaction_session_timeout = 300000

-- 设置语句超时时间
statement_timeout = 30000

3.2 资源限制配置

sql
-- postgresql.conf
-- 设置每个连接的内存限制
work_mem = 4MB
maintenance_work_mem = 64MB

-- 设置共享内存
shared_buffers = 2GB

-- 设置 WAL 相关参数
wal_buffers = 16MB
checkpoint_timeout = 30min
checkpoint_completion_target = 0.9

-- 设置自动清理参数
autovacuum = on
autovacuum_max_workers = 3
autovacuum_naptime = 1min

3.3 使用连接池

  • PgBouncer:轻量级连接池,支持三种模式:会话模式、事务模式、语句模式
  • PGPool-II:功能更丰富的连接池,支持读写分离、负载均衡等
ini
# PgBouncer 配置示例
[databases]
* = host=localhost port=5432

[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 20
min_pool_size = 5
reserve_pool_size = 10
reserve_pool_timeout = 5

4. 应用层防范

4.1 实现请求限流

java
// Spring Boot 中使用 Redis 实现请求限流
@Aspect
@Component
public class RateLimitAspect {
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    @Before("@annotation(rateLimit)")
    public void before(JoinPoint joinPoint, RateLimit rateLimit) throws Exception {
        // 获取客户端 IP
        String ip = RequestContextHolder.currentRequestAttributes().getSessionId();
        // 生成限流 key
        String key = "rate_limit:" + ip;
        // 获取当前计数
        String count = redisTemplate.opsForValue().get(key);
        if (count != null && Integer.parseInt(count) >= rateLimit.limit()) {
            throw new Exception("请求过于频繁,请稍后再试");
        }
        // 自增计数
        redisTemplate.opsForValue().increment(key, 1);
        // 设置过期时间
        redisTemplate.expire(key, rateLimit.seconds(), TimeUnit.SECONDS);
    }
}

4.2 实现请求验证

  • 实现验证码机制,防止自动化攻击
  • 实现 API 密钥认证,限制合法请求
  • 实现请求签名验证,防止请求篡改

5. 监控和告警

5.1 配置 PostgreSQL 日志

sql
-- postgresql.conf
-- 设置日志级别
log_min_messages = warning
log_min_error_statement = error

-- 设置日志格式
log_destination = 'stderr'
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d
log_rotation_size = 100MB

-- 记录慢查询
log_min_duration_statement = 1000

-- 记录连接信息
log_connections = on
log_disconnections = on

5.2 使用 Prometheus + Grafana 监控

yaml
# prometheus.yml 配置示例
scrape_configs:
  - job_name: 'postgresql'
    static_configs:
      - targets: ['localhost:9187']  # postgres_exporter 地址
    metrics_path: '/metrics'
    scrape_interval: 15s

5.3 关键指标监控

  • 连接数:监控当前连接数、最大连接数、连接增长率
  • CPU 使用率:监控数据库进程的 CPU 使用率
  • 内存使用率:监控数据库进程的内存使用率
  • 磁盘 I/O:监控磁盘读写速率、IOPS
  • 查询性能:监控慢查询数量、平均查询时间
  • WAL 日志:监控 WAL 日志生成速率、归档状态

6. 应急响应

6.1 DDoS 攻击检测

  • 异常流量检测:通过网络设备监控异常流量
  • 连接数突增:监控 PostgreSQL 连接数突增情况
  • CPU/内存突增:监控数据库服务器 CPU/内存突增情况
  • 慢查询突增:监控慢查询数量突增情况

6.2 应急响应步骤

  1. 确认攻击类型:分析日志,确认 DDoS 攻击类型
  2. 启用防护措施
    • 启用防火墙规则,限制攻击 IP
    • 调整 PostgreSQL 配置,如增大 max_connections、设置连接超时
    • 启用连接池,缓解连接压力
  3. 隔离攻击源
    • 使用 iptables 或防火墙封禁攻击 IP
    • 联系 ISP 或云服务商,请求 DDoS 清洗
  4. 恢复服务
    • 清理无效连接
    • 优化查询性能
    • 恢复正常配置
  5. 事后分析
    • 分析攻击原因和防护效果
    • 更新防护策略
    • 完善监控和告警机制

最佳实践

1. 生产环境配置建议

  • 分层防护:采用网络层、操作系统层、数据库层、应用层的分层防护策略
  • 定期演练:定期进行 DDoS 攻击演练,测试防护效果
  • 备份数据:定期备份数据库数据,确保数据安全
  • 更新补丁:及时更新 PostgreSQL 和操作系统补丁,修复安全漏洞
  • 权限管理:严格控制数据库用户权限,实现最小权限原则

2. 性能优化建议

  • 合理设置连接数:根据硬件配置和业务需求,合理设置 max_connections
  • 使用连接池:使用 PgBouncer 或 PGPool-II 等连接池,减少连接开销
  • 优化查询:对慢查询进行优化,减少数据库资源消耗
  • 配置适当的 work_mem:根据查询复杂度和并发情况,配置适当的 work_mem

3. 安全性建议

  • 使用 SSL/TLS:配置 PostgreSQL 使用 SSL/TLS 加密连接
  • 限制访问 IP:在 pg_hba.conf 中限制允许访问的 IP 地址
  • 使用强密码:配置复杂的密码策略,定期更换密码
  • 启用审计日志:使用 pgaudit 等工具,记录数据库操作日志
  • 定期安全审计:定期进行数据库安全审计,发现潜在安全隐患

常见问题(FAQ)

Q1:如何处理连接耗尽攻击?

A1:可以采用以下几种方式处理:

  1. 增大 max_connections:临时增大 max_connections 参数,但会增加内存消耗
  2. 使用连接池:使用 PgBouncer 或 PGPool-II 等连接池,减少实际连接数
  3. 配置防火墙规则:使用 iptables 限制每个 IP 的连接数
  4. 设置连接超时:配置 connect_timeout 和 idle_in_transaction_session_timeout 参数,及时释放空闲连接
  5. 使用超级用户预留连接:确保超级用户始终能连接到数据库,进行管理操作

Q2:如何处理查询风暴攻击?

A2:可以采用以下几种方式处理:

  1. 设置语句超时:配置 statement_timeout 参数,限制查询执行时间
  2. 优化慢查询:对慢查询进行优化,如添加索引、重写查询语句
  3. 使用资源组:PostgreSQL 10+ 支持资源组,可以限制每个用户或角色的资源使用
  4. 配置 connection_limits:在 pg_hba.conf 中限制每个 IP 的连接数
  5. 使用查询缓存:对热点数据实现应用层缓存,减少数据库查询压力

Q3:如何监控 DDoS 攻击?

A3:可以采用以下几种方式监控:

  1. 使用 PostgreSQL 日志:监控连接数、慢查询数量等指标
  2. 使用 Prometheus + Grafana:配置监控面板,监控关键指标
  3. 使用网络监控工具:如 Zabbix、Nagios 等,监控网络流量和系统资源
  4. 使用云服务商的监控服务:如 AWS CloudWatch、阿里云监控等
  5. 配置告警规则:当关键指标超过阈值时,发送告警通知

Q4:如何配置 PgBouncer 防御 DDoS 攻击?

A4:可以采用以下配置:

ini
# PgBouncer 配置示例
[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction
max_client_conn = 10000  # 允许大量客户端连接
default_pool_size = 50   # 限制到数据库的实际连接数
min_pool_size = 10
reserve_pool_size = 20
reserve_pool_timeout = 5
server_reset_query = DISCARD ALL
server_check_delay = 30
server_check_query = select 1

Q5:如何区分合法流量和 DDoS 攻击流量?

A5:可以从以下几个方面区分:

  1. 流量特征:DDoS 攻击流量通常具有突发、持续时间长、来源 IP 分散等特征
  2. 请求特征:攻击请求通常具有相似的模式,如相同的 User-Agent、相同的请求路径等
  3. 资源消耗:攻击流量会导致 CPU、内存、带宽等资源急剧消耗
  4. 连接模式:攻击连接通常具有短连接、高频率、无实际业务逻辑等特征
  5. 业务逻辑:攻击请求通常不符合正常的业务逻辑,如大量重复请求、无效参数等

Q6:如何应对大流量 DDoS 攻击?

A6:可以采用以下几种方式:

  1. 使用专业的 DDoS 防护服务:如 Cloudflare、Akamai 等,提供大流量清洗能力
  2. 联系 ISP 或云服务商:请求协助,对攻击流量进行清洗或黑洞路由
  3. 启用弹性伸缩:自动扩容服务器资源,应对流量峰值
  4. 实现流量分流:将流量分散到多个服务器或数据中心
  5. 优化应用架构:采用微服务架构、CDN 加速等,提高系统的抗攻击能力