Feche o túnel ssh sem root e sem matar todas as outras conexões ssh

Feche o túnel ssh sem root e sem matar todas as outras conexões ssh

Eu tenho um túnel ssh escutando em uma porta local, digamos 8888, aberta em uma máquina remota com ssh -R 8888:localhost:80 myuser@myhost. Preciso escrever um script para "myuser" em "myhost" que feche este túnel.

O script será executado por “myuser” em “myhost”. Não será executado pelo root nem poderá fazer sudo.

Uma abordagem seria encontrar o PID do processo escutando em 8888 usando lsof ou netstat e então encerrar o processo. No entanto, tanto o lsof quanto o netstat se recusam a me fornecer o PID sem usar o sudo. Com o netstat, recebo -em vez de "PID/Nome do programa" sem sudo.

Existe uma maneira de descobrir o PID do processo que escuta em uma determinada porta sem os privilégios de root? O processo de escuta nesta porta está sendo executado pelo mesmo usuário que nós. Ou existe alguma outra maneira de fechar o túnel ssh de fora dele?

Observe que usar a sequência de escape ssh para redefinir a conexão não é uma solução, pois estamosnãono túnel. Nosso script precisa ser executado separadamente do túnel no mesmo host pelo mesmo usuário.

Observe também que apenas executar killall sshdnão é uma solução, pois eliminará todas as outras conexões ssh, não apenas esta.

Esta pergunta não é uma duplicata de muitas perguntas semelhantes, porque todas as respostas aceitas que encontrei exigem privilégios de root ou apenas eliminam todas as conexões ssh.

O host "myhost" está executando o Ubuntu 12.04.5.


Editar: Resumo da discussão conforme solicitado por @Jakuje:

  • @Patrick sugeriu uma abordagem para usar setuidou modificar /etc/sudoerspara permitir que o usuário execute o script com privilégios de root sem ter o sudo completo. Embora, setuidprecisaríamos escrever um binário em vez do script. No entanto, permitir que o usuário execute o script com privilégios de root pode ser um risco potencial à segurança. E ainda assim esta solução não cobre o caso em que o usuário não tem acesso root, então ele não pode modificar arquivos /etc/sudoers. Se @Patrick escrever isso como uma resposta, com certeza vou votar a favor, mas não vou marcá-lo como aceito ainda.

  • @EricRenouf descobriu que o sshd mostra o soquete para o usuário, para que o usuário não possa usar /proc/*/fdpara encontrar o processo que possui o soquete. Provavelmente é por isso que nem lsof nem netstat mostram isso.

Mais ideias:

Como @EricRenouf descobriu, provavelmente não há como obter o sshd PID pelo número da porta do soquete aberto nem pelo inode. Mas estou curioso para saber se não há outro truque para encontrar esse PID sshd ou como dizer para ele fechar a conexão. Talvez de alguma forma diretamente com o sshd.

Por exemplo, se eu habilitasse o modo de depuração sshd, sshd -dele registraria qual processo sshd abriu um túnel para qual porta /var/log/auth.logpode ser lida pelo usuário. Assim, o script poderia analisar o log e encontrar o PID lá. Mas executar um sshd em modo de depuração não é uma boa ideia. Na verdade existe umpatch simples para sshdpara registrar túneis abertos mesmo sem modo de depuração. Mas também não tenho certeza se executar um sshd corrigido seria uma boa ideia.

Existe algum outro truque?

Responder1

Comece configurando uma chave SSH personalizada para conectar-se ao “myhost”. Em seguida, edite seu arquivo .ssh/authorized_keys em "myhost" para que o PID pai do shell seja gravado em um arquivo:

command="echo $PPID > tunnel.pid; bash" ssh-rsa AAA...

Você pode querer ajustar algumas outras configurações de segurança e/ou escrever um script personalizado para apenas escrever o PID e travar. O princípio é o mesmo de qualquer maneira.

Depois de ter o PID do processo que mantém a sessão SSH aberta, é só uma questão de script ...

kill `cat tunnel.pid`

...para encerrar o processo, fechando assim a sessão SSH.

Observe que você pode usar o -isinalizador do sshcomando para especificar uma chave privada a ser usada para a conexão.

Editar: matar o processo shell não fechará o túnel se houver conexões ativas, então matamos o processo SSH pai.

Editar: embora minha primeira inclinação com qualquer conexão SSH automatizada seja usar chaves SSH, o mesmo processo pode ser emulado com:

ssh -R 8888:localhost:80 myuser@myhost 'echo $PPID > tunnel.pid; for ((;;)); do sleep 1; done'

Você também pode substituir um script que verifique alguns outros critérios para decidir quando encerrar-se. Essa é provavelmente uma maneira mais limpa de lidar com isso.

informação relacionada