การแชร์ 'ssh-agent' เดียวกันระหว่างการเข้าสู่ระบบหลายครั้ง


61

มีวิธีที่สะดวกเพื่อให้แน่ใจว่าการเข้าสู่ระบบทั้งหมดจากผู้ใช้ที่ได้รับ (เช่นฉัน) ใช้ ssh-agent เดียวกันหรือไม่? ฉันแฮกสคริปต์เพื่อให้งานนี้ใช้เวลาส่วนใหญ่ แต่ฉันสงสัยว่าตลอดมีวิธีที่จะทำสิ่งที่ฉันเพิ่งพลาด นอกจากนี้ตั้งแต่นั้นมามีความก้าวหน้าอย่างมากในด้านเทคโนโลยีคอมพิวเตอร์เช่นเว็บไซต์นี้

ดังนั้นเป้าหมายที่นี่ก็คือ

  • เมื่อใดก็ตามที่ฉันเข้าสู่กล่องไม่ว่าจะผ่าน SSH หรือในเซสชันกราฟิกเริ่มต้นจาก gdm / kdm / etc หรือที่คอนโซล:
    • หากชื่อผู้ใช้ของฉันไม่มีการssh-agentทำงานอยู่ในขณะนี้หนึ่งจะเริ่มต้นตัวแปรสภาพแวดล้อมที่ส่งออกและssh-addเรียกว่า
    • มิฉะนั้นพิกัดของตัวแทนที่มีอยู่จะถูกส่งออกในตัวแปรสภาพแวดล้อมของเซสชันการเข้าสู่ระบบ

สิ่งอำนวยความสะดวกนี้มีค่าโดยเฉพาะอย่างยิ่งเมื่อใช้กล่องที่เป็นปัญหาเป็นจุดถ่ายทอดเมื่อsshเข้าไปในกล่องที่สาม ในกรณีนี้มันหลีกเลี่ยงการพิมพ์ข้อความรหัสผ่านของไพรเวตคีย์ทุกครั้งที่คุณทำเช่นนั้นgit pushหรือต้องการทำอะไรบางอย่าง

สคริปต์ที่ให้ไว้ด้านล่างทำสิ่งนี้ได้อย่างน่าเชื่อถือแม้ว่ามันจะไม่เรียบร้อยเมื่อ X เกิดข้อผิดพลาดและฉันก็เริ่มเซสชั่นกราฟิกอื่น ในกรณีนั้นอาจมีความรุนแรงอื่น ๆ เกิดขึ้น

นี่คือสคริปต์ที่ไม่ดีของฉัน ฉันมาจากที่.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;

โปรดบอกฉันว่ามีวิธีที่ดีกว่าในการทำเช่นนี้ นอกจากนี้โปรดอย่า nitpick ความไม่สอดคล้อง / gaffes (เช่นใส่varสิ่งของetc) ฉันเขียนเมื่อไม่นานมานี้และเรียนรู้หลายสิ่งหลายอย่างตั้งแต่นั้นมา


1
KeyError: ไม่พบ 'DWTFYWT' หมายถึงWTFPLv2หรือเปล่า
grawity

@grawity: ขอบคุณสำหรับลิงค์นั้นคำถามที่พบบ่อยของพวกเขาทำให้วันของฉัน: โดยวิธีการที่มี WTFPL ฉันสามารถ ... ยัง โอ้ แต่ใช่แน่นอนคุณสามารถ แต่ฉันจะ… ใช่คุณทำได้ ทำได้…ได้ ! hahahahahaha
ต้มตุ๋น quixote

@grawity: ไม่นั่นเป็นเพียงสิ่งที่ฉันต้องการให้คุณคิด mwahahaha
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ป้องกันไม่ให้มีการพิมพ์พา ธ ซึ่ง ณ จุดนี้ฉันไม่แน่ใจว่ามันชัดเจนกว่านี้ แต่ฉันคิดว่ามันช่วยให้คุณประหยัดคำสั่งพิเศษได้
Zed

ดังนั้นโดยทั่วไปคำตอบคือไม่แล้ว อึ. ดูเหมือนว่านี่จะมีวิวัฒนาการมากกว่าแฮ็คของฉันดังนั้นอาจเป็นประโยชน์ แปลกที่ไม่มีวิธีการที่มีโครงสร้างมากขึ้นในการทำเช่นนี้ แต่ดูเหมือนว่าบางสิ่งบางอย่างที่จะมีประโยชน์มาก
สัญชาตญาณ

ฉันอยู่ในสภาพที่น่าเชื่อถือทุกอย่างในวันนี้ดังนั้นฉันจึงตั้งrepo gitHubสำหรับสคริปต์ของคุณ ขอบคุณอีกครั้ง. ฉันหวังว่าฉันเป็นทางการมากพอที่จะให้สิทธิ์ใช้งาน: ~ /
intuited

ฉันไม่รังเกียจ โปรดแสดงความคิดเห็นที่นี่หากมีคนส่งการปรับปรุง
เซด

36

ssh -A [user@]remotehost

ฉันคิดว่านี่อาจเป็นสิ่งที่คุณกำลังมองหา ใช้สวิตช์ -A เมื่อเรียกใช้ ssh ไปข้างหน้า ssh-agent ของคุณ นี่คือ usecase:

ฉันมีเซิร์ฟเวอร์ระยะไกลที่มี repos คอมไพล์อยู่กับรีโมตที่ชี้ไปที่ gitub หากไม่มีเอสเอส - เอเจนต์ที่ทำงานในหน้าจอฉันต้องป้อนข้อความรหัสผ่านสำหรับคีย์ของฉันเพื่อที่จะทำ "ต้นแบบต้นกำเนิดดึง git" Booo! นอกจากนี้ฉันต้องมีรหัสส่วนตัวของฉันติดตั้งบนเซิร์ฟเวอร์ระยะไกล - Boooo มากขึ้น!

ให้ใช้การssh -A [user@]remotehostส่งผ่านตามตัวแทนในท้องถิ่นของฉัน ตอนนี้ฉันไม่ต้องการกุญแจส่วนตัวของฉันอีกต่อไปที่จะมีอยู่บนโฮสต์ระยะไกล ฉันไม่เชื่อว่าคุณต้องทำสคริปต์ใด ๆ เลยกับ ssh-agent


4
ไม่ทราบเกี่ยวกับเรื่องนี้ แต่มันกลับกลายเป็นว่าสิ่งที่ฉันกำลังมองหาเมื่อฉันทำเพื่อคำถามนี้
Will McCutchen

1
นี่เป็นสิ่งที่ดียิ่งกว่าสิ่งที่ฉันกำลังมองหา! คำตอบที่ดี!
WhyNotHugo

1
ดูเพิ่มเติมman 5 ssh_configสำหรับการForwardAgentตั้งค่า ช่วยให้ตัวแทนการส่งต่อโดยค่าเริ่มต้นเอาความต้องการ-Aอาร์กิวเมนต์ ก่อนที่จะใช้ตัวแทนการส่งต่อโปรดทราบว่ามีความเสี่ยงด้านความปลอดภัยที่ผู้ใช้สิทธิพิเศษอื่น ๆ ในเครื่องระยะไกลสามารถเข้าถึงซ็อกเก็ตตัวแทนส่งต่อ นี่คือยังกล่าวถึงในหน้าคน นี้จะอธิบายได้ดีที่นี่
starfry

ผมคิดว่าเป็นตัวเลือกที่ AllowAgentForwarding จะต้องตั้งค่าใช่บนเซิร์ฟเวอร์แม้ว่า
Ziofil

20

นี่เป็นสิ่งที่ดีงามที่ทำงานใน Cygwin เช่นกัน:

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) สำหรับ windows
โลมา

1
${SSH_ENV}ต้องเป็น"${SSH_ENV}"ถ้าชื่อผู้ใช้ windows ของคุณมีที่ว่างอยู่
rgvcorley

ดูเหมือนว่าคำตอบนี้จะตีกลับไปทั่วอินเทอร์เน็ต นี่มันอยู่บนด้าย StackOverflow ใหญ่มาก วิธีที่ดีที่สุด / ง่ายที่สุด IMHO
ลุคเดวิส


6

ฉันเพิ่งเริ่มใช้:

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

สิ่งที่ฉันต้องทำคือเพิ่ม:

  alias ssh=/path/to/ssh-ident

ในไฟล์. bashrc ของฉัน สคริปต์ดูแล:

  • การสร้างเอเจนต์เมื่อจำเป็นครั้งแรก
  • โหลดกุญแจที่จำเป็นตามต้องการ
  • แบ่งปันตัวแทนในช่วงการเข้าสู่ระบบหลายครั้ง
  • จัดการตัวแทนหลายตัวหนึ่งตัวสำหรับแต่ละ 'ตัวตน' ที่ฉันใช้ออนไลน์และใช้ตัวแทนที่ถูกต้องโดยยึดตามโฮสต์ที่ฉันกำลังเชื่อมต่อหรือไดเรกทอรีการทำงานปัจจุบัน

ssh-ident ยอดเยี่ยมมาก! มันปลดล็อคกุญแจและโหลดตัวแทนเมื่อฉันพยายาม 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

ในกรณีของฉันฉันมีการตั้งค่าposit-gitใน PowerShell และต้องการให้ cygwin ใช้ตัวแทน ssh เดียวกัน ฉันต้องจัดการเส้นทางบางอย่างเนื่องจากใช้โฟลเดอร์ tmp ที่แตกต่างกันและไฟล์. env ที่สร้างขึ้นนั้นเป็น UTF16 ที่มี BOM และ CR \ LF ดังนั้นมันจึงสนุกกับการจัดการ การเพิ่มสิ่งต่อไปนี้ใน. bashrc ที่ใช้โดย cygwin ควรทำงาน:

# 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 ที่อาจถูกแชร์ระหว่างหลาย ๆ โฮสต์, ชื่อโฮสต์จะถูกใช้เป็นส่วนหนึ่งของชื่อไฟล์เพื่อแยกความแตกต่างระหว่างพวกมัน, ดังนั้นการล็อกอินจากเครื่องหนึ่งจะไม่ปิดกั้นไฟล์ตัวแทนที่ใช้งานอยู่

พฤติกรรม:

1) เซสชันผู้ใช้ครั้งแรกจะได้รับพร้อมต์สำหรับวลีรหัสผ่านที่สำคัญ

2) เซสชันที่สองสามและสี่ (และอื่น ๆ ) สืบทอดเอเจนต์ SSH และคีย์ที่เพิ่มในครั้งแรก

3) หากเอเจนต์ถูกฆ่าหรือล้มเหลวเซสชันแรกที่ตามมาจะสร้างเอเจนต์ใหม่เขียนทับไฟล์เอเจนต์ด้วยอันใหม่ - และแจ้งให้ใส่คีย์รหัสผ่านอีกครั้ง เซสชันที่สร้างในภายหลังนั้นจะทำงานเหมือนสถานการณ์จำลอง 2) ตราบใดที่เอเจนต์ SSH ใหม่ยังคงทำงานอยู่


0

(นี่หมายถึงโพสต์ที่ 2 ที่สูงกว่าฉันไม่สามารถเพิ่มความคิดเห็น)

@raghavan: ตัวอย่างของคุณมีประโยชน์ แต่ขอแนะนำให้เปลี่ยนสองบรรทัดที่มี

pgrep ssh-agent

ไปยัง

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

เพื่อให้พบเฉพาะตัวแทนที่ทำงานภายใต้ผู้ใช้ปัจจุบันเท่านั้นและ pid ไม่ได้ถูกสะท้อนไปยังหน้าจอ (ตัวล้าง)

ยังจะ sugegst เปลี่ยน $ HOME / ssh-agent.out เป็น $ HOME / .ssh-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-agent ต่อผู้ใช้ในระบบ
  • มีการตั้งค่าตัวแปรสภาพแวดล้อม HOME (เพราะเหตุใดจึงไม่เป็นเช่นนั้น)
  • คุณจะจัดการกับสถานการณ์ที่มีกระบวนการทำงานด้วยตนเอง แต่ด้วยเหตุผลบางอย่างไม่ได้ใช้ไฟล์ซ็อกเก็ตที่กำหนด

โดยรวมแล้วฉันคิดว่ามันให้ความรู้สึกเหมือนเป็นทางออกที่ง่าย


0

ฉันพบว่าฉันมักจะมีssh-agentกระบวนการทำงานหลายอย่างและ PID ที่อยู่ในชื่อไฟล์ซ็อกเก็ตไม่ตรงกับ PID ของการทำงานssh-agentดังนั้นฉันจึงแฮ็กข้อมูลเพื่อพยายามกู้คืนจากเงื่อนไขเหล่านี้ตามตัวอย่างมากมายด้านบน

มันเป็นฟังก์ชั่นเดียวมันใช้ตัวแปร Zsh สำหรับ ID ผู้ใช้ถ้ามันอยู่ที่นั่นและพยายามที่จะใช้เวลาน้อยลงในการแยก/tmpไดเรกทอรีใหญ่ที่อาจเป็นไปได้ด้วยการ จำกัดfind(1)อีกเล็กน้อย

มันอาจจะยังคงเกิดข้อผิดพลาดได้ง่ายและซับซ้อน แต่การทดสอบคร่าวๆบางอย่างบ่งชี้ว่าส่วนใหญ่ใช้งานได้สำหรับกรณีการใช้งานของฉันดังนั้นที่นี่จะไป:

Attach_ssh_agent () {
  ถ้า [-n "$ SSH_AGENT_PID"]; แล้วก็
    ssh-add -l> / dev / null
    เกษียณ = $?
    ถ้า [$ ret -ge 2]; แล้วก็
      echo "Agent pid $ SSH_AGENT_PID มีประโยชน์น้อยกว่า (ret = $ ret) - กำลังฆ่า ... "
      ฆ่า $ SSH_AGENT_PID
      ยกเลิกการตั้งค่า $ SSH_AGENT_PID
    elif [$ ret = 1]; แล้วก็
      echo "Agent pid $ SSH_AGENT_PID มีประโยชน์น้อยกว่า (ret = $ ret) - จะทำการเพาะ ... "
    อื่น
      echo "Agent pid $ SSH_AGENT_PID"
      กลับ
    Fi
  Fi
  ถ้า [-S "$ SSH_AUTH_SOCK"]; แล้วก็
    ssh-add -l> / dev / null
    เกษียณ = $?
    ถ้า [$ ret = 2]; แล้วก็
      echo "ซ็อกเก็ต $ SSH_AUTH_SOCK นั้นตายแล้ว - กำลังลบ ... "
      rm -f $ SSH_AUTH_SOCK
      ยกเลิกการตั้งค่า SSH_AUTH_SOCK
    elif [$ ret = 1]; แล้วก็
      echo "ซ็อกเก็ต $ SSH_AUTH_SOCK ชี้ไปที่เอเจนต์โดยไม่มีคีย์ ... "
      SSH เพิ่ม
    อื่น
      echo "พบ ssh-agent $ SSH_AUTH_SOCK (ret = $ ret)"
      กลับ
    Fi
  Fi
  สำหรับเอสเอฟใน $ (หา / tmp / -mindepth 2 -maxdepth 2 -uid $ {UID: - $ (id -u)} -path '/tmp/ssh-*/agent.*' -type s); ทำ
    ทดสอบ -r $ sf || ต่อ
    ส่งออก SSH_AUTH_SOCK = $ sf
    SSH_AGENT_PID = $ (ชื่อฐาน $ SSH_AUTH_SOCK | cut -d. -f2)
    # แข่งกับส้อมกระบวนการอื่น ๆ argh
    ลอง = 50
    ในขณะที่ [$ ลอง -gt 0]; ทำ
      ลอง = $ (($ ลอง-1))
      ส่งออก SSH_AGENT_PID = $ (($ SSH_AGENT_PID + 1))
      echo "การทดสอบ $ SSH_AUTH_SOCK -> $ SSH_AGENT_PID"
      ssh_agent_running = $ (ps -u $ USER | grep ssh-agent)
      ถ้า [-z "$ ssh_agent_running"]; แล้วก็
        echo "ซ็อกเก็ต $ SSH_AUTH_SOCK ไม่มีลิงก์ไปยังเอเจนต์ที่กำลังรันอยู่ - กำลังลบ ... "
        rm -f $ SSH_AUTH_SOCK
        ต่อ
      Fi
      ถ้า echo "$ ssh_agent_running" | \
           awk '$ 1 ==' $ SSH_AGENT_PID '{
                  พบ = 1;
                  ออก (0);
              }
              END {
                  หาก (พบ!) {
                      พิมพ์ "ไม่พบการเรียกใช้ PID '$ SSH_AGENT_PID'";
                      ทางออก (1);
                  }
              } '; แล้วก็
        ssh-add -l> / dev / null
        เกษียณ = $?
        ถ้า [$ ret -ge 2]; แล้วก็
          echo "Socket $ SSH_AUTH_SOCK ไม่มีลิงก์ไปยังตัวแทนที่มีประโยชน์ที่ $ SSH_AGENT_PID - กำลังลบ ... "
          rm -f $ SSH_AUTH_SOCK
          ฆ่า $ SSH_AGENT_PID
          ยกเลิกการตั้งค่า SSH_AGENT_PID
          ดำเนินการต่อ 2
        elif [$ ret = 1]; แล้วก็
          echo "ซ็อกเก็ต $ SSH_AUTH_SOCK มีลิงก์ไปยังเอเจนต์ที่มีประโยชน์น้อยกว่าที่ $ SSH_AGENT_PID - การหยอด ... "
          SSH เพิ่ม
          ถ้า! ssh-add -l> / dev / null; แล้วก็
            echo "ซ็อกเก็ต $ SSH_AUTH_SOCK ยังคงมีลิงก์ไปยังเอเจนต์ที่มีประโยชน์น้อยกว่าที่ $ SSH_AGENT_PID - ยกเลิก"
            กลับ
          อื่น
            หยุดพัก
          Fi
        อื่น
          หยุดพัก
        Fi
      อื่น
# echo "ไม่สามารถจับคู่ซ็อกเก็ต $ SSH_AUTH_SOCK กับเอเจนต์ PID $ SSH_AGENT_PID - ข้าม ... "
        ต่อ
      Fi
    เสร็จแล้ว
    ถ้า [ลอง $ -gt 0]; แล้วก็
      echo "พบ ssh-agent $ SSH_AUTH_SOCK"
      echo "Agent pid $ SSH_AGENT_PID"
      กลับ
    Fi
  เสร็จแล้ว
  ถ้า [-n "$ ลอง" -a -n "$ SSH_AUTH_SOCK" -a -n "$ ssh_agent_running"]; แล้วก็
    echo "เราลองหลายครั้ง แต่ไม่สามารถจับคู่ $ SSH_AUTH_SOCK กับเอเจนต์ที่กำลังทำงานอยู่ถอนหายใจ"
    echo "$ ssh_agent_running"
    echo "ทิ้งสิ่งที่เหลือเหล่านี้ไว้ข้างหลังและเริ่มตัวแทนใหม่ ... "
  Fi
  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-agent เดิมอีกครั้งหรือเริ่ม ssh-agent อีกครั้งหากไม่ได้ทำงานอยู่ กุญแจสำคัญคือการใช้-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

แหล่ง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.