You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by GitBox <gi...@apache.org> on 2022/11/29 07:12:41 UTC

[GitHub] [apisix] soulbird commented on a diff in pull request #8403: feat: support global data encryption of secret information

soulbird commented on code in PR #8403:
URL: https://github.com/apache/apisix/pull/8403#discussion_r1034364481


##########
apisix/plugin.lua:
##########
@@ -849,6 +850,65 @@ check_plugin_metadata = function(item)
 end
 
 
+local function check_enable_and_get_plugin_schema(name, schema_type)
+    local plugin_schema = local_plugins_hash and local_plugins_hash[name]
+    local schema
+    if schema_type == core.schema.TYPE_CONSUMER then
+        schema = plugin_schema.consumer_schema
+    else
+        schema = plugin_schema.schema
+    end
+
+    return schema
+end
+
+
+local function decrypt_conf(name, conf, schema_type)
+    local enable = core.table.try_read_attr(local_conf, "apisix", "data_encryption", "enable")
+    if not enable then
+        return conf
+    end
+
+    local schema = check_enable_and_get_plugin_schema(name, schema_type)
+    if not schema then
+        return
+    end
+
+    for key, props in pairs(schema.properties) do
+        if props.type == "string" and props.encrypted and conf[key] then
+            local encrypted, err = apisix_ssl.aes_decrypt_pkey(conf[key], "data_encrypt")
+            if not encrypted then
+                core.log.warn("failed to decrypt the conf of plugin [", name,
+                               "] key [", key, "], err: ", err)
+            else
+                conf[key] = encrypted
+            end
+        end
+    end
+end
+_M.decrypt_conf = decrypt_conf
+
+
+local function encrypt_conf(name, conf, schema_type)
+    local enable = core.table.try_read_attr(local_conf, "apisix", "data_encryption", "enable")
+    if not enable then
+        return conf
+    end
+
+    local schema = check_enable_and_get_plugin_schema(name, schema_type)
+    if not schema then
+        return
+    end
+
+    for key, props in pairs(schema.properties) do

Review Comment:
   Don't we consider the case of configuration nesting here?



##########
apisix/plugins/basic-auth.lua:
##########
@@ -39,7 +38,7 @@ local consumer_schema = {
     title = "work with consumer object",
     properties = {
         username = { type = "string" },
-        password = { type = "string" },
+        password = { type = "string", encrypted = true },

Review Comment:
   We need to adjust the documentation of the corresponding plugin for this point.



##########
t/node/consumer-group.t:
##########
@@ -310,3 +310,140 @@ world
     }
 --- response_body
 bar
+
+
+
+=== TEST 5: data encryption
+--- yaml_config
+apisix:
+    data_encryption:
+        enable: true
+        keyring:
+            - edd1c9f0985e76a2
+--- config
+    location /t {
+        content_by_lua_block {
+            local json = require("toolkit.json")
+            local t = require("lib.test_admin").test
+            local etcd = require("apisix.core.etcd")
+            local code, body = t('/apisix/admin/consumer_groups/company_a',

Review Comment:
   Why use consumer_groups?



##########
t/node/consumer-group.t:
##########
@@ -310,3 +310,140 @@ world
     }
 --- response_body
 bar
+
+
+
+=== TEST 5: data encryption
+--- yaml_config
+apisix:
+    data_encryption:
+        enable: true
+        keyring:
+            - edd1c9f0985e76a2
+--- config
+    location /t {
+        content_by_lua_block {
+            local json = require("toolkit.json")
+            local t = require("lib.test_admin").test
+            local etcd = require("apisix.core.etcd")
+            local code, body = t('/apisix/admin/consumer_groups/company_a',
+                ngx.HTTP_PUT,
+                [[{
+                    "plugins": {
+                        "limit-count": {
+                            "count": 2,
+                            "time_window": 60,
+                            "rejected_code": 503,
+                            "key": "remote_addr"
+                        }
+                    }
+                }]]
+            )
+            if code >= 300 then
+                ngx.status = code
+                ngx.say(body)
+                return
+            end
+
+            ngx.sleep(0.1)
+
+            local code, body = t('/apisix/admin/consumers/foobar',
+                ngx.HTTP_PUT,
+                [[{
+                    "username": "foobar",
+                    "plugins": {
+                        "key-auth": {
+                            "key": "auth-two"
+                        }
+                    },
+                    "group_id": "company_a"
+                }]]
+            )
+            if code >= 300 then
+                ngx.status = code
+                ngx.say(body)
+                return
+            end
+            ngx.sleep(0.1)
+
+            -- get plugin conf from admin api, key is decrypted
+            local code, message, res = t('/apisix/admin/consumers/foobar',
+                ngx.HTTP_GET
+            )
+            res = json.decode(res)
+            if code >= 300 then
+                ngx.status = code
+                ngx.say(message)
+                return
+            end
+
+            ngx.say(res.value.plugins["key-auth"].key)
+
+            -- get plugin conf from etcd, key is encrypted
+            local etcd = require("apisix.core.etcd")
+            local res = assert(etcd.get('/consumers/foobar'))
+            ngx.say(res.body.node.value.plugins["key-auth"].key)
+        }
+    }
+--- response_body
+auth-two
+vU/ZHVJw7b0XscDJ1Fhtig==
+
+
+
+=== TEST 6: verify data encryption
+--- yaml_config
+apisix:
+    data_encryption:
+        enable: true
+        keyring:
+            - edd1c9f0985e76a2
+--- config
+    location /t {
+        content_by_lua_block {
+            local json = require "t.toolkit.json"
+            local t = require("lib.test_admin").test
+            local code, err = t('/apisix/admin/routes/1',
+                ngx.HTTP_PUT,
+                [[{
+                    "uri": "/hello",
+                    "upstream": {
+                        "nodes": {
+                            "127.0.0.1:1980": 1
+                        },
+                        "type": "roundrobin"
+                    },
+                    "plugins": {
+                        "key-auth": {}
+                    }
+                }]]
+            )
+            if code > 300 then
+                ngx.log(ngx.ERR, err)
+                return
+            end
+            ngx.sleep(0.1)
+
+            local http = require "resty.http"
+            local uri = "http://127.0.0.1:" .. ngx.var.server_port
+                        .. "/hello"
+            local ress = {}
+            for i = 1, 3 do

Review Comment:
   Why not use `pipelined_requests`?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org