Como você faz com que a tela se conecte automaticamente ao agente ssh atual ao se reconectar a uma tela existente?

47

Se você iniciar uma sessão de tela enquanto o ssh-agent estiver em execução (do encaminhamento de agente ssh -A), o acesso ao ssh-agent funcionará bem. No entanto, se você desanexar dessa sessão, efetuar logout, efetuar login novamente (com o encaminhamento de agente ssh) e anexar novamente à sua sessão de tela, o acesso do agente ssh não funcionará.

Como isso pode ser corrigido?

    
por Der Hochstapler 23.03.2009 / 19:56

11 respostas

41

1) Em seu script SSH rc (~ / .ssh / rc) você irá configurar um link simbólico de um local canônico para o SSH_AUTH_SOCK "atual". Aqui está como eu faço isso no bash (conteúdo de ~ / .ssh / rc):

#!/bin/bash
if test "$SSH_AUTH_SOCK" ; then
    ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
fi

(e certifique-se de chmod 755 ~ / .ssh / rc). O "teste" é apenas para evitar que um erro seja exibido se você não estiver executando o ssh-agent (ou seja, você ssh sem -A). A segunda metade desse comando configura um symlink em um local canônico que se atualiza para o SSH_AUTH_SOCK "real" no momento do login. Isto é independente de usar um shell em ssh ou chamar diretamente um comando, funciona também com "ssh -t screen -RRD".

Nota: a existência de ~ / .ssh / rc altera o comportamento do sshd. Notavelmente, não irá chamar xauth. Veja man sshd para mais informações e como corrigir isso.

Além disso, você não deve usar "-v" com ln assim que interromper o rsync-over-ssh com os seguintes diagnósticos:

$ rsync -n addr.maps.dev.yandex.net: .
protocol version mismatch -- is your shell clean?
(see the rsync man page for an explanation)
rsync error: protocol incompatibility (code 2) at compat.c(173) [Receiver=3.0.7]

2) No seu .screenrc, você só precisa substituir o SSH_AUTH_SOCK para o local canônico:

setenv SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock

Note que você usa setenv não importa qual shell você usa; Eu acho que setenv é a sintaxe da tela, não o shell.

Solução originalmente adaptada de este post , que não funciona, mas tem o direito idéia.

    
por 23.03.2009 / 19:56
22

Eu acho que isso funciona como uma simplificação da resposta do @ sandip-bhattacharya. Coloque isso no seu arquivo ~/.bashrc e execute o comando de exportação em qualquer sessão da tela em execução no momento.

if [ -S "$SSH_AUTH_SOCK" ] && [ ! -h "$SSH_AUTH_SOCK" ]; then
    ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock

Se " $SSH_AUTH_SOCK for um soquete ( -S ) e não um link simbólico ( ! -h ), crie um novo link simbólico no caminho conhecido. Em todos os casos, redefina SSH_AUTH_SOCK para apontar para o caminho conhecido.

O ! -h evita criar uma referência circular se você executar isso várias vezes.

Além disso, se você usa byobu , ele faz isso automaticamente, sem precisar editar arquivos de configuração.

O único bug que encontrei neste item ( byobu também) é que, se você abrir uma segunda ssh -A ou ForwardAgent , sobrescreverá o primeiro soquete, e se você fechar a segunda conexão antes do primeiro, você perderá sua única boa tomada.

    
por 18.06.2012 / 16:28
4

"ssh -t some.machine screen -R" não executará bash e, portanto, não executará o script .bash_profile onde o symlink é criado.

Você poderia tentar: ssh -t some.machine bash -c "screen -R"

(assumindo que você está usando o bash como seu shell, é claro)

Edit: Essa "resposta" é na verdade um comentário sobre a primeira resposta dada acima :)

    
por 14.05.2009 / 16:49
3

Eu acho que você precisa de autossh. Eu tenho usado isso há anos e, combinado com a tela, torna todas as minhas sessões de terminal totalmente portáteis e transparentes. Eu simplesmente fecho o lappy, mudo para o novo local, abrai o lappy e todas as minhas telas e telas aninhadas se conectam automaticamente. Eu nem penso mais nisso.

link

é o básico ... Eu fiz um script lil para automatizar o processo no meu .screenrc para um determinado host. (também faz meu encaminhamento ssh, então em todos esses lugares diferentes eu posso tunelar minha conexão através de meus servidores)

na autossh distro deve haver um programa chamado rscreen (e .. existe!)

#!/bin/sh                                                                       
#
# sample script to use autossh to open up a remote screen
# session, or reconnect to an existing one. 
#
# $Id: rscreen,v 1.4 2002/05/07 17:54:13 harding Exp $
#
if [ "X$1" = "X" ]; then
    echo "usage: 'basename $0' <host>"
    exit 1
fi

if [ "X$SSH_AUTH_SOCK" = "X" ]; then
    eval 'ssh-agent -s'
    ssh-add $HOME/.ssh/id_rsa
fi

#AUTOSSH_POLL=600
#AUTOSSH_PORT=20000
#AUTOSSH_GATETIME=30
#AUTOSSH_LOGFILE=$HOST.log
#AUTOSSH_DEBUG=yes 
#AUTOSSH_PATH=/usr/local/bin/ssh
export AUTOSSH_POLL AUTOSSH_LOGFILE AUTOSSH_DEBUG AUTOSSH_PATH AUTOSSH_GATETIME 

autossh -M 20004 -t $1 "screen -e^Zz -D -R"

Isso deve ajudar com problemas de ssh / screen

Finalmente, para manter meu agente ssh em execução, eu uso keychain, já que sou uma espécie de cabeça de shell ... Eu acho que o OSX tem algo disponível para manter seu agente por perto ...

    
por 16.06.2009 / 15:29
2

Aqui está o método que eu uso:

SOCK=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "
function ssh-screen-auth() {
  SOCK=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "
SOCK=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "
function ssh-screen-auth() {
  SOCK=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "%pre%" "\n" | grep SSH_AUTH_SOCK)
  eval $SOCK
  export SSH_AUTH_SOCK
  DISP=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "%pre%" "\n" | grep DISPLAY)
  eval $DISP
  export DISPLAY
}
" "\n" | grep SSH_AUTH_SOCK) ; eval $SOCK ; export SSH_AUTH_SOCK DISP=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "%pre%" "\n" | grep DISPLAY) ; eval $DISP ; export DISP
" "\n" | grep SSH_AUTH_SOCK) eval $SOCK export SSH_AUTH_SOCK DISP=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "%pre%" "\n" | grep DISPLAY) eval $DISP export DISPLAY }
" "\n" | grep SSH_AUTH_SOCK) ; eval $SOCK ; export SSH_AUTH_SOCK DISP=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "%pre%" "\n" | grep DISPLAY) ; eval $DISP ; export DISP

Eu geralmente configuro um alias ou uma função de shell com esses comandos:

%pre%

Você pode ter que adaptar a expressão regular ' tela - (r | DR) ' aos comandos exatos que você usa para recolocar sua tela.

  • A primeira linha lê a variável de ambiente SSH_AUTH_SOCK no espaço de processo do comando " tela -r " que você acabou de digitar e atualiza o valor no seu shell atual. / li>
  • A segunda linha é necessária se você usar " ssh -X " para encaminhar conexões X11: ela atualiza a variável DISPLAY da mesma maneira.

Uma ressalva com meu método: as coisas podem dar errado se houver outro comando " tela " em execução no computador.

    
por 14.04.2010 / 12:14
1

Geralmente, mantenho sessões de longo prazo (6 meses ou mais) sendo executadas no meu local de trabalho em servidores diferentes. Tão repetidamente reconectando e tendo um agente de encaminhamento ssh viável tem sido problemático. Isso é o que eu configurei nos meus sistemas:

if [ -z "${STY}" -a -t 0 -a X${USER} = Xmyusername ]; then
    reattach () {
        if [ -n "${SSH_AUTH_SOCK}" ]; then
            ln -snf "${SSH_AUTH_SOCK}" "${HOME}/.ssh/agent-screen"
            SSH_AUTH_SOCK="${HOME}/.ssh/agent-screen" export SSH_AUTH_SOCK
        fi
        exec screen -A -D -RR ${1:+"$@"} ;
    }

    screen -wipe
    echo 'starting screen... (type Cntl-C to abort)'
    sleep 5 && reattach
fi

Se eu fizer o login no servidor remoto sem iniciar / reconectar a tela, haverá dois "soquetes", um em uso por screen e outro pelo novo shell. Não deve haver duas sessões de "inicialização", mas uma segunda sessão ainda pode ser iniciada usando reattach -S new ; nessa situação, o agente seria compartilhado com o valor ~/.ssh/agent-screen . Para obter um agente de encaminhamento de trabalho de volta, eu desanexava e fazia o login novamente. O X${USER} = Xmyusername garante que o código não será chamado por sudo no mesmo servidor.

    
por 19.12.2011 / 21:20
1

Estou usando uma variação do que @apinstein está usando para meu .bashrc .

case "$TERM" in
    screen)
           export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock
        ;;
         *)
           if [[ -n "$SSH_AUTH_SOCK" ]]; then
               ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
           fi
        ;;
esac

Isso funciona para todos os aplicativos em execução na minha sessão de tela. Isso funcionaria para todos os novos shells na sua sessão de tela. Para shells existentes, você precisa executar export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock no shell do host para fazê-lo funcionar.

P.S. Desculpe por adicionar isso como uma resposta independente, considerando que ele foi construído com base na resposta de @ apinstein. Teve que fazer isso como comentários em stackoverflow não suportam blocos de código.

    
por 29.03.2012 / 10:42
0

Eu tentei este simples liner como sugerido em Vamos fazer amigos de screen e ssh-agent e isso funciona para mim.

Login pela primeira vez no Target. Precisa ser feito apenas uma vez.

ssh -o StrictHostKeyChecking=no -C <userid>@<server>

Ecrã de lançamento pela primeira vez .. Precisa de ser feito apenas uma vez.

eval 'ssh-agent'; /usr/bin/screen -D -R -h 10000
ssh-add

Se estiver desconectado ou desconectado, use este comando para efetuar login subsequentemente para conectar-se à tela existente.

ssh -o StrictHostKeyChecking=no -C -t <userid>@<server> ssh-agent /usr/bin/screen -D -R -h 10000
    
por 13.04.2012 / 14:08
0

Todas essas respostas são realmente boas. Eu faço isso de maneira um pouco diferente. Depois de iniciar uma nova sessão ssh e reconectar a tela, redefino a variável de ambiente SSH_AUTH_SOCK com base no conteúdo do ambiente bash bash. Eu só preciso de acesso ssh-agent ocasionalmente quando estou usando o svn, então eu apenas reconfixo o SSH_AUTH_SOCK conforme necessário nestes shells.

Isso usa o sistema de arquivos proc e é específico do Linux. Eu só testei isso em uma caixa de Linux sem cabeça que só é acessada por mim, pode levar alguns ajustes para fazê-lo funcionar em outros ambientes.

Para redefinir o SSH_AUTH_SOCK (isso pode ser feito como um alias).

$ . ~/bin/screen_auth.sh

screen_auth.sh se parece com isso

# Find the pid of putty's bash shell
tty='who | awk '/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ { print substr($2, 5) }''
pid='ps -t $tty | grep bash | awk '{print $1}''
# Find the SSH_AUTH_SOCK variable in its enviornment
auth_sock='xargs --null --max-args=1 echo < /proc/$pid/environ | grep SSH_AUTH_SOCK'
eval "export $auth_sock"
    
por 20.01.2012 / 09:07
0

Todas as soluções acima sofrem de condições de corrida (em várias sessões SCREEN ou em várias conexões SSH). A única solução universal que consigo pensar é primeiro enviar o SSH_AUTH_SOCK para o processo do servidor SCREEN em screen -r e, em seguida, puxá-lo para dentro da sessão BASH antes de cada comando interativo não integrado. Infelizmente, o SCREEN e o BASH foram criados sem o conhecimento de tal tipo de problemas, por isso é bastante difícil de implementar adequadamente (embora nunca seja tarde para postar solicitações de recursos para ambos os projetos). Minha tentativa foi feita para superar este problema para as sessões do BASH, que podem ser encontradas aqui:

Para instalar:

  1. coloque os dois scripts em $HOME/bin , adicione o bit executável;
  2. Certifique-se de que $HOME/bin seja anterior a /usr/bin no PATH:

    PATH = $ HOME / bin: $ PATH

  3. adicione isso ao seu .bashrc :

    source $ HOME / bin / configuração do screen-helper

Agora você pode tentar criar a sessão SCREEN dentro da sessão SSH, desconectar, desconectar, conectar e reconectar e esperamos que ssh-add -l mostre corretamente suas chaves.

    
por 21.11.2014 / 15:44
0

Eu examinei outras respostas e não consegui encontrar as minhas. Aqui está o que eu uso. Crie um arquivo ~/.screenrc-wrapper com o seguinte conteúdo:

escape ^xx
bindkey ^Ad detach

E adicione isso ao seu ~/.bashrc (ou ~/.zshrc se você usar isso):

  if echo $TERM | grep -v 'screen' && ! screen -x -SU wrapper; then
      if echo $TERM | grep -v 'screen' && ! screen -x -SU main; then
      screen -c ~/.screenrc-wrapper -SU wrapper ssh-agent screen -SU main
      fi
  fi

Dessa forma, você usaria duas sessões de tela - uma é "wrapper" e uma é a interna. Isto irá manter o último ativo, mesmo quando você sair e vai continuar com o agente ssh. Outro recurso interessante é que ele vai lembrar da configuração da sua janela - se você usar janelas divididas, pode ser muito útil.

Você pode encontrar esse recurso no contexto dos meus dotfiles .

    
por 31.10.2015 / 21:55