プロジェクト

全般

プロフィール

バグ #448

完了

宅内 HTTPS サービスの証明書更新失敗の検知と自動リトライ

nop_thread さんが8ヶ月前に追加. 8ヶ月前に更新.

ステータス:
終了
優先度:
通常
担当者:
開始日:
2024/08/05
期日:
進捗率:

0%

一時中断:
いいえ
pinned:
いいえ
リマインド予定日:
前回確認日:
2024/08/05
管理外残件あり:
いいえ

説明

Step CA と Caddy どちらが問題なのか不明だが、とにかく相性が悪く証明書更新が失敗する (失敗し続ける) ことが頻繁にある。
復旧するには更新成功まで Caddy の再起動を繰り返すほかなさそうである。
(Caddy 自身のリトライ機構はうまくいかないようだ。)

原因がわからずどちらも中身を覗きたくないので、証明書の更新状況を確認し失敗しているようなら Caddy の再起動を行うスクリプトを systemd timer か何かで回すことでワークアラウンドとしたい。

nop_thread さんが8ヶ月前に更新

証明書の失効日時 (の unix date) の取得: openssl s_client -connect DOMAIN:443 </dev/null 2>/dev/null | openssl x509 -noout -dates 2>/dev/null | sed -ne 's!^notAfter=\(.*\)$!\1!p' | date -f - '+%s'

nop_thread さんが8ヶ月前に更新 · 編集済み

できた。

Usage: restart-caddy-to-renew-certs.sh [HOST[:PORT]]...

#!/bin/sh
{{ ansible_managed | comment }}
set -eu

NOW="$(date '+%s')"
FORCE_RENEW_PERIOD='{{ __caddy_force_renew_grace_period }}'

while [ $# -gt 0 ] ; do
	# Note that `openssl s_client -connect` requires the `:port` part
	# even for the port 443.
	HOST_PORT="$1"
	if [ "x${HOST_PORT%:*}" = "x${HOST_PORT}" ] ; then
		# `:port` is omitted.
		HOST_PORT="${HOST_PORT}:443"
	fi

	NOW="$(date '+%s')"
	NOT_AFTER="$(timeout 3 openssl s_client -connect "$HOST_PORT" </dev/null 2>/dev/null | openssl x509 -noout -dates 2>/dev/null | sed -ne 's!^notAfter=\(.*\)$!\1!p' | date -f - '+%s')"

	if [ "x${NOT_AFTER:-}" = x ] ; then
		# Cannot connect. Skip.
		echo "Skipping due to connection failure: domain=${HOST_PORT}"
		shift
		continue
	fi

	if [ "$(( $NOW + $FORCE_RENEW_PERIOD ))" -gt "$NOT_AFTER" ] ; then
		echo "Trying force renewal by restart: domain=${HOST_PORT}, notAfter=$(date -d "$NOT_AFTER" '+%F_%T%:z')"
		# The certificate will expire in FORCE_RENEW_PERIOD seconds
		# (or already have been expired).
		systemctl try-restart caddy.service

		# Renewal will take some seconds.
		sleep 10
		continue
	else
		shift
	fi
done

# vim: set ft=sh :

nop_thread さんが8ヶ月前に更新

  • ステータス新規 から 終了 に変更
  • 担当者nop_thread にセット
  • 開始日2024/08/05 にセット
  • 前回確認日2024/08/05 にセット

動作確認できたのでデプロイした。
完了。

他の形式にエクスポート: Atom PDF