From 85773e3beae3613ea653a3a598a23f101547f5de Mon Sep 17 00:00:00 2001 From: Aapo Talvensaari Date: Tue, 16 Aug 2022 19:38:21 +0300 Subject: [PATCH 1/7] feat(conf): allow *_cert and *_cert_key to be stored in environment variables and vaults ### Summary Allow several `kong.conf` values to be stored in vaults or environment variables: - `ssl_cert` - `ssl_cert_key` - `admin_ssl_cert` - `admin_ssl_cert_key` - `status_ssl_cert` - `status_ssl_cert_key` - `cluster_cert` - `cluster_cert_key` - `client_ssl_cert` - `client_ssl_cert_key` #### Usage The following is possible after this is commit is merged: ```bash CERT=$( Date: Wed, 31 Aug 2022 18:19:04 +0200 Subject: [PATCH 2/7] feat(conf): add support for remaining variables (#9352) * move creation of certificate and key files in a separate block * add file creation for the remaining certs and keys: cluster_ and client_ * update configuration with generated path for cluster_* and client_* --- kong/cmd/utils/prefix_handler.lua | 72 +++++++++++++++++++++++----- kong/conf_loader/init.lua | 12 ++--- spec/01-unit/03-conf_loader_spec.lua | 24 +++++----- 3 files changed, 79 insertions(+), 29 deletions(-) diff --git a/kong/cmd/utils/prefix_handler.lua b/kong/cmd/utils/prefix_handler.lua index 3bc6fff13e3c..59218b86c604 100644 --- a/kong/cmd/utils/prefix_handler.lua +++ b/kong/cmd/utils/prefix_handler.lua @@ -461,24 +461,74 @@ local function prepare_prefix(kong_config, nginx_custom_template_path, skip_writ ssl_cert_key[1] = kong_config[prefix .. "ssl_cert_key_default"] ssl_cert[2] = kong_config[prefix .. "ssl_cert_default_ecdsa"] ssl_cert_key[2] = kong_config[prefix .. "ssl_cert_key_default_ecdsa"] + end + end + end - else - local ssl_path = join(kong_config.prefix, "ssl") - makepath(ssl_path) + -- create certs files and assign paths if needed + do - for i, cert in ipairs(ssl_cert) do - local path = join(ssl_path, target .. "-" .. i .. ".crt") - write_ssl_cert(path, cert) - ssl_cert[i] = path + local function write_file_set_path( + file, + format, + write_func, + ssl_path, + target, + config_key + ) + if type(file) == "string" then + if not exists(file) then + if not exists(ssl_path) then + makepath(ssl_path) + end + local path = join(ssl_path, target .. format) + write_func(path, file) + kong_config[config_key] = path end - for i, cert_key in ipairs(ssl_cert_key) do - local path = join(ssl_path, target .. "-" .. i .. ".key") - write_ssl_cert_key(path, cert_key) - ssl_cert_key[i] = path + else + for i, cert_key in ipairs(file) do + if not exists(cert_key) then + if not exists(ssl_path) then + makepath(ssl_path) + end + local path = join(ssl_path, target .. "-" .. i .. format) + write_func(path, cert_key) + file[i] = path + end end end end + + for _, target in ipairs({ + "proxy", + "admin", + "status", + "client", + "cluster" + }) do + + local prefix + if target == "proxy" then + prefix = "ssl" + elseif target == "cluster" then + prefix = target + else + prefix = target .. "_ssl" + end + + local cert_k = prefix .. "_cert" + local key_k = prefix .. "_cert_key" + local ssl_cert = kong_config[cert_k] + local ssl_cert_key = kong_config[key_k] + + if ssl_cert and ssl_cert_key and #ssl_cert > 0 and #ssl_cert_key > 0 then + local ssl_path = join(kong_config.prefix, "ssl") + + write_file_set_path(ssl_cert, ".crt", write_ssl_cert, ssl_path, target, cert_k) + write_file_set_path(ssl_cert_key, ".key", write_ssl_cert_key, ssl_path, target, key_k) + end + end end if kong_config.lua_ssl_trusted_certificate_combined then diff --git a/kong/conf_loader/init.lua b/kong/conf_loader/init.lua index 6653b664bb68..00487455a126 100644 --- a/kong/conf_loader/init.lua +++ b/kong/conf_loader/init.lua @@ -752,7 +752,7 @@ local function check_and_infer(conf, opts) if not exists(cert) then local _, err = openssl_x509.new(cert) if err then - errors[#errors + 1] = prefix .. "ssl_cert: no such file at " .. cert + errors[#errors + 1] = prefix .. "ssl_cert: failed loading certificate from " .. cert end end end @@ -763,7 +763,7 @@ local function check_and_infer(conf, opts) if not exists(cert_key) then local _, err = openssl_pkey.new(cert_key) if err then - errors[#errors + 1] = prefix .. "ssl_cert_key: no such file at " .. cert_key + errors[#errors + 1] = prefix .. "ssl_cert_key: failed loading key from " .. cert_key end end end @@ -785,14 +785,14 @@ local function check_and_infer(conf, opts) if client_ssl_cert and not exists(client_ssl_cert) then local _, err = openssl_x509.new(client_ssl_cert) if err then - errors[#errors + 1] = "client_ssl_cert: no such file at " .. client_ssl_cert + errors[#errors + 1] = "client_ssl_cert: failed loading certificate from " .. client_ssl_cert end end if client_ssl_cert_key and not exists(client_ssl_cert_key) then local _, err = openssl_pkey.new(client_ssl_cert_key) if err then - errors[#errors + 1] = "client_ssl_cert_key: no such file at " .. + errors[#errors + 1] = "client_ssl_cert_key: failed loading key from " .. client_ssl_cert_key end end @@ -1013,14 +1013,14 @@ local function check_and_infer(conf, opts) if not exists(cluster_cert) then local _, err = openssl_x509.new(cluster_cert) if err then - errors[#errors + 1] = "cluster_cert: no such file at " .. cluster_cert + errors[#errors + 1] = "cluster_cert: failed loading certificate from " .. cluster_cert end end if not exists(cluster_cert_key) then local _, err = openssl_pkey.new(cluster_cert_key) if err then - errors[#errors + 1] = "cluster_cert_key: no such file at " .. cluster_cert_key + errors[#errors + 1] = "cluster_cert_key: failed loading key from " .. cluster_cert_key end end end diff --git a/spec/01-unit/03-conf_loader_spec.lua b/spec/01-unit/03-conf_loader_spec.lua index f799dedd650b..ac0c88a09f8f 100644 --- a/spec/01-unit/03-conf_loader_spec.lua +++ b/spec/01-unit/03-conf_loader_spec.lua @@ -770,8 +770,8 @@ describe("Configuration loader", function() ssl_cert_key = "/path/cert_key.pem" }) assert.equal(2, #errors) - assert.contains("ssl_cert: no such file at /path/cert.pem", errors) - assert.contains("ssl_cert_key: no such file at /path/cert_key.pem", errors) + assert.contains("ssl_cert: failed loading certificate from /path/cert.pem", errors) + assert.contains("ssl_cert_key: failed loading key from /path/cert_key.pem", errors) assert.is_nil(conf) conf, _, errors = conf_loader(nil, { @@ -779,7 +779,7 @@ describe("Configuration loader", function() ssl_cert_key = "/path/cert_key.pem" }) assert.equal(1, #errors) - assert.contains("ssl_cert_key: no such file at /path/cert_key.pem", errors) + assert.contains("ssl_cert_key: failed loading key from /path/cert_key.pem", errors) assert.is_nil(conf) end) it("requires SSL DH param file to exist", function() @@ -1050,8 +1050,8 @@ describe("Configuration loader", function() client_ssl_cert_key = "/path/cert_key.pem" }) assert.equal(2, #errors) - assert.contains("client_ssl_cert: no such file at /path/cert.pem", errors) - assert.contains("client_ssl_cert_key: no such file at /path/cert_key.pem", errors) + assert.contains("client_ssl_cert: failed loading certificate from /path/cert.pem", errors) + assert.contains("client_ssl_cert_key: failed loading key from /path/cert_key.pem", errors) assert.is_nil(conf) conf, _, errors = conf_loader(nil, { @@ -1060,7 +1060,7 @@ describe("Configuration loader", function() client_ssl_cert_key = "/path/cert_key.pem" }) assert.equal(1, #errors) - assert.contains("client_ssl_cert_key: no such file at /path/cert_key.pem", errors) + assert.contains("client_ssl_cert_key: failed loading key from /path/cert_key.pem", errors) assert.is_nil(conf) end) it("resolves SSL cert/key to absolute path", function() @@ -1117,8 +1117,8 @@ describe("Configuration loader", function() admin_ssl_cert_key = "/path/cert_key.pem" }) assert.equal(2, #errors) - assert.contains("admin_ssl_cert: no such file at /path/cert.pem", errors) - assert.contains("admin_ssl_cert_key: no such file at /path/cert_key.pem", errors) + assert.contains("admin_ssl_cert: failed loading certificate from /path/cert.pem", errors) + assert.contains("admin_ssl_cert_key: failed loading key from /path/cert_key.pem", errors) assert.is_nil(conf) conf, _, errors = conf_loader(nil, { @@ -1126,7 +1126,7 @@ describe("Configuration loader", function() admin_ssl_cert_key = "/path/cert_key.pem" }) assert.equal(1, #errors) - assert.contains("admin_ssl_cert_key: no such file at /path/cert_key.pem", errors) + assert.contains("admin_ssl_cert_key: failed loading key from /path/cert_key.pem", errors) assert.is_nil(conf) end) it("resolves SSL cert/key to absolute path", function() @@ -1188,8 +1188,8 @@ describe("Configuration loader", function() status_ssl_cert_key = "/path/cert_key.pem" }) assert.equal(2, #errors) - assert.contains("status_ssl_cert: no such file at /path/cert.pem", errors) - assert.contains("status_ssl_cert_key: no such file at /path/cert_key.pem", errors) + assert.contains("status_ssl_cert: failed loading certificate from /path/cert.pem", errors) + assert.contains("status_ssl_cert_key: failed loading key from /path/cert_key.pem", errors) assert.is_nil(conf) conf, _, errors = conf_loader(nil, { @@ -1198,7 +1198,7 @@ describe("Configuration loader", function() status_ssl_cert_key = "/path/cert_key.pem" }) assert.equal(1, #errors) - assert.contains("status_ssl_cert_key: no such file at /path/cert_key.pem", errors) + assert.contains("status_ssl_cert_key: failed loading key from /path/cert_key.pem", errors) assert.is_nil(conf) end) it("resolves SSL cert/key to absolute path", function() From 026b86b5e056f301051a480035aad35cf4e6e697 Mon Sep 17 00:00:00 2001 From: Samuele Illuminati Date: Fri, 2 Sep 2022 15:16:02 +0200 Subject: [PATCH 3/7] feat(conf): support base64 encoded *_cert and *_cert_key (#9367) * support base64 encoded *_cert and *_cert_key * support base64url encoding This adds a test case to ensure base64 encoded properties are corectly parsed and decoded. --- kong/conf_loader/init.lua | 35 +++++++++++++++++++++++++ spec/01-unit/03-conf_loader_spec.lua | 39 ++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/kong/conf_loader/init.lua b/kong/conf_loader/init.lua index 00487455a126..e0f3681fc551 100644 --- a/kong/conf_loader/init.lua +++ b/kong/conf_loader/init.lua @@ -18,6 +18,7 @@ local utils = require "kong.tools.utils" local log = require "kong.cmd.utils.log" local env = require "kong.cmd.utils.env" local ffi = require "ffi" +local base64 = require "ngx.base64" local fmt = string.format @@ -44,6 +45,8 @@ local abspath = pl_path.abspath local tostring = tostring local tonumber = tonumber local setmetatable = setmetatable +local decode_base64 = ngx.decode_base64 +local decode_base64url = base64.decode_base64url local get_phase do @@ -622,6 +625,26 @@ local function infer_value(value, typ, opts) end +local function try_base64_decode(vals) + if type(vals) == "table" then + for i, v in ipairs(vals) do + vals[i] = decode_base64(v) + or decode_base64url(v) + or v + end + return vals + end + + if type(vals) == "string" then + return decode_base64(vals) + or decode_base64url(vals) + or vals + end + + return vals +end + + -- Validate properties (type/enum/custom) and infer their type. -- @param[type=table] conf The configuration table to treat. local function check_and_infer(conf, opts) @@ -646,6 +669,18 @@ local function check_and_infer(conf, opts) conf[k] = value end + -- decode base64 for supported fields + for _, prefix in ipairs({ + "ssl", + "admin_ssl", + "status_ssl", + "client_ssl", + "cluster" + }) do + conf[prefix .. "_cert"] = try_base64_decode(conf[prefix .. "_cert"]) + conf[prefix .. "_cert_key"] = try_base64_decode(conf[prefix .. "_cert_key"]) + end + --------------------- -- custom validations --------------------- diff --git a/spec/01-unit/03-conf_loader_spec.lua b/spec/01-unit/03-conf_loader_spec.lua index ac0c88a09f8f..9840ca9dad4a 100644 --- a/spec/01-unit/03-conf_loader_spec.lua +++ b/spec/01-unit/03-conf_loader_spec.lua @@ -728,6 +728,45 @@ describe("Configuration loader", function() assert.is_nil(conf) end) describe("SSL", function() + it("accepts and decodes valid base64 values", function() + local ssl_fixtures = require "spec.fixtures.ssl" + local prefixes = { + "ssl", + "admin_ssl", + "status_ssl", + "client_ssl", + "cluster" + } + local cert = ssl_fixtures.cert + local key = ssl_fixtures.key + local cert_base64 = ngx.encode_base64(cert) + local key_base64 = ngx.encode_base64(key) + local params = {} + for _, prefix in ipairs(prefixes) do + params[prefix .. "_cert"] = cert_base64 + params[prefix .. "_cert_key"] = key_base64 + end + local conf, err = conf_loader(nil, params) + + assert.is_nil(err) + assert.is_table(conf) + for _, prefix in ipairs(prefixes) do + local certs = conf[prefix .. "_cert"] + local keys = conf[prefix .. "_cert_key"] + + if type(certs) == "table" then + for i = 1, #certs do + assert.equals(cert, certs[i]) + assert.equals(key, keys[i]) + end + end + + if type(certs) == "string" then + assert.equals(cert, certs) + assert.equals(key, keys) + end + end + end) describe("proxy", function() it("does not check SSL cert and key if SSL is off", function() local conf, err = conf_loader(nil, { From 9dd92c240afdc54f562d661bcf25d9f74eed03f0 Mon Sep 17 00:00:00 2001 From: samugi Date: Mon, 5 Sep 2022 17:59:03 +0200 Subject: [PATCH 4/7] feat(conf): add cluster_ca_cert, ssl_dhparam, lua_ssl_trusted_certificate This adds to the supported properties that can be assigned via environment variables or vault. --- kong/cmd/utils/prefix_handler.lua | 93 +++++++++++++++++++++------ kong/conf_loader/init.lua | 96 ++++++++++++++++++++-------- spec/01-unit/03-conf_loader_spec.lua | 28 +++++++- 3 files changed, 169 insertions(+), 48 deletions(-) diff --git a/kong/cmd/utils/prefix_handler.lua b/kong/cmd/utils/prefix_handler.lua index 59218b86c604..f14516e3a2cc 100644 --- a/kong/cmd/utils/prefix_handler.lua +++ b/kong/cmd/utils/prefix_handler.lua @@ -468,33 +468,64 @@ local function prepare_prefix(kong_config, nginx_custom_template_path, skip_writ -- create certs files and assign paths if needed do + local function propagate_dhparam(path) + kong_config["nginx_http_ssl_dhparam"] = path + kong_config["nginx_stream_ssl_dhparam"] = path + + for _, directive in ipairs(kong_config["nginx_http_directives"]) do + if directive.name == "ssl_dhparam" and directive.value then + directive.value = path + end + end + + for _, directive in ipairs(kong_config["nginx_stream_directives"]) do + if directive.name == "ssl_dhparam" and directive.value then + directive.value = path + end + end + end + + local function is_predefined_dhgroup(group) + if type(group) ~= "string" then + return false + end + + return not not openssl_pkey.paramgen({ + type = "DH", + group = group, + }) + end + local function write_file_set_path( - file, + contents, format, write_func, ssl_path, target, config_key ) - if type(file) == "string" then - if not exists(file) then + if type(contents) == "string" then + if not exists(contents) then if not exists(ssl_path) then makepath(ssl_path) end local path = join(ssl_path, target .. format) - write_func(path, file) + write_func(path, contents) kong_config[config_key] = path + if target == "ssl-dhparam" then + propagate_dhparam(path) + end end else - for i, cert_key in ipairs(file) do - if not exists(cert_key) then + for i, content in ipairs(contents) do + if not exists(content) then if not exists(ssl_path) then makepath(ssl_path) end local path = join(ssl_path, target .. "-" .. i .. format) - write_func(path, cert_key) - file[i] = path + write_func(path, content) + contents[i] = path end end end @@ -505,28 +536,48 @@ local function prepare_prefix(kong_config, nginx_custom_template_path, skip_writ "admin", "status", "client", - "cluster" + "cluster", + "ssl-dhparam", + "lua-ssl-trusted", + "cluster-ca" }) do + local ssl_path = join(kong_config.prefix, "ssl") + local cert_name + local key_name + local ssl_cert + local ssl_key - local prefix if target == "proxy" then - prefix = "ssl" + cert_name = "ssl_cert" + key_name = "ssl_cert_key" elseif target == "cluster" then - prefix = target + cert_name = target .. "_cert" + key_name = target .. "_cert_key" + elseif target == "cluster-ca" then + cert_name = "cluster_ca_cert" + elseif target == "ssl-dhparam" then + cert_name = "ssl_dhparam" + elseif target == "lua-ssl-trusted" then + cert_name = "lua_ssl_trusted_certificate" else - prefix = target .. "_ssl" + cert_name = target .. "_ssl_cert" + key_name = target .. "_ssl_cert_key" end - local cert_k = prefix .. "_cert" - local key_k = prefix .. "_cert_key" - local ssl_cert = kong_config[cert_k] - local ssl_cert_key = kong_config[key_k] + if cert_name and (cert_name ~= "ssl_dhparam" or + not is_predefined_dhgroup(kong_config[cert_name])) then + ssl_cert = kong_config[cert_name] + end + ssl_key = key_name and kong_config[key_name] - if ssl_cert and ssl_cert_key and #ssl_cert > 0 and #ssl_cert_key > 0 then - local ssl_path = join(kong_config.prefix, "ssl") + if ssl_cert and #ssl_cert > 0 then + write_file_set_path(ssl_cert, ".crt", write_ssl_cert, ssl_path, target, + cert_name) + end - write_file_set_path(ssl_cert, ".crt", write_ssl_cert, ssl_path, target, cert_k) - write_file_set_path(ssl_cert_key, ".key", write_ssl_cert_key, ssl_path, target, key_k) + if ssl_key and #ssl_key > 0 then + write_file_set_path(ssl_key, ".key", write_ssl_cert_key, ssl_path, + target, key_name) end end end diff --git a/kong/conf_loader/init.lua b/kong/conf_loader/init.lua index e0f3681fc551..634dab470960 100644 --- a/kong/conf_loader/init.lua +++ b/kong/conf_loader/init.lua @@ -626,9 +626,15 @@ end local function try_base64_decode(vals) + -- names that we should not attempt decoding + local decode_blacklist = { + system = "system" + } + if type(vals) == "table" then for i, v in ipairs(vals) do - vals[i] = decode_base64(v) + vals[i] = decode_blacklist[v] + or decode_base64(v) or decode_base64url(v) or v end @@ -636,7 +642,8 @@ local function try_base64_decode(vals) end if type(vals) == "string" then - return decode_base64(vals) + return decode_blacklist[vals] + or decode_base64(vals) or decode_base64url(vals) or vals end @@ -669,16 +676,23 @@ local function check_and_infer(conf, opts) conf[k] = value end - -- decode base64 for supported fields - for _, prefix in ipairs({ - "ssl", - "admin_ssl", - "status_ssl", - "client_ssl", - "cluster" + -- decode base64 for supported properties + for cert_name, has_key in pairs({ + ssl_cert = true, + admin_ssl_cert = true, + status_ssl_cert = true, + client_ssl_cert = true, + cluster_cert = true, + ssl_dhparam = false, + lua_ssl_trusted_certificate = false, + cluster_ca_cert = false }) do - conf[prefix .. "_cert"] = try_base64_decode(conf[prefix .. "_cert"]) - conf[prefix .. "_cert_key"] = try_base64_decode(conf[prefix .. "_cert_key"]) + conf[cert_name] = try_base64_decode(conf[cert_name]) + + if has_key then + local key_name = cert_name .. "_key" + conf[key_name] = try_base64_decode(conf[key_name]) + end end --------------------- @@ -836,11 +850,11 @@ local function check_and_infer(conf, opts) if conf.lua_ssl_trusted_certificate then local new_paths = {} - for _, path in ipairs(conf.lua_ssl_trusted_certificate) do - if path == "system" then + for _, trusted_cert in ipairs(conf.lua_ssl_trusted_certificate) do + if trusted_cert == "system" then local system_path, err = utils.get_system_trusted_certs_filepath() if system_path then - path = system_path + trusted_cert = system_path elseif not ngx.IS_CLI then log.info("lua_ssl_trusted_certificate: unable to locate system bundle: " .. err .. @@ -849,12 +863,17 @@ local function check_and_infer(conf, opts) end end - if path ~= "system" then - if not exists(path) then - errors[#errors + 1] = "lua_ssl_trusted_certificate: no such file at " .. path + if trusted_cert ~= "system" then + if not exists(trusted_cert) then + local _, err = openssl_x509.new(trusted_cert) + if err then + errors[#errors + 1] = "lua_ssl_trusted_certificate: " .. + "failed loading certificate from " .. + trusted_cert + end end - new_paths[#new_paths + 1] = path + new_paths[#new_paths + 1] = trusted_cert end end @@ -885,8 +904,18 @@ local function check_and_infer(conf, opts) end if conf.ssl_dhparam then - if not is_predefined_dhgroup(conf.ssl_dhparam) and not exists(conf.ssl_dhparam) then - errors[#errors + 1] = "ssl_dhparam: no such file at " .. conf.ssl_dhparam + if not is_predefined_dhgroup(conf.ssl_dhparam) + and not exists(conf.ssl_dhparam) then + local _, err = openssl_pkey.new( + { + type = "DH", + param = conf.ssl_dhparam + } + ) + if err then + errors[#errors + 1] = "ssl_dhparam: failed loading certificate from " + .. conf.ssl_dhparam + end end else @@ -1040,6 +1069,7 @@ local function check_and_infer(conf, opts) if conf.role == "control_plane" or conf.role == "data_plane" then local cluster_cert = conf.cluster_cert local cluster_cert_key = conf.cluster_cert_key + local cluster_ca_cert = conf.cluster_ca_cert if not cluster_cert or not cluster_cert_key then errors[#errors + 1] = "cluster certificate and key must be provided to use Hybrid mode" @@ -1059,6 +1089,14 @@ local function check_and_infer(conf, opts) end end end + + if cluster_ca_cert and not exists(cluster_ca_cert) then + local _, err = openssl_x509.new(cluster_ca_cert) + if err then + errors[#errors + 1] = "cluster_ca_cert: failed loading certificate from " .. + cluster_ca_cert + end + end end if conf.upstream_keepalive_pool_size < 0 then @@ -1769,7 +1807,7 @@ local function load(path, custom_conf, opts) end end - if conf.cluster_ca_cert then + if conf.cluster_ca_cert and exists(conf.cluster_ca_cert) then conf.cluster_ca_cert = abspath(conf.cluster_ca_cert) end @@ -1777,7 +1815,7 @@ local function load(path, custom_conf, opts) conf.stream_proxy_ssl_enabled or conf.admin_ssl_enabled or conf.status_ssl_enabled - + for _, name in ipairs({ "nginx_http_directives", "nginx_stream_directives" }) do for i, directive in ipairs(conf[name]) do if directive.name == "ssl_dhparam" then @@ -1789,7 +1827,7 @@ local function load(path, custom_conf, opts) remove(conf[name], i) end - else + elseif exists(directive.value) then directive.value = abspath(directive.value) end @@ -1800,8 +1838,16 @@ local function load(path, custom_conf, opts) if conf.lua_ssl_trusted_certificate and #conf.lua_ssl_trusted_certificate > 0 then - conf.lua_ssl_trusted_certificate = - tablex.map(pl_path.abspath, conf.lua_ssl_trusted_certificate) + + conf.lua_ssl_trusted_certificate = tablex.map( + function(cert) + if exists(cert) then + return abspath(cert) + end + return cert + end, + conf.lua_ssl_trusted_certificate + ) conf.lua_ssl_trusted_certificate_combined = abspath(pl_path.join(conf.prefix, ".ca_combined")) diff --git a/spec/01-unit/03-conf_loader_spec.lua b/spec/01-unit/03-conf_loader_spec.lua index 9840ca9dad4a..c68392314698 100644 --- a/spec/01-unit/03-conf_loader_spec.lua +++ b/spec/01-unit/03-conf_loader_spec.lua @@ -827,7 +827,7 @@ describe("Configuration loader", function() ssl_dhparam = "/path/dhparam.pem" }) assert.equal(1, #errors) - assert.contains("ssl_dhparam: no such file at /path/dhparam.pem", errors) + assert.contains("ssl_dhparam: failed loading certificate from /path/dhparam.pem", errors) assert.is_nil(conf) conf, _, errors = conf_loader(nil, { @@ -845,7 +845,7 @@ describe("Configuration loader", function() lua_ssl_trusted_certificate = "/path/cert.pem", }) assert.equal(1, #errors) - assert.contains("lua_ssl_trusted_certificate: no such file at /path/cert.pem", errors) + assert.contains("lua_ssl_trusted_certificate: failed loading certificate from /path/cert.pem", errors) assert.is_nil(conf) end) it("accepts several CA certs in lua_ssl_trusted_certificate, setting lua_ssl_trusted_certificate_combined", function() @@ -904,6 +904,30 @@ describe("Configuration loader", function() }) assert.is_nil(errors) end) + it("requires cluster_cert and key files to exist", function() + local conf, _, errors = conf_loader(nil, { + role = "data_plane", + database = "off", + cluster_cert = "path/kong_clustering.crt", + cluster_cert_key = "path/kong_clustering.key", + }) + assert.equal(2, #errors) + assert.contains("cluster_cert: failed loading certificate from path/kong_clustering.crt", errors) + assert.contains("cluster_cert_key: failed loading key from path/kong_clustering.key", errors) + assert.is_nil(conf) + end) + it("requires cluster_ca_cert file to exist", function() + local conf, _, errors = conf_loader(nil, { + role = "data_plane", + database = "off", + cluster_ca_cert = "path/kong_clustering_ca.crt", + cluster_cert = "spec/fixtures/kong_clustering.crt", + cluster_cert_key = "spec/fixtures/kong_clustering.key", + }) + assert.equal(1, #errors) + assert.contains("cluster_ca_cert: failed loading certificate from path/kong_clustering_ca.crt", errors) + assert.is_nil(conf) + end) it("autoload cluster_cert or cluster_ca_cert for data plane in lua_ssl_trusted_certificate", function() local conf, _, errors = conf_loader(nil, { role = "data_plane", From c52d0f9f3abd6e2718740a293c9dbf095f60404b Mon Sep 17 00:00:00 2001 From: samugi Date: Tue, 6 Sep 2022 18:39:41 +0200 Subject: [PATCH 5/7] feat(conf): more test cases * test all base64 decodings * test that properties passed as content result in files being stored --- spec/01-unit/03-conf_loader_spec.lua | 58 ++++++++++++++----------- spec/01-unit/04-prefix_handler_spec.lua | 45 +++++++++++++++++++ spec/fixtures/ssl.lua | 9 ++++ 3 files changed, 87 insertions(+), 25 deletions(-) diff --git a/spec/01-unit/03-conf_loader_spec.lua b/spec/01-unit/03-conf_loader_spec.lua index c68392314698..2043189afae8 100644 --- a/spec/01-unit/03-conf_loader_spec.lua +++ b/spec/01-unit/03-conf_loader_spec.lua @@ -730,40 +730,48 @@ describe("Configuration loader", function() describe("SSL", function() it("accepts and decodes valid base64 values", function() local ssl_fixtures = require "spec.fixtures.ssl" - local prefixes = { - "ssl", - "admin_ssl", - "status_ssl", - "client_ssl", - "cluster" - } local cert = ssl_fixtures.cert + local cacert = ssl_fixtures.cert_ca local key = ssl_fixtures.key - local cert_base64 = ngx.encode_base64(cert) - local key_base64 = ngx.encode_base64(key) - local params = {} - for _, prefix in ipairs(prefixes) do - params[prefix .. "_cert"] = cert_base64 - params[prefix .. "_cert_key"] = key_base64 + local dhparam = ssl_fixtures.dhparam + + local properties = { + ssl_cert = cert, + ssl_cert_key = key, + admin_ssl_cert = cert, + admin_ssl_cert_key = key, + status_ssl_cert = cert, + status_ssl_cert_key = key, + client_ssl_cert = cert, + client_ssl_cert_key = key, + cluster_cert = cert, + cluster_cert_key = key, + cluster_ca_cert = cacert, + ssl_dhparam = dhparam, + lua_ssl_trusted_certificate = cacert + } + + local conf_params = { + ssl_cipher_suite = "old" + } + for n, v in pairs(properties) do + conf_params[n] = ngx.encode_base64(v) end - local conf, err = conf_loader(nil, params) + + local conf, err = conf_loader(nil, conf_params) assert.is_nil(err) assert.is_table(conf) - for _, prefix in ipairs(prefixes) do - local certs = conf[prefix .. "_cert"] - local keys = conf[prefix .. "_cert_key"] - - if type(certs) == "table" then - for i = 1, #certs do - assert.equals(cert, certs[i]) - assert.equals(key, keys[i]) + for name, decoded_val in pairs(properties) do + local values = conf[name] + if type(values) == "table" then + for i = 1, #values do + assert.equals(decoded_val, values[i]) end end - if type(certs) == "string" then - assert.equals(cert, certs) - assert.equals(key, keys) + if type(values) == "string" then + assert.equals(decoded_val, values) end end end) diff --git a/spec/01-unit/04-prefix_handler_spec.lua b/spec/01-unit/04-prefix_handler_spec.lua index bb4e14efdb9b..c6bf789fe504 100644 --- a/spec/01-unit/04-prefix_handler_spec.lua +++ b/spec/01-unit/04-prefix_handler_spec.lua @@ -965,6 +965,51 @@ describe("NGINX conf compiler", function() assert.truthy(exists(join(conf.prefix, "ssl", conf.nginx_http_ssl_dhparam .. ".pem"))) assert.truthy(exists(join(conf.prefix, "ssl", conf.nginx_stream_ssl_dhparam .. ".pem"))) end) + it("accepts and stores values passed as 'content', reconfigures valid paths", function() + local ssl_fixtures = require "spec.fixtures.ssl" + local cert = ssl_fixtures.cert + local cacert = ssl_fixtures.cert_ca + local key = ssl_fixtures.key + local dhparam = ssl_fixtures.dhparam + + local params = { + ssl_cipher_suite = "old", + prefix = tmp_config.prefix, + ssl_cert = cert, + ssl_cert_key = key, + admin_ssl_cert = cert, + admin_ssl_cert_key = key, + status_ssl_cert = cert, + status_ssl_cert_key = key, + client_ssl_cert = cert, + client_ssl_cert_key = key, + cluster_cert = cert, + cluster_cert_key = key, + cluster_ca_cert = cacert, + ssl_dhparam = dhparam, + lua_ssl_trusted_certificate = cacert + } + + local conf, err = conf_loader(nil, params) + assert(prefix_handler.prepare_prefix(conf)) + assert.is_nil(err) + assert.is_table(conf) + + for name, _ in pairs(params) do + if name ~= "ssl_cipher_suite" and name ~= "prefix" then + local paths = conf[name] + if type(paths) == "table" then + for i = 1, #paths do + assert.truthy(exists(paths[i])) + end + end + + if type(paths) == "string" then + assert.truthy(exists(paths)) + end + end + end + end) end) describe("custom template", function() diff --git a/spec/fixtures/ssl.lua b/spec/fixtures/ssl.lua index 59aadde179e6..1ae6d6689b91 100644 --- a/spec/fixtures/ssl.lua +++ b/spec/fixtures/ssl.lua @@ -593,4 +593,13 @@ BfRWvYpS5xKcHmXg2QJxy2VpvElHLg5Y2lligEZhO+5Sm2OG/hixBmiFvEvxPEB8 XDbnPBpOQK9nicehY7oscy9yTB9Q3bUHecYLY822ueCwaJgwJWFUH+Xe4u6xIH5l A/IyIfyOqxjUc34Me+37ehNmbTIxZ1BqLddppm9QsSAD7cDMurfb3pRpju4= -----END RSA PRIVATE KEY-----]], + + dhparam = [[-----BEGIN DH PARAMETERS----- +MIIBDAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz ++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a +87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 +YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi +7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD +ssbzSibBsu/6iGtCOGEoXJf//////////wIBAgICAOE= +-----END DH PARAMETERS-----]] } From bb9fcb1f1c652d554b67f8b383e80b1aee865ec7 Mon Sep 17 00:00:00 2001 From: samugi Date: Wed, 7 Sep 2022 20:51:11 +0200 Subject: [PATCH 6/7] feat(conf): safe base64 and tests * base64 conversion is moved later in the flow in order to make it safer, so that values like system are not attempted to be decoded * test coverage for the content of the created files * refactoring --- kong/cmd/utils/prefix_handler.lua | 46 ++++++----- kong/conf_loader/init.lua | 83 ++++++++++---------- spec/01-unit/03-conf_loader_spec.lua | 10 ++- spec/01-unit/04-prefix_handler_spec.lua | 100 ++++++++++++++++-------- spec/fixtures/ssl.lua | 2 +- 5 files changed, 144 insertions(+), 97 deletions(-) diff --git a/kong/cmd/utils/prefix_handler.lua b/kong/cmd/utils/prefix_handler.lua index f14516e3a2cc..605c34d78fba 100644 --- a/kong/cmd/utils/prefix_handler.lua +++ b/kong/cmd/utils/prefix_handler.lua @@ -465,12 +465,17 @@ local function prepare_prefix(kong_config, nginx_custom_template_path, skip_writ end end - -- create certs files and assign paths if needed + -- create certs files and assign paths when they are passed as content do - local function propagate_dhparam(path) - kong_config["nginx_http_ssl_dhparam"] = path - kong_config["nginx_stream_ssl_dhparam"] = path + local function set_dhparam_path(path) + if kong_config["nginx_http_ssl_dhparam"] then + kong_config["nginx_http_ssl_dhparam"] = path + end + + if kong_config["nginx_stream_ssl_dhparam"] then + kong_config["nginx_stream_ssl_dhparam"] = path + end for _, directive in ipairs(kong_config["nginx_http_directives"]) do if directive.name == "ssl_dhparam" and directive.value then @@ -496,7 +501,9 @@ local function prepare_prefix(kong_config, nginx_custom_template_path, skip_writ }) end - local function write_file_set_path( + -- ensure the property value is a "content" (not a path), + -- write the content to a file and set the path in the configuration + local function write_content_set_path( contents, format, write_func, @@ -513,11 +520,11 @@ local function prepare_prefix(kong_config, nginx_custom_template_path, skip_writ write_func(path, contents) kong_config[config_key] = path if target == "ssl-dhparam" then - propagate_dhparam(path) + set_dhparam_path(path) end end - else + elseif type(contents) == "table" then for i, content in ipairs(contents) do if not exists(content) then if not exists(ssl_path) then @@ -531,17 +538,16 @@ local function prepare_prefix(kong_config, nginx_custom_template_path, skip_writ end end + local ssl_path = join(kong_config.prefix, "ssl") for _, target in ipairs({ "proxy", "admin", "status", "client", "cluster", - "ssl-dhparam", "lua-ssl-trusted", "cluster-ca" }) do - local ssl_path = join(kong_config.prefix, "ssl") local cert_name local key_name local ssl_cert @@ -555,8 +561,6 @@ local function prepare_prefix(kong_config, nginx_custom_template_path, skip_writ key_name = target .. "_cert_key" elseif target == "cluster-ca" then cert_name = "cluster_ca_cert" - elseif target == "ssl-dhparam" then - cert_name = "ssl_dhparam" elseif target == "lua-ssl-trusted" then cert_name = "lua_ssl_trusted_certificate" else @@ -564,24 +568,28 @@ local function prepare_prefix(kong_config, nginx_custom_template_path, skip_writ key_name = target .. "_ssl_cert_key" end - if cert_name and (cert_name ~= "ssl_dhparam" or - not is_predefined_dhgroup(kong_config[cert_name])) then - ssl_cert = kong_config[cert_name] - end + ssl_cert = cert_name and kong_config[cert_name] ssl_key = key_name and kong_config[key_name] if ssl_cert and #ssl_cert > 0 then - write_file_set_path(ssl_cert, ".crt", write_ssl_cert, ssl_path, target, - cert_name) + write_content_set_path(ssl_cert, ".crt", write_ssl_cert, ssl_path, + target, cert_name) end if ssl_key and #ssl_key > 0 then - write_file_set_path(ssl_key, ".key", write_ssl_cert_key, ssl_path, - target, key_name) + write_content_set_path(ssl_key, ".key", write_ssl_cert_key, ssl_path, + target, key_name) end end + + local dhparam_value = kong_config["ssl_dhparam"] + if dhparam_value and not is_predefined_dhgroup(dhparam_value) then + write_content_set_path(dhparam_value, ".pem", write_ssl_cert, ssl_path, + "ssl-dhparam", "ssl_dhparam") + end end + if kong_config.lua_ssl_trusted_certificate_combined then gen_trusted_certs_combined_file( kong_config.lua_ssl_trusted_certificate_combined, diff --git a/kong/conf_loader/init.lua b/kong/conf_loader/init.lua index 634dab470960..d97c3895f69c 100644 --- a/kong/conf_loader/init.lua +++ b/kong/conf_loader/init.lua @@ -625,30 +625,32 @@ local function infer_value(value, typ, opts) end -local function try_base64_decode(vals) - -- names that we should not attempt decoding - local decode_blacklist = { - system = "system" - } +local function decode_base64_str(str) + if type(str) == "string" then + return decode_base64(str) + or decode_base64url(str) + or nil, "base64 decoding failed: invalid input" - if type(vals) == "table" then - for i, v in ipairs(vals) do - vals[i] = decode_blacklist[v] - or decode_base64(v) - or decode_base64url(v) - or v + else + return nil, "base64 decoding failed: not a string" + end +end + + +local function try_decode_base64(value) + if type(value) == "table" then + for i, v in ipairs(value) do + value[i] = decode_base64_str(v) or v end - return vals + + return value end - if type(vals) == "string" then - return decode_blacklist[vals] - or decode_base64(vals) - or decode_base64url(vals) - or vals + if type(value) == "string" then + return decode_base64_str(value) or value end - return vals + return value end @@ -676,25 +678,6 @@ local function check_and_infer(conf, opts) conf[k] = value end - -- decode base64 for supported properties - for cert_name, has_key in pairs({ - ssl_cert = true, - admin_ssl_cert = true, - status_ssl_cert = true, - client_ssl_cert = true, - cluster_cert = true, - ssl_dhparam = false, - lua_ssl_trusted_certificate = false, - cluster_ca_cert = false - }) do - conf[cert_name] = try_base64_decode(conf[cert_name]) - - if has_key then - local key_name = cert_name .. "_key" - conf[key_name] = try_base64_decode(conf[key_name]) - end - end - --------------------- -- custom validations --------------------- @@ -797,25 +780,31 @@ local function check_and_infer(conf, opts) end if ssl_cert then - for _, cert in ipairs(ssl_cert) do + for i, cert in ipairs(ssl_cert) do if not exists(cert) then + cert = try_decode_base64(cert) + ssl_cert[i] = cert local _, err = openssl_x509.new(cert) if err then errors[#errors + 1] = prefix .. "ssl_cert: failed loading certificate from " .. cert end end end + conf[prefix .. "ssl_cert"] = ssl_cert end if ssl_cert_key then - for _, cert_key in ipairs(ssl_cert_key) do + for i, cert_key in ipairs(ssl_cert_key) do if not exists(cert_key) then + cert_key = try_decode_base64(cert_key) + ssl_cert_key[i] = cert_key local _, err = openssl_pkey.new(cert_key) if err then errors[#errors + 1] = prefix .. "ssl_cert_key: failed loading key from " .. cert_key end end end + conf[prefix .. "ssl_cert_key"] = ssl_cert_key end end end @@ -832,6 +821,8 @@ local function check_and_infer(conf, opts) end if client_ssl_cert and not exists(client_ssl_cert) then + client_ssl_cert = try_decode_base64(client_ssl_cert) + conf.client_ssl_cert = client_ssl_cert local _, err = openssl_x509.new(client_ssl_cert) if err then errors[#errors + 1] = "client_ssl_cert: failed loading certificate from " .. client_ssl_cert @@ -839,6 +830,8 @@ local function check_and_infer(conf, opts) end if client_ssl_cert_key and not exists(client_ssl_cert_key) then + client_ssl_cert_key = try_decode_base64(client_ssl_cert_key) + conf.client_ssl_cert_key = client_ssl_cert_key local _, err = openssl_pkey.new(client_ssl_cert_key) if err then errors[#errors + 1] = "client_ssl_cert_key: failed loading key from " .. @@ -865,11 +858,12 @@ local function check_and_infer(conf, opts) if trusted_cert ~= "system" then if not exists(trusted_cert) then + trusted_cert = try_decode_base64(trusted_cert) local _, err = openssl_x509.new(trusted_cert) if err then errors[#errors + 1] = "lua_ssl_trusted_certificate: " .. - "failed loading certificate from " .. - trusted_cert + "failed loading certificate from " .. + trusted_cert end end @@ -906,6 +900,7 @@ local function check_and_infer(conf, opts) if conf.ssl_dhparam then if not is_predefined_dhgroup(conf.ssl_dhparam) and not exists(conf.ssl_dhparam) then + conf.ssl_dhparam = try_decode_base64(conf.ssl_dhparam) local _, err = openssl_pkey.new( { type = "DH", @@ -1076,6 +1071,8 @@ local function check_and_infer(conf, opts) else if not exists(cluster_cert) then + cluster_cert = try_decode_base64(cluster_cert) + conf.cluster_cert = cluster_cert local _, err = openssl_x509.new(cluster_cert) if err then errors[#errors + 1] = "cluster_cert: failed loading certificate from " .. cluster_cert @@ -1083,6 +1080,8 @@ local function check_and_infer(conf, opts) end if not exists(cluster_cert_key) then + cluster_cert_key = try_decode_base64(cluster_cert_key) + conf.cluster_cert_key = cluster_cert_key local _, err = openssl_pkey.new(cluster_cert_key) if err then errors[#errors + 1] = "cluster_cert_key: failed loading key from " .. cluster_cert_key @@ -1091,6 +1090,8 @@ local function check_and_infer(conf, opts) end if cluster_ca_cert and not exists(cluster_ca_cert) then + cluster_ca_cert = try_decode_base64(cluster_ca_cert) + conf.cluster_ca_cert = cluster_ca_cert local _, err = openssl_x509.new(cluster_ca_cert) if err then errors[#errors + 1] = "cluster_ca_cert: failed loading certificate from " .. diff --git a/spec/01-unit/03-conf_loader_spec.lua b/spec/01-unit/03-conf_loader_spec.lua index 2043189afae8..7f0a8b9c7bbe 100644 --- a/spec/01-unit/03-conf_loader_spec.lua +++ b/spec/01-unit/03-conf_loader_spec.lua @@ -750,14 +750,18 @@ describe("Configuration loader", function() ssl_dhparam = dhparam, lua_ssl_trusted_certificate = cacert } - local conf_params = { - ssl_cipher_suite = "old" + ssl_cipher_suite = "old", + client_ssl = "on", + role = "control_plane", + status_listen = "127.0.0.1:123 ssl", + proxy_listen = "127.0.0.1:456 ssl", + admin_listen = "127.0.0.1:789 ssl" } + for n, v in pairs(properties) do conf_params[n] = ngx.encode_base64(v) end - local conf, err = conf_loader(nil, conf_params) assert.is_nil(err) diff --git a/spec/01-unit/04-prefix_handler_spec.lua b/spec/01-unit/04-prefix_handler_spec.lua index c6bf789fe504..550d15a85aeb 100644 --- a/spec/01-unit/04-prefix_handler_spec.lua +++ b/spec/01-unit/04-prefix_handler_spec.lua @@ -2,6 +2,8 @@ local helpers = require "spec.helpers" local conf_loader = require "kong.conf_loader" local prefix_handler = require "kong.cmd.utils.prefix_handler" local ffi = require "ffi" +local tablex = require "pl.tablex" +local ssl_fixtures = require "spec.fixtures.ssl" local exists = helpers.path.exists local join = helpers.path.join @@ -965,50 +967,82 @@ describe("NGINX conf compiler", function() assert.truthy(exists(join(conf.prefix, "ssl", conf.nginx_http_ssl_dhparam .. ".pem"))) assert.truthy(exists(join(conf.prefix, "ssl", conf.nginx_stream_ssl_dhparam .. ".pem"))) end) - it("accepts and stores values passed as 'content', reconfigures valid paths", function() - local ssl_fixtures = require "spec.fixtures.ssl" - local cert = ssl_fixtures.cert - local cacert = ssl_fixtures.cert_ca - local key = ssl_fixtures.key - local dhparam = ssl_fixtures.dhparam - - local params = { - ssl_cipher_suite = "old", - prefix = tmp_config.prefix, - ssl_cert = cert, - ssl_cert_key = key, - admin_ssl_cert = cert, - admin_ssl_cert_key = key, - status_ssl_cert = cert, - status_ssl_cert_key = key, - client_ssl_cert = cert, - client_ssl_cert_key = key, - cluster_cert = cert, - cluster_cert_key = key, - cluster_ca_cert = cacert, - ssl_dhparam = dhparam, - lua_ssl_trusted_certificate = cacert - } - - local conf, err = conf_loader(nil, params) - assert(prefix_handler.prepare_prefix(conf)) - assert.is_nil(err) - assert.is_table(conf) - - for name, _ in pairs(params) do - if name ~= "ssl_cipher_suite" and name ~= "prefix" then + describe("accept raw content for configuration properties", function() + it("writes files and re-configures valid paths", function() + local cert = ssl_fixtures.cert + local cacert = ssl_fixtures.cert_ca + local key = ssl_fixtures.key + local dhparam = ssl_fixtures.dhparam + + local params = { + ssl_cipher_suite = "old", + prefix = tmp_config.prefix, + } + local ssl_params = { + ssl_cert = cert, + ssl_cert_key = key, + admin_ssl_cert = cert, + admin_ssl_cert_key = key, + status_ssl_cert = cert, + status_ssl_cert_key = key, + client_ssl_cert = cert, + client_ssl_cert_key = key, + cluster_cert = cert, + cluster_cert_key = key, + cluster_ca_cert = cacert, + ssl_dhparam = dhparam, + lua_ssl_trusted_certificate = cacert + } + + local conf, err = conf_loader(nil, tablex.merge(params, ssl_params, true)) + assert(prefix_handler.prepare_prefix(conf)) + assert.is_nil(err) + assert.is_table(conf) + + for name, input_content in pairs(ssl_params) do local paths = conf[name] if type(paths) == "table" then for i = 1, #paths do assert.truthy(exists(paths[i])) + local configured_content = assert(helpers.file.read(paths[i])) + assert.equals(input_content, configured_content) end end if type(paths) == "string" then assert.truthy(exists(paths)) + local configured_content = assert(helpers.file.read(paths)) + assert.equals(input_content, configured_content) end end - end + end) + it("sets lua_ssl_trusted_certificate to a combined file" .. + "(multiple content entries)", function() + local cacerts = string.format( + "%s,%s", + ssl_fixtures.cert_ca, + ssl_fixtures.cert_ca + ) + local conf = assert(conf_loader(nil, { + lua_ssl_trusted_certificate = cacerts, + prefix = tmp_config.prefix + })) + assert(prefix_handler.prepare_prefix(conf)) + assert.is_table(conf) + local trusted_certificates = conf["lua_ssl_trusted_certificate"] + assert.equal(2, #trusted_certificates) + local combined = assert( + helpers.file.read(conf["lua_ssl_trusted_certificate_combined"]) + ) + assert.equal( + combined, + string.format( + "%s\n%s\n", + ssl_fixtures.cert_ca, + ssl_fixtures.cert_ca + ) + ) + end) end) end) diff --git a/spec/fixtures/ssl.lua b/spec/fixtures/ssl.lua index 1ae6d6689b91..db731bc8282d 100644 --- a/spec/fixtures/ssl.lua +++ b/spec/fixtures/ssl.lua @@ -601,5 +601,5 @@ MIIBDAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi 7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD ssbzSibBsu/6iGtCOGEoXJf//////////wIBAgICAOE= ------END DH PARAMETERS-----]] +-----END DH PARAMETERS-----]], } From f87af245d26e29d9125b60e4b8dde20b35267e72 Mon Sep 17 00:00:00 2001 From: samugi Date: Tue, 13 Sep 2022 09:51:43 +0200 Subject: [PATCH 7/7] docs(conf): kong.conf.default and CHANGELOG.md updates Update kong.conf.default to reflect the fact some properties can be configured directly via content or base64 --- CHANGELOG.md | 8 +++++ kong.conf.default | 88 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 74 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f04cb3fbee1..0605879d386b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,14 @@ ## Unreleased +### Additions + +#### Core +- Allow `kong.conf` ssl properties to be stored in vaults or environment + variables. Allow such properties to be configured directly as content + or base64 encoded content. + [#9253](https://github.com/Kong/kong/pull/9253) + ### Fixes #### Core diff --git a/kong.conf.default b/kong.conf.default index 2e0b0e5c6ff3..274b39d11773 100644 --- a/kong.conf.default +++ b/kong.conf.default @@ -261,7 +261,7 @@ # DP node, but issued by a cluster-wide # common CA certificate: `cluster_ca_cert`. -#cluster_cert = # Filename of the cluster certificate to use +#cluster_cert = # Cluster certificate to use # when establishing secure communication # between control and data plane nodes. # You can use the `kong hybrid` command to @@ -270,8 +270,14 @@ # for all nodes. Under `pki` mode it # should be a different certificate for each # DP node. + # + # The certificate can be configured on this + # property with either of the following values: + # * absolute path to the certificate + # * certificate content + # * base64 encoded certificate content -#cluster_cert_key = # Filename of the cluster certificate key to +#cluster_cert_key = # Cluster certificate key to # use when establishing secure communication # between control and data plane nodes. # You can use the `kong hybrid` command to @@ -280,6 +286,12 @@ # for all nodes. Under `pki` mode it # should be a different certificate for each # DP node. + # + # The certificate key can be configured on this + # property with either of the following values: + # * absolute path to the certificate key + # * certificate key content + # * base64 encoded certificate key content #cluster_ca_cert = # The trusted CA certificate file in PEM # format used for Control Plane to verify @@ -294,6 +306,12 @@ # # This field is ignored if `cluster_mtls` is # set to `shared`. + # + # The certificate can be configured on this property + # with either of the following values: + # * absolute path to the certificate + # * certificate content + # * base64 encoded certificate content #------------------------------------------------------------------------------ # HYBRID MODE DATA PLANE @@ -654,8 +672,9 @@ #ssl_dhparam = # Defines DH parameters for DHE ciphers from the # predefined groups: `ffdhe2048`, `ffdhe3072`, - # `ffdhe4096`, `ffdhe6144`, `ffdhe8192`, or - # from the absolute path to a parameters file. + # `ffdhe4096`, `ffdhe6144`, `ffdhe8192`, + # from the absolute path to a parameters file, or + # directly from the parameters content. # # This value is ignored if `ssl_cipher_suite` # is `modern` or `intermediate`. The reason is @@ -680,8 +699,7 @@ # # See http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_timeout -#ssl_cert = # Comma-separated list of the absolute path to the certificates for - # `proxy_listen` values with TLS enabled. +#ssl_cert = # Comma-separated list of certificates for `proxy_listen` values with TLS enabled. # # If more than one certificates are specified, it can be used to provide # alternate type of certificate (for example, ECC certificate) that will be served @@ -692,9 +710,14 @@ # Unless this option is explicitly set, Kong will auto-generate # a pair of default certificates (RSA + ECC) first time it starts up and use # it for serving TLS requests. + # + # Certificates can be configured on this property with either of the following + # values: + # * absolute path to the certificate + # * certificate content + # * base64 encoded certificate content -#ssl_cert_key = # Comma-separated list of the absolute path to the keys for - # `proxy_listen` values with TLS enabled. +#ssl_cert_key = # Comma-separated list of keys for `proxy_listen` values with TLS enabled. # # If more than one certificate was specified for `ssl_cert`, then this # option should contain the corresponding key for all certificates @@ -703,40 +726,54 @@ # Unless this option is explicitly set, Kong will auto-generate # a pair of default private keys (RSA + ECC) first time it starts up and use # it for serving TLS requests. + # + # Keys can be configured on this property with either of the following + # values: + # * absolute path to the certificate key + # * certificate key content + # * base64 encoded certificate key content #client_ssl = off # Determines if Nginx should attempt to send client-side # TLS certificates and perform Mutual TLS Authentication # with upstream service when proxying requests. -#client_ssl_cert = # If `client_ssl` is enabled, the absolute - # path to the client certificate for the `proxy_ssl_certificate` directive. +#client_ssl_cert = # If `client_ssl` is enabled, the client certificate + # for the `proxy_ssl_certificate` directive. # # This value can be overwritten dynamically with the `client_certificate` # attribute of the `Service` object. + # + # The certificate can be configured on this property with either of the following + # values: + # * absolute path to the certificate + # * certificate content + # * base64 encoded certificate content -#client_ssl_cert_key = # If `client_ssl` is enabled, the absolute - # path to the client TLS key for the `proxy_ssl_certificate_key` directive. +#client_ssl_cert_key = # If `client_ssl` is enabled, the client TLS key + # for the `proxy_ssl_certificate_key` directive. # # This value can be overwritten dynamically with the `client_certificate` # attribute of the `Service` object. + # + # The certificate key can be configured on this property with either of the following + # values: + # * absolute path to the certificate key + # * certificate key content + # * base64 encoded certificate key content -#admin_ssl_cert = # Comma-separated list of the absolute path to the certificates for - # `admin_listen` values with TLS enabled. +#admin_ssl_cert = # Comma-separated list of certificates for `admin_listen` values with TLS enabled. # # See docs for `ssl_cert` for detailed usage. -#admin_ssl_cert_key = # Comma-separated list of the absolute path to the keys for - # `admin_listen` values with TLS enabled. +#admin_ssl_cert_key = # Comma-separated list of keys for `admin_listen` values with TLS enabled. # # See docs for `ssl_cert_key` for detailed usage. -#status_ssl_cert = # Comma-separated list of the absolute path to the certificates for - # `status_listen` values with TLS enabled. +#status_ssl_cert = # Comma-separated list of certificates for `status_listen` values with TLS enabled. # # See docs for `ssl_cert` for detailed usage. -#status_ssl_cert_key = # Comma-separated list of the absolute path to the keys for - # `status_listen` values with TLS enabled. +#status_ssl_cert_key = # Comma-separated list of keys for `status_listen` values with TLS enabled. # # See docs for `ssl_cert_key` for detailed usage. @@ -1492,8 +1529,8 @@ # https://github.com/openresty/lua-nginx-module -#lua_ssl_trusted_certificate = system # Comma-separated list of paths to certificate - # authority files for Lua cosockets in PEM format. +#lua_ssl_trusted_certificate = system # Comma-separated list of certificate authorities + # for Lua cosockets in PEM format. # # The special value `system` attempts to search for the # "usual default" provided by each distro, according @@ -1515,6 +1552,13 @@ # are enabled, these certificate authority files will be # used for verifying Kong's database connections. # + # Certificates can be configured on this property + # with either of the following values: + # * `system` + # * absolute path to the certificate + # * certificate content + # * base64 encoded certificate content + # # See https://github.com/openresty/lua-nginx-module#lua_ssl_trusted_certificate #lua_ssl_verify_depth = 1 # Sets the verification depth in the server