From 8428c5d11a5fa4a2bab73608dd99bf15e79cea12 Mon Sep 17 00:00:00 2001 From: David Merfield <dmerfield@gmail.com> Date: Fri, 27 Oct 2023 18:34:53 +0100 Subject: [PATCH] Updates init.lua --- config/openresty/conf/init.lua | 187 +++++++++++++++++++-------------- 1 file changed, 107 insertions(+), 80 deletions(-) diff --git a/config/openresty/conf/init.lua b/config/openresty/conf/init.lua index 092b74a8deb..e58c69520fa 100644 --- a/config/openresty/conf/init.lua +++ b/config/openresty/conf/init.lua @@ -1,3 +1,84 @@ + +local redis = require "resty.redis" + +local redis_options = { host = "{{redis.host}}", port = 6379 , prefix = "ssl" } + +local function get_redis_instance(redis_options) + + local instance = ngx.ctx.auto_ssl_redis_instance + + if instance then + return instance + end + + instance = redis:new() + + local ok, err + + if redis_options["socket"] then + ok, err = instance:connect(redis_options["socket"]) + else + ok, err = instance:connect(redis_options["host"], redis_options["port"]) + end + + if not ok then + return false, err + end + + if redis_options["auth"] then + ok, err = instance:auth(redis_options["auth"]) + if not ok then + return false, err + end + end + + ngx.ctx.auto_ssl_redis_instance = instance + return instance +end + +auto_ssl = (require "resty.auto-ssl").new() + +auto_ssl:set("redis", redis_options) + +-- Certificates are stored in redis +auto_ssl:set("storage_adapter", "resty.auto-ssl.storage_adapters.redis") + +-- This function determines whether the incoming domain +-- should automatically issue a new SSL certificate. +-- I need to set domain:blot.im to foo in the database so that +-- the allow_domain function works as expected even though +-- it's not technically a user's domain +auto_ssl:set("allow_domain", function(domain) + + local certstorage = auto_ssl.storage + + local fullchain_pem, privkey_pem = certstorage:get_cert(domain) + + -- If we have this cert in the memory cache + -- then return it without checking redis to save time + if fullchain_pem then + return true + end + + local redis_instance, instance_err = get_redis_instance(redis_options) + + if instance_err then + return nil, instance_err + end + + local res, err = redis_instance:get('domain:' .. domain) + + if res == ngx.null then + return false + end + + return true +end) + +auto_ssl:init() + +-- now we rehydrate the cache + local cache_directory = "{{{cache_directory}}}" -- this file will read the contents of the cache directory and store them in @@ -42,14 +123,35 @@ local function extractHostFromCacheFile (cache_file_path) -- KEY: http://example.com/xyz/abc local file = io.open(cache_file_path, "r") local first_line = file:read() + + -- keep reading the file until we get a line that starts with KEY + while (first_line ~= nil and string.match(first_line, "^KEY:") == nil) do + first_line = file:read() + end + + if (first_line == nil) then + ngx.log(ngx.NOTICE, "uri is nil") + return nil + end + local uri = string.match(first_line, "KEY: (.*)") + if (uri == nil) then + ngx.log(ngx.NOTICE, "uri is nil") + return nil + end + -- the protocol is included in the uri so we need to remove it local uri_without_protocol = string.match(uri, "://(.*)") -- the host is the first part of the uri, up to question mark or slash if present local host = string.match(uri_without_protocol, "([^/?]+)") + if (host == nil) then + ngx.log(ngx.NOTICE, "host is nil") + return nil + end + file:close() ngx.log(ngx.NOTICE, "found host from cache_file_path: " .. host) @@ -101,7 +203,8 @@ if ngx ~= nil then local cache_file_path = top_level_directory .. "/" .. second_level_directory .. "/" .. file local host = extractHostFromCacheFile(second_level_directory_path .. "/" .. file) - -- add the host to the list of hosts + if (host ~= nil) then + -- add the host to the list of hosts if (hosts[host] == nil) then ngx.log(ngx.NOTICE, "found host: " .. host) table.insert(hosts, host) @@ -111,6 +214,9 @@ if ngx ~= nil then ngx.log(ngx.NOTICE, "found cache file path: " .. cache_file_path) proxy_cache_keys_by_host:set(cache_file_path, true) proxy_cache_keys_by_host:rpush(host, cache_file_path) + end + + end end end @@ -119,82 +225,3 @@ if ngx ~= nil then deduplicate_key_list_by_host(host, proxy_cache_keys_by_host) end end - - -local redis = require "resty.redis" - -local redis_options = { host = "{{redis.host}}", port = 6379 , prefix = "ssl" } - -local function get_redis_instance(redis_options) - - local instance = ngx.ctx.auto_ssl_redis_instance - - if instance then - return instance - end - - instance = redis:new() - - local ok, err - - if redis_options["socket"] then - ok, err = instance:connect(redis_options["socket"]) - else - ok, err = instance:connect(redis_options["host"], redis_options["port"]) - end - - if not ok then - return false, err - end - - if redis_options["auth"] then - ok, err = instance:auth(redis_options["auth"]) - if not ok then - return false, err - end - end - - ngx.ctx.auto_ssl_redis_instance = instance - return instance -end - -auto_ssl = (require "resty.auto-ssl").new() - -auto_ssl:set("redis", redis_options) - --- Certificates are stored in redis -auto_ssl:set("storage_adapter", "resty.auto-ssl.storage_adapters.redis") - --- This function determines whether the incoming domain --- should automatically issue a new SSL certificate. --- I need to set domain:blot.im to foo in the database so that --- the allow_domain function works as expected even though --- it's not technically a user's domain -auto_ssl:set("allow_domain", function(domain) - - local certstorage = auto_ssl.storage - - local fullchain_pem, privkey_pem = certstorage:get_cert(domain) - - -- If we have this cert in the memory cache - -- then return it without checking redis to save time - if fullchain_pem then - return true - end - - local redis_instance, instance_err = get_redis_instance(redis_options) - - if instance_err then - return nil, instance_err - end - - local res, err = redis_instance:get('domain:' .. domain) - - if res == ngx.null then - return false - end - - return true -end) - -auto_ssl:init() \ No newline at end of file