最近、私は自動起動(KDE)に次のスクリプトを追加しました:
eval `ssh-agent`
ssh-add
スクリプトはログイン時に開始され、パスワードを要求してキーをロードする必要があります。効果はほぼ完璧です。スクリプトが正しく実行され、エージェントが起動し、環境変数がすべて設定され、パスワードの入力を求められます。唯一の問題は、後でキーがロードされないことです。ただし、端末に ssh-add と入力すると、パスワードの入力を求められ、残りの X セッション中にキーが保存されます。
私は何が間違っていましたか?パスワードを入力する要求にもかかわらず、キーがロードされないのはなぜですか?
PS:私はDebian jessieを使っています。
答え1
この問題を引き起こす可能性がある2つのシナリオを考えてみましょう。
どちらも、多くのデスクトップマネージャが独自のSSHキーエージェントをリリースしているという事実から来ています。エクスポートされた変数をインポートするには、デスクトップマネージャ(ターミナルエミュレータ)で起動されたアプリケーションがデスクトップマネージャの前にエージェントを起動する必要があるため、これが行われます。
デスクトップマネージャを起動すると、デスクトップマネージャは独自のSSHエージェントを起動し、最終的にそれを置き換えます。
SSHエージェントをいつ起動するのかはわかりませんが、エージェントの後にDesktop Managerが起動すると、エクスポートした変数が作成した変数よりも優先されます。
デスクトップ管理者は、ユーザーが起動する前に独自の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
は実際に競争していません。ただssh-add
スクリプトからロードされたIDと共にそこにいるだけで、実際にそれについて知っている人は誰もいません。
何が起こっているのかを理解するには、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
処理する前にその場所に出力を追加しますssh-agent
(したがって変数をエクスポートします)。ファイルの内容を新しく作成されたシェル端末などの環境変数SSH_AUTH_SOCK
と比較します。SSH_AGENT_PID
ほとんどの場合、PIDは(定期的に)単調に増加するため、どちらが最初に開始されたかがわかります。このセクションは、一部のDEがgpg-agent
SSHプロキシサービスを提供する機能も使用するために存在します。gpg-agent
行呼び出しを完全に削除することもできますssh-agent
。 SSHエージェントがデスクトップ環境を作成した後にスクリプトを実行すると、環境変数が存在するため、[パスワード]ダイアログボックス(正しいエージェント用)が表示されます。それ以外の場合は、スクリプトがDEのプロキシインスタンスの前に実行されているため、プロキシにまったくアクセスできないことを意味します。
1つの括弧は賢いトリックgrep
プロセスリストから自分を削除します。