GitlabサーバのSSL証明書の更新で躓いて紆余曲折の果てに和解した話

GitlabにpushしようとしたらSSL証明書の期限が切れている旨のエラーメッセージを吐かれ、pushできなくなりました。

……おかしいな、自動更新を設定しているはずだったのに。

結果

後から分かったことですが、外部からのアクセスに制限をかけていたので認証の処理が走らなかった、というのが自動更新が失敗していた理由でした。

上記の認証の処理については、

  1. certbotのコマンドで認証用のファイルを配置
  2. Let’s Encryptの認証局サーバから1.で設置したファイル(通常、http://example.com/.well-known/acme-challenge/hogehogeのパス)めがけてアクセス
  3. 取得できれば認証成功し、証明書発行

という流れになっているようです。2.で外部からアクセスされるため、80または443ポートが開いている必要があります(ググり過ぎてどこで見た情報だったか失念)。

ちなみに諸々の事情により2.のアクセス元のIPは公開されていないようです(参考: よくある質問 – Let’s Encrypt 総合ポータル)。

そのため、ベーシックなやり方で行う場合は全面的に開けておくことになるかと思います。

途中経過と対処

今回ドツボにハマってしまったのは下記の条件が解決できなかったため。

  1. 最初に「期限が切れてしまったから最初から取得しなおそう」と思って期限切れの証明書をrmしてしまった
  2. 1.の証明書がないため、gitlab-ctl restartしてもGitlabサーバが上がらなくなった(証明書がないためHTTPSを強制する設定だと起動に失敗する)
  3. HTTPに設定変更してもGitlab(というよりはnginx)の/.well-knownへのアクセスが失敗する
  4. Gitllabを一時的に停止してApacheを起動、Apacheを使用すれば/.well-knownへのアクセスは成功し、認証が通る(SSL証明書の新規取得が可能)
  5. 4.の条件(Apache起動)だと、80番ポートが競合するのでnginxが起動できず、Gitlabが上がらない
  6. Let’s Encryptは3ヶ月で期限が切れるので、その度にGitlab停止→Apache起動→手動で証明書更新→Apache停止→Gitlab起動するのはちょっと……

そもそも1.で失敗してしまったわけですが、下に行けば行くほどドツボっぽい感じに……。

で、最終的には「Gitlab(nginx)のHTTPポートを別の番号にし、Apacheと競合しないようにする」ということで解決。

# GitlabのURLはhttps
external_url 'https://example.com'
# Unicornのポート番号を80以外に変更
unicorn['port'] = XXXX

# これはいらない気がする
nginx['redirect_http_to_https'] = false

# 上のUnicornのポートに合わせる
nginx['redirect_http_to_https_port'] = XXXX
# apacheを使う方法に変更するので、逆に下記設定は不要
#nginx['custom_gitlab_server_config'] = "location ^~ /.well-known { root /var/www/letsencrypt; }"

以上のようにgitlab.rbを変更し、ApacheとGitlabを共存させることでひとまず解決させました。

……うーん、力業……。

この記事を書いた人

アバター

アルム=バンド

フルスタックエンジニアっぽい何か。LAMPやNodeからWP、gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。