Let’s EncryptのワイルドカードSSL証明書を取得して設定する

Let’s EncryptのワイルドカードSSL証明書を取得して、Apacheに設定してみたのでその手順を紹介します。
Debian9にはcertbotをパッケージでインストールできますが古いので、新しいコマンドのインストールから紹介しています。
環境はこんな感じです。

  • OS: Debian 9
  • WebServer: Apache 2.4
  • Client: certbot-auto 0.23

Let’s Encryptのクライアントをインストール

Debianにはcertbotコマンドをパッケージでインストールできるけどかなり古いようでワイルドカード証明書に対応していないらしい。
そこで、Githubに公開されているコマンドを取得して使います。ちなみに、私は自分でインストールするコマンドは /opt/ 配下に入れるようにしています。

$ sudo cd /opt
$ sudo git clone https://github.com/certbot/certbot

これで /opt/certbot/ にコマンドが配置されます。パスを通すならここに。自分は使用頻度低いのでパスは通していません。
あと、バージョン違いのコマンドが入っていると面倒が起きそうなので、certbotをパッケージからインストールしている場合は削除しておいた方が無難かも。

Let’s Encryptのワイルドカード証明書を取得

証明書の取得にはドメイン認証が必要です。DNSレコードを変更する必要があります。
先ほどインストールしたコマンドを使って証明書を発行します。

下記のコマンドは nautilus-code.jp ドメインに対するワイルドカード証明書を発行しています。
変更するところは、ドメインとメールアドレスくらいですね。

$ sudo /opt/certbot/certbot-auto certonly --manual \
-d *.nautilus-code.jp -m <メールアドレス> --agree-tos --manual-public-ip-logging-ok \
--preferred-challenges dns-01 \
--server https://acme-v02.api.letsencrypt.org/directory

不足しているパッケージがあると、自動的にインストールされます。(すごい!)
実行結果は下の感じになります。
許諾系のダイアログとドメイン認証の情報が途中で表示されます。

$ sudo /opt/certbot/certbot-auto certonly --manual \
> -d *.nautilus-code.jp -m <メールアドレス> --agree-tos --manual-public-ip-logging-ok \
> --preferred-challenges dns-01 \
> --server https://acme-v02.api.letsencrypt.org/directory
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None

-------------------------------------------------------------------------------
Would you be willing 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 EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o: y
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for nautilus-code.jp

-------------------------------------------------------------------------------
Please deploy a DNS TXT record under the name
_acme-challenge.nautilus-code.jp with the following value:

Zr83mCRJ9Dk3TLYVG1bLeWkhT-wPKn8VWbX37eZ61XE

Before continuing, verify the record is deployed.
-------------------------------------------------------------------------------
Press Enter to Continue
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/nautilus-code.jp/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/nautilus-code.jp/privkey.pem
   Your cert will expire on 2018-07-22. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot-auto
   again. To non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

ドメイン認証

ドメイン認証は _acme-challenge.nautilus-code.jp というサブドメインのTXTレコードに指定のコードを登録します。
こんな感じに見えるように登録する。

$ dig _acme-challenge.nautilus-code.jp txt

; <<>> DiG 9.10.3-P4-Debian <<>> _acme-challenge.nautilus-code.jp txt
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48112
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;_acme-challenge.nautilus-code.jp. IN   TXT

;; ANSWER SECTION:
_acme-challenge.nautilus-code.jp. 300 IN TXT    "Zr83mCRJ9Dk3TLYVG1bLeWkhT-wPKn8VWbX37eZ61XE"

;; Query time: 21 msec
;; SERVER: 133.242.0.3#53(133.242.0.3)
;; WHEN: Tue Apr 24 10:34:35 JST 2018
;; MSG SIZE  rcvd: 117

DNSを変更しても浸透するまで時間かかるので、次に進まないように注意。
指定のコードは実行のたびに変わるので、我慢できないで進んでしまってドメイン認証通らなかったらまたやり直し。
手元のコンソールで浸透できたように見えても浸透しきっていないと通らないこともあったので、十分待った方がよさそう。
# 私は何度もやり直しましたが…

ワイルドカード証明書の利用設定

証明書の発行に成功すると下記に証明書・中間証明書、キーファイルが作成されます。

  • /etc/letsencrypt/live/nautilus-code.jp/fullchain.pem
  • /etc/letsencrypt/live/nautilus-code.jp/privkey.pem

これらをバーチャルホストに設定します。
/etc/apache2/site-available/hogehoge.confとして登録します。

<IfModule mod_ssl.c>
<VirtualHost hogehoge.nautilus-code.jp:443>
  ServerName hogehoge.nautilus-code.jp
  ServerAdmin webmaster@nautilus-code.jp

  SSLEngine On
  SSLCertificateFile /etc/letsencrypt/live/nautilus-code.jp/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/nautilus-code.jp/privkey.pem

  DocumentRoot /srv/www/hogehoge
  <Directory /srv/www/hogehoge>
    Require all granted
    Options -MultiViews
    AllowOverride all
  </Directory>

  <Files ~ "^\.ht">
    Order allow,deny
    Deny from all
    Satisfy All
  </Files>

  LogLevel info ssl:warn
  ErrorLog ${APACHE_LOG_DIR}/hogehoge_error.log
  CustomLog ${APACHE_LOG_DIR}/hogehoge_access.log combined
</VirtualHost>
</IfModule>

VirtualHostディレクティブのところにポート番号 443 を必ずしているするように。
SSLEngine, SSLCertificateFile, SSLCertificateKeyFileを指定します。

あとは設定を有効にしてApacheをリロードします。

$ sudo a2ensite hogehoge
$ sudo service apache2 reload

これで設定は終わり!
サイトにhttpsでアクセスしてみて、証明書を確認して発行元の情報が *.nautilus-code.jp になっていればOK!(もちろん、別ドメインならそのドメインね)

証明書の自動更新

Let's Encryptの証明書は3ヶ月で期限が切れます。
毎回手動で更新するのも忘れるし面倒なので、スケジュールします。

下記のようにCRONの設定をしています。(この作業はrootユーザで。)

# crontab -l
# m h  dom mon dow   command
0 3 1  *  * /opt/certbot/certbot-auto renew --pre-hook "service apache2 stop" --post-hook "service apache2 start"

月に一度、証明書の更新処理を実施します。更新可能は期限日の30日前からなので、更新可能な日にならないと実際の更新処理は走りません。
また、更新処理は80番ポートが使用されていると動かないそうなので、更新処理前にApacheを停止して処理後に起動するようにしています。

これで更新を気にせずにワイルドカードSSL証明書を使い続けられます。

いじょう