From 0dde7056a0bdf825bfb75e47da966a795946a48f Mon Sep 17 00:00:00 2001 From: SkyeYoung Date: Fri, 15 Aug 2025 15:51:21 +0800 Subject: [PATCH 1/5] fix: judge cert in tls to avoid only `tls.verify` --- apisix/upstream.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apisix/upstream.lua b/apisix/upstream.lua index e55694f7ec25..8a376f1b9110 100644 --- a/apisix/upstream.lua +++ b/apisix/upstream.lua @@ -261,8 +261,8 @@ function _M.set_by_route(route, api_ctx) local checker = healthcheck_manager.fetch_checker(up_conf.resource_key, resource_version) api_ctx.up_checker = checker local scheme = up_conf.scheme - if (scheme == "https" or scheme == "grpcs") and up_conf.tls then - + local tls_has_cert = up_conf.tls and (up_conf.tls.client_cert or up_conf.tls.client_cert_id) + if (scheme == "https" or scheme == "grpcs") and tls_has_cert then local client_cert, client_key if up_conf.tls.client_cert_id then client_cert = api_ctx.upstream_ssl.cert From c61ae736a1d91141f9e70a5fc8e72e64ec74fe90 Mon Sep 17 00:00:00 2001 From: SkyeYoung Date: Fri, 15 Aug 2025 17:07:52 +0800 Subject: [PATCH 2/5] docs(admin-api): add missing tls.verify --- docs/en/latest/admin-api.md | 1 + docs/zh/latest/admin-api.md | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/en/latest/admin-api.md b/docs/en/latest/admin-api.md index 753327453f0e..f8841a61e2d8 100644 --- a/docs/en/latest/admin-api.md +++ b/docs/en/latest/admin-api.md @@ -1019,6 +1019,7 @@ In addition to the equalization algorithm selections, Upstream also supports pas | tls.client_cert | False, can't be used with `tls.client_cert_id` | HTTPS certificate | Sets the client certificate while connecting to a TLS Upstream. | | | tls.client_key | False, can't be used with `tls.client_cert_id` | HTTPS certificate private key | Sets the client private key while connecting to a TLS Upstream. | | | tls.client_cert_id | False, can't be used with `tls.client_cert` and `tls.client_key` | SSL | Set the referenced [SSL](#ssl) id. | | +| tls.verify | False, currently only kafka upstream is supported | Boolean | Turn on server certificate verification, currently only kafka upstream is supported. | | | keepalive_pool.size | False | Auxiliary | Sets `keepalive` directive dynamically. | | | keepalive_pool.idle_timeout | False | Auxiliary | Sets `keepalive_timeout` directive dynamically. | | | keepalive_pool.requests | False | Auxiliary | Sets `keepalive_requests` directive dynamically. | | diff --git a/docs/zh/latest/admin-api.md b/docs/zh/latest/admin-api.md index 3e9037986624..bf9b3f859c1c 100644 --- a/docs/zh/latest/admin-api.md +++ b/docs/zh/latest/admin-api.md @@ -1027,6 +1027,7 @@ APISIX 的 Upstream 除了基本的负载均衡算法选择外,还支持对上 | tls.client_cert | 否,不能和 `tls.client_cert_id` 一起使用 | https 证书 | 设置跟上游通信时的客户端证书,详细信息请参考下文。 | | | tls.client_key | 否,不能和 `tls.client_cert_id` 一起使用 | https 证书私钥 | 设置跟上游通信时的客户端私钥,详细信息请参考下文。 | | | tls.client_cert_id | 否,不能和 `tls.client_cert`、`tls.client_key` 一起使用 | SSL | 设置引用的 SSL id,详见 [SSL](#ssl)。 | | +| tls.verify | 不对,目前仅支持Kafka上游。 | Boolean | 开启服务器证书验证功能,目前仅支持 Kafka 上游。 | | |keepalive_pool.size | 否 | 辅助 | 动态设置 `keepalive` 指令,详细信息请参考下文。 | |keepalive_pool.idle_timeout | 否 | 辅助 | 动态设置 `keepalive_timeout` 指令,详细信息请参考下文。 | |keepalive_pool.requests | 否 | 辅助 | 动态设置 `keepalive_requests` 指令,详细信息请参考下文。 | From a33c3762546990d316cdfa8229c28fc8ffd53c4f Mon Sep 17 00:00:00 2001 From: SkyeYoung Date: Fri, 15 Aug 2025 17:55:50 +0800 Subject: [PATCH 3/5] docs: typo --- docs/zh/latest/admin-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/latest/admin-api.md b/docs/zh/latest/admin-api.md index bf9b3f859c1c..660b188bd38d 100644 --- a/docs/zh/latest/admin-api.md +++ b/docs/zh/latest/admin-api.md @@ -1027,7 +1027,7 @@ APISIX 的 Upstream 除了基本的负载均衡算法选择外,还支持对上 | tls.client_cert | 否,不能和 `tls.client_cert_id` 一起使用 | https 证书 | 设置跟上游通信时的客户端证书,详细信息请参考下文。 | | | tls.client_key | 否,不能和 `tls.client_cert_id` 一起使用 | https 证书私钥 | 设置跟上游通信时的客户端私钥,详细信息请参考下文。 | | | tls.client_cert_id | 否,不能和 `tls.client_cert`、`tls.client_key` 一起使用 | SSL | 设置引用的 SSL id,详见 [SSL](#ssl)。 | | -| tls.verify | 不对,目前仅支持Kafka上游。 | Boolean | 开启服务器证书验证功能,目前仅支持 Kafka 上游。 | | +| tls.verify |否,目前仅支持Kafka上游。 | Boolean | 开启服务器证书验证功能,目前仅支持 Kafka 上游。 | | |keepalive_pool.size | 否 | 辅助 | 动态设置 `keepalive` 指令,详细信息请参考下文。 | |keepalive_pool.idle_timeout | 否 | 辅助 | 动态设置 `keepalive_timeout` 指令,详细信息请参考下文。 | |keepalive_pool.requests | 否 | 辅助 | 动态设置 `keepalive_requests` 指令,详细信息请参考下文。 | From bd2a746ed425396fc2d2d5bc86d327d4242e3ac2 Mon Sep 17 00:00:00 2001 From: SkyeYoung Date: Mon, 18 Aug 2025 14:04:21 +0800 Subject: [PATCH 4/5] test: add tls.verify only cases --- docs/zh/latest/admin-api.md | 2 +- t/core/schema_def.t | 13 ++++++++++ t/node/upstream-mtls.t | 48 +++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/docs/zh/latest/admin-api.md b/docs/zh/latest/admin-api.md index 660b188bd38d..5701f4686257 100644 --- a/docs/zh/latest/admin-api.md +++ b/docs/zh/latest/admin-api.md @@ -1027,7 +1027,7 @@ APISIX 的 Upstream 除了基本的负载均衡算法选择外,还支持对上 | tls.client_cert | 否,不能和 `tls.client_cert_id` 一起使用 | https 证书 | 设置跟上游通信时的客户端证书,详细信息请参考下文。 | | | tls.client_key | 否,不能和 `tls.client_cert_id` 一起使用 | https 证书私钥 | 设置跟上游通信时的客户端私钥,详细信息请参考下文。 | | | tls.client_cert_id | 否,不能和 `tls.client_cert`、`tls.client_key` 一起使用 | SSL | 设置引用的 SSL id,详见 [SSL](#ssl)。 | | -| tls.verify |否,目前仅支持Kafka上游。 | Boolean | 开启服务器证书验证功能,目前仅支持 Kafka 上游。 | | +| tls.verify |否,目前仅支持 Kafka 上游。 | Boolean | 开启服务器证书验证功能,目前仅支持 Kafka 上游。 | | |keepalive_pool.size | 否 | 辅助 | 动态设置 `keepalive` 指令,详细信息请参考下文。 | |keepalive_pool.idle_timeout | 否 | 辅助 | 动态设置 `keepalive_timeout` 指令,详细信息请参考下文。 | |keepalive_pool.requests | 否 | 辅助 | 动态设置 `keepalive_requests` 指令,详细信息请参考下文。 | diff --git a/t/core/schema_def.t b/t/core/schema_def.t index da3bb51f8b26..0d27139f917c 100644 --- a/t/core/schema_def.t +++ b/t/core/schema_def.t @@ -232,6 +232,19 @@ passed assert(not ok) assert(err ~= nil) + upstream = { + nodes = { + ["127.0.0.1:8080"] = 1 + }, + type = "roundrobin", + tls = { + verify = false + } + } + local ok, err = core.schema.check(schema_def.upstream, upstream) + assert(not ok) + assert(err ~= nil) + ngx.say("passed") } } diff --git a/t/node/upstream-mtls.t b/t/node/upstream-mtls.t index b7bff235aa6a..bc26afcf6532 100644 --- a/t/node/upstream-mtls.t +++ b/t/node/upstream-mtls.t @@ -682,3 +682,51 @@ GET /hello --- error_code: 502 --- error_log failed to get ssl cert: ssl id [1] not exits + + + +=== TEST 19: `tls.verify` only +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin") + local json = require("toolkit.json") + local ssl_cert = t.read_file("t/certs/mtls_client.crt") + local data = { + upstream = { + scheme = "https", + type = "roundrobin", + nodes = { + ["127.0.0.1:1983"] = 1, + }, + tls = { + verify = true + } + }, + uri = "/hello" + } + local code, body = t.test('/apisix/admin/routes/1', + ngx.HTTP_PUT, + json.encode(data) + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + + +=== TEST 20: hit +When only `tls.verify` is present, the matching logic related to client_cert/client_key +or client_cert_id should not be entered. +--- request +GET /hello +--- response_body +hello world From 50d03786bfe688b8fe644bfee41b5842d47d0520 Mon Sep 17 00:00:00 2001 From: SkyeYoung Date: Tue, 19 Aug 2025 11:03:46 +0800 Subject: [PATCH 5/5] test: adjust cases --- t/core/schema_def.t | 4 +-- t/node/upstream-mtls.t | 57 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/t/core/schema_def.t b/t/core/schema_def.t index 0d27139f917c..2d816d560dc9 100644 --- a/t/core/schema_def.t +++ b/t/core/schema_def.t @@ -242,8 +242,8 @@ passed } } local ok, err = core.schema.check(schema_def.upstream, upstream) - assert(not ok) - assert(err ~= nil) + assert(ok) + assert(err == nil) ngx.say("passed") } diff --git a/t/node/upstream-mtls.t b/t/node/upstream-mtls.t index bc26afcf6532..998543e25aff 100644 --- a/t/node/upstream-mtls.t +++ b/t/node/upstream-mtls.t @@ -724,8 +724,61 @@ passed === TEST 20: hit -When only `tls.verify` is present, the matching logic related to client_cert/client_key -or client_cert_id should not be entered. +When only `tls.verify` is present, the matching logic related to +`client_cert`, `client_key` or `client_cert_id` should not be entered +--- request +GET /hello +--- response_body +hello world + + + +=== TEST 21: set `verify` with `client_cert`, `client_key` +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin") + local json = require("toolkit.json") + local ssl_cert = t.read_file("t/certs/mtls_client.crt") + local ssl_key = t.read_file("t/certs/mtls_client.key") + local data = { + upstream = { + scheme = "https", + type = "roundrobin", + nodes = { + ["127.0.0.1:1983"] = 1, + }, + tls = { + client_cert = ssl_cert, + client_key = ssl_key, + verify = true + } + }, + uri = "/hello" + } + local code, body = t.test('/apisix/admin/routes/1', + ngx.HTTP_PUT, + json.encode(data) + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + + +=== TEST 22: hit +`tls.verify` does not affect the parsing of `client_cert`, `client_key` +--- upstream_server_config + ssl_client_certificate ../../certs/mtls_ca.crt; + ssl_verify_client on; --- request GET /hello --- response_body