Let's EncryptでワイルドカードなSSL証明書を入れる - Amazon Linux2編

WebサーバにSSL対応した約40件のサブドメインを追加する必要に迫られたのですが、さすがに1個ずつSSL証明書を発行するのは地獄なのでワイルドカード証明書を導入した際のメモになります。

無料のSSL証明書としておなじみのLet's Encryptでは2018年からワイルドカード証明書に対応しているためこちらを利用します。

今回の環境は以下の通り。

Let's Encryptでワイルドカード証明書

必要なソフトを入れる

EPELを有効にしcertbotpython-certbot-apacheを入れます。このタイミングでhttpdmod_sslが入っていない場合は一緒に入ります。

$ sudo amazon-linux-extras install epel
$ sudo yum install certbot python-certbot-apache

※nginxを使う場合はpython-certbot-nginxを入れます。

無事に入ったようです。後ほどcronで自動更新の設定をする際に利用するのでwhichの結果はメモしておきます。

$ certbot --version
certbot 1.11.0

$ which certbot
/usr/bin/certbot

SSL証明書を発行する

certbot certonly

-dに続いて取得したいドメインを指定します。ここではneecbox.net*.neecbox.netの2つを同時に指定しています。後者がワイルドカードですね。

$ sudo certbot certonly --manual \
    --preferred-challenges dns-01 \
    --server https://acme-v02.api.letsencrypt.org/directory \
    -m katsubemakito@gmail.com \
    -d neecbox.net \
    -d *.neecbox.net

またメールアドレスは自分に届く物に変更してください。有効期限切れで失効しそうになるとお知らせメールが飛んできます。Let's Encryptはいつの間にか自動更新がコケていることがあるので結構役に立ちます。

規約に同意しますか?

ここから質問に回答しながら進めていきます。最初は規約に同意するか聞かれますので「Y」を入力しエンター。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

メルマガを購読する?

運営元の財団にメールアドレスを渡しつつメールマガジンを購読するか聞かれますが、これはYesでもNoでもどちらでもOKです。私はすでに購読していたのでここでは「N」を入力しエンター。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N

DNSにTXTレコードを追加

今回はDNSに特定のレコードを追加することで「あ、この人は本当にドメインの所有者なんだな」と認証する仕組みを利用するのですが、このタイミングで具体的に登録する内容が表示されます。

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

bKoTMXjZt4sNceTDes4R5Ekl1m0MoRZEeZsLQBorxh0

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue

Route53の場合はこんな感じで入力します。

別のTerminalでnslookupdigコマンドを実行し正常に反映されているか確認します。反映されるまで数分程度かかる場合もあるので焦らずに待ちます。

$ nslookup -type=TXT _acme-challenge.neecbox.net 8.8.8.8
Server:     8.8.8.8
Address:    8.8.8.8#53

Non-authoritative answer:
_acme-challenge.neecbox.net text = "bKoTMXjZt4sNceTDes4R5Ekl1m0MoRZEeZsLQBorxh0"

Authoritative answers can be found from:

最終的にもとのTerminalでエンターキーを押すと自動的にDNS認証が実行されます。

DNS認証の結果

以下のように「Congratulations!」から始まるメッセージが表示されていればSSL証明書の発行が正常に完了しています。

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/neecbox.net/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/neecbox.net/privkey.pem
   Your certificate will expire on 2021-07-09. To obtain a new or
   tweaked version of this certificate in the future, simply run
   certbot again. To non-interactively renew *all* of your
   certificates, run "certbot renew"

英文で書いてある通り、以下の2つのファイルが生成されています。これはこのあとWebサーバから参照します。

  • /etc/letsencrypt/live/neecbox.net/fullchain.pem
  • /etc/letsencrypt/live/neecbox.net/privkey.pem

Let's EncryptのSSL証明書の有効期限は3ヶ月と少し短め。これを実行したのが4月10日でしたので、メッセージ中に「Your certificate will expire on 2021-07-09」とあるように7月9日まで有効な証明書となっています。後ほど自動更新の設定をして楽をします。

Apacheの設定

最初にデフォルトの設定ファイルをバックアップします。diffコマンドでどこを変更したか一発で確認できるので便利です(設定ファイルをバージョン管理している場合は不要)

$ sudo cp /etc/httpd/conf.d/ssl.conf  /etc/httpd/conf.d/ssl.conf.org

先ほど作成したSSL証明書に変更します。書き換えるのは以下の2行です(追加ではなく既存の項目を書き換えてください)

$ sudo vi /etc/httpd/conf.d/ssl.conf
SSLCertificateFile /etc/letsencrypt/live/neecbox.net/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/neecbox.net/privkey.pem

Apacheを起動または再起動すれば完了です。

$ sudo systemctl start httpd

Webブラウザなどで本当に適用されているか確認します。今回は2パターンのSSL証明書を追加したので、それぞれの挙動を見ておきます。

その他

certbotで生成されるファイル

certbot certonlyで生成されるファイルは/etc/letsencrypt/live/(ドメイン名)の下に保存されます。

実際には以下のファイルが生成されています。

# ファイル 用途
1 privkey.pem 秘密鍵
2 cert.pem 証明書
3 chain.pem 中間CA証明書
4 fullchain.pem 証明書+中間CA証明書

今回のようにApache2.4.8以降やnginxではprivkey.pemとfullchain.pemがあれば設定可能なので、他のマシンで使いたい場合は単純にコピーして利用します。

自動更新がしたかったが…

更新

DNSで認証する場合、TXTレコードの値を更新する必要があるためcertbot renewコマンドを実行するだけでは更新が出来ないようです。そのため3ヶ月に1度冒頭のコマンドを実行し、TXTレコードを書き換えます。

$ sudo certbot certonly --manual \
    --preferred-challenges dns-01 \
    --server https://acme-v02.api.letsencrypt.org/directory \
    -m katsubemakito@gmail.com \
    -d neecbox.net \
    -d *.neecbox.net

ちなみにcertbot renewコマンドを実行すると以下のようなエラーメッセージが出ます。

# /usr/bin/certbot renew --post-hook "systemctl restart httpd"
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/neecbox.net.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Could not choose appropriate plugin: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',)
Failed to renew certificate neecbox.net with error: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',)

DNSにRoute53を利用している場合、API経由で更新できそうな気もしますね。またこれも手が空いたらやってみたいですね。

参考ページ