SSH sem fornecer .bashrc

Sep 14 2020

Eu estava testando meu .bashrcarquivo enquanto fazia login remotamente em um servidor por SSH. Eu inadvertidamente deixei um exitlá que fez com que todos os logins subsequentes fossem desconectados imediatamente. Eu estava efetivamente bloqueado. Consegui recuperar o acesso com a intervenção de alguém com privilégios de root, mas seria possível sem a ajuda de outra pessoa?

Tentei fazer coisas como executar ssh <server> 'bash --norc --noprofile'e ssh <server> 'mv .bashrc bashrc-backup', e até tentar sobrescrever à força com scp empty-file <server>:.bashrc. No entanto, todas essas opções parecem depender primeiro do código-fonte quebrado .bashrcantes de executar o comando, portanto, nenhuma delas funcionou.

Pode muito bem ser o caso de não haver saída para esse tipo de situação. Mas isso é intencional? Existe uma razão pela qual é tão fácil bloquear um sistema, por exemplo, apenas executando ssh <server> 'echo exit > .bashrc'? Existem maneiras de mitigar esse tipo de erro?

Respostas

2 Kenster Sep 14 2020 at 08:43

Conforme discutido na outra resposta, quando um cliente SSH se conecta ao servidor OpenSSH, o servidor OpenSSH geralmente inicia uma sessão de shell em nome do cliente, usando o shell de login do usuário:

  1. Se o cliente solicitar uma sessão interativa, o servidor iniciará o shell de login do usuário.
  2. Se o cliente solicitar a execução de um comando, o servidor usará o shell de login do usuário para executar o comando como um comando shell.
  3. Utilitários como scp, rsynce gitque usam ssh para transporte solicitarão que um comando seja executado no sistema remoto, portanto, eles se enquadram no # 2.

Se houver algo nos arquivos de inicialização do shell do usuário remoto que faça com que o shell seja encerrado, você terá problemas para entrar.

SFTP, entretanto, é um caso especial. O servidor OpenSSH pode ser configurado para suportar SFTP sem iniciar um comando externo. Se for esse o caso, você poderá usar o sftp para se conectar ao servidor e excluir, renomear ou alterar o .bashrcarquivo que está causando o problema.

Depende de como o servidor está configurado para suportar sftp. Ele pode atender às sessões sftp iniciando um programa externo (nomeado sftp-server). Nesse caso, você teria o mesmo problema de entrada que tem com programas como o scp. Ou o servidor pode atender à sessão sftp por algo conhecido como "internal-sftp" , que não requer a chamada de um shell. Depende apenas de como o servidor SSH específico está configurado.

bk2204 Sep 14 2020 at 03:07

A razão disso acontecer é porque sshd, o componente do lado do servidor, invoca processos usando seu shell. Se estiver gerando um shell interativo, ele será gerado como um shell de login; caso contrário, ele usa o -cargumento para gerar um shell não interativo para executar o comando que você especificar.

Todas as operações que você especificou (comandos especificados e scp) são operações não interativas, portanto, normalmente o bash não carrega .bashrc, mas o bash tem uma caixa especial para quando invocado por sshdpara que o invoque de qualquer maneira. Se você estivesse usando zsh, então .zshenv(que é invocado para todos os shells) seria carregado, mas .zshrc(que é apenas para shells interativos) não seria, a menos que você estivesse carregando especificamente uma sessão de shell.

Nesse caso, se você estiver usando o bash, está sem sorte. Não há como invocar um comando SSH no lado do servidor sem usar o shell; isso é verdadeiro até mesmo para scp e sftp. Na maioria das vezes, você deseja usar o shell porque ele configura coisas como PATHpara vários programas e permite uma quantidade razoável de scripts de comandos complexos, portanto, o OpenSSH sempre o usa.

Isso também tem alguns benefícios de segurança: se você tentar fazer login em uma conta do sistema que de alguma forma tem uma senha válida, mas uma shell de /usr/sbin/nologinou /bin/false, você não poderá fazer nada, que é provavelmente a intenção do administrador do sistema.

Existem maneiras de atenuar isso. Muitas pessoas mantêm um repositório Git de seus dotfiles e os desenvolvem em um sistema, depois os implantam em outros. Por exemplo, sempre faço desenvolvimento de dotfile no meu laptop. Presumivelmente, você notaria esse problema um pouco mais cedo se, a qualquer momento que abrisse uma nova janela de terminal, ela saísse imediatamente e você pudesse ter acesso root para corrigi-lo sozinho.

Se você precisar testar uma configuração que pode bloqueá-lo, como uma configuração de shell ou uma sudoersmudança, você pode deixar um shell (normal ou root, respectivamente) aberto e, em seguida, fazer alguns testes, então se você quebrar algo, você ainda tem um maneira de desfazê-lo.