Sometimes getting to various servers especially virtualised systems, can be a nightmare due to various firewall rules restricting the physical machine or just down to the network architecture itself. For this example we’ll use two virtual machines which are located behind nat’d firewalls on two different physical hosts the firewalls permit SSH access out that is it.
[PHYS_A [VM_A:5901]] <–/–> [PHYS_B [VM_B]]
VM_A needs to run a VNC Server that will bind to VM_A:5901, however will no access to the firewall etc.. there is no way that there can be any port forwarding to this internal VM. We could use IPtables on the VM_A and then again use IPtables on PHYS_A to bind 5901 from VM_A’s IP to PHYS_A, however we are still behind a firewall.
To accomplish this sharing a server running SSH is required, the location of this server is completely irrelevant as long as it’s accessible with a standard user account. This server will be called SSH and both machines can access it through the firewall.
[PHYS_A [VM_A:5901]] <—> [SSH] <—> [PHYS_B [VM_B]]
The next step is to push the port on VM_A to the SSH server using the following command:
[user@VM_A]$ ssh -R5901:127.0.0.1:5901 -C user@SSH
This will open a session that will create the port 5901 on the server SSH, this can be confirmed by running a netstat -a on the server SSH and seeing that 5901 is now listed as a TCP4 listening port.
[PHYS_A [VM_A:5901]] <—> [SSH:5901] <—> [PHYS_B [VM_B]]
The next step is to pull the port on SSH to VM_B where we have the client software (vncviwer). The following command is used to pull the port from an IP address and bind it to a local port in VM_B.
[user@VM_B]$ ssh -L5901:127.0.0.1:5901 -C user@SSH
There will now be the port created on VM_B that tunnels through SSH to VM_A.
[PHYS_A [VM_A:5901]] <—> [SSH:5901] <—> [PHYS_B [VM_B:5901]]
The user on VM_B can now use the service as if it was actually running on the host itself.
[user@VM_B] vncviewer localhost:5901
Notes for SSH flags:
-R [port to bind to on remote host] : [local host IP] : [localhost port]
-L [local port to use] : [remote IP] : [remote port]
-C (adds compression)