-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
524 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,3 +19,6 @@ | |
|
||
# Go workspace file | ||
go.work | ||
|
||
# any binary | ||
*.bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# wgsd | ||
|
||
Wireguard Peer Discovery Helper | ||
|
||
> As we all know, Wireguard is a point-to-point VPN protocol. However, most people and tutorials typically use a star-shaped topology, which means that every node needs to go through a central node to connect to other nodes. But when it comes to achieving P2P connections, it becomes a challenge due to Wireguard's lack of built-in device discovery. This often requires two nodes, with one of them having a fixed public network or manually modifying the configuration files each time. This tool is created to address this issue! | ||
### Principle | ||
|
||
In reality, it's quite simple. You run a service on each node, and the central node no longer handles data exchange; instead, it is used for device discovery. The main function of each service is to obtain the peer addresses of devices corresponding to local public keys from specified addresses. It also serves other devices, providing them with the peer addresses of all locally connected devices. This concept is somewhat akin to a simplified version of a DHT (Distributed Hash Table network structure) (although it is far from the same level of complexity). | ||
|
||
For example, suppose you have the following devices: | ||
|
||
| Device Name | Public Address (Address+Port) | Peer Address | | ||
| ----------- | ----------------------------- | ------------ | | ||
| A | 10.0.114.1:19198 | 10.0.6.1 | | ||
| B | NAT: 10.0.114.2:11451 | 10.0.6.2 | | ||
| C | NAT: 10.0.114.2:11452 | 10.0.6.3 | | ||
|
||
In this scenario, typically, you would configure A as a peer on B and C. But what if you need B and C to communicate directly? Even though they are on the same local network and can assign LAN peer addresses to each other directly, if B and C are on different networks, manual address configuration becomes impractical. Moreover, with each connection, the port for address translation may vary. | ||
|
||
Solution: | ||
With wgsd, this process can be simplified. Start by running `./wgsd -l :51220` on A (51220 is the server port, the port that other nodes will connect to). Then, on B and C, run `./wgsd -l :51221 -u IP:51220 "Server Public Key" "Multiple Public Keys" (the public keys are used to prevent circular configurations). With A having a public network connection and accessible by B and C, B can use A's service to obtain C's peer address (and vice versa). As a result, B can directly connect to C, thereby achieving P2P connections! | ||
|
||
Additionally, each instance of wgsd can function as both a server and a client, enabling the creation of a cellular network discovery. | ||
|
||
### Usage | ||
|
||
```bash | ||
# Server | ||
./wgsd -l :51220 | ||
|
||
# Client | ||
./wgsd -l :51221 -u IP:51220 "Server Public Key" "Multiple Public Keys" (public keys are used to prevent circular configurations) | ||
``` | ||
|
||
### TODO | ||
|
||
1. Add support for multiple servers on the client. | ||
2. Implement a handshake simulation before writing to the Wireguard configuration file to verify connectivity. | ||
3. Implement automatic discovery of wgsd services. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,43 @@ | ||
# wgsd | ||
|
||
[English README](README.en.md) | ||
|
||
Wireguard peer discover helper (Wireguard 对等发现助手) | ||
|
||
> 众所周知 Wireguard 是点对点的 VPN 协议, 但是大部分人或者教程都是使用辐射状的拓扑结构, 也就是说每个节点要和其他节点连接都要经过中心节点, 但是想实现 P2P 又会由于 Wireguard 没有内置设备发现的原因需要两个节点又一方是固定公网或者每次都手动修改配置文件, 这个工具就是为了解决这个问题而生的! | ||
### 原理 | ||
|
||
其实很简单, 就是在每个节点上都运行一个服务, 中心节点不做数据交换了, 而是用于设备发现, 每个服务的职能是从指定的地址获取本地公钥对应的设备的对等地址以及服务其他设备获取本地已连接的所有设备的对等地址, 有点类似简化版的 DHT (分布式 HASH 表网络结构) (虽然差得远了) | ||
|
||
比如我有如下设备: | ||
|
||
| 设备名称 | 公网地址 (地址+端口) | 对等地址 | | ||
| -------- | -------------------------- | -------- | | ||
| A | 10.0.114.1:19198 | 10.0.6.1 | | ||
| B | 地址转换: 10.0.114.2:11451 | 10.0.6.2 | | ||
| C | 地址转换: 10.0.114.2:11452 | 10.0.6.3 | | ||
|
||
这种情况下通常会在 B, C 上配置 A 作为对等点, 但是假如我需要 B 和 C 通信怎么办, 虽然这里他们是在同一局域网能直接给双方互相配局域网对等地址 | ||
但是假如 B 和 C 是在两个网络, 这样很显然手动配置地址太麻烦, 并且每次连接都是地址转换的端口都是变化的... | ||
|
||
解决方法: | ||
用 wgsd 就能简化这个步骤, 首先在 A 上面运行 `./wgsd.bin -l :51220` (51220 是服务端口, 也就是其他节点要连接的端口), 然后在 B, C 上面运行 `./wgsd.bin -l :51221 -u 10.0.6.1:51220 "A"` (由于 A 有公网可以直连, 此刻 B, C 都是可以正常访问 10.0.6.1 这个地址的, 后面的 `"A"` 是 A 的公钥用来防止循环配置), 这样 B 就可以通过 A 的服务获取到 C 的对等地址 (反之亦然), 然后 B 就可以直接连接 C 了, 这样就实现了 P2P 的连接了! | ||
|
||
并且每个 wgsd 可以同时为服务端和客户端所以这样能实现蜂窝结构网络发现! | ||
|
||
### 使用 | ||
|
||
```bash | ||
# 服务端 | ||
./wgsd -l :51220 | ||
|
||
# 客户端 | ||
./wgsd -l :51221 -u IP:51220 "服务端公钥" "可以多个公钥" (公钥用于防止循环配置) | ||
``` | ||
|
||
### TODO | ||
|
||
1. 客户端支持多个服务端 | ||
2. 在写入到 Wireguard 配置文件前先模拟握手检查是否能连接 | ||
3. 实现自动发现 wgsd 服务 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
module wgsd | ||
|
||
go 1.21.3 | ||
|
||
// replace uw => /data/Code/Golang/uw | ||
replace uw => github.com/ClarkQAQ/uw v0.0.0-20230911090314-9617b4352e12 | ||
|
||
require ( | ||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 | ||
uw v0.0.0-00010101000000-000000000000 | ||
) | ||
|
||
require ( | ||
github.com/google/go-cmp v0.5.9 // indirect | ||
github.com/josharian/native v1.1.0 // indirect | ||
github.com/mdlayher/genetlink v1.3.2 // indirect | ||
github.com/mdlayher/netlink v1.7.2 // indirect | ||
github.com/mdlayher/socket v0.4.1 // indirect | ||
golang.org/x/crypto v0.8.0 // indirect | ||
golang.org/x/net v0.9.0 // indirect | ||
golang.org/x/sync v0.1.0 // indirect | ||
golang.org/x/sys v0.7.0 // indirect | ||
golang.zx2c4.com/wireguard v0.0.0-20230325221338-052af4a8072b // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
github.com/ClarkQAQ/uw v0.0.0-20230911090314-9617b4352e12 h1:sOV864zIZ/O805fwe8N03lJNSv7/s7loieQaEss8dyU= | ||
github.com/ClarkQAQ/uw v0.0.0-20230911090314-9617b4352e12/go.mod h1:rJFsUALhFkhhxOfSzBsYArYI77cswsrmld6Pa/NoL90= | ||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= | ||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | ||
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= | ||
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= | ||
github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw= | ||
github.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o= | ||
github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g= | ||
github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw= | ||
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U= | ||
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= | ||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws= | ||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc= | ||
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= | ||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= | ||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= | ||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= | ||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= | ||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= | ||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.zx2c4.com/wireguard v0.0.0-20230325221338-052af4a8072b h1:J1CaxgLerRR5lgx3wnr6L04cJFbWoceSK9JWBdglINo= | ||
golang.zx2c4.com/wireguard v0.0.0-20230325221338-052af4a8072b/go.mod h1:tqur9LnfstdR9ep2LaJT4lFUl0EjlHtge+gAjmsHUG4= | ||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE= | ||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80= |
Oops, something went wrong.