Utility Script for Reverse SSH Tunneling When Collaborating with Developers Behind Firewalls

Use Case:

  • Collaboration with peers that allow them to directly interface with your local development TCP/IP Ports using an intermediary SSH server

Two Scenarios with Commands Outputted:

  • Command for Scenario 1:
    • As a developer, I want to be able to expose my local development address/port for usage by another developer who is attempting to assist me,
    • My local firewalls are preventing direct connection on the host and port so I will connect to a remote server and expose a tunnel that will allow the developer to connect in this alternative and secure manner
  • Command for Scenario 2:
    • As a developer, I want to be able to assist my fellow developer who has exposed their connection on a remote server using my local computer
    • The remote firewall on the SSH server does not permit me to connect directly to this exposed port that the developer setup so I will establish a port forwarded tunnel that redirects a specified port on my local machine to the remote server and remote port that I am attempting to hit – therefore allowing me to establish the connection to the end developers reverse proxy

I wrote this script up based off prior usage so I won’t have to fiddle with SSH documentation anymore as the syntax behind this concept is very confusing sometimes especially if you only have to execute this once every few months.

The below script has a ton of comments inline describing how to use it and what each variable does.

The formatting may look horrible in WordPress but if you copy paste it into a text file *.sh it will look and make a ton of sense.

# Use Case:
# - Collaboration with peers that allow them to directly 
#   interface with your local development TCP/IP Ports

#########################################################################################
# For further documentation scroll to the bottom of this script where all the variables #
# are described in detail how they work                                                 #
#########################################################################################

# Scenario 1:
# - As a developer, I want to be able to expose my local development address/port for usage 
#   by another developer who is attempting to assist me, 
# - My local firewalls are preventing direct connection on the host and port so I will 
#   connect to a remote server and expose a tunnel that will allow the developer to connect 
#   in this alternative and secure manner

VARIABLE_REMOTE_SSH_SERVER="myRemoteSshServerForCollaboration.com"
VARIABLE_REMOTE_SSH_PORT="22"
VARIABLE_REMOTE_SSH_USER="myRemoteSshUser"

VARIABLE_REMOTE_BIND_ADDRESS="[::]" #Bind on all remote addresses
VARIABLE_REMOTE_BIND_PORT="1234"

VARIABLE_LOCAL_ADDRESS_TO_FORWARD="localhost"
VARIABLE_LOCAL_PORT_TO_FORWARD="1993"

echo ""
echo "########################################################"
echo "## Give this to the user you are trying to connect to ##"
echo "########################################################"
echo ""
echo ssh -fN -o StrictHostKeyChecking=no -R "$VARIABLE_REMOTE_BIND_ADDRESS:$VARIABLE_REMOTE_BIND_PORT:$VARIABLE_LOCAL_ADDRESS_TO_FORWARD:$VARIABLE_LOCAL_PORT_TO_FORWARD" -l $VARIABLE_REMOTE_SSH_USER $VARIABLE_REMOTE_SSH_SERVER -p $VARIABLE_REMOTE_SSH_PORT

# Scenario 2:
# - As a developer, I want to be able to assist my fellow developer who has exposed their connection
#   on a remote server using my local computer 
# - The remote firewall on the SSH server does not permit me to connect directly to this exposed port 
#   that the developer setup so I will establish a port forwarded tunnel that redirects a specified port
#   on my local machine to the remote server and remote port that I am attempting to hit - therefore allowing
#   me to establish the connection to the end developers reverse proxy

VARIABLE_REMOTE_SSH_SERVER="myRemoteSshServerForCollaboration.com"
VARIABLE_REMOTE_SSH_PORT="22"
VARIABLE_REMOTE_SSH_USER="myRemoteSshUser"

VARIABLE_LOCAL_PORT_FOR_RELAY="1993"

VARIABLE_REMOTE_ADDRESS_FOR_RELAY="localhost"
VARIABLE_REMOTE_PORT_FOR_RELAY="1234"

echo ""
echo "########################################################"
echo "## Execute this locally to connect to the user you    ##"
echo "## who is attempting to expose their local dev ports  ##"
echo "########################################################"
echo ""
echo ssh -fN -o StrictHostKeyChecking=no -L $VARIABLE_LOCAL_PORT_FOR_RELAY:$VARIABLE_REMOTE_ADDRESS_FOR_RELAY:$VARIABLE_REMOTE_PORT_FOR_RELAY -l $VARIABLE_REMOTE_SSH_USER $VARIABLE_REMOTE_SSH_SERVER -p $VARIABLE_REMOTE_SSH_PORT

#
# - VARIABLE_REMOTE_SERVER - specifies what remote intermediary 
#   server you will be exposing your local ports to for another 
#   user to connect with/through
# 
# - VARIABLE_REMOTE_USER - specifies what remote intermediary 
#   server user account you will be using in conjunction with 
#   VARIABLE_REMOTE_SERVER variable
#
# - Parameter -l on SSH Command:
#     - login_name - Specifies the user to log in as on the 
#       remote machine. This also may be specified on a per-host 
#       basis in the configuration file.
#
# - Parameter -N on SSH Command:
#     - Do not execute a remote command. This is useful for 
#       just forwarding ports (protocol version 2 only).
#
# - Parameter -f on SSH Command:
#     - Requests ssh to go to background just before command execution. 
#       This is useful if ssh is going to ask for passwords or passphrases, 
#       but the user wants it in the background. This implies -n. The 
#       recommended way to start X11 programs at a remote site 
#       is with something like ssh -f host xterm.
#
# - Parameter -L on SSH Command:
#     - [bind_address:]port:host:hostport
#     - Specifies that the given port on the local (client) host is to be 
#       forwarded to the given host and port on the remote side. This works 
#       by allocating a socket to listen to port on the local side, optionally 
#       bound to the specified bind_address. 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 remote machine. 
#       Port forwardings can also be specified in the configuration file. 
#
# - Parameter -R on SSH Command:
#     - 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.
#
# - Parameter -o on SSH Command:
#     - option - Can be used to give options in the format used in the 
#       configuration file. This is useful for specifying options for which 
#       there is no separate command-line flag. For full details of the options 
#       listed below, and their possible values, see ssh_config(5).
#
# - Option StrictHostKeyChecking on SSH Option Command:
#     - StrictHostKeyChecking can be used to control logins to machines whose 
#       host key is not known or has changed. The keyword is described in StrictHostKeyChecking.
#     - Useful with AWS EC2 Instances whose host keys constantly change when destroyed/recreated.
#
# - VARIABLE_REMOTE_BIND_ADDRESS - specifies what hostnames or addresses the reverse
#   connection will be available on for usage by other user later on
#
# - VARIABLE_REMOTE_BIND_PORT - specifies the port the reverse connection will be available
#   on for usage by other user later on
#
# - VARIABLE_LOCAL_ADDRESS_TO_FORWARD - Specifies the local hostname to forward to the remote
#   server that will be exposed on the VARIABLE_REMOTE_BIND_ADDRESS and VARIABLE_REMOTE_BIND_PORT
#
# - VARIABLE_LOCAL_PORT_TO_FORWARD - Specifies the local port to forward to the remote
#   server that will be exposed on the VARIABLE_REMOTE_BIND_ADDRESS and VARIABLE_REMOTE_BIND_PORT
#
# - VARIABLE_REMOTE_PORT_FOR_RELAY - Specifies the remote port we want to connect to and make 
#   available locally via the VARIABLE_LOCAL_ADDRESS_FOR_RELAY and VARIABLE_LOCAL_PORT_FOR_RELAY
# 
# - VARIABLE_LOCAL_ADDRESS_FOR_RELAY - Specifies the local address we want to listen on for 
#   connection to the VARIABLE_REMOTE_PORT_FOR_RELAY on the remote ssh server
#
# - VARIABLE_LOCAL_PORT_FOR_RELAY - Specifies the local port we want to listen on for 
#   connection to the VARIABLE_REMOTE_PORT_FOR_RELAY on the remote ssh server
#
# - VARIABLE_REMOTE_SSH_SERVER/VARIABLE_REMOTE_SSH_PORT/VARIABLE_REMOTE_SSH_USER - Specifies
#   the remote ssh server that we will be connecting to where both scenarios are exposed and 
#   accessible for connectivity by both end users

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s