Heroku SSL + Let's Encrypt で、ワイルドカードなSSL証明書を設定する


はじめに

  • Heroku で、Let's EncryptのSSL証明書をACM(Automated Certificate Management)で導入できますが、 ワイルドカードに対応していません 。 なので、自分で設定する必要があります。
  • この記事では、自動更新に関する内容を含みません。ごめんなさい・・・また別の記事で書きます。
  • ワイルドカードのSSL証明書を作成する部分も含みません。
  • サンプルコード内で、Herokuアプリ名は、 sushi です。

本題

Heroku を利用していて、ワイルドカードSSLを無料で入れたくて調べた内容をメモ的に記載します。手順としては、以下2点です。

  1. ドメインを追加する(独自ドメイン)
  2. SSL証明書をアップロードする

ドメインを追加する

$ heroku domains:add *.example.com --app sushi
Added *.example.com to sushi... done
...

ちなみに、Heroku SSLを利用してます。Heroku SSL と、SSL Endpointは別物なので、気をつけてください。今回は、Heroku SSLを利用します。

SSL Endpointを利用した場合には、エンドポイントを指定してあげる必要があります。今や、ほとんど使う機会はないと思います。
https://devcenter.heroku.com/articles/ssl-endpoint#endpoint-details

証明書の準備

  • 証明書+中間CA証明書
    /etc/letsencrypt/live/<ドメイン名 (example.com)>/fullchain.pem

  • 秘密鍵
    /etc/letsencrypt/live/<ドメイン名 (example.com)>/privkey.pem

を使います。

certbot を利用して、Let's Encrypt のSSL証明書を作る方法は、こちらのサイトが丁寧でわかりやすかったです。Let's Encrypt ワイルドカード証明書の取得手順メモ

Heroku SSLに証明書をuploadする

$ sudo heroku certs:update /etc/letsencrypt/live/example.com/fullchain.pem /etc/letsencrypt/live/example.com/privkey.pem --app sushi
Resolving trust chain... done
 ▸    Potentially Destructive Action
 ▸    This command will change the certificate of endpoint example-1234 from ⬢ sushi.
 ▸    To proceed, type sushi or re-run this command with --confirm shushi

> sushi
Updating SSL certificate example-1234 for ⬢ sushi... done

Herokuコマンドの復習

  • 証明書の追加 certs:add
    heroku certs:add [証明書+中間CA証明書のファイルパス] [秘密鍵のファイルパス] --app [アプリ名]

  • 証明書の更新 certs:update
    heroku certs:update [証明書+中間CA証明書のファイルパス] [秘密鍵のファイルパス] --app [アプリ名]

最後に適応されているのかを確認

$ curl -vI https://www.example.com
* About to connect() to www.example.com port 443 (#0)
*   Trying 50.16.234.21... connected
* Connected to www.example.com (50.16.234.21) port 443 (#0)
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using AES256-SHA
* Server certificate:
*    subject: C=US; ST=CA; L=SF; O=SFDC; OU=Heroku; CN=www.example.com
*    start date: 2011-11-01 17:18:11 GMT
*    expire date: 2012-10-31 17:18:11 GMT
*    common name: www.example.com (matched)
*    issuer: C=US; ST=CA; L=SF; O=SFDC; OU=Heroku; CN=www.heroku.com
*    SSL certificate verify ok.
GET / HTTP/1.1
User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8r zlib/1.2.3
Host: www.example.com
Accept: */*

SSL certificate verify ok と記載されていれば、成功です。

curlコマンドのおさらい

  • HTTPレスポンスヘッダーの取得(-I
    $ curl -I http://www.example.com/

  • 詳細をログ出力(-vもしくは--verbose
    $ curl -v http://www.example.com/

ミスった場合には、Rollbackが用意されています。

heroku certs:rollback --app sushi

ちなみに

Let's Encrypt ワイルドカード証明書の取得手順メモ

Let's Encrypt ワイルドカード証明書の取得手順メモの記事が参考になります!!
certbot コマンド実行(SSL証明書作成)

$ certbot certonly --manual \
--server https://acme-v02.api.letsencrypt.org/directory \
--preferred-challenges dns \
-d "*.example.com" -d example.com \
-m [email protected] \
--agree-tos \
--manual-public-ip-logging-ok

そうすると、以下のようにDNSのTXTレコードを修正してねって言われるので言われたように修正する

Please deploy a DNS TXT record under the name
_acme-challenge.example.com with the following value:

R31KSgjQrbga7AH5_H6KdJLjD6-5JNp3KEIRVEotSw0

Before continuing, verify the record is deployed.

TTLは少なく設定したほうが良いと思います。60とか。

DIGでTXTレコードが反映されたかどうかを確認する

$ dig -t TXT _acme-challenge.example.com

#=>

; <<>> DiG 9.10.6 <<>> -t TXT _acme-challenge.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14090
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;_acme-challenge.example.com.   IN  TXT

;; ANSWER SECTION:
_acme-challenge.example.com.    37 IN   TXT "R31KSgjQrbga7AH5_H6KdJLjD6-5JNp3KEIRVEotSw0"

;; Query time: 4 msec
;; SERVER: 61.122.116.147#53(61.122.116.147)
;; WHEN: Mon Sep 14 10:33:04 JST 2020
;; MSG SIZE  rcvd: 115