Certbot で発行した証明書を Heroku SSL で利用する
Heroku SSL の機能を確認するため、調査目的で Certbot を利用し証明書を発行した。Certbot で Let’s Encrypt の証明書を取得する場合、有効期限が90日と短く、定期的な更新作業が必要となるため、通常は Heroku の提供する Automated Certificate Management を利用するのが良い。
ACME Challenge
デフォルトは HTTP-01 Challenge で /.well-known/acme-challenge/<token>
でリクエストを受け付ける必要がある。このためにアプリケーションコードを書き換えたくなかったので、DNS-01 Challenge を利用した。Certbot の Manual プラグインには --preferred-challenges
オプションがあり dns
を指定できる。
— https://certbot.eff.org/docs/using.html#manual
DNS-01 Challenge
コマンドを実行すると DNS に追加する必要がある TXT レコードの値が生成される。デフォルトでは /etc/letsencrypt
に保存されるが、今回の例では ~/.certbot
を使用している。
$ certbot certonly --manual \
--config-dir ~/.certbot/config \
--work-dir ~/.certbot/work \
--logs-dir ~/.certbot/logs \
--preferred-challenges dns \
--agree-tos \
-m [email protected] \
-d hello.tetsuya.dev
...
Please deploy a DNS TXT record under the name
_acme-challenge.hello.tetsuya.dev with the following value:
h5VEci-fn-Ia5I8BHCi4yqJKmDM0KFRyEnvb1U41pvw
DNS に TXT レコードを追加後、反映には数分から数十分かかる場合がある。DNS challenge に失敗すると最初からやり直しとなるため、 dig
コマンドを使って DNS から期待通りの TXT レコードの値が期待通り返却されるか、あらかじめ確認する。
$ dig +short TXT _acme-challenge.hello.tetsuya.dev
"h5VEci-fn-Ia5I8BHCi4yqJKmDM0KFRyEnvb1U41pvw"
ENTER を押すと認証が始まる。Congratulations! が表示されたら認証成功。
Heroku に証明書をアップロード
Manually uploading certificates and intermediaries の手順に沿ってアップロードする。
$ heroku certs:add \
~/.certbot/config/live/hello.tetsuya.dev/fullchain.pem \
~/.certbot/config/live/hello.tetsuya.dev/privkey.pem
Resolving trust chain... done
Adding SSL certificate to ⬢ tetsuya... done
Certificate details:
Common Name(s): hello.tetsuya.dev
Expires At: 2021-06-24 02:08 UTC
Issuer: /C=US/O=Let's Encrypt/CN=R3
Starts At: 2021-03-26 02:08 UTC
Subject: /CN=hello.tetsuya.dev
SSL certificate is verified by a root authority.
アップロードした証明書は certs:info
で確認できる。
$ heroku certs
Name Common Name(s) Expires Trusted Type Domains
──────────────── ───────────────── ──────────────────── ─────── ──── ───────
dryosaurus-15681 hello.tetsuya.dev 2021-06-24 02:08 UTC True SNI 0
$ heroku certs:info --name dryosaurus-15681
Fetching SSL certificate dryosaurus-15681 info for ⬢ tetsuya... done
Certificate details:
Common Name(s): hello.tetsuya.dev
Expires At: 2021-06-24 02:08 UTC
Issuer: /C=US/O=Let's Encrypt/CN=R3
Starts At: 2021-03-26 02:08 UTC
Subject: /CN=hello.tetsuya.dev
SSL certificate is verified by a root authority.
Heroku へカスタムドメインの追加
Add a custom domain with a subdomain の手順に沿ってカスタムドメインを登録する。
$ heroku domains:add hello.tetsuya.dev
Configure your app's DNS provider to point to the DNS Target boiling-hamlet-2nu90czoepy3tmpgmkid9s8r.herokudns.com.
For help, see https://devcenter.heroku.com/articles/custom-domains
The domain hello.tetsuya.dev has been enqueued for addition
Run heroku domains:wait 'hello.tetsuya.dev' to wait for completion
Adding hello.tetsuya.dev to ⬢ tetsuya... done
ドメイン登録後に表示される DNS Target を CNAME レコードに追加してしばらく待つと、カスタムドメインでのアクセスが可能になる。CNAME を忘れた場合 heroku domains
コマンドで確認ができる。
$ heroku domains
=== tetsuya Heroku Domain
tetsuya.herokuapp.com
=== tetsuya Custom Domains
Domain Name DNS Record Type DNS Target SNI Endpoint
───────────────── ─────────────── ───────────────────────────────────────────────────── ────────────────
hello.tetsuya.dev CNAME boiling-hamlet-2nu90czoepy3tmpgmkid9s8r.herokudns.com dryosaurus-15681
接続確認
アップロードした証明証が利用されているか確認。Issuer が Let’s Encrypt になっていることがわかる。
$ openssl s_client -connect boiling-hamlet-2nu90czoepy3tmpgmkid9s8r.herokudns.com:443 \
-servername hello.tetsuya.dev 2>/dev/null | \
openssl x509 -noout -issuer -subject -startdate -enddate
issuer=C=US, O=Let's Encrypt, CN=R3
subject=CN=hello.tetsuya.dev
notBefore=Mar 26 02:08:42 2021 GMT
notAfter=Jun 24 02:08:42 2021 GMT