一个用 Rust 编写的现代、简单的 TCP 隧道,可将本地端口暴露给远程服务器,绕过标准的 NAT 连接防火墙。它只做一件事:不多也不少。

# 安装(需要 Rust,见下方其他方式)
cargo install bore-cli
# 在本地机器上
bore local 8000 --to bore.pub
这将把你的本地端口 localhost:8000 暴露给公共互联网上的 bore.pub:<PORT>,端口号是随机分配的。
类似于 localtunnel 和 ngrok,但 bore 旨在成为一个高效、无偏见的 TCP 流量转发工具,安装简单,易于自托管,没有任何花哨的功能。
(bore 总共约 400 行安全、异步的 Rust 代码,设置简单——只需为客户端和服务器运行一个二进制文件。)
bore 被打包为 Homebrew 核心公式。
brew install bore-cli
bore 在 AUR 中可用,包名为 bore。
yay -S bore # 或你喜欢的 AUR 助手
bore 在 gentoo-zh overlay 中可用。
sudo eselect repository enable gentoo-zh
sudo emerge --sync gentoo-zh
sudo emerge net-proxy/bore
否则,安装 bore 最简单的方式是从预构建的二进制文件。这些文件可在 releases 页面 上获取,支持 macOS、Windows 和 Linux。只需解压适合你平台的相应文件,然后将 bore 可执行文件移动到 PATH 中的某个文件夹。
你也可以使用 Cargo(Rust 包管理器)从源码构建 bore。以下命令将 bore 二进制文件安装到用户可访问的路径。
cargo install bore-cli
我们还会为每个版本发布带版本号的 Docker 镜像。该镜像针对 AMD 64 位架构构建。它们标有特定版本,允许你从最小化的 "scratch" 容器中运行静态链接的 bore 二进制文件。
docker run -it --init --rm --network host ekzhang/bore <ARGS>
本节介绍 bore CLI 命令的详细用法。
你可以使用 bore local 命令转发本地机器上的一个端口。该命令接受一个位置参数(要转发的本地端口),以及一个必需的 --to 选项,用于指定远程服务器的地址。
bore local 5000 --to bore.pub
你可以选择传递 --port 选项来指定远程服务器上的特定端口,但如果该端口不可用,命令将失败。此外,传递 --local-host 允许你在本地局域网中暴露不同于回环地址 localhost 的其他主机。
完整选项如下所示。
启动本地代理到远程服务器
用法: bore local [选项] --to <TO> <LOCAL_PORT>
参数:
<LOCAL_PORT> 要暴露的本地端口 [env: BORE_LOCAL_PORT=]
选项:
-l, --local-host <HOST> 要暴露的本地主机 [默认值: localhost]
-t, --to <TO> 暴露本地端口到的远程服务器地址 [env: BORE_SERVER=]
-p, --port <PORT> 要选择的远程服务器上的可选端口 [默认值: 0]
-s, --secret <SECRET> 用于认证的可选密钥 [env: BORE_SECRET]
-h, --help 打印帮助信息
如启动说明中所述,有一个运行在 bore.pub 的公共 bore 服务器实例。但如果你想在自己的网络上自托管 bore,可以运行以下命令:
bore server
就这么简单!服务器在给定地址上启动后,你可以更新 bore local 命令,添加 --to <ADDRESS> 选项,将本地端口转发到此远程服务器。
可以为控制服务器和隧道指定不同的 IP 地址。这种设置适用于你可能希望控制服务器在私有网络上,同时允许隧道连接通过公共接口(或反之)的情况。
bore server 命令的完整选项如下所示。
运行远程代理服务器
用法: bore server [选项]
选项:
--min-port <MIN_PORT> 最小的接受 TCP 端口号 [env: BORE_MIN_PORT=] [默认值: 1024]
--max-port <MAX_PORT> 最大的接受 TCP 端口号 [env: BORE_MAX_PORT=] [默认值: 65535]
-s, --secret <SECRET> 用于认证的可选密钥 [env: BORE_SECRET]
--bind-addr <BIND_ADDR> 要绑定的 IP 地址,客户端必须能够到达此地址 [默认值: 0.0.0.0]
--bind-tunnels <BIND_TUNNELS> 隧道将监听的 IP 地址,默认为 --bind-addr
-h, --help 打印帮助信息
有一个隐式的 控制端口 在 7835,用于按需创建新连接。初始化时,客户端在 TCP 控制端口向服务器发送一条 "Hello" 消息,请求代理一个选定的远程端口。然后服务器回复确认,并开始监听外部 TCP 连接。
每当服务器在远程端口上获得一个连接时,它会为该连接生成一个安全的 UUID,并将其发送回客户端。客户端随后打开一个到服务器的独立 TCP 流,并在该流上发送一个包含该 UUID 的 "Accept" 消息。然后服务器将这两个连接相互代理。
出于正确性原因并避免内存泄漏,传入连接仅在服务器上存储最多 10 秒,如果客户端未接受,则会被丢弃。
在自定义部署的 bore server 上,你可以选择要求一个 secret(密钥)来防止服务器被他人使用。该协议要求客户端通过回答随机挑战(HMAC 码)来验证每个 TCP 连接上是否持有该密钥。(此密钥仅用于初始握手,默认情况下不会对后续流量进行加密。)
# 在服务器上
bore server --secret my_secret_string
# 在客户端上
bore local <LOCAL_PORT> --to <TO> --secret my_secret_string
如果参数中没有提供 secret,bore 也会尝试从 BORE_SECRET 环境变量中读取。
由 Eric Zhang (@ekzhang1) 创建。基于 MIT 许可证 授权。
作者感谢 Tokio 项目的贡献者和维护者,使得用 Rust 编写人性化且高效的网络服务成为可能。