OpenSSH の AuthorizedPrincipalsCommand を使ったユーザ検索

GitLab Community Edition 11.2で利用可能です。

GitLabのデフォルトのSSH認証では、SSHトランスポートを使う前にSSH公開キーをアップロードする必要があります。

集中管理された(たとえば企業の)環境では、特にSSHキーがユーザーに発行された一時的なキーである場合、たとえば発行から24時間後に失効するようなキーである場合、これはオペレーション上面倒なことになります。

このようなセットアップでは、新しい鍵を常にGitLabにアップロードするために、外部の自動化されたプロセスが必要になります。

警告:OpenSSH のバージョン 6.9 以上が必要です。このバージョンではAuthorizedPrincipalsCommand 設定オプションが導入されているからです。 CentOS 6 をお使いの場合は、以下の指示に従って最新バージョンをコンパイルしてください。

なぜOpenSSH証明書を使うのですか?

OpenSSH証明書を使うことで、GitLabのどのユーザーがその鍵を所有しているかという情報はすべて鍵自体にエンコードされており、OpenSSH自体が、ユーザーがこれを偽造できないことを保証しています。

正しく設定すれば、ユーザーのSSHキーをGitLabにアップロードする必要がなくなります。

GitLab Shell を使った SSH 証明書検索の設定

SSH 証明書を完全にセットアップする方法は、このドキュメントの範囲外です。 その方法についてはOpenSSH のPROTOCOL.certkeysを、それについては RedHat のドキュメントなどを参照してください。

すでにSSH証明書をセットアップしていて、CAのTrustedUserCAKeyssshd_configに追加していると仮定します:

TrustedUserCAKeys /etc/security/mycompany_user_ca.pub

通常、TrustedUserCAKeysMatch User git の下にスコープされません。GitLab サーバー自体へのシステムログインにも使われるからです。しかし、あなたのセットアップによって異なるかもしれません。CA が GitLab だけに使われるのであれば、Match User git セクション(後述)にこれを置くことを検討してください。

そのCAが発行するSSH証明書は、GitLab上のそのユーザーのユーザー名に対応する “key ID “を持たなければなりません

$ ssh-add -L | grep cert | ssh-keygen -L -f -

(stdin):1:
        Type: ssh-rsa-cert-v01@openssh.com user certificate
        Public key: RSA-CERT SHA256:[...]
        Signing CA: RSA SHA256:[...]
        Key ID: "aearnfjord"
        Serial: 8289829611021396489
        Valid: from 2018-07-18T09:49:00 to 2018-07-19T09:50:34
        Principals:
                sshUsers
                [...]
        [...]

技術的には厳密にはそうではありません。例えば、SSHprod-aearnfjord 証明書であれば、通常そのユーザーとしてサーバーにログイン prod-aearnfjordすることができますが、その場合は、デフォルトのものを使うのではなく、独自のAuthorizedPrincipalsCommand

重要なのは、AuthorizedPrincipalsCommand 、何らかの方法で「鍵ID」からGitLabのユーザー名にマッピングできなければならないということです。デフォルトの公開鍵とユーザー名のマッピングのようなものに頼るのではなく、鍵そのものからGitLabのユーザー名を抽出できるようにするのが目的なので、デフォルトのコマンドでは両者の間に1=1のマッピングがあると仮定しています。

それから、sshd_configgit ユーザー用にAuthorizedPrincipalsCommand を設定します。GitLab に同梱されているデフォルトのユーザーを使えるといいですね:

Match User git
    AuthorizedPrincipalsCommandUser root
    AuthorizedPrincipalsCommand /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell-authorized-principals-check %i sshUsers

このコマンドは次のような出力を出します:

command="/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell username-{KEY_ID}",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty {PRINCIPAL}

ここで、{KEY_ID} はスクリプトに渡された%i 引数 (例:aeanfjord)、{PRINCIPAL} はスクリプトに渡されたプリンシパル (例:sshUsers)。

sshUsers の部分をカスタマイズする必要があります。GitLab にログインできるすべてのユーザーの鍵の一部であることが保証されているプリンシパルを指定するか、あるいはプリンシパルのリストを用意して、そのうちのひとつをそのユーザーに指定する必要があります:

    [...]
    AuthorizedPrincipalsCommand /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell-authorized-principals-check %i sshUsers windowsUsers

校長とセキュリティ

AuthorizedPrincipalsFile ドキュメントsshd_config(5)で説明されているように、プリンシパルはいくつでも指定でき、これらは複数行のauthorized_keys 出力に変換されます。

通常、OpenSSH でAuthorizedKeysCommand を使う場合、プリンシパルはそのサーバーへのログインを許可された “グループ “です。 しかし、GitLab では、OpenSSH の要求に応えるためだけに使われます。私たちは事実上、”キー ID “が正しいかどうかだけを気にしています。いったんそれが抽出されると、GitLab はそのユーザーに対して独自の ACL を適用します (たとえば、そのユーザーがアクセスできるプロジェクトなど)。

もしそのユーザーが GitLab にまったくアクセスできない場合は、無効なユーザーであるというメッセージが表示されてエラーになるだけです。

authorized_keys ファイルとのやりとり

SSH証明書は、authorized_keysファイルと組み合わせて使用することができます。上記の設定に従って設定された場合、authorized_keys ファイルはフォールバックとして機能します。

これはAuthorizedPrincipalsCommand がユーザを認証できない場合、OpenSSH は~/.ssh/authorized_keys (あるいはAuthorizedKeysCommand) にフォールバックするからです。

そのため、“Fast lookup of authorized SSH keys in the database”メソッドを併用する理由があるかもしれません。 一般ユーザには SSH 証明書を使い、デプロイ鍵には~/.ssh/authorized_keysフォールバックを使うことになるでしょう。

しかし、通常のユーザーはすべて高速パス(AuthorizedPrincipalsCommand )を使用し、 自動デプロイキーアクセスだけが~/.ssh/authorized_keys、デプロイキーの数よりも通常ユーザー用のキーの数(特に更新された場合)の方が多いため、そのようなことをする理由がないと感じるかもしれません。

その他のセキュリティ上の注意点

ユーザは手動で SSH 公開キーをプロファイルにアップロードすることで SSH 証明書認証を回避することができます。~/.ssh/authorized_keys のフォールバック認証に頼ってください。 現在のところこれを防ぐ機能はありませんが、追加するためのオープンリクエストがあります。

このような制限は、例えばgitlab-shell-authorized-keys-check から返された発見されたkey-IDがデプロイ鍵かどうかをチェックするカスタムAuthorizedKeysCommand を提供することでハックすることができます(デプロイ鍵でない鍵はすべて拒否されるべきです)。

SSHキーがないユーザーに関するグローバルな警告を無効にします。

デフォルトでは、GitLab は SSH キーをプロファイルにアップロードしていないユーザーに対して “You won’t be able to pull or push project code via SSH” という警告を表示します。

SSH証明書を使う場合、ユーザが自分の鍵をアップロードすることは期待されていないので、これは逆効果です。

この警告をグローバルに無効にするには、「アプリケーションの設定」→「アカウントと制限の設定」で、「SSHキーを追加したユーザーのメッセージを表示する」の設定を無効にしてください。

この設定は特にSSH証明書を使うために追加されましたが、他の理由で警告を非表示にしたい場合は、証明書を使わずにオフにすることもできます。