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: + +![Networking concept diagram](../public/images/wg-net-example.svg) + +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 @@ + + +1.1.1.1wg0: 10.10.0.1wg0: 10.10.0.210.10.0.0/242.2.2.2:51820 \ 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. **连接**:同一网络中的两个设备之间可以建立连接,这两个设备至少有一个设备绑定有端点。 + +这些概念可能比较绕,举一个例子 + +![组网概念示意图](/images/wg-net-example.svg) + +图中,两个框代表了两个 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