SSH Reverse Tunnel Utilizing an SSH GateWay

Comments: No Comments
Upper page: SSH HowTos

Synopsis

Ever been stuck at home sick and the boss calls you saying your server at the office, the local wiki/website/samba-server is having issues? And your server at the office is behind a firewall and worse, it does not have an internet facing IP?  OR, your spouse calls you from home saying that the computer won’t print and they need to print ASAP and your internet connection is not static.  So, how does one remotely administer in situations such as these?

You can use TeamViewer, but TV is very expensive to purchase, the free version is cool but a headache and difficult to maintain a “consistent” address and password.   However, TV works great once initiated and you know the ID and password.  But this is usually predicated that someone is there to launch TV.  Not exactly what I consider 24/7/365 support capable.

So how does TV do it?  Well, they utilize what I call a SSH-Gateway-Server (SGS). Your target device/server/workstation establishes a link to the SGS and it is through the SGS that your workstation tunnels into your target. Well that is all well and fine if you have someone at the target machine ready, willing and able to “establish the link”. However, a astute administrator who does not like shelling $4.00/gallon to drive to target machine location to do something he can do from his current internet connected locale. And besides that, he/she wants to save their wonderful company/home money, especially in these hard times. Well, fear not, you have a “FREE”, secure and reliable home grown option. SSH-REVERSE-TUNNEL….. read on.

Assumptions

You are not too green at administering Linux/Nix servers/workstations/devices.  As I may leave out little nuances that will make “monkey-see monkey-do” efforts not work.  Also, your system may differ from Ubuntu 10.04 LTS.  However, you don’t need mad skillz either.

Requirements

  • A remote server (this I call the SSH-Gateway-Server [SGS]) that you can access from anywhere on the internet.  (i.e. Rackspace cloud server).  WHAT?, as you scream, “You said freeand/or cheap!”.  Well, the tunnel will be free.  The rackspace cloud server, that cost can be very low.  You can spend as little as $11/month for a cloud server on rackspace.  You don’t even need a domain.  Yes, you read that right.  A low traffic minimal server on rackspace cloud is $11/month.  Cost goes up with the traffic, but trust me, you won’t be flowing Gigs of data through these tunnels to make that price jump much.  So, relax, and we go back to our SGS requirements.
    • Able to open a port.  You will need a dedicated port for your connection.
    • SSH Server.
    • SSH accepts the tunnel user.
      • I tend to lock my sshd_config down by blocking root logins and by using AllowUser lists.
  • SSH client on your PC.
  • SSH server on target server.  The one stuck behind a firewall/router without an internet facing IP.
  • The ability to administer the SSH servers.
  • The ability to modify the cron of your TARGET (optional if you want this tunnel automated)
  • A dedicated account for the tunnel (optional, but preferable).

Instructions are based on Ubuntu 10.04 LTS

Other than perhaps file locations, the differences will be slight between Linux distributions. Unfortunately, I cannot say the same for OSX, especially in creating a program that, on the target, automates, monitors and revives the tunnel. I will try to give the nuances of OSX at the bottom, as I have done this on OSX Leopard Server.

Configure SGS sshd_config

Pretty simple really.

cd /etc/ssh
cp -p sshd_config sshd_config.v00 #just in case.
# I increment the 00 for each copy
vi sshd_config # and make it so

 

# Package generated configuration file
# See the sshd_config(5) manpage for details
GatewayPorts yes
[...]

 

service ssh restart

That is it here. Nice and simple.

Decide What Port You will Establish the Tunnel on your SGS

# First figure out what ports your server is
# currently listening/utilizing
# You will want to avoid the ports found in
# this listing.
netstat --listen -A inet

For our example we will utilize port 10002 which is traditionally an open port. Now you can use whatever none 22 (ssh) port you want, just make sure your server is not servicing anything on that port. List of ports and the applications that use them…. http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers

SSH Key Exchange (optimal but optional)

Trust me.  If you want to automate this tunnel, you will want this part.  But you can skip it for your tinkering phase.  And you will want this to be a password-less effort as well.

On your target server/PC/device do the following. Why? It is the target that will establish the tunnel, not the client.

ssh-keygen
# you will be asked for a file name.  Might wanna make it
# something meaningful like id_tunnel.
# DO NOT enter a password, just press Enter for each
# password prompt.
#
# Publish the .pub key to the SGS user's .ssh/authorized_keys
# There are several ways to do this.  You can use an ssh
# login with piping and redirecting, or you can scp the file up to
# the SGS, ssh into the proper account on the SGS and append
# to that user's ~/.ssh/authorized_keys file.  Here I do it the ssh way.
cat /home/USERNAME/.ssh/id_tunnel.pub | ssh -i /home/USERNAME/.ssh/id_tunnel sgs-tunnel-user@sgs-server 'cat >> .ssh/authorized_keys'

Configure Your Target Server ssh_config

NOTICE, not sshd_config but ssh_config. Why? You don’t want your tunnel to drop due to non-usage, (aka time-out after a set idle time).

cd /etc/ssh
cp -p ssh_config ssh_config.v00 #make a backup just in case.
vi ssh_config # and make it so

 

[...]
ServerAliveInterval 60
[...]

TEST Manually

You will want to do this initially so that you can de-bug any issues you might run in to.

# On TARGET server
ssh -f -N -R 10002:localhost:22 tunnel-user@sgs-server

# On Client workstation
ssh any-user-on-target@sgs-server -p 10002

So what did we do.

  • Establish a tunnel as a background process on the target server.
  • Connect to any valid user on the TARGET. Notice the user does not have to
    exist upon the SGS. What you are doing is passing through the SGS to your TARGET.

If all goes well, you should have a ssh session on your TARGET server.

AUTOMATE the TUNNEL

You will want on your TARGET server the following:

NOTE: autossh is probably a better way of doing this keeping alive the tunnel, if you can install autossh.  I haven’t tried that yet as this works, but I imagine it is probably more reliable than my way, though I haven’t had problems using my method.

  • Establish tunnel to SGS on boot up (i.e. via rc.local)
  • ENSURE the tunnel stays alive (i.e. via cron)
    • WHY?  Well, does your internet connection really stay up 24/7/365… no, there are network outages beyond thy control…. so you want to “try periodically” to re-establish your tunnel, other-wise your tunnel will be useless.

What you do is:
* make a script
* control the script via cron and have it launch every 15 minutes so that it checks the health of the tunnel.
** Suggestion, have crontab pipe the output into a log file (preferably have the log file rotated by logrotate)
* sample script below.

#!/bin/bash
echo CHECKING TUNNEL
date
a=""

# Try for 50 seconds and 5 attempts to get a connection as the connection
# may sleep a bit.
for i in 1 2 3 4 5
do
  echo This is:$i Attempt of 5 to test connection
  a=$(echo exit | /usr/bin/telnet TARGET PORT-YOU-ASSIGNED-FOR-HOST | /bin/grep 'Connected');
  if [ "$a" != "" ]; then
    break
  fi
  sleep 10s
done

if [ "$a" == "" ]; then
  echo Connection Down
  #kill old
  p=$(ps -ef | /bin/grep 'ssh_key_file_name' | /bin/grep -v grep | /usr/bin/awk '{print $2}')
#echo output of above command for log sakes.
  ps -ef | /bin/grep 'ssh_key_file_name' | /bin/grep -v grep | /usr/bin/awk '{print $2}'
  echo kill process $p
  kill $p
  echo restart tunnel $p
  /etc/init.d/my_tnl #has ssh -f -N -R REMOTE-PORT:localhost:22 tunnel-user@sgs-server
else
  echo Connection Up
fi
No Comments - Leave a comment

Leave a comment

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.


Welcome , today is Sunday, May 19, 2024