- Let’s Encryptインテグレーションを有効にします。
- HTTPSの手動設定
- リバースプロキシまたはロードバランサーのSSLターミネーションの設定
- カスタムSSL暗号を使用
- HTTP/2プロトコルの設定
- 双方向SSLクライアント認証を有効に
- HTTP Strict Transportセキュリティの設定(HSTS)
- カスタム公開証明書のインストール
- GitLabとSSLの仕組みの詳細
- トラブルシューティング
LinuxパッケージインストールのSSL設定
Linuxパッケージは、SSL設定のためのいくつかの一般的なユースケースをサポートしています。
デフォルトでは、HTTPSは有効になっていません。HTTPSを有効にするには
- Let’s Encryptを使用して、無料でHTTPSを自動化します。
- 独自の証明書を使用して手動で HTTPS を設定します。
次の表は、各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を有効にするには
-
/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
です。ワイルドカード証明書を設定する必要はありません。
- 証明書の有効期限は 90 日です。有効期限が近づくと、
-
GitLab を再設定します:
sudo gitlab-ctl reconfigure
証明書の自動更新
デフォルトのインストールでは、毎月4日の午前0時以降に更新がスケジュールされます。アップストリームのLet’s Encryptサーバーの負荷を分散するため、external_url
の値によって分単位が決定されます。
更新時間を明示的に設定するには
-
/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"
-
GitLab を再設定します:
sudo gitlab-ctl reconfigure
自動更新を無効にするには
-
編集
/etc/gitlab/gitlab.rb
:letsencrypt['auto_renew'] = false
-
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を設定するには:
-
/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
-
GitLab を再設定します:
sudo gitlab-ctl reconfigure
証明書に代替ドメインを追加
Let’s Encrypt証明書に代替ドメイン(またはサブジェクトの代替名)を追加できます。これは、バンドルされているNGINXを 他のバックエンドアプリケーションのリバースプロキシとして使用する場合に役立ちます。
代替ドメインのDNSレコードはGitLabインスタンスを指す必要があります。
Let’s Encrypt証明書に代替ドメインを追加するには:
-
/etc/gitlab/gitlab.rb
を編集し、代替ドメインを追加します:# Separate multiple domains with commas letsencrypt['alt_names'] = ['another-application.example.com']
-
GitLab を再設定します:
sudo gitlab-ctl reconfigure
メインの GitLab アプリケーション用に生成された Let’s Encrypt 証明書には、指定した代替ドメインが含まれます。生成されたファイルは以下の場所にあります:
-
/etc/gitlab/ssl/gitlab.example.com.key
にあります。 -
/etc/gitlab/ssl/gitlab.example.com.crt
証明書
HTTPSの手動設定
HTTPSを有効にするには
-
/etc/gitlab/gitlab.rb
を編集します:-
external_url
をあなたのドメインに設定します。URLのhttps
に注意してください:external_url "https://gitlab.example.com"
-
Let’s Encryptインテグレーションを無効にします:
letsencrypt['enable'] = false
GitLabは再設定するたびにLet’s Encrypt証明書を更新しようとします。手動で作成した証明書を使用する場合は、Let’s Encryptインテグレーションを無効にする必要があります。
-
-
/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 エ ラ ーを防止す る には、 証明書チ ェ イ ン を正 し い順序で完全 に使用す る 必要があ り ます。
-
オプション。
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'
-
GitLab を再設定します:
sudo gitlab-ctl reconfigure
-
オプションです。ファイアウォールを使用している場合は、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 にリダイレクトするには、次のようにします:
-
/etc/gitlab/gitlab.rb
を編集します:nginx['redirect_http_to_https'] = true
-
GitLab を再設定します:
sudo gitlab-ctl reconfigure
デフォルトのHTTPSポートの変更
デフォルト(443)以外のHTTPSポートを使用する必要がある場合は、external_url
の一部として指定してください:
-
/etc/gitlab/gitlab.rb
を編集します:external_url "https://gitlab.example.com:2443"
-
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証明書の別の場所を設定するには、以下の手順に従います:
-
ディレクトリを作成し、適切な権限を与え、
.crt
と.key
ファイルをそのディレクトリに置きます:sudo mkdir -p /mnt/gitlab/ssl sudo chmod 755 /mnt/gitlab/ssl sudo cp gitlab.key gitlab.crt /mnt/gitlab/ssl/
ク ラ イ ア ン ト が接続す る 際の SSL エ ラ ーを防止す る には、 証明書チ ェ イ ン を正 し い順序で完全 に使用す る 必要があ り ます。
-
/etc/gitlab/gitlab.rb
を編集します:nginx['ssl_certificate'] = "/mnt/gitlab/ssl/gitlab.crt" nginx['ssl_certificate_key'] = "/mnt/gitlab/ssl/gitlab.key"
-
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_url
にhttps://
が含まれている場合にSSLを使用するかどうかを自動検出し、SSL終了のためにNGINXを設定します。しかし、GitLabをリバースプロキシや外部のロードバランサーの背後で実行するように設定した場合、環境によってはGitLabアプリケーションの外側でSSLを終了させたくなるかもしれません。
バンドルされているNGINXがSSL終端を処理しないようにするには、次のようにします:
-
/etc/gitlab/gitlab.rb
を編集します:nginx['listen_port'] = 80 nginx['listen_https'] = false
-
GitLab を再設定します:
sudo gitlab-ctl reconfigure
外部のロードバランサーは、200
ステータスコードを返す GitLab エンドポイントにアクセスする必要があるかもしれません(ログインが必要なインストールでは、ルートページはログインページへの302
リダイレクトを返します)。その場合は、ヘルスチェックエンドポイントを活用することをお勧めします。
コンテナ・レジストリ、GitLab Pages、Mattermost などの他のバンドル・コンポーネントも、プロキシされた SSL に対して同様の戦略を使用します。特定のコンポーネントの*_external_url
をhttps://
で設定し、nginx[...]
の設定の前にコンポーネント名を付けます。例えば、GitLab コンテナレジストリの設定は、registry_
を先頭に付けます:
-
/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_
接頭辞) にも使えます。 -
GitLab を再設定します:
sudo gitlab-ctl reconfigure
-
オプション。特定のヘッダ(例えば、
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暗号を変更するには
-
/etc/gitlab/gitlab.rb
を編集します:nginx['ssl_ciphers'] = "CIPHER:CIPHER1"
-
GitLab を再設定します:
sudo gitlab-ctl reconfigure
ssl_dhparam
ディレクティブを有効にします:
-
dhparams.pem
を生成します:openssl dhparam -out /etc/gitlab/ssl/dhparams.pem 2048
-
/etc/gitlab/gitlab.rb
を編集します:nginx['ssl_dhparam'] = "/etc/gitlab/ssl/dhparams.pem"
-
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 サポートを無効にすることができます:
-
/etc/gitlab/gitlab.rb
を編集します:nginx['http2_enabled'] = false
-
GitLab を再設定します:
sudo gitlab-ctl reconfigure
双方向SSLクライアント認証を有効に
Web クライアントに信頼できる証明書による認証を要求するには、2 ウェイ SSL を有効にします:
-
編集
/etc/gitlab/gitlab.rb
:nginx['ssl_verify_client'] = "on" nginx['ssl_client_certificate'] = "/etc/pki/tls/certs/root-certs.pem"
-
オプション。クライアントが有効な証明書を持っていないと判断する前に、NGINXが証明書チェーンのどの程度深い部分まで検証するかを設定できます(デフォルトは
1
)。/etc/gitlab/gitlab.rb
を編集します:nginx['ssl_verify_depth'] = "2"
-
GitLab を再設定します:
sudo gitlab-ctl reconfigure
HTTP Strict Transportセキュリティの設定(HSTS)
HTTP Strict Transport Security(HSTS) はデフォルトで有効になっており、HTTPSを使ってウェブサイトにのみアクセスするようブラウザに通知します。ブラウザはGitLabインスタンスに一度でもアクセスすると、ユーザーが明示的にプレーンHTTP URL (http://
) を入力している場合でも、安全でない接続を試行しないように記憶します。プレーンなHTTP URLはブラウザによって自動的にhttps://
にリダイレクトされます。
デフォルトでは、max_age
は 2 年間に設定されています。これはブラウザが HTTPS でのみ接続することを記憶する期間です。
最大年齢を変更するには
-
/etc/gitlab/gitlab.rb
を編集します:nginx['hsts_max_age'] = 63072000 nginx['hsts_include_subdomains'] = false
max_age
を0
に設定すると、HSTS が無効になります。 -
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コレクションを同梱しています。
カスタム公開証明書をインストールするには
- 秘密鍵証明書からPEMまたはDERエンコードされた公開証明書を生成します。
- 公開証明書ファイルのみを
/etc/gitlab/trusted-certs
ディレクトリにコピーします。複数ノードのインストールの場合は、すべてのノードで証明書をコピーしてください。- カスタムの公開証明書を使うようにGitLabを設定する場合、デフォルトでは、GitLabはGitLabドメイン名に
.crt
拡張子を付けた名前の証明書を見つけることを期待します。例えば、サーバーアドレスがhttps://gitlab.example.com
の場合、証明書の名前はgitlab.example.com.crt
となります。 - GitLabがカスタム公開証明書を使う内部リソースに接続する必要がある場合は、証明書を
/etc/gitlab/trusted-certs
ディレクトリに.crt
拡張子で保存します。関連する外部リソースのドメイン名に基づいてファイル名を付ける必要はありませんが、一貫した命名法を使うことは助けになります。
別のパスとファイル名を指定するには、デフォルトのSSL証明書の場所を変更します。
- カスタムの公開証明書を使うようにGitLabを設定する場合、デフォルトでは、GitLabはGitLabドメイン名に
-
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'))
これが裏で起こっていることです:
- require
openssl
” の行は、インタープリターに/opt/gitlab/embedded/lib/ruby/2.3.0/x86_64-linux/openssl.so
をロードさせます。 -
Net::HTTP
の呼び出しは、/opt/gitlab/embedded/ssl/certs/cacert.pem
にあるデフォルトの証明書バンドルの読み込みを試みます。 - SSL ネゴシエーションが発生します。
- サーバーはSSL証明書を送信します。
- 送信された証明書がバンドルに含まれていれば、SSL は正常に終了します。
- そうでない場合、OpenSSL は事前に定義された証明書ディレクトリ内でフィンガープリントに一致するファイルを検索することで、他の証明書を検証する可能性があります。例えば、証明書がフィンガープリント
7f279c95
を持つ場合、OpenSSL は/opt/gitlab/embedded/ssl/certs/7f279c95.0
を読み込もうとします。
OpenSSL ライブラリはSSL_CERT_FILE
とSSL_CERT_DIR
環境変数の定義に対応しています。前者は読み込むデフォルトの証明書バンドルを定義し、後者はより多くの証明書を検索するディレクトリを定義します。これらの変数は、trusted-certs
ディレクトリに証明書を追加している場合は必要ありません。しかし、何らかの理由で設定する必要がある場合は、環境変数として定義できます。例えば
gitlab_rails['env'] = {"SSL_CERT_FILE" => "/usr/lib/ssl/private/customcacert.pem"}
トラブルシューティング
SSLのトラブルシューティングをご覧ください。