novemus/plexus
GitHub: novemus/plexus
一款利用 STUN 实现打洞的 NAT 穿透工具,让无公网 IP 的设备通过 DHT 或邮件交汇点建立直接 P2P 连接。
Stars: 38 | Forks: 3
# README
[plexus](https://github.com/novemus/plexus) 工具旨在为位于 NAT 后方的机器上运行的应用程序之间建立直接网络连接提供可能。为此,`plexus` 使用 STUN 实现了著名的 *UDP/TCP 打洞* 技术。你可以使用 `DHT` 网络或 `Email` 服务作为交汇点 (rendezvous),在本地和远程应用实例之间交换公网地址。为了成功建立连接,至少需要双方的 NAT 实现将内部地址映射到公网地址时采取独立映射策略。也就是说,当出站数据包的目标地址/端口发生改变,而出站数据包的源地址/端口保持不变时,NAT 分配的公网地址和端口不应改变。此外,如果你想使用 `Email` 作为交汇点,你还需要一个可访问的 STUN 服务器以及双方的电子邮件账户。`plexus` 还支持通过 [ricochet](https://github.com/novemus/ricochet) 中继服务器进行间接连接。
对于偏好 GUI 的用户,这里有一个基于 `plexus` 库的 [webpier](https://github.com/novemus/webpier) 应用程序。
## 构建
你可以下载适用于 Linux、MacOS 和 Windows 平台的 [预编译包](https://github.com/novemus/plexus/releases)。
该项目依赖于 [boost](https://github.com/boostorg/boost)、[openssl](https://github.com/openssl/openssl)、[opendht](https://github.com/savoirfairelinux/opendht)、[wormhole](https://github.com/novemus/wormhole)、[tubus](https://github.com/novemus/tubus) 和 [ricochet-client](https://github.com/novemus/ricochet) 库。克隆仓库,然后配置并构建项目。
```
$ cd ~
$ git clone https://github.com/novemus/plexus.git
$ cd ~/plexus
$ [PKG_CONFIG_PATH=...] [CMAKE_PREFIX_PATH=...] cmake -B ./build -DCMAKE_BUILD_TYPE=Release [-DBUILD_SHARED_LIBS=ON] [-DBOOST_ROOT=...] [-DOPENSSL_ROOT_DIR=...]
$ cmake --build ./build --target all
$ cmake --build ./build --target install
```
## 使用说明
创建一个应用程序仓库,并按照 *apprepo/owner@mailer.com/pin* 的格式指定宿主机目录路径。你必须在那里放置宿主机的 X509 *cert.crt* 证书和 *private.key* 私钥。同样地,为对等端创建目录,并在其中放置其 *cert.crt* 证书。在对等端机器上执行相同的操作。如果你使用 `DHT` 作为交汇点,中间目录 *.../owner@mailer.com/...* 可以随意命名,但对于 `Email` 的情况,它必须使用相应的电子邮件地址作为名称。因此,为了兼容性,建议始终使用电子邮件地址。
要运行以下示例,你需要安装 *openvpn*。*exec.sh* 脚本将尝试建立点对点 VPN 连接。
接受方命令:
```
$ plexus --app-name=appname --app-repo=/path/to/apprepo --accept --dht-bootstrap=bootstrap.jami.net --host-id=host@mailer.com/hostid --peer-id=peer@mailer.com/peerid --udp-stun=stun.someserver.com[:xxxx] --exec-cmd=~/plexus/tests/exec.sh [--app-qos=udp:either]
```
邀请方命令:
```
$ plexus --app-name=appname --app-repo=/path/to/apprepo --dht-bootstrap=bootstrap.jami.net --host-id=host@mailer.com/hostid --peer-id=peer@mailer.com/peerid --udp-stun=stun.someserver.com[:xxxx] --exec-cmd=~/plexus/tests/exec.sh [--app-qos=udp:either]
```
`--app-name` 键用于指定目标应用程序。`--host-id` 参数指向本地应用程序标识,而 `--peer-id` 指向远程应用程序标识。`--app-repo` 键用于指定应用程序仓库。`--accept` 键指示应用程序循环接受来自远程的邀请。它只能在一方设置。如果你想接受多个对等端,只需省略 `--peer-id` 参数即可。在这种情况下,仓库中包含的每个对等端都将被接受。要设置特定的应用程序条件,你可以使用带有以下任意值的 `--app-qos` 键:*udp:client|udp:server|udp:mutual|tcp:client|tcp:server|tcp:mutual|ssl:client|ssl:server|ssl:mutual|any:either*。特殊值 *any:either* 允许协商最合适的传输协议和连接模式,因此它仅对特殊的应用程序或场景有意义。协商可能导致双方均采用 *mutual* 连接模式,这与 *client* 模式相同,这意味着 ssl 应用程序不仅必须能够相互连接,还要能够为 ssl 握手选择适当的角色。
某些 *NAT* 在接收到不符合过滤策略的入站数据包时可能会丢弃映射。这个数据包可能是 `plexus` 发送给对等端的打洞包。为了避免这种情况,`plexus` 将打洞包的 *ttl* 设置为一个较小的值,默认为 7。通常,这足以让数据包穿过宿主机 NAT 以进行打洞,但又不足以到达对等端 NAT,从而避免丢弃其对等端映射。如有必要,你可以使用 `--nat-hops` 参数设置更合适的 *ttl*,并通过某些路由工具确定合适的值。
一旦两个 `plexus` 实例相互打通了 *通道 (passage)*,由 `--exec-cmd` 指定的命令就会启动。你可以通过 `--exec-args` 参数将你的参数传递给可执行文件,支持以下通配符:
`%inner%` - 由 `--udp-bind` 或 `--tcp-bind` 参数指定的本地 endpoint
`%outer%` - 由 NAT 分配的公网 endpoint
`%alien%` - 通过交汇点收到的对等端公网 endpoint
`%qos%` - 由交汇点协商一致的应用程序条件
`%hostid%` - 由 `--host-id` 参数指定的宿主机标识符
`%peerid%` - 由 `--peer-id` 参数指定的对等端标识符
你还可以设置 `--exec-env` 参数,以便将额外的环境变量列表传递给命令,支持以下通配符:
`%secret%` - 由交汇点协商一致的共享 64 位密钥
`%hostcert%` - 宿主机证书的路径
`%hostkey%` - 宿主机私钥的路径
`%peercert%` - 对等端证书的路径
要了解附加参数,请使用 `--help` 键运行该工具。
## 扩展与库
众所周知,TCP 应用程序通过 NAT 建立的连接并不稳定,但 `plexus` 可以在可能的情况下穿透 TCP 洞。在双方使用 `--tcp-stun` 键指定 TCP STUN 服务器以及适当的 `--app-qos` 参数。强烈建议同时指定 `--udp-stun` 参数,因为 `plexus` 在将控制权移交给你的应用程序之前,会使用 UDP 握手来同步双方。如果你需要更强的 NAT 容错能力来连接 TCP 应用程序,请考虑将 [wormhole](https://github.com/novemus/wormhole) 隧道工具作为执行 payload。例如,你可以使用以下 payload 参数转发远程 *ssh* 服务。
远程机器:
```
--exec-cmd=wormhole --exec-args="--purpose=export --service=127.0.0.1:22 --gateway=%inner% --faraway=%alien%" --exec-log=export.ssh.log --exec-env="WORMHOLE_SECRET=%secret%"
```
本地机器:
```
--exec-cmd=wormhole --exec-args="--purpose=import --service=127.0.0.1:2222 --gateway=%inner% --faraway=%alien%" --exec-log=import.ssh.log --exec-env="WORMHOLE_SECRET=%secret%"
```
然后通过本地映射连接到远程 *ssh*:
```
$ ssh -p 2222 127.0.0.1
```
`plexus` 库 API 在 [plexus.h](https://github.com/novemus/plexus/blob/master/src/plexus/plexus.h) 头文件中进行了描述。
## Bug 与改进
欢迎随时[报告](https://github.com/novemus/plexus/issues) Bug 并[提出](https://github.com/novemus/plexus/issues)改进建议。
## 许可证
Plexus 采用 Apache License 2.0 进行授权,这意味着只要满足其条件,你就可以自由地将其用于商业和非商业目的。有关更多详细信息,请参阅 LICENSE.txt 文件。
## 版权
版权所有 © 2022 Novemus Band。保留所有权利。
标签:Bash脚本, C++, NAT穿透, P2P网络, STUN, UDP/TCP打洞, 安全测试工具, 数据擦除, 网络工具