-
Notifications
You must be signed in to change notification settings - Fork 182
/
lets_encrypt.lua
80 lines (64 loc) · 2.96 KB
/
lets_encrypt.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
local _M = {}
local shell_execute = require "resty.auto-ssl.utils.shell_execute"
function _M.issue_cert(auto_ssl_instance, domain)
assert(type(domain) == "string", "domain must be a string")
local lua_root = auto_ssl_instance.lua_root
assert(type(lua_root) == "string", "lua_root must be a string")
local base_dir = auto_ssl_instance:get("dir")
assert(type(base_dir) == "string", "dir must be a string")
local hook_port = auto_ssl_instance:get("hook_server_port")
assert(type(hook_port) == "number", "hook_port must be a number")
assert(hook_port <= 65535, "hook_port must be below 65536")
local hook_secret = ngx.shared.auto_ssl_settings:get("hook_server:secret")
assert(type(hook_secret) == "string", "hook_server:secret must be a string")
-- Run dehydrated for this domain, using our custom hooks to handle the
-- domain validation and the issued certificates.
--
-- Disable dehydrated's locking, since we perform our own domain-specific
-- locking using the storage adapter.
local result, err = shell_execute({
"env",
"HOOK_SECRET=" .. hook_secret,
"HOOK_SERVER_PORT=" .. hook_port,
lua_root .. "/bin/resty-auto-ssl/dehydrated",
"--cron",
"--accept-terms",
"--no-lock",
"--domain", domain,
"--challenge", "http-01",
"--config", base_dir .. "/letsencrypt/config",
"--hook", lua_root .. "/bin/resty-auto-ssl/letsencrypt_hooks",
})
-- Cleanup dehydrated files after running to prevent temp files from piling
-- up. This always runs, regardless of whether or not dehydrated succeeds (in
-- which case the certs should be installed in storage) or dehydrated fails
-- (in which case these files aren't of much additional use).
_M.cleanup(auto_ssl_instance, domain)
if result["status"] ~= 0 then
ngx.log(ngx.ERR, "auto-ssl: dehydrated failed: ", result["command"], " status: ", result["status"], " out: ", result["output"], " err: ", err)
return nil, "dehydrated failure"
end
ngx.log(ngx.DEBUG, "auto-ssl: dehydrated output: " .. result["output"])
-- The result of running that command should result in the certs being
-- populated in our storage (due to the deploy_cert hook triggering).
local storage = auto_ssl_instance.storage
local cert, get_cert_err = storage:get_cert(domain)
if get_cert_err then
ngx.log(ngx.ERR, "auto-ssl: error fetching certificate from storage for ", domain, ": ", get_cert_err)
end
-- Return error if things are still unexpectedly missing.
if not cert or not cert["fullchain_pem"] or not cert["privkey_pem"] then
return nil, "dehydrated succeeded, but no certs present"
end
return cert
end
function _M.cleanup(auto_ssl_instance, domain)
assert(string.find(domain, "/") == nil)
assert(string.find(domain, "%.%.") == nil)
local dir = auto_ssl_instance:get("dir") .. "/letsencrypt/certs/" .. domain
local _, rm_err = shell_execute({ "rm", "-rf", dir })
if rm_err then
ngx.log(ngx.ERR, "auto-ssl: failed to cleanup certs: ", rm_err)
end
end
return _M