May the source be with you, but remember the KISS principle ;-)
Home Switchboard Unix Administration Red Hat TCP/IP Networks Neoliberalism Toxic Managers
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and  bastardization of classic Unix

Forwarding traffic with SSH

News SSH Recommended Links Mini-tutorial Reverse SSH Tunnels X11 forwaring over ssh VNC over SSH SSH troubleshooting
sftp SSH in Pipes Passwordless SSH login Getting console via ssh in DRAC Sysadmin Horror Stories SSH Tips Humor Etc

Not only can SSH forward your authentication requests, but it can forward your X Window System traffic as well. And SSH not only forwards the traffic, but also automatically sets X's DISPLAY variable on the remote system, thus simplifying your side of things substantially. Nobody likes messing with the DISPLAY variable, Magic Cookies, or any other part of remote X configuration. SSH can handle all of those at once. You just need to connect SSH using the -X option, or set ForwardX11 yes in the appropriate config files, and run your X application from the remote system's command prompt.

When using X, I always make sure to turn compression on with the -C option (Compression yes in the config file), as X is bandwidth-intensive, to put it politely. With compression on and a fast cipher such as blowfish (the default for recent versions of OpenSSH), Netscape is just about usable over a 10-Mb network. Without compression, it is rather painful, and I would certainly not recommend running any complex X application on less than 10 Mb.

Perhaps even more interesting is SSH's ability to forward arbitrary ports. Maybe you read mail on a server that you can also SSH into, and POP3 mail is running while secure POP3 is not. You therefore wish to forward a port on your workstation to the POP3 port on the server. Let's pick an arbitrary port, such as 2048. Configure your mail client (such as Netscape) to connect POP3 to port 2048 on localhost (that is, your workstation). Then you can run the following command:

ssh -N -f -L [email protected]
and you'll be able to connect securely.

What's happening here? Option -N tells SSH that you're not interested in running a command on the remote system, only in forwarding the connection, and -f tells SSH to go into the background once you've authenticated your connection.

That way, after you've entered your passphrase (or once ssh-agent has authenticated you), you won't need to type more. The magical part is -L That tells SSH to forward the local port 2048 to's port 110. (Port 110 is the standard POP3 port.) So you log in to the mail server, and then anything on local port 2048 is sent over the SSH connection to port 110 on the remote side, thus allowing you to safely retrieve your mail.

That method works very nicely for most protocols, including POP3, HTTP, and IMAP, just so long as you're able to tell the client server to use the local system and the appropriate port on your local system. For FTP, be sure to use passive FTP, because active FTP opens a second connection that will not be forwarded via the SSH port forwarding. Recent versions of OpenSSH support sftp, which works like FTP and uses SSH without the difficulty of port forwarding and passive mode.

Port Forwarding or tunneling

In addition to X11 forwarding, ssh can also be used to forward connections from one port to another, otherwise known as port forwarding or tunneling. Port forwarding can be used to make an otherwise unencrypted connection secure by encrypting it via ssh. It can also be used to connect to a server behind a firewall.

The basic syntax is as follows:

ssh -L <localport>:<remotehost>:<remoteport> <username>@<otherhost>

When a connection is made to port <localport> on the local system, the connection goes over an encrypted tunnel to the <otherhost> and then is forwarded to port <remoteport> on the <remotehost> after successful authentication for username@otherhost.

SSH tunnel is established between the source host and the SSH server. The destination host can be any type of server configured to accept connections on a static port such as a POP3 email server, a web server, or even another SSH server.

The destination host allows connections from the SSH server through the firewall, but the firewall does not allow connections from the source host. So, an encrypted SSH tunnel is established between the source host and the SSH server. Then, packets intended for the destination host are sent over the encrypted tunnel to the SSH server and then forwarded to the destination host on the other side of the firewall. The connection between the SSH server and the destination host is not necessarily encrypted because 'an SSH tunnel has not been established between them. However, the connection can be secured with additional software such as a VPN solution. If the destination host is another SSH server, the connection between the connecting SSH server and the destination host is encrypted because of the SSH connection.


To disable port forwarding on an OpenSSH server, add the following line to /etc/ssh/sshd_config:

AllowTcpForwarding no

Top Visited
Past week
Past month


Old News ;-)

[Aug 25, 2005] OpenSSH for Windows

SSH-Agent Forwarding and GNU Screen

GNU Screen and OpenSSH are two incredibly useful tools. In this tutorial, I hope to help users to work around a small, but annoying, problem that can arise when using SSH-Agent forwarding and Screen. This tutorial assumes you have knowledge of SSH, SSH-Agent, SSH-Agent-forwarding and GNU Screen. I also assume you're using a shell that can handle Bourne shell variable syntax.

The Problem

SSH-Agent forwarding breaks when screen is re-attached on a different host.


The problem involves three hosts*, A, B, and S. All of these hosts have Agent-Forwarding enabled in their SSH configuration.

I log into host A and run ssh-agent, authenticating to my key. I connect from machine A to machine S using my agent/key to authenticate. On machine S, I start screen. I open several screen windows, all running shells. These shells inherit the ssh-agent variables from the parent shell that spawned the screen. (This is where the problem starts.)

I notice that it& drive to work and log into machine B, starting ssh-agent and authenticate to my key. I connect from machine B to machine S using my agent/key to authenticate. I resume the running screen that I started when logged in from machine A. Naturally, all of the ssh environment variables are still set the way they were prior to the screen de/re-attach. So now, despite having ssh-agent forwarding turned on and having an active agent, I can't connect to remote hosts via host S without some kind of magic.

*This problem could also involve two connections from the same host (which will be on different client ports,) to a second host. I think the above example is clearer.

SSH Environment Variables

When you connect, using ssh-agent for authentication, to a host that has ssh-agent forwarding enabled, the following shell variables will be set:

SSH_CLIENT= 4671 22

The SSH_CLIENT variable contains three space-separated pieces of information. The IP address of the client making the connection, the client's port number, and the server's port number.

The SSH_TTY variable is set to the path to the tty device used for the shell opened when the SSH connection was created.

The SSH_AUTH_SOCK variable identifies the path of a unix-domain socket used to communicate with the agent. In other words, this variable sets up a "path" back to the host that is actually running the agent, so that future ssh connections can talk to/use that agent.

The SSH_CONNECTION variable contains four space-separated pieces of information. The IP address of the client, the port number of the client, the IP address of the server and the port number of the server. This variable is necessary to prevent agent hijacking.

So, now that I've reiterated the ssh(1) man page, we can see why, when we connect from A to S, and then from B to S, ssh-agent forwarding fails. In the initial connection, S defines the SSH environment variables to point to host A. When screen starts its shells, they inherit those variables. When host B connects and grabs that instance of screen, the sub-shells have no idea that anything has changed, so the variables now point to the "wrong" machine.

The Solution

The environment variables listed above are set correctly when host B connects to host S, so we need a way to get them propagated to the shells running inside screen. I wrote a small script to cull them out and stick them in a file. The script also re-formats them so that they will be easily integrated into the shell's environment. I called this script "grabssh."


for x in ${SSHVARS} ; do
    (eval echo $x=\$$x) | sed  's/=/="/
                                s/^/export /'
done 1>$HOME/bin/fixssh

The output of this script looks something like this:

export SSH_CLIENT=" 4685 22"
export SSH_TTY="/dev/pts/22"
export SSH_AUTH_SOCK="/tmp/ssh-jtF17289/agent.17289"
export SSH_CONNECTION=" 4685 22"

Rather than having to type in "grabssh" before resuming any screen, I created an alias:

alias Attach='grabssh ; screen -d -R'

So now every time I resume my screen, the correct ssh-agent variables will be written to ${HOME}/bin/fixssh. I wrote another alias to source that file:

alias fixssh='source $HOME/bin/fixssh'

Now, when I'm in a screen-spawned shell and I want to take advantage of ssh-agent forwarding, I run "fixssh" and everything just works. You might even go so far as to create an alias for ssh like this:

alias ssh='fixssh; ssh' 

However, that alias might someday drive you insane if you're troubleshooting some ssh problem and you forget that it is there.

Send comments to Sam Rowe, deadman at deadman dot org

Tunnels for Fun and Profit

21 July 2003 |

by Andre LaBranche, [email protected]

SSH tunnels can solve at least two problems. First, you can use an ssh tunnel to encrypt sensitive data as it traverses an insecure network. Secondly, reverse ssh tunnels can be used to provide remote access to services located behind a NAT device and / or firewall. The second has proved most useful to me, but we'll cover both.


TCP is a very common protocol used by computers to allow applications to talk to each other. For example, your web browser (application) requests a document from a web server (another application) running elsewhere-TCP is responsible (in part) for allowing your browser to talk to the remote server over a network of some sort. Part of this process involves creating a session, which is sort of a logical 'channel' that is maintained across a packet-switched network (as compared to, say, a circuit switched network). This channel allows the two parties on either end (the browser and the server) to conduct (possibly) useful communication across a potentially extremely diverse network (say, the Internet), regardless of the physical path that the data is actually taking.

Hacking Linux Exposed

SSH Bouncing - How to get through firewalls easily.
By Brian Hatch.

Summary: Often you'll have firewalls or other network equipment that doesn't allow direct SSH access to machines behind it. Using a bit of trickery, you can get through without seemingly jumping through any hoops.

Sponsored by Beginning Perl, Second Edition

Hacking Linux Exposed author James Lee's most recent book, Beginning Perl Second Edition, emphasizes the cross-platform nature of Perl. Throughout the book, Lee promotes Perl as a legible, sensible programming language and dispels the myth that Perl is confusing and obscure. Perfect for the beginning Perl user looking to gain a quick and masterful grasp on the language, this concise and focused book begins with the basics and moves on to more advanced features of Perl, including references, modules, and object-oriented programming.

For reviews and purchasing information, go to

Have you ever been in the situation that you wanted to SSH directly to a machine, but there has been some device in between that prevents it? Say you have a Linux firewall that protects your DMZ, and you have a boatload of machines behind it that you want to manage. There are all sorts of methods that are used to do so, and all have some level of annoyance.

SSH to the intermediate host
The first and most simple solution is to SSH to the machine in the way, say the firewall. The firewall administrator can just set up one or more non-privileged accounts for users who need access to the machines behind it. This is a pain, of course - if you want to upload a file, you need to upload it to the firewall via sftp/scp, and then upload it to the target server. What a pain. And security-wise, you now have all these random firewall accounts running amok, probably not your favourite situation.

Of course, it's still nicer than Windows networking, but we can do better.

Non-standard SSH ports
You can set up a bunch of ports that tunnel into the target machines. You might have firewall port 5000 go to port 22 (the SSH port) on machine1, firewall:5001 go to machine2, firewall:5002 go to machine3, etc. For example,
  # Set up forwards for inbound SSH

  EXT_IP=205.382.29.20    # External IP address
  EXT_IFACE=eth0          # External Interface
  INT_IFACE=eth1          # Internal Interface

  # handy dandy tcp forward function
  tcp_forward () {
    local ext_port int_ip
    echo "$1" | {
      read int_ip  ext_port
       # create prerouting and appropriate forward from the tuple
       iptables -A PREROUTING -t nat -p tcp -d $EXT_IP \
          --dport $ext_port -j DNAT \
          --to-destination $int_ip:22
       iptables -A FORWARD -i $EXT_IFACE -o $INT_IFACE \
          -p tcp -d $int_ip --dport 22 -m state \
          --state NEW -j ACCEPT


   tcp_forward "      5000"
   tcp_forward "      5001"
   tcp_forward "      5002"
   tcp_forward "      5003"
   tcp_forward "     5057"
   tcp_forward "     5058"

What problems do we have with this setup? Well, you need to manage the forwards, which is rather a pain. Also, you now have these ports open to the outside world, which means you need to create ACLs for them on the firewall or the target or both, lest anyone be able to try to guess passwords.

The other problem with this is that you'll get ssh host key conflicts unless you're careful -- you appear to connect to the machine 'firewall' but you get different keys when you hit the actual machine behind it. To get around this, you can use $HOME/.ssh/config sections like this:

  Host machine1
  Port 5000
  HostKeyAlias machine1

  Host machine2
  Port 5001
  HostKeyAlias machine2

Then you can just ssh machine1 and not need to remember the port, and due to the HostKeyAlias option each machine will have it's own key recognised correctly, rather than sharing the one for the firewall.

Netcat SSH bounce
This is my preferred method, and it can be used to create a seamless connection. What you do is SSH to the intermediate machine (the firewall in this example) and from that machine you run Netcat (nc). Netcat can be used in all sorts of situations, such as a replacement for telnet:
 $ nc 80
 GET / HTTP/1.0


When used as a telnet-like replacement, all it does is open up a connection to the remote port and transfer the data, unaltered, to and from it and your keyboard/screen. So how do we use this to help out with our SSH connection?

OpenSSH supports the ability to use a proxy command. A proxy command is a program (shell script, binary, etc) that /usr/bin/ssh will run, rather than making an actual TCP connection to the target. The job of the proxy command is to establish a connection to the target. /usr/bin/ssh talks to this command, and doesn't care how it does its work.

So, what will our proxy command do?

  • The proxy command will SSH to the firewall
  • On the firewall, it will run Netcat as follows:
      nc -w 1 target_host 22

The nc command says 'connect to port 22 on the target host, and wait one second after the connection is dead before closing it.' Now Netcat's stdin/stdout are going to be connected to the SSH server on the target, and the /usr/bin/ssh client on your desktop. To the client program, it looks just like it's hit the target directly, the proxy does the work of getting them together.

So, how do we create this proxy? How 'bout a shell script:

  $ cat netcat-proxy-command

  ssh bouncehost   nc -w 1 $target 22 

Then point to this proxy command via your $HOME/.ssh/config file:

  $ head $HOME/.ssh/config
  Host machine1
  Hostname machine1
  HostKeyAlias machine1
  ProxyCommand netcat-proxy-command

  Host machine2
  Hostname machine2
  HostKeyAlias machine2
  ProxyCommand netcat-proxy-command


Or, to make it even easier to copy/paste, use the fact that %h in a $HOME/.ssh/config file is replaced with the hostname, and you can use the following:

  $ head $HOME/.ssh/config
  Host machine1
  HostKeyAlias machine1
  ProxyCommand netcat-proxy-command %h

  Host machine2
  HostKeyAlias machine2
  ProxyCommand netcat-proxy-command %h

All the logic of how to actually get to the host is in the config file, all the magic in getting there is in the proxy script, and you can connect 'directly' to the target machine at the command line like this:

  $ ssh machine1
  $ scp machine1:/path/to/some/file .

Now doing this requires that you can connect to the firewall without a password[1] If you can't, then you'll want to to enable SSH key based security. If you don't know how to do that yet, see one of the Previous Articles that covers it.

There are many other options that I didn't cover here, such as VPN technologies, Portknocking and fun tunnels like chownat ( While these can all be exciting, I'm trying to stick to pretty portable tools that are likely pre-installed on your machines anyway.

Next time, we'll see how to tighten security a bit by making changes to the firewall user's configuration.


Brian Hatch is Chief Hacker at Onsight, Inc and author of Hacking Linux Exposed and Building Linux VPNs. He can't understand how a few months have gone by since he had time to write. Oh wait, maybe it's the number of kids in his home, and the massive distance between him and any free babysitting -- i.e. relatives... Brian can be reached at [email protected]

Recommended Links

Google matched content

Softpanorama Recommended

Top articles


Top articles





HTTP tunneling

VNC Tunneling



Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy


War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes


Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law


Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Haterís Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D

Copyright © 1996-2021 by Softpanorama Society. was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to to buy a cup of coffee for authors of this site


The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.

Last modified: March, 12, 2019