Совместное использование одного и того же ssh-агента среди нескольких сеансов входа
33481
intuited
Есть ли удобный способ гарантировать, что все логины от данного пользователя (т.е. меня) используют один и тот же ssh-agent? Я взломал сценарий, чтобы сделать эту работу большую часть времени, но я все время подозревал, что есть какой-то способ сделать это, что я только что пропустил. Кроме того, с тех пор были достигнуты удивительные достижения в области компьютерных технологий, как, например, этот веб-сайт.
Итак, цель в том, чтобы
всякий раз, когда я вхожу в ящик, независимо от того, идет ли он через SSH, или в графическом сеансе, запущенном из gdm / kdm / etc, или в консоли:
если мое имя пользователя в данный момент не ssh-agentзапущено, оно запускается, переменные среды экспортируются, иssh-add вызываются.
в противном случае координаты существующего агента экспортируются в переменные среды сеанса входа в систему.
Это средство особенно ценно, когда рассматриваемый ящик используется как точка ретрансляции при sshвходе в третий ящик. В этом случае он избегает необходимости вводить парольную фразу закрытого ключа каждый раз, когда вы вводите 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;
Пожалуйста, скажите мне, что есть лучший способ сделать это. Также, пожалуйста, не придирайтесь к несоответствиям / оплошностям (например, добавляя varвещи etc); Я написал это некоторое время назад и с тех пор многому научился.
KeyError: «DWTFYWT» не найден; Вы имели в виду [WTFPLv2] (http://sam.zoy.org/wtfpl/)?
grawity 14 лет назад
1
@ Grawity: спасибо за эту ссылку, их часто задаваемые вопросы сделали мой день: ** Кстати, с WTFPL, я могу также ... ** * О, да, конечно, вы можете. * ** Но я могу ... ** * Да, вы можете. * ** Может ... ** * Да! * Хахахахахаха
quack quixote 14 лет назад
0
@ Grawity: Нет, это именно то, что я хотел, чтобы вы думали, мвахахаха.
intuited 14 лет назад
0
Я думаю, что это может быть то, что вы ищете. Используйте ключ -A при запуске ssh forward вашего ssh-agent. Вот пример использования:
У меня есть удаленный сервер, на котором есть некоторые git-репозитории с удаленным указателем на github. Без ssh-agent, запущенного в сеансе экрана, я должен ввести ключевую фразу для моего ключа, чтобы сделать «мастер происхождения git pull». Booo! Кроме того, на удаленном сервере должен быть установлен мой закрытый ключ - больше Boooo!
Вместо этого, просто используя ssh -A [user@]remotehostпроходы по моему локально работающему ssh-agent. Теперь мне больше не нужен мой личный ключ, чтобы существовать даже на удаленном хосте. Я не верю, что вам нужно делать какие-либо скрипты с ssh-agent.
Это то, что я искал, спасибо!
tmow 13 лет назад
2
Не знал об этом, но оказалось, что это именно то, что я искал, когда подошел к этому вопросу.
Will McCutchen 12 лет назад
3
Это даже лучше, чем я искал! Отличный ответ!
WhyNotHugo 11 лет назад
1
Смотрите также `man 5 ssh_config` для настройки конфигурации` ForwardAgent`. По умолчанию он включает переадресацию агента, устраняя необходимость в аргументе `-A`. Перед использованием переадресации агентов следует помнить, что существует угроза безопасности, когда другие привилегированные пользователи на удаленном компьютере могут получить доступ к перенаправленному сокету агента. Это также упоминается на странице руководства. Это хорошо объяснено [здесь] (http://www.symantec.com/connect/articles/ssh-and-ssh-agent).
starfry 10 лет назад
1
24
Zed
С таким же успехом я мог бы добавить свой вариант:
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.
`если [! -x "$ (которое ssh-add)"]; `следует заменить на` if! который ssh-add; `или` if! команда -v ssh-add`. (Помните, `[` это просто команда)
grawity 14 лет назад
2
Ну, вы можете сделать это, но на самом деле это должно быть `if! который ssh-add> / dev / null` для предотвращения печати пути, и в этот момент я не совсем уверен, что он более понятен, хотя, полагаю, это сэкономит вам один дополнительный вызов команды.
Zed 14 лет назад
0
так что в основном ответ - нет. дерьмо. Ну, это выглядит более развитым, чем мой хак, поэтому, вероятно, это будет полезно. Странно, что нет более структурированного способа сделать это, хотя, кажется, что-то, что было бы весьма полезно.
intuited 14 лет назад
0
Сейчас я нахожусь в порыве репозиториев, поэтому я настроил [github repo] (http://github.com/intuited/sshag) для вашего сценария. Еще раз спасибо. Я надеюсь, что я был достаточно формален с лицензированием: ~ /
intuited 14 лет назад
0
Я не против Пожалуйста, прокомментируйте здесь, если кто-то представит улучшения, хотя.
Zed 14 лет назад
0
In my case I could have multiple agent socket files. To always use the latest one (by timestamp) I modified the above find command to this: `find /tmp -uid $(id -u) -type s -printf '%Ts\t%p\n' -name agent.\* 2>/dev/null | sort -nr | cut -f2`
Dirk Gorissen 8 лет назад
0
Как сказал Кев: попробуйте использовать брелок, он создан для этого. Но еще лучше, делай то, что сказал MarkMo!
00prometheus 8 лет назад
0
https://github.com/intuited/sshag/pull/1 "используйте` sshag user @ domain` вместо `ssh user @ domain`". Протестировано на Linux и Git-for-Windows (MSYS2).
go2null 7 лет назад
0
20
vonhogen
Вот довольно хороший, который работает и в Cygwin:
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
Также хорошо работает с Git Bash (mingw64) для Windows
Dolphin 8 лет назад
0
`$ ` должен быть `" $ "`, если в вашем имени пользователя Windows есть пробел
rgvcorley 7 лет назад
1
Этот ответ, кажется, скачет по интернету. Здесь он находится в [гораздо большем потоке stackoverflow] (https://stackoverflow.com/a/18915067/4970632). Лучший / самый простой подход ИМХО.
Luke Davis 6 лет назад
0
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-идент это фантастика! Он разблокирует ключ и загружает агент, когда я пытаюсь выполнить ssh, вместо того, чтобы разблокировать ключ заранее. Это делает ключевые тайм-ауты полезными. Что еще более важно, он хранит мои агенты отдельно для разных целей (серьезная угроза безопасности; у root на одной машине мой уровень доступа ко всем остальным машинам, для которых у текущего агента есть ключи!)
00prometheus 8 лет назад
0
5
grawity
Я предпочитаю сделать вещи максимально простыми: (фрагмент из ~/.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раньше, но это может быть проще:
Ницца. Я несколько упростил это в своем ответе (ниже).
Ether 9 лет назад
0
2
Greg Bray
В моем случае у меня есть шикарно-ГИТ установка в 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="$" 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
Снова пример для немедленного добавления вашего .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
# 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
create file ~/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