एक ही `ssh-agent` को कई लॉगिन सत्रों में साझा करना


61

क्या यह सुनिश्चित करने का एक सुविधाजनक तरीका है कि किसी दिए गए उपयोगकर्ता (यानी मेरे) से सभी लॉगिन समान ssh- एजेंट का उपयोग करें? मैंने ज्यादातर समय इस काम को करने के लिए एक स्क्रिप्ट को हैक किया, लेकिन मुझे सभी पर संदेह था कि ऐसा करने का कोई तरीका था जो मुझे अभी याद नहीं था। इसके अतिरिक्त, उस समय से कंप्यूटिंग तकनीक में आश्चर्यजनक प्रगति हुई है, उदाहरण के लिए इस वेबसाइट पर।

तो यहाँ लक्ष्य यह है कि

  • जब भी मैं बॉक्स में लॉग इन करता हूं, चाहे वह एसएसएच के माध्यम से हो, या जीडीएम / केडीएम / आदि से शुरू हुआ या एक कंसोल में:
    • यदि मेरे उपयोगकर्ता नाम में वर्तमान में कोई ssh-agentरनिंग नहीं है, तो एक शुरू किया जाता है, पर्यावरण चर निर्यात किया जाता है, और ssh-addकहा जाता है।
    • अन्यथा, मौजूदा एजेंट के निर्देशांक लॉगिन सत्र के पर्यावरण चर में निर्यात किए जाते हैं।

यह सुविधा विशेष रूप से मूल्यवान है जब प्रश्न में बॉक्स को sshतीसरे बॉक्स में प्रवेश करते समय रिले बिंदु के रूप में उपयोग किया जाता है । इस मामले में यह निजी कुंजी के पासफ़्रेज़ में टाइप करने से बचता है जब आप हर बार ssh में और फिर उदाहरण के लिए, कुछ git pushया कुछ करना चाहते हैं।

नीचे दी गई स्क्रिप्ट ज्यादातर यह विश्वसनीय रूप से करती है, हालांकि यह हाल ही में बॉट हुआ जब एक्स दुर्घटनाग्रस्त हो गया और मैंने फिर एक और ग्राफिकल सत्र शुरू किया। हो सकता है उस उदाहरण में अन्य पेंच हो।

यहाँ मेरी बुरी-अच्छी स्क्रिप्ट है। मैं अपने से यह स्रोत .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;

कृपया मुझे बताएं कि ऐसा करने का एक बेहतर तरीका है। इसके अलावा विसंगतियों / gaffes (उदाहरण के लिए varसामान डालना etc) को नितंब न करें ; मैंने यह कुछ समय पहले लिखा था और तब से मैंने कई चीजें सीखी हैं।


1
KeyError: 'DWTFYWT' नहीं मिला; क्या आपका मतलब WTFPLv2 है ?
१४:१०

@grawity: उस लिंक के लिए धन्यवाद, उनके FAQs ने मेरा दिन बना दिया: वैसे, WTFPL के साथ, मैं भी कर सकता हूँ ... ओह, लेकिन हाँ, बेशक आप कर सकते हैं। लेकिन क्या मैं ... हाँ आप कर सकते हैं। कर सकते हैं ... हाँ! hahahahahaha
नीम हकीम क्विक्सोट

@ श्रद्धा: नहीं, बस यही मैं चाहता था कि आप सोचें, मावहहा।
intuited

जवाबों:


25

मैं मिश्रण में अपनी भिन्नता भी फेंक सकता हूं:

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"

और फिर हर बार जब मैं लॉग इन करता हूं, अगर मैं एक एजेंट संलग्न करना चाहता हूं (जो मैं हमेशा नहीं करता हूं), मैं बस टाइप करता हूं sagent


2
if [ ! -x "$(which ssh-add)" ];के साथ प्रतिस्थापित किया जाना चाहिए if ! which ssh-add;या if ! command -v ssh-add। (याद रखें, [सिर्फ एक आदेश है)
grawity

ठीक है, आप ऐसा कर सकते हैं, लेकिन यह वास्तव if ! which ssh-add > /dev/nullमें पथ को मुद्रित होने से रोकने की आवश्यकता होगी , जिस बिंदु पर मुझे वास्तव में यकीन नहीं है कि यह कोई भी स्पष्ट है, हालांकि मुझे लगता है कि यह आपको एक अतिरिक्त कमांड आह्वान से बचाता है।
जेड

तो मूल रूप से जवाब नहीं है, तो। बकवास। वैसे यह मेरी हैक की तुलना में अधिक विकसित हो रहा है, इसलिए शायद यह उपयोगी होगा। अजीब है कि ऐसा करने का एक अधिक संरचित तरीका नहीं है, हालांकि, ऐसा लगता है कि यह काफी उपयोगी होगा।
intuited

मैं इन दिनों सब कुछ repositorifying के लायक हूं, इसलिए मैंने आपकी स्क्रिप्ट के लिए एक github repo स्थापित किया । एक बार फिर धन्यवाद। मुझे आशा है कि मैं लाइसेंस के साथ पर्याप्त औपचारिक था: ~ /
अंतर्वासित

मुझे कोई आपत्ति नहीं है। कृपया यहाँ टिप्पणी करें कि क्या कोई इसमें सुधार करता है, हालाँकि।
ज़ेड

36

ssh -A [user@]remotehost

मुझे लगता है कि यह वही हो सकता है जो आप खोज रहे हैं। अपने ssh- एजेंट को आगे बढ़ाते समय -A स्विच का उपयोग करें। यहाँ एक usecase है:

मेरे पास एक रिमोट सर्वर है, जिस पर कुछ गिट रिपोस है, जिस पर एक रिमोट पॉइंट गिथब की ओर इशारा किया गया है। स्क्रीन सत्र में चलने वाले एक ssh- एजेंट के बिना, मुझे "git पुल ओरिजिनल मास्टर" करने के लिए अपनी कुंजी के लिए पासफ़्रेज़ दर्ज करना होगा। Booo! इसके अलावा, मेरे पास रिमोट सर्वर पर मेरी निजी कुंजी स्थापित होनी चाहिए - अधिक Boooo!

इसके बजाय, बस ssh -A [user@]remotehostमेरे स्थानीय स्तर पर चल रहे ssh- एजेंट के साथ पास का उपयोग कर । अब, मुझे दूरस्थ होस्ट पर भी अपनी निजी कुंजी की आवश्यकता नहीं है। मुझे विश्वास नहीं है कि आपको ssh-Agent के साथ किसी भी स्क्रिप्टिंग को करने की आवश्यकता है।


4
इस बारे में पता नहीं था, लेकिन यह वही निकला जो मैं इस प्रश्न के लिए अपना रास्ता बनाते समय देख रहा था।
विल मैकूचेन

1
यह उस चीज़ से भी बेहतर है जिसे मैं ढूंढ रहा था! बहुत बढ़िया जवाब!
WhyNotHugo

1
कॉन्फ़िगरेशन सेटिंग के man 5 ssh_configलिए भी देखें ForwardAgent। यह -Aतर्क की आवश्यकता को दूर करते हुए एजेंट को डिफ़ॉल्ट रूप से अग्रेषित करने में सक्षम बनाता है। एजेंट अग्रेषण का उपयोग करने से पहले ध्यान रखें कि एक सुरक्षा जोखिम है जहां दूरस्थ मशीन पर अन्य विशेषाधिकार प्राप्त उपयोगकर्ता अग्रेषित एजेंट सॉकेट तक पहुंच सकते हैं। मैन पेज पर भी इसका उल्लेख है। यह यहाँ अच्छी तरह से समझाया गया है
स्टारफ्री

मुझे लगता है कि AllowAgentForwarding विकल्प को सर्वर पर हां करने के लिए सेट किया जाना चाहिए, हालाँकि
Ziofil

20

यहाँ बहुत अच्छा है जो साइगविन में काम करता है:

SSH_ENV=$HOME/.ssh/environment

function start_agent {
     echo "Initialising new SSH agent..."
     /usr/bin/ssh-agent | sed 's/^echo/#echo/' > ${SSH_ENV}
     echo succeeded
     chmod 600 ${SSH_ENV}
     . ${SSH_ENV} > /dev/null
     /usr/bin/ssh-add;
}

# Source SSH settings, if applicable

if [ -f "${SSH_ENV}" ]; then
     . ${SSH_ENV} > /dev/null
     #ps ${SSH_AGENT_PID} doesn't work under cywgin
     ps -efp ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
         start_agent;
     }
else
     start_agent;
fi

इसे अपने .bash_profile या .bashrc में जोड़ें

स्रोत: http://www.cygwin.com/ml/cygwin/2001-06/msg00537.html


इसके अलावा Git Bash (mingw64) के साथ खिड़कियों के लिए ठीक काम करता है
Dolphin

1
${SSH_ENV}होने की जरूरत है "${SSH_ENV}"आपका Windows उपयोगकर्ता नाम उस में एक जगह है, तो
rgvcorley

यह उत्तर इंटरनेट के आसपास उछलता हुआ प्रतीत होता है। यहाँ यह बहुत बड़े स्टैकओवरफ्लो थ्रेड पर है । सबसे अच्छा / सरल दृष्टिकोण IMHO।
ल्यूक डेविस


6

मैंने हाल ही में इसका उपयोग शुरू किया है:

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

मुझे बस इतना करना है:

  alias ssh=/path/to/ssh-ident

मेरी .bashrc फ़ाइल में। स्क्रिप्ट का ख्याल रखता है:

  • जब पहली बार जरूरत हो तो एक एजेंट बनाना
  • मांग पर आवश्यक कुंजी लोड करें
  • कई लॉगिन सत्रों में एजेंटों को साझा करें
  • कई एजेंटों को प्रबंधित करें, प्रत्येक 'पहचान' के लिए जो मैं ऑनलाइन का उपयोग करता हूं, और उस होस्ट के आधार पर सही एजेंट का उपयोग करता हूं जिसे मैं वर्तमान कार्य निर्देशिका से जोड़ रहा हूं।

ssh- पहचान शानदार है! यह कुंजी को अनलॉक करता है और एजेंट को लोड करता है जब मैं पहले से चाबी को अनलॉक करने के बजाय ssh करने की कोशिश करता हूं। यह महत्वपूर्ण टाइमआउट को उपयोगी बनाता है। इससे भी महत्वपूर्ण बात, यह मेरे एजेंटों को अलग-अलग उपयोगों के लिए अलग रखता है (एक प्रमुख सुरक्षा जोखिम; एक मशीन पर जड़ें अन्य सभी मशीनों के लिए मेरी पहुंच का स्तर है जो वर्तमान एजेंट के लिए चाबियाँ हैं!)
00prometheus

5

मैं चीजों को यथासंभव सरल रखना पसंद करता हूं: (से स्निपेट ~/.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
}

मैंने -aपहले इस्तेमाल करने के बारे में नहीं सोचा था , लेकिन यह आसान हो सकता है:

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

अच्छा लगा। मैंने अपने उत्तर (नीचे) में इसे कुछ हद तक सरल किया है।
ईथर

2

मेरे मामले में मेरे पास PowerShell में पॉश-गिट सेटअप है और वह उसी ssh- एजेंट का उपयोग करने के लिए cygwin चाहता था। मुझे कुछ रास्ते में हेरफेर करना पड़ा क्योंकि वे अलग-अलग tmp फ़ोल्डरों का उपयोग करते हैं, और .env फ़ाइल बनाई गई UTF16 BOM और CR \ LF के साथ थी ताकि निपटने में मज़ा आए। निम्नलिखित काम को जोड़ना चाहिए।

# 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="${AUTH_SOCK/\/tmp/$SSH_AGENT_ENV}"
    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

फिर से अपने .bash_profile में डालने के लिए एक उदाहरण और लॉगऑन में अपनी डिफ़ॉल्ट कुंजी जोड़ने के लिए कह रहा है। मेरे मामले में अग्रेषण एक विकल्प नहीं था।

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

यह मेरा समाधान है, https://superuser.com/a/141233/5255 (इस धागे में) से अनुकूलित :

# 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

फ़ाइल बनाएं ~ / 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

फ़ाइल को .bashrc में शामिल करें

. ~/ssh-agent.sh

0

यह कुछ ऐसा है जो मैंने जोड़ा है जो मेरे लिए काम करता है। यह पहले यह देखने के लिए जांचता है कि क्या आपके पास एक एजेंट चल रहा है, यदि हाँ यह इसके लिए उचित वातावरण सेट करेगा, यदि यह इसे नहीं बनाएगा। अतिरिक्त एजेंट बनाने को भी समाप्त करता है:

बस अपने में डाल दिया .bashrc

function start_agent() {
    killall ssh-agent  2> /dev/null
    ssh-agent | sed 's/ Agent pid//' > $SSH_ENV
    . $SSH_ENV > $SSH_PID_FILE
    ssh-add ~/.ssh/bb_readonly_rsa 2> /dev/null
}

mkdir -p "$HOME/.ssh/agent"
SSH_ENV="$HOME/.ssh/agent/env"
SSH_PID_FILE="$HOME/.ssh/agent/pid"

if [[ -e $SSH_PID_FILE ]]; then
    SSH_PID=$(< $SSH_PID_FILE) 
    PROCESS=$(ps -p $SSH_PID -o comm=)

    if [[ $PROCESS == 'ssh-agent' ]]; then
        . $SSH_ENV > $SSH_PID_FILE
    else 
        start_agent
    fi  
else
    start_agent
fi

0

मैं इस समस्या पर एक भिन्नता रखता हूं, भी, सीधे मेरे .bashrc से लिया गया:

# File for storing SSH agent information
OSH=".agent.${HOSTNAME}"

# Test if an agent file exists
if [ -f ${OSH} ];

    # We have one, so let's use it
    then eval `cat ${OSH}` >/dev/null

else

    # No file exists, so we must spawn a new agent
    eval `ssh-agent | tee ${OSH}` >/dev/null

fi

# Try to list agent keys
ssh-add -l &>/dev/null

# Determine the agent status
case $? in

    # Current and SSH keys installed, nothing to do here
    0) ;;

    # Current but no SSH keys installed, so we must add them
    1) ssh-add ;;

    # Stale, so we must redo from scratch with a new agent, then add keys
    *) eval `ssh-agent | tee ${OSH}` >/dev/null && ssh-add ;;

esac

यह समाधान आपके होम डायरेक्टरी में SSH एजेंट की जानकारी की एक प्रति संग्रहीत करता है। यदि आपके पास एक NFS-automounted होम डाइरेक्टरी है जिसे कई होस्ट्स के बीच साझा किया जा सकता है, तो होस्टनाम का उपयोग उनके बीच अंतर करने के लिए फ़ाइलनाम के हिस्से के रूप में किया जाता है, इसलिए एक मशीन से लॉग इन करने पर एजेंट फ़ाइल को दूसरे के उपयोग में नहीं लाएगा।

व्यवहार:

1) पहली बार उपयोगकर्ता सत्र एक प्रमुख पासफ़्रेज़ के लिए संकेत दिया जाता है।

2) दूसरा-, तीसरा- और चौथा- (et cetera) सत्र पहले में जोड़े गए SSH एजेंट और कुंजी (इन) को विरासत में मिलाते हैं।

3) यदि एजेंट मारा जाता है या दुर्घटनाग्रस्त हो जाता है, तो पहले बाद का सत्र एक नया एजेंट बनाएगा, एजेंट फ़ाइल को नए के साथ अधिलेखित करेगा - और फिर से एक कुंजी पासफ़्रेज़ के लिए संकेत देगा। बाद में बनाए गए सत्र परिदृश्य 2 की तरह व्यवहार करेंगे), जब तक कि नया एसएसएच एजेंट चालू रहता है।


0

(यह पोस्ट 2 उच्चतर को संदर्भित करता है, मैं एक टिप्पणी जोड़ने में असमर्थ था)

@ आराघवन: आपका उदाहरण उपयोगी है, लेकिन जो दो पंक्तियाँ हैं, उन्हें बदलने का सुझाव देंगे

pgrep ssh- एजेंट

सेवा

pgrep -u $ USER ssh-Agent> / dev / null

ताकि केवल मौजूदा उपयोगकर्ता के तहत चलने वाले एजेंट मिलें, और स्क्रीन (क्लीनर) पर पीड गूंज न हो।

$ HOME / ssh-agent.out को $ HOME / .shsh-agent.out में बदलने का भी प्रयास करेंगे

सादर


0

मैंने आपके मूल समाधान और कई सुझाए गए लोगों को पढ़ा, लेकिन अपने स्वयं के उपयोग के लिए प्रक्रिया को सरल बनाने का निर्णय लिया। इसे मैंने अपने .bashrc में जोड़ा है:

    # get active ssh-agent, or launch new
    SSH_AGENT_PID=$(ps -fC ssh-agent | grep "ssh-agent -a ${HOME}/.ssh/ssh-agent-socket" | awk '{print $2}')
    if [ -z "${SSH_AGENT_PID}" ]; then
      # If there is no ssh-agent running, we'll make sure one hasn't left a socket file dangling
      rm ${HOME}/.ssh/ssh-agent-socket &> /dev/null
      # And of course start one
      eval $(ssh-agent -a ${HOME}/.ssh/ssh-agent-socket)
    else
      # We found a process matching our requirements, so sticking with that
      export SSH_AGENT_PID
      export SSH_AUTH_SOCK="${HOME}/.ssh/ssh-agent-socket"
    fi

मैंने यहाँ कुछ धारणाएँ बनाई हैं:

  • कि ~ / .ssh निर्देशिका मौजूद है।
  • आप सिस्टम पर प्रति उपयोगकर्ता केवल एक ssh- एजेंट सॉकेट चाहते हैं।
  • कि गृह पर्यावरण चर सेट है (क्योंकि यह क्यों नहीं होगा, ठीक है?)।
  • कि आप मैन्युअल रूप से एक स्थिति को संभालेंगे जहां एक प्रक्रिया चल रही है, लेकिन यह किसी कारण से निर्दिष्ट सॉकेट फ़ाइल का उपयोग नहीं करता है।

सब सब मुझे लगता है कि यह एक सरल समाधान की तरह लगता है।


0

मैंने पाया कि मेरे पास अक्सर कई ssh-agentप्रक्रियाएं चल रही थीं , और यह कि सॉकेट फाइलनाम के अंदर पीआईडी ​​वास्तव में चलने वाले पीआईडी ​​से मेल नहीं खाती थी ssh-agent, इसलिए मैंने ऊपर की कई मिसालों के आधार पर इन स्थितियों से उबरने की कोशिश करने के लिए कुछ हैक किया।

यह एक एकल फ़ंक्शन है, यह उपयोगकर्ता आईडी के लिए एक ज़ेड चर का उपयोग करता है यदि यह वहां है, और थोड़ा अधिक /tmpप्रतिबंधित करके संभवतः विशाल निर्देशिकाओं को पार्स करने में कम समय बिताने की कोशिश करता है find(1)

यह शायद अभी भी त्रुटि-प्रवण और दृढ़ है, लेकिन कुछ सरसरी परीक्षण यह दर्शाता है कि यह ज्यादातर मेरे उपयोग के मामलों के लिए काम करता है, इसलिए यहां यह है:

संलग्न_श_जेंट () {
  अगर [-n "$ SSH_AGENT_PID"]; फिर
    ssh-add -l> / dev / null
    सेवानिवृत्त = $?
    अगर [$ $ -2 2]; फिर
      इको "एजेंट पीआईडी ​​$ SSH_AGENT_PID उपयोगी से कम है (रिट = $ रिट) - हत्या ..."
      $ SSH_AGENT_PID को मारें
      $ SSH_AGENT_PID को परेशान करें
    एलीफ [$ रिट = 1]; फिर
      इको "एजेंट पीआईडी ​​$ SSH_AGENT_PID उपयोगी (रिट = $ रिट) से कम है - यह बीज होगा ..."
    अन्य
      इको "एजेंट पीड $ SSH_AGENT_PID"
      वापसी
    फाई
  फाई
  अगर [-S "$ SSH_AUTH_SOCK"]; फिर
    ssh-add -l> / dev / null
    सेवानिवृत्त = $?
    अगर [$ रिट = 2]; फिर
      इको "सॉकेट $ SSH_AUTH_SOCK मर चुका है - हटा रहा है ..."
      rm -f $ SSH_AUTH_SOCK
      SSH_AUTH_SOCK को परेशान करें
    एलीफ [$ रिट = 1]; फिर
      इको "सॉकेट $ SSH_AUTH_SOCK एक एजेंट को बिना किसी कुंजी के इंगित करता है ..."
      ssh-ऐड
    अन्य
      इको "एसएसएच-एजेंट $ SSH_AUTH_SOCK (रिट = $ रिट)" मिला
      वापसी
    फाई
  फाई
  $ में sf के लिए (ढूँढें / tmp / -mindepth 2 -maxdepth 2 -uid $ {UID: - $ (id -u)} -path '/tmp/ssh-*/agent.*_type s); करना
    परीक्षण -r $ sf || जारी रखें
    SSH_AUTH_SOCK = $ sf निर्यात करें
    SSH_AGENT_PID = $ (basename $ SSH_AUTH_SOCK | कट -d -ff)।
    # अन्य प्रक्रिया कांटे, अर्घ के साथ दौड़
    कोशिश = 50
    जबकि [$ कोशिश -२ ०]; करना
      कोशिश = $ (($ कोशिश -1))
      निर्यात SSH_AGENT_PID = $ (($ SSH_AGENT_PID + 1))
      इको "परीक्षण $ SSH_AUTH_SOCK -> $ SSH_AGENT_PID"
      ssh_agent_running = $ (ps -u $ USER | grep ssh-agent)
      अगर [-z "$ ssh_agent_running"]; फिर
        इको "सॉकेट $ SSH_AUTH_SOCK में किसी भी रनिंग एजेंट का लिंक नहीं है - हटा रहा है ..."
        rm -f $ SSH_AUTH_SOCK
        जारी रखें
      फाई
      अगर गूंज "$ ssh_agent_running" | \
           awk '$ 1 ==' $ SSH_AGENT_PID '{
                  = 1 पाया;
                  बाहर निकलने के (0);
              }
              समाप्त {
                  अगर मिल गया) {
                      प्रिंट "PID '$ SSH_AGENT_PID' नहीं मिला;"
                      बाहर निकलने के (1);
                  }
              } '; फिर
        ssh-add -l> / dev / null
        सेवानिवृत्त = $?
        अगर [$ $ -2 2]; फिर
          इको "सॉकेट $ SSH_AUTH_SOCK में $ SSH_AGENT_PID के उपयोगी एजेंट का लिंक नहीं है - हटा रहा है ..."
          rm -f $ SSH_AUTH_SOCK
          $ SSH_AGENT_PID को मारें
          SSH_AGENT_PID को परेशान करें
          जारी रखें २
        एलीफ [$ रिट = 1]; फिर
          इको "सॉकेट $ SSH_AUTH_SOCK में $ SSH_AGENT_PID - बोने ..." से कम उपयोगी एजेंट की लिंक शामिल है।
          ssh-ऐड
          अगर ! ssh-add -l> / dev / null; फिर
            इको "सॉकेट $ SSH_AUTH_SOCK में अभी भी $ SSH_AGENT_PID में उपयोगी एजेंट से कम लिंक है - गर्भपात।"
            वापसी
          अन्य
            टूटना
          फाई
        अन्य
          टूटना
        फाई
      अन्य
# गूंज "सॉकेट $ SSH_AUTH_SOCK से एजेंट PID $ SSH_AGENT_PID से मेल नहीं खा सकता है - लंघन ..."
        जारी रखें
      फाई
    किया हुआ
    अगर [$ कोशिश -२ ०]; फिर
      इको "एसएसएच-एजेंट $ SSH_AUTH_SOCK मिला"
      इको "एजेंट पीड $ SSH_AGENT_PID"
      वापसी
    फाई
  किया हुआ
  अगर [-n "$ try" -a -n "$ SSH_AUTH_SOCK" -a -n "$ ssh_agent_running"]; फिर
    इको "हमने कई बार कोशिश की, लेकिन $ SSH_AUTH_SOCK को किसी भी चल रहे एजेंट से मेल नहीं कर सका, s_2
    गूंज "$ ssh_agent_running"
    इको "इन बचे हुए को पीछे छोड़कर एक नया एजेंट शुरू करना ..."
  फाई
  eval $ (ssh-Agent -t 28800)
  ssh-ऐड
}

0

यहाँ इस पर मेरी स्पिन है। मैं अपने .bash_profile से नीचे की स्क्रिप्ट को ' स्रोत ' :

MYAGENTS=(`pgrep -U $USER -f ^ssh-agent$|sort -n`)

echo "Found ${#MYAGENTS[@]} ssh-agents."

# Let's try to take over the agents, like we do everynight Pinky!
if [[ "${MYAGENTS[@]}" ]];then
  KEEPER=${MYAGENTS[0]}
  echo KEEPER: $KEEPER
  OUTCAST=${MYAGENTS[@]:1}
  [[ "$OUTCAST" ]] && { echo "Goodbye agent $OUTCAST"; kill $OUTCAST; }
  SSH_AUTH_SOCK=`awk '/tmp\/ssh/ {print $NF}' /proc/$KEEPER/net/unix`
  export SSH_AUTH_SOCK;
  SSH_AGENT_PID=$KEEPER; export SSH_AGENT_PID;
else
  NEWAGENT="`ssh-agent`"
  echo $NEWAGENT;
  eval $NEWAGENT
fi

ssh-add -l | grep "The agent has no identities" && ssh-add

0

यहाँ एक सरल स्क्रिप्ट है जो हमेशा उसी ssh- एजेंट का उपयोग करेगा, या ssh- एजेंट को शुरू करेगा यदि वह नहीं चल रहा है। कुंजी एक -aही सॉकेट नाम का उपयोग करने के लिए विकल्प का उपयोग करना है। अन्यथा, डिफ़ॉल्ट रूप से यह हर बार एक यादृच्छिक सॉकेट नाम का चयन करेगा। आप इन 3 लाइनों को 1 पंक्ति के उपनाम के रूप में भी आसानी से जोड़ सकते हैं।

# set SSH_AUTH_SOCK env var to a fixed value
export SSH_AUTH_SOCK=~/.ssh/ssh-agent.sock

# test whether $SSH_AUTH_SOCK is valid
ssh-add -l 2>/dev/null >/dev/null

# if not valid, then start ssh-agent using $SSH_AUTH_SOCK
[ $? -ge 2 ] && ssh-agent -a "$SSH_AUTH_SOCK" >/dev/null

स्रोत

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.