Skip to main content
Arc 的安全能力分为三层独立体系,每层都在网络栈不同位置工作,可独立做丢弃或节流。

XDP 与 eBPF 包过滤

Arc 的内核程序(arc-xdp)挂载在网卡 XDP hook 点,在内核 TCP 栈处理之前就能拦截每个入站包。整个处理流程都在内核态完成,不需要每包切回用户态。

检查流程

每个包都会经过以下步骤:
  1. 解析以太网头和可选 VLAN 头
  2. 解析 IPv4/IPv6 并提取源 IP
  3. 白名单:命中即 XDP_PASS
  4. 黑名单:命中且未过期即 XDP_DROP
  5. TCP 包继续做:
    • SYN flood 评分(按 IP 指数衰减)
    • SYN proxy(返回 syncookie SYN-ACK,并校验 ACK)
    • RST 校验(序列号窗口)
    • ACK flood 评分
  6. UDP 包做按端口 PPS/BPS 限速

BPF Map

所有 map 默认 pin 到 /sys/fs/bpf/arc/

功能开关

通过 control plane 的 POST /v1/xdp/config 在运行时开关 XDP 功能:

动态阈值计算

用户态管理器每 100ms 运行一次后台任务,用 Welford 在线算法计算 SYN 速率的均值和标准差,动态阈值计算公式为:
当前 PPS 超过阈值时会自动进入 defense mode。

黑白名单管理

可通过 网关控制面 API 参考 在运行时管理 XDP 黑白名单:

Kubernetes 说明

XDP 需要 NET_ADMINSYS_ADMINprivileged: true。多数托管 Kubernetes 平台不支持这组能力。部署清单中仅以注释形式保留示例。

速率限制

Arc 内置两套独立限流机制。

路由级限流(GCRA)

最常用的是直接在路由上配置:
该模式使用单层 GCRA 令牌桶,状态存储在 worker 本地 HashMap,不会产生跨线程协调。

两级全局限流

跨节点统一限流由 GlobalRateLimiter 实现两级架构: L1(worker 本地): 每个 worker 维护按 key 的令牌桶 HashMap,热路径无锁,try_acquire 每请求内联执行。
L2(Redis 后端): 独立后端线程通过 Lua 脚本访问 Redis,做集群级令牌一致性。
熔断器: Redis 不可达时自动 open,worker 退化为 L1-only,默认 open 窗口 500ms。
worker 热路径:
  1. 从后端最多拉取 8 条待处理补令牌结果
  2. 在本地 l1 HashMap 查找或创建 key 对应 Entry
  3. 后端健康且全局令牌足够时消费 1 个全局令牌
  4. 后端健康但全局令牌耗尽时返回 429
  5. 后端故障时使用本地 L1 令牌桶
  6. 当令牌低于低水位时异步发起补充请求
这样 worker 不会因为等 Redis 阻塞。

L7 防护

在正式进入限流前,Arc 会对每条连接执行三类 L7 防护。

SlowlorisGuard

用于识别 Slowloris 攻击(极慢发送请求头,占满连接资源)。

TlsFloodGuard

按 IP 限制每秒 TLS 握手速率。状态存储在固定大小 AtomicU64 数组中,每个槽编码 (second << 32) | count。当当前秒计数超过 max_handshakes_per_ip_per_sec 时拒绝连接。

H2StreamFloodGuard

面向 HTTP/2 的 per-connection 防护,用于处理 stream flood 和 RST flood。 计数窗口按秒重置,实际 GOAWAY 发送由 worker 负责。

请求超时

Arc 以纳秒精度跟踪请求 deadline,不额外分配计时器对象。每个请求都会应用四类边界: 每个阶段会同时受“阶段超时、单次尝试超时、总超时”三重约束,避免局部超时突破整体预算。 示例:

故障排查

XDP 依赖网卡驱动支持。可先用 ip link show <iface> 检查。系统会按 native → generic → skb 兜底尝试;全部失败时网关会在无 XDP 模式继续启动并记录告警。可通过 GET /v1/xdp/status 确认状态。
先查看黑名单:curl http://localhost:22100/v1/xdp/blacklist。流量突刺下动态阈值可能误判,可用 DELETE /v1/xdp/blacklist 解封,并通过 POST /v1/xdp/config 提高 sigma_multiplier(如 {"sigma_multiplier": 5.0})来放宽阈值。配合 /metricsarc_xdp_blacklisted_total 一起观察。
先确认 control_plane.enabled: true,且 observability.metrics_bind 可访问。路由级限流只依赖本地 GCRA,不需要 Redis。集群级限流需要 Redis 可达且编译了 redis feature。可查看 arc_ratelimit_rejected_total 判断限流是否真的触发。
该防护会对“请求头长期不完整”的连接触发。可以适当提高相关阈值,或在内网监听器不启用这类 L7 防护。
/metricsarc_ratelimit_circuit_open1,表示 Redis 后端不可达,Arc 已自动退化为 L1(每 worker)限流。请检查 Redis 连通性,并通过 control plane 查看熔断器的 open_until_ns