Я понял это; один из uniq
опции -c
, для "строк префикса количеством случаев":
$ uniq -c
(У меня нет a /dev/tcp
устройство в моей системе; однако bash
кажется, имеет некоторую встроенную обработку для него, выделяя сокет tcp, подключенный к следующему /host/port
часть.)
Так, Ваша команда прокси ssh надежно работает на оболочке gatewayserver
который делает:
exec 3<>/dev/tcp/targetserver/22
т.е. присоедините сокет на filedescriptor 3 (подключенный с targetserver
/port
). Затем:
cat <&3 & cat >&3; kill $!
который является способом иметь двунаправленное перенаправление (использующий два отдельных процесса) между несколькими filedescriptors 0
(вход) и 1
(вывод) и filedescriptor 3
(ввод и вывод). kill $!
есть ли для уничтожения фонового процесса cat <&3
после другого процесса cat >&3
возвратился.
Все это - просто некоторый эквивалент более стандартного:
ProxyCommand ssh gatewayserver "tcpconnect targetserver port"
использование /dev/tcp
(или bash
) функции вместо tcpconnect
команда.
Еще некоторые детали:
Команда прокси, используемая ssh, там, чтобы определить, как соединиться с удаленным хостом targetserver
(шифрование не действительно необходимо там, потому что ssh протокол будет использоваться по этому каналу). В нашем случае мы хотим установить соединение с этой канавкой целевого узла gatewayserver
(вероятно, потому что брандмауэр предотвращает для соединения с targetserver
непосредственно.
Так процесс
ssh gatewayserver 'exec 3<>/dev/tcp/targetserver/22; cat <&3 & cat >&3;kill $!'
запускается и:
1
(иначе стандартный вывод), будет использоваться ssh клиентом для отправки данных в целевой узел.0
(иначе стандартный вход), будет использоваться ssh клиентом для чтения данных с удаленного хоста. ssh gatewayserver
используется для первого соединения со шлюзом, который будет первым транзитным участком. Новая оболочка запускается на этом хосте и этом ssh
экземпляр передаст fd 0
/fd 1
из процесса на источнике размещают к fd 0
/fd 1
из оболочки, работающей на хосте шлюза. Команда, выполняемая этой оболочкой:
exec 3<>/dev/tcp/targetserver/22; cat <&3 & cat >&3;kill $!
exec
без команды ничего не выполнит, она просто применит следующие перенаправления сама оболочка. Обычные перенаправления:
n>file
перенаправить fd n
кому: file
(открытый для записи только, n
1
если опущено).n<file
перенаправить fd n
кому: file
(открытый для чтения только, n
0
если опущено).n<>file
перенаправить fd n
кому: file
(открытый для чтения и записи).n>&m
или n<&m
или n<>&m
, fd n
перенаправляется в файл, на который ранее указывает fd m
.Здесь следующее используется:
exec 3<>/dev/tcp/targetserver/22
Это перенаправит недавно созданный fd 3
в некоторый совершенно особый файл /dev/tcp/targetserver/22
(который не является действительно файлом, но что-то колотит, понимает исходно). Здесь, удар создает сокет (специальный файл, который использует tcp протокол) говорить targetserver
на порте 22
(Где мы ожидаем находить a sshd
сервер), и этот файл открыто (read&write) на fd 3
.
Теперь мы должны "накачать" данные по fd 0
(данные от клиента), и отправляют его в fd 3
(подключенный к целевому серверу). Мы также должны гарантировать обратную коммуникацию путем "нагнетания" данных по fd 3
и передача обратно его к fd 1
(результат для клиента). Те два "насоса" настраиваются с помощью два cat
процессы:
cat <&3
(который читает из fd оболочки 3
и запишите в fd оболочки 1
.)cat >&3
(который читает из fd оболочки 0
и запишите в fd оболочки 3
.)Оба cat
s должен быть выполнен параллельно, таким образом, нужно быть фоном. Здесь, мы хотим тот, который читает на fd 0
(который, вероятно, будет tty) быть тем, оставленным на переднем плане. Это дает:
cat <&3 & #run in the background
cat >&3; kill $!
kill $!
есть ли для уничтожения фонового процесса ($!
расширяется до pid последнего фонового процесса). Таким образом, когда клиент зависает, приоритетный процесс, завершается, уничтожение выполняется, и последний процесс завершается также.
Именно! Мы сделали мост:
хост источника — (ssh) → шлюз — (pumps+socket) → targetserver (порт 22)
ssh user@targetserver
на источнике хост сможет соединиться с целевым узлом через этот мост!