[Webarena Indigo] cronによる定時実行でLet’s Encryptを自動更新(Slack通知付き)

Let’s Encryptの証明書更新を怠ってしまった場合

Let’s Encryptは無料でサイトをSSL化できるのですが、3カ月ごとに証明書を更新する必要があります。

それを怠ればERR_CERT_DATE_INVALIDになってしまい、訪れたユーザのブラウザには「この接続ではプライバシーが保護されません。」という過激な表示がされてしまいます。

こんなのを見せられたら、まぁページを開くことはしないですね。

こ の 接 続 で は プ ラ イ バ シ ー が 保 護 さ れ ま せ ん 
ー ー で は 、 悪 意 の あ る ユ ー ザ ー に よ っ て 、 バ ス ワ ー ド 、 メ ッ セ ー ン 、 ク 
レ ジ ッ ト カ ー ド な ど 0 メ 青 報 が 盗 ま れ る 可 能 性 が あ り ま す 。 
NET::ERR_CERT_DATE_I NVALID 
ロ ア ク セ ス し た ペ ー ジ の URL 、 ラ ス デ ム 情 報 、 お よ び ペ ー ジ の コ ン テ ン ツ の 一 部 を G009 厄 に 送 信 し 
て 、 Ch 「 ome セ キ ュ リ テ ィ の 改 酋 に ご 協 力 く だ さ い 。 プ ラ イ バ シ ー ボ リ シ ー 
詳 細 設 定 
セ キ ュ リ テ ィ で 保 護 さ れ た ペ ー ジ に 戻 る

自動更新をTODOにいれて、定期的に更新できる豆な人は上記のような事態になることはないと思うのですが、それでも忘れてしまうことはあると思います。

環境周りの情報

早速構築していきます。

最初に、今回のジョブを仕込む環境についてです。

  • Webarena Indigo
    • 月額380円でVPS環境が利用できる、NTT系列のサービス
    • めっちゃお得。詳しくは以下をご覧ください。
    • WebARENA(VPSクラウド) 
    • OSはいくつか選べますが、Ubuntu 18.04.1 LTS (GNU/Linux 4.15.0-106-generic x86_64)を使ってます。
  • Nginx
    • 証明書を利用しているNginxはDocker上で動いてます
    • そのため、証明書の更新後にコンテナの再起動をします
  • Slack
  • Certbot

Shellスクリプトの作成

cronで定期的に実行したい作業をshellスクリプトとして用意します。

全部で3つのスクリプトを作成しています。

  • cerbot-renew.sh
    • メイン処理
      • 証明書の現状をチェック
      • 証明書の更新処理を実行
      • 結果をslackへ通知
  • docker-cerbot-renew.sh
    • 証明書の更新処理(Dockerコマンドで実行)
  • notifyMaitokuSlack.sh
    • slackへの通知処理

証明書更新のメイン処理(cronで定期実行するshell)

ポイントですが、

certbotで証明書の更新処理(docker-cerbot-renew.sh)を実行する以下のコマンドです。

printf '2\n' | sudo sh /home/ubuntu/shell/docker-cerbot-renew.sh

既に証明書が存在する場合、本当に更新するか/処理をやめるか聞かれ、Shellが入力待ちとなります。

What would you like to do?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Keep the existing certificate for now
2: Renew & replace the cert (may be subject to CA rate limits)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
wuulv_l yuu 10 uU: 
l: Keep the existing certificate for now 
. Renew & replace the cert (may be subject to CA rate I imits) 
elect the appropr iate nther (1-2] then [enter] (press •c • to cancel): 
0 
ITCRTÅNT NOTES: 
- Congratulations! Your certif icate and chain have been saved at: 
/etc/letsencrypt/l ive/r 
'/ful Icha in.pem 
Your key fi le has been saved at: 
/etc/letsencrypt/l ive/r 
/pr ivkey.pem 
Your cert will expire on 2021-04-02. To obtain a new or tweaked 
version of this certif icate in the future, sinply run certbot 
again. TO non-interactively renew Of your certif icates. run 
-certbot renew- 
- If you like Certbot, please consider supporting our work by: 
Renewing an existing certificate for 
Donating to ISRG / Let's Encrypt: 
Donating to EFF: 
https://letsencrypt.org/donate 
ht tps://eff .org/donate-le

そのため

printf '2\n' |

によって、証明書の更新を行う処理を続行しています。

$ cat shell/cerbot-renew.sh
#!/bin/sh

DATETIME=`date +%Y%m%d_%H%M%S_%3N`
echo "--------------------------------------"
echo "[start]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo $DATETIME
echo "--------------------------------------"

#check

docker run -i --rm \
        --name certbot \
        -v "/etc/letsencrypt:/etc/letsencrypt" \
        -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
        certbot/certbot certificates

#update

printf '2\n' | sudo sh /home/ubuntu/shell/docker-cerbot-renew.sh

sudo sh /home/ubuntu/shell/notifyMaitokuSlack.sh

cd /home/ubuntu/git/maitokuapi/

docker-compose restart

DATETIME=`date +%Y%m%d_%H%M%S_%3N`
echo "--------------------------------------"
echo "[ end ]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo $DATETIME
echo "--------------------------------------"

証明書の更新コマンド(私の環境ではDockerを使って実行)

更新処理の引数のポイントとしては、

-d :自身サービスのドメイン名です。(google.comみたいな)

-m :メールアドレスです。

$ cat shell/docker-cerbot-renew.sh
#!/bin/sh

docker run -i --rm \
        --name certbot \
        -v "/etc/letsencrypt:/etc/letsencrypt" \
        -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
        certbot/certbot certonly \
        --manual \
        -d *********** \
        -m *********@gmail.com \
        --agree-tos \
        --manual-public-ip-logging-ok \
        --preferred-challenges dns-01 \
        --server https://acme-v02.api.letsencrypt.org/directory

Slackへの通知処理

通知するURLをSLACK_WEBHOOK_API_URLに設定します。

$ cat shell/notifyMaitokuSlack.sh
#!/usr/bin/env bash

# set here your Webhook URL
SLACK_WEBHOOK_API_URL='https://hooks.slack.com/services/*****/****/*****'

MSG=" CERBOT DONE "
JSON="{ \"text\": \"$MSG\" }"

RES=`curl -s -X POST -H 'Content-Type: application/json' -d "$JSON" $SLACK_WEBHOOK_API_URL`

echo $RES

実行結果

上記のスクリプトを実行した結果が以下になります。

--------------------------------------
[start]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
20210102_120501_798
--------------------------------------
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: *************
    Serial Number: ********************************************
    Key Type: RSA
    Domains: *************
    Expiry Date: 2021-04-02 08:38:20+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/*************/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/*************/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Use of --manual-public-ip-logging-ok is deprecated.
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Use of --manual-public-ip-logging-ok is deprecated.
Cert not yet due for renewal

You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry.
(ref: /etc/letsencrypt/renewal/*************.conf)

What would you like to do?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Keep the existing certificate for now
2: Renew & replace the cert (may be subject to CA rate limits)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): Renewing an existing certificate for *************
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/*************/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/*************/privkey.pem
   Your cert will expire on 2021-04-02. 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"
 - 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

ok
Restarting nginx    ... done                                                                                           
Restarting django   ... done                                                                                           
Restarting postgres ... done                                                                                           --------------------------------------
[ end ]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
20210102_120523_572
--------------------------------------

cronへの登録

Linuxでの定時実行はcronを使います。

cronへの登録

実行した結果を残したいため、

cerbot-renew.log 2&gt;&amp;1

でログを出力しています。

cat /etc/cron.d/cron_cerbot
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
*/2 * * * * sudo sh /home/ubuntu/shell/cerbot-renew.sh >> cerbot-renew.log 2>&1

cronに登録できたか確認

$ crontab -l

を実行することで、登録できているか確認できます。

以下は実行結果です。

0 3 1 * * sudo sh /home/ubuntu/shell/cerbot-renew.sh >> /home/ubuntu/shell/cerbot-renew.log 2>&1
ubuntu@i- 
Edit this file to introduce tasks to be run by cron. 
Each task to run has to be defined through a single line 
indicat ing with different fields *hen the task will be run 
and *hat comand to run for the task 
To define the t irre you can provide concrete values for 
minute (m). hour (h). day of mnth (dom). mnth (non). 
and day Of week (dow) or use in these fields (for 
Not ice that tasks will be started based on the cron's system 
daemon's notion of tine and tinpzones. 
Output of the crontab jobs (including errors) is sent through 
ernail to the user the crontab file belongs to (unless redirected). 
For exarrple. you can run a backup of all your user accounts 
at 5 a.m every week with: 
0 5 x x 1 tar -zcf ,-horre/ 
For Tore information see the nanual pages Of crontab(5) and cron(8) 
m h dom rmn dow corm-and 
3 1 * * sudo sh /'home/l_buntu/shel l/cerbot-renew.sh /%ore/ubuntu/shel l/cerbot-renew. log 
buntu@i -

実行した結果はslackへ通知されます。

まとめ

以上が、Indigo でcronを利用した定時実行により、Let’s Encryptを自動更新し、Slackに通知する手順でした。

これで安心。

About: ken


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください