Запустите 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 (Сантьяго).

10 ответов

Решение

Пожалуйста, просмотрите эту статью. Вы можете найти это очень полезным:

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} doesn't work under cywgin
    ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
        start_agent;
    }
else
    start_agent;
fi

Эта версия особенно хороша, так как она увидит, запустили ли вы уже ssh-agent, и, если он не может его найти, запустит его и сохранит настройки, чтобы их можно было использовать при следующем запуске. ракушка.

В Arch Linux следующие функции работают очень хорошо (должны работать на всех системных дистрибутивах):

Создайте службу пользователя 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.

Старый вопрос, но я сталкивался с подобной ситуацией. Не думайте, что приведенный выше ответ полностью достигает того, что необходимо. Недостающий кусок 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

Добавьте это к вашему ~/.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 | grep "The agent has no identities" && ssh-add

Это должно запрашивать пароль только при первом входе в систему после каждой перезагрузки. Это будет продолжать использовать ssh-agent пока он работает.

Принятое решение имеет следующие недостатки:

  • это сложно поддерживать;
  • он оценивает файл хранилища, который может привести к ошибкам или нарушениям безопасности;
  • он запускает агента, но не останавливает его, что близко к оставлению ключа в замке зажигания.

Если ваши ключи не требуют ввода пароля, я предлагаю следующее решение. Добавьте следующее к вашему .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.

У него есть возможные недостатки:

  • интерактивный ssh-add командование будет влиять только на один сеанс, который на самом деле является проблемой только в очень нетипичных обстоятельствах;
  • невозможно использовать, если требуется ввод пароля;
  • Запущенная оболочка становится не авторизованной (что ни на что не влияет AFAIK).

Обратите внимание, что несколько ssh-agent процессы не являются недостатком, потому что они не занимают больше памяти или процессорного времени.

Пробовал пару решений из многих источников, но все казалось слишком большой проблемой. Наконец нашел самый простой:)

Если вы еще не знакомы с zsh и oh-my-zsh, установите его. Тебе это понравится:)

Затем отредактируйте .zshrc

vim ~/.zshrc

находить plugins раздел и обновите его, чтобы использовать ssh-agent вот так:

plugins=(ssh-agent git)

И это все! У тебя будетssh-agent запускается каждый раз, когда вы запускаете свою оболочку

Просто чтобы добавить еще одно решение: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-агент, если он еще не запущен

Комментарии приветствуются:)

Поэтому я использовал подходы, описанные выше, но я предпочитаю, чтобы агент умер, когда мой последний сеанс 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              

Извините за опоздание:

Пользователи оболочки рыбы могут использовать этот скрипт, чтобы сделать то же самое.

# 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

Я решил это, добавив это в /etc/profile - для всей системы (или для локального пользователя.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-agent, если он не запущен для пользователя, или переустанавливает параметр env ssh-agent, если работает.

Очень нравятся ваши ответы. Это сделало работу от 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

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

Я использую для этого инструмент ssh-identify.

От своего человека-page:

ssh-ident - запускает и использует ssh-agent и при необходимости загружает идентификаторы.

Другие вопросы по тегам