web-dev-qa-db-ja.com

投獄されたユーザーにSSHを許可し、秘密鍵を保護する要塞ホスト

基本的に、私はユーザーに秘密鍵への読み取りアクセス権なしで秘密鍵を使用させようとしています。

ユースケース:従業員はデータセンターのサーバーにSSHで接続する必要があります。要塞に保存されているすべてのサーバーに1つの秘密鍵があります。秘密鍵を保護しながら、従業員が要塞をジャンプボックスとして使用するにはどうすればよいですか?

  1. 従業員は(SSH経由で)要塞に接続します。
  2. 要塞ホストは、監獄のシェルを使用して、その従業員のアクセスをロックダウンします。
  3. 次に、従業員はエンドサーバーにSSH接続します(ただし、その過程で秘密鍵には触れませんでした)

要塞が秘密鍵を従業員に開示せずに別のサーバーへのSSHアクセスを提供するためのアプリケーション/ツール/スクリプト/メソッドはありますか?

私の考えの1つは、要塞のリスナーがエンドノードへの独自のSSH接続をトリガーし、刑務所にいるユーザーに共有「画面」または共有シェルを提供してエンドへのアクセスを容易にする方法があるかもしれないということでした。ノード?

多分私はこれを複雑にしすぎて、もっと良い解決策がそこにあります。ユーザーごとの秘密鍵は、管理するのが悪夢のようです。

6
BastionH0st2

「Sudo」(またはそれに依存するスクリプト/エイリアス)を使用する可能性があります。

Sudoのおかげで、非常に具体的なコマンドを実行するために、ユーザーが一時的に別のルート(必ずしもルートではない)を使用できるようにすることができます。

  1. 秘密鍵を所有する新しいアカウントを作成し、
  2. ユーザーがこのアカウントとその秘密鍵を使用してSSHクライアントを起動できるようにSudoを構成します。

このようにして、ユーザーは秘密鍵自体に直接アクセスすることを許可されなくても、秘密鍵を使用して非特権SSHクライアントを実行できます。

7
WhiteWinterWolf

1:チャレンジ/レスポンスベースの認証用に構成されたYubikeyなどのハードウェアトークンを使用します。またはスマートカード。あなたはそれらすべてにキーをロードし、それらを配ります。それらは秘密を秘密に保つように設計されています。

2:説明責任と実用的な取り消しのために、単一のキーの使用を停止し、ユーザーごとに1つのキーペアの使用を開始します。

4
Natanael

[〜#〜]警告[〜#〜]:創造性の先を行く、これはセキュリティにしばしば悪いことです(少なくとも徹底的なレビューなしでは)。

これは、SSHエージェントが役立つケースのように思えます。 SSHエージェントは、SSHクライアントがエージェントにキー操作の実行を要求できるソケットインターフェースを提供します。これにより、次の一般的な使用が可能になります。

  • 各クライアントに個別にキーを復号化させるのではなく、長期実行エージェントに秘密鍵を一度復号化させることができます。
  • SSHクライアントにエージェント接続を転送させることで、リモートホストのキーを実際にそこに保存したり公開したりせずに使用できるようになります。

この2番目のケースは、別のホストにアクセス権を付与する代わりに、同じホスト上の複数のユーザーにアクセス権を付与することを除いて、特にユースケースによく似ています。

次のようになります。

sshkeeper@bastion$ eval "$(ssh-agent -a /path/to/socket)"
sshkeeper@bastion$ echo $SSH_AUTH_SOCK
/path/to/socket

sshkeeper@bastion$ ssh-add
Enter passphrase for /home/sshkeeper/.ssh/id_rsa:

sshkeeper@bastion$ chmod 660 /path/to/socket
sshkeeper@bastion$ chgrp ssh-users /path/to/socket

キーは必ずしもパスフレーズを必要としません。イラスト用に入れました。いずれの場合も、ソケットへの読み取りおよび書き込み権限を持つ誰もが使用できます...

jander@bastion$ export SSH_AUTH_SOCK=/path/to/socket
jander@bastion$ ssh private_server
Error reading response length from authentication socket.
Permission denied (publickey).

おっとっと。 ssh-agentは偏執狂的で、ソケットに接続しているユーザーのユーザーIDを再確認するため、これは少しトリッキーです。したがって、回避策が必要です。 socatをプロキシとして使用してみましょう:

sshkeeper@bastion$ eval "$(ssh-agent -a /home/sshkeeper/ssh_agent_socket)"
sshkeeper@bastion$ ssh-add
Enter passphrase for /home/sshkeeper/.ssh/id_rsa:
sshkeeper@bastion$ rm /path/to/socket
sshkeeper@bastion$ umask 117
sshkeeper@bastion$ socat UNIX-LISTEN:/path/to/socket,fork,group=ssh-users UNIX-CONNECT:/home/sshkeeper/ssh_agent_socket &

これで、エージェントに接続しているのはsshkeeperが所有するsocatプロセスであり、janderが所有するSSHクライアントではないため、エージェントに問題はありません。

jander@bastion$ export SSH_AUTH_SOCK=/path/to/socket
jander@bastion$ ssh private_server
jander@private_server$ █

ソケットを保護するために残されているのは、ソケットにアクセスするためのファイルシステム権限に注意する必要があります。ソケットへのパスに沿ってsshkeeper以外の書き込みアクセス権を与えないでください。また、一部のBSD派生システムは、ソケットファイル自体の権限を無視することにも注意してください。これをシステムで十分にテストしてください。

最後に、これはSSHエージェントの非標準的な使用法であることに注意してください。実際、私はそれを機能させるためにセキュリティ機能を回避する必要がありました。適切なファイルシステム権限を持つLinuxシステムでは、少なくともSudoソリューションと同じかそれ以上の安全性があると思いますが、私のWordを使用するべきではありません。これを使用する前に、ここで何が起こっているのかを正確に理解していることを確認してください。


[〜#〜] update [〜#〜]openssh ssh-agentソースを確認しましたcode を使用して、エージェントソケットで何ができるかを確認します。小さないたずらの可能性がいくつかあります。つまり、ユーザーはエージェントにキーの追加または削除を依頼できます。

したがって、誰かがエージェントにキーをドロップするように指示し、あなた(またはスクリプト)がキーを再度追加するまで、他の全員をサーバーからロックアウトすることができます。

また、キーを追加して、他のすべてのユーザーが追加のサーバーにアクセスできるようにすることもできます。ただし、この人は他の人に直接(サーバーを使用せずに)キーを渡すことも、独自の共有エージェントを使用することもできるため、この点は比較的軽微です。

4
Jander

Sudoの回答(実際には賢い)に加えて、別の解決策は制限付きシェルです。この場合、1つ作成する必要があります。この場合、受け入れる必要があるコマンドは「ssh <hostname>」と「exit」だけなので、それほど難しくありません。

私は完全を期すためにこれを実際に投稿するだけですが、一般的な手法は他のコンテキストでは価値があります。

2
Joshua

ホストベースの認証を使用

Sshは一般的には知られていませんが、rshとよく似た方法でリモートマシンの認証をサポートしています(ただし、より安全です)。

https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Host-based_Authentication には良いマニュアルがあります

要塞sshサーバーには秘密鍵があり、setuid ssh-keysignバイナリを介してアクセスします(ユーザーはそれにアクセスできません)。リモートサーバーは、要塞ホストから来るすべてのユーザーを単純に信頼するように構成されます(ユーザーが決定するそれが賢明かどうか)。

1
Ángel