You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2021/09/08 01:27:16 UTC

[apisix] branch master updated: feat: allow configuring fallback SNI (#5000)

This is an automated email from the ASF dual-hosted git repository.

spacewander 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 dd4bc04  feat: allow configuring fallback SNI (#5000)
dd4bc04 is described below

commit dd4bc04c7dd74cacf18b3b6b728419e854c8fc17
Author: 罗泽轩 <sp...@gmail.com>
AuthorDate: Wed Sep 8 09:27:08 2021 +0800

    feat: allow configuring fallback SNI (#5000)
    
    The fallback SNI works around cases that client doesn't send a SNI
    during handshake.
    By configuring a fallback SNI we can configure a fallback certificate
    with the current SSL APIs.
    Fix #3147
    
    Signed-off-by: spacewander <sp...@gmail.com>
---
 apisix/ssl.lua                      | 11 ++++++++++
 apisix/ssl/router/radixtree_sni.lua |  2 +-
 apisix/stream/router/ip_port.lua    |  4 ++--
 conf/config-default.yaml            |  3 +++
 t/router/radixtree-sni2.t           | 44 +++++++++++++++++++++++++++++++++++++
 t/stream-node/sni.t                 | 24 +++++++++++++++++---
 6 files changed, 82 insertions(+), 6 deletions(-)

diff --git a/apisix/ssl.lua b/apisix/ssl.lua
index 1dc9cb3..828ebbe 100644
--- a/apisix/ssl.lua
+++ b/apisix/ssl.lua
@@ -35,6 +35,17 @@ local pkey_cache = core.lrucache.new {
 local _M = {}
 
 
+function _M.server_name()
+    local sni, err = ngx_ssl.server_name()
+    if not err and not sni then
+        local local_conf = core.config.local_conf()
+        sni = core.table.try_read_attr(local_conf, "apisix", "ssl", "fallback_sni")
+    end
+
+    return sni, err
+end
+
+
 local _aes_128_cbc_with_iv = false
 local function get_aes_128_cbc_with_iv()
     if _aes_128_cbc_with_iv == false then
diff --git a/apisix/ssl/router/radixtree_sni.lua b/apisix/ssl/router/radixtree_sni.lua
index 6f44a2f..6e7a41c 100644
--- a/apisix/ssl/router/radixtree_sni.lua
+++ b/apisix/ssl/router/radixtree_sni.lua
@@ -128,7 +128,7 @@ function _M.match_and_set(api_ctx)
     end
 
     local sni
-    sni, err = ngx_ssl.server_name()
+    sni, err = apisix_ssl.server_name()
     if type(sni) ~= "string" then
         local advise = "please check if the client requests via IP or uses an outdated protocol" ..
                        ". If you need to report an issue, " ..
diff --git a/apisix/stream/router/ip_port.lua b/apisix/stream/router/ip_port.lua
index 44b0ab3..271ae73 100644
--- a/apisix/stream/router/ip_port.lua
+++ b/apisix/stream/router/ip_port.lua
@@ -18,7 +18,7 @@ local core      = require("apisix.core")
 local config_util = require("apisix.core.config_util")
 local plugin_checker = require("apisix.plugin").stream_plugin_checker
 local router_new = require("apisix.utils.router").new
-local ngx_ssl = require("ngx.ssl")
+local apisix_ssl = require("apisix.ssl")
 local error     = error
 local tonumber  = tonumber
 local ipairs = ipairs
@@ -134,7 +134,7 @@ do
             router_ver = user_routes.conf_version
         end
 
-        local sni = ngx_ssl.server_name()
+        local sni = apisix_ssl.server_name()
         if sni and tls_router then
             local sni_rev = sni:reverse()
 
diff --git a/conf/config-default.yaml b/conf/config-default.yaml
index ab1f3d4..781239b 100644
--- a/conf/config-default.yaml
+++ b/conf/config-default.yaml
@@ -139,9 +139,12 @@ apisix:
     ssl_ciphers: ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
     ssl_session_tickets: false              #  disable ssl_session_tickets by default for 'ssl_session_tickets' would make Perfect Forward Secrecy useless.
                                             #  ref: https://github.com/mozilla/server-side-tls/issues/135
+
     key_encrypt_salt: edd1c9f0985e76a2      #  If not set, will save origin ssl key into etcd.
                                             #  If set this, must be a string of length 16. And it will encrypt ssl key with AES-128-CBC
                                             #  !!! So do not change it after saving your ssl, it can't decrypt the ssl keys have be saved if you change !!
+
+    #fallback_sni: "my.default.domain"      # If set this, when the client doesn't send SNI during handshake, the fallback SNI will be used instead
   enable_control: true
   #control:
   #  ip: 127.0.0.1
diff --git a/t/router/radixtree-sni2.t b/t/router/radixtree-sni2.t
index e3ec3b7..57aadd0 100644
--- a/t/router/radixtree-sni2.t
+++ b/t/router/radixtree-sni2.t
@@ -354,3 +354,47 @@ failed to do SSL handshake: handshake failed
 failed to fetch ssl config: failed to find SNI: please check if the client requests via IP or uses an outdated protocol
 --- no_error_log
 [alert]
+
+
+
+=== TEST 9: client request without sni, but fallback_sni is set
+--- yaml_config
+apisix:
+  node_listen: 1984
+  ssl:
+    fallback_sni: "a.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
+
+            local sess, err = sock:sslhandshake(nil, nil, 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
diff --git a/t/stream-node/sni.t b/t/stream-node/sni.t
index ab70117..ff80c95 100644
--- a/t/stream-node/sni.t
+++ b/t/stream-node/sni.t
@@ -277,7 +277,25 @@ proxy request to 127.0.0.2:1995
 
 
 
-=== TEST 10: no sni matched, fall back to non-sni route
+=== TEST 10: use fallback sni to match route
+--- yaml_config
+apisix:
+  node_listen: 1984
+  stream_proxy:
+    tcp:
+      - 9100
+  ssl:
+    fallback_sni: a.test.com
+--- stream_tls_request
+mmm
+--- response_body
+hello world
+--- error_log
+proxy request to 127.0.0.2:1995
+
+
+
+=== TEST 11: no sni matched, fall back to non-sni route
 --- config
     location /t {
         content_by_lua_block {
@@ -301,7 +319,7 @@ passed
 
 
 
-=== TEST 11: hit route
+=== TEST 12: hit route
 --- stream_tls_request
 mmm
 --- stream_sni: b.test.com
@@ -312,7 +330,7 @@ proxy request to 127.0.0.3:1995
 
 
 
-=== TEST 12: clean up routes
+=== TEST 13: clean up routes
 --- config
     location /t {
         content_by_lua_block {