From a505f88b7555cee737a98363896ad30eb3082323 Mon Sep 17 00:00:00 2001 From: "felipe.lisboa" Date: Thu, 8 Jun 2017 14:39:18 -0300 Subject: [PATCH] feature: added support for 80 bytes key --- .travis.yml | 111 ++++++++++++ README.md | 4 + lualib/ngx/ssl/session/ticket.lua | 11 +- .../ngx/ssl/session/ticket/key_rotation.lua | 12 +- src/ngx_http_lua_ssl_module.c | 62 +++++-- t/cert/dummy-48.key | 1 + t/cert/dummy-80.key | 1 + t/cert/test.crt | 35 ++++ t/cert/test.key | 52 ++++++ t/sanity.t | 160 ++++++++++++++++++ util/build.sh | 3 +- 11 files changed, 429 insertions(+), 23 deletions(-) create mode 100644 .travis.yml create mode 100644 t/cert/dummy-48.key create mode 100644 t/cert/dummy-80.key create mode 100644 t/cert/test.crt create mode 100644 t/cert/test.key create mode 100644 t/sanity.t diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..fda4372 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,111 @@ +dist: bionic + +branches: + only: + - "master" + +os: linux + +language: c + +compiler: + - gcc + +addons: + apt: + packages: + - ack + - axel + - cpanminus + - libtest-base-perl + - libtext-diff-perl + - liburi-perl + - libwww-perl + - libtest-longstring-perl + - liblist-moreutils-perl + +cache: + directories: + - download-cache + +env: + global: + - JOBS=3 + - NGX_BUILD_JOBS=$JOBS + - LUAJIT_PREFIX=/opt/luajit21 + - LUAJIT_LIB=$LUAJIT_PREFIX/lib + - LUAJIT_INC=$LUAJIT_PREFIX/include/luajit-2.1 + - LUA_INCLUDE_DIR=$LUAJIT_INC + - PCRE_VER=8.45 + - PCRE_PREFIX=/opt/pcre + - PCRE_LIB=$PCRE_PREFIX/lib + - PCRE_INC=$PCRE_PREFIX/include + - OPENSSL_PREFIX=/opt/ssl + - OPENSSL_LIB=$OPENSSL_PREFIX/lib + - OPENSSL_INC=$OPENSSL_PREFIX/include + - LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH + - TEST_NGINX_SLEEP=0.006 + jobs: + - NGINX_VERSION=1.21.4 OPENSSL_VER=1.1.1s OPENSSL_PATCH_VER=1.1.1f + +before_install: + - sudo apt update + - sudo apt install --only-upgrade ca-certificates + - '! grep -n -P ''(?<=.{80}).+'' --color `find src -name ''*.c''` `find . -name ''*.h''` || (echo "ERROR: Found C source lines exceeding 80 columns." > /dev/stderr; exit 1)' + - '! grep -n -P ''\t+'' --color `find src -name ''*.c''` `find . -name ''*.h''` || (echo "ERROR: Cannot use tabs." > /dev/stderr; exit 1)' + - /usr/bin/env perl $(command -v cpanm) --sudo --notest Test::Nginx IPC::Run > build.log 2>&1 || (cat build.log && exit 1) + - pyenv global 2.7 +install: + - if [ ! -f download-cache/pcre-$PCRE_VER.tar.gz ]; then wget -P download-cache https://downloads.sourceforge.net/project/pcre/pcre/${PCRE_VER}/pcre-${PCRE_VER}.tar.gz; fi + - if [ ! -f download-cache/openssl-$OPENSSL_VER.tar.gz ]; then wget -P download-cache https://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz || wget -P download-cache https://www.openssl.org/source/old/${OPENSSL_VER//[a-z]/}/openssl-$OPENSSL_VER.tar.gz; fi + - git clone https://github.com/openresty/test-nginx.git + - git clone https://github.com/openresty/openresty.git ../openresty + - git clone https://github.com/openresty/no-pool-nginx.git ../no-pool-nginx + - git clone https://github.com/openresty/openresty-devel-utils.git + - git clone https://github.com/openresty/mockeagain.git + - git clone https://github.com/openresty/lua-resty-lock ../lua-resty-lock + - git clone https://github.com/openresty/lua-resty-memcached ../lua-resty-memcached + - git clone https://github.com/openresty/lua-resty-memcached-shdict ../lua-resty-memcached-shdict + - git clone https://github.com/openresty/lua-resty-shdict-simple ../lua-resty-shdict-simple + - git clone https://github.com/openresty/echo-nginx-module.git ../echo-nginx-module + - git clone https://github.com/openresty/nginx-eval-module.git ../nginx-eval-module + - git clone https://github.com/simpl/ngx_devel_kit.git ../ndk-nginx-module + - git clone https://github.com/FRiCKLE/ngx_coolkit.git ../coolkit-nginx-module + - git clone https://github.com/openresty/set-misc-nginx-module.git ../set-misc-nginx-module + - git clone https://github.com/openresty/lua-resty-core.git ../lua-resty-core + - git clone https://github.com/openresty/lua-resty-lrucache.git ../lua-resty-lrucache + - git clone https://github.com/spacewander/lua-resty-rsa.git ../lua-resty-rsa + - git clone https://github.com/openresty/lua-resty-string.git ../lua-resty-string + - git clone https://github.com/openresty/lua-nginx-module.git ../lua-nginx-module + - git clone -b v2.1-agentzh https://github.com/openresty/luajit2.git luajit2 + +script: + - export PATH=$PWD/work/nginx/sbin:$PWD/openresty-devel-utils:$PATH + - ngx-releng > check.txt || true + - lines=`wc -l check.txt | awk '{print $1}'`; if [ $lines -gt 5 ]; then cat check.txt; exit 1; fi + - sudo sysctl -w kernel.pid_max=10000 + - cd luajit2/ + - make -j$JOBS CCDEBUG=-g Q= PREFIX=$LUAJIT_PREFIX CC=$CC XCFLAGS='-DLUA_USE_APICHECK -DLUA_USE_ASSERT -msse4.2' > build.log 2>&1 || (cat build.log && exit 1) + - sudo make install PREFIX=$LUAJIT_PREFIX > build.log 2>&1 || (cat build.log && exit 1) + - cd ../mockeagain/ && make CC=$CC -j$JOBS && cd .. + - tar zxf download-cache/pcre-$PCRE_VER.tar.gz + - cd pcre-$PCRE_VER/ + - ./configure --prefix=$PCRE_PREFIX --enable-jit --enable-utf --enable-unicode-properties > build.log 2>&1 || (cat build.log && exit 1) + - make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1) + - sudo PATH=$PATH make install > build.log 2>&1 || (cat build.log && exit 1) + - cd .. + - tar zxf download-cache/openssl-$OPENSSL_VER.tar.gz + - cd openssl-$OPENSSL_VER/ + - patch -p1 < ../../openresty/patches/openssl-$OPENSSL_PATCH_VER-sess_set_get_cb_yield.patch + - ./config shared enable-ssl3 enable-ssl3-method -g --prefix=$OPENSSL_PREFIX -DPURIFY > build.log 2>&1 || (cat build.log && exit 1) + - make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1) + - sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1) + - cd .. + - export NGX_BUILD_CC=$CC + - sh util/build.sh $NGINX_VERSION > build.log 2>&1 || (cat build.log && exit 1) + - nginx -V + - ldd `which nginx`|grep -E 'luajit|ssl|pcre' + - export LD_PRELOAD=$PWD/mockeagain/mockeagain.so + - export LD_LIBRARY_PATH=$PWD/mockeagain:$LD_LIBRARY_PATH + - export TEST_NGINX_RESOLVER=8.8.4.4 + - /usr/bin/env perl $(command -v prove) -I. -Itest-nginx/lib -r t/ diff --git a/README.md b/README.md index a36e527..051bd17 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,9 @@ http { memc_conn_max_idle_time = 1 * 1000, -- in ms, for in-pool connections, -- optional, default to nil + key_length = 48 -- in bytes, optional, default 48, possible 80 if using with + -- nginx > 1.12.0, any other values it will + -- fallback to default length } } @@ -61,6 +64,7 @@ http { # Put a dummy key to trigger external ticket key usage in nginx/OpenSSL # init_by_lua* will replace this dummy key with existing cached keys # or a random key if cached keys are not available. + # If key_length was set to 80 bytes in init_by_lua*, the dummy key needs to be 80 bytes too. ssl_session_ticket_key dummy.key; ... diff --git a/lualib/ngx/ssl/session/ticket.lua b/lualib/ngx/ssl/session/ticket.lua index d85cb3b..86ca992 100644 --- a/lualib/ngx/ssl/session/ticket.lua +++ b/lualib/ngx/ssl/session/ticket.lua @@ -23,9 +23,10 @@ ffi.cdef[[ int ngx_http_lua_ffi_get_ssl_ctx_count(void); int ngx_http_lua_ffi_get_ssl_ctx_list(void **buf); int ngx_http_lua_ffi_update_ticket_encryption_key(void *ctx, - const unsigned char *key, unsigned int nkeys, char **err); + const unsigned char *key, const unsigned int nkeys, + const unsigned int key_length, char **err); int ngx_http_lua_ffi_update_last_ticket_decryption_key(void *ctx, - const unsigned char *key, char **err); + const unsigned char *key, const unsigned int key_length, char **err); ]] @@ -61,7 +62,7 @@ function _M.update_ticket_encryption_key(key, nkeys) -- OpenSSL session ticket key is 48 bytes. -- key structure: -- 16 bytes key name, 16 bytes AES key, 16 bytes HMAC key. - if not key or #key ~= 48 then + if not key or (#key ~= 48 and #key ~= 80) then return nil, 'invalid ticket key' end @@ -69,6 +70,7 @@ function _M.update_ticket_encryption_key(key, nkeys) local rc = C.ngx_http_lua_ffi_update_ticket_encryption_key(ctx, key, nkeys, + #key, errmsg) if rc ~= 0 then -- not NGX_OK return nil, ffi_str(errmsg[0]) @@ -88,13 +90,14 @@ function _M.update_last_ticket_decryption_key(key) end -- OpenSSL session ticket key is 48 bytes. - if not key or #key ~= 48 then + if not key or (#key ~= 48 and #key ~= 80) then return nil, 'invalid ticket key' end for _, ctx in ipairs(ctxs) do local rc = C.ngx_http_lua_ffi_update_last_ticket_decryption_key(ctx, key, + #key, errmsg) if rc ~= 0 then -- not NGX_OK return nil, ffi_str(errmsg[0]) diff --git a/lualib/ngx/ssl/session/ticket/key_rotation.lua b/lualib/ngx/ssl/session/ticket/key_rotation.lua index a5b8431..5e3817f 100644 --- a/lualib/ngx/ssl/session/ticket/key_rotation.lua +++ b/lualib/ngx/ssl/session/ticket/key_rotation.lua @@ -99,7 +99,7 @@ local function shdict_get_and_decrypt(ctx, idx) -- Ideally we should protect the ticket key with some encryption. -- key = decrypt(key, key_encryption_key) - if #key ~= 48 then + if #key ~= 48 and #key ~= 80 then return fail("malformed key: #key ", #key) end @@ -132,7 +132,7 @@ local function memc_get_and_decrypt(ctx, idx, offset) -- Ideally we should protect the ticket key with some encryption. -- key = decrypt(key, key_encryption_key) - if #key ~= 48 then + if #key ~= 48 and #key ~= 80 then return fail("malformed key: #key ", #key) end @@ -256,8 +256,14 @@ function _M.init(opts) local memc_conn_max_idle_time = opts.memc_conn_max_idle_time + local key_length = opts.key_length + local frandom = assert(io.open("/dev/urandom", "rb")) - fallback_random_key = frandom:read(48) + -- if key_length is not set or is different from 48 or 80, use default 48 bytes + if not key_length or (key_length ~= 48 and key_length ~= 80) then + key_length = 48 + end + fallback_random_key = frandom:read(key_length) frandom:close() nkeys = floor(ticket_ttl / time_slot) + 2 diff --git a/src/ngx_http_lua_ssl_module.c b/src/ngx_http_lua_ssl_module.c index e33eded..7b07c96 100644 --- a/src/ngx_http_lua_ssl_module.c +++ b/src/ngx_http_lua_ssl_module.c @@ -183,7 +183,8 @@ ngx_http_lua_ffi_get_ssl_ctx_list(SSL_CTX **buf) int ngx_http_lua_ffi_update_ticket_encryption_key(SSL_CTX *ctx, - const unsigned char *key, const ngx_uint_t nkeys, char **err) + const unsigned char *key, const ngx_uint_t nkeys, + const unsigned int key_length, char **err) { #ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB @@ -226,12 +227,25 @@ ngx_http_lua_ffi_update_ticket_encryption_key(SSL_CTX *ctx, * key. */ if (keys->nelts > 0) { pkey = keys->elts; - if (ngx_memcmp(pkey->name, key, 16) == 0 - && ngx_memcmp(pkey->aes_key, key + 16, 16) == 0 - && ngx_memcmp(pkey->hmac_key, key + 32, 16) == 0) - { - dd("duplicate ticket key"); - return NGX_OK; + if (key_length == 48) { + dd("key size is 48"); + if (ngx_memcmp(pkey->name, key, 16) == 0 + && ngx_memcmp(pkey->aes_key, key + 16, 16) == 0 + && ngx_memcmp(pkey->hmac_key, key + 32, 16) == 0) + { + dd("duplicate ticket key"); + return NGX_OK; + } + + } else if (key_length == 80) { + dd("key size is 80"); + if (ngx_memcmp(pkey->name, key, 16) == 0 + && ngx_memcmp(pkey->aes_key, key + 16, 32) == 0 + && ngx_memcmp(pkey->hmac_key, key + 48, 32) == 0) + { + dd("duplicate ticket key"); + return NGX_OK; + } } } @@ -255,13 +269,23 @@ ngx_http_lua_ffi_update_ticket_encryption_key(SSL_CTX *ctx, } /* copy the new key */ - ngx_memcpy(pkey->name, key, 16); - ngx_memcpy(pkey->aes_key, key + 16, 16); - ngx_memcpy(pkey->hmac_key, key + 32, 16); + if (key_length == 48) { + ngx_memcpy(pkey->name, key, 16); + ngx_memcpy(pkey->aes_key, key + 16, 16); + ngx_memcpy(pkey->hmac_key, key + 32, 16); #if (nginx_version >= 1011008) pkey->size = 48; #endif + } else if (key_length == 80) { + ngx_memcpy(pkey->name, key, 16); + ngx_memcpy(pkey->aes_key, key + 16, 32); + ngx_memcpy(pkey->hmac_key, key + 48, 32); +#if (nginx_version >= 1011008) + pkey->size = 80; +#endif + } + return NGX_OK; #else @@ -275,7 +299,7 @@ ngx_http_lua_ffi_update_ticket_encryption_key(SSL_CTX *ctx, int ngx_http_lua_ffi_update_last_ticket_decryption_key(SSL_CTX *ctx, - const unsigned char *key, char **err) + const unsigned char *key, const unsigned int key_length, char **err) { ngx_array_t *keys; ngx_ssl_session_ticket_key_t *pkey; @@ -306,13 +330,23 @@ ngx_http_lua_ffi_update_last_ticket_decryption_key(SSL_CTX *ctx, pkey = &pkey[keys->nelts - 1]; dd("replace the last key"); - ngx_memcpy(pkey->name, key, 16); - ngx_memcpy(pkey->aes_key, key + 16, 16); - ngx_memcpy(pkey->hmac_key, key + 32, 16); + if (key_length == 48) { + ngx_memcpy(pkey->name, key, 16); + ngx_memcpy(pkey->aes_key, key + 16, 16); + ngx_memcpy(pkey->hmac_key, key + 32, 16); #if (nginx_version >= 1011008) pkey->size = 48; #endif + } else if (key_length == 80) { + ngx_memcpy(pkey->name, key, 16); + ngx_memcpy(pkey->aes_key, key + 16, 32); + ngx_memcpy(pkey->hmac_key, key + 48, 32); +#if (nginx_version >= 1011008) + pkey->size = 80; +#endif + } + return NGX_OK; #else diff --git a/t/cert/dummy-48.key b/t/cert/dummy-48.key new file mode 100644 index 0000000..91612c2 --- /dev/null +++ b/t/cert/dummy-48.key @@ -0,0 +1 @@ +׎�"��~���w�-L�W8�_a�.چE�J��7"�Y��7�Z��y�m��ٗ \ No newline at end of file diff --git a/t/cert/dummy-80.key b/t/cert/dummy-80.key new file mode 100644 index 0000000..5a349f0 --- /dev/null +++ b/t/cert/dummy-80.key @@ -0,0 +1 @@ +��h�Vl|S��+����m��ԋ�L*��:����fiHc���c.}��9/O'P����H��ɩ�E3 ]�x$��񝥂��` \ No newline at end of file diff --git a/t/cert/test.crt b/t/cert/test.crt new file mode 100644 index 0000000..bfcc567 --- /dev/null +++ b/t/cert/test.crt @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIGETCCA/mgAwIBAgIUE3pqyVuRQL+qGuSFAUCLq4g7pt4wDQYJKoZIhvcNAQEL +BQAwgZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH +DA1TYW4gRnJhbmNpc2NvMRIwEAYDVQQKDAlPcGVuUmVzdHkxEjAQBgNVBAsMCU9w +ZW5SZXN0eTERMA8GA1UEAwwIdGVzdC5jb20xIDAeBgkqhkiG9w0BCQEWEWFnZW50 +emhAZ21haWwuY29tMB4XDTIyMDUyOTA2MTk1N1oXDTMyMDUyNjA2MTk1N1owgZcx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4g +RnJhbmNpc2NvMRIwEAYDVQQKDAlPcGVuUmVzdHkxEjAQBgNVBAsMCU9wZW5SZXN0 +eTERMA8GA1UEAwwIdGVzdC5jb20xIDAeBgkqhkiG9w0BCQEWEWFnZW50emhAZ21h +aWwuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyLzMbnMBcxYB +2W0uEqPKo2lOJdUQTnakipVLqRvZIJv7NkZgU76pxdFwoSxPpvJcpJ4rsosBZvhV +dkGoKmuVfIFU0lYcdaccq88aT7E9XfTXiiyB2tkT6jS6wr+QxDj7KW47zdUBUT9O +6ClNyY2o1gZldElTG0Bwk4j2sAkXuWGmyncTOJ4ge3mWVksAQYbL5pwfdfyqgDmK +B4nLJHBkorLbF7nm7pK2HzQCtaEUJpQKpJdCULcOHrydjVAwHUQsZAb9XXjQWPTb +A0BSplbgMSI6saT9uA2RjLBzpYKj8J1rWGadWteSyQAf6XooQrquTPuR+OWF6t/m +2vkTcJlh1ukPPAPZBvlAQX9VSLWk5fmAQZA5BxYXNVWcMGVNO7UtilRmjqK1nCmv +oyDXHzpE5RZPBZH4ecOqTscUgmS72ItPGWMtEtCQYbzWyMAa1cpCvK40YRa4814r +XgffWgWJQfqyVvRjzpWIUiqwjUX3/p3W3pxX/GNHOv2ZH/pebcODOl7EFxzv5eQc +z9vW5+RfiCSzs5bGG7qw58dMFROeAJbwR6t2o6GRd0HfgTTwSDcrrpcdLP/PaL+v +twnrNa9r7rIwXnDWxYo3KiGpqEfG2WwW+lJsUzZOi9eI9kYPyvFmNFLugZbHMi+h +ICCb8AQB2thON5X4N7FtP5GVfMR9vIkCAwEAAaNTMFEwHQYDVR0OBBYEFDEy866N +WPHPTJKeL/96VYoczkINMB8GA1UdIwQYMBaAFDEy866NWPHPTJKeL/96VYoczkIN +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAHJgyS6/OyRqzqwd ++6DnntGV+MTo9WBNvNs/fekJghnrr85oG330GasYENQLi0wF20to7FMan2U9kwgV +cbhDwe70JD0jg8htYof/uXOMBVWT4iZ+eXn60mP3iLsSutwt/drXBBzbxMYbUC12 +CIiadkV8aMPIN6oGnF7TLF4AvBqYYp2qAVGXr/ZQm3L7NPB0jkSktSe6obnaq1tO +ug18ImhzAqkn1UGnLRiTADOba5HuKtovwWtLblNBODdnv1E7IK1A6jpqwiYjlbU5 +4v9ZzFzEJw+GqYHkTRmJGCA2Uw7HNEUFeno1BTp19Ce9fvrkofTWYmLp/NAvEp6E +aFnBdCjY4tWzI2Iig7IjDIM7F6igGODybeN9ijD7oSyEDtNE7ECLSuXhgekiQJ8c +NYALgbbNPxWx8zJcNiYy1NDYdIjO5vYFOpbn+rQObKVCX/X+Al9fT126ciTT1xAF +fZtkGPpp3Wjgws9UDSzetvWHYt0Rs70m351LFPHyR4tQLHoDFqnA2buG/mSvKZ9U +to0JQ/8QPRIYv0FUJcF0+/xQRYrIqvmjiCpfL2hwJyRViq7f8z0/tmMoLxFlPo/k +GC+gvh3WwTB622h9JEqS48lllcYZIQWOX2mbFtUtNFdzUtSRmZMa8RmcYr5So2OH +9QLIIjC6ntPFjWq+uLJAJ8uazRt7 +-----END CERTIFICATE----- diff --git a/t/cert/test.key b/t/cert/test.key new file mode 100644 index 0000000..0c07e06 --- /dev/null +++ b/t/cert/test.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +jxLWsmKbkVA5hFln8GPxs6EqfqOJhkM= +-----END PRIVATE KEY----- diff --git a/t/sanity.t b/t/sanity.t new file mode 100644 index 0000000..ae88977 --- /dev/null +++ b/t/sanity.t @@ -0,0 +1,160 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: + +use Test::Nginx::Socket::Lua; + +repeat_each(1); + +plan tests => repeat_each() * (blocks() * 3); + +no_shuffle(); +no_long_string(); + +our $pwd = `pwd`; +chomp $pwd; + +our $HtmlDir = html_dir; + +$ENV{TEST_NGINX_HTML_DIR} = $HtmlDir; +$ENV{TEST_NGINX_PWD} ||= $pwd; + +run_tests(); + +__DATA__ + +=== TEST 1: 48 bit key +--- http_config + lua_shared_dict my_cache 10m; + lua_shared_dict locks 1m; + lua_package_path '$TEST_NGINX_PWD/../lua-resty-lock/lib/?.lua;$TEST_NGINX_PWD/../lua-resty-memcached/lib/?.lua;$TEST_NGINX_PWD/../lua-resty-memcached-shdict/lib/?.lua;$TEST_NGINX_PWD/../lua-resty-shdict-simple/lib/?.lua;$TEST_NGINX_PWD/../lua-resty-core/lib/?.lua;$TEST_NGINX_PWD/lualib/?.lua;;'; + + init_by_lua_block { + require("ngx.ssl.session.ticket.key_rotation").init{ + locks_shdict_name = "locks", + + disable_shm_cache = false, -- default false + cache_shdict_name = "my_cache", + shm_cache_positive_ttl = 24 * 3600 * 1000, -- in ms + shm_cache_negative_ttl = 0, -- in ms + + ticket_ttl = 24 * 3600, -- in sec + key_rotation_period = 3600, -- in sec + + memc_key_prefix = "ticket-key/", + + memc_host = "127.0.0.1", + memc_port = 11211, + memc_timeout = 500, -- in ms + memc_conn_pool_size = 1, + memc_fetch_retries = 1, -- optional, default 1 + memc_fetch_retry_delay = 100, -- in ms, optional, default to 100 (ms) + + memc_conn_max_idle_time = 1 * 1000, -- in ms, for in-pool connections, + -- optional, default to nil + key_length = 48 -- in bytes, optional, default 48, possible 80 if using with + -- nginx > 1.12.0, any other values it will + -- fallback to default length + } + } + + init_worker_by_lua_block { + require("ngx.ssl.session.ticket.key_rotation").start_update_timer() + } + + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name test.com; + ssl_client_hello_by_lua_block { print("ssl client hello by lua is running!") } + ssl_certificate ../../cert/test.crt; + ssl_certificate_key ../../cert/test.key; + ssl_session_ticket_key ../../cert/dummy-48.key; + + server_tokens off; + location /foo { + default_type 'text/plain'; + content_by_lua_block { ngx.status = 201 ngx.say("foo") ngx.exit(201) } + } + } + +--- config + location = /t { + content_by_lua_block { + ngx.say("Hello world") + } + } +--- request +GET /t +--- response_body +Hello world +--- timeout: 10 +--- error_log +unable to get current key from memc; use backup random key + + + +=== TEST 2: 80 bit key +--- http_config + lua_shared_dict my_cache 10m; + lua_shared_dict locks 1m; + lua_package_path '$TEST_NGINX_PWD/../lua-resty-lock/lib/?.lua;$TEST_NGINX_PWD/../lua-resty-memcached/lib/?.lua;$TEST_NGINX_PWD/../lua-resty-memcached-shdict/lib/?.lua;$TEST_NGINX_PWD/../lua-resty-shdict-simple/lib/?.lua;$TEST_NGINX_PWD/../lua-resty-core/lib/?.lua;$TEST_NGINX_PWD/lualib/?.lua;;'; + + init_by_lua_block { + require("ngx.ssl.session.ticket.key_rotation").init{ + locks_shdict_name = "locks", + + disable_shm_cache = false, -- default false + cache_shdict_name = "my_cache", + shm_cache_positive_ttl = 24 * 3600 * 1000, -- in ms + shm_cache_negative_ttl = 0, -- in ms + + ticket_ttl = 24 * 3600, -- in sec + key_rotation_period = 3600, -- in sec + + memc_key_prefix = "ticket-key/", + + memc_host = "127.0.0.1", + memc_port = 11211, + memc_timeout = 500, -- in ms + memc_conn_pool_size = 1, + memc_fetch_retries = 1, -- optional, default 1 + memc_fetch_retry_delay = 100, -- in ms, optional, default to 100 (ms) + + memc_conn_max_idle_time = 1 * 1000, -- in ms, for in-pool connections, + -- optional, default to nil + key_length = 80 -- in bytes, optional, default 48, possible 80 if using with + -- nginx > 1.12.0, any other values it will + -- fallback to default length + } + } + + init_worker_by_lua_block { + require("ngx.ssl.session.ticket.key_rotation").start_update_timer() + } + + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name test.com; + ssl_client_hello_by_lua_block { print("ssl client hello by lua is running!") } + ssl_certificate ../../cert/test.crt; + ssl_certificate_key ../../cert/test.key; + ssl_session_ticket_key ../../cert/dummy-80.key; + + server_tokens off; + location /foo { + default_type 'text/plain'; + content_by_lua_block { ngx.status = 201 ngx.say("foo") ngx.exit(201) } + } + } + +--- config + location = /t { + content_by_lua_block { + ngx.say("Hello world") + } + } +--- request +GET /t +--- response_body +Hello world +--- timeout: 10 +--- error_log +unable to get current key from memc; use backup random key diff --git a/util/build.sh b/util/build.sh index 50ea5d1..fd24709 100755 --- a/util/build.sh +++ b/util/build.sh @@ -10,10 +10,9 @@ home=~ #--with-cc=gcc46 \ ngx-build $force $version \ - --with-ld-opt="-L$PCRE_LIB -Wl,-rpath,$PCRE_LIB:$LIBDRIZZLE_LIB:/usr/local/lib" \ + --with-ld-opt="-L$PCRE_LIB -Wl,-rpath,$PCRE_LIB:/usr/local/lib" \ --with-cc-opt="-DDEBUG_MALLOC" \ --with-http_stub_status_module \ - --with-http_image_filter_module \ --with-http_ssl_module \ --without-mail_pop3_module \ --without-mail_imap_module \