{"id":13395166,"url":"https://github.com/ekzhang/bore","last_synced_at":"2025-05-13T15:04:39.493Z","repository":{"id":37498922,"uuid":"477528511","full_name":"ekzhang/bore","owner":"ekzhang","description":"🕳 bore is a simple CLI tool for making tunnels to localhost","archived":false,"fork":false,"pushed_at":"2025-04-14T21:52:18.000Z","size":69,"stargazers_count":9733,"open_issues_count":9,"forks_count":414,"subscribers_count":57,"default_branch":"main","last_synced_at":"2025-05-05T22:41:56.160Z","etag":null,"topics":["cli","localhost","networking","proxy","rust","self-hosted","tcp","tunnel"],"latest_commit_sha":null,"homepage":"http://bore.pub","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ekzhang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["ekzhang"]}},"created_at":"2022-04-04T02:47:54.000Z","updated_at":"2025-05-05T21:41:14.000Z","dependencies_parsed_at":"2024-09-29T20:40:50.683Z","dependency_job_id":"8fc8d181-0672-4596-aad8-4042405de5ff","html_url":"https://github.com/ekzhang/bore","commit_stats":{"total_commits":38,"total_committers":11,"mean_commits":"3.4545454545454546","dds":0.2894736842105263,"last_synced_commit":"931f2aa20b4b7b04defdd063167450ae4c981f44"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ekzhang%2Fbore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ekzhang%2Fbore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ekzhang%2Fbore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ekzhang%2Fbore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ekzhang","download_url":"https://codeload.github.com/ekzhang/bore/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253968880,"owners_count":21992259,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","localhost","networking","proxy","rust","self-hosted","tcp","tunnel"],"created_at":"2024-07-30T17:01:44.754Z","updated_at":"2025-05-13T15:04:39.436Z","avatar_url":"https://github.com/ekzhang.png","language":"Rust","readme":"# bore\n\n[![Build status](https://img.shields.io/github/actions/workflow/status/ekzhang/bore/ci.yml)](https://github.com/ekzhang/bore/actions)\n[![Crates.io](https://img.shields.io/crates/v/bore-cli.svg)](https://crates.io/crates/bore-cli)\n\nA 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.**\n\n![Video demo](https://i.imgur.com/vDeGsmx.gif)\n\n```shell\n# Installation (requires Rust, see alternatives below)\ncargo install bore-cli\n\n# On your local machine\nbore local 8000 --to bore.pub\n```\n\nThis will expose your local port at `localhost:8000` to the public internet at `bore.pub:\u003cPORT\u003e`, where the port number is assigned randomly.\n\nSimilar to [localtunnel](https://github.com/localtunnel/localtunnel) and [ngrok](https://ngrok.io/), 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.\n\n(`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.)\n\n## Installation\n\n### macOS\n\n`bore` is packaged as a Homebrew core formula.\n\n```shell\nbrew install bore-cli\n```\n\n### Linux\n\n#### Arch Linux\n\n`bore` is available in the AUR as `bore`.\n\n```shell\nyay -S bore # or your favorite AUR helper\n```\n\n#### Gentoo Linux\n\n`bore` is available in the [gentoo-zh](https://github.com/microcai/gentoo-zh) overlay.\n\n```shell\nsudo eselect repository enable gentoo-zh\nsudo emerge --sync gentoo-zh\nsudo emerge net-proxy/bore\n```\n\n### Binary Distribution\n\nOtherwise, the easiest way to install bore is from prebuilt binaries. These are available on the [releases page](https://github.com/ekzhang/bore/releases) for macOS, Windows, and Linux. Just unzip the appropriate file for your platform and move the `bore` executable into a folder on your PATH.\n\n### Cargo\n\nYou also can build `bore` from source using [Cargo](https://doc.rust-lang.org/cargo/), the Rust package manager. This command installs the `bore` binary at a user-accessible path.\n\n```shell\ncargo install bore-cli\n```\n\n### Docker\n\nWe 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.\n\n```shell\ndocker run -it --init --rm --network host ekzhang/bore \u003cARGS\u003e\n```\n\n## Detailed Usage\n\nThis section describes detailed usage for the `bore` CLI command.\n\n### Local Forwarding\n\nYou 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.\n\n```shell\nbore local 5000 --to bore.pub\n```\n\nYou 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`.\n\nThe full options are shown below.\n\n```shell\nStarts a local proxy to the remote server\n\nUsage: bore local [OPTIONS] --to \u003cTO\u003e \u003cLOCAL_PORT\u003e\n\nArguments:\n  \u003cLOCAL_PORT\u003e  The local port to expose [env: BORE_LOCAL_PORT=]\n\nOptions:\n  -l, --local-host \u003cHOST\u003e  The local host to expose [default: localhost]\n  -t, --to \u003cTO\u003e            Address of the remote server to expose local ports to [env: BORE_SERVER=]\n  -p, --port \u003cPORT\u003e        Optional port on the remote server to select [default: 0]\n  -s, --secret \u003cSECRET\u003e    Optional secret for authentication [env: BORE_SECRET]\n  -h, --help               Print help\n```\n\n### Self-Hosting\n\nAs 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:\n\n```shell\nbore server\n```\n\nThat's all it takes! After the server starts running at a given address, you can then update the `bore local` command with option `--to \u003cADDRESS\u003e` to forward a local port to this remote server.\n\nIt'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.\n\nThe full options for the `bore server` command are shown below.\n\n```shell\nRuns the remote proxy server\n\nUsage: bore server [OPTIONS]\n\nOptions:\n      --min-port \u003cMIN_PORT\u003e          Minimum accepted TCP port number [env: BORE_MIN_PORT=] [default: 1024]\n      --max-port \u003cMAX_PORT\u003e          Maximum accepted TCP port number [env: BORE_MAX_PORT=] [default: 65535]\n  -s, --secret \u003cSECRET\u003e              Optional secret for authentication [env: BORE_SECRET]\n      --bind-addr \u003cBIND_ADDR\u003e        IP address to bind to, clients must reach this [default: 0.0.0.0]\n      --bind-tunnels \u003cBIND_TUNNELS\u003e  IP address where tunnels will listen on, defaults to --bind-addr\n  -h, --help                         Print help\n```\n\n## Protocol\n\nThere 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.\n\nWhenever the server obtains a connection on the remote port, it generates a secure [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier) 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.\n\nFor 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.\n\n## Authentication\n\nOn 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.)\n\n```shell\n# on the server\nbore server --secret my_secret_string\n\n# on the client\nbore local \u003cLOCAL_PORT\u003e --to \u003cTO\u003e --secret my_secret_string\n```\n\nIf a secret is not present in the arguments, `bore` will also attempt to read from the `BORE_SECRET` environment variable.\n\n## Acknowledgements\n\nCreated by Eric Zhang ([@ekzhang1](https://twitter.com/ekzhang1)). Licensed under the [MIT license](LICENSE).\n\nThe author would like to thank the contributors and maintainers of the [Tokio](https://tokio.rs/) project for making it possible to write ergonomic and efficient network services in Rust.\n","funding_links":["https://github.com/sponsors/ekzhang"],"categories":["Rust","HarmonyOS","Networking","Online tools","Uncategorized","cli","\u003ca name=\"networking\"\u003e\u003c/a\u003eNetworking","Lovely Commands","Projects","Development tools"],"sub_categories":["Windows Manager","Kubernetes","Sharing Stuff","Uncategorized","Tunnel"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fekzhang%2Fbore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fekzhang%2Fbore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fekzhang%2Fbore/lists"}