web-dev-qa-db-ja.com

通常のユーザーが読み取れない秘密鍵を使用してSSHを使用できるようにする

マシンごとに1つのアカウント(サポートアクセスアカウント)のみを使用して、少数の人々(サポートスタッフと呼ばれる)のみがSSHで接続できる一連のマシン(ここでは顧客のマシンと呼ばれます)があるとします。

サポートスタッフは、キーを使用してお客様のマシンにログインすることのみを想定しています。さらに、サポートスタッフは進化する可能性があるため、サポートスタッフを離れた人は、どのカスタマーマシンにもログインできません。したがって、スタッフは顧客のマシンへのログインに使用される秘密鍵を読み取ることを禁じられています。また、お客様のマシンのauthorized_keysファイルを変更することは禁じられています。

その構成を実現するために、サポートスタッフがログインし(LDAP認証を使用しますが、これは別の問題です)、秘密鍵を含むSSHプロキシを使用することを考えました。

問題は、サポートスタッフがSSH秘密鍵を読み取れなくても使用できるようにするにはどうすればよいですか?

ユーザーの要求を受け入れてSSHセッションを開くプロキシマシンでrootとしてデーモンを実行する必要があると思いますが、その方法がわかりません。何か案は?

8
Raspbeguy

私はいくつかのオプションを提案します。

  1. 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で保護する必要があります。

  2. サポートの各メンバーに独自のローカルユーザーアカウントを提供し、各ユーザーに独自のプライベートsshキーを使用してクライアントのサーバーにアクセスしてもらいます。ある人がサポートグループを離れるとき、あなたはその人のsshキーをクライアントのサーバーから削除します。これは、スタッフが秘密のsshキーを知らないようにすることを心配する必要がなくなったことを意味します。

6
roaima

本当にやりたいのは、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証明書」までスクロールダウン)です。

期間限定で有効になるようにキーに署名できることに特に注意してください。そうすれば、キーは自動的に期限切れになります。

11
galaxy

Sudoまたはsetuid-executable(特別な目的non-rootアカウント)を介して呼び出されるsshのラッパースクリプトに関連するいくつかの異なる回答があります。 nkmsによると のように、すべての引数をsshに渡すと、ユーザーは保護しようとしているsshキーを使用して任意の操作を実行できます。他の極端なものは、ホスト名のみを許可することです。

OPは、管理者が物事をアップロードできる必要があると述べています。

2つの異なるfixed-args-to-sshラッパーを持つことができます。 1つはログインシェル用、もう1つはscp用です。ホスト名(およびアップロードするファイル名)以外のユーザー指定の引数はありません。

または、getopt自体を使用して非常に限られたオプションを解析し、ほとんど修正されたsshコマンドにプラグインするラッパースクリプト。認識されないオプションを無視(またはエラー)するのが最善の方法です。

「危険な」sshオプションを除外しようとしないでください。対話型ログイン、またはファイル(ローカルおよびリモートファイル名)のアップロードの2つのことを実行できるラッパーを作成するだけです。あなたはまだそこでいくつかの消毒をする必要があると思います。

実際、これはまだ間違いやすいです。ユーザーがsshキーを保持しているファイルをローカルファイルとして提供しないようにする方法を見つける必要があります。したがって、何も許可しないことから始めるのではなく、許可しない必要があるすべてのことをまだ考えようとしています。ファイル名に@または:が含まれていないことを確認することから始めます。

2
Peter Cordes

SSHプロキシサーバーを設定する場合は、スタッフユーザーのシェル(/etc/passwd)は、bashなどのシェルではなく、シェルアクセスを許可しない単純なスクリプトに設定されます。代わりに、ターゲットのホスト名(read target)、次にexec ssh "support@$target"

このようなプロキシを使用すると、scpなどのツールを使用して顧客のマシンとの間でファイルを転送することが困難になる可能性があることに注意してください。これは問題または利点かもしれません!

1
Toby Speight

サポート担当者は常にそのプロキシマシンを介して、そこからのみ接続するため、クライアントは単純に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 としてログインします。 。

0
Ángel

ラッパーバイナリを使用する

この特定のユースケース(以下の重要な注意事項を参照)の場合、1つの可能性は、これらの発信SSH接続専用のユーザー(たとえばsupport-ssh)を作成し、/usr/bin/sshを実行する小さなラッパーバイナリをインストールすることです。

  • sshバイナリ自体をコピー+ chmodしないでください。セキュリティ更新プログラムを適用するたびに、バイナリを再コピーすることを忘れないためです。
  • また、rootをより特権のあるユーザーとして使用しないでください。これは、私が信頼する理由から明らかです。

これは、次のトレードオフを使用して、Sudoを使用して特権をsupport-sshアカウントの特権に昇格させるのと機能的に同等の代替手段です。

  • これはSudoよりも小さくてスリムなので、構成エラーが意図した以上に開くリスクが少なくなります。
  • それを正しくコーディングするのはあなたの責任です-あなたが非常に注意そして(理想的には)セキュリティクリティカルなコーディングの経験がある場合にのみこれを行ってください。
  • Sudoよりも具体的にするように調整できます(ただし、記述するコードが多いほど、セキュリティを監査する必要があります)。

ラッパーバイナリは、HOMEsupport-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]が許可されたホスト名のセットに含まれていることを確認することをお勧めします。または、制限を緩和し、オプション引数(のサブセット)を許可します。環境変数を完全に置き換えることもできます(ただし、TERMLC_*などの重要な変数は保持してください)。 LD_LIBRARY_PATHLD_PRELOADは特に危険であることに注意してください。

必要に応じて、同様のラッパープログラムをscpに提供できます。

適用性に関する注記

この回答は、ユーザーが契約上手順に従う義務があり、それらに違反した場合の制裁(解雇など)があるという質問の特定の状況に対処します。決心した攻撃者が不正アクセスを取得するのを防ぐのではなく、従業員が何気なく秘密鍵をコピーするのを防ぎたいと考えています。

私は、セキュリティは技術的防御と非技術的防御の両方によって達成され、ここで、またはSudoを使用して達成されるバランスは提示された状況に適していると考えています。

0
Toby Speight