diff --git a/apisix/core/etcd.lua b/apisix/core/etcd.lua index 6ce2742a..50c13cca 100644 --- a/apisix/core/etcd.lua +++ b/apisix/core/etcd.lua @@ -100,6 +100,10 @@ function _M.get_format(res, real_key, is_dir, formatter) return nil, "insufficient credentials code: 401" end + if res.body.error == "etcdserver: permission denied" then + return nil, "etcd forbidden code: 403" + end + res.headers["X-Etcd-Index"] = res.body.header.revision if not res.body.kvs then diff --git a/t/core/etcd-auth-fail.t b/t/core/etcd-auth-fail.t index e04eca8f..708b1d24 100644 --- a/t/core/etcd-auth-fail.t +++ b/t/core/etcd-auth-fail.t @@ -32,6 +32,11 @@ system('etcdctl --endpoints="http://127.0.0.1:2379" role add root'); system('etcdctl --endpoints="http://127.0.0.1:2379" user grant-role root root'); system('etcdctl --endpoints="http://127.0.0.1:2379" role list'); system('etcdctl --endpoints="http://127.0.0.1:2379" user user list'); +# Grant the user access to the specified directory +system('etcdctl --endpoints="http://127.0.0.1:2379" user add apisix:abc123'); +system('etcdctl --endpoints="http://127.0.0.1:2379" role add apisix'); +system('etcdctl --endpoints="http://127.0.0.1:2379" user grant-role apisix apisix'); +system('etcdctl --endpoints=http://127.0.0.1:2379 role grant-permission apisix --prefix=true readwrite /apisix/'); system('etcdctl --endpoints="http://127.0.0.1:2379" auth enable'); run_tests; @@ -40,7 +45,8 @@ run_tests; system('etcdctl --endpoints="http://127.0.0.1:2379" --user root:5tHkHhYkjr6cQY auth disable'); system('etcdctl --endpoints="http://127.0.0.1:2379" user delete root'); system('etcdctl --endpoints="http://127.0.0.1:2379" role delete root'); - +system('etcdctl --endpoints="http://127.0.0.1:2379" user delete apisix'); +system('etcdctl --endpoints="http://127.0.0.1:2379" role delete apisix'); __DATA__ === TEST 1: Set and Get a value pass @@ -59,3 +65,28 @@ GET /t --- error_code: 500 --- error_log eval qr /insufficient credentials code: 401/ + + + +=== TEST 2: etcd grants permissions with a different prefix than the one used by apisix, etcd will forbidden +--- config + location /t { + content_by_lua_block { + local core = require("apisix.core") + local key = "/test_key" + local val = "test_value" + local res, err = core.etcd.set(key, val) + ngx.say(err) + } + } +--- yaml_config +etcd: + host: + - "http://127.0.0.1:2379" + prefix: "/apisix" + user: apisix + password: abc123 +--- request +GET /t +--- error_log eval +qr /etcd forbidden code: 403/ diff --git a/t/core/etcd-auth.t b/t/core/etcd-auth.t index e83fb9cf..f2f322db 100644 --- a/t/core/etcd-auth.t +++ b/t/core/etcd-auth.t @@ -32,6 +32,11 @@ system('etcdctl --endpoints="http://127.0.0.1:2379" role add root'); system('etcdctl --endpoints="http://127.0.0.1:2379" user grant-role root root'); system('etcdctl --endpoints="http://127.0.0.1:2379" role list'); system('etcdctl --endpoints="http://127.0.0.1:2379" user user list'); +# Grant the user access to the specified directory +system('etcdctl --endpoints="http://127.0.0.1:2379" user add apisix:abc123'); +system('etcdctl --endpoints="http://127.0.0.1:2379" role add apisix'); +system('etcdctl --endpoints="http://127.0.0.1:2379" user grant-role apisix apisix'); +system('etcdctl --endpoints=http://127.0.0.1:2379 role grant-permission apisix --prefix=true readwrite /apisix'); system('etcdctl --endpoints="http://127.0.0.1:2379" auth enable'); run_tests; @@ -40,6 +45,8 @@ run_tests; system('etcdctl --endpoints="http://127.0.0.1:2379" --user root:5tHkHhYkjr6cQY auth disable'); system('etcdctl --endpoints="http://127.0.0.1:2379" user delete root'); system('etcdctl --endpoints="http://127.0.0.1:2379" role delete root'); +system('etcdctl --endpoints="http://127.0.0.1:2379" user delete apisix'); +system('etcdctl --endpoints="http://127.0.0.1:2379" role delete apisix'); __DATA__ @@ -63,3 +70,28 @@ GET /t test_value --- no_error_log [error] + + + +=== TEST 2: etcd grants permissions with the same prefix as apisix uses, etcd is normal +--- config + location /t { + content_by_lua_block { + local core = require("apisix.core") + local key = "/test_key" + local val = "test_value" + local res, err = core.etcd.set(key, val) + ngx.say(err) + } + } +--- yaml_config +etcd: + host: + - "http://127.0.0.1:2379" + prefix: "/apisix" + user: apisix + password: abc123 +--- request +GET /t +--- no_error_log +[error]