Let's Encrypt - izudon/izudon.github.io GitHub Wiki

結論

  1. Let's EncryptACME というプロトコルで、
    自動更新の SSL 証明書を発行する無料サービスである。
  2. CertbotACME クライアント であり、
    Linux のディストリビューションにもパッケージとして含まれている。
  3. 従って、ディストリビューションのパッケージから Certbot をインストールし、
    証明書署名要求(CSR) を作成して Certbot のコマンドを叩けば、
    /etc/letsencrypt/ 配下に関係ファイルができ、
    証明書が取り寄せられ自動更新も設定される
  4. あとは署名された証明書のパスをウェブサーバなどの設定ファイルで指定するだけ。

自動更新について補足

1. 残30日となるまでは何も起きない

  • 証明書の自動更新は systemd に登録されるが、
    残30日を切ったところで、証明書署名要求(CSR)が作られるなど、具体的に動いていくよう。
    残30日となるまでは特に何も起きない。
  • 実際、2023-08-03 に登録した 2023-11-01 に期限となる証明書を使っていたところ、
    更新用の最初の証明書署名要求は 2023-10-03(29日前)に作られていた。
  • なおここでじつは、下記のように Port 80 を閉じていなかったため、更新がエラー終了していた。
    このため結果的に(エラーに気づいて解消した)2023-10-29 までは、
    証明書署名要求(CER)が 毎日 作られてしまっており、
    /etc/letsencrypt/csr/ フォルダ内がファイルで溢れていた。

2. Port 80 は 閉じておく

  • 証明書署名要求時に Port 80 を開き認証するというステップがある。
    このときウェブサーバ等で Port 80 が開いていると、エラーとなり、
    証明書の更新ができない。
  • /var/log/letsencrypt/letsencrypt.log を見て気づいた。

実際のエラーメッセージ(抜粋):

certbot.errors.StandaloneBindError: Problem binding to port 80: [Errno 98] Address already in use

3. nginx は 要「自動再読込」

  1. 問題点を解消(Port 80 を閉じる)して半日ほど放置すると、
    証明書は更新できていたようであった(ログや /etc/letsencrypt/ 等で確認)。
  2. ところが、ブラウザで https:// のページを表示し、証明書を確認しても、
    有効期限は元のまま(2023-11-01)である。
  3. 実は、デフォルトで自動設定される、自動更新のスクリプトは、
    nginx の再起動(設定の再読込)を、更新後に起動しない(シンプルな)コマンドだった。
  4. nginx の再起動(設定の再読み込み)をしたのち、設定を、
    nginx の再起動(設定の再読み込み)を含むものに変更しておいた。

(1)の資料

  • /var/log/letsencrypt/letsencrypt.log に、
    実際の証明書署名要求と、それを HTTP で投げている様子が、
    記録されていた。
2023-10-29 00:44:31,208:DEBUG:certbot._internal.client:CSR: CSR(file='/etc/letse
ncrypt/csr/0053_csr-certbot.pem', data=b'-----BEGIN CERTIFICATE REQUEST-----\nMI
ICgDCCAWgCAQAwADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKCc\nG7k1oI3fH2lcpRsx
b4p2DpqugaC8O8D4sSswYcqCvH/VfMqnMn9dF5QNsI6OnH3h\nnwuhLKxnl56OhVAZjyh7L0sG8XMfDn
  :
2023-10-29 00:44:33,441:DEBUG:acme.client:Received response:
HTTP 200
Server: nginx
Date: Sat, 28 Oct 2023 15:44:33 GMT
Content-Type: application/pem-certificate-chain
Content-Length: 5556
Connection: keep-alive
Cache-Control: public, max-age=0, no-cache
Link: <https://acme-v02.api.letsencrypt.org/directory>;rel="index", <https://acme-v02.api.letsencrypt.org/acme/cert/045ebb45217e69701f8f888a4a9b538b41c8/1>;rel="alternate"
Replay-Nonce: drGA4aWAm78fcVxNvR9rzwFcCaVqSWehiyZ1qmtN-uNSCkAigQA
X-Frame-Options: DENY
Strict-Transport-Security: max-age=604800

-----BEGIN CERTIFICATE-----
MIIFCDCCA/CgAwIBAgISBF67RSF+aXAfj4iKSptTi0HIMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
  :
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----

(2)の資料

省略

(3)の資料

/lib/systemd/system/certbot.service

[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://certbot.eff.org/docs
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot -q renew
PrivateTmp=true

(4)の資料

$ sudo systemctl reload nginx

/lib/systemd/system/certbot.service

[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://certbot.eff.org/docs
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot -q renew --post-hook "systemctl reload nginx"
PrivateTmp=true

具体

Certbot のインストール

$ sudo apt install certbot

証明書と鍵の取得

$ sudo certbot certonly --standalone -d www.example.com
  • メールアドレスを聞かれる。
  • 瞬間 Port:80 を閉じてくれと言われる。
    • Let's Encrypt 側(インターネット側)から Port:80 にアクセスして、
      何事かやっていると思われるので、パケットフィルタリングの設定は、
      開けておく必要があるはず。

nginx 等への設定

server {
    :
    ssl_certificate
        /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key
        /etc/letsencrypt/live/www.example.com/privkey.pem;
    :
}

資料