# Reliable SSH access via pubnix with portforwarding, AutoSSH, and proxyjump

In this article, I discussed a setup to use pubnix to reliably surface LAN hosts SSH access, via port forwarding and the use of AutoSSH.

Directly allowing ssh access to a home network machine can be risky. I used to do that. At first, I noticed frequent password guessing attachs in the logs. Later I made two mitigations. One is changing the ssh port off of 22. The other is using sshguard to ban attachers after some failures. While that worked out fine, the biggest security risk remains - that my machine is directly accessible through the internet.

I don’t think there is ever a perfect solution to it. But I found using ssh reverse port forwarding (-R) can effectively reduce the risk surface. On top of that, I’ve found the use of autossh has been a success - it is surprisingly reliable. Therefore, I’m sharing this setup with you all.

## Setting Up SSH Reverse Port Forwarding

Here’s an explain of the reverse port forwarding:

On host HOME, we start ssh to PUBNIX:

ssh -R 4444:localhost:2222 PUBNIX
         ^     ^       ^
         |     |       |
         |     |        `- host port
         |      `- host (forwarded to) (name resolved on local)
          `- remote port (listened to (on remote side))

-R [bind_address:]port:host:hostport

Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side. This works by allocating a socket to listen to port on the remote side, and whenever a connection is made to this port, the connection is forwarded over the secure channel, and a connection is made to host port hostport from the local machine.

Note that the host is resolved locally, thus localshot refers to HOME.

  .-----------.                     .--------.
  |   HOME    |                     | PUBNIX |
  | (1)  ssh  ----------------------- >      |
  |           |                     |        |
  | (2)  2222 <<<<<<<<<<<<<<<<<<<<<<| 4444 <---------- SSH Client
  |     (sshd)|                    .---------.
  .------------

## Making the Forwarding Connection Persistent via AutoSSH

AutoSSH starts and monitors an ssh connection, and tries to reconnect if it terminates. Some unix distro may provide a service for it, but I found it works well enough to as a crontab.

@reboot AUTOSSH_DEBUG=1 autossh -M0 -fN -o ServerAliveInterval=15 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes -R 4444:localhost:2222 user@pubnix.org

Use SSH config’s proxy jump to surface multiple LAN hosts

Once we have LAN_HOST_A surfaced, we can make use of ssh config’s proxyjump feature to surface multiple LAN hosts.

                           .-----------.                     .--------.
  LAN_HOST_B....           | LAN_HOST_A|                     | PUBNIX |
               .           | (1)  ssh  ----------------------- >      |
               ............|           |                     |        |
  LAN_HOST_C...............| (2)  2222 <<<<<<<<<<<<<<<<<<<<<<| 4444 <---------- SSH Client
             proxyjump     |     (sshd)|                    .---------.
                           .------------

In a client’s ~/.ssh/config, where we want to access a deeply buried LAN host (e.g., LAN_HOST_B):

host PUBNIX
    hostname example.pubnix.com
    user xxx

host LAN_HOST_A
    hostname localhost
    port 4444
    proxyjump PUBNIX

host LAN_HOST_B
    hostname 192.169.0.xxx
    proxyjump LAN_HOST_A

host LAN_HOST_C
    hostname 192.169.0.yyy
    proxyjump LAN_HOST_A

Note that the awesome fact that proxyjump can be chained, e.g.,

LAN_HOST_B  <-- LAN_HOST_A  <-- PUBNIX

I have this setup working for months and it is very reliable.