Last active
January 22, 2020 09:46
-
-
Save marklkelly/0bce688dc494d5e96882 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local log = ngx.log | |
local exit = ngx.exit | |
local null = ngx.null | |
local ERR = ngx.ERR | |
local INFO = ngx.INFO | |
local DEBUG = ngx.DEBUG | |
local HTTP_INTERNAL_SERVER_ERROR = ngx.HTTP_INTERNAL_SERVER_ERROR | |
-- Setup Redis connection | |
local redis = require "resty.redis" | |
local red = redis:new() | |
local ok, err = red:connect("127.0.0.1", "6379") | |
if not ok then | |
log(ERR, "REDIS: Failed to connect to redis: ", err) | |
return exit(HTTP_INTERNAL_SERVER_ERROR) | |
end | |
-- Setup TLS related. | |
local ssl = require "ngx.ssl" | |
local server_name = ssl.server_name() | |
local addr, addrtyp, err = ssl.raw_server_addr() | |
local byte = string.byte | |
local key, cert | |
-- Local cache related | |
local cert_cache = ngx.shared.cert_cache | |
local cert_cache_duration = 7200 -- 2 hours | |
ssl.clear_certs() | |
-- Check for SNI request - if we don't have the server name, attempt to use the IP address instead. | |
if server_name == nil then | |
log(INFO, "SNI Not present - performing IP lookup") | |
-- Set server name as IP address. | |
server_name = string.format("%d.%d.%d.%d", byte(addr, 1), byte(addr, 2), byte(addr, 3), byte(addr, 4)) | |
log(INFO, "IP Address: ", server_name) | |
end | |
-- Check cache for certficate | |
key = cert_cache:get(server_name .. "_k") | |
cert = cert_cache:get(server_name .. "_c") | |
if key ~= nil and cert ~= nil then | |
log(DEBUG, "Cert cache HIT for: ", server_name) | |
else | |
log(DEBUG, "Cert cache MISS for: ", server_name) | |
-- If the cert isn't in the cache, attept to retrieve from Redis | |
local domain, err = red:hmget("domain:" .. server_name, "key", "cert") | |
if domain[1] == null then | |
log(ERR, "failed to retreive certificates for domain: ", server_name, " Err: ", err) | |
return | |
end | |
key = domain[1] | |
cert = domain[2] | |
-- If we've retrieved the cert and key, attempt to cache | |
if key ~= nil and cert ~= nil then | |
-- Add key and cert to the cache | |
local success, err, forcible = cert_cache:set(server_name .. "_k", key, cert_cache_duration) | |
log(DEBUG, "Caching Result: ", success, " Err: ", err) | |
success, err, forcible = cert_cache:set(server_name .. "_c", cert, cert_cache_duration) | |
log(DEBUG, "Caching Result: ", success, " Err: ", err) | |
log(DEBUG, "Cert and key retrieved and cached for: ", server_name) | |
else | |
log(ERR, "Failed to retrieve " .. (key and "" or "key ") .. (cert and "" or "cert "), "for ", server_name) | |
return | |
end | |
end | |
-- Set cert | |
local ok, err = ssl.set_der_cert(cert) | |
if not ok then | |
log(ERR, "failed to set DER cert: ", err) | |
return | |
end | |
-- Set key | |
local ok, err = ssl.set_der_priv_key(key) | |
if not ok then | |
log(ERR, "failed to set DER key: ", err) | |
return | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment