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


262

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)を実行しています。


2
ログインするたびに実行したいことはすべて、.profile(ターミナルログイン)または.xinitrc(GUIログインの場合)に記述してください。
Barmar 2013

1
ああ!.bash_profileを使用していました... .profileと.bash_profileの違いは何ですか?
Pathsofdesign 2013

1
そもそもなぜそのようにコマンドを実行しているのかわからない。ssh-agent <command><command>サブプロセスとして実行されるssh-agentため、新しいシェルを開始します。あなたが欲しいと思うeval ssh-agent
Barmar 2013

9
.bash_profilebashに固有で、.profileすべてのPOSIXシェルに共通です。bash最初にを探し.bash_profile、次にデフォルトでを探します.profile
Barmar 2013

5
ssh-agent「標準」(POSIX互換)シェルを生成する正しい方法はeval $(ssh-agent -s)です。また、ログアウトするときにエージェントを適切trap 'kill $SSH_AGENT_PID' EXITに削除する必要があることにも注意してください。そのため.profile、エージェントを開始する行の後ろに追加することをお勧めします。
kostix 2013

回答:


368

この記事を読んでください。これは非常に便利です。

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

上記のリンクがいつか消える場合に備えて、私は以下のソリューションの主要部分をキャプチャしています:

ダニエル・スタリンによるジョセフ・M・リーグルのこの解決策:

これにあなたを追加 .bash_profile

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


8
マシンの再起動は必要ありません。現在のシェルセッションで.bash_profileを使用source ~/.bash_profileしてリロードできます。とにかく新しい構成をロードするため、マシンの再起動も機能します。
リトマス2014

11
使用するSSH_ENV="$HOME/.ssh/env"(つまり、/ environmentだけではない)なぜですか?sshdは〜/ .ssh / environmentを使用します(manページ:PermitUserEnvironmentを参照)。Githubのも、彼らのソリューションでこれをお勧めします- help.github.com/articles/...
アンドリュー・マーフィー

7
このスクリプトは、〜/ .bashrcファイル(〜/ .profileまたは〜/ .bash_profileではない)に入れたときに機能しました。ローカルコンソールを初めて開くと、パスフレーズの入力を求められますが、それ以降は何も入力せずにすべてが機能します。乾杯。
Andrew Pate 2015

3
ssh-agent.bashrcに開始コマンドを追加すると、scpコマンドが機能しなくなります。
Dzanvu 2015年

5
まだ面倒です... sshを使用しない場合でも、ログインするたびにこれを行う必要があります。sshが呼び出されるたびにこれを起動する必要があります...理想的には、どのホストがどのキーをロードするかを設定できる必要があります。
Erik Aronesty

98

Arch Linuxでは、次のものが非常に優れています(すべてのsystemdベースのディストリビューションで動作するはずです)。

以下をに入れて、systemdユーザーサービスを作成します~/.config/systemd/user/ssh-agent.service

[Unit]
Description=SSH key agent

[Service]
Type=simple
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
ExecStart=/usr/bin/ssh-agent -D -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-addする必要はありません。


3
Ubuntuでこれを行おうとしたときにこのコメントを見つけました。少なくともシステムがどのように動作するかについての私の知識を考えると、起動スクリプトに何かをハッキングするよりも、組み込みシステムでうまく機能するようです。
xiterion 2017

Ubuntu 16.04 LTSでこれを試しました。残念ながら、すべてのシェルプロセスは個別のssh-agentプロセスを必要とします。ドキュメントを読んだ後でも、おそらく知識が不足しています。
荒巻大輔

Type = simpleを使用することもできます。wiki.archlinux.org/index.php/...
ハンス・J。シュミット

2
それで、このソリューションは基本的にsystemdサービスをインストール/構成しますか?
Trevor Boyd Smith、

SSH_AGENT_PIDただし、これは環境変数を設定しません:(
MrMeszaros

73

古い質問ですが、私は同じような状況に出くわしました。上記の答えが必要なものを完全に達成するとは思わないでください。欠けているのはkeychain; まだインストールしていない場合は、インストールしてください。

sudo apt-get install keychain

次に、次の行を ~/.bashrc

eval $(keychain --eval id_rsa)

これによりssh-agent、実行されていない場合はが起動し、実行されている場合は接続され、ssh-agent環境変数がシェルに読み込まれ、sshキーが読み込まれます。

ロードするid_rsaプライベートキーに変更し~/.sshます。

参照

/unix/90853/how-can-i-run-ssh-add-automatically-without-password-prompt


キーチェーンは、指定された手順に従って機能しません。.bash_profileに追加しても、sshは毎回パスワードを要求します。同じシェルで何度か試してみました。サイコロはありません。基本的なssh-agentアプローチに戻る
javadba

eval keychain --eval id_[yourid file]を.bashrcに追加
xelber '11

4
StackOverflowのコメントの書式設定のため、ソリューションの調査に20分を費やしました。上記xelberさんのコメントごとに、正解があるeval `keychain --eval id_[yourid file]`.bashrc。実行中のssh-agentにアクセスするために、現在のシェルの環境変数を評価するために必要なバックティック。
ジェームズ

2
これが正しい簡単なソリューションです。keychainコマンドの実行時にログを表示したくない場合は-q、クワイエットモードのオプションを追加できます。キーチェーンの詳細:funtoo.org/Keychain
Diki Ananta

4
Thx、これは断然最もエレガントなソリューションです。
greenspand

37

承認されたソリューションには、次の欠点があります。

  • メンテナンスが複雑です。
  • エラーやセキュリティ違反につながる可能性のあるストレージファイルを評価します。
  • エージェントを起動しますが、停止しません。これは、キーを点火したままにするのと同じです。

キーでパスワードを入力する必要がない場合は、次の解決策をお勧めします。以下を.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コマンドは、1つのセッションのみに影響します。これは、実際には非常に珍しい状況でのみ問題になります。
  • パスワードの入力が必要な場合は使用できません。
  • 起動したシェルが非ログインになります(AFAIKには影響しません)。

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


Git Bashを使用して、Windows 10の$ HOME外のディレクトリにSSHキーを持っています。RSAへのパスを変更するだけで、これを機能させることができました。TYVM!
kayleeFrye_onDeck 2016年

7
私は、と主張するだろう「あなたの鍵は、パスワードを入力する必要がない場合は、」イグニッションにキーを残すことに近いと同等です。
Bruno Bronosky 2016年

少なくとも、ネットワーク上のどこかではなく、自分のホスト上にあります。
midenok

1
「「キーにパスワードを入力する必要がない場合」は、キーを点火したままにすることとほぼ同じだと私は主張します。」<-その理由を説明してください。キーはパスワードよりもはるかに柔軟性が高いため、取り消しがはるかに簡単です(何ですか?フルアクセス権を持つsudoユーザーに対してのみキーを使用していますか?tsk tsk)。ユーザーの複数のプロファイル用の複数のキーのセット。何かを自動化したい場合は(展開やエンドツーエンドのチェックなど)、 "オーケストレーション"中にパスワードを常に入力してください。
スコットプライブ

2
それをしないでください。パスワードなしのキーは悪い習慣です。
user48678 2017

26

これをに追加してから~/.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実行している限り、同じように再利用し続けます。


複数のキーがあり、それらに名前が付けられていない場合は、代わりに何を使用し~/.ssh/id_rsaますか?ssh-addあなたの答えの一部は、キーのデフォルトのファイル名を期待しているようです。
ガブリエルステープルズ

うん。必要に応じて、ファイル名を最後の行の最後に追加できると思います
Collin Anderson

しかし、スクリプトを自動化して、たとえばパスワードを手動で入力せずにgitをプルすることはできませんか?それを避ける方法は?
trainoasis

7

したがって、以前は上記のアプローチを使用していましたが、最後の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              

これを他のシェル(BASH以外)のログイン時にBASHスクリプトとして実行すると、動作するはずです。
hoijui、

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 yesssh構成にあることを確認して、使用時にキーが自動的に追加されるようにします
  • ログイン時にパスフレーズを入力するように求められません(この場合も、初回使用時にパスフレーズの入力が1回発生します)。
  • ssh-agentをまだ開始していない場合は、それをサイレントに開始します

コメント歓迎:)


1
これは完璧に機能しました。Kubuntuでは.profileに入れました。
Shai

1
AddKeysToAgent yes設定について知っておくと便利です。ありがとう。
コリンアンダーソン

3

私はこれを追加することによってそれを解決するの/ etc /プロファイル -システム全体(またはユーザーローカルに.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が開始され、実行されている場合はssh-agent envパラメータが再設定されます。


エージェントがすでに実行されているかどうかを確認する方法を言ってくれてありがとう!
マイクマクスウェル

どのように機能しif pgrep -u $WHOAMI $SERVICE >/dev/nullますか?
Josh Desmond

3

魚の殻のユーザーは、このスクリプトを使用して同じことを行うことができます。

# 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

これにはssh-identツールを使用します

そのmanページから:

ssh-ident-ssh-agentを起動して使用し、必要に応じてIDをロードします。


1

多くのソースからいくつかのソリューションを試してみましたが、すべてが面倒すぎるように見えました。最後に私は最も簡単なものを見つけました:)

zshoh-my-zshにまだ慣れていない場合は、インストールしてください。きっと気にいる :)

次に編集します .zshrc

vim ~/.zshrc

pluginsセクションを見つけてssh-agent、次のように使用するように更新します。

plugins=(ssh-agent git)

そしてそれだけです!あなたはあるでしょうssh-agentアップし、あなたのシェルを起動するたびに実行されています


1

私はあなたの答えがとても好きです。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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.