Add support for multiple alias and remove duplication of SSL certificates (#4472)
This commit is contained in:
parent
4847bb02f0
commit
8def5ef7ca
19 changed files with 190 additions and 101 deletions
|
|
@ -3,6 +3,7 @@ local cjson = require("cjson.safe")
|
|||
-- this is the Lua representation of Configuration struct in internal/ingress/types.go
|
||||
local configuration_data = ngx.shared.configuration_data
|
||||
local certificate_data = ngx.shared.certificate_data
|
||||
local certificate_servers = ngx.shared.certificate_servers
|
||||
|
||||
local _M = {}
|
||||
|
||||
|
|
@ -35,7 +36,12 @@ local function fetch_request_body()
|
|||
end
|
||||
|
||||
function _M.get_pem_cert_key(hostname)
|
||||
return certificate_data:get(hostname)
|
||||
local uid = certificate_servers:get(hostname)
|
||||
if not uid then
|
||||
return nil
|
||||
end
|
||||
|
||||
return certificate_data:get(uid)
|
||||
end
|
||||
|
||||
local function handle_servers()
|
||||
|
|
@ -45,30 +51,39 @@ local function handle_servers()
|
|||
return
|
||||
end
|
||||
|
||||
local raw_servers = fetch_request_body()
|
||||
local raw_configuration = fetch_request_body()
|
||||
|
||||
local servers, err = cjson.decode(raw_servers)
|
||||
if not servers then
|
||||
ngx.log(ngx.ERR, "could not parse servers: ", err)
|
||||
local configuration, err = cjson.decode(raw_configuration)
|
||||
if not configuration then
|
||||
ngx.log(ngx.ERR, "could not parse configuration: ", err)
|
||||
ngx.status = ngx.HTTP_BAD_REQUEST
|
||||
return
|
||||
end
|
||||
|
||||
local err_buf = {}
|
||||
for _, server in ipairs(servers) do
|
||||
if server.hostname and server.sslCert.pemCertKey then
|
||||
local success, set_err, forcible = certificate_data:set(server.hostname, server.sslCert.pemCertKey)
|
||||
if not success then
|
||||
local err_msg = string.format("error setting certificate for %s: %s\n", server.hostname, tostring(set_err))
|
||||
table.insert(err_buf, err_msg)
|
||||
end
|
||||
if forcible then
|
||||
local msg = string.format("certificate_data dictionary is full, LRU entry has been removed to store %s",
|
||||
server.hostname)
|
||||
ngx.log(ngx.WARN, msg)
|
||||
end
|
||||
else
|
||||
ngx.log(ngx.WARN, "hostname or pemCertKey are not present")
|
||||
|
||||
for server, uid in pairs(configuration.servers) do
|
||||
local success, set_err, forcible = certificate_servers:set(server, uid)
|
||||
if not success then
|
||||
local err_msg = string.format("error setting certificate for %s: %s\n", server, tostring(set_err))
|
||||
table.insert(err_buf, err_msg)
|
||||
end
|
||||
if forcible then
|
||||
local msg = string.format("certificate_servers dictionary is full, LRU entry has been removed to store %s",
|
||||
server)
|
||||
ngx.log(ngx.WARN, msg)
|
||||
end
|
||||
end
|
||||
|
||||
for uid, cert in pairs(configuration.certificates) do
|
||||
local success, set_err, forcible = certificate_data:set(uid, cert)
|
||||
if not success then
|
||||
local err_msg = string.format("error setting certificate for %s: %s\n", uid, tostring(set_err))
|
||||
table.insert(err_buf, err_msg)
|
||||
end
|
||||
if forcible then
|
||||
local msg = string.format("certificate_data dictionary is full, LRU entry has been removed to store %s", uid)
|
||||
ngx.log(ngx.WARN, msg)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ end
|
|||
local EXAMPLE_CERT = read_file("rootfs/etc/nginx/lua/test/fixtures/example-com-cert.pem")
|
||||
local DEFAULT_CERT = read_file("rootfs/etc/nginx/lua/test/fixtures/default-cert.pem")
|
||||
local DEFAULT_CERT_HOSTNAME = "_"
|
||||
local UUID = "2ea8adb5-8ebb-4b14-a79b-0cdcd892e884"
|
||||
local DEFAULT_UUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
local function assert_certificate_is_set(cert)
|
||||
spy.on(ngx, "log")
|
||||
|
|
@ -45,50 +47,57 @@ describe("Certificate", function()
|
|||
ngx.exit = function(status) end
|
||||
|
||||
|
||||
ngx.shared.certificate_data:set(DEFAULT_CERT_HOSTNAME, DEFAULT_CERT)
|
||||
ngx.shared.certificate_servers:set(DEFAULT_CERT_HOSTNAME, DEFAULT_UUID)
|
||||
ngx.shared.certificate_data:set(DEFAULT_UUID, DEFAULT_CERT)
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
ngx = unmocked_ngx
|
||||
ngx.shared.certificate_data:flush_all()
|
||||
ngx.shared.certificate_servers:flush_all()
|
||||
end)
|
||||
|
||||
it("sets certificate and key when hostname is found in dictionary", function()
|
||||
ngx.shared.certificate_data:set("hostname", EXAMPLE_CERT)
|
||||
ngx.shared.certificate_servers:set("hostname", UUID)
|
||||
ngx.shared.certificate_data:set(UUID, EXAMPLE_CERT)
|
||||
|
||||
assert_certificate_is_set(EXAMPLE_CERT)
|
||||
end)
|
||||
|
||||
it("sets certificate and key for wildcard cert", function()
|
||||
ssl.server_name = function() return "sub.hostname", nil end
|
||||
ngx.shared.certificate_data:set("*.hostname", EXAMPLE_CERT)
|
||||
ngx.shared.certificate_servers:set("*.hostname", UUID)
|
||||
ngx.shared.certificate_data:set(UUID, EXAMPLE_CERT)
|
||||
|
||||
assert_certificate_is_set(EXAMPLE_CERT)
|
||||
end)
|
||||
|
||||
it("sets certificate and key for domain with trailing dot", function()
|
||||
ssl.server_name = function() return "hostname.", nil end
|
||||
ngx.shared.certificate_data:set("hostname", EXAMPLE_CERT)
|
||||
ngx.shared.certificate_servers:set("hostname", UUID)
|
||||
ngx.shared.certificate_data:set(UUID, EXAMPLE_CERT)
|
||||
|
||||
assert_certificate_is_set(EXAMPLE_CERT)
|
||||
end)
|
||||
|
||||
it("fallbacks to default certificate and key for domain with many trailing dots", function()
|
||||
ssl.server_name = function() return "hostname..", nil end
|
||||
ngx.shared.certificate_data:set("hostname", EXAMPLE_CERT)
|
||||
ngx.shared.certificate_servers:set("hostname", UUID)
|
||||
ngx.shared.certificate_data:set(UUID, EXAMPLE_CERT)
|
||||
|
||||
assert_certificate_is_set(DEFAULT_CERT)
|
||||
end)
|
||||
|
||||
it("sets certificate and key for nested wildcard cert", function()
|
||||
ssl.server_name = function() return "sub.nested.hostname", nil end
|
||||
ngx.shared.certificate_data:set("*.nested.hostname", EXAMPLE_CERT)
|
||||
ngx.shared.certificate_servers:set("*.nested.hostname", UUID)
|
||||
ngx.shared.certificate_data:set(UUID, EXAMPLE_CERT)
|
||||
|
||||
assert_certificate_is_set(EXAMPLE_CERT)
|
||||
end)
|
||||
|
||||
it("logs error message when certificate in dictionary is invalid", function()
|
||||
ngx.shared.certificate_data:set("hostname", "something invalid")
|
||||
ngx.shared.certificate_servers:set("hostname", "something invalid")
|
||||
|
||||
spy.on(ngx, "log")
|
||||
|
||||
|
|
@ -108,7 +117,8 @@ describe("Certificate", function()
|
|||
end)
|
||||
|
||||
it("fails when hostname does not have certificate and default cert is invalid", function()
|
||||
ngx.shared.certificate_data:set(DEFAULT_CERT_HOSTNAME, "invalid")
|
||||
ngx.shared.certificate_servers:set(DEFAULT_CERT_HOSTNAME, UID)
|
||||
ngx.shared.certificate_data:set(UID, "invalid")
|
||||
|
||||
spy.on(ngx, "log")
|
||||
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ describe("Configuration", function()
|
|||
describe("handle_servers()", function()
|
||||
it("should not accept non POST methods", function()
|
||||
ngx.var.request_method = "GET"
|
||||
|
||||
|
||||
local s = spy.on(ngx, "print")
|
||||
assert.has_no.errors(configuration.handle_servers)
|
||||
assert.spy(s).was_called_with("Only POST requests are allowed!")
|
||||
|
|
@ -232,7 +232,7 @@ describe("Configuration", function()
|
|||
|
||||
local s = spy.on(ngx, "log")
|
||||
assert.has_no.errors(configuration.handle_servers)
|
||||
assert.spy(s).was_called_with(ngx.ERR,
|
||||
assert.spy(s).was_called_with(ngx.ERR,
|
||||
"error setting certificate for hostname: error\nerror setting certificate for hostname2: error\n")
|
||||
assert.same(ngx.status, ngx.HTTP_INTERNAL_SERVER_ERROR)
|
||||
end)
|
||||
|
|
|
|||
|
|
@ -506,7 +506,7 @@ http {
|
|||
|
||||
## start server {{ $server.Hostname }}
|
||||
server {
|
||||
server_name {{ $server.Hostname }} {{ $server.Alias }};
|
||||
server_name {{ $server.Hostname }} {{range $server.Aliases }}{{ . }} {{ end }};
|
||||
|
||||
{{ if gt (len $cfg.BlockUserAgents) 0 }}
|
||||
if ($block_ua) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue