Files
RemLink/README.md
T
qsc20001102 6174531cee
ci / Go checks (ubuntu-latest) (push) Has been cancelled
ci / Go checks (windows-latest) (push) Has been cancelled
README说明文档重写
2026-08-29 14:44:35 +08:00

17 KiB
Raw Permalink Blame History

RemLink

RemLink 是一套面向工业现场的 IPv4 三层远程接入系统,用于让远程工程师通过中心服务器安全访问现场 PLC、HMI、工控机及其他 IP 设备。

系统由三个完全独立的程序组成:

  • RemLink Server:运行在 Linux,负责节点注册、Overlay 地址分配、WireGuard 中心转发、会话调度和 Web 管理。
  • RemLink Engineer:运行在工程师 Windows 电脑,提供图形界面,把指定现场网段路由到当前远程会话。
  • RemLink Site:运行在现场 Windows 电脑,通过 gVisor 用户态网络栈访问现场局域网设备。

典型数据路径:

Engineer Windows
    │
    │ WireGuard Overlay
    ▼
RemLink ServerLinux 中心节点)
    │
    │ WireGuard Overlay
    ▼
Site Windows ── gVisor netstack ── 现场 LAN ── PLC/HMI/工控设备

Engineer、Site 和 Server 的发布包、配置及运行数据彼此独立,不能混放或互相替换。

主要功能

  • 以 Linux 内核 WireGuard 为中心建立 10.88.0.0/16 Overlay 网络。
  • Engineer 和 Site 各自只创建并复用一个 RemLink Wintun 适配器。
  • 自动注册节点、分配 Overlay IP、维护心跳及在线状态。
  • Engineer 可选择 Site,并为该 Site 设置一个或多个远程 CIDR。
  • 不同 Site 的远程网段分别保存,切换现场时不需要反复删除和重新添加。
  • 支持多个 Engineer、多个 Site,以及不同 Site 使用相同现场网段。
  • Site 使用进程内 gVisor netstack 转发通用 TCP、UDP 和 ICMP Echo 流量。
  • Site 离线后,Server 自动关闭相关会话,Engineer 自动清理当前远程路由。
  • Server 提供中文 Web 管理页面,可查看节点、会话、网络配置和事件日志。
  • Engineer、Site、Server 的面向操作员日志均已中文化,同时保留协议状态和错误码。
  • Engineer 和 Site 使用便携目录,配置、身份、日志和 wintun.dll 均位于各自 EXE 目录。

系统边界

  • RemLink 是中心辐射结构,所有 Overlay 流量均经过 Server,不建立节点间 P2P。
  • Site 不要求 PLC 或现场设备配置返回 Overlay 的路由。
  • Site 必须从本机通过直连路由或明确静态路由到达现场网段;只有默认路由时会返回 SITE_NO_ROUTE
  • 每个 Engineer 同时只允许一个非终态远程会话。
  • 当前版本只支持 IPv4,不提供二层以太网桥接。
  • Server v1.0 不直接终止 TLS;公网管理和注册入口应置于 HTTPS 反向代理之后。

项目目录与文件作用

路径 作用
cmd/server/ Linux Server 程序入口和启动编排
cmd/engineer/ Windows Engineer/Wails GUI 程序入口
cmd/site/ Windows Site 控制台程序入口
internal/admin/ Server 管理 API、节点和网络配置管理
internal/bootstrap/ 节点首次注册、Token 校验和权威配置下发
internal/control/ Server 与 Windows 节点之间的控制通道
internal/session/ 远程会话状态机、超时、关闭和统计
internal/overlay/clientwg/ Windows wireguard-go、Wintun 和 PacketMux
internal/overlay/serverwg/ Linux 内核 WireGuard 管理
internal/subnetgateway/ Site gVisor netstack 及 TCP/UDP/ICMP 转发
internal/platform/windows/ Windows 路由、DPAPI、网卡和 Wintun 运行库
internal/database/internal/ipam/ SQLite 持久化和 Overlay 地址分配
frontend/engineer/ Engineer Vue 图形界面,构建后嵌入 Wails EXE
frontend/server/ Server Vue Web 管理页面,构建后嵌入 Server 二进制
config/*.example.yaml Server、Engineer、Site 的安全配置模板
deploy/docker/ Server Dockerfile、Compose、预检和中国网络模板
scripts/build-release.ps1 构建和验证三端独立发布包
scripts/validation/ 架构、发布包和 T01–T18 验收工具
scripts/maintenance/ Git 候选文件和敏感内容检查
specs/ Phase 0–10 开发任务、规格和验收清单
docs/ 中文部署、实现状态、设计和物理验收文档
third_party/THIRD_PARTY_NOTICES.md 第三方组件许可说明
.github/workflows/ci.yml GitHub Actions 自动构建和测试

以下目录是本地生成内容,不应提交到 Git:

  • build/:临时可执行文件。
  • dist/:三端发布目录和 ZIP。
  • frontend/node_modules/:前端依赖。
  • frontend/*/dist/:前端编译结果。
  • data/logs/runtime/evidence/:运行数据和验收证据。

开发与打包环境

推荐在 Windows PowerShell 7 中执行发布脚本,准备:

  • Go:版本以 go.mod 为准。
  • Node.js:与 .github/workflows/ci.yml 中的版本一致。
  • npm:使用 frontend/package-lock.json 锁定依赖。
  • PowerShell 7。
  • Git。

检查环境:

go version
node --version
npm --version
git --version
$PSVersionTable.PSVersion

构建三个独立发布包

在项目根目录执行:

$version = "1.0.7"
./scripts/build-release.ps1 -Version $version

版本号必须是语义化版本,例如 1.0.71.1.0-beta.1。发布脚本会自动执行:

  1. Git 仓库候选文件和敏感内容检查。
  2. 前端依赖清洁安装、Vue 类型检查和生产构建。
  3. 前端 Demo 数据泄漏检查。
  4. Go 依赖校验、全量测试和 go vet
  5. 架构规则与验收工具自测。
  6. Windows/Linux 交叉编译。
  7. 三端目录隔离、SHA-256 生成和发布包解压复核。

成功后在 dist/ 得到:

dist/
├─ RemLink-Engineer-v1.0.7-windows-amd64/
├─ RemLink-Engineer-v1.0.7-windows-amd64.zip
├─ RemLink-Site-v1.0.7-windows-amd64/
├─ RemLink-Site-v1.0.7-windows-amd64.zip
├─ RemLink-Server-v1.0.7-linux-amd64/
└─ RemLink-Server-v1.0.7-linux-amd64.zip

每个发布目录都包含 BUILD-INFO.jsonSHA256SUMS.txt。Engineer 包不会包含 Site 或 ServerSite 包不会包含 Engineer 或 ServerServer 包也不会包含 Windows 客户端。

只运行开发检查、不生成发布包时执行:

./scripts/maintenance/Test-RepositoryHygiene.ps1
npm ci --prefix frontend
npm run typecheck --prefix frontend
npm run build --prefix frontend
go test -count=1 ./...
go vet ./...
./scripts/validation/Test-FrontendProduction.ps1
./scripts/validation/Test-Architecture.ps1
./scripts/validation/Test-AcceptanceTools.ps1

部署前网络准备

端口 用途 是否需要公网或跨网访问
8080/tcp Web、Bootstrap、Admin API 仅可信管理网;公网应使用 HTTPS 反向代理
51820/udp WireGuard 公网入口 Engineer 和 Site 必须能够访问
7001/tcp Overlay Control WebSocket 只在 Overlay 内使用,不映射公网
6200/udp Overlay Session 数据 只在 Overlay 内使用,不映射公网

部署前确认:

  • Server 是 Linux amd64,并支持内核 WireGuard 和 /dev/net/tun
  • Engineer 和 Site 是 Windows amd64,并以管理员权限运行。
  • 默认 Overlay 10.88.0.0/16 不与任一 Windows 主机的本地网络重叠。
  • Server 的 WireGuard UDP 端口已在云安全组、防火墙和 NAT 中放行。
  • Site Windows 本机能够直接访问目标 PLC/HMI 网段。

部署 ServerUbuntu + Docker Compose

1. 检查宿主机

uname -m
test -c /dev/net/tun && echo "TUN 正常"
sudo modprobe wireguard
docker version
docker compose version

2. 解压和安装 Server 包

以下使用 1.0.7 举例,实际部署时替换为构建出的版本:

unzip RemLink-Server-v1.0.7-linux-amd64.zip
sudo mkdir -p /opt/remlink
sudo cp -a RemLink-Server-v1.0.7-linux-amd64/. /opt/remlink/
cd /opt/remlink/docker

3. 创建 .env

普通网络环境:

sudo cp .env.example .env

中国大陆网络环境:

sudo cp .env.china.example .env

编辑 .env。下面是通用模板的配置形式;如果复制的是 .env.china.example,请保留其中已经填写的两个镜像地址,不要用下面的空值覆盖:

REMLINK_WG_ENDPOINT=vpn.example.com:51820
REMLINK_WG_PORT=51820
REMLINK_HTTP_BIND=127.0.0.1
REMLINK_ADMIN_TOKEN=替换为足够长的随机管理令牌
REMLINK_APT_FORCE_IPV4=1
REMLINK_APT_DEBIAN_MIRROR=
REMLINK_APT_SECURITY_MIRROR=

关键配置说明:

  • REMLINK_WG_ENDPOINTEngineer/Site 实际可访问的公网 IP 或域名及 UDP 端口。
  • REMLINK_WG_PORT:必须与 endpoint、server.yaml、防火墙和 NAT 端口一致。
  • REMLINK_HTTP_BIND=127.0.0.1Web 只允许本机反向代理访问。
  • 需要在可信局域网直接打开 Web 时,可改为 Server 的管理网 IP;只有明确接受风险时才使用 0.0.0.0
  • REMLINK_ADMIN_TOKENServer Web 和 Admin API 的 Bearer Token,不能提交到 Git。
  • 中国模板已设置适合中国网络的 Debian 镜像和 IPv4 构建参数。

4. 检查 Server YAML

docker/server.yaml 默认配置:

server:
  http_listen: "0.0.0.0:8080"
  control_listen: "10.88.0.1:7001"
  wireguard_port: 51820

data:
  directory: "/app/data"

network:
  overlay_cidr: "10.88.0.0/16"
  server_overlay_ip: "10.88.0.1"
  session_udp_port: 6200
  mtu: 1280

没有网络冲突时建议保持默认值。如果修改 wireguard_port,必须同步修改 .env、云安全组、防火墙和 NAT。

5. 启动 Server

cd /opt/remlink/docker
sudo chmod 600 .env
sudo mkdir -p data
sudo docker compose --env-file .env -f compose.release.yaml config --quiet
sudo docker compose --env-file .env -f compose.release.yaml up --build -d
sudo docker compose --env-file .env -f compose.release.yaml ps
sudo docker compose --env-file .env -f compose.release.yaml logs --tail=100 server
curl --fail http://127.0.0.1:8080/api/v1/server/info

6. 获取 Join Token

sudo docker compose --env-file .env -f compose.release.yaml exec server \
  remlink-server -config /etc/remlink/server.yaml -print-join-token

Join Token 用于 Engineer 和 Site 第一次注册。节点全部注册完成后建议轮换:

sudo docker compose --env-file .env -f compose.release.yaml exec server \
  remlink-server -config /etc/remlink/server.yaml -rotate-join-token

浏览器访问受保护的 Server 地址,例如 http://服务器管理网IP:8080 或反向代理后的 HTTPS 域名。在左侧令牌框输入 .env 中的 REMLINK_ADMIN_TOKEN 并点击“应用”。

部署 EngineerWindows

将 Engineer ZIP 单独解压到固定目录,例如:

C:\RemLink\Engineer

编辑 EXE 同目录的 engineer.yaml

server: "https://remlink.example.com"
node_name: "Engineer-Shanghai-01"
join_token: "粘贴从 Server 获取的 Join Token"

如果没有配置 HTTPS 反向代理,在可信网络中可临时使用:

server: "http://服务器IP:8080"

以管理员身份运行:

Set-Location C:\RemLink\Engineer
.\RemLinkEngineer.exe

首次启动会注册节点,并在当前目录生成受机器级 DPAPI 保护的 identity.json。该身份只能在原 Windows 主机上使用,不能复制到另一台电脑。

部署 SiteWindows

将 Site ZIP 单独解压到另一台现场 Windows 主机,例如:

C:\RemLink\Site

编辑 EXE 同目录的 site.yaml

server: "https://remlink.example.com"
node_name: "Qingdao-Site-01"
join_token: "粘贴从 Server 获取的 Join Token"

netstack:
  tcp_flow_limit: 2048
  udp_flow_limit: 4096
  udp_idle_seconds: 60

配置含义:

  • tcp_flow_limitSite 同时处理的 TCP flow 上限。
  • udp_flow_limitSite 同时处理的 UDP flow 上限。
  • udp_idle_secondsUDP flow 空闲回收时间。
  • Site YAML 不配置现场网段;现场 CIDR 由 Engineer 创建会话时动态下发。

以管理员身份运行:

Set-Location C:\RemLink\Site
.\RemLinkSite.exe

正常状态应包含:

WireGuard=CONNECTED
Control=CONNECTED
RemoteSubnet=READY
SubnetGateway=GVISOR_NETSTACK/READY

建立会话前,先在 Site 本机验证目标和路由:

Get-NetRoute -AddressFamily IPv4 | Sort-Object DestinationPrefix,RouteMetric
ping 192.168.17.10
Test-NetConnection 192.168.17.10 -Port 502

目标网段必须是直连网络或具有明确非默认路由。只有默认路由时,RemLink 会拒绝会话。

基础使用流程

  1. 启动 Server,确认 /api/v1/server/info 正常。
  2. 使用 Join Token 分别启动并注册 Site 和 Engineer。
  3. 在 Server Web“节点”页面确认两个节点均为“在线(ONLINE)”。
  4. 在 Site 本机确认目标 PLC/HMI 的 IP、端口和明确路由可达。
  5. 打开 Engineer,选择需要连接的 Site。
  6. 为该 Site 添加远程网段,例如 192.168.17.0/24
  7. 等待 Engineer 的本地 CIDR 冲突检查通过。
  8. 点击“连接现场”,等待状态进入“活动中(ACTIVE)”。
  9. 在 Engineer 电脑使用原生工具访问现场设备:
ping 192.168.17.10
Test-NetConnection 192.168.17.10 -Port 102
Test-NetConnection 192.168.17.10 -Port 502
Test-NetConnection 192.168.17.10 -Port 80
  1. 使用完成后点击“断开会话”,确认远程路由被删除。

Engineer 会按 Site Node ID 保存远程 CIDR。例如:

  • 现场 A 保存 192.168.17.0/24
  • 现场 B 保存 192.168.107.0/24

切换 Site 时只加载对应现场的 CIDR,不需要手工删除其他现场的网段。Site 离线后,当前会话会自动关闭。

三端运行文件位置

Engineer

Engineer目录/
├─ RemLinkEngineer.exe
├─ engineer.yaml
├─ identity.json
├─ site-profiles.json
├─ wintun.dll
└─ logs/engineer.jsonl

Site

Site目录/
├─ RemLinkSite.exe
├─ site.yaml
├─ identity.json
├─ wintun.dll
└─ logs/site.jsonl

Docker Server

/opt/remlink/docker/
├─ .env
├─ server.yaml
├─ compose.release.yaml
└─ data/
   ├─ remlink.db
   ├─ logs/server.jsonl
   └─ WireGuard及Server运行数据

不要把 Engineer 和 Site 放在同一个目录,也不要互相复制 identity.json。升级 Windows 程序时保留本端 YAML、身份、日志和已校验的 wintun.dll

常见问题

现象 原因或处理方法
Server 页面无法打开 检查 REMLINK_HTTP_BIND、Docker 端口映射、防火墙和反向代理
页面提示需要 Bearer Admin Token 输入 .env 中的 REMLINK_ADMIN_TOKEN
JOIN_TOKEN_INVALID Join Token 已轮换或填写错误,重新从 Server 安全获取
SITE_NO_ROUTE / DEFAULT_ONLY Site 没有目标网段的直连或明确静态路由
CIDR_LOCAL_CONFLICT Engineer 本地已有覆盖远程 CIDR 的网卡或路由
OVERLAY_LOCAL_CONFLICT 10.88.0.0/16 与某台 Windows 主机本地网络冲突
DPAPI Key not valid for use in specified state identity.json 来自其他机器/账户状态或已损坏,应隔离旧身份并重新注册
容器预检提示 WireGuard 或 CAP_NET_ADMIN 不可用 检查宿主机 WireGuard、/dev/net/tun、Compose 的 NET_ADMIN 和 IPv4 forwarding
中国网络构建停在 apt-get 使用 .env.china.example,并检查 Docker DNS、IPv4 和镜像连接

更完整的故障排查、备份、升级和 HTTPS 配置见部署文档。

安全注意事项

  • Join Token 和 Admin Token 都不得提交到 Git、截图或公开日志。
  • Engineer/Site YAML 中只允许明文保存首次注册所需的 Join TokenNode Token 和 WireGuard 私钥由程序及 DPAPI 管理。
  • .envidentity.jsonsite-profiles.json、数据库、日志和私钥均已加入 .gitignore
  • 不要对 Server 容器启用 privileged;当前 Compose 只授予 NET_ADMIN 并映射 /dev/net/tun
  • 不要把 7001/tcp6200/udp 映射到公网。
  • 公网 Bootstrap/Admin 必须使用外部 HTTPS 反向代理保护。
  • ZIP 和 EXE 应放到 GitHub Release 或其他发布渠道,不应直接提交到源码历史。

提交前执行:

./scripts/maintenance/Test-RepositoryHygiene.ps1
git status --short
git diff --check

文档入口

当前验证状态

Phase 010 的生产代码、前端、自动化测试、发布打包和 Docker 基线均已实现。自动化覆盖 Bootstrap、IPAM、数据库、Control 重连、Session 状态机、数据包验证、gVisor TCP/UDP/ICMP 往返、网络迁移、重复现场 CIDR 隔离及发布包校验。

Gate AD 和 T01–T18 的正式结果必须在符合拓扑要求的 Linux/Windows 实机环境中按验收手册采集证据。单元测试、浏览器测试和一次人工联通不能替代完整物理验收记录。