Pytanie (TL; DR)
Jak dynamicznie przypisywać porty do zdalnego przekazywania (inaczej -Ropcja), 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ą -Xopcji. Przydzielony adres X jest przechowywany w zmiennej środowiskowej DISPLAYi 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_SERVERi 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_SERVERi PULSE_SERVERpoprawnie.
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 0jako bind-port do zdalnego przekazywania ( -Ropcja). 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, sshwydrukuję 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_SERVERi PULSE_SERVERna zdalnym hoście?
Dead Ends
Jedyną łatwą rzeczą, jaką mogłem znaleźć, było zwiększenie szczegółowości, sshddopó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 sshdnie 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,55710a6010; kubki, puls i X, odpowiednio.6010jest identyfikowany jako port X za pomocąDISPLAY.41273jest portem kubków, ponieważlpstat -h localhost:41273 -azwraca0.55710jest portem impulsowym, ponieważpactl -s localhost:55710 statzwraca0. (Drukuje nawet nazwę hosta mojego klienta!)
(Aby wykonać odejmowanie zestawu I sort -ui zapisać dane wyjściowe z powyższych wierszy poleceń i użyć commdo 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, 55710i 6010do tego samego sshdprocesu. netstatnie ujawni tych informacji użytkownikom innym niż root. Dostaję tylko -w PID/Program namekolumnie, w której chciałbym przeczytać 2339/54(w tym konkretnym przypadku). Tak blisko ...
netstatnie pokaże PID dla procesów, których nie jesteś właścicielem lub które są przestrzenią jądra. Na przykład