0 votes
by (250 points)

Hi,
in Linux there is an opensource tool called sshuttle.
It implements basically sort of a VPN by using a connection to an SSH server, setting up tunnels and updating local routing settings. It can route all traffic (including DNS if need be) through the tunnel.
Rebex can create Incoming and Outgoing tunnels.
But these seem to need specific ports.
Do I need to setup one tunnel per port?
Any hints highly appreciated!
Thanks in advance.

Best Regards
Yahia

1 Answer

0 votes
by (149k points)

Hi,

The sshuttle tool actually uploads its Python source code to the server, executes it there, and uses that instead of SSH's tunneling. So, basically, it's not really an SSH VPN, it's a proprietary VPN that runs over SSH session. At also uses iptables REDIRECT rules to capture outgoing TCP sessions. These clever hacks make it a useful tool.

But unfortunately, this also means that reproducing sshuttle using SSH alone is not possible - not with Rebex, not with OpenSSH.

The closest you can get is to set up a SOCKS5 server that tunnels its connections through an SSH server. This eliminates the need to setup one tunnel per port, but it also requires each client app to support connecting via a SOCKS5 server and be configured to use it. To work around that, you would need something like sshuttle that operates via a SOCKS5 server. Unfortunately, we are not aware of any such tool, and we have no plans to implement it.

by (250 points)
Thank you very much for the clear answer.
I was not aware of sshuttle actually uploading some code to the server...

I know that for tunnels there is no authentication etc.
Is there an event that gets fired when someone connects to an existing tunnel? Perhaps https://www.rebex.net/doc/api/Rebex.Net.Servers.FileServer.Connecting.html?

Thanks in advance!
by (149k points)
There is the TunnelRequested event that is fired when an attempt is made to establish a new tunnel:
https://www.rebex.net/doc/api/Rebex.Net.Servers.FileServer.TunnelRequested.html

This can be used to accept or deny the request based on the server user or IP address/port.
by (250 points)
Perhaps I am a bit confused...
Is the TunnelRequested event about creation of a new tunnel (it has serversession which makes me think that the request is part of an already authenticated user session)?
Or is it about anyone connecting to a port of an existing tunnel (which does not have authentication)? I am interested in the latter...
by (149k points)
All SSH tunnels run over an already-authenticated SSH session. When the session ends, all its tunnels associated have to end as well. It's not possible for an SSH tunnel to exist without the underlying SSH channel, which runs over an authenticated SSH session. This applies to both forward tunneling and reverse tunneling.
by (250 points)
Thank you for the answer... I think I am expressing myself in a confusing way.
Let's take this scenario:
Server S (Rebex), Client A (Rebex) and Client B
Client A logs into Server S via SSH and start an IncomingTunnel.
The IncomingTunnel means that Server S opens port 7000.
Anyone connecting to Port 7000 on Server S will be sent through the tunnel as long as Client A is connected and does not close the tunnel.
Client B connects (TCP) to port 7000 on Server S and is sent through the tunnel.
Does Client B connecting to port 7000 on Server S raise any event (either on Server S or Client A)?
by (149k points)
When Client B connects to port 7000 on Server S:

- The TunnelRequested event is raised on the server app on Server S. If the request is accepted, a tunnel is established.

- No event is raised at Client A if you used Ssh.StartIncomingTunnel API. (Event is raised on Client A if you use the low-level SshSession API for this.)
by (149k points)
Some additional clarification on this:

> The IncomingTunnel means that Server S opens port 7000.
> Anyone connecting to Port 7000 on Server S will be sent through the tunnel as long as Client A is connected and does not close the tunnel.

This is correct, but the term "tunnel" (as used in our API and elsewhere) is a bit confusing, because it's used for two different things: The reverse port forwarding (which is configuring the SSH server to be capable of establishing tunnels back to the client), and the tunnel itself (which is only established when a client actually connects to that port and is accepted).
by (250 points)
Understood, thank you very much for the clear explanations!
by (250 points)
One question: I read somewhere on the rebex site that Rebex SSH server does not support "IncomingTunnels" / only OutgoingTunnels are supported? Is this a misunderstanding on my side?
by (149k points)
Rebex SSH server does support incoming tunnels, although this feature was only added recently (see https://www.rebex.net/file-server/history.aspx#R6.0) and some pages might still be outdated. Sorry for the confusion.
by (250 points)
Thank you very much.

You wrote "- No event is raised at Client A if you used Ssh.StartIncomingTunnel API. (Event is raised on Client A if you use the low-level SshSession API for this.)"

How do I create Incoming/Outgoing Tunnel using the low-level API? Is there a sample that shows how to do that properly so I can receive an event on Client A too (not only on Server S)?
by (149k points)
Unfortunately, there is no sample code for this. Basically, you would have to do this:
1. Use SshSession class instead of Ssh class.
2. Use Connect and Authenticate methods to establish an SSH session.
3. Register ForwardingRequest event handler.
4. Call StartTcpIpForward method to start accepting incoming tunnels at the SSH server.
5. When a connection gets accepted by the server, the ForwardingRequest event handler will be fired. You can then accept the tunnel by calling event arguments Accept method.
6. This will give you an instance of SshChannel. This can be basically used in a manner similar to a server-side socket.
7. If you need to tunnel these channels to another target machine, you would have to establish the Socket connection yourself, and then pass traffic in both directions.

However, I just noticed that ForwardingRequest don't currently contain the originating IP/port, which makes this just an overly complex way to achieve the functionality provided by the Ssh class.
...