No VPN? No problem! Using SSH tunnels for remote access to closed networks

Last modification on

Rationale

Corporate and academic networks are closed by design, with routers and firewalls forwarding and filtering content going to and from the wider internet. For security reasons this is an absolute necessity, as the guardkeeping prevents unwanted incoming connections to the networked devices.

However, it is often necessary to connect to internal devices or services from the outside. This could be the case if an employee needs to access a shared database on the company network, or a subscription website only allows full access from a certain range of IP addresses. Network administrators usually offer virtual private network (VPN) access to achieve such goals. Unfortunately, VPN access occasionally requires particular software that may not work on all operating systems. In other cases, the network administrators may enforce strict requirements to the remote systems before allowing VPN access.

 ###### Closed Network ######
 #                          #
 #  +----------+      +----------+             +----------+
 #  |  Office  |      | Router/  |      ?      | Outside  |
 #  | Computer |<~~~~>| Firewall |    ?   ?    | Computer |
 #  +----------+      +----------+             +----------+
 #                          #
 ############################

So what do you do if you need outside access to a network, have no administrative rights over the router and firewall, and cannot (or don't want to) access via VPN? Fortunately, OpenSSH, the widely used secure shell (SSH) implementation, offers simple and secure solutions to this problem. Almost all Linux/BSD/UNIX/MacOS systems come with OpenSSH preinstalled, so you might already have it on your system.

If you can access the closed network from the outside via SSH, this makes things straightforward as described in Scenario 1 below. If not, see Scenario 2.

Scenario 1: SSH access available from the outside

Some networks are configured to allow outsiders to connect to an internal SSH server through port forwarding on the network router:

 ###### Closed Network ######
 #                          #
 #  +----------+      +----------+      +----------+
 #  |  Office  |  SSH | Router/  |  SSH | Outside  |
 #  | Computer |<~~~~~| Firewall |<~~~~~| Computer |
 #  +----------+      +----------+      +----------+
 #                          #
 ############################

For the purposes described here, this is an ideal situation since it is easy to create a tunnel that connects the outside computer with the internal network via SSH. The following command creates the tunnel when executed on the outside computer:

$ ssh -D 1337 -C -N company-domain.com

Note that the port number specified with the -D option should be greater than 1000 when running as an unpriviledged (non-root) user. The -C option turns on compression, which is useful for slow network connections at the cost of little CPU overhead.

With the SSH tunnel in place, you can make most webbrowsers and other network programs on the outside computer use the tunnel for all their network traffic by pointing them to the SOCKSv5 proxy "socks://localhost:1337". This allows access from programs on the outside computer to any device within the closed network. Connections to the wider internet utilizing the tunnel will originate from an IP address associated with the closed network, achieving the objectives stated above.

Scenario 2: SSH access unavailable from the outside

Unfortunately, outside SSH access to corporate networks is becoming increasingly rare. However, the OpenSSH toolset again offers a solution if you have a persistent SSH server outside of the network at your disposal:

 ###### Closed Network ######
 #                          #
 #  +----------+      +----------+      +---------+      +---------+
 #  |  Office  |  SSH | Router/  |  SSH | Outside |  SSH | Outside |
 #  | Computer |<~~~~>| Firewall |<~~~~>| Server  |<~~~~~| Laptop  |
 #  +----------+      +----------+      +---------+      +---------+
 #                          #
 ############################

As long as you can initiate *outgoing* SSH connections from inside the closed network to your outside SSH server, you can create a reverse ssh tunnel and utilize it in a similar manner as in the previous scenario. On the office computer, create a reverse tunnel to the outside server:

$ ssh -f -N -R 10022:localhost:22 outside-server.com

As long as the above command runs, you can initiate new SSH connections from the outside server to the office computer with the command `ssh -p 10022 localhost`. If you're working from an outside laptop, you can utilize this reverse tunnel to connect to the office computer and network. Add the following configuration to `~/.ssh/config` on the outside laptop:

Host office_computer
    ProxyCommand ssh -q outside-server.com nc localhost 10022

With the above configuration, it is very easy to establish a SSH connection from the outside laptop to the office computer:

$ ssh office_computer

As in the previous example, you can use this setup to create a SSH tunnel all the way from the outside laptop to the office computer:

$ ssh -D 1337 -C -N office_computer

Again, this creates a SOCKSv5 proxy that you can use for tunneling network traffic from the outside laptop to the closed network. It is useful to automatically monitor the tunnel status using pgrep(1), and reinitialize it if the ssh command unexpectedly quits.

References

Thanks to KatolaZ for feedback on this post.