Tunneling with OpenSSH

From LQWiki
Jump to: navigation, search

SSH tunneling means to send network traffic from an incoming port to an outgoing port using ssh encryption. It is called a tunnel because it connects two points and, because of encryption, the traffic content is not visible to spectators.

Tunneling Ports with SSH

You can use ssh for port forwarding so e.g. traffic arriving at port 42 of your computer is forwarded to port 80 of wiki.linuxquestions.org. Additionally, this traffic will be encrypted and compressed. You can use this

  • if some port, maybe 80 is not routed inside your netWork
  • if you want a light-weight vpn for security reasons
  • if you want to connect to a network service on a non-default port (see below)

As an example, I need to access a server target with the rdesktop protocol on port 1807. The only possibility to do this is to forward port 3389 from my local computer to port 1807 of the remote computer and then rdesktop to localhost. To do the port forwarding, I type

ssh -g root@localhost -L 3389:target:1807

and login. As soon as I have logged in, I can rdesktop to localhost and get a connection to the target computer.

With other words, your syntax is

ssh -g user@local machine -L local port:remote machine:remote port

Extras

  • You can have your local system accept outside connections. So anyone on your LAN could connect to your system on port 99, and have tunneled access to your VNC sever. (So long as the SSH session is active).
  • You can do the same thing for FTP, HTTP, etc to get access to home servers, without publicly exposing those ports. Theoretically, you can close all ports but 22 (SSH).
  • You can reverse the direction using remote port forwarding: any traffic sent to the SSH server on a given port is forwarded to the local system. Good for picking up SNMP traps from home systems.
  • Port forwarding is only active once you have authenticated, so people can't launch anonymous attacks on your network.
  • SSH can also be tunneled through HTTP proxies by use of programs like corkscrew.

Reverse SSH for remote access behind NAT or firewall

disclaimer, this is NOT to be used in violation of company rules you could get fired or worse.
A great use for this is to gain access to a family members laptop while they are on the road. This is exactly what I use it for so I can administer my wife and daughters laptops from any place as long as we both have internet access.
This is much easier if you use ssh keys see: HOWTO Create ssh keys
You will need ssh access to a 3rd computer, I will call this remote_server and two other computers (computer_A and computer_B) that can run and handle ssh.
1. From the computer that needs to allow ssh access (computer_A) that is either behind a firewall or is on a NAT network issue the following command as USER.
ssh -fNR 22222:localhost:22 remote_user@remote_server
This creates a ssh connection that runs in the background and creates a reverse tunnel.
     -f    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.
     -N      Do not execute a remote command.  This is useful for just forwarding ports (protocol ver-
            sion 2 only).
     -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 for-
            warded over the secure channel, and a connection is made to host port hostport from the
            local machine.
.
            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 speci-
            fied by enclosing the address in square braces or using an alternative syntax:
            [bind_address/]host/port/hostport.
.
            By default, the listening socket 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.
2. For computer_B (say your home computer) to access computer_A all that needs to be done is to ssh into remote_server and connect to the specific localhost port.
computer_B:~ user$ ssh user@remote_server
(user@remote_server) ~ $ ssh -p22222 user@localhost
Last login: Sun Aug  4 20:07:22 2013 from localhost 
computer_A:~ user$

Scripting remote access for multiple users

Say you have more then one remote user you need access to their system to assist, fix, update, what ever. Instead of trying to get the user to make the connection by hand use a simple script they can call for you.
*NOTE* Keep in mind that ever time you use this process you will need to delete the localhost line in:
/home/user/.ssh/known_hosts
or you will get errors as every computer is going to have its own key. I am sure there is a way around this, but I do not know it.
Feel free to copy/paste/modify this script as long as you keep the license and properly document any and all changes.
1. As root on the remote computers (field computers or Computer_A from the above example) copy/paste the script into
/use/bin/foo.sh
were foo is what ever you want to call it. I named mine remote_connection.sh This is something that is simple enough to remember and type.
2. Follow the same steps as above.
#!/bin/bash
#
########################################################### 
### Created by Ray Brunkow Aug 4, 2013
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 or version 3 of the
# license, at your option.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###
###########################################################
###########################################################
###
#
# The sole purpose of this script is to provide me remote access to 
# my wifes computer for management reasons anytime and place
# she has internet access.  Specifically while she is at work.  The 
# intent is NOT to break any law(s) or company rules.  Keeping her
# Linux computer connected with her MS Windows work environment
# is the primary reason for the creation of this script.
#
###
###########################################################
###########################################################
### setting variables
#
RHOST=some_URL.com	# set your own URL/IP address for your remote server
RUSER=user		# set your own remote user
#
###
###########################################################
###########################################################
### test for specific users and set appropriate port number
### The following code was suggested by Firerat
#
case $(whoami) in
    user1) PORT=11111;;
    user2) PORT=22222;;
    user3) PORT=33333;;
    user4) PORT=44444;;
        *) echo "Error, user \"$(whoami)\" undefined";exit 1;;
esac
#
###
###########################################################
### side note.  If you run this with the -fN and you lose connection from computer_A
### you will lock up that specific port.  If that is a potential issue have the person
### on computer_A run it without the -fN.  You will have to edit the script before
### it is run.
#
ssh -fNR "$PORT":localhost:22 "$RUSER"@"$RHOST" 
#ssh -R "$PORT":localhost:22 "$RUSER"@"$RHOST" 
exit