Por que eu tenho que redefinir os env vars no tmux quando reconecto?

37

Eu trabalho principalmente em um mac e ssh / tmux anexado a uma máquina Linux para fazer o meu trabalho. Eu tenho o ssh-agent em execução na máquina Linux. eu tenho

set -g update-environment "SSH_AUTH_SOCK SSH_ASKPASS WINDOWID SSH_CONNECTION XAUTHORITY"

no meu .tmux.conf. No entanto, sempre que me reconecto a esta sessão, tenho que executar

tmux setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK

para que as novas janelas tmux sejam $SSH_AUTH_SOCKdefinidas corretamente. Eu preferiria não ter que fazer isso. Alguma ideia?

Atualizar

Eu acho que não estou explicando isso bem. Aqui está a minha função de shell para abrir um shell em uma máquina remota:

sshh () {
    tmux -u neww -n ${host} "ssh -Xt ${host} $*"
}

Quando o tmux executa esse comando ssh, ele não$SSH_AUTH_SOCK está definido, mesmo que esteja definido no meu ambiente local. Se eu colocar isso no ambiente do tmux com o comando acima, tudo funcionará bem. Minha pergunta é: por que eu tenho que executar o comando setenv?setenv

Atualização 2

Mais Informações:

Quando eu me conecto a uma sessão existente, $SSH_AUTH_SOCKnão está definido no ambiente tmux (ou ambiente global).

% tmux showenv | grep -i auth_sock
-SSH_AUTH_SOCK

Se eu configurá-lo manualmente, as coisas funcionam:

% tmux setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK

Se eu desconectar e reconectá-lo, $SSH_AUTH_SOCKvoltará a não ser definido.

Chris W.
fonte
Isso não é sobre SSH, não é? De quais variáveis ​​de ambiente você possui em um novo shell, qual é o resultado env?
Hauke ​​Laging
Qual shell você está usando no Mac? Bater?
Slm
@HaukeLaging É realmente sobre tmux.
Chris W.
@ slm Estou usando o zsh.
Chris W.
E as janelas existentes? Eles ainda funcionam?
Hauke ​​Laging

Respostas:

35

Como recebi o Bounty, repassarei meu comentário-chave por uma questão de integridade - e para evitar colocar os visitantes com o mesmo problema na trilha errada:

O Tmux removerá variáveis ​​de ambiente

A página de manual do Tmux afirma que o update-environment removerá variáveis "que não existem no ambiente de origem [...] como se -r fosse fornecido ao comando set-environment".

Aparentemente, o que causou o problema. Veja a resposta de Chris abaixo . No entanto, ainda não consigo imaginar como a variável poderia estar ausente no "ambiente de origem" e ainda ser válida na recém-criada janela do tmux ...


Resposta anterior:

Como o encaminhamento SSH funciona

Na máquina remota, dê uma olhada no ambiente do seu shell depois de estabelecer a conexão SSH:

user@remote:~$ env | grep SSH
SSH_CLIENT=68.38.123.35 45926 22
SSH_TTY=/dev/pts/0
SSH_CONNECTION=68.38.123.35 48926 10.1.35.23 22
SSH_AUTH_SOCK=/tmp/ssh-hRNwjA1342/agent.1342

O importante aqui é SSH_AUTH_SOCK, que está atualmente definido para algum arquivo em / tmp. Se você examinar esse arquivo, verá que é um soquete de domínio Unix - e está conectado à instância específica do ssh na qual você se conectou. Importante, isso muda toda vez que você se conecta.

Assim que você efetua logout, esse arquivo de soquete específico desaparece. Agora, se você reconectar sua sessão tmux, verá o problema. Ele tem o ambiente a partir do momento em que o tmux foi lançado originalmente - o que poderia ter acontecido semanas atrás. Esse soquete em particular já está morto há muito tempo.

Solução

Como sabemos que o problema tem a ver com saber onde está o soquete de autenticação SSH atualmente ativo, vamos colocá-lo em um local previsível!

No arquivo .bashrc ou .zshrc na máquina remota, adicione o seguinte:

# Predictable SSH authentication socket location.
SOCK="/tmp/ssh-agent-$USER-screen"
if test $SSH_AUTH_SOCK && [ $SSH_AUTH_SOCK != $SOCK ]
then
    rm -f /tmp/ssh-agent-$USER-screen
    ln -sf $SSH_AUTH_SOCK $SOCK
    export SSH_AUTH_SOCK=$SOCK
fi

Eu acho que você nem precisa colocar um 'comando update-environment' no seu tmux.conf. De acordo com a página do manual, SSH_AUTH_SOCK já está coberto por padrão.

Crédito

Minha resposta é um trecho desta postagem de blog de Mark 'xb95' Smith, que explica o mesmo problema de tela .

djf
fonte
Obrigado pela sua resposta atenciosa. Minha pergunta não é sobre definir meus $SSH_AUTH_SOCKnovos shells, é sobre como definir $SSH_AUTH_SOCKem novas janelas tmux antes que o .bashrc / .zshrc seja originado.
18113 Chris W.
@ChrisW. Eu assumi que o script deveria ser colocado no arquivo rc do seu shell de login na máquina remota. Se você efetuar login, um novo shell será gerado, SSH_AUTH_SOCK será alterado e exportado . Quando você inicia o tmux, ele herdará SSH_AUTH_SOCK do ambiente pai. Como o valor de SSH_AUTH_SOCK está agora fixo, tmux deve continuar trabalhando em logins subseqüentes ... Talvez eu mal o problema
djf
Eu acho que minha confusão é sobre o ambiente em que o ssh é executado pelo tmux no contexto de uma nova janela (por exemplo tmux neww ssh somehost).
18113 Chris W.
Um problema com essa abordagem é que a segunda conexão SSH com a máquina substituirá o valor de SSH_AUTH_SOCK. Essa abordagem funciona apenas enquanto a sessão do tmux está aberta através da conexão SSH mais recente.
Phylae #
12

Eu descobri isso. Resposta curta, eu precisava para remover SSH_AUTH_SOCKa partir update-environment. Como estava nessa lista, o valor estava sendo descartado toda vez que eu recolocava. Obrigado a @djf pela pista. O bit saliente da página do manual tmux (1) na update-environmentseção:

Quaisquer variáveis ​​que não existam no ambiente de origem são configuradas para serem removidas do ambiente da sessão (como se -r tivesse sido fornecido ao comando set-environment).

Chris W.
fonte
11
@ChrisW. você poderia ser um pouco mais claro? Acho que tenho o mesmo problema: às vezes o agente para de funcionar quando eu reconecta as sessões do tmux. Faz algum sentido, pois a conexão SSH é nova e, quando eu ssh, iniciará um novo agente. O que eu tenho que mudar para que funcione? Espero que seja algo que eu possa executar, pois não quero reconfigurar cada máquina em que estou inserindo. - Agora eu tenho um wrapper ssh que inicia o tmux remotamente ou restaura as conexões existentes, provavelmente eu poderia fazer algo antes de restaurar o tmux.
sorin
@ChrisW. respostas curtas às vezes são boas, mas você poderia dar uma resposta longa? Estou lutando para que isso funcione e nada neste post está funcionando para mim.
Redbmk
@sorin @redbmk Desculpe por isso. Esta é a única linha que precisei alterar .tmux.confpara que isso funcionasse: set -g update-environment "SSH_ASKPASS WINDOWID SSH_CONNECTION XAUTHORITY" Você está vendo problemas sshou variáveis ​​de ambiente em geral?
Chris W.
2

Em vez de usar o tmux para lidar com meu ssh-agent, eu tenho o bash para lidar com isso:

### SSH Agent ### {{{
SSH_ENV="$HOME/.ssh/environment"

function start_agent {
    echo "Initialising new SSH agent..."
    /usr/bin/ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}"
    echo succeeded
    chmod 600 "${SSH_ENV}"
    . "${SSH_ENV}" > /dev/null
    /usr/bin/ssh-add;
}

## Source SSH settings, if applicable
if [ -f "${SSH_ENV}" ]; then
    . "${SSH_ENV}" > /dev/null
    ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
        start_agent;
    }
  else
    start_agent;
fi
### End SSH Agent ### }}}

Eu tenho isso no meu ~ / bashrc , e funciona muito bem.

recatado
fonte
$SSH_AUTH_SOCKestá definido corretamente em minhas conchas, mas quando eu fizer algo assim tmux neww ssh somehost, minha senha será solicitada para desbloquear minha chave privada, a menos que eu corra tmux setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK.
13133 Chris W.
1

Respondi a uma pergunta semelhante no StackOverflow https://stackoverflow.com/a/49395839/241025 . Como essa página apareceu primeiro nas minhas pesquisas no Google, eu queria postar uma versão resumida dela aqui.

Para que cada sessão do tmux tenha um conjunto de variáveis ​​de ambiente customizadas, você deve adicionar os valores às variáveis ​​de ambiente por sessão do tmux. Aqui está um exemplo de como fazê-lo.

tmux new-session -s one
tmux setenv FOO foo-one
export FOO='foo-one'

A última etapa da exportação explícita do FOO é necessária para que o painel atual escolha a variável de ambiente. Quaisquer painéis ou janelas subsequentes criados para esta sessão do tmux herdarão o FOO, mas não serão exibidos em outras sessões.

RobotNerd
fonte
0

A explicação de djf traz outra solução possível para minha mente:

Antes tmux/ screenestá em execução:

  1. Entrar.
  2. Inicie uma instância de ssh-agent.
  3. Inicie tmux/ screencom as variáveis ​​de ambiente para isso ssh-agent.

Isso não pôde usar o encaminhamento SSH para o cliente, mas isso não foi solicitado.

Hauke ​​Laging
fonte
11
ssh-agentnão liga ao TTY, por que deveria ser eliminado no logout (?) - por que usar nohup?
Poige 19/05
@poige Correct.
Hauke ​​Laging