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 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..5701f4686257 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` 指令,详细信息请参考下文。 | diff --git a/t/core/schema_def.t b/t/core/schema_def.t index da3bb51f8b26..2d816d560dc9 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(ok) + assert(err == nil) + ngx.say("passed") } } diff --git a/t/node/upstream-mtls.t b/t/node/upstream-mtls.t index b7bff235aa6a..998543e25aff 100644 --- a/t/node/upstream-mtls.t +++ b/t/node/upstream-mtls.t @@ -682,3 +682,104 @@ 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 + + + +=== 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 +hello world