Verwenden Sie den gleichen "ssh-agent" für mehrere Anmeldesitzungen

33518
intuited

Gibt es eine bequeme Möglichkeit, sicherzustellen, dass alle Anmeldungen eines bestimmten Benutzers (dh ich) denselben ssh-agent verwenden? Ich habe ein Skript ausgehackt, um die meiste Zeit dafür zu sorgen, dass dies funktioniert, aber ich hatte die ganze Zeit den Verdacht, dass es einen Weg gab, den ich einfach vermisst hatte. Darüber hinaus gab es seitdem erstaunliche Fortschritte in der Computertechnologie, wie zum Beispiel diese Website.

Das Ziel hier ist also das

  • Immer, wenn ich mich bei der Box anmelde, unabhängig davon, ob es sich um SSH handelt, oder in einer grafischen Sitzung, die von gdm / kdm / etc oder von einer Konsole aus gestartet wurde:
    • Wenn mein Benutzername derzeit nicht ssh-agentläuft, wird einer gestartet, die Umgebungsvariablen werden exportiert und ssh-addaufgerufen.
    • Andernfalls werden die Koordinaten des vorhandenen Agenten in die Umgebungsvariablen der Anmeldesitzung exportiert.

Diese Möglichkeit ist besonders nützlich, wenn die betreffende Box als sshRelaispunkt verwendet wird, wenn sie in eine dritte Box eingesetzt wird. In diesem Fall muss nicht jedes Mal die Passphrase des privaten Schlüssels eingegeben werden, wenn Sie ssh eingeben und dann beispielsweise git pushetwas tun möchten .

Das unten angegebene Skript macht dies meistens zuverlässig, obwohl es kürzlich verpatzte, als X abstürzte und ich dann eine weitere grafische Sitzung startete. In diesem Fall gab es möglicherweise andere Unregelmäßigkeiten.

Hier ist mein schlechtes ist-gutes Drehbuch. Ich beziehe das von meinem .bashrc.

# ssh-agent-procure.bash # v0.6.4 # ensures that all shells sourcing this file in profile/rc scripts use the same ssh-agent. # copyright me, now; licensed under the DWTFYWT license.  mkdir -p "$HOME/etc/ssh";  function ssh-procure-launch-agent { eval `ssh-agent -s -a ~/etc/ssh/ssh-agent-socket`; ssh-add; }  if [ ! $SSH_AGENT_PID ]; then if [ -e ~/etc/ssh/ssh-agent-socket ] ; then SSH_AGENT_PID=`ps -fC ssh-agent |grep 'etc/ssh/ssh-agent-socket' |sed -r 's/^\S+\s+(\S+).*$/\1/'`;  if [[ $SSH_AGENT_PID =~ [0-9]+ ]]; then # in this case the agent has already been launched and we are just attaching to it.  ##++ It should check that this pid is actually active & belongs to an ssh instance export SSH_AGENT_PID; SSH_AUTH_SOCK=~/etc/ssh/ssh-agent-socket; export SSH_AUTH_SOCK; else # in this case there is no agent running, so the socket file is left over from a graceless agent termination. rm ~/etc/ssh/ssh-agent-socket; ssh-procure-launch-agent; fi; else ssh-procure-launch-agent; fi; fi; 

Bitte sag mir, dass es einen besseren Weg gibt, dies zu tun. Bitte wählen Sie auch die Inkonsistenzen / Gaffeln nicht aus (zB varSachen einfügen etc); Ich habe das vor einiger Zeit geschrieben und habe seitdem viele Dinge gelernt.

57
KeyError: 'DWTFYWT' nicht gefunden; Meinten Sie [WTFPLv2] (http://sam.zoy.org/wtfpl/)? grawity vor 13 Jahren 1
@grawity: danke für diesen Link, ihre FAQs machten meinen Tag: ** Übrigens, mit der WTFPL kann ich auch… ** * Oh aber ja, natürlich kannst du. * ** Aber kann ich… ** * Ja kannst du. * ** Kann… ** * Ja! * Hahahahahaha quack quixote vor 13 Jahren 0
@grawity: Nein, genau das wollte ich dir sagen, mwahahaha. intuited vor 13 Jahren 0

15 Antworten auf die Frage

33
h355ian

ssh -A [user@]remotehost

Ich denke, das ist, wonach Sie suchen. Verwenden Sie den Schalter -A, wenn Sie ssh vor Ihrem ssh-agent ausführen. Hier ist ein Anwendungsfall:

Ich habe einen Remote-Server, der einige Git-Repos mit einem Remote-Verweis auf Github hat. Wenn in einer Bildschirmsitzung kein ssh-agent ausgeführt wird, muss ich die Passphrase für meinen Schlüssel eingeben, um einen "git pull origin master" auszuführen. Booo! Außerdem muss ich meinen privaten Schlüssel auf dem Remote-Server installiert haben - mehr Boooo!

Verwenden Sie stattdessen einfach ssh -A [user@]remotehostPässe für meinen lokal laufenden ssh-agent. Jetzt brauche ich meinen privaten Schlüssel nicht mehr, um überhaupt auf dem Remote-Host zu existieren. Ich glaube nicht, dass Sie überhaupt ein Scripting mit ssh-agent machen müssen.

Das war es, wonach ich gesucht habe, thx! tmow vor 12 Jahren 2
Wußte nichts davon, aber es war genau das, wonach ich gesucht hatte, als ich zu dieser Frage kam. Will McCutchen vor 12 Jahren 3
Das ist noch besser als das, wonach ich gesucht habe! Gute Antwort! WhyNotHugo vor 11 Jahren 1
Siehe auch "man 5 ssh_config" für die Konfigurationseinstellung "ForwardAgent". Es ermöglicht standardmäßig die Agentenweiterleitung, wodurch das Argument `-A` entfällt. Beachten Sie vor der Verwendung der Agentenweiterleitung, dass ein Sicherheitsrisiko besteht, wenn andere privilegierte Benutzer auf dem Remote-Computer auf den Socket des weitergeleiteten Agenten zugreifen können. Dies wird auch auf der Manpage erwähnt. Dies ist gut erklärt (http://www.symantec.com/connect/articles/ssh-and-ssh-agent). starfry vor 9 Jahren 1
24
Zed

Ich könnte meine eigene Variation genauso gut in die Mischung einbringen:

function sshagent_findsockets { find /tmp -uid $(id -u) -type s -name agent.\* 2>/dev/null }  function sshagent_testsocket { if [ ! -x "$(which ssh-add)" ] ; then echo "ssh-add is not available; agent testing aborted" return 1 fi  if [ X"$1" != X ] ; then export SSH_AUTH_SOCK=$1 fi  if [ X"$SSH_AUTH_SOCK" = X ] ; then return 2 fi  if [ -S $SSH_AUTH_SOCK ] ; then ssh-add -l > /dev/null if [ $? = 2 ] ; then echo "Socket $SSH_AUTH_SOCK is dead! Deleting!" rm -f $SSH_AUTH_SOCK return 4 else echo "Found ssh-agent $SSH_AUTH_SOCK" return 0 fi else echo "$SSH_AUTH_SOCK is not a socket!" return 3 fi }  function sshagent_init { # ssh agent sockets can be attached to a ssh daemon process or an # ssh-agent process.  AGENTFOUND=0  # Attempt to find and use the ssh-agent in the current environment if sshagent_testsocket ; then AGENTFOUND=1 ; fi  # If there is no agent in the environment, search /tmp for # possible agents to reuse before starting a fresh ssh-agent # process. if [ $AGENTFOUND = 0 ] ; then for agentsocket in $(sshagent_findsockets) ; do if [ $AGENTFOUND != 0 ] ; then break ; fi if sshagent_testsocket $agentsocket ; then AGENTFOUND=1 ; fi done fi  # If at this point we still haven't located an agent, it's time to # start a new one if [ $AGENTFOUND = 0 ] ; then eval `ssh-agent` fi  # Clean up unset AGENTFOUND unset agentsocket  # Finally, show what keys are currently in the agent ssh-add -l }  alias sagent="sshagent_init" 

Und wenn ich dann jedes Mal einlogge, wenn ich einen Agenten anhängen möchte (was ich nicht immer tun kann), tippe ich einfach sagent.

wenn [! -x "$ (which ssh-add)"]; `sollte durch` if! ersetzt werden. welche ssh-add; `oder` if! Befehl -v ssh-add`. (Denken Sie daran, `[` ist nur ein Befehl) grawity vor 13 Jahren 2
Nun, Sie können das tun, aber es müsste tatsächlich sein, wenn! which ssh-add> / dev / null`, um zu verhindern, dass der Pfad gedruckt wird. An diesem Punkt bin ich nicht wirklich sicher, ob er klarer ist, obwohl ich nehme an, dass er Ihnen einen zusätzlichen Befehlsaufruf erspart. Zed vor 13 Jahren 0
Die Antwort lautet also im Grunde nein. Mist. Nun, das scheint mehr zu sein als mein Hack, also wird es wahrscheinlich nützlich sein. Seltsamerweise gibt es keinen strukturierteren Weg, dies zu tun, es scheint etwas zu sein, das ziemlich nützlich wäre. intuited vor 13 Jahren 0
Ich bin in der Lage, in letzter Zeit alles zu repositorifizieren, also habe ich ein [github repo] (http://github.com/intuited/sshag) für Ihr Skript eingerichtet. Danke noch einmal. Ich hoffe, ich war förmlich genug mit der Lizenzierung: ~ / intuited vor 13 Jahren 0
Es macht mir nichts aus Bitte kommentieren Sie dies hier, wenn jemand Verbesserungen einreicht. Zed vor 13 Jahren 0
In meinem Fall könnte ich mehrere Agent-Socket-Dateien haben. Um immer das letzte (durch Zeitstempel) zu verwenden, habe ich den obigen find-Befehl folgendermaßen geändert: `find / tmp -uid $ (id -u) -type s -printf '% Ts \ t% p \ n' -name agent. \ * 2> / dev / null | sort -nr | cut -f2` Dirk Gorissen vor 7 Jahren 0
Wie Kev sagte: Versuchen Sie es mit einem Schlüsselbund, es ist dafür gemacht. Aber noch besser, tun Sie, was MarkMo gesagt hat! 00prometheus vor 7 Jahren 0
https://github.com/intuited/sshag/pull/1 "Verwenden Sie" sshag user @ domain "anstelle von" ssh user @ domain "." Getestet unter Linux und Git-for-Windows (MSYS2). go2null vor 7 Jahren 0
20
vonhogen

Hier ist eine ziemlich schöne, die auch in Cygwin funktioniert:

SSH_ENV=$HOME/.ssh/environment  function start_agent { echo "Initialising new SSH agent..." /usr/bin/ssh-agent | sed 's/^echo/#echo/' > $ echo succeeded chmod 600 $ . $ > /dev/null /usr/bin/ssh-add; }  # Source SSH settings, if applicable  if [ -f "$" ]; then . $ > /dev/null #ps $ doesn't work under cywgin ps -efp $ | grep ssh-agent$ > /dev/null || { start_agent; } else start_agent; fi 

Fügen Sie es Ihrem .bash_profile oder .bashrc hinzu

Quelle: http://www.cygwin.com/ml/cygwin/2001-06/msg00537.html

Funktioniert auch gut mit Git Bash (mingw64) für Windows Dolphin vor 8 Jahren 0
"$ " muss "$ " sein, wenn Ihr Windows-Benutzername ein Leerzeichen enthält rgvcorley vor 7 Jahren 1
Diese Antwort scheint sich im Internet zu bewegen. Hier handelt es sich um einen [viel größeren Stackoverflow-Thread] (https://stackoverflow.com/a/18915067/4970632). Der beste / einfachste Ansatz IMHO. Luke Davis vor 5 Jahren 0
9
kev

Versuchen Sie es mit einem Schlüsselbund, dafür gemacht. http://www.gentoo.org/doc/de/keychain-guide.xml

6
MarkMo

I have recently started using:

https://github.com/ccontavalli/ssh-ident

All I have to do is add:

 alias ssh=/path/to/ssh-ident 

In my .bashrc file. The script takes care of:

  • creating an agent when it is first needed
  • load the necessary keys on demand
  • share agents across multiple login sessions
  • manage multiple agents, one for each 'identity' that I use online, and use the right agent based on the host I'm connecting to or the current working directory.
ssh-ident ist fantastisch! Es entriegelt den Schlüssel und lädt den Agenten, wenn ich versuche, SSH zu verwenden, anstatt den Schlüssel vorher zu entsperren. Dies macht Key Timeouts nützlich. Noch wichtiger ist, dass meine Agenten für verschiedene Zwecke getrennt bleiben (ein großes Sicherheitsrisiko; root auf einem Computer hat meine Zugriffsebene auf alle anderen Computer, für die der aktuelle Agent Schlüssel hat!) 00prometheus vor 7 Jahren 0
5
grawity

Ich ziehe es vor, die Dinge so einfach wie möglich zu halten: (Ausschnitt aus ~/.profile)

check-ssh-agent() { [ -S "$SSH_AUTH_SOCK" ] && { ssh-add -l >& /dev/null || [ $? -ne 2 ]; } }  # attempt to connect to a running agent check-ssh-agent || export SSH_AUTH_SOCK="$(< ~/.tmp/ssh-agent.env)" # if agent.env data is invalid, start a new one check-ssh-agent || { eval "$(ssh-agent -s)" > /dev/null echo "$SSH_AUTH_SOCK" > ~/.tmp/ssh-agent.env } 

Ich habe vorher nicht an die Verwendung gedacht -a, aber es könnte einfacher sein:

check-ssh-agent || export SSH_AUTH_SOCK=~/.tmp/ssh-agent.sock check-ssh-agent || eval "$(ssh-agent -s -a ~/.tmp/ssh-agent.sock)" > /dev/null 
Nett. Ich habe es in meiner Antwort etwas vereinfacht (unten). Ether vor 9 Jahren 0
2
Greg Bray

In my case I have posh-git setup in PowerShell and wanted cygwin to use the same ssh-agent. I had to do some path manipulation since they use different tmp folders, and the .env file created was UTF16 with BOM and CR\LF so that was fun to deal with. Adding the following to the .bashrc used by cygwin should work:

# Connect to ssh-agent started by posh-git SSH_AGENT_ENV=$(cygpath "$LOCALAPPDATA\Temp") if [ -z $SSH_AUTH_SOCK ] && [ -z $SSH_TTY ]; then # if no agent & not in ssh if [ -f "$SSH_AGENT_ENV/.ssh/SSH_AUTH_SOCK.env" ]; then AUTH_SOCK=$(iconv -c -f UTF-16LE -t US-ASCII "$SSH_AGENT_ENV/.ssh/SSH_AUTH_SOCK.env" | tr -d '\r\n') export SSH_AUTH_SOCK="$" ssh-add -l > /dev/null if [ $? = 2 ] ; then echo "Failed to setup posh-git ssh-agent using $AUTH_SOCK" unset SSH_AUTH_SOCK else echo "Found posh-git ssh-agent $AUTH_SOCK" fi else #Start new agent if you want (not shared by posh-git) echo "failed to setup posh-git ssh-agent" #eval `ssh-agent -s` > /dev/null fi fi 
1
Jorrit Jorritsma

Again an example to put in your .bash_profile immediately and asking to add your default key at logon. Forwarding was not an option in my case.

do-ssh-agent() { # function to start the ssh-agent and store the agent details for later logon ssh-agent -s > ~/.ssh-agent.conf 2> /dev/null . ~/.ssh-agent.conf > /dev/null } # set time a key should be kept in seconds keyage=3600 if [ -f ~/.ssh-agent.conf ] ; then . ~/.ssh-agent.conf > /dev/null ssh-add -l > /dev/null 2>&1 # $?=0 means the socket is there and it has a key # $?=1 means the socket is there but contains no key # $?=2 means the socket is not there or broken stat=$? if [ $stat -eq 1 ] ; then ssh-add -t $keyage > /dev/null 2>&1 elif [ $stat -eq 2 ] ; then rm -f $SSH_AUTH_SOCK do-ssh-agent ssh-add -t $keyage > /dev/null 2>&1 fi else do-ssh-agent ssh-add -t $keyage > /dev/null 2>&1 fi 
1
Ether

Dies ist meine Lösung, angepasst an https://superuser.com/a/141233/5255 (in diesem Thread):

# attempt to connect to a running agent - cache SSH_AUTH_SOCK in ~/.ssh/ sagent() { [ -S "$SSH_AUTH_SOCK" ] || export SSH_AUTH_SOCK="$(< ~/.ssh/ssh-agent.env)"  # if cached agent socket is invalid, start a new one [ -S "$SSH_AUTH_SOCK" ] || { eval "$(ssh-agent)" ssh-add -t 25920000 -K ~/.ssh/id_rsa echo "$SSH_AUTH_SOCK" > ~/.ssh/ssh-agent.env } } 
1
raghavan

Erstellen Sie die Datei ~ / ssh-agent.sh

agent_out_file="$HOME/ssh-agent.out"  function initialize { pgrep ssh-agent && kill $(pgrep ssh-agent) ssh-agent -s > $agent_out_file  . $agent_out_file }  pgrep ssh-agent if [ $? -eq 0 ]; then # ssh agent running ssh-add -l > /dev/null 2>&1 status=$? if [ $status -eq 0 ]; then # can connect to ssh agent and keys available echo nothing to do elif [ $status -eq 1 ]; then # can connect to ssh agent and no keys available echo nothing to do elif [ $status -eq 2 ]; then # cannot connect to ssh agent . $agent_out_file fi else # ssh agent not running initialize  fi 

Fügen Sie die Datei in .bashrc ein

. ~/ssh-agent.sh