This is an automated email from the ASF dual-hosted git repository.
guoqqqi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new de0782a91a fix: return 421 for SNI and Host mismatches on mTLS
requests (#14013)
de0782a91a is described below
commit de0782a91a98febd3733d0f3c547166a7b7464f5
Author: ruanweihong-aaa <[email protected]>
AuthorDate: Tue Oct 20 08:49:56 2026 +0800
fix: return 421 for SNI and Host mismatches on mTLS requests (#14013)
---
apisix/init.lua | 25 ++++++++++++-------------
t/node/client-mtls-openresty.t | 8 ++++----
t/node/client-mtls.t | 8 ++++----
3 files changed, 20 insertions(+), 21 deletions(-)
diff --git a/apisix/init.lua b/apisix/init.lua
index b25069c744..45120aac03 100644
--- a/apisix/init.lua
+++ b/apisix/init.lua
@@ -482,6 +482,15 @@ local function verify_https_client(ctx)
local matched_ssl = ctx.matched_ssl
if matched_ssl.value.client and apisix_ssl.support_client_verification()
then
+ local sni = apisix_ssl.server_name()
+ if sni ~= host then
+ -- A reused connection cannot negotiate the target host's client
certificate.
+ -- Reject it before checking the certificate so clients can retry
with its SNI.
+ core.log.error("request SNI ", sni, " does not match host ", host,
+ " for an mTLS-enabled SSL configuration")
+ return false, 421
+ end
+
local verified = apisix_base_flags.client_cert_verified_in_handshake
if not verified then
-- vanilla OpenResty requires to check the verification result
@@ -497,17 +506,6 @@ local function verify_https_client(ctx)
end
end
- local sni = apisix_ssl.server_name()
- if sni ~= host then
- -- There is a case that the user configures a SSL object with
`*.domain`,
- -- and the client accesses with SNI `a.domain` but uses Host
`b.domain`.
- -- This case is complex and we choose to restrict the access until
there
- -- is a stronge demand in real world.
- core.log.error("client certificate verified with SNI ", sni,
- ", but the host is ", host)
- return false
- end
-
if not verify_tls_session_resumption() then
return false
end
@@ -858,8 +856,9 @@ function _M.http_access_phase()
local span = tracer.start(ngx_ctx, "apisix.phase.access",
tracer.kind.server)
- if not verify_https_client(api_ctx) then
- return core.response.exit(400)
+ local verified, status = verify_https_client(api_ctx)
+ if not verified then
+ return core.response.exit(status or 400)
end
debug.dynamic_debug(api_ctx)
diff --git a/t/node/client-mtls-openresty.t b/t/node/client-mtls-openresty.t
index 050394d1ba..9c69336855 100644
--- a/t/node/client-mtls-openresty.t
+++ b/t/node/client-mtls-openresty.t
@@ -189,9 +189,9 @@ GET /t
--- exec
curl -k https://localhost:1994/hello -H "Host: test.com"
--- response_body eval
-qr/400 Bad Request/
+qr/421 Misdirected Request/
--- error_log
-client certificate was not present
+request SNI localhost does not match host test.com for an mTLS-enabled SSL
configuration
@@ -267,6 +267,6 @@ GET /t
--- exec
curl --cert t/certs/mtls_client.crt --key t/certs/mtls_client.key -k
https://localhost:1994/hello -H "Host: test.com"
--- response_body eval
-qr/400 Bad Request/
+qr/421 Misdirected Request/
--- error_log
-client certificate verified with SNI localhost, but the host is test.com
+request SNI localhost does not match host test.com for an mTLS-enabled SSL
configuration
diff --git a/t/node/client-mtls.t b/t/node/client-mtls.t
index e594169605..b71cccb426 100644
--- a/t/node/client-mtls.t
+++ b/t/node/client-mtls.t
@@ -490,9 +490,9 @@ GET /t
--- exec
curl -k https://localhost:1994/hello -H "Host: test.com"
--- response_body eval
-qr/400 Bad Request/
+qr/421 Misdirected Request/
--- error_log
-client certificate verified with SNI localhost, but the host is test.com
+request SNI localhost does not match host test.com for an mTLS-enabled SSL
configuration
@@ -568,9 +568,9 @@ GET /t
--- exec
curl --cert t/certs/mtls_client.crt --key t/certs/mtls_client.key -k
https://localhost:1994/hello -H "Host: test.com"
--- response_body eval
-qr/400 Bad Request/
+qr/421 Misdirected Request/
--- error_log
-client certificate verified with SNI localhost, but the host is test.com
+request SNI localhost does not match host test.com for an mTLS-enabled SSL
configuration