diff --git a/apisix/ssl.lua b/apisix/ssl.lua index 828ebbe5b598..c0c47aec07fd 100644 --- a/apisix/ssl.lua +++ b/apisix/ssl.lua @@ -18,7 +18,8 @@ local core = require("apisix.core") local ngx_ssl = require("ngx.ssl") local ngx_encode_base64 = ngx.encode_base64 local ngx_decode_base64 = ngx.decode_base64 -local aes = require "resty.aes" +local aes = require("resty.aes") +local str_lower = string.lower local assert = assert local type = type @@ -37,12 +38,20 @@ local _M = {} function _M.server_name() local sni, err = ngx_ssl.server_name() - if not err and not sni then + if err then + return nil, err + end + + if not sni then local local_conf = core.config.local_conf() sni = core.table.try_read_attr(local_conf, "apisix", "ssl", "fallback_sni") + if not sni then + return nil + end end - return sni, err + sni = str_lower(sni) + return sni end diff --git a/apisix/ssl/router/radixtree_sni.lua b/apisix/ssl/router/radixtree_sni.lua index 6e7a41cb02de..433ed2de07bf 100644 --- a/apisix/ssl/router/radixtree_sni.lua +++ b/apisix/ssl/router/radixtree_sni.lua @@ -25,6 +25,7 @@ local type = type local error = error local str_find = core.string.find local str_gsub = string.gsub +local str_lower = string.lower local ssl_certificates local radixtree_router local radixtree_router_ver @@ -226,6 +227,21 @@ function _M.ssls() end +local function ssl_filter(ssl) + if not ssl.value then + return + end + + if ssl.value.sni then + ssl.value.sni = str_lower(ssl.value.sni) + elseif ssl.value.snis then + for i, v in ipairs(ssl.value.snis) do + ssl.value.snis[i] = str_lower(v) + end + end +end + + function _M.init_worker() local err ssl_certificates, err = core.config.new("/ssl", { @@ -234,6 +250,7 @@ function _M.init_worker() checker = function (item, schema_type) return apisix_ssl.check_ssl_conf(true, item) end, + filter = ssl_filter, }) if not ssl_certificates then error("failed to create etcd instance for fetching ssl certificates: " diff --git a/t/router/radixtree-sni2.t b/t/router/radixtree-sni2.t index 57aadd03e4b7..6b6f1b233e53 100644 --- a/t/router/radixtree-sni2.t +++ b/t/router/radixtree-sni2.t @@ -398,3 +398,133 @@ GET /t [error] --- response_body ssl handshake: true + + + +=== TEST 10: set sni with uppercase +--- config +location /t { + content_by_lua_block { + local core = require("apisix.core") + local t = require("lib.test_admin") + + local ssl_cert = t.read_file("t/certs/test2.crt") + local ssl_key = t.read_file("t/certs/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) + ) + + ngx.status = code + ngx.say(body) + } +} +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 11: match case insensitive +--- 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, "a.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() + } +} +--- request +GET /t +--- no_error_log +[error] +--- response_body +ssl handshake: true + + + +=== TEST 12: set snis with uppercase +--- config +location /t { + content_by_lua_block { + local core = require("apisix.core") + local t = require("lib.test_admin") + + local ssl_cert = t.read_file("t/certs/test2.crt") + local ssl_key = t.read_file("t/certs/test2.key") + local data = {cert = ssl_cert, key = ssl_key, snis = {"TesT2.com", "a.com"}} + + local code, body = t.test('/apisix/admin/ssl/1', + ngx.HTTP_PUT, + core.json.encode(data) + ) + + ngx.status = code + ngx.say(body) + } +} +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 13: match case insensitive +--- 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() + } +} +--- request +GET /t +--- no_error_log +[error] +--- response_body +ssl handshake: true