- Notifications
You must be signed in to change notification settings - Fork401
🕳 bore is a simple CLI tool for making tunnels to localhost
License
ekzhang/bore
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
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 machineborelocal 8000 --to bore.pub
This will expose your local port atlocalhost:8000
to the public internet atbore.pub:<PORT>
, where the port number is assigned randomly.
Similar tolocaltunnel andngrok, exceptbore
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.)
If you're on macOS,bore
is packaged as a Homebrew core formula.
brew install bore-cli
Otherwise, the easiest way to install bore is from prebuilt binaries. These are available on thereleases page for macOS, Windows, and Linux. Just unzip the appropriate file for your platform and move thebore
executable into a folder on your PATH.
You also can buildbore
from source usingCargo, the Rust package manager. This command installs thebore
binary at a user-accessible path.
cargo install bore-cli
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-linkedbore
binary from a minimal "scratch" container.
docker run -it --init --rm --network host ekzhang/bore<ARGS>
This section describes detailed usage for thebore
CLI command.
You can forward a port on your local machine by using thebore 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.
borelocal 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 addresslocalhost
.
The full options are shown below.
Starts alocal proxy to the remote serverUsage: borelocal [OPTIONS] --to<TO><LOCAL_PORT>Arguments:<LOCAL_PORT> Thelocal port to exposeOptions: -l, --local-host<HOST> Thelocal host to expose [default: localhost] -t, --to<TO> Address of the remote server to exposelocal ports to [env: BORE_SERVER=] -p, --port<PORT> Optional port on the remote server toselect[default: 0] -s, --secret<SECRET> Optional secretfor authentication [env: BORE_SECRET] -h, --help Printhelp information
As mentioned in the startup instructions, there is a public instance of thebore
server running atbore.pub
. However, if you want to self-hostbore
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 thebore local
command with option--to <ADDRESS>
to forward a local port to this remote server.
The full options for thebore server
command are shown below.
Runs the remote proxy serverUsage: bore server [OPTIONS]Options: --min-port<MIN_PORT> Minimum accepted TCP port number [default: 1024, env: BORE_MIN_PORT] --max-port<MAX_PORT> Maximum accepted TCP port number [default: 65535, env: BORE_MAX_PORT] -s, --secret<SECRET> Optional secretfor authentication [env: BORE_SECRET] -h, --help Printhelp information
There is an implicitcontrol port at7835
, 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 secureUUID 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.
On a custom deployment ofbore server
, you can optionally require asecret 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 serverbore server --secret my_secret_string# on the clientborelocal<LOCAL_PORT> --to<TO> --secret my_secret_string
If a secret is not present in the arguments,bore
will also attempt to read from theBORE_SECRET
environment variable.
Created by Eric Zhang (@ekzhang1). Licensed under theMIT license.
The author would like to thank the contributors and maintainers of theTokio project for making it possible to write ergonomic and efficient network services in Rust.
About
🕳 bore is a simple CLI tool for making tunnels to localhost