ComputingInternet Of Things

SSH Port Forwarding

There’s heaps on this on the internet. Here is my specific take. Useful for IoT connections. Don’t forget to secure things.

Remote Server Access

I want to connect remotely to a web server on machine.com. But it’s behind a firewall which refuses incoming connections and/or has no public IP address.:

# machine.com>
ssh -nNT -R 8080:localhost:80 ssh-user@your.public.server

-nNT: using no shell…
-R : listen on the remote machine…
8080: at this remote port…
localhost:80: and forward connection that back here…
ec2-user@your.public.server: do this by sshing to this remote machine

image 13
image 13

Finally, there’s a configuration setting on public.com required. See details here.

And now, from Admin’s computer, we can connect to public.com:8080 which is really connecting to machine.com:80, it’s webserver. From the public.com machine, we can see it’s listening on :8080 to forward to machine.com:80

public.com>ss -t -l -n
 State      Recv-Q      Send-Q            Local Address:Port           Peer Address:Port     
 LISTEN     0           128                     0.0.0.0:8080                0.0.0.0:*               

SSH Tunnel over SSH

Can we do a similiar thing with SSH connections? It is a bit odd as we’re tunnelling ssh over ssh? But yes, it’s the same, except we:

# machine.com:
ssh -nNT -R 2222:localhost:22 ec2-user@public.com

And then from an admin machine connect to sshd on monitor by:

# admin machine
ssh -p 2222 ec2-user@machine.com
# and we get:
machine.com>

Multiple Connections

If there are multiple machine.com (e.g. machine1.com, machine2.com), we must connect back to the server of different ports (e.g. 2001, 2002) and get some record of machine names. On the server, let’s block out XX000 to XX999. A script on the server can periodically ssh into the machine and get their hostname/ips and maintain a list on the server which can be looked up via the command line.

Persistent Connections

Use a simple script (from here) to check. Firstly, we copy ssh to ssh-tunnel and use that to differentiate. Then we run the script with cron.

#!/bin/bash
createTunnel() {
  /usr/bin/sshtunnel -N -o "ServerAliveInterval 20" -o "ServerAliveCountMax 3" -R 2222:localhost:22 serverUser@25.25.25.25
  if [[ $? -eq 0 ]]; then
    echo Tunnel to jumpbox created successfully
  else
    echo An error occurred creating a tunnel to jumpbox. RC was $?
  fi
}
/bin/pidof ssh-tunnel
if [[ $? -ne 0 ]]; then
  echo Creating new tunnel connection
  createTunnel
fi

and in cronta run this each minute and log
*/1 * * * * /home/pi/create_ssh_tunnel.sh > tunnel.log 2>&1

Forward Local Network Server to Public Server

So, we’ve ssh’d onto a remote machine. On that remote machine’s network is a device (“device.local”) with a web server we need to access.

First let’s find available web servers on the local network:

nmap -q --open -oG a -p 80 10.1.1.* && cat a

We can forward one IP or host to our public machine. Have to config sshd on the remote machine too (see details here.) Then:

ssh -f -N -R 8080:hfs02a.local:80 ec2-user@live.public.com

This forks. Just kill when finished. Now we can access hfs02a from outside. This needs security consideration!

Leave a Reply

Your email address will not be published. Required fields are marked *