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=全部记录)参数说明
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | bool | false | 是否启用 Egress 限速 |
rate_mbps | float64 | 1.0 | 限速速率(Mbps),每秒允许通过的流量大小 |
burst_bytes | uint64 | 250000 | 突发上限(Bytes),令牌桶容量,允许短暂突发的数据量 |
drop_log_enabled | bool | false | 是否记录被丢弃的包信息 |
drop_log_sample_rate | uint32 | 1 | 丢包日志采样率,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_mbps | burst_bytes | 平均速率 | 最大突发 | 适用场景 |
|---|---|---|---|---|
| 1.0 Mbps | 250 KB | ~125 KB/s | ~2 秒突发 | 防止对外 DDoS 回传 |
| 10 Mbps | 2.5 MB | ~1.25 MB/s | ~2 秒突发 | 一般业务限制 |
| 100 Mbps | 25 MB | ~12.5 MB/s | ~2 秒突发 | 高带宽控制 |
丢包日志
当启用 drop_log_enabled 后,被令牌桶丢弃的数据包信息会通过 RingBuf 上报到用户态并持久化存储。
日志字段
| 字段 | 类型 | 说明 |
|---|---|---|
dst_ip | string | 被限速的目标 IP 地址 |
pkt_len | uint32 | 被丢弃的数据包大小(字节) |
tokens | uint64 | 丢弃时刻桶中剩余的令牌数 |
rate_bytes | uint64 | 当前配置的速率(bytes/sec) |
timestamp | string | 丢弃时间戳 |
日志查询 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=查询参数:
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
date | string | 查询日期(YYYY-MM-DD) | 今天 |
start_hour | int | 起始小时(0-23) | 0 |
end_hour | int | 结束小时(0-23) | 23 |
page | int | 页码 | 1 |
page_size | int | 每页条数 | 20 |
dst_ip | string | 按目标 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: true3. 流量整形
配合入口防护实现双向流量控制,保障服务质量:
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 部署时确保包含此能力。 ::