Open cipriancraciun opened 3 years ago
Thanks for the suggestion!
Assuming this is similar to reverse SSH tunnelling, this would only work if a onetun
-compatible daemon was running on the remote server. Specifically, it would need to open a port on the remote server, which isn't possible without having a process running on the remote server in the first place.
SSH reverse-tunnelling works because sshd
(daemon) can open ports on the remote server on demand, after being instructed to do so by the client (ssh
) using a special request.
I have no plans for a onetund
at the moment since it goes against the idea of onetun
being useful in non-root/daemon-less environments. I would also need to design a protocol for onetun
to instruct onetund
to open a port forward.
I might change my mind down the line if I see some interest in it, or if I find a use for it myself.
this would only work if a onetun-compatible daemon was running on the remote server.
On the contrary, one wouldn't need onetun
on the remote server.
Let me expand upon how I think this could work:
onetun
's source IP on the arguments;)0.0.0.0
IP) would be reachable from any other Wireguard client (or even from the internet if the Wireguard router handles the DNAT;)onetun
; all of a sudden if one would send a packet (in our case TCP SYN) to the "source IP", it would reach onetun
;onetun
just ignores any packets that are not related to the (outbound) TCP/IP connections it has initiated;What I'm proposing is that onetun
reacts to the inbound TCP/IP connections and forwards them to the local computer (in the reverse way).
Currently onetun
allows the following (here "remote TCP endpoint" is any IP reachable via the Wireguard router):
local TCP client -> connect to local TCP endpoint -> [onetun TCP stack] -> [wireguard] -> ... -> server TCP listen on remote endpoint
What I'm proposing is the reverse (here the "remote endpoint" is the Wireguard IP address of the onetun
client):
local TCP server <- listens on local TCP port <- [onetun TCP stack] <- [wireguard] <- ... <- client TCP connect to remote TCP endpoint
If the current command is this:
./onetun 127.0.0.1:8080 192.168.4.2:8080 \
--endpoint-addr 140.30.3.182:51820 \
--endpoint-public-key 'PUB_****************************************' \
--private-key 'PRIV_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' \
--source-peer-ip 192.168.4.3 \
--keep-alive 10
The command line for the reverse would be:
./onetun 127.0.0.1:8080 192.168.4.3:8080 \
--reverse \
--endpoint-addr 140.30.3.182:51820 \
--endpoint-public-key 'PUB_****************************************' \
--private-key 'PRIV_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' \
--source-peer-ip 192.168.4.3 \
--keep-alive 10
I.e. the only difference is --reverse
, and the fact that the second address that you call "destination address" is actually the source-peer-ip
of the onetun
instance.
Thus any other client (that uses Wireguard or is routed through the Wireguard router) might just connect to 192.168.4.3:8080
, which in fact would imply that onetun
running locally would receive TCP packets related to inbound connections. So it could just inject these in its TCP/IP stack that would trigger some sort of accept
inside onetun
that instead would connect to the local server running on the onetun
client.
That would limit the port on the remote server to only be accessible via onetun's peer IP, which IMO reduces the utility compared to SSH's reverse tunnelling, which allows opening a port on any interface.
[any interface]:[any port] <- [ssh] <- [sshd] <- [any interface]:[any port] <- client TCP connect
[any interface]:[any port] <- [onetun] <- [wireguard] <- [onetun peer IP]:[any port] <- client TCP connect
I can see how that would still be useful in some cases though, where you want to make a local port accessible to your WireGuard mesh without having to install WG/root access. I'll look into it for v0.3.
[any interface]:[any port] <- [onetun] <- [wireguard] <- [onetun peer IP]:[any port] <- client TCP connect
I agree that the above is even better that what I've proposed.
My intended use-case is the following: Imagine I have an "HTTP router" (for example HAProxy) installed somewhere on a internet-accessible node. With that "HTTP router" I can route HTTP requests (based on Host
or path) to one of the endpoints that are acessible through Wirefuard, and served at the other end by a server (forwarded via onetun
). This would allow local instances running on my development laptop to be reachable from the internet via the "HTTP router". Obviously this is even possible today by using a proper Wireguard client or ssh -R
, but I think by using onetun
it's even more tidy and nice.
Is remote port forwarding actually implemented in 73671a4d07bce45db354dbc9d9831d4bc0c5954c, or is it just the parsing part? I'm asking because I have a use case that I can't seem to get working. I'm experimenting with a VPN provider that allows you to forward ports from the VPN public IP to your internal IP via the tunnel. This way, you can expose services without revealing your personal IP. So, it looks something like:
client --TCP--> VPN endpoint --WG tunnel--> me
I tried the following onetun command:
onetun --endpoint-addr XXX --endpoint-public-key XXX --private-key XXX --source-peer-ip XXX -keep-alive 10 -r 12345:localhost:12345:TCP,UDP
The idea is then, I should be able to reach my service on port 12345 by calling the VPN endpoint's port 12345. But it does not work... If I connect to the VPN using the official WireGuard desktop client, then the same scenario works.
Thanks!
@ViRb3 It's only the parsing for now, I merged that in in case someone has time to implement this feature. Otherwise I'll start implementing it over time.
Ah, makes sense. I don't have the time or knowledge myself, but looking forward to this feature getting implemented by any other means.
No problem! It'll be a very useful feature to have for sure. It's not going to be super difficult to adapt the existing code, my main blocker is abstracting the smoltcp core enough so that it can support both directions.
I think having the option to support [--reverse] would be very nice. This would open up numerous options for connecting to client resources. Any thoughts on when (or if) this feature will be supported? In either case this is a very nice project!
I would be interested in sponsoring this feature and/or placing a bounty if the option were available.
Note: my new project wgslirpy may be of interest of you want onetun, but in reverse.
It forwards all the connections, not one by one.
onetun
looks like exactly what I need -- I want to terminate TLS and accept HTTP on a remote server, reverse proxy to a onetun peer that is forwarding traffic to caddy, running on localhost, configured to route to various local services on various ports based on the Host
header.
I can't quite wrap my head around wgslirpy
and don't really want it to mess with DNS, nor forward all traffic.
I don't want to be annoying, but I would definitely donate to this cause or someone taking it on. I don't think smoltcp is something I can just dive into with my knowledge, nor is something I can dig into right now.
It seems like onetun with reverse connections, combined with caddy on other sides, is basically cloudflare tunnel but freer, and better.
@colemickens , If you have proper access both to the remote server and to local host then maybe better just configure proper, in-kernel Wireguard connection (with a port redirection rule) instead of using user-space hacks?
@vi Indeed that's the approach I'm trialing now. However, this is part of a dev environment that otherwise is very, very portable, non-root, etc. My colleagues will probably rather tolerate "use root" over "use cloudflare" but the real ideal would be to just have this packaged as another script we run with process-compose
.
@colemickens For easy, but temporary dev setup you may want to use ngrok or something like that, if you want to just accept global https://
on local machine.
Very interested on this working btw. I don't have as much Rust knowledge but I'd like to give it ago. Any advice or place in the code where I should start looking ? @aramperes
At the moment
onetun
supports forwarding outbound connections (from local client to remote server).It would be especially useful for developers to also have the reverse, namely inbound connections (from remote clients to local servers).
Based on your description on how it uses
smoltun
it seems to be a matter of implementing the reverse logic for the TCP forwarding.