- なぜ OpenSSH 証明書を使うのですか?
- GitLab Shell経由でのSSH証明書ルックアップの設定
- プリンシパルとセキュリティ
authorized_keys
ファイルとのやりとり- その他のセキュリティ上の注意点
- SSHキーがないユーザーに関するグローバルな警告を無効にします。
OpenSSHのAuthorizedPrincipalsCommandによるユーザー検索
GitLab 11.2で導入されました。
GitLabのデフォルトのSSH認証では、ユーザーがSSHトランスポートを使用する前にSSH公開キーをアップロードする必要があります。
特に、SSHキーがユーザーに発行された一時的なもので、発行から24時間後に失効するものである場合などです。
そのようなセットアップでは、常に新しい鍵をGitLabにアップロードするために、外部の自動化されたプロセスが必要になります。
AuthorizedKeysCommand
がフィンガープリントを受け付ける必要があるため、OpenSSH のバージョンは 6.9 以上が必要です。サーバー上のOpenSSHのバージョンを確認してください。なぜ OpenSSH 証明書を使うのですか?
OpenSSH証明書を使うことで、GitLabのどのユーザーが鍵を所有しているかという情報はすべて鍵自体にエンコードされており、OpenSSH自体が、ユーザーがこれを偽造できないことを保証しています。
正しく設定すれば、ユーザーのSSHキーをGitLabにアップロードする必要がなくなります。
GitLab Shell経由でのSSH証明書ルックアップの設定
SSH 証明書の完全な設定方法はこのドキュメントの範囲外です。どのように動作するかはOpenSSH のPROTOCOL.certkeys
(たとえばRedHat のドキュメント) を参照ください。
すでに SSH 証明書をセットアップしていて、CA のTrustedUserCAKeys
をsshd_config
などに追加していると仮定します:
TrustedUserCAKeys /etc/security/mycompany_user_ca.pub
通常はTrustedUserCAKeys
をMatch 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
[...]
[...]
技術的には厳密にはそうではありません。たとえば、prod-aearnfjord
通常ユーザーとしてサーバーにサインインする SSH 証明書 prod-aearnfjord
であればそうなる可能性がありますが、その場合は私たちが提供するデフォルトを使うのではなく、独自のAuthorizedPrincipalsCommand
を指定してマッピングを行う必要があります。
重要なのは、AuthorizedPrincipalsCommand
が何らかの方法で “鍵ID” から GitLab のユーザー名にマッピングできなければならないということです。デフォルトのコマンドでは、この二つの間に 1=1 のマッピングがあると仮定しています。これは、デフォルトの公開鍵とユーザー名のマッピングのようなものに頼るのではなく、鍵そのものから GitLab のユーザー名を抽出できるようにするためです。
sshd_config
内部でgit
ユーザー用に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
プリンシパルとセキュリティ
プリンシパルはいくつでも指定でき、sshd_config(5)
のAuthorizedPrincipalsFile
ドキュメントで説明されているように、authorized_keys
の複数行の出力に変換されます。
通常、OpenSSH でAuthorizedKeysCommand
を使う場合、プリンシパルとはそのサーバーへのログインを許可された「グループ」のことです。しかし、GitLabではOpenSSHの要求に応えるためだけに使われるもので、事実上、”key ID “が正しいかどうかだけを気にしています。一旦それが抽出されると、GitLabはそのユーザーに対して独自のACLを強制します(例えば、そのユーザーがアクセスできるプロジェクトなど)。
そのため、許可する内容は大目に見てもかまいません。たとえば、そのユーザーが GitLab にアクセスできない場合は、無効なユーザーであることを示すメッセージとともにエラーが発生します。
authorized_keys
ファイルとのやりとり
SSH 証明書はauthorized_keys
ファイルと組み合わせて使用することができます。上記の設定に従ってauthorized_keys
ファイルを設定しても、フォールバックとして機能します。
これはAuthorizedPrincipalsCommand
がユーザーを認証できない場合、OpenSSH は~/.ssh/authorized_keys
(またはAuthorizedKeysCommand
) にフォールバックするからです。
ですから、データベースの SSH キーを高速に検索する方法と、 この方法を併用する理由があるかもしれません。一般的なユーザーには 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キーをアップロードすることは期待されていないので、これは逆効果です。
この警告をグローバルに無効にするには、”Application settings -> Account and limit settings” で “Show user add SSHキー message” 設定を無効にしてください。
この設定は特にSSH証明書を使用するために追加されましたが、他の理由で警告を非表示にしたい場合は、証明書を使用せずにオフにすることができます。