This tutorial shows you how to set up strong SSL security on the nginx webserver. We do this by disabling SSL Compression to mitigate the CRIME attack, disable SSLv3 and below because of vulnerabilities in the protocol and we will set up a strong ciphersuite that enables Forward Secrecy when possible. We also enable HSTS and HPKP. This way we have a strong and future proof ssl configuration and we get an A on the Qually Labs SSL Test.

TL;DR: Copy-pastable strong cipherssuites for NGINX, Apache and Lighttpd: https://cipherli.st

This tutorial is tested on a Digital Ocean VPS. If you like this tutorial and want to support my website, use this link to order a Digital Ocean VPS: https://www.digitalocean.com/?refcode=7435ae6b8212

This tutorial works with the stricter requirements of the SSL Labs test announced on the 21st of January 2014 (It already did before that, if you follow(ed) it you get an A+)

This tutorial is also available for Apache
This tutorial is also available for Lighttpd
This tutorial is also available for FreeBSD, NetBSD and OpenBSD over at the BSD Now podcast: http://www.bsdnow.tv/tutorials/nginx

You can find more info on the topics by following the links below:

We are going to edit the nginx settings in the file /etc/nginx/sited-enabled/yoursite.com (On Ubuntu/Debian) or in /etc/nginx/conf.d/nginx.conf (On RHEL/CentOS).

For the entire tutorial, you need to edit the parts between the server block for the server config for port 443 (ssl config). At the end of the tutorial you can find the complete config example.

Make sure you back up the files before editing them!

本文向你们展示如何在nginx的web服务器上设置更强的SSL。我们是通过使SSL无效来减弱CRIME攻击的这种方法实现。不使用在协议中易受攻击的SSLv3以及以下版本并且我们会设置一个更强的密码套件为了在可能的情况下能够实现Forward Secrecy,同时我们还启用HSTS和HPKP。这样我们就有了一个更强、不过时的SSL配置并且我们在Qually Labs SSL 测试中得到了A等级。

TL:DR:Copy-pastable strong cipherssuites for NGINX, Apache and Lighttpd: https://cipherli.st

这个说明是在Digital Ocean VPS是测试过的。如果你喜欢这个说明指到并且支持我的网站,通过下面的链接预定一个Digital Ocean VPS。



This tutorial is also available for Apache
This tutorial is also available for Lighttpd

This tutorial is also available for FreeBSD, NetBSD and OpenBSD over at the BSD Now podcasthttp://www.bsdnow.tv/tutorials/nginx



/etc/nginx/sited-enabled/yoursite.com (On Ubuntu/Debian)或者在

/etc/nginx/conf.d/nginx.conf (On RHEL/CentOS).



The BEAST attack and RC4

In short, by tampering with an encryption algorithm's CBC - cipher block chaining - mode's, portions of the encrypted traffic can be secretly decrypted. More info on the above link.

Recent browser versions have enabled client side mitigation for the beast attack. The recommendation was to disable all TLS 1.0 ciphers and only offer RC4. However, [RC4 has a growing list of attacks against it],(http://www.isg.rhul.ac.uk/tls/) many of which have crossed the line from theoretical to practical. Moreover, there is reason to believe that the NSA has broken RC4, their so-called "big breakthrough."

Disabling RC4 has several ramifications. One, users with shitty browsers such as Internet Explorer on Windows XP will use 3DES in lieu. Triple-DES is more secure than RC4, but it is significantly more expensive. Your server will pay the cost for these users. Two, RC4 mitigates BEAST. Thus, disabling RC4 makes TLS 1.0 users susceptible to that attack, by moving them to AES-CBC (the usual server-side BEAST "fix" is to prioritize RC4 above all else). I am confident that the flaws in RC4 significantly outweigh the risks from BEAST. Indeed, with client-side mitigation (which Chrome and Firefox both provide), BEAST is a nonissue. But the risk from RC4 only grows: More cryptanalysis will surface over time.



新版本的浏览器客户端可以缓解BEASE攻击。建议禁用所有的TLS 1.0密码并且只是用RC4。然而,[RC4有一个不断增加的列表来防止攻击],(http://www.isg.rhul.ac.uk/tls/)其中的很多都将理论和现实交叉在一起。而且,这就是为什么NSA已经破解了RC4,他们所谓的“重大的突破”。

禁用RC4有几个结果。一、使用差劲儿浏览器的用户将使用3DES来代替。3-DES比RC4更安全。但是就意味着更加昂贵。你的服务器会因为这样的用户开销更大。二、RC4可以缓解BEAST攻击。因此,禁用RC4使TLS 1用户容易受到攻击,通过移动他们AES-CBC(通常的服务器端的BEAST“修复”是优先考虑高于一切的RC4)。我很确信,在BEAST上RC4上的缺陷明显大于风险。确实,客户端的缓解(chrome和火狐都提供)BEAST已不再是个问题。但对于增长RC4的风险:随着时间的推移更多的密码分析将很表面化。

Factoring RSA-EXPORT Keys (FREAK)

FREAK is a man-in-the-middle (MITM) vulnerability discovered by a group of cryptographers at INRIA, Microsoft Research and IMDEA. FREAK stands for "Factoring RSA-EXPORT Keys."

The vulnerability dates back to the 1990s, when the US government banned selling crypto software overseas, unless it used export cipher suites which involved encryption keys no longer than 512-bits.

It turns out that some modern TLS clients - including Apple's SecureTransport and OpenSSL - have a bug in them. This bug causes them to accept RSA export-grade keys even when the client didn't ask for export-grade RSA. The impact of this bug can be quite nasty: it admits a 'man in the middle' attack whereby an active attacker can force down the quality of a connection, provided that the client is vulnerable and the server supports export RSA.

There are two parts of the attack as the server must also accept "export grade RSA."

The MITM attack works as follows:

  • In the client's Hello message, it asks for a standard 'RSA' ciphersuite.

  • The MITM attacker changes this message to ask for 'export RSA'.

  • The server responds with a 512-bit export RSA key, signed with its long-term key.

  • The client accepts this weak key due to the OpenSSL/SecureTransport bug.

  • The attacker factors the RSA modulus to recover the corresponding RSA decryption key.

  • When the client encrypts the 'pre-master secret' to the server, the attacker can now decrypt it to recover the TLS 'master secret'.

  • From here on out, the attacker sees plaintext and can inject anything it wants.

The ciphersuite offered here on this page does not enable EXPORT grade ciphers. Make sure your OpenSSL is updated to the latest available version and urge your clients to also use upgraded software.


FREAK是在密码专家小组在INRIA, Microsoft Research and IMDEA所发现的一种中间人攻击。FREAK就是“Factoring RSA-EXPORT Keys .”。这种攻击可以追溯到90世纪90年代,也就是在美国政府禁止出售加密软件到海外的时候,除非输出的密码套件中加密密钥的长度不超过512位。




  • 在客户端的Hello消息中,它请求一个标准的“RSA”密码套件。

  • MITM攻击者改变这个消息为了得到“RSA的输出”.

  • 服务器返回一个512位的RSA输出密钥,并用它的永久密钥签名。

  • 由于OpenSSL和SecureTransport存有bug,客户端就接受了这个弱密钥。

  • 攻击者分析RSA模块为了恢复正在通信时RSA的解密密钥。

  • 当客户端把加密的“预备主密钥”发送给服务器时,攻击者现在可以解密它从而得到TLS的“主密钥”。

  • 从现在起,攻击者就可以看到明文了,并且可以注入任何他想的东西。



Heartbleed is a security bug disclosed in April 2014 in the OpenSSL cryptography library, which is a widely used implementation of the Transport Layer Security (TLS) protocol. Heartbleed may be exploited regardless of whether the party using a vulnerable OpenSSL instance for TLS is a server or a client. It results from improper input validation (due to a missing bounds check) in the implementation of the DTLS heartbeat extension (RFC6520), thus the bug's name derives from "heartbeat". The vulnerability is classified as a buffer over-read, a situation where more data can be read than should be allowed.

What versions of the OpenSSL are affected by Heartbleed?

Status of different versions:

  • OpenSSL 1.0.1 through 1.0.1f (inclusive) are vulnerable

  • OpenSSL 1.0.1g is NOT vulnerable

  • OpenSSL 1.0.0 branch is NOT vulnerable

  • OpenSSL 0.9.8 branch is NOT vulnerable

The bug was introduced to OpenSSL in December 2011 and has been out in the wild since OpenSSL release 1.0.1 on 14th of March 2012. OpenSSL 1.0.1g released on 7th of April 2014 fixes the bug.

By updating OpenSSL you are not vulnerable to this bug.





  • OpenSSL 1.0.1 到 1.0.1f (包括) 受攻击。

  • OpenSSL 1.0.1g不受攻击。

  • OpenSSL 1.0.0的分支不受攻击。

  • OpenSSL 0.9.8 的分支不受攻击。



SSL Compression (CRIME attack)

The CRIME attack uses SSL Compression to do its magic. SSL compression is turned off by default in nginx 1.1.6+/1.0.9+ (if OpenSSL 1.0.0+ used) and nginx 1.3.2+/1.2.2+ (if older versions of OpenSSL are used).

If you are using al earlier version of nginx or OpenSSL and your distro has not backported this option then you need to recompile OpenSSL without ZLIB support. This will disable the use of OpenSSL using the DEFLATE compression method. If you do this then you can still use regular HTML DEFLATE compression.

SSLv2 and SSLv3

SSL v2 is insecure, so we need to disable it. We also disable SSLv3, as TLS 1.0 suffers a downgrade attack, allowing an attacker to force a connection to use SSLv3 and therefore disable forward secrecy.

Again edit the config file:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

SSL 压缩(犯罪攻击)

通常来说,犯罪攻击使用 SSL 压缩来施展它的魔法。SSL 压缩在 nginx1.1.6+/1.0.9+ 中默认是关闭的(如果使用 openssl 1.0.0+).

如果你正在使用 nginx 或者 OpenSSL 其他早期版本,并且你的发行版并没有回迁此选项,那么你需要重新编译不支持 ZLIB 的 OpenSSL。这将禁止使用DEFLATE压缩方法来使用 OpenSSL。如果你这样做,那么你仍然可以使用常规的HTML DEFLATE压缩。


SSL v2 并不安全,因此我们需要禁用它。我们也可以禁用 SSL v3,当 TLS 1.0 遭受一个降级攻击时,可以允许一个攻击者强迫使用 SSL v3 来连接,因此禁用“向前保密”。


ssl_protocols TLSv1 TLSv1.1 TLSv1.2;


SSLv3 allows exploiting of the POODLE bug. This is one more major reason to disable this.

Google have proposed an extension to SSL/TLS named TLSFALLBACKSCSV that seeks to prevent forced SSL downgrades. This is automatically enabled if you upgrade OpenSSL to the following versions:

  • OpenSSL 1.0.1 has TLSFALLBACKSCSV in 1.0.1j and higher.

  • OpenSSL 1.0.0 has TLSFALLBACKSCSV in 1.0.0o and higher.

  • OpenSSL 0.9.8 has TLSFALLBACKSCSV in 0.9.8zc and higher.

More info on the NGINX documentation

The Cipher Suite

Forward Secrecy ensures the integrity of a session key in the event that a long-term key is compromised. PFS accomplishes this by enforcing the derivation of a new key for each and every session.

This means that when the private key gets compromised it cannot be used to decrypt recorded SSL traffic.

The cipher suites that provide Perfect Forward Secrecy are those that use an ephemeral form of the Diffie-Hellman key exchange. Their disadvantage is their overhead, which can be improved by using the elliptic curve variants.


SSLv3允许利用“贵宾犬 POODLE”漏洞,这是禁用它的一个主要原因。Google已经提议一种叫TLSFALLBACKSCSV的SSL/TLS的拓展,旨在防止强制SSL降级。以下是升级后自动启用的OpenSSL版本:

  • OpenSSL 1.0.1 有 TLSFALLBACKSCSV 在 1.0.1j 及更高的版本.

  • OpenSSL 1.0.0 有 TLSFALLBACKSCSV 在 1.0.0o 及更高的版本.

  • OpenSSL 0.9.8 有 TLSFALLBACKSCSV 在 0.9.8zc 及更高的版本.



Forward Secrecy 确保了在永久密钥被泄漏的事件中,会话密钥的完整性。PFS 实现这些是通过执行推导每个会话的新密钥来完成。


密码套件提供 Perfect Forward Secrecy 暂时使用 Diffie-Hellman 密钥交换的形式。他们的缺点是开销大,这可以通过使用椭圆曲线的变异的改进。

The following two ciphersuites are recommended by me, and the latter by the Mozilla Foundation.

The recommended cipher suite:

ssl_ciphers 'AES128+EECDH:AES128+EDH';

The recommended cipher suite for backwards compatibility (IE6/WinXP):


If your version of OpenSSL is old, unavailable ciphers will be discarded automatically. Always use the full ciphersuite above and let OpenSSL pick the ones it supports.

The ordering of a ciphersuite is very important because it decides which algorithms are going to be selected in priority. The recommendation above prioritizes algorithms that provide perfect forward secrecy.

Older versions of OpenSSL may not return the full list of algorithms. AES-GCM and some ECDHE are fairly recent, and not present on most versions of OpenSSL shipped with Ubuntu or RHEL.

Prioritization logic

  • ECDHE+AESGCM ciphers are selected first. These are TLS 1.2 ciphers and not widely supported at the moment. No known attack currently target these ciphers.

  • PFS ciphersuites are preferred, with ECDHE first, then DHE.

  • AES 128 is preferred to AES 256. There has been discussions on whether AES256 extra security was worth the cost, and the result is far from obvious. At the moment, AES128 is preferred, because it provides good security, is really fast, and seems to be more resistant to timing attacks.

  • In the backward compatible ciphersuite, AES is preferred to 3DES. BEAST attacks on AES are mitigated in TLS 1.1 and above, and difficult to achieve in TLS 1.0. In the non-backward compatible ciphersuite, 3DES is not present.

  • RC4 is removed entirely. 3DES is used for backward compatibility. See discussion in #RC4_weaknesses

Mandatory discards

  • aNULL contains non-authenticated Diffie-Hellman key exchanges, that are subject to Man-In-The-Middle (MITM) attacks

  • eNULL contains null-encryption ciphers (cleartext)

  • EXPORT are legacy weak ciphers that were marked as exportable by US law

  • RC4 contains ciphers that use the deprecated ARCFOUR algorithm

  • DES contains ciphers that use the deprecated Data Encryption Standard

  • SSLv2 contains all ciphers that were defined in the old version of the SSL standard, now deprecated

  • MD5 contains all the ciphers that use the deprecated message digest 5 as the hashing algorithm

我建议以下两个密码套件,后者来自 Mozilla 基金会。


ssl_ciphers 'AES128+EECDH:AES128+EDH';

推荐的密码套件向后兼容(IE6 / WinXP):


  如果您的 OpenSSL 是旧版本,不可用密码将被自动丢弃。总是使用完整的密码套件,让OpenSSL选它所支持的。


老版本的 OpenSSL 可能不会返回算法的完整列表。AES-GCM 和一些 ECDHE 相当近,而不是出现在大多数版本的 Ubuntu OpenSSL 附带或 RHEL。


  • 首先选择 ECDHE + AESGCM 密码。这些都是 TLS 1.2 密码并没有受到广泛支持。这些密码目前没有已知的攻击目标。

  • PFS 密码套件是首选,ECDHE 第一,然后 DHE。

  • AES 128 更胜 AES 256。有讨论是否 AES256 额外的安全是值得的成本,结果远不明显。目前,AES128 是首选的,因为它提供了良好的安全,似乎真的是快,更耐时机攻击。

  • 向后兼容的密码套件,AES 优先 3DES。暴力攻击 AES 在 TLS1.1 及以上,减轻和 TLS1.0 中难以实现。向后不兼容的密码套件,3DES 不存在.

  • RC4 被完全移除. 3DES 用于向后兼容。 查看讨论 #RC4_weaknesses


  • aNULL 包含未验证 diffie - hellman 密钥交换,受到中间人这个攻击

  • eNULL 包含未加密密码(明文)

  • EXPORT 被美国法律标记为遗留弱密码

  • RC4 包含了密码,使用废弃ARCFOUR算法

  • DES 包含了密码,使用弃用数据加密标准

  • SSLv2 包含所有密码,在旧版本中定义SSL的标准,现在弃用

  • MD5 包含所有的密码,使用过时的消息摘要5作为散列算法

Extra settings

Make sure you also add these lines:

ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;

When choosing a cipher during an SSLv3 or TLSv1 handshake, normally the client's preference is used. If this directive is enabled, the server's preference will be used instead.

More info on sslpreferserver_ciphers
More info on ssl_ciphers

Forward Secrecy & Diffie Hellman Ephemeral Parameters

The concept of forward secrecy is simple: client and server negotiate a key that never hits the wire, and is destroyed at the end of the session. The RSA private from the server is used to sign a Diffie-Hellman key exchange between the client and the server. The pre-master key obtained from the Diffie-Hellman handshake is then used for encryption. Since the pre-master key is specific to a connection between a client and a server, and used only for a limited amount of time, it is called Ephemeral.

With Forward Secrecy, if an attacker gets a hold of the server's private key, it will not be able to decrypt past communications. The private key is only used to sign the DH handshake, which does not reveal the pre-master key. Diffie-Hellman ensures that the pre-master keys never leave the client and the server, and cannot be intercepted by a MITM.



ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;


更多关于SSL preferserver密码的信息


向前保密(Forward SecrecyDiffie Hellman Ephemeral Parameters


由于有Forward Secrecy,即使攻击者持有服务器的私钥,也不能够解密过去的会话。私钥仅仅用来签名DH(Diffie-Hellman)的握手,它并没有泄漏副主密钥。Diffie-Hellman确保了副主密钥不会离开客户端和服务器,也不会被中间人截获。

All versions of nginx as of 1.4.4 rely on OpenSSL for input parameters to Diffie-Hellman (DH). Unfortunately, this means that Ephemeral Diffie-Hellman (DHE) will use OpenSSL's defaults, which include a 1024-bit key for the key-exchange. Since we're using a 2048-bit certificate, DHE clients will use a weaker key-exchange than non-ephemeral DH clients.

We need generate a stronger DHE parameter:

cd /etc/ssl/certs
openssl dhparam -out dhparam.pem 4096

And then tell nginx to use it for DHE key-exchange:

ssl_dhparam /etc/ssl/certs/dhparam.pem;

OCSP Stapling

When connecting to a server, clients should verify the validity of the server certificate using either a Certificate Revocation List (CRL), or an Online Certificate Status Protocol (OCSP) record. The problem with CRL is that the lists have grown huge and takes forever to download.

1.4.4所有的nginx版本在往Diffiel-Hellman输入参数时依赖OpenSSL。不幸的时,这就意味着Ephemeral Diffiel-Hellman(DHE)会使用OpenSSL的这一缺陷,包括一个1024位的交换密钥。由于我们正在使用一个2048位的证书,DHE客户端比非ephemeral客户端将使用一个更弱的密钥交换。


cd /etc/ssl/certs
openssl dhparam -out dhparam.pem 4096


ssl_dhparam /etc/ssl/certs/dhparam.pem;



OCSP is much more lightweight, as only one record is retrieved at a time. But the side effect is that OCSP requests must be made to a 3rd party OCSP responder when connecting to a server, which adds latency and potential failures. In fact, the OCSP responders operated by CAs are often so unreliable that browser will fail silently if no response is received in a timely manner. This reduces security, by allowing an attacker to DoS an OCSP responder to disable the validation.

The solution is to allow the server to send its cached OCSP record during the TLS handshake, therefore bypassing the OCSP responder. This mechanism saves a roundtrip between the client and the OCSP responder, and is called OCSP Stapling.

The server will send a cached OCSP response only if the client requests it, by announcing support for the status_request TLS extension in its CLIENT HELLO.

Most servers will cache OCSP response for up to 48 hours. At regular intervals, the server will connect to the OCSP responder of the CA to retrieve a fresh OCSP record. The location of the OCSP responder is taken from the Authority Information Access field of the signed certificate.

View my tutorial on enabling OCSP stapling on NGINX


解决方案是在TLS握手期间,允许服务器发送缓存的OCSP记录,这样来绕过OCSP响应者。这个技术节省了在客户端和OCSP响应者之间的一个来回,称为OCSP闭合(OCSP Stapling)。

服务器只在客户端请求的时候,发送一个缓存的OCSP响应,通过对CLIENT HELLO的status_request TLS拓展来声明支持。

大多数服务器都会缓存OCSP响应到48小时。在常规间隔,服务器会连接到CA的OCSP响应者来获取最新的OCSP记录。OCSP响应者的位置是从签名证书的Authority Information Access 字段来获取。

请参阅我的关于在NGINX上增加OCSP闭合(OCSP stapling)的教程