データベース内の作成者SSHキーの高速検索

note
この文書では、authorized_keys ファイルのドロップイン代替について説明します。標準的な (デプロイ鍵を使わない) ユーザはSSH 証明書の使用を検討してください。SSH証明書はより高速ですが、ドロップインで置き換えられるものではありません。

通常の SSH オペレーションはユーザーの数が増えるにつれて遅くなります。 なぜなら OpenSSH はユーザーを作成するためのキーを直線的に探すからです。ユーザーがGitLabにアクセスする権限がない場合など、最悪のケースでは、OpenSSHはファイル全体をスキャンしてキーを探します。これにはかなりの時間とディスク I/O がかかり、ユーザーがリポジトリにプッシュしたりプルしたりするのが遅れてしまいます。さらに悪いことに、ユーザーが頻繁にキーを追加したり削除したりすると、オペレーション・システムがauthorized_keys ファイルをキャッシュできなくなり、ディスクに何度もアクセスすることになります。

GitLab Shellは、GitLabデータベースの高速でインデックス化された検索によってSSHユーザーを作成する方法を提供することで、これを解決します。このページでは、作成者のSSHキーを高速に検索する方法を説明します。

高速ルックアップはGeoに必要です。

クラウドネイティブ GitLab とは異なり、デフォルトでは Linux パッケージインストールはgit ユーザーのホームディレクトリにあるauthorized_keys ファイルを管理します。ほとんどのインストールでは、このファイルは/var/opt/gitlab/.ssh/authorized_keys の下にありますが、以下のコマンドを使ってシステム上のauthorized_keys を探すことができます:

getent passwd git | cut -d: -f6 | awk '{print $1"/.ssh/authorized_keys"}'

authorized_keys ファイルには、GitLabへのアクセスを許可されたユーザーの公開SSHキーがすべて含まれています。しかし、真実の単一のソースを維持するために、Geoはデータベース検索を介してSSH指紋検索を実行するように設定する必要があります。

Geo のセットアップの一環として、プライマリノードとセカンダリノードの両方で以下に説明する手順を実行する必要がありますが、データベースのレプリケーションが機能していればセカンダリにも自動的に反映されるため、プライマリノードでのみ“authorized keys” ファイルへの書き込みのチェックを外す必要があります。

高速ルックアップの設定

GitLab Shellは、GitLabデータベースへの高速でインデックス化されたルックアップによってSSHユーザーを認証する方法を提供します。GitLab ShellはSSHキーのフィンガープリントを使って、ユーザーがGitLabにアクセスする権限があるかどうかをチェックします。

高速ルックアップは以下のSSHサーバで有効にすることができます:

それぞれのサービスに別々のポートを使用することで、両方のサービスを同時に実行することができます。

この場合gitlab-sshd

gitlab-sshd を設定するには、 gitlab-sshd ドキュメント を参照してください。をgitlab-sshd 有効にすると、GitLab Shell と gitlab-sshd高速ルックアップが自動的に使用されるように設定されます。

OpenSSH では

caution
AuthorizedKeysCommand はフィンガープリントを受け付ける必要があるので、 OpenSSH のバージョンは 6.9 以上が必要です。sshd -V でサーバー上の OpenSSH のバージョンを確認してください。

sshd_config ファイルに以下を追加します。このファイルは通常/etc/ssh/sshd_config にありますが、LinuxパッケージのインストールからDockerを使用している場合は/assets/sshd_config にあります:

Match User git    # Apply the AuthorizedKeysCommands to the git user only
  AuthorizedKeysCommand /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell-authorized-keys-check git %u %k
  AuthorizedKeysCommandUser git
Match all    # End match, settings apply to all users again

OpenSSHをリロードします:

# Debian or Ubuntu installations
sudo service ssh reload

# CentOS installations
sudo service sshd reload

authorized_keys ファイルのユーザーキーをコメントアウトして SSH が機能していることを確認し (行頭を# で始めるとコメントアウトされます)、内部マシンからリポジトリを取り出したり実行したりしてみてください:

ssh -T git@gitlab.example.com

プルやウェルカムメッセージが成功したということは、GitLab がデータベースから鍵を見つけられたということです。

note
セルフコンパイルによるインストールの場合、install from sourceの指示に従えばこのコマンドは/home/git/gitlab-shell/bin/gitlab-shell-authorized-keys-check に置かれます。このコマンドはroot が所有し、グループや他の人が書き込みできないようにする必要があるため、どこか別の場所にラッパースクリプトを作成することを検討するとよいでしょう。必要に応じてこのコマンドの所有者を変更することも検討できますが、その場合、gitlab-shell のアップグレード時に一時的に所有者を変更する必要があるかもしれません。
caution
SSHが完全に動作することを確認するまでは、書き込みを無効にしないでください。そうしないと、ファイルはすぐに古くなってしまいます。

ルックアップに失敗した場合(これはよくあることです)も、authorized_keys ファイルはスキャンされます。ですから、大きなファイルが存在する限り、Git SSHのパフォーマンスは多くのユーザーにとって遅いままでしょう。

authorized_keys ファイルへの書き込みを無効にするには、次のようにします:

  1. 左のサイドバーで、Search を選択するか、次のページに進んでください。
  2. Admin Areaを選択します。
  3. 左サイドバーで、「設定」 > 「ネットワーク」を選択します。
  4. パフォーマンスの最適化]を展開します。
  5. SSHキーの認証にauthorized_keysファイルを使用する]チェックボックスをオフにします。
  6. 変更を保存を選択します。

もう一度、UIでユーザーのSSHキーを削除し、新しいキーを追加し、リポジトリをプルしようとして、SSHが機能していることを確認してください。

その後、authorized_keys ファイルをバックアップして削除すると、最高のパフォーマンスが得られます。現在のユーザーの鍵はすでにデータベースに存在しているので、マイグレーションやユーザーが鍵を再追加する必要はありません。

authorized_keys ファイルの使用に戻る方法

この概要は簡単です。詳しくは上記の説明を参照してください。

  1. authorized_keys ファイル を再構築します。
  2. authorized_keys ファイルへの書き込みを有効にします。
    1. 左のサイドバーで、Search を選択するか、次のページに進んでください。
    2. Admin Areaを選択します。
    3. 左サイドバーで、「設定」 > 「ネットワーク」を選択します。
    4. パフォーマンスの最適化]を展開します。
    5. SSHキーの認証にauthorized_keysファイルを使用する]チェックボックスを選択します。
  3. /etc/ssh/sshd_config 、またはLinuxパッケージ・インストールからDockerを使用している場合は/assets/sshd_configAuthorizedKeysCommand の行を削除します。
  4. リロードsshd:sudo service sshd reload.

SELinuxのサポートと制限

GitLabはauthorized_keysSELinuxによるデータベース検索をサポートしています。

SELinuxのポリシーは静的なものなので、GitLabは今のところ内部ウェブサーバのポートを変更する機能をサポートしていません。動的に生成されるわけではないので、管理者は環境用の特別な.te ファイルを作成する必要があります。

追加ドキュメント

gitlab-sshd に関する追加の技術文書はGitLab Shell ドキュメントにあります。

トラブルシューティング

SSHトラフィックが遅い、またはCPU負荷が高い

SSHトラフィックが遅い、またはCPU負荷が高い場合は、/var/log/btmp のサイズを確認し、定期的に、または一定のサイズに達したらローテーションするようにしてください。このファイルが非常に大きい場合、GitLab SSH fast lookupがボトルネックになる頻度が高くなり、パフォーマンスがさらに低下する可能性があります。もし可能であれば、/var/log/btmp を完全に読み込まないようにsshd_config](https://linux.die.net/man/5/sshd_config) で[UsePAM を無効にすることを検討してみてください。

実行中のsshd: git プロセスでstracelsof を実行すると、デバッグ情報が返されます。進行中のGit over SSH接続でIPx.x.x.xstrace を取得するには、次のように実行します:

sudo strace -s 10000 -p $(sudo netstat -tp | grep x.x.x.x | egrep 'ssh.*: git' | sed -e 's/.*ESTABLISHED *//' -e 's#/.*##')

あるいは、実行中の Git over SSH プロセスのlsof を取得します:

sudo lsof -p $(sudo netstat -tp | egrep 'ssh.*: git' | head -1 | sed -e 's/.*ESTABLISHED *//' -e 's#/.*##')