How to set up Remote SSH to any machine behind the firewall

In this post, the method to remote SSH into a Linux machine is covered. This is especially helpful when you do not wish to open any Port open in your ISP-provided Router configuration. Using this method, you can SSH into your home machine from any computer on the internet. You would not need any fancy software to do this, SSHD running is the only prerequisite.

To make things simple to remember, let’s assume we have two laptops:

  • 1st laptop is at home and cannot be taken out. This laptop is named “homelab”.
  • 2nd laptop is the laptop the user can freely take out and connect to the Internet. This laptop is named “cloudvm”.
Here is the diagram of my setup:

Validate SSHD state and listening ports on both Machines:

If you have SSHD running, you can validate that SSHD is listening on its assigned port. In the default case, it’s port 22.

To validate the SSHD process running or not and its listing port, run the following command,

In my homelab sshd is running and listening on default port 22.

ps@homelab:~$sudo netstat -plont |grep ssh
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1479/sshd: /usr/sbi off (0.00/0/0)
tcp6 0 0 :::22 :::* LISTEN 1479/sshd: /usr/sbi off (0.00/0/0)

Validating the SSHD and its port on cloudvm:

cloud_vm@cloudvm:~$ sudo netstat -plnt |grep sshd
tcp 0 0 0.0.0.0:4343 0.0.0.0:* LISTEN 455/sshd: /usr/sbin
tcp6 0 0 :::4343 :::* LISTEN 455/sshd: /usr/sbin
Create Reverse SSH Tunnel:

Now let’s make an SSH Tunnel, using the below Syntax, note that this must be initiated by “homelab”. 

ps@homelab:~$ ssh -R <SOME-UNPRIVILEDGED-PORT>:localhost:22 cloud_user@REDACTED -p <OPTIONAL-PORT-IF-NOT-PORT-22>

Example:

Unless you have not modified the SSHD listening port, you don’t need to put -p 4343. In my cloudvm, sshd listens on port 4343.  When this command is executed, it will create a reverse tunnel. This means any traffic coming on port 34000 on remote machine(cloudvm) will be forwarded to localhost(homelab) port 22.

ps@homelab:~$ ssh -R 34000:localhost:22 cloud_user@REDACTED -p 4343
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0 x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Last login: Sun Mar 20 03:36:42 2022 from 1.2.3.4
cloud_vm@cloudvm:~$
Connecting to homelab from the cloudvm:

Notice that, ssh to localhost on remote machine(cloudvm) over port 34000 is forwarding us to localhost’s port 22(homelab).

cloud_user@cloudvm:~$ ssh ps@localhost -p 34000
ps@localhost's password: <password-for-homelab>
ps@controller:~$

In case you are interested, here is the snippet from the man page:

-R [bind_address:]port:host:hostport
-R [bind_address:]port:local_socket
-R remote_socket:host:hostport
-R remote_socket:local_socket
-R [bind_address:]port
Specifies that connections to the given TCP port or Unix socket on the remote (server) host are to be forwarded to the local side.
This works by allocating a socket to listen to either a TCP port or to a Unix socket on the remote side. Whenever a connection is made to this port or Unix socket, the connection is forwarded over the secure
channel, and a connection is made from the local machine to either an explicit destination specified by host port hostport, or local_socket, or, if no explicit destination was specified, ssh will act as a SOCKS
4/5 proxy and forward connections to the destinations requested by the remote SOCKS client.
Port forwardings can also be specified in the configuration file. Privileged ports can be forwarded only when logging in as root on the remote machine. IPv6 addresses can be specified by enclosing the address
in square brackets.
By default, TCP listening sockets on the server will be bound to the loopback interface only. This may be overridden by specifying a bind_address. An empty bind_address, or the address ‘*’, indicates that the
remote socket should listen on all interfaces. Specifying a remote bind_address will only succeed if the server's GatewayPorts option is enabled (see sshd_config(5)).
If the port argument is ‘0’, the listen port will be dynamically allocated on the server and reported to the client at run time. When used together with -O forward the allocated port will be printed to the
standard output.
0 0 votes
Please, Rate this post
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x
Scroll to Top