默认连接公共实例 bore.pub,远端端口随机分配,指定 --port 时端口被占用会失败;--secret 只用于握手认证,默认不加密隧道流量;自托管服务端默认绑定 0.0.0.0 且控制端口固定为 7835,需自行放行防火墙
cargo install bore-cli
bore local 8000 --to bore.pubREADME 未说明硬件要求,仅说明 Docker 镜像为 AMD 64 位架构构建
用 Rust 写的极简 TCP 隧道工具,把本地端口暴露到公网,可自托管
用 Rust 写的极简命令行工具,一条命令就能把本地端口暴露到公网,方便调试 Webhook、临时分享服务,无需配置复杂的内网穿透。
核心能力
- 用 bore local 把本地端口转发到远端服务器
- 用 bore server 一条命令自托管服务端
- 支持 --secret 通过 HMAC 挑战做客户端认证
- 控制端口固定 7835,按需建立隧道连接
- 约 400 行安全异步 Rust 代码,单二进制部署
容易踩的坑
- v0.6.0最新正式版2025-06-09 · 2025-06-09 20:13 UTC
This version fixes a bug in handling of half-closed TCP streams. Previously, half-closing a TCP stream (FIN) would result in the entire proxy connection being dropped, but now it only closes that half of the stream.
What's Changed
- Use copy_bidirectional, handle half-closed TCP streams by @ekzhang in https://github.com/ekzhang/bore/pull/165
Full Changelog: https://github.com/ekzhang/bore/compare/v0.5.3...v0.6.0
- v0.5.32025-04-14 · 2025-04-14 21:48 UTC
查看更新说明
What's Changed
- Fix Dockerfile by @StefMa in https://github.com/ekzhang/bore/pull/151
- docs: update installation instructions for Linux by @gouwazi in https://github.com/ekzhang/bore/pull/152
- Add configurable control/tunnel addresses for the server by @confor in https://github.com/ekzhang/bore/pull/162
New Contributors
- @StefMa made their first contribution in https://github.com/ekzhang/bore/pull/151
- @gouwazi made their first contribution in https://github.com/ekzhang/bore/pull/152
- @confor made their first contribution in https://github.com/ekzhang/bore/pull/162
Full Changelog: https://github.com/ekzhang/bore/compare/v0.5.2...v0.5.3
- v0.5.22024-12-05 · 2024-12-05 18:44 UTC
查看更新说明
What's Changed
- feat:add more target in github action flow by @czyt in https://github.com/ekzhang/bore/pull/120
- 🔧 Adding minimum and maximum port as environment variable by @ricardoapaes in https://github.com/ekzhang/bore/pull/136
- Expose local port as env value by @archer884 in https://github.com/ekzhang/bore/pull/132
- Update tracing-subscriber to support NO_COLOR environment variable by @silasalberti in https://github.com/ekzhang/bore/pull/146
New Contributors
- @czyt made their first contribution in https://github.com/ekzhang/bore/pull/120
- @ricardoapaes made their first contribution in https://github.com/ekzhang/bore/pull/136
- @archer884 made their first contribution in https://github.com/ekzhang/bore/pull/132
- @silasalberti made their first contribution in https://github.com/ekzhang/bore/pull/146
Full Changelog: https://github.com/ekzhang/bore/compare/v0.5.1...v0.5.2
- v0.5.12024-06-11 · 2024-06-11 01:51 UTC
查看更新说明
What's Changed
- Update Homebrew installation instructions by @ekzhang in https://github.com/ekzhang/bore/pull/80
- Fix typo, Maxmium -> Maximum by @kianmeng in https://github.com/ekzhang/bore/pull/81
- arm64 docker image by @kennycallado in https://github.com/ekzhang/bore/pull/114
- Fix CI runners by @ekzhang in https://github.com/ekzhang/bore/pull/118
- Bump version to 0.5.1 by @ekzhang in https://github.com/ekzhang/bore/pull/119
New Contributors
- @kianmeng made their first contribution in https://github.com/ekzhang/bore/pull/81
- @kennycallado made their first contribution in https://github.com/ekzhang/bore/pull/114
Full Changelog: https://github.com/ekzhang/bore/compare/v0.5.0...v0.5.1
- v0.5.02023-04-28 · 2023-04-28 02:05 UTC
查看更新说明
This version changes the behavior of bore in relation to the
--min-portoption. Now, when a minimum port is specified, any user that connects to bore by default (port: 0) will pick a random port that respects the value of the option. Previously the min port was only used as validation when the user connected with an explicitly specified--portvariable, and the OS was queried for a free port instead.This also lets us add a
--max-portoption, which was requested by multiple people.What's Changed
- Use random ports when port number is 0 by @ekzhang in https://github.com/ekzhang/bore/pull/79
Full Changelog: https://github.com/ekzhang/bore/compare/v0.4.1...v0.5.0
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
bore
A modern, simple TCP tunnel in Rust that exposes local ports to a remote server, bypassing standard NAT connection firewalls. That's all it does: no more, and no less.

# Installation (requires Rust, see alternatives below)
cargo install bore-cli
# On your local machine
bore local 8000 --to bore.pub
This will expose your local port at localhost:8000 to the public internet at bore.pub:<PORT>, where the port number is assigned randomly.
Similar to localtunnel and ngrok, except bore is intended to be a highly efficient, unopinionated tool for forwarding TCP traffic that is simple to install and easy to self-host, with no frills attached.
(bore totals about 400 lines of safe, async Rust code and is trivial to set up — just run a single binary for the client and server.)
Installation
macOS
bore is packaged as a Homebrew core formula.
brew install bore-cli
Linux
Arch Linux
bore is available in the AUR as bore.
yay -S bore # or your favorite AUR helper
Gentoo Linux
bore is available in the gentoo-zh overlay.
sudo eselect repository enable gentoo-zh
sudo emerge --sync gentoo-zh
sudo emerge net-proxy/bore
Binary Distribution
Otherwise, the easiest way to install bore is from prebuilt binaries. These are available on the releases page for macOS, Windows, and Linux. Just unzip the appropriate file for your platform and move the bore executable into a folder on your PATH.
Cargo
You also can build bore from source using Cargo, the Rust package manager. This command installs the bore binary at a user-accessible path.
cargo install bore-cli
Docker
We also publish versioned Docker images for each release. The image is built for an AMD 64-bit architecture. They're tagged with the specific version and allow you to run the statically-linked bore binary from a minimal "scratch" container.
docker run -it --init --rm --network host ekzhang/bore <ARGS>
Detailed Usage
This section describes detailed usage for the bore CLI command.
Local Forwarding
You can forward a port on your local machine by using the bore local command. This takes a positional argument, the local port to forward, as well as a mandatory --to option, which specifies the address of the remote server.
bore local 5000 --to bore.pub
You can optionally pass in a --port option to pick a specific port on the remote to expose, although the command will fail if this port is not available. Also, passing --local-host allows you to expose a different host on your local area network besides the loopback address localhost.
The full options are shown below.
Starts a local proxy to the remote server
Usage: bore local [OPTIONS] --to <TO> <LOCAL_PORT>
Arguments:
<LOCAL_PORT> The local port to expose [env: BORE_LOCAL_PORT=]
Options:
-l, --local-host <HOST> The local host to expose [default: localhost]
-t, --to <TO> Address of the remote server to expose local ports to [env: BORE_SERVER=]
-p, --port <PORT> Optional port on the remote server to select [default: 0]
-s, --secret <SECRET> Optional secret for authentication [env: BORE_SECRET]
-h, --help Print help
Self-Hosting
As mentioned in the startup instructions, there is a public instance of the bore server running at bore.pub. However, if you want to self-host bore on your own network, you can do so with the following command:
bore server
That's all it takes! After the server starts running at a given address, you can then update the bore local command with option --to <ADDRESS> to forward a local port to this remote server.
It's possible to specify different IP addresses for the control server and for the tunnels. This setup is useful for cases where you might want the control server to be on a private network while allowing tunnel connections over a public interface, or vice versa.
The full options for the bore server command are shown below.
Runs the remote proxy server
Usage: bore server [OPTIONS]
Options:
--min-port <MIN_PORT> Minimum accepted TCP port number [env: BORE_MIN_PORT=] [default: 1024]
--max-port <MAX_PORT> Maximum accepted TCP port number [env: BORE_MAX_PORT=] [default: 65535]
-s, --secret <SECRET> Optional secret for authentication [env: BORE_SECRET]
--bind-addr <BIND_ADDR> IP address to bind to, clients must reach this [default: 0.0.0.0]
--bind-tunnels <BIND_TUNNELS> IP address where tunnels will listen on, defaults to --bind-addr
-h, --help Print help
Protocol
There is an implicit control port at 7835, used for creating new connections on demand. At initialization, the client sends a "Hello" message to the server on the TCP control port, asking to proxy a selected remote port. The server then responds with an acknowledgement and begins listening for external TCP connections.
Whenever the server obtains a connection on the remote port, it generates a secure UUID for that connection and sends it back to the client. The client then opens a separate TCP stream to the server and sends an "Accept" message containing the UUID on that stream. The server then proxies the two connections between each other.
For correctness reasons and to avoid memory leaks, incoming connections are only stored by the server for up to 10 seconds before being discarded if the client does not accept them.
Authentication
On a custom deployment of bore server, you can optionally require a secret to prevent the server from being used by others. The protocol requires clients to verify possession of the secret on each TCP connection by answering random challenges in the form of HMAC codes. (This secret is only used for the initial handshake, and no further traffic is encrypted by default.)
# on the server
bore server --secret my_secret_string
# on the client
bore local <LOCAL_PORT> --to <TO> --secret my_secret_string
If a secret is not present in the arguments, bore will also attempt to read from the BORE_SECRET environment variable.
Acknowledgements
Created by Eric Zhang (@ekzhang1). Licensed under the MIT license.
The author would like to thank the contributors and maintainers of the Tokio project for making it possible to write ergonomic and efficient network services in Rust.