Nginx : Security configuration tips

Updated: 04/01/2021

This article is going to give you some advices to improve the security of you web server Nginx. Several criteria are taken into account: system security, SSL/TLS security and data security.

In a first part, we will see how to strengthen our server to limit data leak. In a second part, we will focus on SSL/TLS security to protect the communication between the server and the client.

System Security

To check the security of you web server, I advise you to download the package nikto (or nikto_console) :

nikto -h https://mywebserver.domainnet/ -ssl

This command is going to analyze your web server (and smash it a little bit) to find potential flaws.

1. Basic security

The best way to protect your web server is to leak the minimum data possible to the attacker : version number of Nginx, PHP, OS, etc..

Generally, information is hidden in HTTP headers.

Testing configuration

# Display "Server" header
curl https://mywebserver.domain.net/ -ksv 2>&1 >/dev/null | grep Server

2. Strict Transport Security (HSTS)

This security makes it possible to declare to an HTTP client that your web server allows HTTPs.

The HSTS policy protects users from eavesdropping attacks. A man-in-the-middle attack can not intercept a request while the HSTS is active.

3. Other protections

Data leak via Header ETag
Anti-clickjacking X-Frame-Options

SSL/TLS EXCHANGE SECURITY

The following parts are made to explain and provide answers about SSL / TLS security. The most well known and current attacks are summarized below where the emphasis has been on countermeasures. To test the SSL / TLS security of your web server, try online and free Qualys SSL Labs.

1. SSL and TLS encryption protocols

When we talk about “SSL”, it’s actually SSL / TLS. It must be known that SSL has been abandoned since 1999 and that its latest version, SSLv3, dates from 1996.
Since then, TLS has taken over the torch and released three versions: TLSv1.0, TLSv1.1 and TLSv1.2.

Until October 2014, SSLv3 and TLS versions lived, so to speak, in perfect harmony. Google claims since October 14, 2014 can decrypt communications using the SSLv3 protocol via the attack POODLE. While 2/3 web servers on the internet accept this protocol and use it the community were in panic. Admittedly, the exploit is not simple, but if we combine with an attack that lowers the level of cryptography (like Logjam, see below), then all versions of TLS are potentially impacted.

The best way to be protected is to disable SSLv3.

Update 2021:
TLSv1.0 are TLSv1.1 are not longer secured.

Testing configuration

# Does your server support SSLv3 ?
echo -n | openssl s_client -connect mywebserver.domain.net:443 -ssl3 >/dev/null 2>&1; echo $?
# TLS1.0, TLS1.1, etc.
echo -n | openssl s_client -connect mywebserver.domain.net:443 -tls1 >/dev/null 2>&1; echo $?
echo -n | openssl s_client -connect mywebserver.domain.net:443 -tls1_1 >/dev/null 2>&1; echo $?
echo -n | openssl s_client -connect mywebserver.domain.net:443 -tls1_2 >/dev/null 2>&1; echo $?
echo -n | openssl s_client -connect mywebserver.domain.net:443 -tls1_3 >/dev/null 2>&1; echo $?

2. Cipher Suite

The encryption algorithms break down into 4 types:
- Key exchange
- Authentication
- Block encryption
- Message Authentication

Some algorithms are to be avoided (RC4, DH, 3DES, EXP, etc.) and others are to be prioritized. This gives us a configuration a little long but normally with the best ratio security / accessibility for customers.

According to this reference: https://wiki.mozilla.org/Security/Cipher_Suites

3. HTTP Request Smuggling Vulnerability

During the summer of 2019, an old vulnerability appeared again on almost all web servers. I am assuming you are using Nginx, if you are using a version lower than 1.18.0 you are vulnerable.

This vulnerability can lead to cache poisoning, credential hijacking, or security bypass.

More informations in this article from Blackhat 2020.

# Display nginx version under Debian/Ubuntu
dpkg -l | grep nginx

4. BEAST attack and RC4

This attack exists ONLY IF TLSv1.0 is active.

This attack makes it possible to decrypt portions of the traffic in a discrete way, without being able to alter it without being identified. If the TLSv1.0 encryption protocol is used during exchanges, an attack is possible.

There are two ways to approach the implementation of a countermeasure, either client-side or server-side.

Recent browsers support all TLSv1.1 and TLSv1.2. So, the client only have to update his browser to be protected from BEAST.

On the server side, it is possible to drastically remove TLSv1.0 from the list of allowed protocols but this will cause the incompatibility of many clients that do not support TLS versions too recent (Android ≤2.3.7, Baidu, IE <11.0, Java <8u31, openssl≤0.9.8, safari <7 (except iOS)) because of too old equipment.
The other method is to allow only the RC4 bulk cipher algorithm. Unfortunately, RC4 is weak for a long time, so it is absolutely not an alternative.

For maximum compatibility, the option is to disable RC4 but to allow TLSv1.0. This will cause the use of AES254 in block cipher for those who decide to use it (those that do not support TLSv1.1 and TLSv1.2), but will also make them vulnerable to BEAST …
In conclusion, the BEAST attack is less severe than RC4. Make your choice.

Testing configuration

# Does your server support TLSv1.1 and not RC4 ?
echo -n | openssl s_client -connect mywebserver.domain.net:443 -cipher DHE-RSA-CAMELLIA128-SHA -tls1_1 >/dev/null 2>&1; echo $?
# Does your server support TLSv1.0 ?
echo -n | openssl s_client -connect mywebserver.domain.net:443 -tls1 >/dev/null 2>&1; echo $?

5. FREAK attack (Factoring RSA-EXPORT Keys)

To be protected against this attack, you must disable encryption keys in the Export library.
Same SSLCipherSuite configuration as before, checking that it contains !EXP.

Testing configuration

# Does your server support EXP ?
echo -n | openssl s_client -connect mywebserver.domain.net:443 -cipher EXP-EDH-RSA-DES-CBC-SHA >/dev/null 2>&1; echo $?

6. Logjam attack

This attack makes it possible to lower the cryptography level of the TLS exchange. To be protected against this, it is better to only allow the TLSv1.0, TLSv1.1 and TLSv1.2 protocols.

In addition, key exchange algorithms should no longer be conventional DH, but elliptic curves: EECDH or EDH.

Finally, force the highest encryption level by default and create a unique and strong 4096-bit Diffie Hellman group.

# Generate 4096-bits DH group
openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
# Check DH group
openssl dh -in /etc/ssl/certs/dhparam.pem -text

7. Heartbleed

You are subject to this flaw if your version of openssl is too old. In this case, if the server uses a version 1.0.1 with any patch before “g”.

# Display openssl version under Debian/Ubuntu
dpkg -l openssl

CONCLUSION

REFERENCES

[1] Nginx ETag Inode Information Leakage : https://www.rapid7.com/db/vulnerabilities/http-nginx-etag-inode-leak
[2] Clickjacking : https://www.owasp.org/index.php/Clickjacking
[3] Qualys SSL Labs — SSL Server Test : https://www.ssllabs.com/ssltest/analyze.html
[4] Wikipedia — POODLE : https://en.wikipedia.org/wiki/POODLE
[5] Wikipedia — Cipher suite : https://en.wikipedia.org/wiki/Cipher_suite#Examples_of_algorithms_used
[6] Wikipedia — BEAST Attack : https://en.wikipedia.org/wiki/Transport_Layer_Security#BEAST_attack
[7] Chrome Stable Release : http://googlechromereleases.blogspot.fr/2011/10/chrome-stable-release.html
[8] Bug 665814 — (CVE-2011–3389) Rizzo/Duong chosen plaintext attack (BEAST) on SSL/TLS 1.0 : https://bugzilla.mozilla.org/show_bug.cgi?id=665814
[9] Bulletin de securite Microsoft MS12–006 : https://technet.microsoft.com/library/security/ms12-006
[10] Killing RC4: The Long Goodbye : https://blog.cloudflare.com/killing-rc4-the-long-goodbye/
[11] Wikipedia — FREAK : https://en.wikipedia.org/wiki/FREAK
[12] Wikipedia — Logjam : https://en.wikipedia.org/wiki/Logjam_(computer_security)
[13] Wikipedia — HeartBleed : https://en.wikipedia.org/wiki/Heartbleed
[14] Wikipedia — CRIME : https://en.wikipedia.org/wiki/CRIME