Pergunta (TL; DR)
Ao atribuir portas dinamicamente para encaminhamento remoto ( -R
opção aka ), como um script na máquina remota (por exemplo, proveniente de .bashrc
) determina quais portas foram escolhidas pelo OpenSSH?
fundo
Eu uso o OpenSSH (nas duas extremidades) para conectar-se ao nosso servidor central, que eu compartilho com vários outros usuários. Para a minha sessão remota (por enquanto), gostaria de encaminhar X, cups e pulseaudio.
O mais trivial é encaminhar o X, usando a -X
opção O endereço X alocado é armazenado na variável ambiental DISPLAY
e, a partir disso, posso determinar a porta TCP correspondente, na maioria dos casos. Mas quase nunca preciso, porque Xlib honra DISPLAY
.
Eu preciso de um mecanismo semelhante para copos e pulseaudio. O básico para ambos os serviços existe, na forma de variáveis ambientais CUPS_SERVER
e PULSE_SERVER
, respectivamente. Aqui estão alguns exemplos de uso:
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
O problema está definido CUPS_SERVER
e PULSE_SERVER
corretamente.
Usamos muito o encaminhamento de portas e, portanto, preciso de alocações dinâmicas de portas. Alocações de porta estática não são uma opção.
O OpenSSH possui um mecanismo para alocação dinâmica de porta no servidor remoto, especificando 0
como porta de ligação para encaminhamento remoto (a -R
opção). Usando o comando a seguir, o OpenSSH alocará dinamicamente portas para copas e encaminhamento de pulso.
ssh -X -R0:localhost:631 -R0:localhost:4713 datserver
Quando eu uso esse comando, ssh
imprimo o seguinte para 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
Existe a informação que eu quero! Por fim, quero gerar:
export CUPS_SERVER=localhost:41273
export PULSE_SERVER=localhost:55710
No entanto, as mensagens "Porta alocada ..." são criadas na minha máquina local e enviadas para as STDERR
quais não consigo acessar na máquina remota. Curiosamente, o OpenSSH parece não ter meios de recuperar informações sobre encaminhamentos de portas.
Como obtenho essas informações para colocá-las em um script shell para definir adequadamente CUPS_SERVER
e PULSE_SERVER
no host remoto?
Becos-sem-saída
A única coisa fácil que pude encontrar foi aumentar a verbosidade sshd
até que essas informações possam ser lidas nos logs. Isso não é viável, pois essas informações divulgam muito mais informações do que é sensato tornar acessível por usuários não-root.
Eu estava pensando em aplicar um patch ao OpenSSH para oferecer suporte a uma sequência de escape adicional que imprime uma boa representação da estrutura interna permitted_opens
, mas mesmo se é isso que eu quero, ainda não consigo script acessando as seqüências de escape do cliente pelo lado do servidor.
Deve haver uma maneira melhor
A abordagem a seguir parece muito instável e está limitada a uma sessão SSH por usuário. No entanto, preciso de pelo menos duas sessões simultâneas e outros usuários ainda mais. Mas eu tentei ...
Quando as estrelas estão alinhadas corretamente, depois de sacrificar uma galinha ou duas, posso abusar do fato de sshd
não ter sido iniciado como meu usuário, mas eliminado privilégios após o login bem-sucedido, para fazer isso:
obter uma lista de números de porta para todos os soquetes de escuta que pertencem ao meu usuário
netstat -tlpen | grep ${UID} | sed -e 's/^.*:\([0-9]\+\) .*$/\1/'
obter uma lista de números de porta para todos os soquetes de escuta que pertencem aos processos que meu usuário iniciou
lsof -u ${UID} 2>/dev/null | grep LISTEN | sed -e 's/.*:\([0-9]\+\) (LISTEN).*$/\1/'
Todas as portas que estão no primeiro set, mas não no segundo set têm uma alta probabilidade de ser meus portos de encaminhamento e, na verdade subtrair os rendimentos conjuntos
41273
,55710
e6010
; copos, pulso e X, respectivamente.6010
é identificado como a porta X usandoDISPLAY
.41273
é a porta de copos, porquelpstat -h localhost:41273 -a
retorna0
.55710
é a porta de pulso, porquepactl -s localhost:55710 stat
retorna0
. (Ele até imprime o nome do host do meu cliente!)
(Para fazer a subtração definida I sort -u
e armazenar a saída das linhas de comando acima e use comm
para fazer a subtração.)
O Pulseaudio permite identificar o cliente e, para todos os efeitos, pode servir de âncora para separar as sessões SSH que precisam ser separadas. No entanto, eu não encontrei uma maneira de amarrar 41273
, 55710
e 6010
ao mesmo sshd
processo. netstat
não divulgará essas informações para usuários não raiz. Eu só recebo um -
na PID/Program name
coluna em que gostaria de ler 2339/54
(neste exemplo em particular). Tão perto ...
netstat
não mostrará o PID para processos que você não possui ou que são espaço no kernel. Por exemplo