Domanda (TL; DR)
Quando si assegnano le porte in modo dinamico per l'inoltro remoto ( -R
opzione aka ), come può uno script sul computer remoto (ad esempio proveniente da .bashrc
) determinare quali porte sono state scelte da OpenSSH?
sfondo
Uso OpenSSH (su entrambe le estremità) per connettermi al nostro server centrale, che condivido con più altri utenti. Per la mia sessione remota (per ora) vorrei inoltrare X, tazze e pulseaudio.
Il più banale è l'inoltro di X, usando l' -X
opzione. L'indirizzo X allocato viene memorizzato nella variabile ambientale DISPLAY
e da questo posso determinare la porta TCP corrispondente, nella maggior parte dei casi comunque. Ma non ne ho quasi mai bisogno, perché Xlib onora DISPLAY
.
Ho bisogno di un meccanismo simile per tazze e pulseaudio. Esistono le basi per entrambi i servizi, rispettivamente sotto forma di variabili ambientali CUPS_SERVER
e PULSE_SERVER
. Ecco alcuni esempi di utilizzo:
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
Il problema si sta configurando CUPS_SERVER
e PULSE_SERVER
correttamente.
Usiamo molto il port forwarding e quindi ho bisogno di allocazioni di porte dinamiche. Le allocazioni di porte statiche non sono un'opzione.
OpenSSH ha un meccanismo per l'allocazione dinamica delle porte sul server remoto, specificando 0
come bind-port per l'inoltro remoto (l' -R
opzione). Usando il comando seguente, OpenSSH alloca dinamicamente le porte per le tazze e l'inoltro degli impulsi.
ssh -X -R0:localhost:631 -R0:localhost:4713 datserver
Quando uso quel comando, ssh
stampa quanto segue su 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
Ci sono le informazioni che voglio! Alla fine voglio generare:
export CUPS_SERVER=localhost:41273
export PULSE_SERVER=localhost:55710
Tuttavia, i messaggi "Porta assegnata ..." vengono creati sul mio computer locale e inviati a STDERR
cui non riesco ad accedere sul computer remoto. Stranamente OpenSSH non sembra avere i mezzi per recuperare le informazioni sul port forwarding.
Come posso recuperare queste informazioni per inserirle in uno script shell per impostarle adeguatamente CUPS_SERVER
e PULSE_SERVER
sull'host remoto?
Vicoli ciechi
L'unica cosa facile che ho trovato è stata la prolissità crescente sshd
fino a quando le informazioni non possono essere lette dai registri. Ciò non è fattibile in quanto tali informazioni rivelano molte più informazioni di quante sia sensato rendere accessibili agli utenti non root.
Stavo pensando di patchare OpenSSH per supportare un'ulteriore sequenza di escape che stampa una bella rappresentazione della struttura interna permitted_opens
, ma anche se è quello che voglio, non riesco ancora a accedere alle sequenze di escape del client dal lato server.
Deve esserci un modo migliore
Il seguente approccio sembra molto instabile ed è limitato a una di queste sessioni SSH per utente. Tuttavia, ho bisogno di almeno due sessioni simili e altri utenti ancora di più. Ma ho provato ...
Quando le stelle sono allineate correttamente, dopo aver sacrificato un pollo o due, posso abusare del fatto che sshd
non è iniziato come il mio utente, ma abbandona i privilegi dopo il login riuscito, per fare questo:
ottenere un elenco di numeri di porta per tutte le prese di ascolto che appartengono al mio utente
netstat -tlpen | grep ${UID} | sed -e 's/^.*:\([0-9]\+\) .*$/\1/'
ottenere un elenco di numeri di porta per tutti i socket di ascolto che appartengono ai processi avviati dal mio utente
lsof -u ${UID} 2>/dev/null | grep LISTEN | sed -e 's/.*:\([0-9]\+\) (LISTEN).*$/\1/'
Tutte le porte che si trovano nel primo set, ma non nel secondo set hanno un'alta probabilità di essere le mie porte di inoltro e sottrarre i rendimenti degli insiemi
41273
,55710
e6010
; tazze, impulso e X, rispettivamente.6010
viene identificato come la porta X utilizzandoDISPLAY
.41273
è la porta della coppa, perchélpstat -h localhost:41273 -a
ritorna0
.55710
è la porta del polso, perchépactl -s localhost:55710 stat
ritorna0
. (Stampa persino il nome host del mio client!)
(Per eseguire la sottostrazione impostata I sort -u
e memorizzare l'output dalle righe di comando sopra e utilizzare comm
per eseguire la sottostrazione.)
Pulseaudio mi consente di identificare il client e, a tutti gli effetti, questo può servire da ancoraggio per separare le sessioni SSH che devono essere separate. Tuttavia, non ho trovato un modo per legare 41273
, 55710
e 6010
allo stesso sshd
processo. netstat
non divulgherà tali informazioni a utenti non root. Ottengo solo un -
nella PID/Program name
colonna in cui vorrei leggere 2339/54
(in questo caso particolare). Così vicino ...
netstat
non ti mostrerà il PID per i processi che non possiedi o che sono spazio del kernel. Ad esempio