Начать 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

еще раз спасибо