Quick temporal VPN

[linkstandalone]

Sometimes I need to access an internal network or server where a customer hosts their services. This internal network is usually behind some firewall that allows generally unrestricted outgoing traffic but blocks incoming connections or lacks of any NAT configuration.

It would look something like this.

INTERNET           ║             LAN
                   ║
                   ║
                ╭──╨───╮      ╭───────╮
             ◀──┤router├────┬─┤server1│
                ╰──╥───╯    │ ╰───────╯
                   ║        │
                   ║        │ ╭───────╮
                   ║        ├─┤server2│
                   ║        │ ╰───────╯
                   ║        │
                   ║        │ ╭───────╮
                   ║        ╰─┤server3│
                   ║          ╰───────╯
                   ║

In these cases, you need some setup that allows you to connect to these servers and that is simple, mostly on the customer side. Ideally allowing a non-technical person on the client side to follow just a couple of easy steps.

Solution

You need a server with a public IP. If you already have one you can even have a permanent setup. If not you hire an inexpensive VPS in many hosting providers for $5/month or even less. Let's call this host myhost.

This server needs to have a user account that allows Port Forwarding via SSH, which is allowed by default in most distributions. To secure the account you can assign to it the /bin/true shell, so it can login but not execute commands. In this example, the user will be called tunnel.

root@myhost:~# adduser --no-create-home --shell /bin/true  --gecos '' tunnel

Now you ask a person with access to any server in the internal network to execute the following command and provide him or her with the password for the tunnel user.

user@server2:~$ ssh tunnel@myhost -N -R 1080

This command will not provide any output and will stay there as if nothing happens. However, in the background it is using SSH to create a remote SOCKS proxy in your server, listening in localhost and port 1080

INTERNET           ║             LAN
                   ║
                   ║
                ╭──╨───╮      ╭───────╮
   ╭─────────◀──┤router├────┬─┤server1│
   │            ╰──╥───╯    │ ╰───────╯
   ▼               ║        │
╭──────╮           ║        │ ╭───────╮
│myhost│           ║        ├─┤server2│
╰──────╯           ║        │ ╰───────╯
                   ║        │
                   ║        │ ╭───────╮
                   ║        ╰─┤server3│
                   ║          ╰───────╯
                   ║

Now in your server you can access the internal network using localhost:1080 as a SOCKS proxy.

The easiest way to do this is to install tsocks.

root@myhost:~# apt install tsocks

Once installed, edit /etc/tsocks.conf like this:

# Remove any "local = 192.168.0.0" or other "local" variable lines
server = localhost
server_type = 5
server_port = 1080

Now you can enable the access to the internal network in one of your server shells with.

root@myhost:~# . tsocks -on

After this command, you will be able to access any server in the internal network just like if you were inside the network.

root@myhost:~# ssh root@server3
root@server3:~# exit
root@myhost:~# ssh root@server1
root@server1:~#

I hope you find this trick useful. Keep in mind that once you have this setup in your end, the other end only needs to execute one command.