kazeno memo

メモとか

Nginx & MyDNS.jpな環境でLet's Encryptの自動更新

証明書発行&自動更新を行う。

Nginxの導入は各自で行ってください。

必要なもの

PHP

MyDNSが提供しているDirectEditで必要。
https://www.rem-system.com/centos-nginx-php/
このサイトを参考に導入した。

Certbot

Let'sEncryptが提供している証明書取得・更新用のツール。
まずEPELリポジトリを導入しておく

$ sudo yum install epel-release

certbotのインストール

$ sudo yum install certbot
DirectEdit

MyDNSが提供しているLet'sEncrypt用のDNS認証自動化ツール。
https://github.com/disco-v8/DirectEdit/
READMEを参考に導入する。
ここでは、Nginxデフォルトのドキュメントルートへファイルを配置する。
デフォルトでなくても、ドキュメントルートであればなんでも良い。

$ cd /usr/share/nginx/html/ ##ドキュメントルートへ移動
$ sudo wget 'https://github.com/disco-v8/DirectEdit/archive/master.zip' -O mydns.zip
$ sudo unzip ./mydns.zip
$ cd ./mydns/
$ sudo chmod 700 ./*.php
$ sudo chmod 600 ./*.conf

DirectEditの設定

DirectEditの設定ファイル"txtedit.conf"に、MyDNS.jpのアカウント情報とドメインを追加する。

~~~~~~
    $MYDNSJP_MASTERID  = 'ユーザ名';
    $MYDNSJP_MASTERPWD = 'パスワード';
    $MYDNSJP_DOMAIN = 'ドメイン';
~~~~~~

複数ドメインの場合

ドキュメントルート
    └ mydns/
            ├ ドメイン1.com/
            │      ├txtregist.php
            │      ├txtdelete.php
            │      └txtedit.conf
            └ ドメイン2.com/
                   ├txtregist.php
                   ├txtdelete.php
                   └txtedit.conf

こんな感じでファイルを配置してそれぞれの"txtedit.conf"に、必要な情報を追加する。

Certbotで証明書発行

次のコマンドでは"ドメイン1.com"の証明書&ワイルドカード証明書を取得出来る。
まずは、"--dry-run"オプションで上手くいくか確認。

$ sudo certbot certonly --manual \
$ --preferred-challenges=dns \
$ --manual-auth-hook /usr/share/nginx/html/mydns/txtregist.php \
$ --manual-cleanup-hook /usr/share/nginx/html/mydns/txtdelete.php \
$ -d ドメイン1.com -d *.ドメイン1.com \
$ --server https://acme-v02.api.letsencrypt.org/directory \
$ --agree-tos -m 連絡用メールアドレス \
$ --manual-public-ip-logging-ok
$ --dry-run

成功すると
IMPORTANT NOTES:
- The dry run was successful.
と出る。
失敗したならオプションとかDirectEditの設定を見直す。

次は、"--dry-run"を取って実際に証明書を発行する。

$ sudo certbot certonly --manual \
$ --preferred-challenges=dns \
$ --manual-auth-hook /usr/share/nginx/html/mydns/txtregist.php \
$ --manual-cleanup-hook /usr/share/nginx/html/mydns/txtdelete.php \
$ -d ドメイン1.com -d *.ドメイン1.com \
$ --server https://acme-v02.api.letsencrypt.org/directory \
$ --agree-tos -m 連絡用メールアドレス \
$ --manual-public-ip-logging-ok

成功すると
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
てな感じで、証明書の保存場所が表示される。

場所はデフォルトでは"/etc/letsencrypt/live/ドメイン1.com/"
複数のファイルが生成されるのでNginxに設定する。

オプションの解説

certonly				証明書を取得するだけ(サーバへの設定は手動)
--manual				認証を手動で行う
--preferred-challenges=dns		DNSを使った認証を行う
--manual-auth-hook			DNSへ認証コードを登録するときに使用するスクリプトを指定
--manual-cleanup-hook			登録した認証コードを削除するときに使用するスクリプトを指定
-d					ドメイン名(複数指定/ワイルドカード可能)
-m					連絡用のメールアドレス指定(失効前などにメールを送ってくれる。変更可能)
--server				ワイルドカード証明書の発行に対応ているサーバを明示的に指定している
--agree-tos				利用規約に同意
--manual-public-ip-logging-ok		証明書発行を要求したIPの公開を許可

NginxにSSL証明書を設定する

設定ファイルに次のように追加。

$ ssl_certificate /etc/letsencrypt/live/ドメイン1.com/fullchain.pem;
$ ssl_certificate_key /etc/letsencrypt/live/ドメイン1.com/privkey.pem;
##設定によっては以下も追加
$ ssl_trusted_certificate /etc/letsencrypt/live/ドメイン1.com/chain.pem;

Cronで証明書を自動更新&MyDNSへIPを自動通知

$ sudo crontab -e

でviが開くので設定追加
(以下はあくまで例)

#MyDNSへIP通知
*/10 * * * * curl -4 -o /dev/null "https://ユーザ名:パスワード@www.mydns.jp/login.html"
#Let'sEncrypt自動更新
* * 1 * * certbot renew --renew-hook "systemctl restart nginx" --renew-hook "systemctl restart postfix" --renew-hook "systemctl restart dovecot" -q >> /var/log/certbot-renew.log

MyDNSの方
10分ごとにcurlを使ってIPv4アドレスのみを通知している。
IPv6も通知したい場合は"-4"を取る。

Let'sEncryptの方
一日ごとに証明書の更新を試行する。
"--renew-hook"は更新に成功した場合、指定したコマンドを実行する。複数指定することも可能。
"-q"は詳細を出力。
">> /var/log/certbot-renew.log"で出力を保存。