Вопрос (TL; DR)
При динамическом назначении портов для удаленной переадресации (иначе -R
), как скрипт на удаленном компьютере (например, из источника .bashrc
) может определить, какие порты были выбраны OpenSSH?
Фон
Я использую OpenSSH (на обоих концах) для подключения к нашему центральному серверу, которым я делюсь с несколькими другими пользователями. Для моего удаленного сеанса (на данный момент) я хотел бы переслать X, чашки и pulseaudio.
Наиболее тривиальным является пересылка X с использованием -X
опции. Выделенный X-адрес хранится в переменной среды, DISPLAY
и из этого я могу определить соответствующий порт TCP, в большинстве случаев в любом случае. Но мне вряд ли когда-нибудь понадобится, потому что Xlib чтит DISPLAY
.
Мне нужен аналогичный механизм для чашек и pulaudio. Основы для обоих сервисов существуют в форме переменных среды CUPS_SERVER
и PULSE_SERVER
, соответственно. Вот примеры использования:
ssh -X -R12345:localhost:631 -R54321:localhost:4713 datserver
export CUPS_SERVER=localhost:12345
lowriter #and I can print using my local printer
lpr -P default -o Duplex=DuplexNoTumble minutes.pdf #printing through the tunnel
lpr -H localhost:631 -P default -o Duplex=DuplexNoTumble minutes.pdf #printing remotely
mpg123 mp3s/van_halen/jump.mp3 #annoy co-workers
PULSE_SERVER=localhost:54321 mpg123 mp3s/van_halen/jump.mp3 #listen to music through the tunnel
Проблема в настройке CUPS_SERVER
и PULSE_SERVER
правильности.
Мы часто используем переадресацию портов, поэтому мне нужно динамическое распределение портов. Статическое распределение портов не вариант.
OpenSSH имеет механизм динамического распределения портов на удаленном сервере, определяя 0
как bind-порт для удаленной пересылки ( -R
опция). Используя следующую команду, OpenSSH будет динамически распределять порты для чашек и пересылки импульсов.
ssh -X -R0:localhost:631 -R0:localhost:4713 datserver
Когда я использую эту команду, ssh
выведите следующее STDERR
:
Allocated port 55710 for remote forward to 127.0.0.1:4713
Allocated port 41273 for remote forward to 127.0.0.1:631
Есть информация, которую я хочу! В конечном итоге я хочу создать:
export CUPS_SERVER=localhost:41273
export PULSE_SERVER=localhost:55710
Однако сообщения «Выделенный порт ...» создаются на моем локальном компьютере и отправляются на него STDERR
, к которому я не могу получить доступ на удаленном компьютере. Как ни странно, OpenSSH, похоже, не имеет средств для получения информации о переадресации портов.
Как мне получить эту информацию, чтобы поместить ее в сценарий оболочки для соответствующей установки CUPS_SERVER
и PULSE_SERVER
на удаленном хосте?
Мертвые концы
Единственной легкой вещью, которую я мог найти, было увеличение детализации, sshd
пока эта информация не будет прочитана из журналов. Это нежизнеспособно, поскольку эта информация раскрывает гораздо больше информации, чем разумно сделать доступной для пользователей без полномочий root.
Я думал о исправлении OpenSSH для поддержки дополнительной escape-последовательности, которая печатает хорошее представление внутренней структуры permitted_opens
, но даже если это то, что я хочу, я все еще не могу написать сценарий доступа к escape-последовательностям клиента со стороны сервера.
Должен быть лучший способ
Следующий подход кажется очень нестабильным и ограничивается одним таким сеансом SSH на пользователя. Однако мне нужно как минимум два одновременных таких сеанса, а другим пользователям - еще больше. Но я пытался ...
Когда звезды выровнены должным образом, пожертвовав курицей или двумя, я могу злоупотреблять тем, что sshd
не запускается как мой пользователь, но удаляет привилегии после успешного входа в систему, чтобы сделать это:
получить список номеров портов для всех прослушивающих сокетов, которые принадлежат моему пользователю
netstat -tlpen | grep ${UID} | sed -e 's/^.*:\([0-9]\+\) .*$/\1/'
получить список номеров портов для всех прослушивающих сокетов, которые принадлежат процессам, запущенным моим пользователем
lsof -u ${UID} 2>/dev/null | grep LISTEN | sed -e 's/.*:\([0-9]\+\) (LISTEN).*$/\1/'
Все порты, которые находятся в первом наборе, но не во втором наборе, имеют высокую вероятность быть моими портами переадресации и действительно вычитать выходы наборов
41273
,55710
и6010
; чашки, пульс и Х соответственно.6010
определяется как использование X-портаDISPLAY
.41273
порт чашки, потому чтоlpstat -h localhost:41273 -a
возвращается0
.55710
это импульсный порт, потому чтоpactl -s localhost:55710 stat
возвращается0
. (Он даже печатает имя хоста моего клиента!)
(Чтобы сделать заданное вычитание I sort -u
и сохранить выходные данные из приведенных выше командных строк и использовать comm
для выполнения вычитания.)
Pulseaudio позволяет мне идентифицировать клиента, и, для всех целей и задач, это может служить якорем для отдельных сеансов SSH, которые необходимо разделить. Тем не менее, я не нашел способ связать 41273
, 55710
и 6010
к тому же sshd
процессу. netstat
не будет раскрывать эту информацию пользователям без прав root. Я получаю только -
в PID/Program name
столбце, где я хотел бы прочитать 2339/54
(в данном конкретном случае). Так близко ...
netstat
PID не будет отображаться для процессов, которыми вы не владеете или которые являются пространством ядра. Например