Come si ottiene lo schermo per connettersi automaticamente all'attuale agente ssh quando si ricollega a uno schermo esistente?


47

Se si avvia una sessione dello schermo mentre ssh-agent è in esecuzione (dall'inoltro dell'agente ssh -A), l'accesso a ssh-agent funziona correttamente. Tuttavia, se ci si disconnette da quella sessione, si disconnette, si riconnette (con l'inoltro di ssh-agent) e si riconnette alla sessione dello schermo, l'accesso a ssh-agent non funziona.

Come si puo aggiustare?

Risposte:


41

1) Nel tuo script SSH rc (~ / .ssh / rc) imposterai un collegamento simbolico da una posizione canonica al "corrente" SSH_AUTH_SOCK. Ecco come lo faccio in bash (contenuto di ~ / .ssh / rc):

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

(e assicurati di modificare 755 ~ / .ssh / rc). Il "test" serve solo a impedire la visualizzazione di un errore se non si esegue ssh-agent (ovvero se si è ssh senza -A). La seconda metà di quel comando imposta un collegamento simbolico in una posizione canonica che si aggiorna al "vero" SSH_AUTH_SOCK al momento dell'accesso. Questo è indipendente dall'uso di una shell in ssh o dalla chiamata diretta di un comando, funziona anche con "ssh -t screen -RRD".

Nota: l'esistenza di ~ / .ssh / rc modifica il comportamento di sshd. In particolare, non chiamerà xauth. Vedi man sshd per maggiori informazioni e come risolverlo.

Inoltre, non dovresti usare "-v" con ln non appena interromperà rsync-over-ssh con la seguente diagnostica:

$ 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) Nel tuo .screenrc, devi solo sovrascrivere SSH_AUTH_SOCK nella posizione canonica:

setenv SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock

Nota che usi setenv, indipendentemente dalla shell che usi; Penso che setenv sia la sintassi dello schermo, non la shell.

Soluzione originariamente adattata da questo post , che non funziona, ma ha l'idea giusta.


Ciò presuppone che tu prima esegua il login, quindi inizi la schermata. Giusto?
inMar

1
Come può essere diversamente? Come inizieresti la schermata senza aver effettuato l'accesso?

1
Hai ragione. La domanda è stata formulata in modo stupido. Ma devi effettuare il login, avviare una shell e da lì iniziare la schermata? Faccio spesso qualcosa del tipo "ssh -t some.machine screen -R".
innaM

1
Ah ok. Bene, ho appena provato questo e non funziona (es. Ssh-agent non è collegato). Immagino che ssh non crei le prese appropriate quando usato in questo modo. Forse qualche altro argomento potrebbe pulirlo?

SSH imposta i socket, non avvia mai la shell. Ma questo suggerimento è così utile che penso che potrei semplicemente cambiare le mie abitudini.
innaM

22

Penso che questo funzioni come una semplificazione della risposta di @ sandip-bhattacharya. Inseriscilo nel tuo ~/.bashrcfile ed esegui il comando export in tutte le sessioni dello schermo attualmente in esecuzione.

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

In questo modo "if $SSH_AUTH_SOCKè un socket ( -S) e non un collegamento simbolico ( ! -h), crea un nuovo collegamento simbolico nel percorso noto. In tutti i casi, ridefinisci SSH_AUTH_SOCKper indicare il percorso noto.

Le ! -hevita la creazione di un riferimento circolare se si esegue questo più volte.

Inoltre, se lo usi byobu, lo fa automaticamente, senza la necessità di modificare alcun file di configurazione.

L'unico bug che ho trovato in questo (ce l' byobuha anche) è se apri un secondo ssh -Ao una ForwardAgentconnessione sovrascriverà il primo socket, e se chiudi la seconda connessione prima del primo, perderai il tuo unico buon socket.


1
Questo funziona anche per tmux.
Dag Høidahl,

Funziona alla grande, ma si rompe quando si utilizzano cartelle home montate in remoto. In tal caso, utilizzare ~/.ssh/ssh_auth_sock_"$(hostname)"per il collegamento simbolico. Manterrà socket di autenticazione separati per ciascun host.
Kibber,

4

"ssh -t some.machine screen -R" non eseguirà bash e quindi non eseguirà lo script .bash_profile in cui viene creato il collegamento simbolico.

Puoi provare: ssh -t some.machine bash -c "screen -R"

(supponendo che tu stia usando bash come shell ovviamente)

Modifica: quella "risposta" è in realtà un commento sulla prima risposta fornita sopra :)


"Prima risposta fornita sopra" non significa nulla in quanto le risposte cambiano in base all'ordine di votazione, ecc. Ti preghiamo di includere il link di condivisione della risposta a cui ti riferisci, poiché ciò non cambierà.
rjmunro,

3

Penso che tu abbia bisogno di autossh. Lo uso da anni ormai e, combinato con lo schermo, rende tutte le mie sessioni terminali completamente portatili e trasparenti. Chiudo semplicemente lappy, mi sposto in una nuova posizione, apro lappy e tutti i miei schermi e schermi nidificati si collegano automaticamente. Non ci penso nemmeno più.

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

sono le basi ... Ho rubato un lil script per automatizzare il processo nel mio .screenrc per un determinato host. (fa anche il mio inoltro ssh, quindi in tutti questi posti diversi posso tunnelare la mia connessione attraverso i miei server)

nella distribuzione automatica dovrebbe esserci un programma chiamato rscreen (e .. c'è!)

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

Questo dovrebbe aiutare con problemi ssh / screen

Infine, al fine di mantenere il mio agente ssh in esecuzione, uso il portachiavi, dal momento che sono una specie di testa di shell ... Penso che OSX abbia qualcosa a disposizione per mantenere il tuo agente in giro ...


2

Ecco il metodo che 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

Di solito imposto un alias o una funzione shell con questi comandi:

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
}

Potrebbe essere necessario adattare l'espressione regolare " schermo - (r | DR) " agli esatti comandi utilizzati per ricollegare lo schermo.

  • La prima riga legge la variabile di ambiente SSH_AUTH_SOCK nello spazio del processo del comando " screen -r " appena digitato e aggiorna il valore nella shell corrente.
  • La seconda riga è necessaria se si utilizza " ssh -X " per inoltrare le connessioni X11: aggiorna la variabile DISPLAY allo stesso modo.

Un avvertimento con il mio metodo: le cose potrebbero andare storte se sul computer è in esecuzione un altro comando " schermo ".


-1 per l'uso non necessario di sudo.
0xC0000022L

1

Di solito tengo sessioni di lunga durata (6+ mesi) in esecuzione sul mio posto di lavoro su server diversi. Quindi ricollegare ripetutamente e avere un valido agente di inoltro ssh è stato problematico. Questo è ciò che ho impostato sui miei sistemi:

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 accedo al server remoto senza avviare / ricollegare la schermata, allora ci saranno due "socket", uno in uso da screene un altro dalla nuova shell. Non ci dovrebbero essere due sessioni di "avvio", ma una seconda sessione potrebbe essere comunque avviata utilizzando reattach -S new; in questa situazione, l'agente sarebbe condiviso con il ~/.ssh/agent-screenvalore. Per riavere un agente di inoltro funzionante, quindi mi staccherei, riconnetterò. In X${USER} = Xmyusernamequesto modo il codice non verrà richiamato sudosullo stesso server.


1

Sto usando una variazione di ciò che @apinstein sta usando per il mio .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

Funziona con tutte le app in esecuzione nella mia sessione dello schermo. Funzionerebbe con tutte le nuove shell nella sessione dello schermo. Per le shell esistenti è necessario eseguire export SSH_AUTH_SOCK=~/.ssh/ssh_auth_socksulla shell host per farlo funzionare.

PS Ci scusiamo per l'aggiunta di questa come risposta indipendente, mentre si basava solo sulla risposta di @apinstein. Ho dovuto farlo poiché i commenti in StackOverflow non supportano i blocchi di codice.


Perché non sempre link simbolico ed esportazione sempre?
Collin Anderson,

@CollinAnderson Due comportamenti diversi. uno all'interno di una shell dello schermo e uno all'interno della normale shell di accesso. la variabile d'ambiente in una shell di login è impostata da ssh e quindi il link simbolico lì. se lo facciamo all'interno di una sessione dello schermo, provocheremo un ciclo di collegamento simbolico.
Sandip Bhattacharya,

Ah, giusto. Dovresti collegarti solo se $ SSH_AUTH_SOCK non è già un collegamento. Vedi il mio post superuser.com/a/424588/134212
Collin Anderson il

0

Ho provato questa semplice fodera come suggerito su Facciamo amicizia con screen e ssh-agent e funziona per me.

Prima volta accedi a Target. Le operazioni devono essere eseguite una sola volta.

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

Avvia la schermata per la prima volta ... Le operazioni devono essere eseguite una sola volta.

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

Se disconnesso o disconnesso, utilizzare questo comando per accedere successivamente per connettersi alla schermata di uscita.

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

0

Sono tutte risposte davvero buone, lo faccio in modo leggermente diverso. Dopo aver avviato una nuova sessione SSH e ricollegare lo schermo, ho reimpostato la SSH_AUTH_SOCKvariabile di ambiente in base al contenuto dell'ambiente root bash. Ho bisogno dell'accesso occasionale a ssh-agent solo quando sto usando svn, quindi ho appena resettato SSH_AUTH_SOCKcome richiesto in queste shell.

Questo utilizza il file system proc, quindi è specifico di Linux. Ho provato questo su un box Linux senza testa a cui accedo solo da me, potrebbe volerci un po 'di modifiche per farlo funzionare su altri ambienti.

Per ripristinare SSH_AUTH_SOCK (questo potrebbe essere un alias).

$ . ~/bin/screen_auth.sh

screen_auth.sh si presenta così

# 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

Tutte le soluzioni sopra menzionate soffrono di condizioni di gara (in più sessioni SCREEN o in più connessioni SSH). L'unica soluzione universale che mi viene in mente è quella di spingere dapprima SSH_AUTH_SOCK sul processo del server SCREEN screen -re quindi tirarlo all'interno della sessione BASH prima di ogni comando interattivo non incorporato. Sfortunatamente SCREEN e BASH sono stati progettati senza consapevolezza di questo tipo di problemi, quindi è piuttosto difficile da implementare correttamente (anche se non è mai tardi per inviare richieste di funzionalità a entrambi i progetti). Il mio tentativo è stato fatto per superare questo problema per le sessioni BASH che possono essere trovate qui:

Installare:

  1. inserire entrambi gli script $HOME/bin, aggiungere bit eseguibile;
  2. assicurarsi che ciò $HOME/binaccada prima /usr/binin PERCORSO:

    PATH = $ HOME / bin: $ PATH

  3. aggiungi questo al tuo .bashrc:

    sorgente $ HOME / bin / configurazione schermo-helper

Ora puoi provare a creare la sessione SCREEN all'interno della sessione SSH, staccare, disconnettere, connettere e ricollegare e, si spera, ssh-add -ldovrebbe mostrare correttamente le tue chiavi.


Nota che quel ssh-agentdemone permanente (come suggerito qui superuser.com/a/412052/376867 ) non soffre di condizioni di gara, ma soffre di portachiavi stantio. E ciò che è più importante, non è molto sicuro lasciare tutte le tue chiavi sull'host remoto insieme alla sessione dello schermo (o anche più a lungo fino al riavvio in caso di post menzionato).
midenok,

0

Ho sfogliato altre risposte e non sono riuscito a trovare la mia. Ecco cosa uso. Creare un file ~/.screenrc-wrappercon i seguenti contenuti:

escape ^xx
bindkey ^Ad detach

E aggiungi questo al tuo ~/.bashrc(o ~/.zshrcse lo usi):

  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

In questo modo useresti due sessioni sullo schermo: una è "wrapper" e una è quella interna. Questo manterrà vivo quest'ultimo anche quando ci si disconnette e continuerà ad avere ssh-agent attivo. Un'altra caratteristica interessante è che ricorderà la tua configurazione della finestra - se usi finestre divise, potrebbe essere molto utile.

Puoi trovare questa funzione nel contesto dei miei dotfile .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.