From 3e091ef3d515a094fd4493faacbc5c3ba266c2ad Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Thu, 25 Jan 2018 00:08:44 +0000 Subject: [PATCH] Add a cron job to check SSL certificate validity --- .../files/default/bin/check-certificate | 36 +++++++++++++++++++ cookbooks/letsencrypt/recipes/default.rb | 8 +++++ .../templates/default/check-certificates.erb | 5 +++ .../letsencrypt/templates/default/cron.erb | 3 +- 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100755 cookbooks/letsencrypt/files/default/bin/check-certificate create mode 100644 cookbooks/letsencrypt/templates/default/check-certificates.erb diff --git a/cookbooks/letsencrypt/files/default/bin/check-certificate b/cookbooks/letsencrypt/files/default/bin/check-certificate new file mode 100755 index 000000000..46ca8e848 --- /dev/null +++ b/cookbooks/letsencrypt/files/default/bin/check-certificate @@ -0,0 +1,36 @@ +#!/usr/bin/ruby + +require "net/http" + +domain = ARGV.first + +begin + connection = Net::HTTP.start(domain, :use_ssl => true) + certificate = connection.peer_cert + + if Time.now < certificate.not_before + puts "Certificate #{domain} not valid until #{certificate.not_before}" + elsif certificate.not_after - Time.now < 14 * 86400 + puts "Certificate #{domain} expires at #{certificate.not_after}" + else + subject_alt_name = certificate.extensions.find { |e| e.oid == "subjectAltName" } + + if subject_alt_name.nil? + puts "Certificate #{domain} has no subject_alt_name" + else + alt_names = subject_alt_name.value.split(/\s*,\s*/).sort + + ARGV.sort.each do |expected| + puts "Certificate #{domain} is missing subject_alt_name #{expected}" unless alt_names.shift == "DNS:#{expected}" + end + + alt_names.each do |name| + puts "Certificate #{domain} has unexpected altName #{name}" + end + end + end + + connection.finish +rescue OpenSSL::SSL::SSLError => error + puts "Error connecting to #{domain}: #{error.message}" +end diff --git a/cookbooks/letsencrypt/recipes/default.rb b/cookbooks/letsencrypt/recipes/default.rb index 8f9564457..a2c42e1c5 100644 --- a/cookbooks/letsencrypt/recipes/default.rb +++ b/cookbooks/letsencrypt/recipes/default.rb @@ -143,6 +143,14 @@ certificates.each do |name, details| end end +template "/srv/acme.openstreetmap.org/bin/check-certificates" do + source "check-certificates.erb" + owner "root" + group "root" + mode 0o755 + variables :certificates => certificates +end + template "/etc/cron.d/letsencrypt" do source "cron.erb" owner "root" diff --git a/cookbooks/letsencrypt/templates/default/check-certificates.erb b/cookbooks/letsencrypt/templates/default/check-certificates.erb new file mode 100644 index 000000000..d03e98a4d --- /dev/null +++ b/cookbooks/letsencrypt/templates/default/check-certificates.erb @@ -0,0 +1,5 @@ +#!/bin/sh + +<% @certificates.each_value do |certificate| -%> +/srv/acme.openstreetmap.org/bin/check-certificate <%= certificate[:domains].join(" ") %> +<% end -%> diff --git a/cookbooks/letsencrypt/templates/default/cron.erb b/cookbooks/letsencrypt/templates/default/cron.erb index fa89edaea..74a8ee0a2 100644 --- a/cookbooks/letsencrypt/templates/default/cron.erb +++ b/cookbooks/letsencrypt/templates/default/cron.erb @@ -2,4 +2,5 @@ MAILTO=admins@openstreetmap.org -0 */12 * * * letsencrypt /srv/acme.openstreetmap.org/bin/renew +00 */12 * * * letsencrypt /srv/acme.openstreetmap.org/bin/renew +30 */12 * * * letsencrypt /srv/acme.openstreetmap.org/bin/check-certificates -- 2.43.2