Pytanie (TL; DR)
Jak dynamicznie przypisywać porty do zdalnego przekazywania (inaczej -R
opcja), w jaki sposób skrypt na zdalnej maszynie (na przykład pochodzącej z .bashrc
) może określić, które porty zostały wybrane przez OpenSSH?
tło
Używam OpenSSH (na obu końcach) do łączenia się z naszym centralnym serwerem, który udostępniam wielu innym użytkownikom. Do mojej zdalnej sesji (na razie) chciałbym przesłać X, puchary i pulseaudio.
Najbardziej trywialnym jest przekazywanie X za pomocą -X
opcji. Przydzielony adres X jest przechowywany w zmiennej środowiskowej DISPLAY
i na tej podstawie mogę określić odpowiedni port TCP, w większości przypadków i tak. Ale prawie nigdy nie muszę, bo Xlib honoruje DISPLAY
.
Potrzebuję podobnego mechanizmu do filiżanek i pulseaudio. Istnieją podstawy dla obu usług, w postaci odpowiednio zmiennych środowiskowych CUPS_SERVER
i PULSE_SERVER
. Oto przykłady użycia:
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
Problem jest ustawiony CUPS_SERVER
i PULSE_SERVER
poprawnie.
Często korzystamy z przekierowania portów, dlatego potrzebuję dynamicznych przydziałów portów. Statyczne przydziały portów nie są opcją.
OpenSSH ma mechanizm dynamicznej alokacji portów na zdalnym serwerze, określając 0
jako bind-port do zdalnego przekazywania ( -R
opcja). Korzystając z następującego polecenia, OpenSSH dynamicznie przydziela porty dla pucharów i przekazywania impulsów.
ssh -X -R0:localhost:631 -R0:localhost:4713 datserver
Gdy użyję tego polecenia, ssh
wydrukuję następujące informacje 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
Potrzebuję informacji! Ostatecznie chcę wygenerować:
export CUPS_SERVER=localhost:41273
export PULSE_SERVER=localhost:55710
Jednak komunikaty „Przydzielony port ...” są tworzone na moim komputerze lokalnym i wysyłane do STDERR
, do którego nie mam dostępu na komputerze zdalnym. Co dziwne, OpenSSH wydaje się nie mieć środków do pobierania informacji o przekierowaniu portów.
Jak pobrać te informacje, aby umieścić je w skrypcie powłoki, aby odpowiednio ustawić CUPS_SERVER
i PULSE_SERVER
na zdalnym hoście?
Dead Ends
Jedyną łatwą rzeczą, jaką mogłem znaleźć, było zwiększenie szczegółowości, sshd
dopóki informacje te nie zostaną odczytane z dzienników. Nie jest to wykonalne, ponieważ informacje te ujawniają znacznie więcej informacji niż jest to rozsądne, aby udostępnić je użytkownikom innym niż root.
Zastanawiałem się nad załataniem OpenSSH do obsługi dodatkowej sekwencji ucieczki, która wypisuje ładną reprezentację wewnętrznej struktury permitted_opens
, ale nawet jeśli tego właśnie chcę, nadal nie mogę uzyskać skryptu uzyskującego dostęp do sekwencji ucieczki klienta po stronie serwera.
Musi być lepszy sposób
Poniższe podejście wydaje się bardzo niestabilne i jest ograniczone do jednej takiej sesji SSH na użytkownika. Potrzebuję jednak co najmniej dwóch równoczesnych sesji i jeszcze więcej użytkowników. Ale próbowałem ...
Gdy gwiazdy są odpowiednio wyrównane, po poświęceniu jednego lub dwóch kurczaków, mogę nadużywać faktu, że sshd
nie został uruchomiony jako mój użytkownik, ale po upuszczeniu upuszcza uprawnienia, aby to zrobić:
uzyskać listę numerów portów dla wszystkich gniazd nasłuchujących należących do mojego użytkownika
netstat -tlpen | grep ${UID} | sed -e 's/^.*:\([0-9]\+\) .*$/\1/'
uzyskać listę numerów portów dla wszystkich gniazd nasłuchujących należących do procesów uruchomionych przez mojego użytkownika
lsof -u ${UID} 2>/dev/null | grep LISTEN | sed -e 's/.*:\([0-9]\+\) (LISTEN).*$/\1/'
Wszystkie porty, które są w pierwszym secie, ale nie w drugim zestawie mają wysoką Likelyhood być moim porty spedycji, a nawet odjęcie wydajności zestawów
41273
,55710
a6010
; kubki, puls i X, odpowiednio.6010
jest identyfikowany jako port X za pomocąDISPLAY
.41273
jest portem kubków, ponieważlpstat -h localhost:41273 -a
zwraca0
.55710
jest portem impulsowym, ponieważpactl -s localhost:55710 stat
zwraca0
. (Drukuje nawet nazwę hosta mojego klienta!)
(Aby wykonać odejmowanie zestawu I sort -u
i zapisać dane wyjściowe z powyższych wierszy poleceń i użyć comm
do odejmowania.)
Pulseaudio pozwala mi zidentyfikować klienta i, dla wszystkich celów i celów, może to służyć jako kotwica do oddzielnych sesji SSH, które wymagają oddzielenia. Jednak nie znaleźli sposób, aby związać 41273
, 55710
i 6010
do tego samego sshd
procesu. netstat
nie ujawni tych informacji użytkownikom innym niż root. Dostaję tylko -
w PID/Program name
kolumnie, w której chciałbym przeczytać 2339/54
(w tym konkretnym przypadku). Tak blisko ...
netstat
nie pokaże PID dla procesów, których nie jesteś właścicielem lub które są przestrzenią jądra. Na przykład