Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ssl): match sni in case-insensitive way #5074

Merged
merged 1 commit into from
Sep 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions apisix/ssl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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


Expand Down
17 changes: 17 additions & 0 deletions apisix/ssl/router/radixtree_sni.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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", {
Expand All @@ -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: "
Expand Down
130 changes: 130 additions & 0 deletions t/router/radixtree-sni2.t
Original file line number Diff line number Diff line change
Expand Up @@ -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