From 206433ac9c621222a76da45096b7473f13897584 Mon Sep 17 00:00:00 2001 From: Thibault Charbonnier Date: Mon, 19 Mar 2018 10:51:29 -0700 Subject: [PATCH] feat(cache) use a different shm for cache misses Following this mlcache patch: https://github.com/thibaultcha/lua-resty-mlcache/pull/42 We can now specify a different shm for mlcache to cache L3 misses. This is especially helpful in the context of Kong since client-triggered DB lookups can have a very high cardinality of keys to fetch (e.g. credentials such as API keys) and can make the cache turnover so high that it can be rendered almost useless (filled with misses, thus evicting actual hits from the cache shm). This is considered as a potential attack vector. The size of this shm (12MB) allows for roughly ~45,000 nil sentinel values to be stored in the shm (depending on the size of the keys). This value is aligned with that chosen for the rate-limiting shared dict in PR #3311 (12MB and about ~48,000 simultaneous counters). --- kong/cache.lua | 5 +++-- kong/constants.lua | 3 ++- kong/templates/nginx_kong.lua | 3 ++- spec/01-unit/003-prefix_handler_spec.lua | 2 +- spec/fixtures/custom_nginx.template | 3 ++- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/kong/cache.lua b/kong/cache.lua index cf66b5b14e9d..dbee118d4629 100644 --- a/kong/cache.lua +++ b/kong/cache.lua @@ -10,7 +10,7 @@ local NOTICE = ngx.NOTICE local DEBUG = ngx.DEBUG -local SHM_CACHE = "kong_cache" +local SHM_CACHE = "kong_db_cache" --[[ Hypothesis ---------- @@ -69,7 +69,8 @@ function _M.new(opts) return error("opts.resty_lock_opts must be a table") end - local mlcache, err = resty_mlcache.new("kong_db_cache", SHM_CACHE, { + local mlcache, err = resty_mlcache.new(SHM_CACHE, SHM_CACHE, { + shm_miss = "kong_db_cache_miss", lru_size = LRU_SIZE, ttl = max(opts.ttl or 3600, 0), neg_ttl = max(opts.neg_ttl or 300, 0), diff --git a/kong/constants.lua b/kong/constants.lua index afcedece88aa..2b0e07daa258 100644 --- a/kong/constants.lua +++ b/kong/constants.lua @@ -78,7 +78,8 @@ return { }, DICTS = { "kong", - "kong_cache", + "kong_db_cache", + "kong_db_cache_miss", "kong_process_events", "kong_cluster_events", "kong_healthchecks", diff --git a/kong/templates/nginx_kong.lua b/kong/templates/nginx_kong.lua index 52d519761564..cee3a59f92f3 100644 --- a/kong/templates/nginx_kong.lua +++ b/kong/templates/nginx_kong.lua @@ -29,7 +29,8 @@ lua_socket_pool_size ${{LUA_SOCKET_POOL_SIZE}}; lua_max_running_timers 4096; lua_max_pending_timers 16384; lua_shared_dict kong 5m; -lua_shared_dict kong_cache ${{MEM_CACHE_SIZE}}; +lua_shared_dict kong_db_cache ${{MEM_CACHE_SIZE}}; +lua_shared_dict kong_db_cache_miss 12m; lua_shared_dict kong_process_events 5m; lua_shared_dict kong_cluster_events 5m; lua_shared_dict kong_healthchecks 5m; diff --git a/spec/01-unit/003-prefix_handler_spec.lua b/spec/01-unit/003-prefix_handler_spec.lua index 7ea74d435ab2..37790ab7c135 100644 --- a/spec/01-unit/003-prefix_handler_spec.lua +++ b/spec/01-unit/003-prefix_handler_spec.lua @@ -69,7 +69,7 @@ describe("NGINX conf compiler", function() admin_listen = "127.0.0.1:8001" })) local kong_nginx_conf = prefix_handler.compile_kong_conf(conf) - assert.matches("lua_shared_dict kong_cache%s+128k;", kong_nginx_conf) + assert.matches("lua_shared_dict kong_db_cache%s+128k;", kong_nginx_conf) assert.matches("listen 0.0.0.0:80;", kong_nginx_conf, nil, true) assert.matches("listen 127.0.0.1:8001;", kong_nginx_conf, nil, true) end) diff --git a/spec/fixtures/custom_nginx.template b/spec/fixtures/custom_nginx.template index 60c066800ed6..e5c93c150189 100644 --- a/spec/fixtures/custom_nginx.template +++ b/spec/fixtures/custom_nginx.template @@ -42,7 +42,8 @@ http { lua_max_running_timers 4096; lua_max_pending_timers 16384; lua_shared_dict kong 5m; - lua_shared_dict kong_cache ${{MEM_CACHE_SIZE}}; + lua_shared_dict kong_db_cache ${{MEM_CACHE_SIZE}}; + lua_shared_dict kong_db_cache_miss 12m; lua_shared_dict kong_process_events 5m; lua_shared_dict kong_cluster_events 5m; lua_shared_dict kong_healthchecks 5m;