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


48

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

Como isso pode ser consertado?

Respostas:


41

1) No seu script SSH rc (~ / .ssh / rc), você 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 impedir 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 link simbólico em um local canônico que se atualiza para o SSH_AUTH_SOCK "real" no momento do login. Isso é independente do uso de um shell no ssh ou da chamada direta de um comando, também funciona com "ssh -t screen -RRD".

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

Além disso, você não deve usar "-v" com o ln assim que ele 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

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

Solução originalmente adaptada deste post , que não funciona, mas tem a ideia certa.


Isso pressupõe que você primeiro faça login e, em seguida, inicie a tela. Direito?
innaM 24/03/09

1
Como pode ser de outra maneira? Como você iniciaria a tela sem estar conectado?

1
Você está certo. A pergunta foi formulada de uma maneira estúpida. Mas você precisa fazer login, iniciar um shell e a partir daí a tela inicial? Costumo fazer algo como "ssh -t some.machine screen -R".
24410 innaM

1
Ah ok. Bem, eu apenas tentei isso e não funciona (ou seja, o ssh-agent não está conectado). Eu acho que o ssh não configura os soquetes apropriados quando usado dessa maneira. Talvez um pouco mais de argumento pudesse limpar isso?

O SSH configura os soquetes, apenas nunca inicia o shell. Mas essa dica é tão útil que acho que posso mudar meus hábitos.
31129 innaM

23

Eu acho que isso funciona como uma simplificação da resposta de @ sandip-bhattacharya. Coloque isso em seu ~/.bashrcarquivo e execute o comando export em qualquer sessão de 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

Que lê "se $SSH_AUTH_SOCKé 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_SOCKpara apontar para o caminho conhecido.

Os ! -hevita a criação de uma referência circular se você executar isso várias vezes.

Além disso, se você usar byobu, ele fará isso automaticamente, sem a necessidade de editar nenhum arquivo de configuração.

O único bug que encontrei ( byobutambém) é se você abrir um segundo ssh -Aou ForwardAgentconexão, ele substituirá o primeiro soquete e se você fechar a segunda conexão antes do primeiro, perderá seu único soquete bom.


1
Isso funciona tmuxtambém.
Dag Høidahl 9/09/16

Funciona muito bem, mas é interrompido ao usar pastas domésticas montadas remotamente. Nesse caso, use ~/.ssh/ssh_auth_sock_"$(hostname)"para o seu link simbólico. Ele manterá soquetes de autenticação separados para cada host.
Kibber

4

"ssh -t some.machine screen -R" não será executado bash e, portanto, não será executado o script .bash_profile onde o link simbólico é criado.

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

(supondo que você esteja usando o bash como seu shell, é claro)

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


"Primeira resposta dada acima" não significa nada, pois as respostas mudam de ordem conforme são votadas, etc. Inclua o link de compartilhamento da resposta a que você está se referindo, pois isso não será alterado.
Rjmunro

3

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

http://www.linux.com/archive/feature/134133

é o básico ... Eu escrevi um script lil para automatizar o processo no meu .screenrc para um determinado host. (também encaminha meu ssh, para que em todos esses lugares diferentes eu possa encapsular minha conexão através dos meus servidores)

na distribuição autossh 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 ssh-agent funcionando, eu uso o chaveiro, já que sou uma espécie de cabeça de concha ... acho que o OSX tem algo disponível para manter seu agente por perto ...


2

Aqui está o método que eu uso:

SOCK=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "\0" "\n" | grep SSH_AUTH_SOCK) ; eval $SOCK ; export SSH_AUTH_SOCK
DISP=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "\0" "\n" | grep DISPLAY) ; eval $DISP ; export DISP

Eu costumo configurar um alias ou uma função shell com estes comandos:

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

Pode ser necessário adaptar a expressão regular ' tela - (r | DR) ' aos comandos exatos que você usa para reconectar sua tela.

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

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


-1 para o uso desnecessário de sudo.
0xC0000022L

1

Normalmente, mantenho sessões de longo prazo (mais de 6 meses) em execução no meu local de trabalho em diferentes servidores. Portanto, recolocar repetidamente e ter um agente de encaminhamento ssh viável tem sido problemático. Isto é 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 apenas efetuar login no servidor remoto sem iniciar / recolocar a tela, haverá dois "soquetes", um em uso screene outro pelo novo shell. Não deve haver duas sessões de "inicialização", mas uma segunda sessão ainda pode ser iniciada reattach -S new; nessa situação, o agente seria compartilhado com o ~/.ssh/agent-screenvalor. Para recuperar um agente de encaminhamento de trabalho, desanexe e faça login novamente. X${USER} = XmyusernameIsso garante que o código não seja chamado sudono mesmo servidor.


1

Estou usando uma variação do que @apinstein está usando para o 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 da tela. Isso funcionaria para todos os novos shells na sua sessão de tela. Para shells existentes, é necessário executar export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sockno shell do host para fazê-lo funcionar.

PS Desculpe por adicionar isso como uma resposta independente, ao passo que ele se baseia na resposta de @ apinstein. Teve que fazer isso, pois os comentários no stackoverflow não suportam blocos de código.


Por que nem sempre ligar e sempre exportar?
Collin Anderson

@CollinAnderson Dois comportamentos diferentes. um dentro de um shell de tela e outro dentro do shell de logon regular. a variável de ambiente em um shell de login é definida por ssh e, portanto, o link simbólico lá. se fizermos isso em uma sessão de tela, causaremos um loop de link simbólico.
Sandip Bhattacharya

Ahh, certo. Você precisaria vincular apenas se $ SSH_AUTH_SOCK ainda não for um link. Veja meu post superuser.com/a/424588/134212
Collin Anderson

0

Eu tentei esse liner simples, como sugerido em Vamos fazer amigos da tela e do ssh-agent e funciona para mim.

Primeiro faça login no Target.Precisa ser feito apenas uma vez.

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

Iniciar a tela pela primeira vez .. Precisa ser feito apenas uma vez.

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

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

ssh -o StrictHostKeyChecking=no -C -t <userid>@<server> ssh-agent /usr/bin/screen -D -R -h 10000

0

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

Isso usa o sistema de arquivos proc, portanto, é específico do Linux. Eu só testei isso em uma caixa Linux sem cabeça que só é acessada por mim; pode levar alguns ajustes para que ele funcione em outros ambientes.

Para redefinir SSH_AUTH_SOCK (isso pode ser um alias).

$ . ~/bin/screen_auth.sh

screen_auth.sh tem esta aparência

# 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"

0

Todas as soluções acima sofrem de condições de corrida (em várias sessões de TELA ou em várias conexões SSH). A única solução universal em que consigo pensar é primeiro empurrar SSH_AUTH_SOCK para o processo do servidor SCREEN screen -re puxá-lo para dentro da sessão BASH antes de cada comando interativo não incorporado. Infelizmente, o SCREEN e o BASH foram projetados sem o conhecimento de tais tipos de problemas, por isso é bastante difícil de implementar adequadamente (embora nunca seja tarde para publicar solicitações de recursos nos dois projetos). Minha tentativa foi feita para superar esse problema nas sessões BASH, que podem ser encontradas aqui:

Para instalar:

  1. coloque os dois scripts $HOME/bin, adicione o bit executável;
  2. certifique-se de que isso $HOME/binocorre antes /usr/binno PATH:

    PATH = $ HOME / bin: $ PATH

  3. adicione isso ao seu .bashrc:

    origem $ HOME / configuração do bin / auxiliar de tela

Agora você pode tentar criar uma sessão SCREEN dentro da sessão SSH, desconectar, desconectar, conectar e reconectar e, esperançosamente ssh-add -l, mostrar corretamente suas chaves.


Observe que esse ssh-agentdaemon permanente (como sugerido aqui superuser.com/a/412052/376867 ) não sofre condição de corrida, mas sofre de chaveiro antigo. E o mais importante, não é muito seguro deixar todas as suas chaves no host remoto junto com a sessão de tela (ou até mais até a reinicialização, no caso da publicação mencionada).
precisa saber é o seguinte

0

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

escape ^xx
bindkey ^Ad detach

E adicione isso ao seu ~/.bashrc(ou ~/.zshrcse 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 outra é a interna. Isso manterá o último ativo, mesmo quando você sair e continuará com o ssh-agent. Outro recurso interessante é que ele lembrará a configuração da janela - se você usar janelas divididas, pode ser muito útil.

Você pode encontrar esse recurso no contexto em meus arquivos de ponto .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.