annotate mod_checkcerts/mod_checkcerts.lua @ 1879:18123e0f5d58

mod_checkcerts: Improve logic for finding an ssl section with a certificate
author Kim Alvefur <zash@zash.se>
date Tue, 29 Sep 2015 14:53:16 +0200
parents d9fcf9d8e787
children a7c1f1b6ef05
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
667
ea9941812721 mod_checkcerts: New module that logs a warning when your cert is about to expire.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
1 local ssl = require"ssl";
1098
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
2 local datetime_parse = require"util.datetime".parse;
1672
d9fcf9d8e787 mod_checkcerts: Fix for removal of globals in LuaSec
Kim Alvefur <zash@zash.se>
parents: 1098
diff changeset
3 local load_cert = ssl.loadcertificate;
941
a6c2345bcf87 mod_checkcerts: Nag admins about certs that have, or are about to expire. Often.
Kim Alvefur <zash@zash.se>
parents: 855
diff changeset
4 local st = require"util.stanza"
855
1983d4d51e1a mod_checkcerts: Improve, add comments, add forward compatibility.
Kim Alvefur <zash@zash.se>
parents: 667
diff changeset
5
1098
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
6 -- These are in days.
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
7 local nag_time = module:get_option_number("checkcerts_notify", 7) * 86400;
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
8
855
1983d4d51e1a mod_checkcerts: Improve, add comments, add forward compatibility.
Kim Alvefur <zash@zash.se>
parents: 667
diff changeset
9 if not load_cert then
1983d4d51e1a mod_checkcerts: Improve, add comments, add forward compatibility.
Kim Alvefur <zash@zash.se>
parents: 667
diff changeset
10 module:log("error", "This version of LuaSec (%s) does not support certificate checking", ssl._VERSION);
667
ea9941812721 mod_checkcerts: New module that logs a warning when your cert is about to expire.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
11 return
ea9941812721 mod_checkcerts: New module that logs a warning when your cert is about to expire.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
12 end
ea9941812721 mod_checkcerts: New module that logs a warning when your cert is about to expire.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
13
1098
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
14 local pat = "^([JFMAONSD][ceupao][glptbvyncr]) ?(%d%d?) (%d%d):(%d%d):(%d%d) (%d%d%d%d) GMT$";
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
15 local months = {Jan=1,Feb=2,Mar=3,Apr=4,May=5,Jun=6,Jul=7,Aug=8,Sep=9,Oct=10,Nov=11,Dec=12};
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
16 local function parse_x509_datetime(s)
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
17 local month, day, hour, min, sec, year = s:match(pat); month = months[month];
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
18 return datetime_parse(("%04d-%02d-%02dT%02d:%02d:%02dZ"):format(year, month, day, hour, min, sec));
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
19 end
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
20
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
21 local timeunits = {"minute",60,"hour",3600,"day",86400,"week",604800,"month",2629746,"year",31556952,};
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
22 local function humantime(timediff)
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
23 local ret = {};
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
24 for i=#timeunits,2,-2 do
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
25 if timeunits[i] < timediff then
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
26 local n = math.floor(timediff / timeunits[i]);
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
27 if n > 0 and #ret < 2 then
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
28 ret[#ret+1] = ("%d %s%s"):format(n, timeunits[i-1], n ~= 1 and "s" or "");
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
29 timediff = timediff - n*timeunits[i];
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
30 end
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
31 end
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
32 end
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
33 return table.concat(ret, " and ")
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
34 end
941
a6c2345bcf87 mod_checkcerts: Nag admins about certs that have, or are about to expire. Often.
Kim Alvefur <zash@zash.se>
parents: 855
diff changeset
35
667
ea9941812721 mod_checkcerts: New module that logs a warning when your cert is about to expire.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
36 local function check_certs_validity()
941
a6c2345bcf87 mod_checkcerts: Nag admins about certs that have, or are about to expire. Often.
Kim Alvefur <zash@zash.se>
parents: 855
diff changeset
37 local now = os.time();
a6c2345bcf87 mod_checkcerts: Nag admins about certs that have, or are about to expire. Often.
Kim Alvefur <zash@zash.se>
parents: 855
diff changeset
38
855
1983d4d51e1a mod_checkcerts: Improve, add comments, add forward compatibility.
Kim Alvefur <zash@zash.se>
parents: 667
diff changeset
39 -- First, let's find out what certificate this host uses.
1098
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
40 local ssl_config = config.rawget(module.host, "ssl");
1879
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
41 if not ssl_config or not ssl_config.certificate then
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
42 ssl_config = config.get(module.host:match("%.(.*)"), "ssl");
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
43 end
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
44 if not ssl_config or not ssl_config.certificate then
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
45 ssl_config = config.get("*", "ssl");
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
46 end
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
47 if not ssl_config or not ssl_config.certificate then
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
48 log("warn", "Could not find a certificate to check");
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
49 return;
667
ea9941812721 mod_checkcerts: New module that logs a warning when your cert is about to expire.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
50 end
ea9941812721 mod_checkcerts: New module that logs a warning when your cert is about to expire.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
51
1879
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
52 local certfile = ssl_config.certificate;
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
53 local fh = io.open(certfile); -- Load the file.
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
54 cert = fh and fh:read"*a";
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
55 fh = fh and fh:close();
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
56 local cert = cert and load_cert(cert); -- And parse
855
1983d4d51e1a mod_checkcerts: Improve, add comments, add forward compatibility.
Kim Alvefur <zash@zash.se>
parents: 667
diff changeset
57
1879
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
58 if not cert then
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
59 module:log("warn", "No certificate configured for this host, please fix this and reload this module to check expiry");
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
60 return
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
61 end
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
62 local expires_at = parse_x509_datetime(cert:notafter());
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
63 local expires_in = os.difftime(expires_at, now);
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
64 local fmt = "Certificate %s expires in %s"
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
65 local nag_admin = expires_in < nag_time;
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
66 local log_warn = expires_in < nag_time * 2;
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
67 local timediff = expires_in;
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
68 if expires_in < 0 then
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
69 fmt = "Certificate %s expired %s ago";
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
70 timediff = -timediff;
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
71 end
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
72 timediff = humantime(timediff);
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
73 module:log(log_warn and "warn" or "info", fmt, certfile, timediff);
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
74 if nag_admin then
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
75 local body = fmt:format("for host ".. module.host, timediff);
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
76 for _,admin in ipairs(module:get_option_array("admins", {})) do
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
77 module:send(st.message({ from = module.host, to = admin, type = "chat" }, body));
1098
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
78 end
667
ea9941812721 mod_checkcerts: New module that logs a warning when your cert is about to expire.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
79 end
1879
18123e0f5d58 mod_checkcerts: Improve logic for finding an ssl section with a certificate
Kim Alvefur <zash@zash.se>
parents: 1672
diff changeset
80 return math.max(86400, expires_in / 3);
667
ea9941812721 mod_checkcerts: New module that logs a warning when your cert is about to expire.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
81 end
ea9941812721 mod_checkcerts: New module that logs a warning when your cert is about to expire.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
82
1098
cbbeac61f1ab mod_checkcerts: Add timestamp parsing, format time until expiry more human-readable, adjust check intervals to time left.
Kim Alvefur <zash@zash.se>
parents: 943
diff changeset
83 module:add_timer(1, check_certs_validity);