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

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

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

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

警告:AuthorizedKeysCommand 、フィンガープリントを受け付ける必要があるため、OpenSSHのバージョンは6.9以上が必要です。これらの手順は、2017年9月時点でCentOS 6に含まれているものなど、古いバージョンのOpenSSHを使用したインストールを破壊します。 CentOS 6でこの機能を使用する場合は、続行する前に、カスタムOpenSSHパッケージをビルドしてインストールする方法の手順に従ってください。

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

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

Geo のセットアップの一環として、プライマリノードとセカンダリノードの両方について、以下に説明する手順を実行する必要があります。ただし、データベースのレプリケーションが機能していれば、セカンダリにも自動的に反映されるため、Write to "authorized keys" file のチェックボックスはプライマリノードでのみチェックを外す必要があることに注意してください。

GitLab Shell による高速ルックアップの設定

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

sshd_config ファイルに以下を追加してください。これは通常/etc/ssh/sshd_configにありますが、Omnibus 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が機能していることを確認してください。

プルに成功したということは、GitLabがそのキーをデータベースから見つけることができたということです。

注:Omnibus Dockerについては、GitLab 11.11以降ではデフォルトでAuthorizedKeysCommand
注意:ソースからのインストールの場合、このコマンドは、ソースからのインストー ルの指示に従うと、/home/git/gitlab-shell/bin/gitlab-shell-authorized-keys-check に置かれます。このコマンドは、root が所有し、グループや他の人が書き込みできないようにする必要があるため、 どこか別の場所にラッパースクリプトを作成することを検討するとよいでしょう。 必要に応じて、このコマンドの所有者を変更することも検討できますが、その場合、gitlab-shell のアップグレード時に一時的に所有者を変更する必要があるかもしれません。
注意:SSHが完全に動作することが確認されるまで、書き込みを無効にしないでください。

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

GitLabインストールの管理エリア > 設定 > ネットワーク > パフォーマンスの最適化でWrite to "authorized_keys" file のチェックを外すことで、authorized_keys ファイルへの書き込みを無効にすることができます。

Write to authorized keys setting

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

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

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

これは簡単な概要であり、詳細については上記の説明を参照してください。

  1. authorized_keys ファイルの再構築
  2. アプリケーション設定でauthorized_keys ファイルへの書き込みを有効にします。
  3. /etc/ssh/sshd_config または Omnibus Docker を使用している場合は/assets/sshd_config からAuthorizedKeysCommand 行を削除します。
  4. リロードsshdsudo service sshd reload
  5. /opt/gitlab-shell/authorized_keys ファイルを削除します。

CentOS 6用OpenSSHのカスタムバージョンのコンパイル

Ubuntu 16.04にはOpenSSH 7.2が同梱されているため、Ubuntu 16.04ユーザーにとってカスタムバージョンのOpenSSHをビルドする必要はありません。

CentOS 7.0 - 7.3 をお使いの場合は、この手順を実行せずに CentOS 7.4 にアップグレードすることを強くお勧めします。これはyum updateを実行するのと同じくらい簡単です。

CentOS 6のユーザーは、データベース経由でSSHルックアップを有効にするために、独自のOpenSSHパッケージをビルドする必要があります。 OpenSSH 7.5のビルドには、以下の手順を使用できます:

  1. まず、パッケージをダウンロードし、必要なパッケージをインストールします:

    sudo su -
    cd /tmp
    curl --remote-name https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-7.5p1.tar.gz
    tar xzvf openssh-7.5p1.tar.gz
    yum install rpm-build gcc make wget openssl-devel krb5-devel pam-devel libX11-devel xmkmf libXt-devel
    
  2. ファイルを適切な場所にコピーしてビルドの準備をします:

    mkdir -p /root/rpmbuild/{SOURCES,SPECS}
    cp ./openssh-7.5p1/contrib/redhat/openssh.spec /root/rpmbuild/SPECS/
    cp openssh-7.5p1.tar.gz /root/rpmbuild/SOURCES/
    cd /root/rpmbuild/SPECS
    
  3. 次に、スペック設定を適切に行います:

    sed -i -e "s/%define no_gnome_askpass 0/%define no_gnome_askpass 1/g" openssh.spec
    sed -i -e "s/%define no_x11_askpass 0/%define no_x11_askpass 1/g" openssh.spec
    sed -i -e "s/BuildPreReq/BuildRequires/g" openssh.spec
    
  4. RPMを構築します:

    rpmbuild -bb openssh.spec
    
  5. RPMが構築されていることを確認します:

    ls -al /root/rpmbuild/RPMS/x86_64/
    

    以下のように表示されるはずです:

    total 1324
    drwxr-xr-x. 2 root root   4096 Jun 20 19:37 .
    drwxr-xr-x. 3 root root     19 Jun 20 19:37 ..
    -rw-r--r--. 1 root root 470828 Jun 20 19:37 openssh-7.5p1-1.x86_64.rpm
    -rw-r--r--. 1 root root 490716 Jun 20 19:37 openssh-clients-7.5p1-1.x86_64.rpm
    -rw-r--r--. 1 root root  17020 Jun 20 19:37 openssh-debuginfo-7.5p1-1.x86_64.rpm
    -rw-r--r--. 1 root root 367516 Jun 20 19:37 openssh-server-7.5p1-1.x86_64.rpm
    
  6. パッケージをインストールしてください。 OpenSSH パッケージは/etc/pam.d/sshdを独自のバージョンに置き換えるので、 ユーザがログインできなくなる可能性があります:

    timestamp=$(date +%s)
    cp /etc/pam.d/sshd pam-ssh-conf-$timestamp
    rpm -Uvh /root/rpmbuild/RPMS/x86_64/*.rpm
    yes | cp pam-ssh-conf-$timestamp /etc/pam.d/sshd
    
  7. インストールされているバージョンを確認します。 別のWindowsで、サーバーへのログインを試みます:

    ssh -v <your-centos-machine>
    

    debug1: Remote protocol version 2.0, remote software version OpenSSH_7.5” という行が表示されるはずです。

    そうでない場合は、sshd (例:systemctl restart sshd.service)を再起動する必要があるかもしれません。

  8. 重要!終了する前にサーバーに新しいSSHセッションを開き、すべてが機能していることを確認してください!ダウングレードする必要がある場合は、古いパッケージをインストールするだけです:

    # Only run this if you run into a problem logging in
    yum downgrade openssh-server openssh openssh-clients
    

SELinuxのサポートと制限

GitLab 10.5 で導入されました

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

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