web-dev-qa-db-ja.com

ログイン時にssh-agentを起動する

SSHエイリアスを使ってBitbucket.comから引っ張ってくるリモートGitレポとしてのサイトがあります。私は自分のサーバー上で手動でssh-agentを起動することができますが、SSHでログインするたびにこれをしなければなりません。

私は手動でssh-agentを起動します。

eval ssh-agent $Shell

それから私はエージェントを追加します。

ssh-add ~/.ssh/bitbucket_id

それから私がするときそれが表示されます。

ssh-add -l

そして行ってよかった。このプロセスを自動化する方法はありますか。ログインするたびに実行する必要はありません。サーバーはRedHat 6.2(Santiago)を実行しています。

209
Pathsofdesign

この記事を読んでください。これはとても便利です。

http://mah.everybody.org/docs/ssh

上記のリンクがいつか消えてしまった場合のために、私は以下の解決策の主要部分をとらえています:

Daniel StarinによるJoseph M. Reagleによる次の解決策:

これをあなたの.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をすでに起動しているかどうかを確認し、見つからない場合は起動して次回の起動時に使用できるように設定を保存するため、特に便利です。シェル。

308
Litmus

Arch Linuxでは、次のものがとてもうまくいきます(systemdベースのすべてのディストリビューションでうまくいくはずです)。

~/.config/systemd/user/ssh-agent.serviceに次のように入力してsystemdユーザーサービスを作成します。

[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で追加する必要はありません。

75
spheenik

昔の質問ですが、私は同じような状況に出くわしました。上記の答えが必要なものを完全に達成しているとは思わないでください。足りない部分は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

46
xelber

受け入れられている解決策には、次のような欠点があります。

  • 維持するのは複雑です。
  • エラーやセキュリティ侵害につながる可能性のあるストレージファイルを評価します。
  • それはエージェントを始動させますがそれを止めません。

あなたのキーがパスワードをタイプすることを要求しないならば、私は以下の解決策を提案します。次の行を.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コマンドは1つのセッションにのみ影響しますが、実際には非常に特殊な状況でのみ問題になります。
  • パスワードの入力が必要な場合は使用できません。
  • シェルはログインしなくなります(これはAFAIKには影響しません)。

いくつかのssh-agentプロセスはより多くのメモリやCPU時間を消費しないので、不利ではないことに注意してください。

36
midenok

これをあなたの~/.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を再利用し続けます。

21
Collin Anderson

それで私は上で説明されたアプローチを使用していました、しかし私は私の最後の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
Micah

さらに別の解決策を追加するために、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設定内にあることを保証しますので、使用時に自動的にキーが追加されます
  • ログイン時にパスフレーズを入力するように要求しません(初回使用時に1回限りのパスフレーズ入力が行われます)。
  • ssh-agentがまだ起動していない場合は、静かに起動します。

コメント歓迎:)

5
Keego

システム全体(またはユーザーのローカル.profile、または.bash_profile)にこれを/ etc/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を起動し、実行されている場合はssh-agent envパラメータを再設定します。

2
TheFrog

遅刻してすみません。

フィッシュシェル のユーザーは、この スクリプト を使って同じことができます。 。

# 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
2
Daniel Gerber

あなたの答えがたくさん好きです。 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

再度、感謝します

1
Knelis