Make certificate cache size configurable

This commit is contained in:
Dayang Shen 2022-03-20 14:29:26 +08:00
parent 8ab1a31daf
commit 08694cc9de
5 changed files with 28 additions and 14 deletions

View file

@ -95,6 +95,7 @@ The following table shows a configuration option's name, type, and the default v
|[ssl-session-ticket-key](#ssl-session-ticket-key)|string|`<Randomly Generated>`| |[ssl-session-ticket-key](#ssl-session-ticket-key)|string|`<Randomly Generated>`|
|[ssl-session-timeout](#ssl-session-timeout)|string|"10m"|| |[ssl-session-timeout](#ssl-session-timeout)|string|"10m"||
|[ssl-buffer-size](#ssl-buffer-size)|string|"4k"|| |[ssl-buffer-size](#ssl-buffer-size)|string|"4k"||
|[ssl-certificate-cache-size](#ssl-certificate-cache-size)|int|1000|
|[use-proxy-protocol](#use-proxy-protocol)|bool|"false"|| |[use-proxy-protocol](#use-proxy-protocol)|bool|"false"||
|[proxy-protocol-header-timeout](#proxy-protocol-header-timeout)|string|"5s"|| |[proxy-protocol-header-timeout](#proxy-protocol-header-timeout)|string|"5s"||
|[enable-aio-write](#enable-aio-write)|bool|"true"|| |[enable-aio-write](#enable-aio-write)|bool|"true"||
@ -701,6 +702,14 @@ Sets the size of the [SSL buffer](https://nginx.org/en/docs/http/ngx_http_ssl_mo
_References:_ _References:_
[https://www.igvita.com/2013/12/16/optimizing-nginx-tls-time-to-first-byte/](https://www.igvita.com/2013/12/16/optimizing-nginx-tls-time-to-first-byte/) [https://www.igvita.com/2013/12/16/optimizing-nginx-tls-time-to-first-byte/](https://www.igvita.com/2013/12/16/optimizing-nginx-tls-time-to-first-byte/)
## ssl-certificate-cache-size
Sets the size of cache that stores parsed SSL certificate objects.
The cache helps reduce memory consumption of SSL context per connection. Increase the value if you have huge amount of certificates.
_**default:**_ is 1000.
## use-proxy-protocol ## use-proxy-protocol
Enables or disables the [PROXY protocol](https://www.nginx.com/resources/admin-guide/proxy-protocol/) to receive client connection (real IP address) information passed through proxy servers and load balancers such as HAProxy and Amazon Elastic Load Balancer (ELB). Enables or disables the [PROXY protocol](https://www.nginx.com/resources/admin-guide/proxy-protocol/) to receive client connection (real IP address) information passed through proxy servers and load balancers such as HAProxy and Amazon Elastic Load Balancer (ELB).

View file

@ -413,6 +413,10 @@ type Configuration struct {
// Default: false // Default: false
SSLRejectHandshake bool `json:"ssl-reject-handshake"` SSLRejectHandshake bool `json:"ssl-reject-handshake"`
// Sets the size of cache that stores parsed SSL certificate objects.
// The cache helps reduce memory consumption of SSL context per connection.
SSLCertificateCacheSize int `json:"ssl-certificate-cache-size,omitempty"`
// Enables or disables the use of the PROXY protocol to receive client connection // Enables or disables the use of the PROXY protocol to receive client connection
// (real IP address) information passed through proxy servers and load balancers // (real IP address) information passed through proxy servers and load balancers
// such as HAproxy and Amazon Elastic Load Balancer (ELB). // such as HAproxy and Amazon Elastic Load Balancer (ELB).
@ -837,6 +841,7 @@ func NewDefault() Configuration {
SSLSessionCacheSize: sslSessionCacheSize, SSLSessionCacheSize: sslSessionCacheSize,
SSLSessionTickets: false, SSLSessionTickets: false,
SSLSessionTimeout: sslSessionTimeout, SSLSessionTimeout: sslSessionTimeout,
SSLCertificateCacheSize: 1000,
EnableBrotli: false, EnableBrotli: false,
EnableAioWrite: true, EnableAioWrite: true,
UseGzip: false, UseGzip: false,

View file

@ -19,16 +19,7 @@ local DEFAULT_CERT_HOSTNAME = "_"
local certificate_data = ngx.shared.certificate_data local certificate_data = ngx.shared.certificate_data
local certificate_servers = ngx.shared.certificate_servers local certificate_servers = ngx.shared.certificate_servers
local ocsp_response_cache = ngx.shared.ocsp_response_cache local ocsp_response_cache = ngx.shared.ocsp_response_cache
local certificate_cache
local CACHE_SIZE = 1000
local cache
do
local err
cache, err = lrucache.new(CACHE_SIZE)
if not cache then
return error("failed to create the certificate cache: " .. (err or "unknown"))
end
end
local function get_cert_and_priv_key(pem_cert_key) local function get_cert_and_priv_key(pem_cert_key)
local cert, cert_err = ssl.parse_pem_cert(pem_cert_key) local cert, cert_err = ssl.parse_pem_cert(pem_cert_key)
@ -232,8 +223,16 @@ function _M.configured_for_current_request()
return ngx.ctx.cert_configured_for_current_request return ngx.ctx.cert_configured_for_current_request
end end
function _M.set_cache_size(size)
local cache, err = lrucache.new(size)
if err then
ngx.log(ngx.ERR, string.format("failed to create the certificate cache: %s", tostring(err)))
end
certificate_cache = cache
end
function _M.flush_cache() function _M.flush_cache()
cache:flush_all() certificate_cache:flush_all()
end end
function _M.call() function _M.call()
@ -258,7 +257,7 @@ function _M.call()
return return
end end
local cached_entry = cache:get(pem_cert_uid) local cached_entry = certificate_cache:get(pem_cert_uid)
if cached_entry then if cached_entry then
cert = cached_entry.cert cert = cached_entry.cert
priv_key = cached_entry.priv_key priv_key = cached_entry.priv_key
@ -283,7 +282,7 @@ function _M.call()
return ngx.exit(ngx.ERROR) return ngx.exit(ngx.ERROR)
end end
cache:set(pem_cert_uid, { cert = cert, priv_key = priv_key, der_cert = der_cert }) certificate_cache:set(pem_cert_uid, { cert = cert, priv_key = priv_key, der_cert = der_cert })
end end
local clear_ok, clear_err = ssl.clear_certs() local clear_ok, clear_err = ssl.clear_certs()

View file

@ -78,7 +78,7 @@ describe("Certificate", function()
ngx.exit = function(status) end ngx.exit = function(status) end
certificate.set_cache_size(1000)
set_certificate(DEFAULT_CERT_HOSTNAME, DEFAULT_CERT, DEFAULT_UUID) set_certificate(DEFAULT_CERT_HOSTNAME, DEFAULT_CERT, DEFAULT_UUID)
end) end)

View file

@ -112,6 +112,7 @@ http {
else else
certificate = res certificate = res
certificate.is_ocsp_stapling_enabled = {{ $cfg.EnableOCSP }} certificate.is_ocsp_stapling_enabled = {{ $cfg.EnableOCSP }}
certificate.set_cache_size({{ $cfg.SSLCertificateCacheSize }})
end end
ok, res = pcall(require, "plugins") ok, res = pcall(require, "plugins")