web-dev-qa-db-ja.com

ssh-agentとscreen

StackOverflowに戻ってしばらくして、私は ssh-agentとcrontabに関するこの質問 を尋ねました。 Linuxシステムのssh-agentとscreenについても同様の質問があります。

そのため、私のMacでは、ssh-agentはシステムの起動時に起動するので、いつでも利用できます。 X-Windowsを使用している場合、Linux(redhat el5/Fedora)でも同じだと思います。ただし、これはリモートサーバーマシンであり、私は常にssh経由でログインしています。

Sshキーを適切に設定して、svnの更新またはコミット中にパスワードを複数回入力する必要がないようにしたいと思います。セッションごとに1回パスフレーズを入力できてうれしいです。また、チームがパスワードなしのsshキーを使用することをお勧めしません。

少しの間、.bash_profileで「eval `ssh-agent -s`」を実行し、ログアウト時にssh-agentを強制終了するコマンドを実行すると機能するように見えました。ただし、長時間実行される対話型プログラムと開発環境を管理するために、 screen を多用します。今説明したようにssh-agentを開始および停止すると、ターミナルを終了するときにssh-agentが強制終了され、そのssh-agentインスタンスを参照していた画面のサブセッションが破棄されます。

では、どうすれば、画面を使用し、sshキーでパスワードを使用し、パスフレーズを常に入力する必要がないコンソールユーザーになることができますか?

8
Michael H.

次の設定では、screenを呼び出すためのラッパーは必要ありません。さらに、/tmpの使用を回避します(結果としてセキュリティリスクが発生します)。

  1. 〜/ tmpディレクトリがあることを確認してください。

    mkdir ~/tmp
    
  2. 次の行を.screenrcに追加します。

    setenv SSH_AUTH_SOCK "$HOME/tmp/ssh-agent-screen"
    
    • これにより、screen内で、sshはパスを変更するのではなく、常に同じ場所にあるソケットを検索します。
    • これは画面であり、シェルコマンドではないため、使用するシェルにはsetenvを使用する必要があります。
  3. 次の行を.bash_profileに追加します。

    [ -n "$SSH_AUTH_SOCK" ] && [ "$SSH_AUTH_SOCK"!="$HOME/tmp/ssh-agent-screen" ] && ln -sf "$SSH_AUTH_SOCK" "$HOME/tmp/ssh-agent-screen"
    
    • これは、固定された場所(sshが見える場所)から実際の場所にリンクし、ssh-agentを開始して後に表示される必要があります。
    • [ -n "$SSH_AUTH_SOCK" ]を使用すると、SSH_AUTH_SOCKが設定されていない場合のエラーを適切に防ぐことができます。
    • [ "$SSH_AUTH_SOCK"!="$HOME/tmp/ssh-agent-screen" ]は、画面ソースが.bash_profileの場合、$ HOME/tmp/ssh-agent-screenをそれ自体にリンクする画面セッションを防ぎます。
  4. ssh-agent.bash_profileを開始する代わりに、ssh -Aに接続することを検討できます(エージェント転送を使用し、リモートマシンにエージェントを使用させるため)。

この設定の後、標準の画面コマンドを使用できます。既存のセッションを再作成するか、セッション内のSSH_AUTH_SOCKを手順2の固定位置に手動で設定するだけで済みます。

クレジット このウェブサイト アイデアのために; /tmpの使用は避けました。 この回答 は似ていますが、追加のエイリアスを使用します。

4
Blaisorblade

sshエージェントの転送をフォローアップするために、ログアウトして再度ログインし、セッションに再接続すると、デフォルトでは、転送されたssh資格情報を画面セッションで使用できないことがわかります。

ただし、画面でSSH_AUTH_SOCK環境変数を既知のものに設定し、その既知の場所を現在の認証ソケットに更新することで、これを回避できます。

このシェル関数を使用して、画面に再度入り、ssh authsockを修正します。

function sr () { 
    if [ ${+STY} = 1 ] ;then 
            echo already in screen\!
    else
            if [ "${SSH_AUTH_SOCK}x" != "x" ]; then
                    if [ ! -d /tmp/screenssh ]; then
                            mkdir /tmp/screenssh 
                    fi
                    rm -f /tmp/screenssh/socket
                    ln -s $SSH_AUTH_SOCK /tmp/screenssh/socket
                    echo $REMIP > /tmp/screenssh/remip
            fi                
            screen -DR
    fi
}

そして私は私の.screenrcにこれを持っています:

setenv SSH_AUTH_SOCK /tmp/screenssh/socket

お役に立てれば。

2
Dan Pritts

チェックアウト キーチェーン 。上記のすべてを実行します。特に--clearおよび--timeoutオプションを見てください。

2
Neil Mayhew

より良いアプローチは、sshエージェント転送-Aオプション)。これにより、sshを使用している人は、元のマシン(おそらく実際に座っているワークステーション)で実行されているssh-agentのキーを使用できます。

2
Neil Mayhew

.bash_profileの代わりにinitscriptからssh-agentを起動できますか?たとえば、私は置くかもしれません

su -c 'ssh-agent -s > ~/.ssh_agent_env' myusername

/etc/conf.d/localの適切な部分にありますが、RHEL/Fedoraはおそらく別のシステムを使用しています。コメントで指摘したように、ターミナルセッションはエージェントに接続できる必要があります。そのため、このコマンドはユーザーのホームディレクトリにファイル.ssh_agent_envを作成します。次に、追加できます

[ -f ~/.ssh_agent_env ] && source ~/.ssh_agent_env >/dev/null

.bash_profileで。

あなたができるもう一つのことは.bash_profileに以下を入れることです

ps -U myusername | grep -q ssh-agent || ssh-agent -s > ~/.ssh_agent_env
source ~/.ssh_agent_env >/dev/null

まだ実行されていない場合にのみssh-agentを開始します。その後、あなたはそれを殺す必要はありません。

2番目の提案とは少し異なる方法として、ssh-agentプロセスの存在を確認する代わりに、ファイル~/.ssh_agent_envの存在を確認することができます。

[ -f ~/.ssh_agent_env ] || ssh-agent -s > ~/.ssh_agent_env
source ~/.ssh_agent_env >/dev/null

すべてが適切に機能する場合、2つの方法の間に大きな違いはないはずです。

2
David Z

私があなたの言うことを正しく理解していれば、スクリーンセッションが必要なだけです。このセッションは、時々切り離して再接続しますが、ssh-agentのパスワード(秘密鍵のパスワード)を再入力することは二度とありません。

サブシェルでssh-agentを起動してから、そのサブシェルにとどまるよりも、画面を起動するのが最も簡単な方法だと思います。つまり.

screen
ssh-agent bash
ssh-add   # enter your password once

# some commands, some logins and logouts to remote servers via ssh public key

# <ctrl>+<a>, <ctrl>+<d> to detach screen
# you can now logout from this computer
# login again

# reattach to your screen
screen -r
# ssh-agent is still running
1
erik