LinuxパッケージインストールのSSL設定

Linuxパッケージは、SSL設定のためのいくつかの一般的なユースケースをサポートしています。

デフォルトでは、HTTPSは有効になっていません。HTTPSを有効にするには

  • Let’s Encryptを使用して、無料でHTTPSを自動化します。
  • 独自の証明書を使用して手動で HTTPS を設定します。
note
プロキシやロードバランサーなどの外部デバイスを使ってGitLabホスト名のSSLを終了する場合は、外部、プロキシ、ロードバランサーのSSL終了をご覧ください。

次の表は、各GitLabサービスがどの方法をサポートしているかを示しています。

サービス|手動SSL|Let’s Encryptインテグレーション|-|-|-|-||GitLabインスタンスドメイン|はいはい||コンテナレジストリ|はい||Mattermost|はい||GitLabページ|はい|いいえ

Let’s Encryptインテグレーションを有効にします。

external_url が HTTPS プロトコルで設定され、他の証明書が設定されていない場合、Let’s Encryptはデフォルトで有効になります。

前提条件:

  • ポート80 および443 は、検証チェックを実行する公開 Let’s Encrypt サーバにアクセス可能でなければなりません。標準以外のポートでは検証は動作しません。環境が非公開またはエアギャップである場合、certbot(Let’s Encryptが使用するツール)はLet’s Encrypt証明書をインストールする手動方法を提供します。

Let’s Encryptを有効にするには

  1. /etc/gitlab/gitlab.rb を編集し、以下のエントリを追加または変更します:

    ## GitLab instance
    external_url "https://gitlab.example.com"         # Must use https protocol
    letsencrypt['contact_emails'] = ['foo@email.com'] # Optional
       
    ## Container Registry (optional), must use https protocol
    registry_external_url "https://registry.example.com"
    #registry_nginx['ssl_certificate'] = "path/to/cert"      # Must be absent or commented out
       
    ## Mattermost (optional), must use https protocol
    mattermost_external_url "https://mattermost.example.com"
    
    • 証明書の有効期限は 90 日です。有効期限が近づくと、contact_emails に指定した電子メール・アドレスにアラートが送信されます。
    • GitLab インスタンスは証明書のプライマリドメイン名です。コンテナ・レジストリなどの追加サービスは、同じ証明書の代替ドメイン名として追加されます。上の例では、プライマリドメインはgitlab.example.com で、コンテナレジストリのドメインはregistry.example.com です。ワイルドカード証明書を設定する必要はありません。
  2. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    

証明書の自動更新

デフォルトのインストールでは、毎月4日の午前0時以降に更新がスケジュールされます。アップストリームのLet’s Encryptサーバーの負荷を分散するため、external_url の値によって分単位が決定されます。

更新時間を明示的に設定するには

  1. /etc/gitlab/gitlab.rb を編集します:

    # Renew every 7th day of the month at 12:30
    letsencrypt['auto_renew_hour'] = "12"
    letsencrypt['auto_renew_minute'] = "30"
    letsencrypt['auto_renew_day_of_month'] = "*/7"
    
  2. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    
note
証明書は30日以内に期限が切れる場合のみ更新されます。例えば、毎月1日の00:00に更新するように設定し、31日に証明書の有効期限が切れる場合、証明書は更新される前に失効します。

自動更新を無効にするには

  1. 編集/etc/gitlab/gitlab.rb

    letsencrypt['auto_renew'] = false
    
  2. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    

証明書の手動更新

以下のいずれかのコマンドを使用して、Let’s Encrypt 証明書を手動で更新します:

sudo gitlab-ctl reconfigure
sudo gitlab-ctl renew-le-certs

前述のコマンドは、証明書の有効期限が近い場合にのみ更新を生成します。更新中にエラーが発生した場合は、アップストリームの速度制限を考慮してください。

Let’s Encrypt以外のACMEサーバを使用する場合

Let’s Encrypt以外のACMEサーバーを使い、GitLabがそれを使って証明書を取得するように設定することもできます。独自のACMEサーバーを提供しているサービスには次のようなものがあります:

カスタムACMEサーバーを使うようにGitLabを設定するには:

  1. /etc/gitlab/gitlab.rb を編集し、ACME エンドポイントを設定します:

    external_url 'https://example.com'
    letsencrypt['acme_staging_endpoint'] = 'https://ca.internal/acme/acme/directory'
    letsencrypt['acme_production_endpoint'] = 'https://ca.internal/acme/acme/directory'
    

    カスタム ACME サーバが提供する場合、ステージングエンドポイントも使用します。最初にステージングエンドポイントをチェックすることで、ACME production にリクエストを送信する前に ACME 設定が正しいことを確認できます。設定作業中に ACME のレート制限を避けるために、このようにしてください。

    デフォルト値は

    https://acme-staging-v02.api.letsencrypt.org/directory
    https://acme-v02.api.letsencrypt.org/directory
    
  2. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    

証明書に代替ドメインを追加

Let’s Encrypt証明書に代替ドメイン(またはサブジェクトの代替名)を追加できます。これは、バンドルされているNGINXを 他のバックエンドアプリケーションのリバースプロキシとして使用する場合に役立ちます。

代替ドメインのDNSレコードはGitLabインスタンスを指す必要があります。

Let’s Encrypt証明書に代替ドメインを追加するには:

  1. /etc/gitlab/gitlab.rb を編集し、代替ドメインを追加します:

    # Separate multiple domains with commas
    letsencrypt['alt_names'] = ['another-application.example.com']
    
  2. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    

メインの GitLab アプリケーション用に生成された Let’s Encrypt 証明書には、指定した代替ドメインが含まれます。生成されたファイルは以下の場所にあります:

  • /etc/gitlab/ssl/gitlab.example.com.key にあります。
  • /etc/gitlab/ssl/gitlab.example.com.crt 証明書

HTTPSの手動設定

caution
NGINXの設定は、HSTSを使用して今後365日間、セキュアな接続を介してのみGitLabインスタンスと通信するようにブラウザとクライアントに伝えます。設定オプションの詳細については、HTTP Strict Transport Securityの設定を参照してください。HTTPSを有効にする場合、少なくとも今後24ヶ月間はインスタンスへのセキュアな接続を提供する必要があります。

HTTPSを有効にするには

  1. /etc/gitlab/gitlab.rb を編集します:
    1. external_url をあなたのドメインに設定します。URLのhttps に注意してください:

      external_url "https://gitlab.example.com"
      
    2. Let’s Encryptインテグレーションを無効にします:

      letsencrypt['enable'] = false
      

      GitLabは再設定するたびにLet’s Encrypt証明書を更新しようとします。手動で作成した証明書を使用する場合は、Let’s Encryptインテグレーションを無効にする必要があります。

  2. /etc/gitlab/ssl ディレクトリを作成し、そこに鍵と証明書をコピーします:

    sudo mkdir -p /etc/gitlab/ssl
    sudo chmod 755 /etc/gitlab/ssl
    sudo cp gitlab.example.com.key gitlab.example.com.crt /etc/gitlab/ssl/
    

    この例では、ホスト名がgitlab.example.com であるため、Linux パッケージのインストールは、それぞれ/etc/gitlab/ssl/gitlab.example.com.key/etc/gitlab/ssl/gitlab.example.com.crt という秘密鍵と公開証明書のファイルを探します。必要であれば、別の場所と証明書名を使用できます。

    ク ラ イ ア ン ト が接続す る 際の SSL エ ラ ーを防止す る には、 証明書チ ェ イ ン を正 し い順序で完全 に使用す る 必要があ り ます。

  3. オプション。certificate.key ファイルがパスワードで保護されている場合、GitLab を再設定する際に NGINX がパスワードを要求することはありません。この場合、Linux パッケージのインストールはエラーメッセージを出さずに静かに失敗します。

    キーファイルのパスワードを指定するには、パスワードをテキストファイル(たとえば、/etc/gitlab/ssl/key_file_password.txt )に保存し、/etc/gitlab/gitlab.rb に以下を追加します:

    nginx['ssl_password_file'] = '/etc/gitlab/ssl/key_file_password.txt'
    
  4. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    
  5. オプションです。ファイアウォールを使用している場合は、443番ポートを開いてHTTPSトラフィックの受信を許可する必要があります:

    # UFW example (Debian, Ubuntu)
    sudo ufw allow https
       
    # lokkit example (RedHat, CentOS 6)
    sudo lokkit -s https
       
    # firewall-cmd (RedHat, Centos 7)
    sudo firewall-cmd --permanent --add-service=https
    sudo systemctl reload firewalld
    

既存の証明書を更新する場合は、別の手順に従ってください。

HTTP リクエストを以下にリダイレクトします。HTTPS

デフォルトでは、https で始まるexternal_url を指定すると、NGINX はポート 80 で暗号化されていない HTTP トラフィックをリッスンしなくなります。すべての HTTP トラフィックを HTTPS にリダイレクトするには、次のようにします:

  1. /etc/gitlab/gitlab.rb を編集します:

    nginx['redirect_http_to_https'] = true
    
  2. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    
note
この動作は、Let’s Encryptインテグレーションを使用している場合、デフォルトで有効になっています。

デフォルトのHTTPSポートの変更

デフォルト(443)以外のHTTPSポートを使用する必要がある場合は、external_url の一部として指定してください:

  1. /etc/gitlab/gitlab.rb を編集します:

    external_url "https://gitlab.example.com:2443"
    
  2. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    

デフォルトのSSL証明書の場所を変更

ホスト名がgitlab.example.com の場合、Linux パッケージインストールはデフォルトで/etc/gitlab/ssl/gitlab.example.com.key という秘密鍵と/etc/gitlab/ssl/gitlab.example.com.crt という公開証明書を探します。

SSL証明書の別の場所を設定するには、以下の手順に従います:

  1. ディレクトリを作成し、適切な権限を与え、.crt.key ファイルをそのディレクトリに置きます:

    sudo mkdir -p /mnt/gitlab/ssl
    sudo chmod 755 /mnt/gitlab/ssl
    sudo cp gitlab.key gitlab.crt /mnt/gitlab/ssl/
    

    ク ラ イ ア ン ト が接続す る 際の SSL エ ラ ーを防止す る には、 証明書チ ェ イ ン を正 し い順序で完全 に使用す る 必要があ り ます。

  2. /etc/gitlab/gitlab.rb を編集します:

    nginx['ssl_certificate'] = "/mnt/gitlab/ssl/gitlab.crt"
    nginx['ssl_certificate_key'] = "/mnt/gitlab/ssl/gitlab.key"
    
  3. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    

SSL証明書の更新

SSL証明書の内容が更新されているにもかかわらず、/etc/gitlab/gitlab.rbに設定変更が加えられていない場合、GitLabを再設定してもNGINXには影響しません。代わりに、NGINXが既存の設定と新しい証明書を優雅にリロードするようにする必要があります:

sudo gitlab-ctl hup nginx 
sudo gitlab-ctl hup registry

リバースプロキシまたはロードバランサーのSSLターミネーションの設定

デフォルトでは、Linuxパッケージインストールは、external_urlhttps:// が含まれている場合にSSLを使用するかどうかを自動検出し、SSL終了のためにNGINXを設定します。しかし、GitLabをリバースプロキシや外部のロードバランサーの背後で実行するように設定した場合、環境によってはGitLabアプリケーションの外側でSSLを終了させたくなるかもしれません。

バンドルされているNGINXがSSL終端を処理しないようにするには、次のようにします:

  1. /etc/gitlab/gitlab.rb を編集します:

    nginx['listen_port'] = 80
    nginx['listen_https'] = false
    
  2. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    

外部のロードバランサーは、200 ステータスコードを返す GitLab エンドポイントにアクセスする必要があるかもしれません(ログインが必要なインストールでは、ルートページはログインページへの302 リダイレクトを返します)。その場合は、ヘルスチェックエンドポイントを活用することをお勧めします。

コンテナ・レジストリ、GitLab Pages、Mattermost などの他のバンドル・コンポーネントも、プロキシされた SSL に対して同様の戦略を使用します。特定のコンポーネントの*_external_urlhttps:// で設定し、nginx[...] の設定の前にコンポーネント名を付けます。例えば、GitLab コンテナレジストリの設定は、registry_を先頭に付けます:

  1. /etc/gitlab/gitlab.rb を編集します:

    registry_external_url 'https://registry.example.com'
       
    registry_nginx['listen_port'] = 80
    registry_nginx['listen_https'] = false
    

    同じフォーマットは、Pages (pages_ 接頭辞) と Mattermost (mattermost_ 接頭辞) にも使えます。

  2. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    
  3. オプション。特定のヘッダ(例えば、Host,X-Forwarded-Ssl,X-Forwarded-For,X-Forwarded-Port)を GitLab(と、もし使っているなら Mattermost)に転送するように、リバースプロキシやロードバランサーを設定する必要があるかもしれません。このステップを忘れると、不適切なリダイレクトや、”422 Unprocessable Entity” や “Can’t verify CSRF token authenticity” といったエラーが表示されるかもしれません。

AWS Certificate Manager(ACM) のようないくつかのクラウドプロバイダのサービスは、証明書のダウンロードを許可していません。このため、GitLabインスタンス上で終了するために使用することができません。このようなクラウド・サービスとGitLabの間でSSLが必要な場合は、GitLabインスタンス上で別の証明書を使用する必要があります。

カスタムSSL暗号を使用

デフォルトでは、GitLabはhttps://gitlab.com 、GitLabコミュニティによって貢献された様々なベストプラクティスを組み合わせたSSL暗号を使用しています。

SSL暗号を変更するには

  1. /etc/gitlab/gitlab.rb を編集します:

    nginx['ssl_ciphers'] = "CIPHER:CIPHER1"
    
  2. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    

ssl_dhparam ディレクティブを有効にします:

  1. dhparams.pem を生成します:

    openssl dhparam -out /etc/gitlab/ssl/dhparams.pem 2048
    
  2. /etc/gitlab/gitlab.rb を編集します:

    nginx['ssl_dhparam'] = "/etc/gitlab/ssl/dhparams.pem"
    
  3. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    

HTTP/2プロトコルの設定

デフォルトでは、GitLabインスタンスにHTTPSでアクセスできるように指定すると、HTTP/2プロトコルも有効になります。

LinuxパッケージはHTTP/2プロトコルと互換性のある必要なSSL暗号を設定します。

独自のカスタムSSL暗号を指定し、その暗号がHTTP/2暗号ブラックリストにある場合、GitLabインスタンスにアクセスしようとすると、ブラウザにINADEQUATE_SECURITY のエラーが表示されます。その場合は、暗号リストから問題の暗号を削除することを検討してください。暗号を変更する必要があるのは、非常に特殊なカスタム設定をしている場合だけです。

HTTP/2プロトコルを有効にする理由の詳細については、NGINX HTTP/2ホワイトペーパーをご覧ください。

暗号を変更することができない場合は、HTTP/2 サポートを無効にすることができます:

  1. /etc/gitlab/gitlab.rb を編集します:

    nginx['http2_enabled'] = false
    
  2. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    
note
HTTP/2の設定は、メインのGitLabアプリケーションに対してのみ機能し、GitLab Pages、コンテナ・レジストリ、Mattermostのような他のサービスに対しては機能しません。

双方向SSLクライアント認証を有効に

Web クライアントに信頼できる証明書による認証を要求するには、2 ウェイ SSL を有効にします:

  1. 編集/etc/gitlab/gitlab.rb

    nginx['ssl_verify_client'] = "on"
    nginx['ssl_client_certificate'] = "/etc/pki/tls/certs/root-certs.pem"
    
  2. オプション。クライアントが有効な証明書を持っていないと判断する前に、NGINXが証明書チェーンのどの程度深い部分まで検証するかを設定できます(デフォルトは1 )。/etc/gitlab/gitlab.rb を編集します:

    nginx['ssl_verify_depth'] = "2"
    
  3. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    

HTTP Strict Transportセキュリティの設定(HSTS)

note
HSTSの設定はメインのGitLabアプリケーションに対してのみ機能し、GitLab Pagesやコンテナ・レジストリ、Mattermostなどの他のサービスに対しては機能しません。

HTTP Strict Transport Security(HSTS) はデフォルトで有効になっており、HTTPSを使ってウェブサイトにのみアクセスするようブラウザに通知します。ブラウザはGitLabインスタンスに一度でもアクセスすると、ユーザーが明示的にプレーンHTTP URL (http://) を入力している場合でも、安全でない接続を試行しないように記憶します。プレーンなHTTP URLはブラウザによって自動的にhttps:// にリダイレクトされます。

デフォルトでは、max_age は 2 年間に設定されています。これはブラウザが HTTPS でのみ接続することを記憶する期間です。

最大年齢を変更するには

  1. /etc/gitlab/gitlab.rb を編集します:

    nginx['hsts_max_age'] = 63072000
    nginx['hsts_include_subdomains'] = false
    

    max_age0 に設定すると、HSTS が無効になります。

  2. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    

HSTSとNGINXの詳細については、https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/

カスタム公開証明書のインストール

環境によっては様々なタスクのために外部リソースに接続しますが、GitLabではこれらの接続にHTTPSを使用することができ、自己署名証明書による接続をサポートしています。GitLabには独自のca-certバンドルがあり、/etc/gitlab/trusted-certs ディレクトリに個々のカスタム証明書を置くことで証明書を追加することができます。そしてバンドルに追加します。追加にはopensslのc_rehash メソッドを使います。

GitLabは、証明書の信頼性を検証するために使用される信頼されたルート認証局の公式CAcert.orgコレクションを同梱しています。

note
自己署名証明書を使うインストールでは、Linuxパッケージがこれらの証明書を管理する方法を提供します。この仕組みの技術的な詳細については、このページの一番下にある詳細をご覧ください。

カスタム公開証明書をインストールするには

  1. 秘密鍵証明書からPEMまたはDERエンコードされた公開証明書を生成します。
  2. 公開証明書ファイルのみを/etc/gitlab/trusted-certs ディレクトリにコピーします。複数ノードのインストールの場合は、すべてのノードで証明書をコピーしてください。
    • カスタムの公開証明書を使うようにGitLabを設定する場合、デフォルトでは、GitLabはGitLabドメイン名に.crt 拡張子を付けた名前の証明書を見つけることを期待します。例えば、サーバーアドレスがhttps://gitlab.example.com の場合、証明書の名前はgitlab.example.com.crt となります。
    • GitLabがカスタム公開証明書を使う内部リソースに接続する必要がある場合は、証明書を/etc/gitlab/trusted-certs ディレクトリに.crt 拡張子で保存します。関連する外部リソースのドメイン名に基づいてファイル名を付ける必要はありませんが、一貫した命名法を使うことは助けになります。

    別のパスとファイル名を指定するには、デフォルトのSSL証明書の場所を変更します。

  3. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    

カスタム証明書チェーンの使用

既知のイシューがあるため、カスタム証明書チェーンを使用する場合は、サーバー証明書、中間証明書、ルート証明書を/etc/gitlab/trusted-certs ディレクトリ内の別々のファイルに格納する必要があります。

これはGitLab自身、またはGitLabが接続しなければならない外部リソースがカスタム証明書チェーンを使用している場合の両方に当てはまります。

例えば、GitLab自身には次のように使います:

  • /etc/gitlab/trusted-certs/example.gitlab.com.crt
  • /etc/gitlab/trusted-certs/example.gitlab.com_intermediate.crt
  • /etc/gitlab/trusted-certs/example.gitlab.com_root.crt

GitLabが接続しなければならない外部リソースに対しては、次のように使います:

  • /etc/gitlab/trusted-certs/external-service.gitlab.com.crt
  • /etc/gitlab/trusted-certs/external-service.gitlab.com_intermediate.crt
  • /etc/gitlab/trusted-certs/external-service.gitlab.com_root.crt

GitLabとSSLの仕組みの詳細

LinuxパッケージにはOpenSSLの独自のライブラリが含まれており、コンパイルされたすべてのプログラム(Ruby、PostgreSQLなど)はこのライブラリに対してリンクされています。このライブラリは/opt/gitlab/embedded/ssl/certs で証明書を探すようにコンパイルされています。

Linux パッケージは、/etc/gitlab/trusted-certs/ に追加された証明書をc_rehashツールを使って/opt/gitlab/embedded/ssl/certs にシンボリックリンクすることで、カスタム証明書を管理します。例えば、customcacert.pem/etc/gitlab/trusted-certs/に追加するとします:

$ sudo ls -al /opt/gitlab/embedded/ssl/certs

total 272
drwxr-xr-x 2 root root   4096 Jul 12 04:19 .
drwxr-xr-x 4 root root   4096 Jul  6 04:00 ..
lrwxrwxrwx 1 root root     42 Jul 12 04:19 7f279c95.0 -> /etc/gitlab/trusted-certs/customcacert.pem
-rw-r--r-- 1 root root 263781 Jul  5 17:52 cacert.pem
-rw-r--r-- 1 root root    147 Feb  6 20:48 README

ここで、証明書のフィンガープリントは7f279c95 であり、カスタム証明書にリンクしていることがわかります。

HTTPS リクエストを行うとどうなるでしょうか?簡単な Ruby プログラムを見てみましょう:

#!/opt/gitlab/embedded/bin/ruby
require 'openssl'
require 'net/http'

Net::HTTP.get(URI('https://www.google.com'))

これが裏で起こっていることです:

  1. requireopenssl” の行は、インタープリターに/opt/gitlab/embedded/lib/ruby/2.3.0/x86_64-linux/openssl.so をロードさせます。
  2. Net::HTTP の呼び出しは、/opt/gitlab/embedded/ssl/certs/cacert.pem にあるデフォルトの証明書バンドルの読み込みを試みます。
  3. SSL ネゴシエーションが発生します。
  4. サーバーはSSL証明書を送信します。
  5. 送信された証明書がバンドルに含まれていれば、SSL は正常に終了します。
  6. そうでない場合、OpenSSL は事前に定義された証明書ディレクトリ内でフィンガープリントに一致するファイルを検索することで、他の証明書を検証する可能性があります。例えば、証明書がフィンガープリント7f279c95 を持つ場合、OpenSSL は/opt/gitlab/embedded/ssl/certs/7f279c95.0 を読み込もうとします。

OpenSSL ライブラリはSSL_CERT_FILESSL_CERT_DIR 環境変数の定義に対応しています。前者は読み込むデフォルトの証明書バンドルを定義し、後者はより多くの証明書を検索するディレクトリを定義します。これらの変数は、trusted-certs ディレクトリに証明書を追加している場合は必要ありません。しかし、何らかの理由で設定する必要がある場合は、環境変数として定義できます。例えば

gitlab_rails['env'] = {"SSL_CERT_FILE" => "/usr/lib/ssl/private/customcacert.pem"}

トラブルシューティング

SSLのトラブルシューティングをご覧ください。