Tunneling is the process of placing an entire packet within another packet and sending it over a network. The protocol of the outer packet is understood by the network and both points, called tunnel interfaces, where the packet enters and exits the network. Tunneling typically requires three (possibly different) protocols:
Tunneling has amazing implications for VPNs. For example, you can place a packet that uses a protocol not supported on the Internet (such as NetBeui) inside an IP packet and send it safely over the Internet. Or you could put a packet that uses a private (non-routable) IP address inside a packet that uses a globally unique IP address to extend a private network over the internet, or create a route, consisting of private addresses only, between two private networks - using the internet. That's how vpn's (Virtual Private Networks) are created. Apart from tunneling, vpn's usually also use
Essentially, tunneling is the process of placing ("wrapping", "encapsulating") an entire packet within another packet and sending it over a network. The private packet becomes the payload (data) of an other packet. You create a VPN tunnels by wrapping packets from private networks in IP packets that get transported over a public network such as the internet. At the receiving end, the wrapper is removed and the original packet continues it's way on the private network.
Tunnels are point-to-point connections and the end-points can either be routers/gateway devices or software running on a PC, and work by creating a (virtual) network interface (a tun device) with its own private network address and a route to tun device on the remote host. Such tunnels can be created between
The principle is always the same : a private packet is encapsulated, routed towards the destination, unpacked, and delivered to the destination or routed further on a private network.
ssh (secure shell) a network protocol for remote command execution. It uses encryption and can use private/public key pairs for authentication. In its simplest form, ssh opens a console session on a remote host over an encrypted connection (so passwords and commands can't be intercepted), but the protocol also supports certificate based authentication, secure (encrypted) file transfer and remote command execution, and it is possible to use ssh as carrier for other protocols (encapsulation), allowing for the creation of secure tunnels without setting up a vpn infrastructure.
When you're looking for secure remote command execution, setting up a vpn infrastructure may well be overkill. ssh allows you to execute commands on a remote system, over a secure connection. It also acts as a carrier for secure file transfer protocols, so you don't necessarily need vpn tunnels if you only need to securely transfer files between hosts.
## ssh - some examples # open a remote shell session ssh user@remotehost # execute a command on a remote host, without starting an interactive session # eg a directory listing ssh user@remotehost ls -al /etc # execute multiple commands on remote host # including running a script with even more commands ssh user@remotehost <<EOF apt-get update apt-get -y upgrade cd tmp wget http://myserver/scripts/postinstallscript chmod a+x postinstallscript ./postinstallscript EOF ## secure copy scp [options] myfile user@remotehost:/home/user/myfile ## starting a secure FTP session (for file upload, download, ...) sftp user@remotehost #defaults to /home/user at remote host ## see also : rsync : file and directory synchronization with remote hosts, over secure connections
more elaborate remote command execution and remote connections can be accomplished through remote desktop sessions, preferably over a secure connection, or by running remote applications and exporting their output to your desktop. This is often done by using ssh as a carrier for other protocols, eg to transport X (the X Window System)
## running a remote graphical file browser and view it on your local desktop # add remote host as 'trusted' xhost +myserver # run xfe file browser to browse remote file system ssh -X jdoe@myserver xfe
see also Server-based computing
With ssh tunnels, you use ssh as a carrier for another (theoretically : any other) application protocol, which offers you the advantage that ssh connections are encrypted and can do client and server authentication. This allows you to establish secure connections with any network application (web server, file server, mail server, ...). Another application of ssh tunnels would be to create secure tunnels through a firewall : the firewall can then simply block all traffic except ssh, and all applications that are tunneled through ssh will continue to work, and securely at that.
There are two kinds of port forwarding: local forwarding and remote forwarding. They are also called outgoing and incoming tunnels, respectively. To understands what happens and how to set it up, we start with "local" (-L) tunnels. This will help to understand "remote" (-R) tunnels later.
to create a local tunnel, you map / connect a local tcp port to a remote socket (remote_address:remote_tcp-port). Consequently, any connection (by a local application on your machine) to that local port, will be 'forwarded' to the remote socket. It helps if you think of it as "port forwarding", which is in fact the more accurate, official name, rather than "tunnels".
For example : you map / connect / forward local port 80 to your web server at 192.168.10.1:80. Now, if you browse to localhost:80, you in fact connect to 192.168.10.1:80, where apache, lighttpd, ... are waiting. You've established a secure connection to a web server. Obviously, this requires an ssh server/daemon (eg openssh-server installed and running on the remote machine.
Likewise, if you forward local ports 110 and 25 to port 110 and 25 of a remote mail server, and configure your mail client (Thunderbird ?) to use localhost for POP3 and SMTP (incoming/outgoing mail), Thunderbird will connect to the remote mail server over the secure ssh connection. It's clear that the target service (www, mail, ...) daemon needs to be configured to be listening on the loopback interface (localhost).
the ssh man page gives the following syntax :
ssh [-l login_name ] hostname OR ssh user@hostname [command ] where ssh can take the following options ssh [-afgknqstvxACNTX1246 ] [-b bind_address ] [-c cipher_spec ] [-e escape_char ] [-i identity_file ] [-l login_name ] [-m mac_spec ] [-o option ] [-p port ] [-F configfile ] [-L port host hostport ] [-R port host hostport ] [-D port ] hostname | user@hostname [command ]
To set up such local portforwarding ("tunnel") :
# example of local portforwarding : local port 80 connected to remote server 'myserver' port 80 ssh me@myserver -L 80:localhost:80 # example of local portforwarding : local port 8081 connected to remote server 'oracle-rdbms-srv' port 8080 ssh oracle-rdbms-srv -L 8081:localhost:8080
Oracle XE comes with a web interface that, by default and for security reasons, is only accessible on localhost, i.e. the server where you installed Oracle XE. To access the web interface, you connect with ssh to the server and establish local port forwarding so you can use a web browser on a remote PC t start configuring Oracle through its web interface. Se also Debian Oracle Primer.
-L 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, and whenever a connection is made to this port, the connection is forwarded over the secure channel, and a connection is made to hostport on the remote machine. The local port and remote port do not need to be the same (see oracle example). Port forwardings can also be specified in the configuration file. Only root can forward privileged ports. IPv6 addresses can be specified with an alternative syntax: port/host/hostport .
The hostname 'localhost' (in the -L parameter) is resolved after the Secure Shell connection (ssh [user@]remote-hostname) has been established - so when defining local forwarding (outgoing tunnels), the 'hostname' is (always ?) localhost, and localhost here refers to the server (remote host computer) you have connected to (with the ssh remote-host statement).
Adding to the confusion : after the tunnel has been established, you'll point your client to "localhost:localport", and in this case localhost really means "your computer", but the port has been forwarded to a remote socket so you end up connecting to the remote host.
http://souptonuts.sourceforge.net/sshtips.htm illustrates some uses of ssh tunneling from both Linux and Windows clients, including:
Remote port forwarding does the opposite of local port forwarding: it forwards traffic coming to a remote port to a specified local port. For example, all traffic coming to port 1234 on the server (host) could be forwarded to port 23 on the client (localhost) : you "pull" the packets, originally destined for a remote host, to your computer. This should be identical to creating an L tunnel while logged on to the remote machine (but I haven't checked that -- FIXME)
You will have to authenticate with a username and password on the remote system. SSH can also be setup to connect passwordless, i.e. through Public Key authentication, host-based authentication, certificates, and so on.
Concept of a vpn connection between two LANs :
Here's an example of traceroute from a host on LAN A (192.168.10.0) to a host on LAN B (192.168.20.0), through a vpn. Although the packets actually travel over the internet, the traceroute program is unaware of this and reports as if there's a direct connection between the vpn gateways.
testhost:~# ifconfig | grep "inet addr" inet addr:192.168.10.2 Bcast:192.168.10.255 Mask:255.255.255.0 testhost:~# traceroute 192.168.20.12 traceroute to 192.168.20.12 (192.168.20.12), 30 hops max, 40 byte packets 1 192.168.10.1 (192.168.10.1) 2.601 ms 1.176 ms 1.518 ms 2 192.168.15.189 (192.168.15.189) 12.377 ms 9.604 ms 10.171 ms 3 192.168.20.12 (192.168.20.12) 15.091 ms 11.495 ms 9.567 ms
When connecting to a public internet address however, be it the WAN (internet) interface of LAN B's router or any arbitrary internet server, traceroute shows the internet route "underneath" the tunnel :
testhost:~# traceroute 188.8.131.52 traceroute to 184.108.40.206 (220.127.116.11), 30 hops max, 40 byte packets 1 192.168.10.1 (192.168.10.1) 2.639 ms 1.426 ms 1.250 ms 2 192.168.15.189 (192.168.15.189) 12.663 ms 10.394 ms 9.927 ms 3 18.104.22.168 (22.214.171.124) 11.685 ms 13.311 ms 9.661 ms [...] 6 * gw1.lvn3.Serlial5-0-4-1.be.uu.net (126.96.36.199) 14.201 ms 19.234 ms 7 so-1-0-0.CR2.BRU5.ALTER.net (188.8.131.52) 23.794 ms 16.985 ms 22.611 ms 8 so-7-0-0.XR2.BRU2.ALTER.net (184.108.40.206) 17.754 ms 14.850 ms 16.319 ms 9 [...] 14 220.127.116.11 (18.104.22.168) 73.894 ms 18.922 ms 21.025 ms 15 22.214.171.124 (126.96.36.199) 99.008 ms 100.935 ms 112.348 ms 16 188.8.131.52 (184.108.40.206) 111.698 ms 100.507 ms 96.053 ms [...]
Here's how to set this up with OpenVPN (on Linux).
the difference between an ssh tunnel and a vpn is that ssh forwarding tunnels TCP-ports associated with applications, while a vpn works at network level (IP routing). http://souptonuts.sourceforge.net/sshtips.htm illustrates how creating multiple tunnels to a number of servers can give you functionality that resembles a vpn, but in fact you're still just tunneling a bunch of applications.
However, you can use ssh to create a vpn tunnel with something like this : ssh and ppp based vpn mini-howto.
Some creative use of -g -b and -D flags or -o (options : Forward..., GatewayPorts.....) may also offer some sort of LAN-to-LAN tunneling possibilities. The OpenBSD implementation of ssh also supports a -w switch to let ssh use tunnel devices (http://www.openbsd.org/cgi-bin/man.cgi?query=ssh). This option is apparently not implemented in the Linux version of ssh.
When using ssh tunnels for secure connections, it is important to note that only the connection between the two hosts involved in the connection is secure. ssh myserver -L ... creates a tunnel from your computer to 'myserver', and only the connection between your computer and 'myserver' is secure. If this server acts as a gateway to other hosts or pulls data from other network resources (eg database server, file server), that traffic isn't secured - unless, of course, you've additionally implemented a secure link between them.