diff --git a/.github/workflows/fips.yml b/.github/workflows/fips.yml index 5b2a004d72b2..e6516d9bb479 100644 --- a/.github/workflows/fips.yml +++ b/.github/workflows/fips.yml @@ -92,6 +92,7 @@ jobs: - name: Linux launch common services run: | make ci-env-up project_compose_ci=ci/pod/docker-compose.common.yml + sudo ./ci/init-common-test-service.sh - name: Cache images id: cache-images diff --git a/.github/workflows/gm.yml b/.github/workflows/gm.yml index 06663006e942..003e567bace8 100644 --- a/.github/workflows/gm.yml +++ b/.github/workflows/gm.yml @@ -72,6 +72,7 @@ jobs: - name: Linux launch common services run: | make ci-env-up project_compose_ci=ci/pod/docker-compose.common.yml + sudo ./ci/init-common-test-service.sh - name: Linux Before install env: diff --git a/apisix/schema_def.lua b/apisix/schema_def.lua index f7b117af93da..bae273c96a17 100644 --- a/apisix/schema_def.lua +++ b/apisix/schema_def.lua @@ -725,8 +725,19 @@ _M.ssl = { default = "server", enum = {"server", "client"} }, - cert = certificate_scheme, - key = private_key_schema, + cert = { + oneOf = { + certificate_scheme, + -- TODO: uniformly define the schema of secret_uri + { type = "string", pattern = "^\\$(secret|env)://"} + } + }, + key = { + oneOf = { + private_key_schema, + { type = "string", pattern = "^\\$(secret|env)://"} + } + }, sni = { type = "string", pattern = host_def_pat, diff --git a/apisix/secret.lua b/apisix/secret.lua index 7dcf9cf4ab22..ca9b09190ebc 100644 --- a/apisix/secret.lua +++ b/apisix/secret.lua @@ -110,14 +110,27 @@ function _M.init_worker() end -local function parse_secret_uri(secret_uri) +local function check_secret_uri(secret_uri) -- Avoid the error caused by has_prefix to cause a crash. if type(secret_uri) ~= "string" then - return nil, "error secret_uri type: " .. type(secret_uri) + return false, "error secret_uri type: " .. type(secret_uri) + end + + if not string.has_prefix(secret_uri, PREFIX) and + not string.has_prefix(upper(secret_uri), core.env.PREFIX) then + return false, "error secret_uri prefix: " .. secret_uri end - if not string.has_prefix(secret_uri, PREFIX) then - return nil, "error secret_uri prefix: " .. secret_uri + return true +end + +_M.check_secret_uri = check_secret_uri + + +local function parse_secret_uri(secret_uri) + local is_secret_uri, err = check_secret_uri(secret_uri) + if not is_secret_uri then + return is_secret_uri, err end local path = sub(secret_uri, #PREFIX + 1) diff --git a/apisix/ssl.lua b/apisix/ssl.lua index 18898027aee5..8bcdec0ffa90 100644 --- a/apisix/ssl.lua +++ b/apisix/ssl.lua @@ -16,6 +16,7 @@ -- local core = require("apisix.core") local ngx_ssl = require("ngx.ssl") +local secret = require("apisix.secret") local ngx_encode_base64 = ngx.encode_base64 local ngx_decode_base64 = ngx.decode_base64 local aes = require("resty.aes") @@ -252,9 +253,13 @@ function _M.check_ssl_conf(in_dp, conf) end end - local ok, err = validate(conf.cert, conf.key) - if not ok then - return nil, err + if not secret.check_secret_uri(conf.cert) and + not secret.check_secret_uri(conf.key) then + + local ok, err = validate(conf.cert, conf.key) + if not ok then + return nil, err + end end if conf.type == "client" then @@ -268,9 +273,13 @@ function _M.check_ssl_conf(in_dp, conf) end for i = 1, numcerts do - local ok, err = validate(conf.certs[i], conf.keys[i]) - if not ok then - return nil, "failed to handle cert-key pair[" .. i .. "]: " .. err + if not secret.check_secret_uri(conf.cert[i]) and + not secret.check_secret_uri(conf.key[i]) then + + local ok, err = validate(conf.certs[i], conf.keys[i]) + if not ok then + return nil, "failed to handle cert-key pair[" .. i .. "]: " .. err + end end end diff --git a/apisix/ssl/router/radixtree_sni.lua b/apisix/ssl/router/radixtree_sni.lua index fd1f55c395dc..f88950be9ff2 100644 --- a/apisix/ssl/router/radixtree_sni.lua +++ b/apisix/ssl/router/radixtree_sni.lua @@ -18,6 +18,7 @@ local get_request = require("resty.core.base").get_request local router_new = require("apisix.utils.router").new local core = require("apisix.core") local apisix_ssl = require("apisix.ssl") +local secret = require("apisix.secret") local ngx_ssl = require("ngx.ssl") local config_util = require("apisix.core.config_util") local ipairs = ipairs @@ -212,7 +213,9 @@ function _M.match_and_set(api_ctx, match_only, alt_sni) ngx_ssl.clear_certs() - ok, err = _M.set_cert_and_key(sni, matched_ssl.value) + local new_ssl_value = secret.fetch_secrets(matched_ssl.value) or matched_ssl.value + + ok, err = _M.set_cert_and_key(sni, new_ssl_value) if not ok then return false, err end diff --git a/docs/en/latest/admin-api.md b/docs/en/latest/admin-api.md index cf65066ce8f1..e2d7457b159d 100644 --- a/docs/en/latest/admin-api.md +++ b/docs/en/latest/admin-api.md @@ -1154,8 +1154,8 @@ SSL resource request address: /apisix/admin/ssls/{id} | Parameter | Required | Type | Description | Example | | ------------ | -------- | ------------------------ | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | -| cert | True | Certificate | HTTPS certificate. | | -| key | True | Private key | HTTPS private key. | | +| cert | True | Certificate | HTTPS certificate. This field supports saving the value in Secret Manager using the [APISIX Secret](../terminology/secret.md) resource. | | +| key | True | Private key | HTTPS private key. This field supports saving the value in Secret Manager using the [APISIX Secret](../terminology/secret.md) resource. | | | certs | False | An array of certificates | Used for configuring multiple certificates for the same domain excluding the one provided in the `cert` field. | | | keys | False | An array of private keys | Private keys to pair with the `certs`. | | | client.ca | False | Certificate | Sets the CA certificate that verifies the client. Requires OpenResty 1.19+. | | diff --git a/docs/zh/latest/admin-api.md b/docs/zh/latest/admin-api.md index d46bd09f4b17..74d008301c2f 100644 --- a/docs/zh/latest/admin-api.md +++ b/docs/zh/latest/admin-api.md @@ -1162,8 +1162,8 @@ SSL 资源请求地址:/apisix/admin/ssls/{id} | 名称 | 必选项 | 类型 | 描述 | 示例 | | ----------- | ------ | -------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------ | -| cert | 是 | 证书 | HTTP 证书。 | | -| key | 是 | 私钥 | HTTPS 证书私钥 | | +| cert | 是 | 证书 | HTTP 证书。该字段支持使用 [APISIX Secret](../terminology/secret.md) 资源,将值保存在 Secret Manager 中。 | | +| key | 是 | 私钥 | HTTPS 证书私钥。该字段支持使用 [APISIX Secret](../terminology/secret.md) 资源,将值保存在 Secret Manager 中。 | | | certs | 否 | 证书字符串数组 | 当你想给同一个域名配置多个证书时,除了第一个证书需要通过 `cert` 传递外,剩下的证书可以通过该参数传递上来。 | | | keys | 否 | 私钥字符串数组 | `certs` 对应的证书私钥,需要与 `certs` 一一对应。 | | | client.ca | 否 | 证书 | 设置将用于客户端证书校验的 `CA` 证书。该特性需要 OpenResty 为 1.19 及以上版本。 | | diff --git a/t/gm/gm.t b/t/gm/gm.t index ab6b62c63e3b..dfd64d370c5a 100644 --- a/t/gm/gm.t +++ b/t/gm/gm.t @@ -15,6 +15,22 @@ # specific language governing permissions and limitations # under the License. +BEGIN { + $ENV{TEST_ENV_GMSSL_CRT_ENC} = "-----BEGIN CERTIFICATE----- +MIIB2DCCAX6gAwIBAgIBAzAKBggqgRzPVQGDdTBFMQswCQYDVQQGEwJBQTELMAkG +A1UECAwCQkIxCzAJBgNVBAoMAkNDMQswCQYDVQQLDAJERDEPMA0GA1UEAwwGc3Vi +IGNhMB4XDTIyMTEwMjAzMTkzNloXDTMyMTAzMDAzMTkzNlowSTELMAkGA1UEBhMC +QUExCzAJBgNVBAgMAkJCMQswCQYDVQQKDAJDQzELMAkGA1UECwwCREQxEzARBgNV +BAMMCnNlcnZlciBlbmMwWjAUBggqgRzPVQGCLQYIKoEcz1UBgi0DQgAED+MQrLrZ +9PbMmz/44Kb73Qc7FlMs7u034XImjJREBAn1KzZ7jqcYfCiV/buhmu1sLhMXnB69 +mERtf1tAaXcgIaNaMFgwCQYDVR0TBAIwADALBgNVHQ8EBAMCAzgwHQYDVR0OBBYE +FBxHDo0gHhMoYkDeHWySTIJy5BZpMB8GA1UdIwQYMBaAFCTrpmbUig3JfveqAIGJ +6n+vAk2AMAoGCCqBHM9VAYN1A0gAMEUCIHtXgpOxcb3mZv2scRZHZz5YGFr45dfk +VfLkF9BkrB/xAiEA8EeUg7nCFfgHzrfgB7v0wgN1Hrgj8snTUO6IDfkBKYM= +-----END CERTIFICATE----- +"; +} + use t::APISIX; if (-f "/usr/local/tongsuo/bin/openssl") { @@ -168,3 +184,74 @@ location /t { --- response_body --- error_log SSL_do_handshake() failed + + + +=== TEST 5: set ssl: server_enc with secret ref +--- config +location /t { + content_by_lua_block { + local core = require("apisix.core") + local t = require("lib.test_admin") + + local f = assert(io.open("t/certs/server_sign.crt")) + local cert_sign = f:read("*a") + f:close() + + local f = assert(io.open("t/certs/server_enc.key")) + local pkey_enc = f:read("*a") + f:close() + + local f = assert(io.open("t/certs/server_sign.key")) + local pkey_sign = f:read("*a") + f:close() + + local data = { + cert = "$env://TEST_ENV_GMSSL_CRT_ENC", + key = pkey_enc, + certs = {cert_sign}, + keys = {pkey_sign}, + sni = "localhost", + gm = true, + } + + local code, body = t.test('/apisix/admin/ssls/1', + ngx.HTTP_PUT, + core.json.encode(data) + ) + + if code >= 300 then + ngx.status = code + ngx.say(body) + return + end + + local code, body = t.test('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/echo" + }]] + ) + + ngx.say(body) + } +} +--- response_body +passed + + + +=== TEST 6: hit +--- exec +/usr/local/tongsuo/bin/openssl s_client -connect localhost:1994 -servername localhost -cipher ECDHE-SM2-WITH-SM4-SM3 -enable_ntls -ntls -verifyCAfile t/certs/gm_ca.crt -sign_cert t/certs/client_sign.crt -sign_key t/certs/client_sign.key -enc_cert t/certs/client_enc.crt -enc_key t/certs/client_enc.key +--- response_body eval +qr/^CONNECTED/ +--- no_error_log +SSL_do_handshake() failed +[error] diff --git a/t/router/radixtree-sni2.t b/t/router/radixtree-sni2.t index b34d0b725a3e..c64a20aae344 100644 --- a/t/router/radixtree-sni2.t +++ b/t/router/radixtree-sni2.t @@ -19,7 +19,76 @@ use t::APISIX 'no_plan'; log_level('debug'); no_root_location(); -$ENV{TEST_NGINX_HTML_DIR} ||= html_dir(); +BEGIN { + $ENV{TEST_NGINX_HTML_DIR} ||= html_dir(); + $ENV{TEST_ENV_SSL_CRT} = "-----BEGIN CERTIFICATE----- +MIIEsTCCAxmgAwIBAgIUMbgUUCYHkuKDaPy0bzZowlK0JG4wDQYJKoZIhvcNAQEL +BQAwVzELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5nRG9uZzEPMA0GA1UEBwwG +Wmh1SGFpMQ8wDQYDVQQKDAZpcmVzdHkxEjAQBgNVBAMMCXRlc3QyLmNvbTAgFw0y +MDA0MDQyMjE3NTJaGA8yMTIwMDMxMTIyMTc1MlowVzELMAkGA1UEBhMCQ04xEjAQ +BgNVBAgMCUd1YW5nRG9uZzEPMA0GA1UEBwwGWmh1SGFpMQ8wDQYDVQQKDAZpcmVz +dHkxEjAQBgNVBAMMCXRlc3QyLmNvbTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCC +AYoCggGBAMQGBk35V3zaNVDWzEzVGd+EkZnUOrRpXQg5mmcnoKnrQ5rQQMsQCbMO +gFvLt/9OEZQmbE2HuEKsPzL79Yjdu8rGjSoQdbJZ9ccO32uvln1gn68iK79o7Tvm +TCi+BayyNA+lo9IxrBm1wGBkOU1ZPasGYzgBAbMLTSDps1EYxNR8t4l9PrTTRsh6 +NZyTYoDeVIsKZ9SckpjWVnxHOkF+AzZzIJJSe2pj572TDLYA/Xw9I4X3L+SHzwTl +iGWNXb2tU367LHERHvensQzdle7mQN2kE5GpB7QPWB+t9V4mn30jc/LyDvOaei6L ++pbl5CriGBTjaR80oXhK765K720BQeKUezri15bQlMaUGQRnzr53ZsqA4PEh6WCX +hUT2ibO32+uZFXzVQw8y/JUkPf76pZagi8DoLV+sfSbUtnpbQ8wyV2qqTM2eCuPi +RgUwXQi2WssKKzrqcgKil3vksHZozLtOmyZiNE4qfNxv+UGoIybJtZmB+9spY0Rw +5zBRuULycQIDAQABo3MwcTAdBgNVHQ4EFgQUCmZefzpizPrb3VbiIDhrA48ypB8w +HwYDVR0jBBgwFoAUCmZefzpizPrb3VbiIDhrA48ypB8wDAYDVR0TBAUwAwEB/zAh +BgNVHREEGjAYggl0ZXN0Mi5jb22CCyoudGVzdDIuY29tMA0GCSqGSIb3DQEBCwUA +A4IBgQA0nRTv1zm1ACugJFfYZfxZ0mLJfRUCFMmFfhy+vGiIu6QtnOFVw/tEOyMa +m78lBiqac15n3YWYiHiC5NFffTZ7XVlOjN2i4x2z2IJsHNa8tU80AX0Q/pizGK/d ++dzlcsGBb9MGT18h/B3/EYQFKLjUsr0zvDb1T0YDlRUsN3Bq6CvZmvfe9F7Yh4Z/ +XO5R+rX8w9c9A2jzM5isBw2qp/Ggn5RQodMwApEYkJdu80MuxaY6s3dssS4Ay8wP +VNFEeLcdauJ00ES1OnbnuNiYSiSMOgWBsnR+c8AaSRB/OZLYQQKGGYbq0tspwRjM +MGJRrI/jdKnvJQ8p02abdvA9ZuFChoD3Wg03qQ6bna68ZKPd9peBPpMrDDGDLkGI +NzZ6bLJKILnQkV6b1OHVnPDsKXfXjUTTNK/QLJejTXu9RpMBakYZMzs/SOSDtFlS +A+q25t6+46nvA8msUSBKyOGBX42mJcKvR4OgG44PfDjYfmjn2l+Dz/jNXDclpb+Q +XAzBnfM= +-----END CERTIFICATE-----"; + $ENV{TEST_ENV_SSL_KEY} = "-----BEGIN RSA PRIVATE KEY----- +MIIG5QIBAAKCAYEAxAYGTflXfNo1UNbMTNUZ34SRmdQ6tGldCDmaZyegqetDmtBA +yxAJsw6AW8u3/04RlCZsTYe4Qqw/Mvv1iN27ysaNKhB1sln1xw7fa6+WfWCfryIr +v2jtO+ZMKL4FrLI0D6Wj0jGsGbXAYGQ5TVk9qwZjOAEBswtNIOmzURjE1Hy3iX0+ +tNNGyHo1nJNigN5Uiwpn1JySmNZWfEc6QX4DNnMgklJ7amPnvZMMtgD9fD0jhfcv +5IfPBOWIZY1dva1TfrsscREe96exDN2V7uZA3aQTkakHtA9YH631XiaffSNz8vIO +85p6Lov6luXkKuIYFONpHzSheErvrkrvbQFB4pR7OuLXltCUxpQZBGfOvndmyoDg +8SHpYJeFRPaJs7fb65kVfNVDDzL8lSQ9/vqllqCLwOgtX6x9JtS2eltDzDJXaqpM +zZ4K4+JGBTBdCLZayworOupyAqKXe+SwdmjMu06bJmI0Tip83G/5QagjJsm1mYH7 +2yljRHDnMFG5QvJxAgMBAAECggGBAIELlkruwvGmlULKpWRPReEn3NJwLNVoJ56q +jUMri1FRWAgq4PzNahU+jrHfwxmHw3rMcK/5kQwTaOefh1y63E35uCThARqQroSE +/gBeb6vKWFVrIXG5GbQ9QBXyQroV9r/2Q4q0uJ+UTzklwbNx9G8KnXbY8s1zuyrX +rvzMWYepMwqIMSfJjuebzH9vZ4F+3BlMmF4XVUrYj8bw/SDwXB0UXXT2Z9j6PC1J +CS0oKbgIZ8JhoF3KKjcHBGwWTIf5+byRxeG+z99PBEBafm1Puw1vLfOjD3DN/fso +8xCEtD9pBPBJ+W97x/U+10oKetmP1VVEr2Ph8+s2VH1zsRF5jo5d0GtvJqOwIQJ7 +z3OHJ7lLODw0KAjB1NRXW4dTTUDm6EUuUMWFkGAV6YTyhNLAT0DyrUFJck9RiY48 +3QN8vSf3n/+3wwg1gzcJ9w3W4DUbvGqu86CaUQ4UegfYJlusY/3YGp5bGNQdxmws +lgIoSRrHp6UJKsP8Yl08MIvT/oNLgQKBwQD75SuDeyE0ukhEp0t6v+22d18hfSef +q3lLWMI1SQR9Kiem9Z1KdRkIVY8ZAHANm6D8wgjOODT4QZtiqJd2BJn3Xf+aLfCd +CW0hPvmGTcp/E4sDZ2u0HbIrUStz7ZcgXpjD2JJAJGEKY2Z7J65gnTqbqoBDrw1q +1+FqtikkHRte1UqxjwnWBpSdoRQFgNPHxPWffhML1xsD9Pk1B1b7JoakYcKsNoQM +oXUKPLxSZEtd0hIydqmhGYTa9QWBPNDlA5UCgcEAxzfGbOrPBAOOYZd3jORXQI6p +H7SddTHMQyG04i+OWUd0HZFkK7/k6r26GFmImNIsQMB26H+5XoKRFKn+sUl14xHY +FwB140j0XSav2XzT38UpJ9CptbgK1eKGQVp41xwRYjHVScE5hJuA3a1TKM0l26rp +hny/KaP+tXuqt9QbxcUN6efubNYyFP+m6nq2/XdX74bJuGpXLq8W0oFdiocO6tmF +4/Hsc4dCVrcwULqXQa0lJ57zZpfIPARqWM2847xtAoHBANVUNbDpg6rTJMc34722 +dAy3NhL3mqooH9aG+hsEls+l9uT4WFipqSScyU8ERuHPbt0BO1Hi2kFx1rYMUBG8 +PeT4b7NUutVUGV8xpUNv+FH87Bta6CUnjTAQUzuf+QCJ/NjIPrwh0yloG2+roIvk +PLF/CZfI1hUpdZfZZChYmkiLXPHZURw4gH6q33j1rOYf0WFc9aZua0vDmZame6zB +6P+oZ6VPmi/UQXoFC/y/QfDYK18fjfOI2DJTlnDoX4XErQKBwGc3M5xMz/MRcJyJ +oIwj5jzxbRibOJV2tpD1jsU9xG/nQHbtVEwCgTVKFXf2M3qSMhFeZn0xZ7ZayZY+ +OVJbcDO0lBPezjVzIAB/Qc7aCOBAQ4F4b+VRtHN6iPqlSESTK0KH9Szgas+UzeCM +o7BZEctNMu7WBSkq6ZXXu+zAfZ8q6HmPDA3hsFMG3dFQwSxzv+C/IhZlKkRqvNVV +50QVk5oEF4WxW0PECY/qG6NH+YQylDSB+zPlYf4Of5cBCWOoxQKBwQCeo37JpEAR +kYtqSjXkC5GpPTz8KR9lCY4SDuC1XoSVCP0Tk23GX6GGyEf4JWE+fb/gPEFx4Riu +7pvxRwq+F3LaAa/FFTNUpY1+8UuiMO7J0B1RkVXkyJjFUF/aQxAnOoZPmzrdZhWy +bpe2Ka+JS/aXSd1WRN1nmo/DarpWFvdLWZFwUt6zMziH40o1gyPHEuXOqVtf2QCe +Q6WC9xnEz4lbb/fR2TF9QRA4FtoRpDe/f3ZGIpWE0RdwyZZ6uA7T1+Q= +-----END RSA PRIVATE KEY-----"; +} add_block_preprocessor(sub { my ($block) = @_; @@ -543,3 +612,211 @@ qr/(fetch|release) table \w+/ --- grep_error_log_out fetch table api_ctx release table api_ctx + + + +=== TEST 15: store secret into vault +--- exec +VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/ssl test2.com.crt=@t/certs/test2.crt test2.com.key=@t/certs/test2.key +--- response_body +Success! Data written to: kv/apisix/ssl + + + +=== TEST 16: set ssl conf with secret ref: vault +--- request +GET /t +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + -- put secret vault config + local code, body = t('/apisix/admin/secrets/vault/test1', + ngx.HTTP_PUT, + [[{ + "uri": "http://127.0.0.1:8200", + "prefix": "kv/apisix", + "token" : "root" + }]] + ) + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + -- set ssl + local code, body = t('/apisix/admin/ssls/1', + ngx.HTTP_PUT, + [[{ + "cert": "$secret://vault/test1/ssl/test2.com.crt", + "key": "$secret://vault/test1/ssl/test2.com.key", + "sni": "test2.com" + }]] + ) + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + + ngx.say("passed") + } + } +--- response_body +passed + + + +=== TEST 17: get cert and key from vault +--- config +listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + +location /t { + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(2000) + + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + + local sess, err = sock:sslhandshake(nil, "test2.com", false) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + ngx.say("ssl handshake: ", sess ~= nil) + end -- do + -- collectgarbage() + } +} +--- response_body +ssl handshake: true + + + +=== TEST 18: set ssl conf with secret ref: env +--- request +GET /t +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + -- set ssl + local code, body = t('/apisix/admin/ssls/1', + ngx.HTTP_PUT, + [[{ + "cert": "$env://TEST_ENV_SSL_CRT", + "key": "$env://TEST_ENV_SSL_KEY", + "sni": "test2.com" + }]] + ) + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + + ngx.say("passed") + } + } +--- response_body +passed + + + +=== TEST 19: get cert and key from env +--- config +listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + +location /t { + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(2000) + + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + + local sess, err = sock:sslhandshake(nil, "test2.com", false) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + ngx.say("ssl handshake: ", sess ~= nil) + end -- do + -- collectgarbage() + } +} +--- response_body +ssl handshake: true + + + +=== TEST 20: set ssl conf with secret ref: only cert use env +--- request +GET /t +--- config + location /t { + content_by_lua_block { + local core = require("apisix.core") + local t = require("lib.test_admin") + -- set ssl + local ssl_key = t.read_file("t/certs/test2.key") + local data = { + cert = "$env://TEST_ENV_SSL_CRT", + key = ssl_key, + sni = "TesT2.com" + } + + local code, body = t.test('/apisix/admin/ssls/1', + ngx.HTTP_PUT, + core.json.encode(data) + ) + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + + ngx.say("passed") + } + } +--- response_body +passed + + + +=== TEST 21: get cert from env +--- config +listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + +location /t { + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(2000) + + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + + local sess, err = sock:sslhandshake(nil, "test2.com", false) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + ngx.say("ssl handshake: ", sess ~= nil) + end -- do + -- collectgarbage() + } +} +--- response_body +ssl handshake: true