最近、次のスクリプトを自動起動(KDE)に追加しました。
eval `ssh-agent`
ssh-add
スクリプトはログイン時に起動し、パスフレーズを要求して秘密鍵をロードします。ほぼ正常に動作します。スクリプトは正しく実行され、エージェントが起動し、環境変数がすべて設定され、パスフレーズが要求されます。唯一の問題は、その後キーがロードされないことです。ただし、その後ターミナルに ssh-add と入力すると、パスフレーズが要求され、キーは X セッションの残りの間保存されます。
何が間違っているのでしょうか? パスフレーズを要求されているのに、キーがロードされないのはなぜですか?
PS: 私は Debian jessie で実行しています。
答え1
これを引き起こしている可能性があるシナリオは 2 つ考えられます。
どちらも、多くのデスクトップ マネージャーが独自の SSH キー エージェントを起動するという事実に起因しています。これは、デスクトップ マネージャー (ターミナル エミュレーター) によって起動されたアプリケーションがエクスポートされた変数を取得するには、エージェントをデスクトップ マネージャーより前に起動する必要があるためです。
デスクトップ マネージャーは、ユーザーが SSH エージェントを起動した後に独自の SSH エージェントを起動し、最終的に SSH エージェントを置き換えてしまいます。
どの時点で、どのように SSH エージェントを起動しているかはわかりませんが、デスクトップ マネージャーが ssh エージェントを起動した後に起動すると、エクスポートされた変数によって、作成した変数が上書きされます。
デスクトップ マネージャーは、独自の SSH エージェントをユーザーの SSH エージェントの前に起動しており、ユーザーの SSH エージェントは永続化されていません。
ターミナル ウィンドウを起動して を実行するだけの場合
eval $(ssh-agent); ssh-add
、それによってエクスポートされた変数は、ssh-agent
ターミナル ウィンドウを閉じた後は保持されません。新しいターミナル ウィンドウを起動すると、デスクトップ マネージャーによって起動された ssh エージェントによって設定された変数が取得されます。
動作方法としてssh-agent
は、バックグラウンドでデーモンを起動し、設定する必要があるいくつかの変数を出力します。
$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-JLbBwVBP4754/agent.4754; export SSH_AUTH_SOCK;
SSH_AGENT_PID=4755; export SSH_AGENT_PID;
echo Agent pid 4755;
つまり、 を実行するとeval $(ssh-agent)
、これらすべての変数を設定することになります。
現在、変数は子にのみ継承されるため、デスクトップ マネージャーに保持するには、デスクトップ マネージャーが起動する前に設定する必要があります。これを正しく行うのは難しく、ディストリビューションによって異なります。多くのデスクトップ マネージャーがこれを独自に行うのはそのためです。
これは、PAM スタックの初期化中にも実行される場合があることに注意してください。
答え2
Patrick が指摘しているように、ssh-agent
デスクトップ環境によって生成されたインスタンスと競合する可能性があります。競合というのはおそらく適切な言葉ではありません。他のアプリケーションがエージェントと通信できるようにする変数は、その環境内になければなりません。デスクトップ セッション内のすべてのアプリケーションは、デスクトップ環境の一部 (セッション マネージャーであると仮定します) によって何らかの方法で生成されるため、まずセッション マネージャーの環境リストに変数を取得する必要があります。これは、次の 2 つの方法で実行できます。
セッション マネージャーはこれを内部的に実行します (どこかで設定したオプションによって異なります)。これには、PAM モジュールによって生成されるエージェント (ログイン/セッション マネージャーから呼び出される) が含まれます。
あなたのようなユーザー スクリプトを通じて。ただし、これは思ったほど簡単ではありません。セッション マネージャーがスクリプトを実行すると、新しいプロセス (スクリプト インタープリター) が作成されます。その環境では変数が設定されますが、セッション マネージャー (親プロセス) に簡単にエクスポートして戻すことはできません。これは、シェルで同じことを行うのと同じです。スクリプトを実行しても、現在のシェルの環境にはまったく影響がありません。これを行う必要があります。そう
source
すれば、コマンドは現在のシェルによって実行され、更新/作成された変数にアクセスできるようになります。これをセッション マネージャーで行うのはかなり複雑です (シェル インタープリターではないため)。したがって、ssh-agent
実際には競合していません。スクリプトから読み込まれた ID とともにそこにあるだけでssh-add
、誰もそれについて知りません。
何が起こっているのかを知るには、1の出力を確認してください。
ps fax | grep -E "(ssh|gpg)-[a]gent"
スクリプトを次のように変更します
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" > ~/ssh-agent.stdout
echo "SSH_AGENT_PID=$SSH_AGENT_PID" >> ~/ssh-agent.stdout
eval `ssh-agent | tee -a ~/ssh-agent.stdout`
これにより、変数のコンテンツがファイルに出力され、その場所に~/ssh-agent.stdout
からの出力が追加されてから処理されます (つまり、変数がエクスポートされます)。ファイルのコンテンツを、たとえば新しく作成されたシェル ターミナルの環境変数と比較します。ほとんどの場合、PID は (周期的に) 単調に増加するため、どれが最初に開始されたかがわかります。この部分は、一部の DE が の機能を使用してSSH エージェント サービスも提供するために存在します。ssh-agent
SSH_AUTH_SOCK
SSH_AGENT_PID
gpg-agent
gpg-agent
その行の呼び出しを完全に削除することもできますssh-agent
。スクリプトが SSH エージェントによってデスクトップ環境が生成された後に実行される場合は、環境変数が存在するため、パスワード ダイアログ (適切なエージェント用) が表示されます。そうでない場合は、スクリプトが DE のエージェント インスタンスの前に実行されているため、どのエージェントにもまったくアクセスできないことを意味します。
1括弧は巧妙なトリックgrep
プロセス リストからそれ自身を削除します。