マシンごとに1つのアカウント(サポートアクセスアカウント)のみを使用して、少数の人々(サポートスタッフと呼ばれる)のみがSSHで接続できる一連のマシン(ここでは顧客のマシンと呼ばれます)があるとします。
サポートスタッフは、キーを使用してお客様のマシンにログインすることのみを想定しています。さらに、サポートスタッフは進化する可能性があるため、サポートスタッフを離れた人は、どのカスタマーマシンにもログインできません。したがって、スタッフは顧客のマシンへのログインに使用される秘密鍵を読み取ることを禁じられています。また、お客様のマシンのauthorized_keys
ファイルを変更することは禁じられています。
その構成を実現するために、サポートスタッフがログインし(LDAP認証を使用しますが、これは別の問題です)、秘密鍵を含むSSHプロキシを使用することを考えました。
問題は、サポートスタッフがSSH秘密鍵を読み取れなくても使用できるようにするにはどうすればよいですか?
ユーザーの要求を受け入れてSSHセッションを開くプロキシマシンでrootとしてデーモンを実行する必要があると思いますが、その方法がわかりません。何か案は?
私はいくつかのオプションを提案します。
Sshキーを保護し、サポートチーム側でSudo
を使用する必要があります。これは、ラッパーを使用して透過的に行うことができます。ラッパーを呼び出して、たとえば/usr/local/bin/ssh-support
とし、次のようなものを含めます(テストされていません)。
#!/bin/bash
export PATH=/usr/local/bin:/usr/bin:/bin
export IFS=$' \t\n'
export SUSER=ssupport
# Restart if not running under Sudo
test "X$1" != 'X-S' && exec Sudo -u "$SUSER" /usr/local/bin/ssh-support -S "$@"
shift
export SHOME="$(getent passwd "$SUSER" | cut -d: -f6)"
# Extract single argument as hostname LABEL and validate that we have
# an RSA private key for it. The target username, real hostname, port,
# etc. can be defined in ~/.ssh/config for the user $SUSER (ssupport)
label="$1"
idfile="$SUSER/.ssh/id_rsa_for_$label"
cgfile="$SUSER/.ssh/config"
ok=true
[[ "$label" =~ '/' ]] && { echo "Invalid label: $label" >&2; ok=; }
[[ ! -s "$idfile" ]] && { echo "Missing identity file: $idfile" >&2; ok=; }
[[ ! -s "$cgfile" ]] && { echo "Missing configuration file: $cgfile" >&2; ok=; }
if test -n "$ok"
then
logger -t ssh-support "$Sudo_USER requested ssh to $label"
exec ssh -i "$idfile" -F "$cgfile" "$label"
fi
exit 1
これには、sudoers
グループのユーザーがツールを使用できるようにするsupport
ファイルのエントリが必要になります。このコマンドを使用すると、ssh-support
ツールをssupport
ユーザーとして実行できます。これは作成する必要があります。 しません root権限を付与します。
%support ALL = (ssupport) /usr/local/bin/ssh-support
サポートユーザーがツールを実行するために独自のパスワードを提供する必要がないことに満足している場合(スクリプト自体の中でSudo
呼び出しによって要求されるように)、次のようにsudoers
定義を修正できます。
%support ALL = (ssupport) NOPASSWD: /usr/local/bin/ssh-support
PATH
に/usr/local/bin/
が含まれているとすると、ssh-support clientname
で呼び出します。また、ssupport
ユーザーを/home/ssupport
として作成したとすると、証明書のペアとして/home/ssupport/.ssh/id_rsa_clientname
と/home/ssupport/.ssh/id_rsa_clientname.pub
を作成し、/home/ssupport/.ssh/config
にホストエントリを作成します。 clientname
は、ターゲットマシンのユーザー、ホスト、ポートなどを定義しました。 X11転送、ポート転送などを明示的に無効にする可能性があります。いつものように、/home/ssupport/.ssh
ディレクトリは権限0700
で保護する必要があります。
サポートの各メンバーに独自のローカルユーザーアカウントを提供し、各ユーザーに独自のプライベートsshキーを使用してクライアントのサーバーにアクセスしてもらいます。ある人がサポートグループを離れるとき、あなたはその人のsshキーをクライアントのサーバーから削除します。これは、スタッフが秘密のsshキーを知らないようにすることを心配する必要がなくなったことを意味します。
本当にやりたいのは、SSH CAを使用して、各サポート担当者が使用するキーに署名し(パスポートなど、独自のsshキーが必要です)、/ etc /内のTrustedUserCAKeys /etc/ssh/users_ca.pub
を使用するようにクライアントのサーバーを構成することです。 ssh/sshd_config。このようにして、サーバーはCAキー(アクセスできる)によって署名されたすべてのキーを受け入れ、authorized_keysに触れることなく、サポートされなくなったユーザーのキーを取り消すことができます。
「sshca」をすばやく検索すると、このチュートリアルが示されます: https://www.digitalocean.com/community/tutorials/how-to-create-an-ssh-ca-to-validate-hosts-and -clients-with-ubunt (「ユーザーキーの構成方法」までスクロールダウン)-チュートリアルではUbuntuについて言及していますが、ディストリビューションに依存しませんが、SSHCAをサポートするOpenSSHの新しいバージョンが必要です。
このトピックに関するもう1つの優れたブログエントリは https://ef.gy/hardening-ssh (「SSH証明書」までスクロールダウン)です。
期間限定で有効になるようにキーに署名できることに特に注意してください。そうすれば、キーは自動的に期限切れになります。
Sudoまたはsetuid-executable(特別な目的non-rootアカウント)を介して呼び出されるsshのラッパースクリプトに関連するいくつかの異なる回答があります。 nkmsによると のように、すべての引数をsshに渡すと、ユーザーは保護しようとしているsshキーを使用して任意の操作を実行できます。他の極端なものは、ホスト名のみを許可することです。
OPは、管理者が物事をアップロードできる必要があると述べています。
2つの異なるfixed-args-to-sshラッパーを持つことができます。 1つはログインシェル用、もう1つはscp用です。ホスト名(およびアップロードするファイル名)以外のユーザー指定の引数はありません。
または、getopt
自体を使用して非常に限られたオプションを解析し、ほとんど修正されたsshコマンドにプラグインするラッパースクリプト。認識されないオプションを無視(またはエラー)するのが最善の方法です。
「危険な」sshオプションを除外しようとしないでください。対話型ログイン、またはファイル(ローカルおよびリモートファイル名)のアップロードの2つのことを実行できるラッパーを作成するだけです。あなたはまだそこでいくつかの消毒をする必要があると思います。
実際、これはまだ間違いやすいです。ユーザーがsshキーを保持しているファイルをローカルファイルとして提供しないようにする方法を見つける必要があります。したがって、何も許可しないことから始めるのではなく、許可しない必要があるすべてのことをまだ考えようとしています。ファイル名に@
または:
が含まれていないことを確認することから始めます。
SSHプロキシサーバーを設定する場合は、スタッフユーザーのシェル(/etc/passwd
)は、bashなどのシェルではなく、シェルアクセスを許可しない単純なスクリプトに設定されます。代わりに、ターゲットのホスト名(read target
)、次にexec ssh "support@$target"
。
このようなプロキシを使用すると、scp
などのツールを使用して顧客のマシンとの間でファイルを転送することが困難になる可能性があることに注意してください。これは問題または利点かもしれません!
サポート担当者は常にそのプロキシマシンを介して、そこからのみ接続するため、クライアントは単純にHostbasedAuthenticationを使用してプロキシマシンを認証する。
プロキシマシンが_supporters.pc
_であり、_customer.pc
_にサポートを提供するとします。
customer.pc はHostbasedAuthentication yes in _/etc/ssh/ssd_config
_、 supporters.pc に_/etc/ssh/shosts.equiv
_および_/etc/ssh/ssh_known_hosts
_の公開鍵。
サポートスタッフが[email protected]にログインし、_ssh customer.pc
_を実行すると、キー署名を処理する ssh-keysign(8) (setuidが必要)が生成されます。 file-you-can-readを使用して、接続が実際に supporters.pc から来ていることをsupporters.pcに証明します。 customer.pc が supporters.pc を信頼するため、スタッフは support としてログインします。 。
この特定のユースケース(以下の重要な注意事項を参照)の場合、1つの可能性は、これらの発信SSH接続専用のユーザー(たとえばsupport-ssh
)を作成し、/usr/bin/ssh
を実行する小さなラッパーバイナリをインストールすることです。
ssh
バイナリ自体をコピー+ chmodしないでください。セキュリティ更新プログラムを適用するたびに、バイナリを再コピーすることを忘れないためです。root
をより特権のあるユーザーとして使用しないでください。これは、私が信頼する理由から明らかです。これは、次のトレードオフを使用して、Sudo
を使用して特権をsupport-ssh
アカウントの特権に昇格させるのと機能的に同等の代替手段です。
Sudo
よりも小さくてスリムなので、構成エラーが意図した以上に開くリスクが少なくなります。Sudo
よりも具体的にするように調整できます(ただし、記述するコードが多いほど、セキュリティを監査する必要があります)。ラッパーバイナリは、HOME
をsupport-ssh
ユーザーのホームディレクトリに設定して、ssh
が適切なssh_config
と秘密鍵を取得するようにする必要があります。ただし、呼び出し元のユーザーが~support-ssh/.ssh/
またはその内容を読み取ることを許可しないでください。
ラッパーは次のように単純にすることができます。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
setenv("HOME", "/home/support-ssh", 1);
/* allow only a single, non-option argument */
if (argc!=2 || *argv[1]=='-') {
fprintf(stderr, "Usage: %s <hostname>", argv[0]);
exit(EXIT_FAILURE);
}
execv("/usr/bin/ssh", argv);
return EXIT_FAILURE;
}
より制限を厳しくして、引数argv[1]
が許可されたホスト名のセットに含まれていることを確認することをお勧めします。または、制限を緩和し、オプション引数(のサブセット)を許可します。環境変数を完全に置き換えることもできます(ただし、TERM
、LC_*
などの重要な変数は保持してください)。 LD_LIBRARY_PATH
とLD_PRELOAD
は特に危険であることに注意してください。
必要に応じて、同様のラッパープログラムをscp
に提供できます。
この回答は、ユーザーが契約上手順に従う義務があり、それらに違反した場合の制裁(解雇など)があるという質問の特定の状況に対処します。決心した攻撃者が不正アクセスを取得するのを防ぐのではなく、従業員が何気なく秘密鍵をコピーするのを防ぎたいと考えています。
私は、セキュリティは技術的防御と非技術的防御の両方によって達成され、ここで、またはSudo
を使用して達成されるバランスは提示された状況に適していると考えています。