LetsEncryptの無料SSL証明書をCertbotを使って自動発行


投稿日 2019年5月23日 >> 更新日 2023年3月3日


今回お話しする内容は、Certbotにより発行した無料SSL証明書を期限が切れる前に自動で再発行すると言った事です。

前提としましては

  • certbot standaloneオプションにて無料SSL証明書を取得済み
  • NginxのWebサーバー

となります。

なおstandaloneオプションでの無料SSL証明書取得に関しては以下のページになります。

実行環境

実行環境
CentoOS7
Nginx

設定ファイルに更新用のディレクティブを追加する

ディレクティブとはnginxで使う構文のことで、server { listen 80....}などを指す。

nginxが起動中でも証明書を発行させる場合は、webrootオプションを使います。

なので、指定したwebrootパスを読み込ませる為の設定をしていきます。

仮に/etc/nginx/conf.d/example.confファイルに自動起動用のディレクティブを追加するとしたら


server {
    ......
    ......
}
server {
    ......
    ......
}
server {
    listen 443 ssl default_server;
    server_name example.com;
    ssl on;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example/privkey.pem;
    location ^~ /.well-known/acme-challenge/ {
        root /var/www/example;   # ←ここからになります
    }
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

nginxが起動したまま証明書を発行するためにwebrootパスである/var/www/exampleディレクトリを使用します。(後にディレクトリを作成)

そして更新された新しい証明書は/etc/letsencrypt/live/example.com/fullchain.pemへ発行されます。

LetsEncryptの証明書はhttpでのアクセスが出来なければ以下のようなエラーとなり発行できなくなってしまう。

デバッグログを/var/log/letsencrypt/letsencrypt.logに保存する
選択したプラグイン:オーセンティケーターWebルート、インストーラーなし
新しいHTTPS接続を開始する(1):acme-v02.api.letsencrypt.org
新しい証明書を入手する
以下の課題を実行します。
example.comのhttp-01チャレンジ
すべての不一致ドメインに対してWebルートパス/ usr / share / nginx / htmlを使用します。
確認を待っています...
課題を片付ける
認証手順が失敗しました。 example.com(http-01):urn:ietf:params:acme:エラー:未承認::クライアントに十分な承認がありません:: http://example.com/.well-known/acme-challenge/1sT6Oq5V7_MtjqX_Wdv7Rからの無効な応答 -  C2fbb0xxDH0PCmMRF-ryo [000.000.00.000]:404 ←サーバーのIPアドレス

重要な注意:
  - サーバーから以下のエラーが報告されました。

   ドメイン:example.com
   タイプ:無許可
   詳細:からの無効な応答
   http://example.com/.well-known/acme-challenge/1sT6Oq5V7_MtjqX_Wdv7R-C2fbb0xxDH0PCmMRF-ryo
   [000.000.00.000]:404 ←サーバーのIPアドレス

   これらのエラーを修正するには、ドメイン名が
   正しく入力され、そのドメインのDNS A / AAAAレコード
   正しいIPアドレスを含む。

「無料SSL証明書が再発行されずにエラーになる」といった事を避ける為にも必要な設定であります。

niginx再起動


$ sudo systemctl restart nginx

コマンドwebrootオプションで再度証明書を取得し設定を書き換える

さきほどの/etc/nginx/conf.d/example.confの設定ファイルにミスが無ければ以下のコマンドで再取得が行えます。


# 先に認証用ファイルを納める為のディレクトリを作成
$ sudo mkdir /var/www/example

# --force-renewalで強制取得
$ sudo certbot certonly --webroot -w /var/www/example -d example.com --force-renewal
# 成功例
Congratulations! Your.....

-w /var/www/exampleは先に作成したディレクトリ下に/etc/nginx.conf.d/example.confで追加した/.well-known/acme-challenge/を置き認証用ファイルを納める指定です。

そしてなぜ強制取得(--force-renewal)をしたかというと、証明書を取得して日が経っていないと更新できないからです。

cronでcertbotに実行命令をする

cronとは、crontabとも言ってUNIX系OSのデーモンプロセスです。
デーモンプロセスと言うとまた分かりにくいので簡単に言ってしまうと、設定した処理要求に対してメモリ上で待機している実行ファイルです。

この実行ファイルの中に無料SSL証明書を自動で発行するコードを記述します。

まずはcertbotのディレクトリを取得します。


# whichコマンドで絶対パス(フルパス)を取得
$ which certbot
/usr/bin/certbot

# ついでにsystemctlのディレクトリも調べておきます
$ which systemctl
/usr/bin/systemctl

次にcronにて設定します


# -eオプションは設定
$ sudo crontab -e

開いたら、毎月1日の午前3時に実行するよう設定します。(viエディタモードなのでキーボードのiで編集開始、終了はキーボード左上のEscを押し:wqで上書き保存)

0 3 1 * * /usr/bin/certbot renew && /usr/bin/systemctl restart nginx

あとは翌月の1日に更新されているか待つだけです。

無料SSL化を自力で(シェル)行う事によってUNIX系にもだいぶ慣れてくると思います。

それでは以上になります。

最後までお読みいただきありがとうございます。