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/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 12c9e6f feat: upstream grpcs support mTLS (#4070)
12c9e6f is described below
commit 12c9e6f2670904c0daa19f47844dd61dae6496a5
Author: 罗泽轩 <[email protected]>
AuthorDate: Tue Apr 20 18:08:13 2021 +0800
feat: upstream grpcs support mTLS (#4070)
---
apisix/init.lua | 62 ++++++++++++++++++++++---------------
apisix/upstream.lua | 24 ++++++++++++--
ci/centos7-ci.sh | 7 +++--
ci/common.sh | 2 ++
ci/linux_openresty_common_runner.sh | 10 +++---
t/grpc-proxy-test.sh | 35 +++++++++++++++++++--
6 files changed, 102 insertions(+), 38 deletions(-)
diff --git a/apisix/init.lua b/apisix/init.lua
index 70be796..24747fc 100644
--- a/apisix/init.lua
+++ b/apisix/init.lua
@@ -14,32 +14,33 @@
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-local require = require
+local require = require
require("apisix.patch").patch()
-local core = require("apisix.core")
-local plugin = require("apisix.plugin")
-local plugin_config = require("apisix.plugin_config")
-local script = require("apisix.script")
-local service_fetch = require("apisix.http.service").get
-local admin_init = require("apisix.admin.init")
-local get_var = require("resty.ngxvar").fetch
-local router = require("apisix.router")
-local set_upstream = require("apisix.upstream").set_by_route
-local upstream_util = require("apisix.utils.upstream")
-local ctxdump = require("resty.ctxdump")
-local ipmatcher = require("resty.ipmatcher")
-local ngx = ngx
-local get_method = ngx.req.get_method
-local ngx_exit = ngx.exit
-local math = math
-local error = error
-local ipairs = ipairs
-local tostring = tostring
-local ngx_now = ngx.now
-local ngx_var = ngx.var
-local str_byte = string.byte
-local str_sub = string.sub
-local tonumber = tonumber
+local core = require("apisix.core")
+local plugin = require("apisix.plugin")
+local plugin_config = require("apisix.plugin_config")
+local script = require("apisix.script")
+local service_fetch = require("apisix.http.service").get
+local admin_init = require("apisix.admin.init")
+local get_var = require("resty.ngxvar").fetch
+local router = require("apisix.router")
+local apisix_upstream = require("apisix.upstream")
+local set_upstream = apisix_upstream.set_by_route
+local upstream_util = require("apisix.utils.upstream")
+local ctxdump = require("resty.ctxdump")
+local ipmatcher = require("resty.ipmatcher")
+local ngx = ngx
+local get_method = ngx.req.get_method
+local ngx_exit = ngx.exit
+local math = math
+local error = error
+local ipairs = ipairs
+local tostring = tostring
+local ngx_now = ngx.now
+local ngx_var = ngx.var
+local str_byte = string.byte
+local str_sub = string.sub
+local tonumber = tonumber
local control_api_router
if ngx.config.subsystem == "http" then
control_api_router = require("apisix.control.router")
@@ -488,6 +489,17 @@ end
function _M.grpc_access_phase()
ngx.ctx = ctxdump.apply_ngx_ctx(ngx_var.ctx_ref)
+
+ local api_ctx = ngx.ctx.api_ctx
+ if not api_ctx then
+ return
+ end
+
+ local code, err = apisix_upstream.set_grpcs_upstream_param(api_ctx)
+ if code then
+ core.log.error("failed to set grpcs upstream param: ", err)
+ core.response.exit(code)
+ end
end
diff --git a/apisix/upstream.lua b/apisix/upstream.lua
index 5bcc679..488dfaf 100644
--- a/apisix/upstream.lua
+++ b/apisix/upstream.lua
@@ -291,7 +291,8 @@ function _M.set_by_route(route, api_ctx)
api_ctx.up_checker = checker
end
- if up_conf.scheme == "https" and up_conf.tls then
+ local scheme = up_conf.scheme
+ if (scheme == "https" or scheme == "grpcs") and up_conf.tls then
-- the sni here is just for logging
local sni = api_ctx.var.upstream_host
local cert, err = apisix_ssl.fetch_cert(sni, up_conf.tls.client_cert)
@@ -304,13 +305,30 @@ function _M.set_by_route(route, api_ctx)
return 503, err
end
+ if scheme == "grpcs" then
+ api_ctx.upstream_grpcs_cert = cert
+ api_ctx.upstream_grpcs_key = key
+ else
+ local ok, err = set_upstream_tls_client_param(cert, key)
+ if not ok then
+ return 503, err
+ end
+ end
+ end
+
+ return
+end
+
+
+function _M.set_grpcs_upstream_param(ctx)
+ if ctx.upstream_grpcs_cert then
+ local cert = ctx.upstream_grpcs_cert
+ local key = ctx.upstream_grpcs_key
local ok, err = set_upstream_tls_client_param(cert, key)
if not ok then
return 503, err
end
end
-
- return
end
diff --git a/ci/centos7-ci.sh b/ci/centos7-ci.sh
index 8a7fabc..b03d4d2 100755
--- a/ci/centos7-ci.sh
+++ b/ci/centos7-ci.sh
@@ -44,12 +44,15 @@ install_dependencies() {
# install and start grpc_server_example
mkdir build-cache
- wget
https://github.com/iresty/grpc_server_example/releases/download/20200901/grpc_server_example-amd64.tar.gz
+ wget
https://github.com/api7/grpc_server_example/releases/download/"$GRPC_SERVER_EXAMPLE_VER"/grpc_server_example-amd64.tar.gz
tar -xvf grpc_server_example-amd64.tar.gz
mv grpc_server_example build-cache/
git clone https://github.com/iresty/grpc_server_example.git
grpc_server_example
cd grpc_server_example/ && mv proto/ ../build-cache/ && cd ..
- ./build-cache/grpc_server_example > grpc_server_example.log 2>&1 || (cat
grpc_server_example.log && exit 1)&
+ ./build-cache/grpc_server_example \
+ -grpc-address :50051 -grpcs-address :50052 -grpcs-mtls-address :50053 \
+ -crt ./t/certs/apisix.crt -key ./t/certs/apisix.key -ca
./t/certs/mtls_ca.crt \
+ > grpc_server_example.log 2>&1 || (cat grpc_server_example.log && exit
1)&
# wait for grpc_server_example to fully start
sleep 3
diff --git a/ci/common.sh b/ci/common.sh
index aec7082..26e7b6f 100644
--- a/ci/common.sh
+++ b/ci/common.sh
@@ -36,3 +36,5 @@ create_lua_deps() {
# maybe reopen this feature later
# luarocks install luacov-coveralls --tree=deps --local > build.log 2>&1
|| (cat build.log && exit 1)
}
+
+GRPC_SERVER_EXAMPLE_VER=20210417
diff --git a/ci/linux_openresty_common_runner.sh
b/ci/linux_openresty_common_runner.sh
index 5b501e0..34c3ecd 100755
--- a/ci/linux_openresty_common_runner.sh
+++ b/ci/linux_openresty_common_runner.sh
@@ -75,8 +75,8 @@ do_install() {
cp ci/ASF* ci/openwhisk-utilities/scancode/
mkdir -p build-cache
- if [ ! -f "build-cache/grpc_server_example_20210122" ]; then
- wget
https://github.com/api7/grpc_server_example/releases/download/20210122/grpc_server_example-amd64.tar.gz
+ if [ ! -f "build-cache/grpc_server_example_$GRPC_SERVER_EXAMPLE_VER" ];
then
+ wget
https://github.com/api7/grpc_server_example/releases/download/"$GRPC_SERVER_EXAMPLE_VER"/grpc_server_example-amd64.tar.gz
tar -xvf grpc_server_example-amd64.tar.gz
mv grpc_server_example build-cache/
@@ -85,7 +85,7 @@ do_install() {
mv proto/ ../build-cache/
popd || exit 1
- touch build-cache/grpc_server_example_20210122
+ touch build-cache/grpc_server_example_"$GRPC_SERVER_EXAMPLE_VER"
fi
if [ ! -f "build-cache/grpcurl" ]; then
@@ -102,8 +102,8 @@ script() {
./utils/set-dns.sh
./build-cache/grpc_server_example \
- -grpc-address :50051 -grpcs-address :50052 \
- -crt ./t/certs/apisix.crt -key ./t/certs/apisix.key \
+ -grpc-address :50051 -grpcs-address :50052 -grpcs-mtls-address :50053 \
+ -crt ./t/certs/apisix.crt -key ./t/certs/apisix.key -ca
./t/certs/mtls_ca.crt \
&
# listen 9081 for http2 with plaintext
diff --git a/t/grpc-proxy-test.sh b/t/grpc-proxy-test.sh
index c6e294c..b6574cd 100755
--- a/t/grpc-proxy-test.sh
+++ b/t/grpc-proxy-test.sh
@@ -16,6 +16,12 @@
# limitations under the License.
#
+clean_up() {
+ #delete test data
+ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X DELETE
+ curl http://127.0.0.1:9080/apisix/admin/ssl/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X DELETE
+}
+
set -ex
# ensure grpc server example is already started
@@ -88,6 +94,29 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H
'X-API-KEY: edd1c9f034335f1
./build-cache/grpcurl -insecure -import-path ./build-cache/proto -proto
helloworld.proto -d '{"name":"apisix"}' test.com:9443
helloworld.Greeter.SayHello | grep 'Hello apisix'
-#delete test data
-curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X DELETE
-curl http://127.0.0.1:9080/apisix/admin/ssl/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X DELETE
+if ! openresty -V 2>&1 | grep "apisix-nginx-module"; then
+ echo "skip vanilla OpenResty"
+ clean_up
+ exit 0
+fi
+
+#test grpcs with mTLS proxy
+curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
+{
+ "methods": ["POST"],
+ "uri": "/helloworld.Greeter/SayHello",
+ "upstream": {
+ "scheme": "grpcs",
+ "tls": {
+ "client_cert": "-----BEGIN
CERTIFICATE-----\nMIIDOjCCAiICAwD6zzANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJjbjESMBAG\nA1UECAwJR3VhbmdEb25nMQ8wDQYDVQQHDAZaaHVIYWkxDTALBgNVBAoMBGFwaTcx\nDDAKBgNVBAsMA29wczEWMBQGA1UEAwwNY2EuYXBpc2l4LmRldjAeFw0yMDA2MjAx\nMzE1MDBaFw0zMDA3MDgxMzE1MDBaMF0xCzAJBgNVBAYTAmNuMRIwEAYDVQQIDAlH\ndWFuZ0RvbmcxDTALBgNVBAoMBGFwaTcxDzANBgNVBAcMBlpodUhhaTEaMBgGA1UE\nAwwRY2xpZW50LmFwaXNpeC5kZXYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\nAoIBAQCfKI8uiEH/ifZikSnRa3/E2B4ohVWRwjo
[...]
+ "client_key": "-----BEGIN RSA PRIVATE
KEY-----\nMIIEpAIBAAKCAQEAnyiPLohB/4n2YpEp0Wt/xNgeKIVVkcI6PyMcgxFqJoEeLS5N\naUiYT/+Egi1rjEExVk20qrdSBWMuGW1Uhx8hqDT5iRqx0SQhhPrIKX859Bo1eJV0\nDyQ9JOhkdQl9jKNU1nRakifx3OQEMHEBZz36CwMLAcuMqq5Zn/emQFMrZf+2ZI3+\nD+5iZCR7TP1oEkdKRoY2UwBkX+QyVqDudZIt4tySPteZjoZp5wqZ5LJxlT35fdqv\ndh8/+L94qhPlE4T2EaXBm53XczLz2gl4mr4PAf7ti1W5+JdGnWpqkBnqTgIw/9ca\n2jlT9lttltD87Q1yeKy3vnGqTUuKBrklH5CBDQIDAQABAoIBAHDe5bPdQ9jCcW3z\nfpGax/DER5b6//UvpfkSoGy/E+Wcmdb2yEVL
[...]
+ },
+ "type": "roundrobin",
+ "nodes": {
+ "127.0.0.1:50053": 1
+ }
+ }
+}'
+
+./build-cache/grpcurl -insecure -import-path ./build-cache/proto -proto
helloworld.proto -d '{"name":"apisix"}' test.com:9443
helloworld.Greeter.SayHello | grep 'Hello apisix'
+clean_up