Implementing a proxy server behind a firewall

0 votes
asked Apr 2 by ioan.crisan (340 points)
edited Apr 3 by ioan.crisan

I have the following requirements:

  • A proxy server behind a firewall. Only outgoing connections are possible from this server outside the firewall.
  • The proxy server has permissions to connect to any machine behind the firewall, using any protocol (ssh/telnet).
  • An application outside the firewall.
  • The application needs to open ssh/telnet connections to machines behind the firewall with the help of the proxy server.
  • Note: the communication between the application and proxy needs to be two-way.

Could you help me figure out how can I use Rebex to achieve such a behavior? Thank you in advance.

commented Apr 3 by Lukas Pokorny (99,010 points)
Before we propose a solution, I need to make sure that our assumptions are correct:
- I assume that any solutions that require any configuration changes at the 'firewall' are not acceptable. Is that correct?
- On the other hand, I assume it is possible to install and run a custom .NET application (possibly based on Rebex libraries) on the 'proxy server'. Please confirm whether this is the case.
- If both of the assumptions are correct, any solution would involve setting up a different kind of proxy server (possibly an SSH server) outside the 'firewall' to facilitate the communication. Is that acceptable as well?
commented Apr 3 by ioan.crisan (340 points)
1. No changes to the firewall.
2. Both the proxy and the application will include the Rebex components.
3. Outside of the firewall we do not have any constraints, meaning that we are in control.

1 Answer

+1 vote
answered Apr 4 by Lukas Pokorny (99,010 points)
selected Apr 4 by ioan.crisan
 
Best answer

Consider the following approach:

  1. Set up an SSH server outside the firewall that is accessible both by the proxy server and by the application.
  2. Configure that external SSH server to allow incoming tunnels (reverse port forwarding) from non-local endpoints.
  3. At the proxy server, run an application that uses Rebex Terminal Emulation's port forwarding API to establish an incoming tunnel (or a set of tunnels) from an address/port at the external SSH server to a machine behind the firewall.

Details:

(1) Any SSH server that supports reverse port forwarding is suitable. An OpenSSH server on a Linux VPS would be fine. (Our Buru SFTP Server is intended for file transfer and doesn't support reverse port forwarding yet.)

(2) In OpenSSH, this can be enabled by setting the GatewayPorts configuration option to yes.

(3) At the proxy server, an application based on Rebex.SshShell assembly would establish tunnels from the SSH server to local machines:

// connect and log in to an SSH server
var ssh = new Rebex.Net.Ssh();
ssh.Connect(hostname);
ssh.Login(username, password);

// create port forwarding rules
var tunnel1 = ssh.StartIncomingTunnel(
    "sshserver.example.org", 10022,  // server-side source address/port
    "192.168.1.1", 22); // client-side target address/port

// create port forwarding rules
var tunnel2 = ssh.StartIncomingTunnel(
    "sshserver.example.org", 11022,  // server-side source address/port
    "192.168.1.2", 22); // client-side target address/port

...

With this setup, an application outside the firewall would be able to connect to (for example) sshserver.example.org:11022 and the connection would get tunneled to 192.168.1.2:22.

With this approach, all of the possible tunnels would have to be pre-configured. Or, in other words, the application outside the firewall could not connect to any IP/port behind the firewall. This could be both a drawback or a benefit, depending on your scenario. But if you need the ability for the application to connect to any IP/port behind the firewall, this could be achieved by first connecting to an SSH server behind the firewall and using forward port forwarding to reach the other machines.

commented Apr 4 by ioan.crisan (340 points)
Thank you for your answer, now it's time to try your suggested solution :).
commented Apr 4 by ioan.crisan (340 points)
Maybe a clarifying question: in your example, it means that both 10022 and 11022 ports must be exposed by the sshserver.example.org (or a valid IP address) to be able to create the tunnels, am I right? If so, if I need access to 1000 machines, then I need 1000 ports to be open, which I don't think it's an option.

Would it then be possible to implement some kind of "splitter", like web servers do, which, based on some kind of discriminator, redirect the calls to a target machine or another?
commented Apr 4 by Lukas Pokorny (99,010 points)
You are right, and I briefly addressed this in the last paragraph of reply. One way to resolve this is to set up another SSH server behind the proxy, and use that as a kind of "splitter". This way, you would only have a single incoming tunnel from the external SSH server to the internal SSH server (let's say sshserver.example.org:10022 to 192.168.1.2:22). Now, the application outside the firewall would be able to connect to other machines as well: First, the application would connect to sshserver.example.org:10022, and that connection would get tunneled to the SSH server at 192.168.1.2:22. Next, the application would use this SSH session to establish an "outgoing tunnel" (sorry if this is getting a bit confusing, but it makes sense from the application's point-of-view) to any other server and port in the internal SSH server's network. To facilitate this, the application could use Rebex Terminal Emulations outgoing tunnel API (https://www.rebex.net/terminal-emulation.net/features/ssh-tunneling.aspx#outgoing-tunnels). There is one drawback - the tunnel would involve a tunnel running over an SSH session that runs over a tunnel within another SSH session, which means data would be encrypted/decrypted twice, which might negatively affect performance and throughput. The benefit of this solution is that all the parts would be based on open standards with no vendor lock-in.
commented Apr 4 by ioan.crisan (340 points)
Thanks again, I think this is what I need. So I need to get to work now and try this.
...