Skip to content
marvinli001Public

About

开源自托管 CDN / WAF / 边缘调度控制面:缓存、HTTPS、OWASP CRS、CC 防护、四层转发、智能 DNS 调度,单进程单镜像,无回连无遥测。

Topics

Resources

Contributing

Security policy

Stars

5 stars

Watchers

0 watching

Forks

Latest commit

 

History

1,623 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Edgeweir

简体中文 | English

CI Docs License: AGPL-3.0-only

加入 Telegram 交流群

自托管的 CDN / WAF / 边缘调度控制平面,面向个人自用:一个运营者账户统一管理边缘节点、源站池、缓存、HTTPS、四层转发、访问策略与 DNS 调度。边缘节点见 edgeweir-node。

文档:https://marvinli001.github.io/edgeweir/zh/

功能

领域 能力
集群与账户 节点组、区域、配置金丝雀、2FA / Passkey、服务账号、审计日志
网站管理 网站标签(按任一 / 全部标签筛选、改名合并、⌘K 搜索)、批量启停 / 清除缓存 / 加减标签 / 删除、把一个网站的设置(15 个部分)预览后复制到其他网站、克隆网站
源站与缓存 源站池与源站组、主动与被动健康检查、会话保持、回源 TLS 校验、S3 签名回源、HTTP/2 回源与 gRPC、WebSocket、表达式缓存规则与浏览器 TTL、缓存键、切片、按 URL / 目录 / Host / Cache-Tag 刷新、按设备与站点地图预热、带密钥的 PURGE 方法、可按集群与节点设置的缓存区、缓存带 Set-Cookie 的响应(Cookie 只发给回源的那次请求)、回源尝试次数与状态码重试、请求体上限、字符编码、对象存储预设、按状态码与 4xx / 5xx 的错误页(HTML 或跳转)、维护模式、WebP / AVIF 格式转换(按 Accept 缓存变体,统计节省的字节数)
四层转发 按集群的 TCP / UDP 端口池;L4 应用:权重与备用源站、被动健康检查、连接与空闲超时、向源站发送 PROXY protocol v1 / v2 与接受 PROXY protocol、端口段与同号源站端口、TCP 的 TLS 卸载、放行 / 拦截名单、每节点并发与新建连接上限;与网站共用 DNS 调度(CNAME、解析线路、备用节点组);按分钟统计连接、拒绝、并发峰值与流量;增删端口时已有连接不断开
域名 精确、泛域名、任意层级后缀与正则域名,国际化域名(Punycode);未知域名与节点 IP 访问的处理(平台页、关闭连接、默认网站)与扫描封禁;可重新生成或自定义的 CNAME 前缀
证书与协议 证书上传、ACME HTTP-01 / DNS-01 签发与续期(Let's Encrypt、ZeroSSL、Google Trust Services 或自定义 ACME 目录,ECDSA / RSA 密钥,ACME 账户列表)、HTTPS、每个网站最多 4 张证书(按 SNI 与客户端能力选择)、客户端证书(双向 TLS)、集群内共享票据密钥的 TLS 会话复用、HSTS、HTTP/2、HTTP/3;80 / 443 之外的监听端口与网站绑定端口、跳转状态码与端口;访客 IP 来自 PROXY protocol 或可信代理报头;Zstandard、Brotli、Gzip 压缩(Gzip 级别、最大压缩长度)
访问策略 IP 名单(全局允许 / 拦截,网站可选本站拦截 / 放行名单)、本地 GeoIP、分阶段规则与内置函数(Cookie、查询参数与请求头按名取值,编码与哈希函数,请求头 / 响应头 / 查询参数的表达式值,含请求体表单与 JSON 字段)、WAF(封禁、自定义响应、断开连接、跳过,CRS 按路径排除与覆盖)、限速与超额封禁、动态重定向与改写、批量重定向、请求头与响应头变换、源站覆盖与压缩规则、按请求覆盖网站设置;访问鉴权(Basic、转发鉴权、URL 鉴权 A–D 与控制台生成签名 URL,缓存命中同样鉴权);访问控制(地区、防盗链、UA 名单、边缘应答 CORS 预检、WebSocket 来源、安全响应头)与 IP 检查;挑战放行已验证的搜索引擎爬虫,挑战失败封禁;秒级下发的 IP 封禁,全局封禁可由 nftables 在内核丢包
托管规则 OWASP CRS:仅检测或拦截、paranoia level、异常分数阈值、按规则 ID 排除、请求体检查上限;命中规则的统计与访问日志
挑战与 CC 防护 Cookie 跳转、JS 计算、工作量证明、图片验证码四级挑战;网站或全局 Under Attack;节点本地分级 CC 自动升级(站点、单 URL、单 IP 自动封禁、源站错误率);集群内通用的签名通行凭证;JA4 指纹用于规则、限速与访问日志
DNS 与观测 独立 DNS 版本、健康节点调度、流量统计去重与汇总、Top URL / IP、告警与订阅
智能调度 区域探针(TCP / HTTP / HTTPS 健康端点)、节点主机指标;调度规则按节点指标与探测结果摘除节点、切换到备用节点组或备用 IP,带预览;运营商解析线路(DNSPod、腾讯云、阿里云、华为云)、备用节点组、多级备用 IP
运维 采样访问日志(UA、来源、协议、地区、回源、拦截原因,可强制记录被拦截的请求,11 种筛选,保留期可调)与 CSV 导出、节点上实时查看请求、统计维度(地区、运营商、来源、终端、协议、拦截原因、挑战通过率)、可选 ClickHouse、只读及可吊销 AccessKey、签名灰度升级与回滚、性能基线、备份恢复

架构

仓库 组成
edgeweir(本仓库) 控制台:Web UI、管理 API(含 OpenAPI /api/v1)、节点通道、pg-boss worker,单进程、单镜像。镜像内含 edgeweir-certd(Go),负责 ACME 证书签发与 DNS 记录管理,由 pg-boss 经有界 stdin/stdout 协议调用,凭据不经进程参数传递。
edgeweir-node 边缘节点:edgeweir-node Go agent 与 OpenResty 数据面。
浏览器、API 调用方 ─:3000──▶ ┌───────────────────────────────────┐
                             │ 控制台(一个 Node.js 进程)       │── PostgreSQL 18(唯一依赖)
                             │   UI · /rpc · /api/v1             │
                             │   节点通道 :8443(mTLS)          │
                             │   pg-boss worker                  │
                             └────────────────▲──────────────────┘
                                              │ Connect-RPC over mTLS
                             ┌────────────────┴──────────────────┐
             终端用户 ─────▶ │ 边缘节点:edgeweir-node agent     │──▶ 源站
                             │           + OpenResty             │
                             └───────────────────────────────────┘

控制台与节点之间的唯一契约为 proto/ 中的 protobuf(buf 管理)。设计细节见 ARCHITECTURE.md。

安全基线

  • 控制台不保存 SSH 凭据。
  • 节点私钥在节点本机生成与保存,不离开节点。
  • 内部 CA 私钥、证书私钥、S3 源站密钥、DNS API 凭据经 EDGEWEIR_MASTER_KEY 信封加密后入库,密文与所属记录绑定。
  • 节点注册 token 单次有效,仅存储 SHA-256;注册完成后节点 RPC 一律使用 mTLS。
  • /api/v1 仅接受 x-api-key;/rpc 仅接受会话 Cookie 与 CSRF 请求头。
  • 无厂商回连,无许可证校验,不发送遥测;第三方依赖的遥测强制关闭。

信任基线、漏洞报告与发布物校验见 SECURITY.md。

发布

制品 地址 版本规则
控制台镜像 ghcr.io/marvinli001/edgeweir(amd64 / arm64) master 上通过 CI 的提交发布为 <YYYYMMDD>-<commit>(如 20260929-a1b2c3d);stable(默认)指向验证过的日期 tag,每次移动附 Release;latest 跟随 master。不使用语义化版本号,镜像经 cosign keyless 签名。
边缘节点 edgeweir-node Releases 签名 Release,语义化版本 vX.Y.Z;stable 控制台支持 1.x 全部次版本。

生产环境通过 EDGEWEIR_VERSION 固定日期 tag。

快速开始

环境要求:Docker、Compose v2。

git clone https://github.com/marvinli001/edgeweir.git
cd edgeweir

umask 077
cat > .env <<EOF
EDGEWEIR_MASTER_KEY=$(openssl rand -base64 32)
POSTGRES_PASSWORD=$(openssl rand -hex 24)
EDGEWEIR_PUBLIC_URL=http://localhost:3000
EOF

docker compose pull        # 从源码构建:docker compose up -d --build
docker compose up -d --wait
docker compose logs console | grep setupToken

访问 http://localhost:3000(3000 默认只监听本机,其他机器经反向代理访问),使用日志中的一次性 setup token 完成初始化向导,创建唯一的运营者账户与默认集群。setup token 在首次初始化成功后失效;无 token 的初始化请求一律拒绝。

环境变量

必填变量:

变量 说明
EDGEWEIR_MASTER_KEY 或 EDGEWEIR_MASTER_KEY_FILE 主密钥,或存放主密钥的文件(主密钥文件)。用于信封加密入库的敏感数据(内部 CA 私钥、证书私钥、S3 源站密钥、DNS API 凭据、setup token)并派生会话密钥。须与数据库备份分开保存,丢失后上述数据不可恢复。
POSTGRES_PASSWORD 或 DATABASE_URL 使用 Compose:内置 PostgreSQL 的密码,DATABASE_URL 由它拼出。不用 Compose:PostgreSQL 18 连接串 DATABASE_URL。
EDGEWEIR_PUBLIC_URL 浏览器访问控制台的地址,在反向代理后为代理地址,如 https://cdn-admin.example.com。须与浏览器地址栏一致,否则登录失败;保留 http://localhost:3000 时生成的节点安装命令也指向本机。

其余变量均有默认值,完整列表见 .env.example。BETTER_AUTH_SECRET 未设置时由主密钥派生;已设置的部署不得移除,否则控制台拒绝启动。节点发布源与源站地址允许清单在初始化后于 系统设置 配置,封禁、全局防护与 GeoIP 在 防护设置,SMTP 在 告警 页。

可选组件

Compose profile 组件 说明
analytics ClickHouse 配合 EDGEWEIR_ANALYTICS=clickhouse 启用原始访问日志与分钟级统计。访问日志采样默认关闭,保留期在系统设置中调整(默认 7 天,ClickHouse 至多 90 天)。控制台图表与告警使用 PostgreSQL 汇总数据。

详见 访问日志与 AccessKey、备份与恢复。

端口

端口 用途 反向代理
3000 Web 控制台与 API 支持在前端终结 TLS(如宝塔 nginx)。须将代理地址写入 EDGEWEIR_TRUSTED_PROXIES,否则审计日志与登录限速取不到真实客户端 IP;其他来源的转发头一律忽略。
8443 节点通道 直接暴露,或经 nginx stream 四层透传。禁止由代理终结 TLS:控制台自行终结 TLS 并强制 mTLS。平台只转发 HTTP 时,节点经 3000 上的 WebSocket 入口 /node-channel 连接,节点通道的 TLS 在 WebSocket 内,见 节点通道的 WebSocket 入口。

部署方式

平台 文档
Docker Compose / docker run Docker Compose 部署
宝塔面板 / aaPanel 宝塔面板 / aaPanel、deploy.sh 参考
Railway Railway
Fly.io Fly.io
bunny.net Magic Containers bunny.net Magic Containers
Render Render;Deploy to Render
Zeabur Zeabur;Deploy on Zeabur

交互式安装与升级脚本 deploy.sh 适用于任何装有 Docker 与 Compose v2 的 Linux,支持本机、云端或内置 PostgreSQL:

curl -fsSL -o deploy.sh https://raw.githubusercontent.com/marvinli001/edgeweir/master/deploy.sh
sudo bash deploy.sh install

接入节点

节点要求:Linux(systemd),amd64 / arm64,glibc 2.34 及以上(RHEL / Rocky / AlmaLinux 9+、Debian 12+、Ubuntu 22.04+),可访问控制台 8443 端口。

  1. 登录控制台,打开 集群与节点,选择集群并生成安装命令。命令包含单次有效 token 与控制台内部 CA 的 SHA-256 指纹。

  2. 在节点上以具备 sudo 权限的账户执行:

    export EDGEWEIR_TOKEN='<一次性 token>'
    curl -fsSL https://<控制台>/install.sh | sudo --preserve-env=EDGEWEIR_TOKEN bash -s -- \
      --server https://<控制台>:8443 --ca-sha256 <CA 指纹>
  3. 节点上线后,控制台显示其在线状态与已应用的配置 revision。

安装脚本行为:

  • token 仅经 EDGEWEIR_TOKEN 环境变量或 --token-file 传递,不出现在进程参数中。
  • 安装前校验 checksums 的 cosign 签名(签发身份须为 edgeweir-node release 工作流及待安装的 tag)与每个包的 SHA-256。
  • 优先安装 .deb / .rpm,否则使用 tar.gz;配置了控制台 /downloads 镜像时从镜像下载,否则从 GitHub Releases 下载。
  • 先安装同一发布中为 Edgeweir 构建的 OpenResty(edgeweir-openresty)与 ModSecurity 模块(edgeweir-openresty-modsecurity,--no-modsecurity 跳过),再安装 edgeweir-node。
  • agent 先核对 CA 指纹再提交 token,本地生成私钥,此后仅经 mTLS 与控制台通信。

安装参数与发布物镜像见接入节点。

API

入口 认证 用途
/api/v1 AccessKey(x-api-key 请求头) 对外 OpenAPI,规范文档位于 /api/v1/openapi.json
/rpc 会话 Cookie + CSRF 请求头 Web UI 专用
/mcp OAuth 访问令牌(Authorization: Bearer) MCP 服务,默认关闭,见 MCP

三个入口由 packages/contract 中的同一份 oRPC 契约提供。

开发

环境要求:Node.js 24+、pnpm 12、Docker。helpers/certd 与 pnpm e2e 另需 Go 1.27.2。buf 随开发依赖安装。

pnpm install
docker compose -f compose.dev.yml up -d   # 本地 PostgreSQL
cp .env.example .env                      # 填写 EDGEWEIR_MASTER_KEY
pnpm dev                                  # UI 与 API :3000,节点通道 :8443
命令 作用
pnpm lint Biome 检查与格式校验、buf lint
pnpm typecheck 全 workspace TypeScript 类型检查
pnpm test 单元与集成测试(Vitest,PostgreSQL 由进程内 PGlite 提供,无需 Docker)
pnpm build 生产构建
pnpm proto:lint 检查 proto/
pnpm proto:gen 由 proto/ 生成 TypeScript 至 packages/proto
pnpm db:generate 由 packages/db/src/schema 的变更生成 SQL 迁移
pnpm e2e 端到端测试,见端到端测试

提交规范、proto 变更流程与国际化规则见 CONTRIBUTING.md。

端到端测试

docker compose -f compose.e2e.yml up -d --build
pnpm e2e     # --up 启动环境;--down 结束后删除环境与卷;--skip-ui 跳过 Playwright

依赖:

  • curl、jq、Docker(节点容器需要 NET_ADMIN)、Node.js
  • 与本仓库同级的 edgeweir-node 检出(或 EDGEWEIR_NODE_CONTEXT)
  • 安装步骤:goreleaser v2、syft、cosign、Go 1.27.2;edgeweir-node 的 out/openresty 中有 Docker 架构对应的 edgeweir-openresty 包(make openresty-packages,缺少时由 scripts/e2e.sh 从缓存取出或构建,需要 Docker Buildx)
  • G3 / G8 步骤:之前的节点镜像 edgeweir-node:pre-g3、edgeweir-node:pre-g8(E2E_OLD_NODE_IMAGE、E2E_PRE_G8_IMAGE,缺少时由 scripts/e2e-g3.mjs / e2e-g8.mjs 从 edgeweir-node 提交 6da3403 / 7e1338f 构建或从缓存载入)
  • 构建缓存:旧节点镜像按提交、edgeweir-openresty 包按 packaging/openresty 的 git tree 保存在 E2E_CACHE_DIR(默认 ~/.cache/edgeweir-e2e,scripts/e2e-cache.mjs),新的 Docker 虚拟机或清空构建缓存后直接载入,不再编译
  • 网络访问:deb.debian.org、openresty.org;首次构建节点镜像或 edgeweir-openresty 包时另需 github.com、download.gnome.org、vault.almalinux.org

覆盖范围:节点注册、配置下发、缓存、刷新与预热、源站与 S3、故障切换、认证路由白名单(better-auth 管理与 api-key 端点关闭,API Key 不转换为会话)、源站地址策略与 CDN-Loop、HTTPS 源站名称校验、1 MiB 切片 Range 请求、install.sh 在干净容器中从控制台镜像安装、节点经终结 TLS 的反向代理以 wss:// 节点通道地址注册(经 mTLS 在线、心跳持续、应用配置版本)、动态封禁(下发延迟 p95 ≤ 5 秒、站点封禁、全局封禁由 nftables 丢包)、挑战与通行凭证(无头浏览器通过 js 与 pow 挑战,凭证在另一节点有效,换网段、换 UA 或伪造后失效)、分级 CC(只升级被攻击的路径、单 IP 自动封禁)、JA4 参与规则匹配、Brotli / Zstandard 按 q 值协商(缓存一份未压缩对象,curl --compressed 解码)、OWASP CRS 检测与拦截(含缓存命中)、旧节点所在集群无法开启这些功能、edgeweir-openresty 包内容、按 Cache-Tag 与 Host 刷新(含过期内容与分片)、按设备与站点地图预热、主动健康检查摘除与恢复、会话保持与故障切换、网站与平台错误页(转义、no-store、请求 ID)、动态重定向与改写及查询参数编辑(无效目标失败关闭)、批量重定向的热更新、源站覆盖规则与回源超时、表达式缓存规则与浏览器 TTL、压缩规则与不绕过缓存的 gzip=false、按规则开关 Under Attack、WebSocket 与日志采样、区域探针(两个探针容器以一次性令牌注册,节点以自身证书兼任探针)、多数探针到不了主地址时切换到备用地址、限定区域的调度规则摘除节点与线路切换到备用节点组、按解析线路写入的记录、四层转发(端口池重叠、端口池外与 UDP PROXY protocol 被拒绝,TCP 与 UDP 经两个节点转发,长连接跨越新增端口引起的 reload,向源站发送 PROXY protocol v1 / v2 与接受 PROXY protocol 的监听,不 reload 更换源站,IP 拦截名单与连接上限,统计与 CNAME)、HTTP/2 回源与 gRPC(只支持 h2c 的源站,经两个节点的 gRPC 单次调用、双向流与错误 trailers,改回 HTTP/1.1 后不再以 HTTP/2 回源)、缓存、源站与内容(集群与节点的缓存区及用量、带 Set-Cookie 的缓存对象只把 Cookie 发给回源的那次响应、排除 utm_* 的缓存键、PURGE 方法、错误页分类与跳转、维护模式、字符编码、请求体上限、Gzip 级别、回源重试、MinIO 预设的 S3 源站)、网站管理(批量加标签与按标签筛选、把规则与缓存设置复制到两个网站后两个节点按新设置服务、缺少源站组的网站复制失败且设置不变、克隆网站、批量停用在一个配置版本内生效)、用量保护(极小上限下的预警与上限告警送达 Webhook、两个节点上开启维护模式与停用网站、调高上限后自动恢复、手动恢复后不再触发)、Playwright 页面流程。

以下变量由 compose.e2e.yml 与 scripts/e2e.sh 共同读取,两侧取值须一致。更换项目名、端口、tag 与子网即可并行运行第二套环境。

变量 默认值 作用
COMPOSE_PROJECT_NAME edgeweir-e2e Compose 项目名,同时用于命名安装容器
E2E_CONSOLE_PORT 13000 控制台宿主机端口
E2E_NODE_PORT 18080 节点 HTTP 宿主机端口
E2E_TAG e2e 控制台与节点镜像 tag
E2E_SUBNET 172.28.213.0/24 默认网络,加入源站地址允许清单
E2E_ISOLATED_SUBNET 172.28.214.0/24 允许清单之外的网络,其中的源站须被拒绝
E2E_INSTALL_IMAGE debian:bookworm-slim(scripts/e2e.sh 中按 digest 固定) 运行 install.sh 的干净环境
EDGEWEIR_NODE_CONTEXT ../edgeweir-node edgeweir-node 检出目录

测试环境缩短了时间:控制台每分钟的任务另外每 5 秒运行一次、节点每 5 秒发心跳(在线窗口 15 秒)、节点每 5 秒上报已结束分钟的统计(compose.e2e.yml 中的 EDGEWEIR_E2E_TICK_SECONDS、EDGEWEIR_E2E_HEARTBEAT_SECONDS、EDGEWEIR_STATS_INTERVAL)。设 E2E_TICK_SECONDS=、E2E_HEARTBEAT_SECONDS=(空值)与 E2E_STATS_INTERVAL=1m 后按生产环境的时间运行。

目录结构

apps/console/              控制台:单一应用包、单一进程
  src/server/              Hono 服务端:API、认证、节点通道、worker
  src/web/                 React SPA
packages/db/               Drizzle schema 与 SQL 迁移
packages/contract/         oRPC 契约与 zod schema
packages/config-compiler/  数据库模型 → NodeConfig IR
packages/proto/            由 proto/ 生成的 TypeScript
proto/                     protobuf(buf 管理),与 edgeweir-node 共享的唯一契约
helpers/certd/             edgeweir-certd(Go):lego 负责 ACME,libdns 负责 DNS 记录
scripts/e2e.sh             端到端测试脚本
docs/deploy/               部署文档
docs/guide/                使用指南
docs/reference/            参考:环境变量、命令行、API
doc/                       文档站(Fumadocs),发布至 GitHub Pages

文档

文档站 https://marvinli001.github.io/edgeweir/zh/ 由以下 Markdown 生成。每篇文档另有英文版 *.en.md。

分类 文档
入门 核心概念 · 快速上手
部署 部署概览 · Docker Compose · 宝塔面板 / aaPanel · deploy.sh 参考 · Railway · Fly.io · bunny.net Magic Containers · Render · Zeabur · 端口、反向代理与可信代理
站点 概览 · 网站管理 · 域名与未知域名 · 源站与缓存 · 分层缓存 · 图片格式转换 · 面向代理的 Markdown · HTTPS 与证书 · 错误页 · L4 转发 · 用量保护 · 统计与访问日志
访问控制 规则、IP 名单与 GeoIP · 访问控制 · 封禁 · 挑战与 CC 防护 · AI 爬虫管理 · OWASP CRS 托管规则 · 攻击与自动缓解
基础设施 集群与节点 · 区域探针与智能调度 · DNS 调度
系统 账户与登录 · 告警 · 系统设置与审计 · 节点扩展
节点 节点概览 · 接入节点 · 节点配置 · 节点升级 · 节点日志 · 节点运维 · 节点排障
运维 版本与升级 · 降级 · 备份与恢复 · 维护 · 故障排查
参考 API 概览 · API:网站 · API:访问控制 · API:证书 · API:集群与节点 · API:DNS 与调度 · API:概览、统计与告警 · API:系统与账户 · 环境变量 · 命令行 · 错误码 · 节点扩展契约
项目 架构 · 安全策略 · 开发与贡献 · 许可证

许可证

AGPL-3.0-only,edgeweir-node 相同。允许在遵守许可证的前提下商用。

开源版是单一运营者的 CDN,不支持多租户;组织与成员等多租户能力、客户门户、套餐计费、财务与分销由独立商业产品提供,不对开源核心附加使用限制。详见 LICENSING.md。

About

开源自托管 CDN / WAF / 边缘调度控制面:缓存、HTTPS、OWASP CRS、CC 防护、四层转发、智能 DNS 调度,单进程单镜像,无回连无遥测。

Topics

Resources

Contributing

Security policy

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages