Recentemente adicionei o seguinte script ao meu início automático (no KDE):
eval `ssh-agent`
ssh-add
O script deve ser iniciado no login e solicitar minha senha e carregar minha chave secreta. Está quase bem. Os scripts são executados corretamente e o agente é iniciado e as variáveis de ambiente estão todas definidas e minha senha é solicitada. O único problema é que a chave não é carregada depois disso. Mas se eu inserir ssh-add em um terminal, minha senha será solicitada e a chave será armazenada pelo resto da minha sessão X.
O que estou fazendo de errado? Por que a chave não está carregada, embora minha senha seja solicitada?
PS: Estou rodando no Debian jessie.
Responder1
Posso pensar em dois cenários possíveis que podem estar causando isso.
Ambos decorrem do fato de que muitos gerenciadores de desktop lançam seu próprio agente chave ssh. Isso é feito porque o agente precisa ser iniciado antes do gerenciador de desktop para que as variáveis exportadas sejam captadas pelos aplicativos iniciados pelo gerenciador de desktop (seu emulador de terminal).
Seu gerenciador de desktop está lançando seu próprio agente ssh depois que você inicia o seu e acaba substituindo-o.
Não tenho certeza em que ponto ou como você está iniciando seu agente ssh, mas se o gerenciador de desktop iniciar um após o seu, suas variáveis exportadas substituirão aquelas que você criou.
Seu gerenciador de desktop está lançando seu próprio agente ssh antes do seu, e o seu não está sendo persistido.
Se você estiver apenas iniciando uma janela de terminal e fazendo isso
eval $(ssh-agent); ssh-add
, as variáveis exportadas por elassh-agent
não persistirão depois que você fechar a janela do terminal. Depois de iniciar uma nova janela de terminal, você obterá as variáveis definidas pelo agente ssh iniciado pelo gerenciador de desktop.
A maneira como ssh-agent
funciona é iniciar um daemon em segundo plano e depois imprimir diversas variáveis que precisam ser configuradas.
$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-JLbBwVBP4754/agent.4754; export SSH_AUTH_SOCK;
SSH_AGENT_PID=4755; export SSH_AGENT_PID;
echo Agent pid 4755;
Então eval $(ssh-agent)
, quando você está apenas definindo todas essas variáveis.
Agora as variáveis são herdadas apenas pelos filhos, portanto, para que elas persistam no seu gerenciador de desktop, elas devem ser definidas antes do seu gerenciador de desktop iniciar. Isso pode ser difícil de acertar e varia entre as distros. É por isso que muitos gerenciadores de desktop fazem isso sozinhos.
Observe que isso às vezes também é feito durante a inicialização da pilha pam.
Responder2
Como Patrick aponta, é provável que você ssh-agent
concorra com uma instância gerada pelo seu ambiente de desktop. Bem, competir provavelmente não é a palavra certa - as variáveis que permitem que outras aplicações se comuniquem com o agente devem estar em seu ambiente. Como todos os aplicativos em sua sessão de desktop são gerados de alguma forma por alguma parte do ambiente de desktop (vamos supor que seja o gerenciador de sessão), primeiro você precisa colocar as variáveis na lista de ambientes do gerenciador de sessão. Isso pode acontecer de duas maneiras:
o gerenciador de sessão faz isso internamente (dependendo de alguma opção que você definiu em algum lugar). Isso incluiria o agente sendo gerado por um módulo PAM (chamado do gerenciador de login/sessão).
através de um script de usuário como o seu. No entanto, isto não é tão simples como pode parecer. Quando o gerenciador de sessão executa seu script, ele cria um novo processo – o interpretador de script. Em seu ambiente, as variáveis são definidas, mas não podem ser facilmente exportadas de volta para o gerenciador de sessões – seu processo pai. Isso equivale a fazer o mesmo no seu shell - a execução do script não terá nenhum efeito no ambiente do shell atual. Você teria que
source
fazer isso - então os comandos seriam executados pelo shell atual, dando-lhe acesso às variáveis atualizadas/criadas. Isso seria bastante complicado de fazer no gerenciador de sessão (já que não é um interpretador de shell). Portanto, vocêssh-agent
não está realmente competindo. Ele simplesmente fica lá com identidades carregadas a partirssh-add
do seu script e ninguém realmente sabe sobre isso.
Para ter uma ideia do que está acontecendo, verifique a saída de 1
ps fax | grep -E "(ssh|gpg)-[a]gent"
e altere seu script para
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" > ~/ssh-agent.stdout
echo "SSH_AGENT_PID=$SSH_AGENT_PID" >> ~/ssh-agent.stdout
eval `ssh-agent | tee -a ~/ssh-agent.stdout`
Isso imprimirá o conteúdo das variáveis no arquivo ~/ssh-agent.stdout
e, em seguida, adicionará a saída ssh-agent
daquele mesmo local antes de processá-la (e, assim, exportar as variáveis). Compare o conteúdo do arquivo com as variáveis de ambiente SSH_AUTH_SOCK
e, SSH_AGENT_PID
por exemplo, em um terminal shell recém-criado. Na maioria dos casos, você será capaz de dizer qual deles foi iniciado primeiro, já que os PIDs estão crescendo (ciclicamente) monotonamente. A gpg-agent
parte existe porque alguns DEs gpg-agent
também usam a capacidade de fornecer serviços de agente SSH.
Você também pode remover ssh-agent
completamente essa chamada de linha - se o seu script estiver sendo executado depois que o agente SSH gerou seu ambiente de área de trabalho, você receberá a caixa de diálogo de senha (para o agente certo, a propósito), já que as variáveis de ambiente estarão presentes. Caso contrário, significa que seu script está sendo executado antes da instância do agente do DE e, portanto, não tem acesso a nenhum agente.
1 os colchetes são umtruque legalpara removê- grep
lo da lista de processos.