Edgeweir
使用指南

封禁

按 IP 地址或 CIDR 临时拦截客户端。封禁经节点通道直接下发,数秒内生效,不产生配置版本。

概念

术语定义
封禁一个 IP 地址或 CIDR,到期前对应请求被拦截。
范围网站:只作用于一个网站。全局:作用于所有集群的全部网站,并由节点在内核丢包(见内核封禁)。API 中分别为 site 与 platform。
来源手动:在 封禁 页或经 API 创建。自动:节点按触发条件自行产生并上报。
到期1 分钟到 7 天。长期拦截用 IP 名单。

封禁地址

  1. 打开 封禁,点击「新建封禁」。

  2. 选择「范围」:「网站」或「全局」。

  3. 范围为「网站」时,在「网站」中选择网站;网站较多时先在「搜索网站」中输入名称或域名。

  4. 填写「IP 或 CIDR」,例如 203.0.113.7 或 198.51.100.0/24。

  5. 选择「原因」与「时长」(1 小时、6 小时、1 天、3 天、7 天),点击「封禁」。

  6. 验证:从被封禁的地址请求该网站:

    curl -sI -H 'Host: www.example.com' http://<节点 IP>/

    返回 403,响应头含 X-Edgeweir-Error: ip-banned。网站封禁不影响同一地址访问其他网站。

解封:点击该行的「解封」并确认。节点在数秒内移除该封禁。手动与自动封禁都可解封。

不必重新输入:访问日志、统计中的热门 IP、网站「安全」页签的 Top IP 与自动封禁事件,在行右侧的「⋯」中提供「封禁 IP」,对话框已填好网站与地址(「范围」可改为「全局」),按 ⌘K / Ctrl+K 选择「封禁 IP…」打开同一对话框(在网站页面时预填该网站)。封禁后提示中的「查看封禁」打开列表。链接 /bans?site=<网站 ID>&ip=<地址> 打开同样预填的对话框,列表只显示与该地址重叠的封禁(地址旁的 × 清除)。

列表只显示有效的封禁(未到期、未解封),按创建时间倒序,可按范围、网站与来源筛选:

列内容
地址规范化的 CIDR;有节点未能保存该封禁时显示「N 个节点未生效」
网站网站名称;全局封禁显示「全局」
原因封禁原因
来源「手动」及操作者;「自动」及来源节点与触发条件(指标、观测值 / 阈值、窗口秒数);未下发的自动封禁另标「未共享」
到期剩余时间;悬停显示到期时间

规则

项目行为
地址IPv4 / IPv6 地址或 CIDR;单个地址视为 /32 或 /128;清除主机位,IPv6 小写并压缩;::ffff:a.b.c.d 按对应的 IPv4 处理;拒绝前导零写法和 zone ID
前缀下限IPv4 /16,IPv6 /48
到期1 分钟到 7 天(界面提供 1 小时到 7 天的选项);节点按到期时间自动失效,控制台在到期一小时后删除记录
原因手动:滥用、攻击、扫描、垃圾请求、其他;自动:单 IP 请求过快
再次封禁同一地址的全局封禁、或同一网站与地址的网站封禁,只有一条有效的手动封禁;再次封禁更新原因与到期时间,不增加数量
受保护地址网站封禁不能包含该网站所在集群的节点地址,全局封禁不能包含任何节点地址;封禁也不能包含回环地址(127.0.0.0/8、::1)与未指定地址(0.0.0.0/8、::),不能与放行名单重叠
执行位置边缘层确定网站之后、规则之前:先查全局封禁,再查网站封禁;放行名单中的地址不受封禁
下发不产生配置版本、不经配置金丝雀、节点不重载
审计ban.create、ban.update(再次封禁)、ban.delete;自动封禁不写审计

数量上限

上限计数设置
手动封禁上限有效的手动封禁,全局与网站封禁合计防护设置 → 封禁 → 手动封禁上限;默认 10000,范围 100–100000
自动封禁每个集群的有效自动封禁固定 10000 条;超出时最早的自动封禁失效

自动封禁不计入手动封禁上限。达到上限时新建封禁返回 BAN_PLATFORM_LIMIT(「手动封禁已达上限(N 条)」);再次封禁仍有效的地址不受上限限制。

自动封禁

节点按触发条件(CC 防护的「单 IP QPS」,见挑战与 CC 防护)自行封禁:IPv4 封单个地址,IPv6 封所在的 /64(一个客户端通常持有整个 /64);回环地址从不封禁。封禁立即在该节点生效,并每 5 秒批量上报控制台。

项目行为
共享防护设置 → 封禁 → 集群内共享自动封禁,默认开启:开启时下发到同集群的全部节点;关闭时只保存供查看,列表标记「未共享」。修改只影响之后新增的自动封禁
合并同一节点、网站与地址只保存一条;再次上报时延长到期时间
校验网站须属于该节点所在的集群;只接受单个地址;到期最长为创建后 7 天;受保护地址不保存
解封与手动封禁相同,点击该行的「解封」;未共享的自动封禁由产生它的节点在数秒内删除(不支持的旧版节点要到期才失效),该节点之后再次自行封禁同一地址不受影响

节点

项目行为
节点能力执行封禁需要 bans-v1;未上报该能力的旧版节点照常服务,不执行封禁
同步节点只取得本集群的封禁与全局封禁。节点保存已应用的序号,只拉取之后的变化;首次连接或控制台数据库恢复后取得完整快照。节点把封禁落盘,重启后先装入再连接控制台
容量节点参数 --ban-capacity(默认 100000 条)与 --ban-dict-mb(默认 32 MiB)。空间不足时先淘汰最早的自动封禁
未生效手动封禁写不下时不会静默丢弃:节点上报未生效的封禁,列表显示「N 个节点未生效」(只计在线节点),节点每分钟重试
状态节点每次心跳上报封禁状态:已应用序号、条目数、容量、未生效的封禁、内核条目数与淘汰的自动封禁数。经 GET /api/v1/nodes/{id} 的 banStatus 读取

内核封禁

全局封禁同时由节点 agent 写入 nftables,在内核丢弃被封地址的入站数据包,被封客户端连 TCP 与 TLS 握手都无法完成。网站封禁只在 HTTP 层执行。L4 应用 只受内核封禁约束:网站封禁与 HTTP 层的封禁不作用于四层流量。

项目行为
条件agent 具备 CAP_NET_ADMIN,主机有 nft。agent 启动时试建表,成功才上报能力 kernel-ban-v1;失败时只做 HTTP 层封禁并记录日志
表agent 只管理自己的表 inet edgeweir(集合 ban4、ban6、allow4、allow6,input 链),启动时清掉残留,退出时删除
永不封禁控制台地址、节点自身地址、回环地址、放行名单
出站连接被封地址的入站包全部丢弃,节点也无法与该地址建立连接(例如该地址恰好是源站)

默认的 systemd 单元与节点镜像不授予 CAP_NET_ADMIN,需要时按下列步骤启用。

systemd 节点

  1. 安装 nftables:

    节点
    sudo apt-get install -y nftables    # Debian、Ubuntu
    sudo dnf install -y nftables        # RHEL 系
  2. 创建 drop-in,在已有的 CAP_NET_BIND_SERVICE 之外增加 CAP_NET_ADMIN:

    /etc/systemd/system/edgeweir-node.service.d/kernel-ban.conf
    [Service]
    AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_ADMIN
    CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_NET_ADMIN
  3. 重新加载并重启:

    节点
    sudo systemctl daemon-reload
    sudo systemctl restart edgeweir-node
  4. 验证:sudo nft list table inet edgeweir 列出集合 ban4 与 ban6;GET /api/v1/nodes/{id} 的 supportedFeatures 含 kernel-ban-v1。

环境能力同样被 agent 启动的 OpenResty 进程继承。

容器节点

  1. 以构建参数 NFT_CAPABILITY=true 构建节点镜像。镜像为 nft 设置文件能力,agent 仍以非 root 用户运行:

    edgeweir-node 源码目录
    docker build --build-arg NFT_CAPABILITY=true -t edgeweir-node:nft .
  2. 运行容器时加 --cap-add NET_ADMIN(Compose:cap_add: [NET_ADMIN])。

  3. 验证:docker exec <容器> nft list table inet edgeweir 列出集合 ban4 与 ban6;GET /api/v1/nodes/{id} 的 supportedFeatures 含 kernel-ban-v1。

节点前的负载均衡

集群的访客 IP 设置决定 HTTP / HTTPS 监听的访客地址(ip.src):

访客 IPHTTP 层封禁、CC、规则、日志内核封禁
直连(默认)TCP 对端;节点前有负载均衡时为负载均衡器的地址,自动封禁会把它整个封掉TCP 对端
PROXY protocolPROXY 头中的访客地址仍只匹配 TCP 对端(负载均衡器),对访客地址的封禁不在内核生效
可信代理报头可信代理报头中的访客地址;可信 CIDR 内的地址永不封禁,也不计入 CC 单 IP 计数同上,只匹配 TCP 对端

后两种模式下,「封禁」页顶部显示「集群 {clusters} 的访客 IP 来自代理:内核封禁只匹配 TCP 对端」。直连模式下节点前仍有负载均衡时,把负载均衡器的地址加入放行名单:它们不会被封禁,也不会在内核被丢包。

L4 应用在自己的监听上接受 PROXY 协议,与 HTTP / HTTPS 监听的访客 IP 设置无关。

API

路径位于 /api/v1 下。

过程端点说明
bans.listGET /bans有效的封禁;查询参数 scope(site / platform)、siteId、source(manual / auto)、address(IP 或 CIDR:覆盖它或在它之内的封禁)、page、pageSize
bans.createPOST /bansscope 为 site 时必须带 siteId,为 platform 时不能带;另需 cidr、reason、durationSeconds
bans.deleteDELETE /bans/{id}解封手动或自动封禁

只读 AccessKey 只能调用 bans.list;服务账号不能调用封禁接口(403 SERVICE_ACCOUNT_FORBIDDEN)。字段与示例见 API 与端点。

故障排查

现象原因处理
「IP 地址或 CIDR 无效」不是 IP 地址或 CIDR,或含前导零、zone ID改为标准写法
「前缀太短,最短为 /16」(或 /48)前缀短于下限拆成更长的前缀,或改用 IP 名单
「封禁时长须在 1 分钟到 7 天之间」到期时间超出范围长期拦截改用 IP 名单
「封禁范围包含受保护的地址 …」封禁包含节点地址、回环或未指定地址,或与放行名单重叠缩小范围
「手动封禁已达上限(N 条)」达到手动封禁上限解封不再需要的地址,或调大 防护设置 → 封禁 → 手动封禁上限
「请选择网站」范围为「网站」但未选择网站选择网站,或把范围改为「全局」
「封禁不存在或已失效」封禁已到期或已解封刷新列表
列表显示「N 个节点未生效」节点封禁容量或内存不足调大节点的 --ban-capacity、--ban-dict-mb,或减少封禁
封禁后仍能访问节点缺少 bans-v1;地址在放行名单中升级节点;检查放行名单
全局封禁没有在内核生效节点缺少 kernel-ban-v1按内核封禁授予 CAP_NET_ADMIN 并安装 nftables
在 GitHub 上编辑

本页目录