I use a lot of SSH tunnels to various servers on my linux machine (for tunnelling to databases, web servers etc) and it would be really handy to view a list of current open tunnels via a shell script.

I can identify local connections via a grep on netstat along the lines of:

netstat -n --protocol inet | grep ':22'

but this won't show me the remote port its connected to (and obviously includes standard SSH connections that aren't tunnelled)

UPDATE: The answers are fine but are not showing me the remote port I'm connected to. E.g I often have a tunnel through to mysql, say localhost:3308 mapping to :3306 on the server. Normally I can guess by the local ports I've chosen but would be nice to have access to both.

Any ideas?

  • 4
    I've seen a couple questions like this recently (not specifically what you are asking), but related to ssh providing information about the connection. As cool as ssh is, it sucks at providing some basic useful information like that. There are some client internal commands you can run like <ret><ret> ~# and the $SSH_CONNECTION environment variable, but they really are sparse on details. A list of running tunnels would be nice. Maybe its time for a feature request. – deltaray Feb 22 '11 at 2:31
up vote 52 down vote accepted

if you only want to list tunnels created by ssh:

% sudo lsof -i -n | egrep '\<ssh\>'
ssh  19749  user  3u  IPv4 148088244   TCP x.x.x.x:39689->y.y.y.y:22 (ESTABLISHED)
ssh  19749  user  4u  IPv6 148088282   TCP [::1]:9090 (LISTEN)
ssh  19749  user  5u  IPv4 148088283   TCP (LISTEN)

(that would be a -L 9090:localhost:80 tunnel)

if you want to see the tunnels / connections made to a sshd:

 % sudo lsof -i -n | egrep '\<sshd\>'
sshd  15767  root  3u  IPv4 147401205   TCP x.x.x.x:22->y.y.y.y:27479 (ESTABLISHED)
sshd  15842  user  3u  IPv4 147401205   TCP x.x.x.x:22->y.y.y.y:27479 (ESTABLISHED)
sshd  15842  user  9u  IPv4 148002889   TCP> (ESTABLISHED)
sshd  1396   user  9u  IPv4 148056581   TCP (LISTEN)
sshd  25936  root  3u  IPv4 143971728   TCP *:22 (LISTEN)

the ssh-daemon listens on port 22 (last line), 2 subprocesses are spawned (first 2 lines, login of 'user'), a -R tunnel created on port 5000, and a -L tunnel which forwards a port from my (local) machine to localhost:80 (www).

  • The 3rd line is only there because the TCP socket is in use. It just says the something through a ssh tunnel has hit your local web server, not that the 33999 port is forwarded to the 80 one. – shellholic Feb 21 '11 at 13:02
  • thats the essence of a -L tunnel... – akira Feb 21 '11 at 13:03
  • That's fine, its showing the remote IP address and the list of tunnelled ports. What I ideally want to know is what the remote port its tunnelled to. For example, if I've got a tunnel open from 3308 locally to 3306 on the server I want to see both. – James Frost Feb 23 '11 at 10:33
  • for that you would have to either login to the server and execute the sshd-related lsof there (reliable) or parse the output of /proc/PID/cmdline for all of your ssh-commands .. which might give you misleading results since you can specify tunnels via .ssh/config as well. – akira Feb 23 '11 at 11:06
  • Yep, makes sense. Need to be a bit cleverer with the script then to parse the results, get a list of remote servers and execute the same command on each to retrieve the remote ports. Definitely doable. Will get on it! – James Frost Mar 2 '11 at 9:49

Try this command, it might be useful:

ps aux | grep ssh
  • my suggestion would be: ps aux | grep [s]shd – CousinCocaine Feb 27 '14 at 8:54
netstat -tpln | grep ssh
  • t: TCP
  • p: show process
  • l: listening
  • n: numeric values

EDIT: example for @akira comment:

(header added, tested on Debian wheezy)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0*               LISTEN      4036/ssh        

Which can be read as: SSH (not SSHd) is listening to local TCP port 1443.

  • Also note that -p shows only your own processes (all processes by root). Also, that command shows sshd too. – Olli Feb 21 '11 at 12:11
  • for -R tunnels you have to avoid -l – akira Feb 21 '11 at 13:16
  • You can't see locally the -R tunnels if not in use. But right, if in use, you can catch them without the -l – shellholic Feb 21 '11 at 13:26

not exactly the solution for your problem, but also handy sometimes:

From within an ssh session:

  1. press enter
  2. type ~ and then #

shows you a list of all open connections over your tunnels for that session.

  • 1
    That works only for interactive tunnels (without -N and -f, …), but interesting to know. – erik Mar 13 '14 at 23:35

This is the top google result for this question, so I will put my answer here. I stayed up all night filtering the results, and came up with a long complex command that shows you only your reverse ssh tunnels in this format:


Here is the code, I am running Ubuntu Server 12. I am running reverse ssh tunnels that forward local port 5900 to my public ssh server, and this nifty command shows all my public ip addresses with the remote port.

sudo lsof -i -n | egrep '\<sshd\>' | grep -v ":ssh" | grep LISTEN | sed 1~2d | awk '{ print $2}' | while read line; do sudo lsof -i -n | egrep $line | sed 3~3d | sed 's/.*->//' | sed 's/:......*(ESTABLISHED)//' | sed 's/.*://' | sed 's/(.*//' | sed 'N;s/\n/:/' 2>&1 ;done
/sbin/ip tunnel list # replacement for the deprecated iptunnel command
#!/bin/csh -f
echo SSH Tunnels Connected
foreach f (`netstat -an -p | grep tcp | grep sshd | grep -v :: | grep -v 0:22 | grep LISTEN | cut -d" " -f45- | cut -d"/" -f1`)
set ip = `netstat -an -p | grep tcp | grep sshd | grep -v :: | grep -v 0:22 | grep ESTABLISH | grep $f | cut -d" " -f20- | cut -d":" -f1`
#set h = `grep -a "$ip" /htdocs/impsip.html | grep br | cut -d" " -f2`
echo -n "$ip    "
echo  `netstat -an -p | grep tcp | grep sshd | grep -v :: | grep -v 0:22 | grep LISTEN | grep $f | cut -d":" -f2  | cut -d" " -f1`
#echo  " $h"

Since I don't like lsof, I suggest an alternative method (another guy taught me :)):

$ netstat -l | grep ssh

In this way you show the ssh tunnels created by ssh that are opened in LISTEN mode (and are omitted by default by netstat).

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.