Список открытых SSH-туннелей

68

Я использую множество SSH-туннелей к различным серверам на моей машине с Linux (для туннелирования к базам данных, веб-серверам и т. Д.), И было бы очень удобно просматривать список текущих открытых туннелей с помощью сценария оболочки.

Я могу идентифицировать локальные соединения с помощью grep на netstat, например:

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

но это не покажет мне удаленный порт, к которому он подключен (и, очевидно, включает в себя стандартные соединения SSH, которые не туннелированы)

ОБНОВЛЕНИЕ : ответы в порядке, но не показывает мне удаленный порт, к которому я подключен. Например, у меня часто есть туннель до mysql, скажем localhost: 3308, сопоставляющийся с: 3306 на сервере. Обычно я могу догадаться по выбранным локальным портам, но было бы неплохо иметь доступ к обоим.

Есть идеи?

Джеймс Фрост
источник
4
Недавно я видел пару таких вопросов (не совсем то, что вы спрашиваете), но связанных с ssh, предоставляющим информацию о соединении. Как бы круто ни был ssh, он не справляется с предоставлением некоторой базовой полезной информации, подобной этой. Есть некоторые клиентские внутренние команды, которые вы можете запускать, например, <ret> <ret> ~ # и переменная окружения $ SSH_CONNECTION, но они действительно скудны по деталям. Список бегущих туннелей был бы хорош. Может быть, пришло время для запроса функции.
Дельтарай

Ответы:

73

если вы хотите перечислить только туннели, созданные 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 127.0.0.1:9090 (LISTEN)

(это будет туннель -L 9090: localhost: 80)

если вы хотите увидеть туннели / соединения с 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 127.0.0.1:33999->127.0.0.1:www (ESTABLISHED)
sshd  1396   user  9u  IPv4 148056581   TCP 127.0.0.1:5000 (LISTEN)
sshd  25936  root  3u  IPv4 143971728   TCP *:22 (LISTEN)

ssh-daemon прослушивает порт 22 (последняя строка), порождаются 2 подпроцесса (первые 2 строки, логин 'user'), туннель -R, созданный на порту 5000, и туннель -L, который перенаправляет порт из моего ( локальный) машина для localhost: 80 (www).

Акира
источник
Третья строка есть только потому, что используется сокет TCP. Он просто говорит, что что-то через ssh-туннель попало в ваш локальный веб-сервер, а не то, что порт 33999 перенаправлен на 80-й.
Shellholic
в этом суть туннеля -L ...
akira
Это нормально, он показывает удаленный IP-адрес и список туннелированных портов. В идеале я хочу знать, к какому туннелю подключен удаленный порт. Например, если у меня открыт туннель с 3308 локально до 3306 на сервере, я хочу увидеть оба.
Джеймс Фрост
для этого вам нужно будет либо войти на сервер и выполнить там lsof (надежно), связанный с sshd, либо проанализировать вывод / proc / PID / cmdline для всех ваших команд ssh ... что может привести к ошибочным результатам, так как вы Можно также указать туннели через .ssh / config.
Акира
Да, имеет смысл. Нужно быть немного умнее со сценарием, чтобы потом анализировать результаты, получать список удаленных серверов и выполнять ту же команду на каждом из них, чтобы получить удаленные порты. Определенно выполнимо. Получу на это!
Джеймс Фрост
16

Попробуйте эту команду, это может быть полезно:

ps aux | grep ssh
Раджеш
источник
мое предложение будет: ps aux | grep [s] shd
двоюродный
16

не совсем решение вашей проблемы, но иногда удобно:

Из сеанса SSH:

  1. нажмите Ввод
  2. введите ~, а затем #

показывает вам список всех открытых соединений через ваши туннели для этого сеанса.

Рето
источник
2
Это работает только для интерактивных туннелей (без -N и -f, ...), но интересно знать.
Эрик
6
netstat -tpln | grep ssh
  • t: TCP
  • p: показать процесс
  • л: слушая
  • n: числовые значения

РЕДАКТИРОВАТЬ: пример комментария @akira:

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

Который может быть прочитан как: SSH (не SSHd) прослушивает локальный порт TCP 1443.

shellholic
источник
Также обратите внимание, что -pпоказывает только ваши собственные процессы (все процессы по корню). Кроме того, эта команда показывает sshdтоже.
Олли
для туннелей -R вы должны избегать-l
akira
Вы не можете видеть локально -Rтуннели, если они не используются. Но верно, если в использовании, вы можете поймать их без-l
shellholic
5

Это лучший результат Google по этому вопросу, поэтому я поставлю свой ответ здесь. Я не спал всю ночь, фильтруя результаты, и придумал длинную сложную команду, которая показывает вам только ваши обратные туннели ssh в этом формате:

publicipaddress: remoteforwardedport

Вот код, я использую Ubuntu Server 12. Я использую обратные туннели ssh, которые перенаправляют локальный порт 5900 на мой общедоступный сервер ssh, и эта изящная команда показывает все мои публичные ip-адреса с удаленным портом.

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
Brandon
источник
2
report_local_port_forwardings() {

  # -a ands the selection criteria (default is or)
  # -i4 limits to ipv4 internet files
  # -P inhibits the conversion of port numbers to port names
  # -c /regex/ limits to commands matching the regex
  # -u$USER limits to processes owned by $USER
  # http://man7.org/linux/man-pages/man8/lsof.8.html
  # https://stackoverflow.com/q/34032299

  echo 
  echo "LOCAL PORT FORWARDING"
  echo
  echo "You set up the following local port forwardings:"
  echo

  lsof -a -i4 -P -c '/^ssh$/' -u$USER -s TCP:LISTEN

  echo
  echo "The processes that set up these forwardings are:"
  echo

  ps -f -p $(lsof -t -a -i4 -P -c '/^ssh$/' -u$USER -s TCP:LISTEN)

}

report_remote_port_forwardings() {

  echo 
  echo "REMOTE PORT FORWARDING"
  echo
  echo "You set up the following remote port forwardings:"
  echo

  ps -f -p $(lsof -t -a -i -c '/^ssh$/' -u$USER -s TCP:ESTABLISHED) | awk '
  NR == 1 || /R (\S+:)?[[:digit:]]+:\S+:[[:digit:]]+.*/
  '
}

report_local_port_forwardings
report_remote_port_forwardings

Образец вывода:

LOCAL PORT FORWARDING

You set up the following local port forwardings:

COMMAND   PID  USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
ssh     10086 user     7u  IPv4 1924960      0t0  TCP localhost:2301 (LISTEN)
ssh     10086 user     9u  IPv4 1924964      0t0  TCP localhost:2380 (LISTEN)
ssh     10086 user    11u  IPv4 1924968      0t0  TCP localhost:2381 (LISTEN)

The processes that set up these forwardings are:

UID        PID  PPID  C STIME TTY          TIME CMD
user     10086  7074  0 13:05 pts/21   00:00:00 ssh -N ssh.example.com

REMOTE PORT FORWARDING

You set up the following remote port forwardings:

UID        PID  PPID  C STIME TTY      STAT   TIME CMD
user      7570 30953  0 11:14 pts/18   S      0:00 ssh -N -R 9000:localhost:3000 ssh.example.com
Робин А. Мид
источник
0
/sbin/ip tunnel list # replacement for the deprecated iptunnel command
Лукас Кимон
источник
0
#! / bin / csh -f
эхо SSH туннели подключены
эхо
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 УСТАНОВИТЬ | 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"
конец
Ричард
источник
0

Поскольку я не люблю lsof, я предлагаю альтернативный метод (другой парень научил меня :)):

$ netstat -l | grep ssh

Таким образом, вы показываете созданные ssh-туннели ssh, которые открываются в режиме LISTEN (и по умолчанию они опускаются netstat).

FSP
источник