Питання (TL; DR)
Коли динамічно призначається порти для віддаленого переадресації (також -R
опція), як скрипт на віддаленій машині (наприклад, отриманий з .bashrc
) визначає, які порти було обрано OpenSSH?
Фон
Я використовую OpenSSH (з обох кінців) для підключення до нашого центрального сервера, яким я ділюся з кількома іншими користувачами. Для мого віддаленого сеансу (зараз) я хотів би переслати X, чашки та pulseaudio.
Найбільш тривіальним є пересилання X, використовуючи -X
опцію. Виділена X-адреса зберігається в змінній навколишнього середовища, DISPLAY
і з цього можу визначити відповідний порт TCP, у більшості випадків у будь-якому випадку. Але мені навряд чи потрібно, бо Xlib шанує DISPLAY
.
Мені потрібен аналогічний механізм для чашок і пульс-аудіо. Основи для обох служб існують у вигляді змінних навколишнього середовища 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
як порт прив'язки для віддаленого переадресації ( -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
поки ця інформація не може бути прочитана з журналів. Це неможливо, оскільки ця інформація розкриває набагато більше інформації, ніж розумно зробити доступною для некореневих користувачів.
Я думав над виправленням OpenSSH для підтримки додаткової послідовності евакуації, яка друкує добре представлення внутрішньої структури permitted_opens
, але навіть якщо це те, що я хочу, я все ще не можу сценарій доступу до клієнтських послідовностей виходу з боку сервера.
Має бути кращий спосіб
Наступний підхід видається дуже нестабільним і обмежується одним таким сеансом 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
не розголошуватимуть цю інформацію для некористуючих користувачів. Я отримую тільки -
в PID/Program name
колонці , де я хотів би читати 2339/54
(в даному конкретному випадку). Дуже близько ...
netstat
не покаже вам PID для процесів, якими ви не володієте, або які є простором ядра. Наприклад