So aktualisieren Sie die Umgebungsvariablen des SSH-Agenten beim Anhängen an vorhandene tmux-Sitzungen automatisch


78

Ich versuche einen guten Weg zu finden, um den SSH-Agenten wiederherzustellen, wenn ich eine getrennte tmux-Sitzung wieder verbinde.

Die Ursache scheint zu sein, dass sich die Sitzung des SSH-Agenten ändert, die Umgebungsvariable aus der tmux-Sitzung jedoch nicht aktualisiert wird.

Wie kann ich dies automatisieren, bevor ich die Sitzung selbst anhänge? Da die Sitzung, an die ich anhänge, nicht immer eine Bash-Eingabeaufforderung enthält, kann ich es mir nicht leisten, etwas darin einzugeben. Es muss etwas sein, das ausgeführt werden muss, bevor die tmux-Sitzung erstellt oder angehängt wird.

Ein Beispiel für den Code, den ich ausführe, ist https://gist.github.com/ssbarnea/8646491 - ein kleiner SSH-Wrapper, der tmux verwendet, um persistem SSH-Verbindungen zu erstellen. Dies funktioniert recht gut, aber manchmal funktioniert der SSH-Agent nicht mehr, sodass ich ihn nicht mehr verwenden kann, um eine Verbindung zu anderen Hosts herzustellen.


Sie sollten wahrscheinlich Pymkins Antwort als Antwort markieren.
— David Sanders

Antworten:


80

Es gibt einen ausgezeichneten Kern von Martijn Vermaat, der Ihr Problem ausführlich behandelt, obwohl er für Bildschirmbenutzer gedacht ist. Deshalb passe ich ihn hier für tmux an.

Zusammenfassen:

  1. Erstellen ~/.ssh/rcSie , wenn es noch nicht vorhanden ist, und fügen Sie den folgenden Inhalt hinzu:

    #!/bin/bash
    
    # Fix SSH auth socket location so agent forwarding works with tmux
    if test "$SSH_AUTH_SOCK" ; then
      ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
    fi
    
  2. Lass es in tmux funktionieren, füge dies zu deinem hinzu ~/.tmux.conf:

    # fix ssh agent when tmux is detached
    setenv -g SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock
    

Zusätzliche Arbeit ist erforderlich, wenn Sie die X11-Weiterleitung aktivieren möchten .


1
Bei der erneuten Verbindung mit tmux wird nicht auf das neueste ssh_auth_sock aktualisiert. Es bleibt bei demjenigen, der die Sitzung ursprünglich erstellt hat, sodass dies nicht funktioniert. Irgendwelche Ideen?
— Bret

6
Ich musste ein set -g update-environment -rzu .tmux hinzufügen , damit dieser Prozess funktioniert. Ich habe auch einige Namespaces zur Erstellung von Socket-Links hinzugefügt: gist.github.com/bcomnes/e756624dc1d126ba2eb6
— Bret

1
Ein Fehler mit dem vorherigen GIST wurde behoben: Hatte $ (Hostname) in $ HOSTNAME in den Dateien .screenrc und .tmux.conf geändert
— Bret

2
@Bret Ihre Lösung funktioniert einwandfrei, wenn Sie sich von einer tmux-Sitzung trennen und dann die SSH-Verbindung schließen. Es funktioniert jedoch nicht, wenn Sie die SSH-Verbindung zwangsweise schließen und dennoch an eine TMXX-Sitzung angeschlossen sind (z. B. wenn Sie plötzlich die Netzwerkverbindung verlieren und die SSH-Verbindung mit [Shift ~] [Enter] schließen. Irgendwelche Ideen, was dies beheben könnte?
— Andrii Yurchuk

2
Nein, ich habe es leider aufgegeben.
— Bret

39

Während Variablen standardmäßig tmux aktualisiert SSH werden, ist dies nicht erforderlich

  • Socket-Pfad ändern / hinzufügen
  • Ändern Sie die SSH_AUTH_SOCKETVariable

Ich mag die Lösung von Chris Down, die ich geändert habe, um eine Funktion hinzuzufügen

fixssh() {
    eval $(tmux show-env    \
        |sed -n 's/^\(SSH_[^=]*\)=\(.*\)/export \1="\2"/p')
}

in ~/.bashrc. Anruf fixsshnach dem Anhängen der Sitzung oder vor ssh/ scp/ rsync.

Neuere Versionen der tmuxSupport- -sOption für show-env, also nur

eval $(tmux show-env -s |grep '^SSH_')

ist möglich.


Vielen Dank, das hat bei mir funktioniert! :) Ein kleines Problem: Wenn Sie dies in einem wieder angebrachten tmux-Bereich tun, funktioniert es nicht. Ich muss den alten Bereich schließen und einen neuen öffnen. Eine Lösung hierfür besteht darin, tmux zu trennen, die $DISPLAYVariable anzuzeigen, tmux erneut zuzuordnen und $DISPLAYin meinem Fall korrekt einzustellen export DISPLAY=localhost:14.0, aber die Anzahl scheint sich bei jeder ssh-Sitzung zu ändern.
— PlasmaBinturong

"Während tmux SSH-Variablen standardmäßig aktualisiert" Worüber sprechen Sie? (Ich vermute, dass der Anker in Ihrem Link jetzt nicht mehr vorhanden ist.
— Bruno Bronosky

1
@BrunoBronosky Ich habe seinen Link repariert. Sie hatten Recht: Anker existierte nicht mehr. Scheint jetzt eine stabile Form zu haben.
— Überdenken Sie den

Dies sollte die beste Antwort sein. Es ist nicht erforderlich, eine neue temporäre Datei zu erstellen.
— Sjy

24

Folgendes verwende ich zum Aktualisieren SSH_AUTH_SOCKin einem tmuxFenster (basierend auf Hans Ginzels Skript):

alias fixssh='eval $(tmux showenv -s SSH_AUTH_SOCK)'

Oder dafür tmuxhat nicht showenv -s:

alias fixssh='export $(tmux showenv SSH_AUTH_SOCK)'

6

Hier ist meine Lösung, die beide Ansätze umfasst und keine zusätzliche Eingabe erfordert, wenn ich mich wieder mit der tmux-Sitzung verbinde

alias ssh='[ -n "$TMUX" ] && eval $(tmux showenv -s SSH_AUTH_SOCK); /usr/bin/ssh'

1
Es sieht so aus, als würde es eval $(tmux showenv -s SSH_AUTH_SOCK)lokal und nicht remote ausgeführt!
— Acgtyrant

Ich habe dies auf der Fernbedienung geschrieben (tmux läuft) und es hat wie erwartet funktioniert. Vielen Dank!
— Riywo

4

Hier gibt es viele gute Antworten. Aber es gibt Fälle, in denen tmux show-environmentnicht gesehen wird SSH_AUTH_SOCK. In diesem Fall können Sie findes explizit suchen.

export SSH_AUTH_SOCK=$(find /tmp -path '*/ssh-*' -name 'agent*' -uid $(id -u) 2>/dev/null | tail -n1)

Das ist lang und kompliziert, also werde ich es aufschlüsseln ...

01  export SSH_AUTH_SOCK=$(
02    find /tmp \
03      -path '*/ssh-*'
04      -name 'agent*'
05      -uid $(id -u)
06      2>/dev/null
07    | tail -n1
08  )
  1. exportDie SSH_AUTH_SOCKUmgebungsvariable, die auf die Ausgabe der $()Befehlssubstitution gesetzt ist
  2. find Dateien, die in beginnen /tmp
  3. Beschränken Sie die Ergebnisse nur auf diejenigen mit /ssh-im Pfad
  4. Beschränken Sie die Ergebnisse nur auf diejenigen, deren Name mit beginnt agent
  5. Beschränken Sie die Ergebnisse auf diejenigen, deren Benutzer-ID mit dem aktuellen Benutzer übereinstimmt
  6. Alle (Berechtigungen usw.) Fehler zum Schweigen bringen
  7. Nimm nur das letzte Ergebnis, wenn es mehrere gibt

Sie können möglicherweise 6 & 7 weglassen, wenn Sie wissen, dass es nur 1 Ergebnis gibt und Sie sich nicht für stderr-Müll interessieren.


1
Von allen hier aufgeführten Lösungen funktionierte nur dies auf dem Mac.
— SilentGuy

Schön, aber es kann erforderlich sein, nur den LETZTEN SSH-Agent-Socket zu verwenden. Dazu können wir eine Sortierung hinzufügen in find:find /tmp -path '*/ssh-*' -name 'agent*' -uid (id -u) -printf "%T+\t%p\n" 2>/dev/null | sort | tail -n1 | awk -F'\t' '{print $2 }'
— ColCh

3

Ich verwende eine Variation der vorherigen Antworten:

eval "export $(tmux show-environment -g SSH_AUTH_SOCK)"

Angenommen, Sie haben den SSH-Agenten von der äußeren Umgebung aus gestartet. Gleiches gilt für andere Umgebungsvariablen wie DISPLAY.


Sind Sie sicher, dass dies für Sie funktioniert? Mit -gbekomme ich den abgestandenen Wert von $SSH_AUTH_SOCK. Weggehen -gmacht den Trick. Siehe auch andere Antworten.
— Feklee

1

Ich ziehe es vor, die Konfiguration von TMUX (usw.) zu vermeiden und alles rein zu behalten ~/.ssh/. Auf dem Remote- System:

Erstellen ~/.ssh/rc:

#!/bin/bash

# Fix SSH auth socket location so agent forwarding works within tmux
if test "$SSH_AUTH_SOCK" ; then
  ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
fi

Fügen Sie Folgendes hinzu, ~/.ssh/configdamit es nicht mehr darauf angewiesen ist $SSH_AUTH_SOCK, was in freistehenden Terminals veraltet ist:

Host *
  IdentityAgent ~/.ssh/ssh_auth_sock

Bekannte Einschränkungen

  • ssh-addwird nicht verwendet ~/.ssh/configund kann daher nicht mit kommunizieren ssh-agent. Befehle wie ssh-add -lerzeugen Fehler, obwohl sie gut ssh user@hostfunktionieren, ebenso wie das Aktualisieren von Git-Fernbedienungen, auf die über SSH zugegriffen wird.

1

Möglicherweise habe ich eine Lösung ausgearbeitet, die vollständig in der ~/.tmux.confKonfigurationsdatei enthalten ist. Es ist ein anderer Ansatz als das Ändern des ~/.bash_profileund ~/.ssh/rc.

Lösung nur mit ~/.tmux.conf

Schneiden Sie einfach den folgenden Code aus und fügen Sie ihn in Ihren ein ~/.tmux.conf

# ~/.tmux.conf

# SSH agent forwarding
#
# Ensure that SSH-Agent forwarding will work when re-attaching to the tmux
#   session from a different SSH connection (after a dropped connection).
#   This code will run upon tmux create, tmux attach, or config reload.
#
# If there is an SSH_AUTH_SOCK originally defined:
#   1) Remove all SSH related env var names from update-environment.
#      Without this, setenv cannot override variables such as SSH_AUTH_SOCK.
#      Verify update-environment with: tmux show-option -g update-environment
#   2) Force-set SSH_AUTH_SOCK to be a known location
#      /tmp/ssh_auth_sock_tmux
#   3) Force-create a link of the first found ssh-agent socket at the known location
if-shell '[ -n $SSH_AUTH_SOCK ]' " \
  set-option -sg update-environment \"DISPLAY WINDOWID XAUTHORITY\"; \
  setenv -g SSH_AUTH_SOCK /tmp/ssh_auth_sock_tmux; \
  run-shell \"ln -sf $(find /tmp/ssh-* -type s -readable | head -n 1) /tmp/ssh_auth_sock_tmux\" \
"

Vorbehalt

Die obige Lösung ist zusammen mit den anderen Lösungen anfällig für eine Race-Bedingung, wenn mehrere Verbindungen zu derselben Maschine hergestellt werden. Bedenken Sie:

  • Client 1 Verbinden: SSH mit machineX, tmux starten / anhängen ( ssh_auth_sockLink schreiben )
  • Client 2 Connect: SSH an machineX, tmux starten / anhängen ( ssh_auth_sockLink überschreiben )
  • Client 2 trennen: Client 1 hat einen veralteten ssh_auth_sockLink, wodurch er unterbrochen wirdssh-agent

Diese Lösung ist jedoch etwas widerstandsfähiger, da sie den ssh_auth_sockLink nur beim Starten / Anhängen von tmux überschreibt , anstatt beim Initialisieren einer Bash-Shell ~/.bash_profileoder einer SSH-Verbindung~/.ssh/rc

Um diese letzte Racebedingung abzudecken, kann eine Schlüsselbindung hinzugefügt werden, um die tmux-Konfiguration mit einer (Ctrl-b r)Schlüsselsequenz neu zu laden .

# ~/.tmux.conf

# reload config file
bind r source-file ~/.tmux.conf

Wenn Sie diese Sequenz innerhalb einer aktiven tmux-Sitzung ausführen, wenn die ssh_auth_sockVerbindung veraltet ist, wird die SSH-Agent-Verbindung aktualisiert .


0

Nachdem ich auf so viele Vorschläge gestoßen war, fand ich endlich eine Lösung, mit der TMUX den veralteten SSH-Agenten nach dem Anhängen aktualisieren kann. Grundsätzlich müssen sowohl die zshrc-Dateien auf dem lokalen als auch auf dem Remotecomputer geändert werden.

Fügen Sie die folgenden Codes in das lokale zshrc ein, das auf dieser Referenz basiert .

export SSH_AUTH_SOCK=~/.ssh/ssh-agent.$(hostname).sock
ssh-add -l 2>/dev/null >/dev/null
# The error of executing ssh-add command denotes a valid agent does not
# exist. 
if [ $? -ge 1 ]; then
  # remove the socket if it exists
  if [ -S "${SSH_AUTH_SOCK}" ]; then
    rm "${SSH_AUTH_SOCK}"
  fi
  ssh-agent -a "${SSH_AUTH_SOCK}" >/dev/null
  # one week life time
  ssh-add -t 1W path-to-private-rsa-file
fi

Fügen Sie den folgenden Code in das Remote-zshrc ein, an das die tmux-Sitzung angehängt wird.

alias fixssh='eval $(tmux showenv -s SSH_AUTH_SOCK)'

Dann ssh in die entfernte Maschine. Die Option -A ist erforderlich.

ssh -A username@hostname

Hängen Sie die TMUX-Sitzung an. Überprüfen Sie die TMUX-Umgebungsvariablen

# run this command in the shell
tmux showenv -s
# or run this command after prefix CTRL+A or CTRL+B
:show-environment

Führen Sie es fixsshin den zuvor vorhandenen Bereichen aus, um den SSH-Agenten zu aktualisieren. Wenn ein neuer Bereich erstellt wird, wird automatisch der neue SSH-Agent abgerufen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.