You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by me...@apache.org on 2020/06/08 02:52:34 UTC
[incubator-apisix] branch master updated: bugfix: wildcard certificates cannot match multi-level subdomains in … (#810)
This is an automated email from the ASF dual-hosted git repository.
membphis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-apisix.git
The following commit(s) were added to refs/heads/master by this push:
new c452846 bugfix: wildcard certificates cannot match multi-level subdomains in … (#810)
c452846 is described below
commit c452846b81a52aecaf43c9747dddfafd8ece9be6
Author: YuanSheng Wang <me...@gmail.com>
AuthorDate: Mon Jun 8 10:52:25 2020 +0800
bugfix: wildcard certificates cannot match multi-level subdomains in … (#810)
---
apisix/http/router/radixtree_sni.lua | 11 ++-
conf/cert/openssl-test2.conf | 40 +++++++++++
conf/cert/test2.crt | 28 ++++++++
conf/cert/test2.key | 39 ++++++++++
t/APISIX.pm | 6 ++
t/router/radixtree-sni.t | 133 ++++++++++++++++++++++++++++++++++-
6 files changed, 255 insertions(+), 2 deletions(-)
diff --git a/apisix/http/router/radixtree_sni.lua b/apisix/http/router/radixtree_sni.lua
index 0ecc3bf..83dc2dc 100644
--- a/apisix/http/router/radixtree_sni.lua
+++ b/apisix/http/router/radixtree_sni.lua
@@ -21,6 +21,7 @@ local ngx_ssl = require("ngx.ssl")
local ipairs = ipairs
local type = type
local error = error
+local str_find = string.find
local ssl_certificates
local radixtree_router
local radixtree_router_ver
@@ -49,6 +50,7 @@ local function create_router(ssl_items)
return
end
api_ctx.matched_ssl = ssl
+ api_ctx.matched_sni = sni
end
}
end
@@ -114,12 +116,19 @@ function _M.match_and_set(api_ctx)
end
core.log.debug("sni: ", sni)
- local ok = radixtree_router:dispatch(sni:reverse(), nil, api_ctx)
+ local sni_rev = sni:reverse()
+ local ok = radixtree_router:dispatch(sni_rev, nil, api_ctx)
if not ok then
core.log.warn("not found any valid sni configuration")
return false
end
+ if str_find(sni_rev, ".", #api_ctx.matched_sni, true) then
+ core.log.warn("not found any valid sni configuration, matched sni: ",
+ api_ctx.matched_sni:reverse(), " current sni: ", sni)
+ return false
+ end
+
local matched_ssl = api_ctx.matched_ssl
core.log.info("debug: ", core.json.delay_encode(matched_ssl, true))
ok, err = set_pem_ssl_key(matched_ssl.value.cert, matched_ssl.value.key)
diff --git a/conf/cert/openssl-test2.conf b/conf/cert/openssl-test2.conf
new file mode 100644
index 0000000..1e5beec
--- /dev/null
+++ b/conf/cert/openssl-test2.conf
@@ -0,0 +1,40 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+[req]
+distinguished_name = req_distinguished_name
+x509_extensions = v3_req
+prompt = no
+
+[req_distinguished_name]
+C = CN
+ST = GuangDong
+L = ZhuHai
+O = iresty
+CN = test2.com
+
+[v3_req]
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid,issuer
+basicConstraints = CA:TRUE
+subjectAltName = @alt_names
+
+[alt_names]
+DNS.1 = test2.com
+DNS.2 = *.test2.com
+
+## openssl genrsa -out test2.key 3072
+## openssl req -new -x509 -key test2.key -sha256 -config openssl-test2.conf -out test2.crt -days 36500
diff --git a/conf/cert/test2.crt b/conf/cert/test2.crt
new file mode 100644
index 0000000..922a8f8
--- /dev/null
+++ b/conf/cert/test2.crt
@@ -0,0 +1,28 @@
+-----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-----
diff --git a/conf/cert/test2.key b/conf/cert/test2.key
new file mode 100644
index 0000000..c25d4e5
--- /dev/null
+++ b/conf/cert/test2.key
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
diff --git a/t/APISIX.pm b/t/APISIX.pm
index 173aa5c..ab50740 100644
--- a/t/APISIX.pm
+++ b/t/APISIX.pm
@@ -72,6 +72,8 @@ if ($enable_local_dns) {
my $yaml_config = read_file("conf/config.yaml");
my $ssl_crt = read_file("conf/cert/apisix.crt");
my $ssl_key = read_file("conf/cert/apisix.key");
+my $test2_crt = read_file("conf/cert/test2.crt");
+my $test2_key = read_file("conf/cert/test2.key");
$yaml_config =~ s/node_listen: 9080/node_listen: 1984/;
$yaml_config =~ s/enable_heartbeat: true/enable_heartbeat: false/;
$yaml_config =~ s/ # stream_proxy:/ stream_proxy:\n tcp:\n - 9100/;
@@ -418,6 +420,10 @@ $user_yaml_config
$ssl_crt
>>> ../conf/cert/apisix.key
$ssl_key
+>>> ../conf/cert/test2.crt
+$test2_crt
+>>> ../conf/cert/test2.key
+$test2_key
$user_apisix_yaml
_EOC_
diff --git a/t/router/radixtree-sni.t b/t/router/radixtree-sni.t
index 8f18545..d68a813 100644
--- a/t/router/radixtree-sni.t
+++ b/t/router/radixtree-sni.t
@@ -362,7 +362,7 @@ passed
-=== TEST 8: client request
+=== TEST 8: client request: test.com
--- config
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
@@ -434,3 +434,134 @@ lua ssl server name: "test.com"
--- no_error_log
[error]
[alert]
+
+
+
+=== TEST 9: set ssl(sni: *.test2.com)
+--- config
+location /t {
+ content_by_lua_block {
+ local core = require("apisix.core")
+ local t = require("lib.test_admin")
+
+ local ssl_cert = t.read_file("conf/cert/test2.crt")
+ local ssl_key = t.read_file("conf/cert/test2.key")
+ local data = {cert = ssl_cert, key = ssl_key, sni = "*.test2.com"}
+
+ local code, body = t.test('/apisix/admin/ssl/1',
+ ngx.HTTP_PUT,
+ core.json.encode(data),
+ [[{
+ "node": {
+ "value": {
+ "sni": "*.test2.com"
+ },
+ "key": "/apisix/ssl/1"
+ },
+ "action": "set"
+ }]]
+ )
+
+ ngx.status = code
+ ngx.say(body)
+ }
+}
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 10: client request: www.test2.com
+--- config
+listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
+
+location /t {
+ content_by_lua_block {
+ -- etcd sync
+ ngx.sleep(0.2)
+
+ 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
+
+ ngx.say("connected: ", ok)
+
+ local sess, err = sock:sslhandshake(nil, "www.test2.com", true)
+ if not sess then
+ ngx.say("failed to do SSL handshake: ", err)
+ return
+ end
+
+ ngx.say("ssl handshake: ", type(sess))
+ end -- do
+ -- collectgarbage()
+ }
+}
+--- request
+GET /t
+--- response_body
+connected: 1
+failed to do SSL handshake: 18: self signed certificate
+--- error_log
+lua ssl server name: "www.test2.com"
+--- no_error_log
+[error]
+[alert]
+
+
+
+=== TEST 11: client request: aa.bb.test2.com
+--- config
+listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
+
+location /t {
+ content_by_lua_block {
+ -- etcd sync
+ ngx.sleep(0.2)
+
+ 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
+
+ ngx.say("connected: ", ok)
+
+ local sess, err = sock:sslhandshake(nil, "aa.bb.test2.com", true)
+ if not sess then
+ ngx.say("failed to do SSL handshake: ", err)
+ return
+ end
+
+ ngx.say("ssl handshake: ", type(sess))
+ end -- do
+ -- collectgarbage()
+ }
+}
+--- request
+GET /t
+--- response_body
+connected: 1
+failed to do SSL handshake: certificate host mismatch
+--- error_log
+lua ssl server name: "aa.bb.test2.com"
+not found any valid sni configuration, matched sni: *.test2.com current sni: aa.bb.test2.com
+--- no_error_log
+[error]
+[alert]