[Nginx] Nginx HTTPS Security and Performance Optimization
Enable HTTPS
1 | server { |
Security
Emitting nginx version
Emitting or disable nginx version.
1 | server_tokens off; |
1 | Syntax: server_tokens on | off | build | string; |
Enables or disables emitting nginx version on error pages and in the “Server” response header field.
The build parameter (1.11.10) enables emitting a build name along with nginx version.
Additionally, as part of our commercial subscription, starting from version 1.9.13 the signature on error pages and the “Server” response header field value can be set explicitly using the string with variables. An empty string disables the emission of the “Server” field.
HTTPS
To configure an HTTPS server, the ssl parameter must be enabled on listening sockets in the server block, and the locations of the server certificate and private key files should be specified:
Example:
1 | server { |
Configuring HTTPS servers - http://nginx.org/en/docs/http/configuring_https_servers.html
Enable HTTPS
1 |
1 | # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate |
Strict SNI
SNI, or Server Name Indication, is an addition to the TLS encryption protocol that enables a client device to specify the domain name it is trying to reach in the first step of the TLS handshake, preventing common name mismatch errors.
We can confirm this on the command line with:
1 | nginx -V |
If you do not have a line like this one, then Nginx will have to be re-compiled manually to include this support.
1 | http { |
Return directive redirect HTTP to HTTPS
1 | server { |
Error_page 497 make HTTP Request Sent to HTTPS Port
Status code 497 used when the client has made a HTTP request to a port listening for HTTPS requests.
1 | error_page 497 =301 https://$host$request_uri; |
Performance optimization
aio
1 | Syntax: aio on | off | threads[=pool]; |
Enables or disables the use of asynchronous file I/O (AIO) on FreeBSD and Linux:
1 | aio on; |
Files can be read and sent using multi-threading (1.7.11), without blocking a worker process:
1 | aio threads; |
By default, multi-threading is disabled, it should be enabled with the --with-threads configuration parameter. Currently, multi-threading is compatible only with the epoll, kqueue, and eventport methods. Multi-threaded sending of files is only supported on Linux.
sendfile
1 | Syntax: sendfile on | off; |
Enables or disables the use of sendfile()
.
1 | sendfile on; |
sendfile()
is called with the SF_NODISKIO flag which causes it not to block on disk I/O, but, instead, report back that the data are not in memory. nginx then initiates an asynchronous data load by reading one byte.
In this configuration, On the first read, the FreeBSD kernel loads the first 128K bytes of a file into memory, although next reads will only load data in 16K chunks. This can be changed using the read_ahead directive.
tcp_nodelay
1 | Syntax: tcp_nodelay on | off; |
Enables or disables the use of the TCP_NODELAY option. The option is enabled when a connection is transitioned into the keep-alive state. Additionally, it is enabled on SSL connections, for unbuffered proxying, and for WebSocket proxying.
tcp_nopush
1 | Syntax: tcp_nopush on | off; |
Enables or disables the use of the TCP_NOPUSH socket option on FreeBSD or the TCP_CORK socket option on Linux. The options are enabled only when sendfile is used. Enabling the option allows
sending the response header and the beginning of a file in one packet, on Linux and FreeBSD 4.*;
sending a file in full packets.
Example
1 | location /video/ { |
keepalive, keepalive_timeout, keepalive_requests
1 | http { |
1 | http { |
HTTPS server optimization
Accessing Nginx via https is generally 30% slower than http access. Improve the performance of Nginx + HTTPS for better TTFB and less latency.
SSL operations consume extra CPU resources. On multi-processor systems several worker processes should be run, no less than the number of available CPU cores. The most CPU-intensive operation is the SSL handshake. There are two ways to minimize the number of these operations per client: the first is by enabling keepalive connections to send several requests via one connection and the second is to reuse SSL session parameters to avoid SSL handshakes for parallel and subsequent connections.
Enable HTTP/2
Networking protocol for low-latency transport of content over the web. Originally started out from the SPDY protocol, now standardized as HTTP version 2.
HTTP/2 protocol | Can I use… Support tables for HTML5, CSS3, etc - https://caniuse.com/http2
Check Nginx and OpenSSL version
- Nginx >= 1.9.5
1 | nginx -V |
1 | server { |
Enable SSL session cache
Enabling SSL Session caching can reduce repeated TLS verification and reduce TLS handshake. 1M of memory can cache 4000 connections, which is very cost-effective.
1 | server { |
Disable SSL session tickets
Since SSL session tickets have not yet been implemented in Nginx, they can be closed.
1 | Syntax: ssl_session_tickets on | off; |
Enables or disables session resumption through TLS session tickets - https://tools.ietf.org/html/rfc5077.
1 | server { |
Enable OCSP Stapling
If you do not enable OCSP Stapling, you need to verify the certificate when the user connects to your server. The time for verifying the certificate is uncontrollable. After we enable OCSP Stapling, you can save this step.
1 | Syntax: ssl_stapling on | off; |
Enables or disables stapling of OCSP responses - https://tools.ietf.org/html/rfc6066#section-8 by the server.
1 | Syntax: ssl_stapling_verify on | off; |
Enables or disables verification of OCSP responses by the server.
For verification to work, the certificate of the server certificate issuer, the root certificate, and all intermediate certificates should be configured as trusted using the ssl_trusted_certificate
directive.
1 | Syntax: ssl_trusted_certificate file; |
Specifies a file with trusted CA certificates in the PEM format used to verify client certificates and OCSP responses if ssl_stapling is enabled.
In contrast to the certificate set by ssl_client_certificate, the list of these certificates will not be sent to clients.
1 | ssl_stapling on; |
Reduce SSL buffer size
ssl_buffer_size
controls the size of the buffer when sending data. In order to minimize the TTFB (time to the first byte), it is best to use a smaller value, so that TTFB can save about 30 – 50ms.
1 | Syntax: ssl_buffer_size size; |
Sets the size of the buffer used for sending data.
By default, the buffer size is 16k, which corresponds to minimal overhead when sending big responses. To minimize Time To First Byte it may be beneficial to use smaller values, for example:
1 | ssl_buffer_size 4k; |
SSL protocols and ciphers
ssl_ciphers
Put the newer and faster Cipher in front, so that the delay is smaller.
1 | Syntax: ssl_ciphers ciphers; |
Specifies the enabled ciphers. The ciphers are specified in the format understood by the OpenSSL library, for example:
1 | ssl_ciphers ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; |
The full list can be viewed using the openssl ciphers
command.
ssl_prefer_server_ciphers
1 | Syntax: ssl_prefer_server_ciphers on | off; |
Specifies that server ciphers should be preferred over client ciphers when using the SSLv3 and TLS protocols.
1 | # prefer a list of ciphers to prevent old and slow ciphers |
ssl_protocols
1 | Syntax: ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3]; |
Enables the specified protocols.
TLS1.3
Version 1.3 (the latest one) of the Transport Layer Security (TLS) browser support:
TLS 1.3 | Can I use… Support tables for HTML5, CSS3, etc - https://caniuse.com/tls1-3
Check Nginx and OpenSSL version:
-
Nginx >= 1.13.0
-
OpenSSL >= 1.1.1
1 | nginx -V |
Remember to make all server(include default server) to use TLSv1.3 protocol;
Example
1 | server { |
Early Data (0-RTT) (Optional)
1 | Syntax: ssl_early_data on | off; |
Enables or disables TLS 1.3 early data.
Requests sent within early data are subject to replay attacks. To protect against such attacks at the application layer, the $ssl_early_data
variable should be used.
1 | server { |
References
[1] Configuring HTTPS servers - http://nginx.org/en/docs/http/configuring_https_servers.html
[2] Module ngx_http_ssl_module - http://nginx.org/en/docs/http/ngx_http_ssl_module.html
[3] hakasenyang/openssl-patch: OpenSSL & NginX Patch - https://github.com/hakasenyang/openssl-patch
[4] rfc7540 - https://datatracker.ietf.org/doc/html/rfc7540
[8] Module ngx_http_core_module - http://nginx.org/en/docs/http/ngx_http_core_module.html
[9] Module ngx_http_headers_module - http://nginx.org/en/docs/http/ngx_http_headers_module.html
[10] NGINX Docs | Configuration Guide - https://docs.nginx.com/nginx-app-protect/configuration/