Skip to content

Egress 出口限速

rho-aias 内置基于 TC(Traffic Control)eBPF 的出口流量限速模块,通过令牌桶算法(Token Bucket)在网卡驱动层面控制出口速率,支持按目标 IP 维度进行 per-flow 限速,并提供完整的丢包日志记录与分析能力。

概述

核心特性

  • TC eBPF 限速:基于 Linux TC(Traffic Control)框架挂载 TBPF 程序,在网卡出口处执行限速
  • 令牌桶算法:经典 Token Bucket 实现,支持平滑限速和可控突发
  • Per-Flow 控制:按目标 IP(dst_ip)维度独立计量和控制速率
  • 零拷贝处理:数据包在内核态完成限速决策,无用户态开销
  • 丢包日志:可选的丢包事件上报与持久化,支持事后分析
  • 动态配置:支持运行时调整限速参数,无需重启

配置

config.yml 中配置 Egress 限速:

yaml
egress_limit:
  enabled: false                    # 总开关(默认关闭)
  rate_mbps: 1.0                    # 限速速率(Mbps),每秒允许通过的流量
  burst_bytes: 250000               # 突发上限(Bytes),约 250KB,允许短暂突发的数据量
  drop_log_enabled: false           # 丢包日志开关
  drop_log_sample_rate: 1           # 丢包日志采样率(1=全部记录)

参数说明

参数类型默认值说明
enabledboolfalse是否启用 Egress 限速
rate_mbpsfloat641.0限速速率(Mbps),每秒允许通过的流量大小
burst_bytesuint64250000突发上限(Bytes),令牌桶容量,允许短暂突发的数据量
drop_log_enabledboolfalse是否记录被丢弃的包信息
drop_log_sample_rateuint321丢包日志采样率,N 表示每 N 个包记录 1 个

限速原理

Egress 限速采用经典的令牌桶算法

令牌桶工作流程:

1. 以固定速率(rate_mbps)向桶中添加令牌
   - rate_mbps = 1 Mbps ≈ 125,000 bytes/s
   - 每秒向桶中加入 125,000 个令牌(每字节一个令牌)

2. 桶有最大容量(burst_bytes)
   - burst_bytes = 250,000 bytes ≈ 2 秒突发量
   - 桶满后多余的令牌被丢弃

3. 数据包发送时检查令牌
   - 包大小 ≤ 当前令牌数 → 消耗对应令牌,放行
   - 包大小 > 当前令牌数 → 丢弃(或记录日志)

典型限速效果

rate_mbpsburst_bytes平均速率最大突发适用场景
1.0 Mbps250 KB~125 KB/s~2 秒突发防止对外 DDoS 回传
10 Mbps2.5 MB~1.25 MB/s~2 秒突发一般业务限制
100 Mbps25 MB~12.5 MB/s~2 秒突发高带宽控制

丢包日志

当启用 drop_log_enabled 后,被令牌桶丢弃的数据包信息会通过 RingBuf 上报到用户态并持久化存储。

日志字段

字段类型说明
dst_ipstring被限速的目标 IP 地址
pkt_lenuint32被丢弃的数据包大小(字节)
tokensuint64丢弃时刻桶中剩余的令牌数
rate_bytesuint64当前配置的速率(bytes/sec)
timestampstring丢弃时间戳

日志查询 API

bash
# 查询某天的丢包记录(需要 egresslog:read 权限)
GET /api/egresslog/records?date=2026-04-17&start_hour=0&end_hour=23&page=1&page_size=20&dst_ip=

查询参数:

参数类型说明默认值
datestring查询日期(YYYY-MM-DD)今天
start_hourint起始小时(0-23)0
end_hourint结束小时(0-23)23
pageint页码1
page_sizeint每页条数20
dst_ipstring按目标 IP 过滤全部

响应示例:

json
{
  "records": [
    {
      "dst_ip": "203.0.113.50",
      "pkt_len": 1400,
      "tokens": 0,
      "rate_bytes": 125000,
      "timestamp": "2026-04-17T10:30:45.123Z"
    }
  ],
  "total": 150,
  "page": 1,
  "page_size": 20,
  "total_pages": 8
}

动态配置支持

Egress 限速模块支持完整的运行时动态配置,可通过 API 热更新所有参数:

bash
# 启用 Egress 限速并设置参数
curl -X POST "http://localhost:8081/api/dynamic-config/egress_limit" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "rate_mbps": 10.0,
    "burst_bytes": 2500000,
    "drop_log_enabled": true,
    "drop_log_sample_rate": 10
  }'

启动时也会从数据库恢复上次保存的动态配置(如果有)。

典型应用场景

1. 防 DDoS 回传放大

当服务器被利用作为 DDoS 反射放大源时,Egress 限速可以限制出站带宽:

yaml
egress_limit:
  enabled: true
  rate_mbps: 10.0       # 限制出口总带宽为 10Mbps
  burst_bytes: 2500000  # 允许 2 秒突发
  drop_log_enabled: true  # 记录丢包以便分析

2. 防止数据外泄

限制敏感服务器的出口带宽,防止大量数据外泄:

yaml
egress_limit:
  enabled: true
  rate_mbps: 1.0        # 严格限制 1Mbps
  burst_bytes: 250000   # 较小突发
  drop_log_enabled: true

3. 流量整形

配合入口防护实现双向流量控制,保障服务质量:

yaml
egress_limit:
  enabled: true
  rate_mbps: 100.0      # 100Mbps 出口限制
  burst_bytes: 25000000 # 25MB 突发缓冲

与其他模块的关系

  • 入站防护由 XDP 程序负责(WAF、异常检测、FailGuard 等)
  • 出站防护由 TC eBPF 负责(Egress 限速)
  • 两者共享同一套动态配置系统和数据库

注意事项

性能影响

  • TC eBPF 程序在每个出口数据包上执行令牌桶计算
  • 正常放行的数据包开销极小(仅需原子操作减令牌)
  • 启用丢包日志会带来额外的 RingBuf 写入开销
  • 建议在生产环境评估后决定是否开启 drop_log_enabled

突发容量建议

  • burst_bytes 建议设置为至少 2 × rate_mbps × 125000(即 2 秒的流量)
  • 过小的 burst 会导致 TCP 连接吞吐量下降
  • 过大的 burst 会失去限速意义

权限要求

Egress 限速需要在网卡上附加 TC qdisc 和 TBPF 程序,需要 CAP_NET_ADMIN 权限。Docker 部署时确保包含此能力。 ::