Bore: A simple CLI tool for making tunnels to localhost
github.comI maintain a list of ngrok/Cloudflare Tunnel alternatives here:
https://github.com/anderspitman/awesome-tunneling
It's interesting to me how many times this particular wheel has been reinvented. That said, it's a great exercise and one I highly recommend if you want to learn a bit more about networking.
I like the minimalism of this implementation.
Thanks for the feedback! I’ve actually seen your list before developing bore, and it was definitely an inspiration for me. Super helpful resource :)
I only found out about ngrok from following a guide for the Twilio API. The local tunnel problem is one I’ve had multiple times, but it’s never seemed worth the effort to find a solution. It’s also simple to solve, so I can see how many people end up implementing it without Googling for an existing solution first.
This problem disappears entirely on IPv6. Even more minimal (:
Most major ISPs in Poland provide only a single IPv6 address to their customers, so unfortunately you still have to deal with NAT.
I am curious about the reason: is it just easier for them to manage such configuration?
These are the major ways networks can set up IPv6:
https://www.ictshore.com/free-ccna-course/dhcpv6-basics/
You can see the easiest one will be SLAAC since you don't have to set up anything but IPv6, but you should be able to see that you can't SLAAC someone a single address. So one possibility is they use DHCP to do it -- DHCP on v6 is pretty similar to IPv4, and can give out single addresses. Another possibility is something called route-filtering. But these are both more complex than SLAAC, so it begs the question why would the sysadmin do something more complex when something easier is (well) easier?
In addition to move your packets around, the ISP needs to know about you moving those packets around, and this typically feeds into accounting and compliance.
One way ISPs do accounting is by monitoring traffic on a link level: This usually involves setting up some database to poll the networking hardware periodically, for example using SNMP polling: https://www.ibm.com/docs/en/networkmanager/4.2.0?topic=mecha... -- this information is then sent to the departments that need usage information.
Another way, is kindof lame, is to do it by assignment: Instead of monitoring the traffic you generate, they arrange for their DHCP-v6 server to trigger an event, for example using SNMP traps or more frequently, by reading the syslog output for ip addresses.
Not knowing anything about Poland except I like your food, but knowing how sysadmins are: my guess is that the move from IPv4 to IPv6 was motivated by trying to reuse some of this accounting/compliance (or configuration) infrastructure the ISP had to build for their IPV4 network. And if all your ISPs do it, well, maybe it's because they all used to be one ISP or the sysadmin-club in Poland is pretty small.
All that being said, something I have seen a few ISPs do in rural UK is interesting: They give you a router which does the NAT locally-- it used SLAAC to establish IPv6 and then it's running a link-local address for me. The effect is the same, but doing NAT carrier-side (or any other kind of connection tracking) is expensive, and more-so for IPv6 (all the addresses are bigger), so even if they gave you a single address, your ISP might not NAT'ing you in their network, but instead gave you a box that NAT's you by default. And if you have (root) access to your router, you can check if this is the case, otherwise you can buy your own router and see if you can swap it. The reason one company gave me for this is that it simplifies support and that "you know what you're doing anyway" so unless you know that you're being NAT'd inside their network, you should check because you might not be.
Can you elaborate? Someone else said that, but they refused more details when asked. Then someone else said you still need port forwarding with ipv6
With IPv6, it is typical (though not guaranteed) that you will be allocated an entire range of IPs rather than a single one. This then allows you to assign a unique, publicly routable address to every device on your local network.
I’m not sure if consumer hardware commonly supports this, or if it does what kind of firewalling they might do, so I have some slight doubt that IPv6 actually makes the problem Bore solves go away. I probably wouldn’t want every device on my network publicly routable even if it were possible — so even without NAT/port forwarding, there’s still a firewall to configure.
> there’s still a firewall to configure
All of my desktops and servers and laptops each have their own firewall, and this is good enough to protect against naughty programs who bind to INADDR_ANY instead of ::1 or a uds. I don't need to waste memory and latency on the router doing connection tracking that doesn't buy anything.
> I’m not sure if consumer hardware commonly supports this,
I have not run across consumer hardware that doesn't. I just tried a bunch of netgear, asus, and tplink kit and it was all fine. I've only run into a few ISPs that it didn't work with, and in every case a phone call was able to sort things out (because it had nothing to do with the consumer equipment). I suspect strongly that almost all consumer hardware commonly supports this.
> All of my desktops and servers and laptops each have their own firewall
Sure, but there are plenty of devices on my network that I don’t have that sort of control over (i.e. my light bulbs).
Get different light bulbs; My light bulbs require a password and route-filter. If yours don't, your firewall isn't protecting you if your computer can reach them because someone can just send you and iframe that pokes your light bulbs.
It does make the problem go away. You no longer need to traverse NAT which is what things like Bore and STUN/TURN/ICE do. With IPv6 every device has a public address you don’t really get a choice. Even for IPv4 NAT was an accident and it doesn't protect you from anything, the firewall via contrack does and the firewall still exists in IPv6. If Bore was just “firewall configuration for lazy people” then there are ways that don’t involve a remote server. You can just speak UPnP for instance.
> so even without NAT/port forwarding, there’s still a firewall to configure.
Yes, this is what I've noticed with consumer, ISP-provided routers in France. I think it's a rather good thing, although those same routers usually come with UPnP turned on...
It's a consumer router if you can buy it. If only your ISP buys it and they give to you, it isn't a "consumer router".
This has nothing to do with the router and more to do with your ISP. I had a UK provider which did that, but it was easy to swap their router (I did have to give them a call though). Here in Portugal the ISP-provided router was fine, so I am happy to use it.
How about UPNPC when your local gateway supports it?
sudo apt install miniupnpc
upnpc -r 22 57922 TCP # forward 57922 on public address to this client's port 22
Together with something like https://dynv6.com/ you even get a subdomain that you can point to the public address: curl "https://ipv4.dynv6.com/api/update?ipv4=auto&token=$TOKEN&zone=$ZONE.dynv6.net"
curl "https://ipv6.dynv6.com/api/update?ipv6=auto&token=$TOKEN&zone=$ZONE.dynv6.net"While this may be very simple to use, why would I use this in preference to SSH, given that SSH has figured out authentication, session security, etc?
Yes, setting this up with SSH is (mildly) more complex, but given the inherent security, one wonders why one would opt for simplicity.
There are different goals here and a different protocol. I use SSH remote port forwarding regularly for my work. It's ubiquitous, encrypted, and works in production. Bore has different goals; it strives for simplicity, ergonomics, efficiency, and correctness. Adding encryption to the tunnel is explicitly out of scope; bore only proxies raw TCP. If you want to add encryption, you would need to run it on top of bore, by setting up TLS termination on your own local web server (TLS runs on top of TCP) or using some other encrypted protocol.
The author has responded in their own top level comment. Currently the lowest comment on the page.
They have responded multiple times "see the FAQ" and "different goals" but haven't actually provided an example advantage of this over ssh -R. Unless the lack of security is a benefit somehow? Speed maybe?
Is SSH even available for Windows? I see people point to SSH a lot with this topic, but it seems like they assume that everyone has SSH already installed.
OpenSSH has been included with windows 10 by default for a number of years now
Nope. I just tried "ssh" and got command not found. Correction, look like they put it in a subfolder:
C:\Windows\System32\OpenSSH\ssh.exe
Hey, author of bore here! I've been summoned by my friend who saw this on the front page of HN. Thanks for posting.
Happy to answer any questions, though the README has most of the technical details already. Quick FAQ:
--
Q: What inspired this?
A: I wanted to make a really simple CLI tool for forwarding local TCP ports. No TLS termination or any other features. Localtunnel is unmaintained, slow, and requires Node.js. Ngrok v2 is proprietary, while Ngrok v1 is unmaintained, leaks memory, and is complicated to set up (requires wildcard certificates...). Why can't we just write a simple, minimal binary that does this? And focus on user experience (good error messages, clean code, systems correctness). That's the goal.
--
Q: Why Rust?
A: Because Rust gives you a lot of things: tracking lifetimes of variables statically, very fast code execution, data-race freedom guaranteed by the compiler, documentation, unit testing, simple binary distribution in the form of `cargo install`, and a strong focus on correctness. Tokio is also a _really_ great asynchronous runtime for writing network services.
--
Q: Why release a public server?
A: Mostly because I want it to be as easy as possible to try and access Bore, even if you don't have access or the technical means to run an instance in the cloud yourself. That said, "bore.pub" is not hard-coded anywhere inside the source code. The CLI usage examples explicitly pass in a mandatory `--to bore.pub` option to make sure that this software is not tied to any particular server instance. And an explicit goal of bore is to be easy to self-host, just run a single command (it's `bore server`) and you're all set.
--
Q: How much does this cost you?
A: I'm running the public server (bore.pub) on a $6/mo DigitalOcean droplet right now, the smallest size on shared vCPU. I just checked my dashboard, and it's only using 2% CPU at the moment. Will upgrade if I need to, but I don't expect the public server to incur significant fees unless bore gets _really_ popular.
--
Q: Is there potential for abuse?
A: I don't believe there's much potential for abuse here, in terms of distributing illegal content. If you wanted to do that, you could just set up port forwarding on your router and have people connect directly. Also, bore.pub doesn't guarantee you a stable TCP port to share with people; it's intended as a developer tool. So the risk seems fairly low.
--
Q: How can I help with this?
A: You can star the repository, share it with your friends, try using bore, and give any feedback on the issues page. Any help with packaging in software repositories or CI/CD binary builds would always be appreciated as well! Right now the only installation option is from source, using `cargo install bore-cli`. Finally, feel free to follow me on Twitter (https://twitter.com/ekzhang1) where I've been posting some updates on this work.
--
Q: How can I learn more?
A: Read the source code — it's literally 400 lines of Rust, super short if you have an hour or so this afternoon. :)
> If you wanted to do that, you could just set up port forwarding on your router and have people connect directly.
But that would expose their IP address. It’s easier to just use your bore.pub server and hide their IP address. If you don’t want to add authentication to the bore.pub server, I hope you have really good logging.
The server does have fairly good logging of each connection, including source IPs — feel free to contribute if you see anything that could be improved on this end though.
You may also want to record source ports and timestamps as many people are behind CGNATs.
> I'm running the public server (bore.pub) on a $6/mo DigitalOcean droplet right now, the smallest size on shared vCPU.
Does this not tunnel traffic. What is your plan once you go over the bandwidth allowance? It seems like you are probably in for some unexpected surprises very soon.
It tunnels traffic. The egress allowance for DigitalOcean droplets is quite high. If you’re concerned about the effect the cost would have on my personal well-being though, you’re welcome to support me in other ways. :)
Have you looked at the SOCKS proxy protocol? It has a BIND (i.e. "listen remotely") command that seems to essentially do the same thing as this, if I'm not mistaken.
Are there planned advantages to this over what can be done with “ssh -g -R”?
ngrok for instance can be used record and replay (potentially modified) API calls.
> I don't believe there's much potential for abuse here, in terms of distributing illegal content.
I think you are quite wrong there. Any public resource can and will be abused.
> If you wanted to do that, you could just set up port forwarding on your router
That will be easily traced back to the the distributor of the content. By using you as a relay the authorities will hit you first. If you keep accurate logs then you can send them onto the next step (which may well be another open proxy) but you'll have some explaining to do.
Also, if it causes any trouble for your service provider they may kick your account first and ask questions later, especially if the content is something insidious like CP. In any case check your service provider's ToS - they may explicitly disallow running open proxy services.
Thanks for the words of warning! I’ll keep a lookout for malicious uses, especially now that it’s gotten a bit of attention on HN, which was not planned. Feel free to let me know if you see something suspicious, as well.
This is a great tool, thank you. I would ignore the haters, plenty of people want something simple like this. Also, you should approach the Rust Foundation to see if they will fund the public site.
Time is probably more expensive for you than the droplet. But you can run stuff for free as well https://paul.totterman.name/posts/free-clouds/ . Or, even better, let the users of your software know how to run it for free themselves.
When I use CTL-C to exit the client, the return code is 130. Is there a way to terminate the client normally?
Great job! By the way, the term "bore" (בור) in hebrew means 'pit' :)
Thanks! That’s great. I was inspired by other commands like “dig” :)
This is a very slick tool that allows you to forward ports from your local machine to a public server at `bore.pub`.
I hope this service will continue to be available, however it looks to me as if this service is very easily abused (e.g. by spreading illegal content). But even if it just gets popular there are bandwidth costs which may run high quickly, if you have a few 100 heavy users.
If the author is here:
- How much of a concern is this for you?
- Do you have plans to offset the bandwidth fees?
- The backend is a single host, right? When would you need to scale this?
I used to provide a public instance of sish (a similar app) [0] and can say abuse is most definitely a problem. People were using sish for command-and-control servers, especially because it used only SSH for establishing tunnels. It was specifically chosen because nothing else needed to be installed. Really only worth it if a service provider (DO, AWS, etc) provides free compute and acknowledges the risk involved.
Interesting! Thanks for sharing your story. I'll keep an eye out for abuse of the kind you mention. Maybe if that seems to be an issue, I'd turn off the explicit `--port` option on the public server, which would only allow randomly assigned ports.
Not the author, but:
- Yes, this will be quickly abused now it has been made more public, unless the service at bore.pub has the shared secret set (have you tried to connect?).
- The service may currently be running on a host that has “unlimited” bandwidth as a limited speed, so there may be no extra bandwidth feeds to offset (though the bandwidth will be increasingly saturated and so progressively much slower for each active connection).
- I don't think scaling was intended, more than people would run their own version on their own service. Scaling could be achieved to an extent with a fatter bandwidth allowance (a faster rate cap, if I'm right about that being the limit not a fixed bandwidth cap). Unless the service is running on a very fast link on a very slow (or congested) CPU, bandwidth will likely be the limiting factor not anything else. If the process is large and forks for each connection then memory could be a limitation, but that could be increased easily or you could have multiple servers on the same name using a load-balancer or simple round-robin DNS.
Though I'm not sure what this offers beyond using a reverse SSH tunnel, if you have your own server/VM to host it on. Of course if you do not have your own external server but an account on someone else's which does not allow tunnels like that then this tool could be useful, but you could also get your own VM with full access for not much more than $1/month.
See my comment below about differences in goals from remote SSH port forwarding (which I also use regularly).
Scaling issues are not a problem for me, but thank you for your concern. The nice thing about scaling is that you only have to worry about it if your service is used a lot, and bore is just a small hobby project. I mention in the FAQ where I’m currently at with CPU/memory usage and network egress; it’s very cheap and not even close to hitting limits. (thanks Rust!)
If these are your concerns, use ngrok.
It's not really a user concern. It's highlighting that open relays like this are infamously abused and the people that run them can face pretty serious investigations or worse. It would not be fun to be woken up by interpol or the FBI yanking you out of bed with guns drawn because someone was using your public bore.pub service to host or send malicious or criminal content, control a botnet, etc.
Wow, that’s pretty violent. Excuse me! Bore is just a proxy I wrote on a train ride home, and I’m making it public for its own sake. I’d honestly rather you not make intimidating suggestions towards threats like this.
It's not useful to bury your head in the sand and write it off as an intimidating suggestion. Take a look at the Tor relay operations faq [1].
> Has anyone ever been sued or prosecuted for running Tor?
> Although we are not aware of an individual being sued, prosecuted, or convicted for running a Tor relay, law enforcement in the United States and other countries has occasionally mistakenly investigated individuals running a Tor relay. We believe that running a Tor relay, including an exit relay that allows people to anonymously send and receive traffic, is legal under U.S. law. Law enforcement, however, often misunderstands how Tor works and has occasionally attributed illegal traffic on the network as originating from a Tor exit relay. This has resulted in police suspecting Tor relay operators of crimes and sometimes seizing computer equipment, including Tor relays. For example, in 2016 Seattle police mistakenly raided the home of a privacy activist operating a Tor exit relay. And Russian authorities wrongfully arrested math instructor and Tor relay operator Dmitry Bogatov, though they later cleared him of charges.
[1] https://community.torproject.org/relay/community-resources/e...
This isn't a threat, this is a warning to be careful about how police and investigators operate with little knowledge of how the internet actually works. If someone were hosting a web server with child porn tunneled through your bore.pub service the authorities would only see bore.pub IPs in traffic logs, and they would definitely contact the DNS and IP block owner to figure exactly who runs that bore.pub server (you) and get a warrant to seize their computers.
I don’t think Parent was making a threat, and think it’s poor form you chose to take it that way.
Could you explain how using this service would spread illegal content?
It can be used as an anonymous reverse proxy, meaning it could be used to host malicious or illegal files on a malicious users computer, while making it more difficult to trace back to them. Any complaints will have the service IP address rather than the malicious users, meaning the server host is the first person the feds will be questioning during an investigation. And when I say questioning, I mean potentially publicly arresting the host for child porn or similar, destroying their life (despite being innocent), or holing the hosts computer equipment as evidence for months / years as part of the crime, even with irrefutable proof of innocence on behalf of the host.
On the things not to host, a public variant of this would be at the top of my list, right next to tor exit nodes.
im not the author,but
don't do that, since crypto mining exist let people access to your machine means they gonna make you mine monero, that's what happens to kill public Unix systems, tradition who start in the early 80s.
but i probably use this to test mobile-web, sometime web APIs, like cameras doesn't work consistently between chrome pc and chrome android for example, let you test this solution in real hardware Without need to deploy.
other option is cloudflare tunnels
This is super cool. Well done!
Thanks!
I'm assuming the bore server would have to be listening on all ports right? Doesn't that cause risk as all ports (or lots of them anyway) are open?
Also, seems like it'd be trivial to add TLS termination. I've used ngrok for it's TLS termination when developing GH Webhook listeners.
Good question. No, the bore server only listens on ports dynamically when it gets a new connection. It cleans up connections as well. This is managed by Rust’s ownership system. Could you also clarify what the specific risk is of opening ports?
Bore has an explicit design goal of being easy to deploy yourself. Unfortunately adding TLS termination would necessitate setup steps like creating a wildcard certificate and uploading it. It also requires additional configuration options, since TLS termination is on top of HTTP, but bore only proxies TCP directly and is unaware of HTTP. This is by design.
> Could you also clarify what the specific risk is of opening ports?
I guess I was meant from a firewall perspective. I understand the ports won't be listening but any potential firewall will not be able to block the port unless you have some integration to dynamically get the firewall to open and close ports on demand.
The number of open ports doesn't matter, if they all point to the same service.
Have nearly finished Domain Driven made functional by Scott Wlaschin, highly recommend it. Have to disagree with the conclusion of refactoring legacy system to an event driven one. Subscribing to events makes it implicit and thus hard to follow what is happening. Being explicit pays off.
Binary musl self contained release would be great for adoption..
Why not just use ssh with local or remote port forwarding? You get free auth, stream encryption, and battle tested code.
Legitimately, what benefits does this have?
Please see the FAQ. I use SSH with remote port forwarding regularly. This has a different purpose. You’re free to use it or not as you wish.
Your faq doesn’t answer my question
I think I would just use Tor onion services for this.
Isn't this socat?
Socat only forwards ports within the machine it’s running.
This sounds more like ssh -R.
Can we get binaries for Linux, Mac & Windows
What would this be used for?
Testing and developing a web service. Run the service on your localhost, like straight from your IDE with a debugger attached, and get a public internet facing bore.pub address for it. You can then point anything at it--your staging/integration or even production service, or maybe just a friend or coworker who wants to see in development work.
Yep, those are all good use cases where TCP tunneling comes in handy — basically, how can I get someone to connect to me?
For me to use it it would need to support https and 443 on bore.pub
Unfortunately this is explicitly out of scope for the implementation, but feel free to check out many of the more complex or commercial alternatives
I really like to test postback integrations with services like that
> This will expose your local port at localhost:8000 to the public internet at bore.pub:<PORT>, where the port number is assigned randomly.
Port numbers are limited to 65535. Isn't this un-scalable and a massive security risk?
This is a small service for developers. Please see the FAQ comment. There are not currently 40,000 proxy connections to the public server (more like 10). If there are then the server will gracefully give an error and terminate the connection.
Please do not spread fear, uncertainty, and doubt about security without precise details. It’s not conducive to a healthy conversation.
Forwarding ports from localhost is a benign activity unless the port is vulnerable in the first place, I wouldn’t be advocating to blindly forward localhost ports to the internet without a second look.
"Please do not spread fear, uncertainty, and doubt about security without precise details."
I read the FAQ several times before posting, and it still didn't answer the security question. Elaborating my concerns...
You suggest developers use this. That means, users will most likely be running dev servers. Dev servers, especially in the NodeJS world offer the ability to connect a debugger.
What happens when someone spams requests to connect a debugger to bore.pub:<PORT>?
You have to explicitly tell bore which server to serve your client on. At no point do you have to use 'bore.pub'. That is being provided by the developer as a public place if you choose not to run your own bore server.