Let’s Encrypt の SSL 証明書を DNS-01 で取得する方法
本記事では、Let’s Encrypt、CloudFlare、DNS-01(DNS による認証)についての説明は一切ありません。また、インフラ初心者が執筆している(覚書)のでご注意ください。
通常、Let’s Encrypt の SSL 証明書を取得する場合、Certbot(旧 letsencrypt)というコマンドラインツールを使用します。ググッて出てくる情報も、Certbot を使用した方法の方が多いと思います。Certbot でも DNS-01 を使用して証明書を取得することは可能ですが、初回のみ手動で DNS レコードを変更しないといけない、またはサードパーティ製のプラグインを使用するなど若干面倒です。
そこで、Certbot の代わりに、dehydrated(旧 letsencrypt.sh)というスクリプトを使用します。dehydrated は Let’s Encrypt の SSL 証明書を取得するサードパーティ製のコマンドラインツールです。Certbotとは全くの別物なので注意してください。また、DNS-01 を使用して SSL 証明書を取得する場合、別途フックスクリプト(プラグイン)が必要です。
DNS-01 を使用できる DNS サービスは、外部から API などで DNS レコードの書き換えが可能な DNS サービスであれば、DNS-01 を使用した SSL 証明書の取得は可能です。本記事では CloudFlare を使用した方法を紹介しますが、AWS Route53 などでも可能です。詳しくは Examples for DNS 01 hooks をご覧ください。
CloudFlare の API Key を取得する
CloudFlare の My Account ページにアクセスします。そのままページをスクロールすると API Key という項目があり、右側に View API Key というボタンがあるのでクリックします。表示された API Key をメモしておいてください。
dehydrated のインストール
$ git clone https://github.com/lukas2511/dehydrated /usr/local/dehydrated
フックスクリプト(プラグイン)のインストール
$ git clone https://github.com/kappataumu/letsencrypt-cloudflare-hook /usr/local/dehydrated/hooks/cloudflare && \ cd /usr/local/dehydrated/ && \ mkdir $PWD/.acme-challenges
インストールされている Python のバージョンを確認します。
$ python -V Python 2.7.5
インストールされている Python のバージョンに合った方を実行します。
# Python のバージョンが2の場合 $ pip install -r ./hooks/cloudflare/requirements-python-2.txt # Python のバージョンが3の場合 $ pip install -r ./hooks/cloudflare/requirements.txt
設定ファイルを作成する
dehydrated の各種設定ファイルを作成します。
本体の設定ファイルを作成する
$ cd /usr/local/dehydrated/ $ cp ./docs/examples/config ./config && \ vi ./config
変更前 | 変更後 |
---|---|
#CHALLENGETYPE=”http-01″ | CHALLENGETYPE=”dns-01″ |
#BASEDIR=$SCRIPTDIR | BASEDIR=/usr/local/letsencrypt.sh |
#HOOK= | HOOK=”${BASEDIR}/hooks/cloudflare/hook.py” |
#CONTACT\_EMAIL= | CONTACT\_EMAIL=”[email protected]” |
1番下に以下を追加します。
export CF_EMAIL='YOUR CLOUDFLARE LOGIN EMAIL ADDRESS' export CF_KEY='YOUR CLOUDFLARE API KEY' export CF_DNS_SERVERS='8.8.8.8 8.8.4.4'
SSL 証明書を発行するドメインリストを作成する
ドメイン毎に改行し、サブドメインは半角スペースで区切って入力します。
$ cd /usr/local/dehydrated/ $ cat <<EOD>$PWD/domains.txt example.com www.example.com example.net www.example.net sub.example.net EOD
DHPARAM を生成する
DHPARAM の生成は結構時間が掛かります。コーヒーでも飲みながら、一休みしているのがいいと思います(笑)
$ openssl dhparam -out /usr/local/dehydrated/certs/example.com/dhparams.pem 4096
ルート証明書とクロスルート証明書を取得する
$ cd /usr/local/dehydrated/ $ wget https://letsencrypt.org/certs/isrgrootx1.pem -O ./certs/isrgrootx1.pem && \ wget https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem -O ./certs/lets-encrypt-x3-cross-signed.pem
OCSP Stapling に使用するパラメータファイルを作成する
Nginx では ssl_trusted_certificate ディレクティブに指定するファイルです。
$ cd /usr/local/dehydrated/ $ cat ./certs/lets-encrypt-x3-cross-signed.pem \ .certs/isrgrootx1.pem > ./certs/example.com/trusted.pem
TLS Session Ticket に使用する鍵を作成する
Nginx では ssl_session_ticket_key ディレクティブに指定するファイルです。
$ cd /usr/local/dehydrated/ $ openssl rand 48 > ./certs/example.com/session-ticket.key
SSL 証明書の自動更新のために Cron 登録をする
Let’s Encrypt の証明書の有効期間は、発行から90日間です。90日毎に手作業で証明書を再発行するのは手間なので、Cron を使って自動更新させます。
スクリプトを作成する
$ vi /usr/local/dehydrated/cron.sh
以下をコピペします。
#!/usr/bin/env bash /usr/local/dehydrated/dehydrated -c -x /usr/local/dehydrated/dehydrated -gc systemctl restart nginx
スクリプトに実行権限を付与する
$ chmod +x /usr/local/dehydrated/cron.sh
crontabでJobを登録する
以下は、毎月1日の午前4時に実行されるようにする例です。
$ crontab -e 0 4 1 * * /usr/local/dehydrated/cron.sh >> /usr/local/dehydrated/cron.log 2>&1
各種証明書
内容 | ファイル |
---|---|
サーバー証明書 | /usr/local/dehydrated/certs/example.com/cert.pem |
中間証明書 | /usr/local/dehydrated/certs/example.com/chain.pem |
サーバ証明書 + 中間証明書 | /usr/local/dehydrated/certs/example.com/fullchain.pem |
秘密鍵 | /usr/local/dehydrated/certs/example.com/privkey.pem |
ルート証明書 + クロスルート証明書 | https://letsencrypt.org/certificates/ |
BASEDIR=/usr/local/letsencrypt.sh
の部分、正しくは
BASEDIR=/usr/local/dehydrated
みたいです。