diff --git a/README.md b/README.md
index d8a4267..40665ae 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,8 @@ FRP-Panel is a visualization management dashboard for FRP, offering centralized
[Detailed Documentation (Wiki)](https://vaala.cat/frp-panel/en/) · [Development Blog](https://vaala.cat/posts/frp-panel-doc/) · [Screenshots & Videos](https://vaala.cat/frp-panel/en/screenshots) · QQ Group: 830620423
+> [WireGuard Multi-Hop Smart Networking Dev Notes](https://vaala.cat/posts/frp-panel-with-wireguard/) — includes a funny demo you can try.
+
English | [中文](./README_zh.md)
@@ -21,6 +23,10 @@ English | [中文](./README_zh.md)
| Visual Interface | Create, edit, and monitor tunnels and Workers via Web UI, with real-time logs and stats |
| Simplified Credential Distribution | Auto-generate and distribute startup commands—no manual parameter passing |
| Edge Worker Deployment | Deploy custom Workers on Clients, expose them via Server, and adjust configs live via Master |
+| WireGuard Smart Networking | WireGuard over UDP/WebSocket with multi-hop routing, custom routes/topology, and latency + bandwidth-aware path selection |
+
+> Networking is currently in beta. Please share feedback.
+> Networking requires at least one client with a public IP as a relay, and currently supports Linux systems only.
## Architecture Overview
@@ -28,7 +34,7 @@ English | [中文](./README_zh.md)
1. **Master** – Centralized management and authentication; requires access from all Servers and Clients
2. **Server** – Public-facing entry point that handles traffic for Clients
-3. **Client** – Internal proxy that supports deploying Workers
+3. **Client** – Internal proxy that supports deploying Workers and WireGuard mesh networking
## Community & Sponsorship
diff --git a/README_zh.md b/README_zh.md
index 2c99a70..e8bbbf2 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -2,7 +2,9 @@
FRP-Panel 是一款基于 FRP 的可视化管理面板,提供中心化配置、统一凭证、动态调度和边缘 Worker 支持,让内网穿透和服务暴露更简单、更安全、更高效。
-[详细使用文档 (Wiki)](https://vaala.cat/frp-panel) | [Blog 开发记录](https://vaala.cat/posts/frp-panel-doc/) | [截图/视频展示](https://vaala.cat/frp-panel/screenshots) | QQ 群:830620423
+[详细使用文档 (Wiki)](https://vaala.cat/frp-panel) | [Frp-panel Blog 开发记录](https://vaala.cat/posts/frp-panel-doc/) | [截图/视频展示](https://vaala.cat/frp-panel/screenshots) | QQ 群:830620423
+
+> [WireGuard 多跳智能组网功能开发笔记](https://vaala.cat/posts/frp-panel-with-wireguard/) 点开有好玩的 Demo 哦!
中文文档 | [English](./README.md)
@@ -20,6 +22,9 @@ FRP-Panel 是一款基于 FRP 的可视化管理面板,提供中心化配置
| 可视化界面 | Web UI 一键创建、编辑、监控隧道和Worker,实时日志与统计一目了然 |
| 简化凭证分发 | 自动生成并分发启动命令,无须手动传参 |
| 边缘 Worker 自部署 | 在 Client 上部署自定义 Worker,Server 将其暴露到公网,Master 可实时调整配置 |
+| WireGuard 智能组网 | 支持 Client 相互之间使用 WireGuard over UDP/Websocket 多跳组网、自定义路由、拓扑,按延迟和带宽智能计算最短路由 |
+
+> 组网功能目前处于测试阶段,可能存在一些问题,欢迎反馈
## 架构概览
@@ -27,7 +32,9 @@ FRP-Panel 是一款基于 FRP 的可视化管理面板,提供中心化配置
1. **Master** – 集中管理与鉴权,要求所有 Server 和 Client 可访问;
2. **Server** – 承载业务流量,作为公网入口,为 Client 提供服务;
-3. **Client** – 内网代理,支持部署 Worker;
+3. **Client** – 内网代理,支持部署 Worker,支持 WireGuard 与其他 Client 智能组网;
+
+> 组网目前要求网络中至少有一个 Client 有公网IP作为中继节点,且目前仅支持 Linux 操作系统组网
## 社区与赞助
diff --git a/docs/.vitepress/config/en.ts b/docs/.vitepress/config/en.ts
index 6fd9f97..7e6cf65 100644
--- a/docs/.vitepress/config/en.ts
+++ b/docs/.vitepress/config/en.ts
@@ -9,7 +9,7 @@ export const enConfig: LocaleSpecificConfig = {
sidebar: [
{
text: "Quick Start",
- collapsed: true,
+ collapsed: false,
link: "/en/quick-start",
items: [
{ text: "Master Deployment", link: "/en/deploy-master" },
@@ -17,6 +17,14 @@ export const enConfig: LocaleSpecificConfig = {
{ text: "Client Deployment", link: "/en/deploy-client" },
],
},
+ {
+ text: "Advanced Usage",
+ collapsed: false,
+ link: "/en/wireguard",
+ items: [
+ { text: "WireGuard Multi-Hop Networking", link: "/en/wireguard" },
+ ],
+ },
{
text: "Configuration",
collapsed: false,
diff --git a/docs/.vitepress/config/zh.ts b/docs/.vitepress/config/zh.ts
index 9e759e7..65911c2 100644
--- a/docs/.vitepress/config/zh.ts
+++ b/docs/.vitepress/config/zh.ts
@@ -18,6 +18,14 @@ export const zhConfig: LocaleSpecificConfig = {
{ text: "Client 部署", link: "/deploy-client" },
],
},
+ {
+ text: "进阶使用",
+ collapsed: false,
+ link: "/advanced-usage",
+ items: [
+ { text: "WireGuard 多跳智能组网", link: "/wireguard" },
+ ],
+ },
{
text: "配置说明",
collapsed: false,
diff --git a/docs/en/wireguard.md b/docs/en/wireguard.md
new file mode 100644
index 0000000..64cad10
--- /dev/null
+++ b/docs/en/wireguard.md
@@ -0,0 +1,161 @@
+# WireGuard Multi-Hop Smart Networking
+
+- Dev notes: [WireGuard multi-hop smart networking development log](https://vaala.cat/posts/frp-panel-with-wireguard/), includes a funny demo you can try.
+
+> The networking feature is currently in beta (minimum supported version: v0.1.25). Please share feedback via QQ group, GitHub issues, or email.
+>
+> Networking currently supports Linux hosts only.
+
+`frp-panel` bundles `wireguard-go` to provide networking. It supports WireGuard over UDP/WebSocket multi-hop networking, custom routes and topology, and calculates the shortest path using latency and bandwidth so it works well even in complex network environments.
+
+## Getting Started
+
+### 0. Concepts
+
+Before you begin, make sure all of the following are true:
+
+1. At least one client in the network has a public IP to act as a relay node.
+2. All participating machines run Linux.
+3. At minimum, `frp-panel master` and `frp-panel client` are installed.
+4. `frp-panel client` must be installed with root privileges.
+
+The networking sidebar contains four submenus:
+
+1. **Network**: Clients in the same network can communicate; a client can join multiple networks.
+2. **Device**: A client can bind multiple devices. Devices can join networks; devices in the same network can communicate.
+3. **Endpoint**: A device can bind multiple endpoints. Endpoints can be connected by other devices. An endpoint is usually a public IP + port.
+4. **Connection**: Two devices in the same network can establish a connection if at least one of them has a bound endpoint.
+
+Example:
+
+
+
+In the diagram, the two boxes represent two clients sharing the `10.10.0.0/24` network.
+
+Left client:
+
+- Has a **device** `wg0` (virtual NIC) with virtual IP `10.10.0.1`.
+- Device `wg0` binds an **endpoint** `10.10.0.1:51820` (public IP + port).
+- Device `wg0` joins the **network** `10.10.0.0/24`.
+- Device `wg0` can talk to other devices in the `10.10.0.0/24` network.
+
+Right client:
+
+- Has a **device** `wg0` (virtual NIC) with virtual IP `10.10.0.2`.
+- Device `wg0` joins the **network** `10.10.0.0/24`.
+- Device `wg0` can talk to other devices in the `10.10.0.0/24` network.
+- The right client creates a **connection** to the left client via the **endpoint** `1.1.1.1:51820`.
+
+This lets the right client communicate with the left client through `frp-panel` networking.
+
+### 1. Prepare the environment
+
+The networking feature depends on kernel capabilities, so verify the environment first.
+
+If your Linux system has `/etc/sysctl.d`, run:
+
+```bash
+echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-frp-panel.conf
+echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-frp-panel.conf
+echo 'net.ipv4.icmp_echo_ignore_all = 1' | sudo tee -a /etc/sysctl.d/99-frp-panel.conf
+sudo sysctl -p /etc/sysctl.d/99-frp-panel.conf
+```
+
+Otherwise, use `/etc/sysctl.conf`:
+
+```bash
+echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
+echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf
+echo 'net.ipv4.icmp_echo_ignore_all = 1' | sudo tee -a /etc/sysctl.conf
+sudo sysctl -p /etc/sysctl.conf
+```
+
+Next, check whether the TUN device exists. If it does, skip; if not, resolve it first:
+
+```bash
+ls /dev/net/tun
+```
+
+If the command succeeds, continue.
+
+### 2. Create a network
+
+Open the networking sidebar, select **Network**, then click **New Network**. Fill in the form:
+
+- **Network Name**: Use lowercase English; avoid special characters.
+- **CIDR**: The network CIDR, e.g., `10.10.0.0/24`. This example covers `10.10.0.0`–`10.10.0.255`.
+- **ACL**: Optional. Controls permissions for **direct connections**. Example:
+
+```json
+{
+ "acls": [
+ { "action": "allow", "src": ["cn"], "dst": ["cn"] },
+ { "action": "allow", "src": ["us"], "dst": ["us"] }
+ ]
+}
+```
+
+`action` is `allow` or `deny`. `src` and `dst` are labels (any strings) used to group devices. Labels are assigned when creating devices.
+
+In the example above, devices labeled `cn` can directly connect to `cn`, and `us` to `us`. Others cannot directly connect.
+
+> Manual connections are not governed by ACLs.
+
+Click **Submit** to create the network.
+
+### 3. Create an endpoint (skip for non-public nodes)
+
+Go to **Endpoint** in the networking sidebar and click **New Endpoint**:
+
+- **Client**: Choose a client with public internet access.
+- **Host Name**: Public IP or domain, e.g., `1.1.1.1` or `example.com`.
+- **Port**: Public-facing port, e.g., `51820`.
+- **Type**: `ws` or `udp`. `ws` means WebSocket; `udp` means UDP.
+- **URI**: Leave empty for UDP. For WS, provide the full URI, e.g., `ws://example.com:51820`.
+
+Click **Create** when done.
+
+### 4. Create a device
+
+Open **Device** in the networking sidebar and click **Join Network** to add a client to a network:
+
+- **Client**: Select a Linux client installed as root.
+- **Network**: Select a known network.
+- **Endpoint** (optional for non-public nodes): Select an existing endpoint.
+- **Interface Name**: Lowercase letters + digits only, such as `frpp0`. The default value is recommended; invalid names cause startup failures.
+- **Local Address**: The device’s virtual IP, e.g., `10.10.0.2`. Must be within the network range. The default value auto-assigns an available IP.
+- **Port**: Device port, e.g., `51820`. For public nodes, match the endpoint port; selecting an endpoint will auto-fill it.
+- **MTU**: Device MTU, e.g., `1420`. The default is recommended.
+- **Labels**: Labels used for **direct connection** permissions. Use English and avoid special characters.
+
+Click **Submit** to create the device.
+
+### 5. Test the network
+
+If everything goes well, your devices should now be networked. In **Network**, pick your network and open the **Topology** tab to view the routing graph.
+
+In theory, if the shortest-path topology shows a route between two nodes (regardless of hops), those nodes can communicate.
+
+Right-click a node in the topology and choose **Open Terminal** to test connectivity.
+
+For example, on the `10.10.0.1` node, run `ping 10.10.0.2`. If it succeeds, networking works.
+
+Click each edge to view detailed routing info.
+
+### 6. Optimize the network (optional)
+
+These settings help nodes pick better links. They do not affect basic functionality.
+
+If things are stable, avoid manual optimization: manual links ignore ACLs, do not adapt to network changes, and incorrect settings can break connectivity. Proceed carefully if you must optimize.
+
+By default, routing is based on latency only, which may be suboptimal.
+
+You can drag from a node’s right black dot to another node’s left black dot to create a connection. When creating manual connections, avoid selecting endpoints to prevent issues when endpoints change.
+
+You can provide actual bandwidth so it factors into shortest-path calculations.
+
+If you need two nodes to always connect directly, you have two options:
+
+1. Configure ACLs so the two nodes can only communicate via direct connections.
+2. Create a manual connection between them and set bandwidth to 1000 Mbps so they prefer a direct link.
+
diff --git a/docs/public/images/wg-net-example.svg b/docs/public/images/wg-net-example.svg
new file mode 100644
index 0000000..2c2a01f
--- /dev/null
+++ b/docs/public/images/wg-net-example.svg
@@ -0,0 +1,4 @@
+
+
+
\ No newline at end of file
diff --git a/docs/wireguard.md b/docs/wireguard.md
new file mode 100644
index 0000000..11ff61d
--- /dev/null
+++ b/docs/wireguard.md
@@ -0,0 +1,158 @@
+# WireGuard 多跳智能组网
+
+- 作者的开发笔记:[WireGuard 多跳智能组网功能开发笔记](https://vaala.cat/posts/frp-panel-with-wireguard/),点开有好玩的 Demo 哦!
+
+> 组网功能目前处于测试阶段(最低支持版本:v0.1.25),可能存在一些问题,欢迎加入QQ群、提交Issue、发送邮件反馈
+
+> 组网功能目前仅支持 Linux 操作系统组网
+
+frp-panel 目前内置了 wiregaurd-go 用于实现组网功能。并且实现了 wireguard over UDP/Websocket 多跳组网、自定义路由、拓扑,按延迟和带宽智能计算最短路由,可以在复杂网络环境下实现优秀的组网体验。
+
+## 开始组网
+
+### 0. 概念介绍
+
+在开始之前,你需要保证满足以下所有条件
+
+1. 网络中至少有一个 Client 有公网IP作为中继节点
+2. 参与组网的设备只能是 Linux 系统
+3. 需要保证至少安装了 frp-panel master 和 frp-panel client
+4. 需要以 root 用户权限安装 frp-panel client
+
+接下来我们以一个简单介绍一下 frp-panel 组网的概念。
+
+组网侧边菜单栏中,有四个子菜单。名字和对应的作用如下
+
+1. **网络**:同一网络中的 Client 可以互通组网,一个 Client 可以加入多个网络。
+2. **设备**:一个 Client 可以绑定多个设备,设备可以加入网络,同一网络中的设备可以互通。
+3. **端点**:一个设备可以绑定多个端点,端点可以被其他设备连接,端点一般是公网IP+端口
+4. **连接**:同一网络中的两个设备之间可以建立连接,这两个设备至少有一个设备绑定有端点。
+
+这些概念可能比较绕,举一个例子
+
+
+
+图中,两个框代表了两个 Client。他们处于 `10.10.0.0/24` 这个相同的网络
+
+左侧的Client:
+- 拥有一个**设备** wg0 (虚拟网卡),设备的虚拟IP是 `10.10.0.1`
+- 设备 wg0 绑定了一个**端点** `10.10.0.1:51820`,这个端点是公网IP+端口
+- 设备 wg0 加入了一个**网络** `10.10.0.0/24`
+- 设备 wg0 可以与其他设备在网络 `10.10.0.0/24` 中互通
+
+右侧的Client:
+- 拥有一个**设备** wg0 (虚拟网卡),设备的虚拟IP是 `10.10.0.2`
+- 设备 wg0 加入了一个**网络** `10.10.0.0/24`
+- 设备 wg0 可以与其他设备在网络 `10.10.0.0/24` 中互通
+- 右侧的Client通过 `1.1.1.1:51820` 与左侧的Client建立了一个**连接**,这个连接的**端点**是 `1.1.1.1:51820`
+
+这样,右侧的Client 就可以通过 frp-panel 的组网功能与左侧的Client 进行通信了。
+
+### 1. 准备环境
+
+由于组网依赖操作系统中已有的一些功能,因此需要首先检查环境是否满足要求。
+
+打开终端,如果你的 Linux 系统拥有 `/etc/sysctl.d` 文件夹, 使用:
+```bash
+echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-frp-panel.conf
+echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-frp-panel.conf
+echo 'net.ipv4.icmp_echo_ignore_all = 1' | sudo tee -a /etc/sysctl.d/99-frp-panel.conf
+sudo sysctl -p /etc/sysctl.d/99-frp-panel.conf
+```
+否则, 使用 `/etc/sysctl.conf` 文件:
+```bash
+echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
+echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf
+echo 'net.ipv4.icmp_echo_ignore_all = 1' | sudo tee -a /etc/sysctl.conf
+sudo sysctl -p /etc/sysctl.conf
+```
+
+接下来,检查tun设备是否存在,如果存在,则跳过这一步,否则需要自行解决问题(为什么不问问神奇的AI呢):
+
+```bash
+ls /dev/net/tun
+```
+
+如果命令成功,则表示可以进行下一步
+
+### 2. 创建网络
+
+点击组网侧边菜单栏中的**网络**,然后点击右上角按钮**新建网络**,填写网络名称和CIDR,如果有ACL需求,请输入ACL,如果没有ACL请忽略。
+
+- **网络名称**:推荐小写英文,不要有特殊字符。
+- **CIDR**:填写网络的CIDR,例如 `10.10.0.0/24`,表示网络的IP分配范围,这个例子代表是 `10.10.0.0` 到 `10.10.0.255` 这个范围内的IP都可以被分配。
+- **ACL**:填写网络的ACL,可以控制节点之间建立**直接连接**的权限,格式如下:
+
+```json
+{
+ "acls": [
+ { "action": "allow", "src": ["cn"], "dst": ["cn"] },
+ { "action": "allow", "src": ["us"], "dst": ["us"] }
+ ]
+}
+```
+
+ACL 是 JSON 格式,`action` 可以是 `allow` 或 `deny`,`src` 和 `dst` 是标签,标签可以是任意字符串,用于圈选设备,可以在后面创建设备时为设备分配标签。
+
+例如,上面的例子表示,网络中的设备 `cn` 可以与设备 `cn` 直接连接,设备 `us` 可以与设备 `us` 直接连接。其他的设备之间无法直接连接。
+
+> 注意⚠️,手动建立的连接不受ACL控制
+
+点击**提交**按钮,网络创建成功。
+
+### 3. 创建端点(非公网节点可跳过)
+
+点击组网侧边菜单栏中的**端点**,然后点击按钮**新建端点**,按照以下要求填写
+- **客户端**:选择一个公网客户端
+- **主机名称**:填写节点的公网IP地址或域名,例如 `1.1.1.1` 或 `example.com`;
+- **端口**:填写节点可对外访问的公网端口,例如 `51820`;
+- **类型**:选择端点类型,支持 `ws` 和 `udp`,其中 `ws` 表示 WebSocket 类型,`udp` 表示 UDP 类型;
+- **URI**:UDP类型不填URI。ws类型请填写完整URI,例如 `ws://example.com:51820`;
+
+填写完成后点击创建。
+
+### 4. 创建设备
+
+点击组网侧边菜单栏中的**设备**,然后点击右上角按钮**加入网络**,用于将 Client 加入一个已知网络。
+
+按照以下要求填写
+
+- **客户端**:选择一个加入网络的客户端,要求是以 root 用户直接安装在 Linux 操作系统的 Client;
+- **网络**:选择一个已知网络;
+- **端点(非公网节点可跳过)**:选择一个已创建的端点;
+- **接口名称**:填写设备名,要求必须是小写英文+数字的形式,如`frpp0`,推荐使用表单的默认值,格式不正确会造成启动失败。
+- **本地地址**:这个设备在网络中的虚拟IP地址,例如 `10.10.0.2`,推荐使用表单的默认值(默认值会自动分配,即便表单显示重复也会自动分配),必须是在网络范围中的IP。
+- **端口**:填写设备的端口,例如 `51820`,公网节点推荐与端点端口一致,选择端点时会默认填充;
+- **MTU**:填写设备的MTU,例如 `1420`,推荐使用默认值;
+- **标签**:用于控制设备之间建立**直接连接**的权限,推荐使用全英文,不要有特殊字符
+
+填写完成后点击**提交**按钮,设备创建成功。
+
+### 5. 测试网络
+
+到这里,如果不出意外,你的设备已经组网成功。你可以点击“网络”菜单选择对应网络,进入“拓扑” tab页,查看自己网络的组网情况。
+
+理论上,只要最短路的拓扑图中,两个节点间有一条路线(无论中间经过了多少跳),那么这两个节点之间就可以通信。
+
+你可以在拓扑图节点上右键点击节点,选择“打开终端”,进入终端界面,测试节点之间是否可以通信。
+
+例如,在 `10.10.0.1` 节点终端输入 `ping 10.10.0.2`,如果ping通,则表示组网成功。
+
+点击每一条边,可以查看连接的详细路由等信息。
+
+### 6. 优化网络(可选)
+
+这一节的配置可以让两个节点选择更加优秀的连接,但不影响整体使用。
+
+如果使用正常,不推荐手动优化,因为手动连接会突破ACL限制、不适应网络变化,错误配置可能导致网络不可用。如果需要手动优化,请谨慎操作。
+
+此时的组网仅基于延迟计算最短路,可能会出现一些不理想的情况。
+
+这时你可以在图中随意找到一个节点,鼠标从右侧的黑色小点拖拽到另一个节点的左侧黑色小点,填写表单建立一个连接(手动连接时不推荐选择端点避免端点变化造成问题)。
+
+这时可以填写真实的带宽,将带宽也加入最短路权重计算。
+
+如果你想两个节点无论何时都直接连接,有两个方法:
+
+1. 配置ACL,让两个节点之间只能通过直接连接通信;
+2. 配置手动连接,为他们配置1000Mbps的带宽,让两个节点之间可以直接连接。
\ No newline at end of file