jenkinsでletsEncrypt自動更新ジョブを作る

現在、自分のサイトはVPS2台構成で動いています。
ssl証明書(LetsEncrypt)をそれぞれのサーバに設置しているので、jenkinsから定期的に実行するように設定してみます

サーバ構成

WordPressが動いている「sheltie-garage.xyz」サーバと jenkinsその他もろもろが動いている開発用サーバ「lab.sheltie-garage.xyz」の2台構成です

lab.sheltie-garage.xyzの設定

jenkinsサーバ上で、letSEncryptを更新するシェルを実行します

手順としてはnginx停止 -> LetsEncrypt更新 -> nginx再開」となります

nginxを停止しないで証明書更新を行うと、以下のようなエラーが表示されました

# ./certbot-auto renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/lab.sheltie-garage.xyz.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator standalone, Installer None
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for lab.sheltie-garage.xyz
Cleaning up challenges
Attempting to renew cert (lab.sheltie-garage.xyz) from /etc/letsencrypt/renewal/lab.sheltie-garage.xyz.conf produced an unexpected error: Problem binding to port 80: Could not bind to IPv4 or IPv6.. Skipping.
All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/lab.sheltie-garage.xyz/fullchain.pem (failure)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/lab.sheltie-garage.xyz/fullchain.pem (failure)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 renew failure(s), 0 parse failure(s)

sudo設定

jenkinsから実行するために、証明書更新に必要なコマンドに対してtomcatユーザーから実行できるように設定を変更します
自分の環境ではjenkinsより実行されたシェルは、tomcatユーザーとして実行されるためです

visudoで以下の通り設定を追加

# add monodon sudo
tomcat localhost=(ALL) /etc/init.d/nginx
tomcat localhost=(ALL) /usr/local/cerbot/letsencrypt/certbot-auto

jenkinsの設定

jenkinsは「フリースタイルプロジェクト」として作成します

作成したプロジェクトの「設定 > ビルド > シェルの実行」を選択すると、実行するシェルを記述できるようになります。

今回は以下のように設定

#!/bin/bash

sudo /etc/init.d/nginx stop
sleep 10s

cd /usr/local/cerbot/letsencrypt/
sudo ./certbot-auto renew

sleep 5s
sudo /etc/init.d/nginx start

nginxを止めて、証明書を更新して、nginxを開始 するだけのシェルですね

実行時のエラーと対応

jenkinsから実行したところ、以下のエラーが発生したので、ぞれぞれ対応しました

sudo: no tty present and no askpass program specified

エラーに対応するため、visudoで以下の通り修正

# Defaults    requiretty
Defaults:tomcat !requiretty

こちらを参考にしました https://utano.jp/entry/2016/04/cron-sudo-require-tty/

実行

jenkinsから実行してみます

無事にシェルが実行されました
たまにLetsEncryptの更新を忘れて、危険なサイト扱いになってしまうことがありましたが、ひとまずこれで自動更新が走りそうです

ちなみに

LetsEncryptでは、自動更新用のCron登録例が準備されています

sudo /usr/bin/certbot-auto renew --post-hook "sudo /etc/init.d/nginx start"

こちらを参考にしました
https://qiita.com/takahiko/items/a08895550727b95b6c36

今回はjenkinsの勉強ということで、あえてCronを使わずjenkins上から設定してみました