Начать ssh-agent при входе в систему
У меня есть сайт в качестве удаленного репозитория Git с Bitbucket.com с использованием псевдонима SSH. Я могу вручную запустить ssh-agent на моем сервере, но я должен делать это каждый раз, когда я вхожу в систему через SSH.
Я вручную запускаю ssh-agent:
eval ssh-agent $SHELL
Затем я добавляю агента:
ssh-add ~/.ssh/bitbucket_id
Затем он появляется, когда я делаю:
ssh-add -l
И я готов идти. Есть ли способ автоматизировать этот процесс, поэтому мне не нужно делать это каждый раз, когда я вхожу в систему? На сервере работает RedHat 6.2 (Сантьяго).
Ответы
Ответ 1
Пожалуйста, просмотрите эту статью. Вы можете найти это очень полезным:
http://mah.everybody.org/docs/ssh
На случай, если однажды вышеприведенная ссылка исчезнет, я запишу основную часть решения ниже:
Это решение от Джозефа М. Рейгла с помощью Дэниела Старина:
Добавьте это в свой .bash_profile
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} does not work under cywgin
ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
start_agent;
}
else
start_agent;
fi
Эта версия особенно хороша, поскольку она увидит, запустили ли вы уже ssh-agent, и, если он не может его найти, запустит его и сохранит настройки, чтобы их можно было использовать в следующий раз, когда вы запустить оболочку.
Ответ 2
В Arch Linux следующие работы действительно великолепны (должны работать на всех дистрибутивах на основе systemd):
Создайте сервисную службу systemd, поместив следующее в ~/.config/systemd/user/ssh-agent.service
:
[Unit]
Description=SSH key agent
[Service]
Type=forking
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
ExecStart=/usr/bin/ssh-agent -a $SSH_AUTH_SOCK
[Install]
WantedBy=default.target
Установите оболочку, чтобы иметь переменную окружения для сокета (.bash_profile, .zshrc, ...
):
export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"
Включить службу, чтобы она запускалась автоматически при входе в систему и запускала ее:
systemctl --user enable ssh-agent
systemctl --user start ssh-agent
Добавьте следующий конфигурационный параметр в ваш конфигурационный файл ssh ~/.ssh/config
(это работает с SSH 7.2):
AddKeysToAgent yes
Это даст указание клиенту ssh всегда добавлять ключ к запущенному агенту, поэтому нет необходимости предварительно его добавлять в ssh.
Ответ 3
Старый вопрос, но я сталкивался с подобной ситуацией. Не думайте, что приведенный выше ответ полностью достигает того, что необходимо. Недостающий кусок - keychain
; установите его, если это еще не сделано.
sudo apt-get install keychain
Затем добавьте следующую строку в ваш ~/.bashrc
eval $(keychain --eval id_rsa)
Это запустит ssh-agent
если он не запущен, подключится к нему, если он есть, загрузит переменные среды ssh-agent
в вашу оболочку и загрузит ключ ssh.
Измените id_rsa
на любой закрытый ключ в ~/.ssh
вы хотите загрузить.
Ссылка
https://unix.stackexchange.com/questions/90853/how-can-i-run-ssh-add-automatically-without-password-prompt
Ответ 4
Принятое решение имеет следующие недостатки:
- это сложно поддерживать;
- оценивает файл хранилища, который может привести к ошибкам или нарушениям безопасности;
- он запускает агент, но не останавливает его, что близко к тому, чтобы оставить ключ в замке зажигания.
Если ваши ключи не требуют ввода пароля, я предлагаю следующее решение. Добавьте в свой .bash_profile
конец > (перейдите в список ключевых слов):
exec ssh-agent $BASH -s 10<&0 << EOF
ssh-add ~/.ssh/your_key1.rsa \
~/.ssh/your_key2.rsa &> /dev/null
exec $BASH <&10-
EOF
Он имеет следующие преимущества:
- гораздо более простое решение;
- сеанс агента завершается, когда заканчивается сеанс bash.
У него есть возможные недостатки:
- interactive
ssh-add
команда будет влиять только на один сеанс, что фактически является проблемой только в очень нетипичных обстоятельствах;
- неприменимо, если требуется ввести пароль;
- начальная оболочка становится недействительной (что не влияет на AFAIK).
Обратите внимание, что несколько процессов ssh-agent
не являются недостатком, поскольку они не занимают больше памяти или процессорного времени.
Ответ 5
Добавьте это к вашему ~/.bashrc
, затем выйдите из системы и снова ~/.bashrc
, чтобы вступить в силу.
if [ ! -S ~/.ssh/ssh_auth_sock ]; then
eval 'ssh-agent'
ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock
ssh-add -l > /dev/null || ssh-add
Это должно запрашивать пароль только при первом входе в систему после каждой перезагрузки. Он будет продолжать использовать один и тот же ssh-agent
пока он работает.
Ответ 6
Итак, я использовал описанные выше подходы, но я предпочитаю, чтобы агент умер, когда закончится мой последний сеанс bash. Это немного дольше, чем другие решения, но мой предпочтительный подход. Основная идея заключается в том, что первый сеанс bash запускает ssh-agent. Затем каждый дополнительный сеанс bash проверяет файл конфигурации (~/.ssh/.agent_env
). Если это так, и есть сеанс, затем укажите среду и создайте жесткую ссылку на файл сокета в /tmp
(должен находиться в той же файловой системе, что и исходный файл сокета). Поскольку bash сеансы завершаются, каждый из них удаляет свою собственную жесткую ссылку. В последнем сеансе будет обнаружено, что жесткие ссылки имеют 2 ссылки (жесткая ссылка и оригинал), удаление процессов собственного сокета и уничтожение процесса приведет к 0, оставив чистую среду после закрытия последнего сеанса bash.
# Start ssh-agent to keep you logged in with keys, use `ssh-add` to log in
agent=`pgrep ssh-agent -u $USER` # get only your agents
if [[ "$agent" == "" || ! -e ~/.ssh/.agent_env ]]; then
# if no agents or environment file is missing create a new one
# remove old agents / environment variable files
kill $agent running
rm ~/.ssh/.agent_env
# restart
eval `ssh-agent`
echo 'export SSH_AUTH_SOCK'=$SSH_AUTH_SOCK >> ~/.ssh/.agent_env
echo 'export SSH_AGENT_PID'=$SSH_AGENT_PID >> ~/.ssh/.agent_env
fi
# create our own hardlink to the socket (with random name)
source ~/.ssh/.agent_env
MYSOCK=/tmp/ssh_agent.${RANDOM}.sock
ln -T $SSH_AUTH_SOCK $MYSOCK
export SSH_AUTH_SOCK=$MYSOCK
end_agent()
{
# if we are the last holder of a hardlink, then kill the agent
nhard=`ls -l $SSH_AUTH_SOCK | awk '{print $2}'`
if [[ "$nhard" -eq 2 ]]; then
rm ~/.ssh/.agent_env
ssh-agent -k
fi
rm $SSH_AUTH_SOCK
}
trap end_agent EXIT
set +x
Ответ 7
Просто добавим еще одно решение: P, я пошел с комбинацией решений @spheenik и @collin-anderson.
# Ensure that we have an ssh config with AddKeysToAgent set to true
if [ ! -f ~/.ssh/config ] || ! cat ~/.ssh/config | grep AddKeysToAgent | grep yes > /dev/null; then
echo "AddKeysToAgent yes" >> ~/.ssh/config
fi
# Ensure a ssh-agent is running so you only have to enter keys once
if [ ! -S ~/.ssh/ssh_auth_sock ]; then
eval `ssh-agent`
ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock
Может быть немного более элегантным, но простым и понятным. Это решение:
- гарантирует, что
AddKeysToAgent yes
находится в вашей конфигурации ssh, поэтому ключи будут автоматически добавлены при использовании
- не запрашивает ввести какие-либо парольные фразы при входе в систему (опять же, при первом использовании вводится однократная вводная фраза)
- тихо запускает ssh-agent, если он еще не запустил
Комментарии приветствуются:)
Ответ 8
Я решил это, добавив это в /etc/profile - system wide (или в локальный .profile пользователя или .bash_profile).
# SSH-AGENT
#!/usr/bin/env bash
SERVICE='ssh-agent'
WHOAMI=`who am i |awk '{print $1}'`
if pgrep -u $WHOAMI $SERVICE >/dev/null
then
echo $SERVICE running.
else
echo $SERVICE not running.
echo starting
ssh-agent > ~/.ssh/agent_env
fi
. ~/.ssh/agent_env
Это запускает новый ssh-агент, если он не выполняется для пользователя, или перезагружает параметр env sv-agent при запуске.
Ответ 9
Извините за опоздание:
Пользователи fish shell могут использовать этот script сделать то же самое.
# content has to be in .config/fish/config.fish
# if it does not exist, create the file
setenv SSH_ENV $HOME/.ssh/environment
function start_agent
echo "Initializing new SSH agent ..."
ssh-agent -c | sed 's/^echo/#echo/' > $SSH_ENV
echo "succeeded"
chmod 600 $SSH_ENV
. $SSH_ENV > /dev/null
ssh-add
end
function test_identities
ssh-add -l | grep "The agent has no identities" > /dev/null
if [ $status -eq 0 ]
ssh-add
if [ $status -eq 2 ]
start_agent
end
end
end
if [ -n "$SSH_AGENT_PID" ]
ps -ef | grep $SSH_AGENT_PID | grep ssh-agent > /dev/null
if [ $status -eq 0 ]
test_identities
end
else
if [ -f $SSH_ENV ]
. $SSH_ENV > /dev/null
end
ps -ef | grep $SSH_AGENT_PID | grep -v grep | grep ssh-agent > /dev/null
if [ $status -eq 0 ]
test_identities
else
start_agent
end
end
Ответ 10
Как и ваши ответы. Это упростило работу с cygwin / linux
хостами. Я объединил функции запуска и завершения, чтобы обеспечить безопасность.
SSH_ENV="$HOME/.ssh/.agent_env"
function start_agent {
echo "Initialising new SSH agent..."
eval `/usr/bin/ssh-agent`
echo 'export SSH_AUTH_SOCK'=$SSH_AUTH_SOCK >> ${SSH_ENV}
echo 'export SSH_AGENT_PID'=$SSH_AGENT_PID >> ${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 -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
start_agent;
}
else
start_agent;
fi
# create our own hardlink to the socket (with random name)
MYSOCK=/tmp/ssh_agent.${RANDOM}.sock
ln -T $SSH_AUTH_SOCK $MYSOCK
export SSH_AUTH_SOCK=$MYSOCK
end_agent()
{
# if we are the last holder of a hardlink, then kill the agent
nhard=`ls -l $SSH_AUTH_SOCK | awk '{print $2}'`
if [[ "$nhard" -eq 2 ]]; then
rm ${SSH_ENV}
/usr/bin/ssh-agent -k
fi
rm $SSH_AUTH_SOCK
}
trap end_agent EXIT
set +x
еще раз спасибо