Nginx服务器中关于SSL的安全配置详解_nginx

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

我们在nginx的设置文档中如下编辑

复制代码 代码如下:

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

复制代码 代码如下:

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

对于整个说明文档,你需要编辑服务器配置的服务器那块和443端口(SSL配置)。在说明文档的最后,你会发现实现了样例的配置。

确保在编辑之前做了备份!

BEAST攻击和RC4算法

简言之,就是通过篡改加密算法CBC密码块的加密模式,部分加密流量可以被偷偷地解密。更多的信息请参照以上链接。

新版本的浏览器客户端可以缓解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的风险:随着时间的推移更多的密码分析将很表面化。

FREAK攻击

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

被证明是一些先进的TLS客户端-包括苹果的SecureTransport和OpenSSL-有一个Bug在里面。这个Bug造成了它们接受了RSA密钥的输出等级甚至当客户端都不要求RSA的密钥输出等级。这个Bug造成的影响还是相当严重的:假如客户端是易受攻击的并且服务器支持输出RSA,它允许第三人通过一个活跃的攻击者来减弱连接的质量进行攻击。

这里是两部分服务器必须接受的“RSA输出等级”攻击。

MITM攻击过成如下:

  •     在客户端的Hello消息中,它请求一个标准的“RSA”密码套件。
  •     MITM攻击者改变这个消息为了得到“RSA的输出”.
  •     服务器返回一个512位的RSA输出密钥,并用它的永久密钥签名。
  •     由于OpenSSL和SecureTransport存有bug,客户端就接受了这个弱密钥。
  •     攻击者分析RSA模块为了恢复正在通信时RSA的解密密钥。
  •     当客户端把加密的“预备主密钥”发送给服务器时,攻击者现在可以解密它从而得到TLS的“主密钥”。
  •     从现在起,攻击者就可以看到明文了,并且可以注入任何他想的东西。

这个页面上提供密码套件但是支持密码输出等级。确保你的OpenSSl是最近更新过的版本而且你的客户端也要使用最新的软件。

Heartbleed(心脏出血)

Hearbleed是一个在2014年四月OpenSSL密码库里被发现的安全漏洞,它被广泛用在运输层(TLS)协议的实施中。Heartbleed可能被使用不管是否使用了一个易受攻击的OpenSSL,比如说在一个服务器或者客户端使用。它是在DTLS心跳扩展(RFC6520)由不合适的输入确认(因为没有边界检查)所造成,因此这个漏洞的名字为“心跳”.这个漏洞被划为一个重读的缓冲区,更多超出允许的数据被读出。

哪些版本的OpenSSL被Heartbleed影响?

不同版本的情况:

  •     OpenSSL 1.0.1 到 1.0.1f (包括) 受攻击。
  •     OpenSSL 1.0.1g不受攻击。
  •     OpenSSL 1.0.0的分支不受攻击。
  •     OpenSSL 0.9.8 的分支不受攻击。

OpenSSL在2011年12月发现这个漏洞而且在2012年3月14日发布OpenSSL1.0.1之前一直没有采取措施。2014年4月7号发布的OpenSSL1.0.1g修复了这个漏洞。

通过更新OpenSSL就可以免受这个漏洞带来的攻击。

SSL 压缩(犯罪攻击)

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

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

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

再次编辑此配置文件:
 
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

贵宾犬攻击和TLS-FALLBACK-SCSV

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 及更高的版本.

更多的信息请参阅NGINX文档
密码套件

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

这意味着当私有密钥被泄露不能用来解密SSL流量记录。

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

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

推荐的密码套件:
 

复制代码 代码如下:

ssl_ciphers 'AES128+EECDH:AES128+EDH';

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

复制代码 代码如下:

ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

  如果您的 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 用于向后兼容。 

强制性的丢弃

  •     aNULL 包含未验证 diffie - hellman 密钥交换,受到中间人这个攻击
  •     eNULL 包含未加密密码(明文)
  •     EXPORT 被美国法律标记为遗留弱密码
  •     RC4 包含了密码,使用废弃ARCFOUR算法
  •     DES 包含了密码,使用弃用数据加密标准
  •     SSLv2 包含所有密码,在旧版本中定义SSL的标准,现在弃用
  •     MD5 包含所有的密码,使用过时的消息摘要5作为散列算法

其它的设置

确保你已经添加了以下几行:
 

复制代码 代码如下:

ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;

在SSLv3或这是TLSv1握手时选择一个密码,通常是使用客户端的偏好。如果这个指令是启用的,那么服务器反而是使用服务器的偏好。

更多关于SSL preferserver密码的信息

更多关于SSL密码的信息
向前保密(Forward Secrecy)与Diffie Hellman Ephemeral Parameters

向前保密的概念很简单:客户端和服务器协商一个可靠的密钥,并在会话结束后销毁。服务器中的RSA私钥用来签名客户端和服务器之间交换的Diffie-Hellman密钥。副主密钥从Diffie-Hellman握手中得到,并用于加密。由于副主密钥在客户端和服务器之间的连接中是明确具体的,并用于有限的时间,因此被叫作Ephemeral(短暂的)。

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

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

我们需要产生一个更强的DHE参数:
cd /etc/ssl/certs
openssl dhparam -out dhparam.pem 4096

然后告诉nginx在DHE密钥交换的时候使用它:
 

复制代码 代码如下:

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

OCSP 适用

在和服务器连接的时候,客户端通过使用证书撤销列表(CRL)来验证服务器证书的有效性,或者是使用在线证书状态协议(OCSP)记录。但是CRL的问题是:CRL的列表项不断增多,而且需要不断地下载。

OCSP是更轻量级的,因为它一次只获取一条记录。但是副作用是,当连接到服务器的时候,OCSP请求必须发送到第三方响应者,这增加了延迟,以及失败的可能。实际上,OCSP响应者由CA操控,由于它常常不可靠,导致浏览器由于收不到适时的响应而失败。这减少了安全性,因为它允许攻击者对OCSP响应者进行DoS攻击来取消验证。

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

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

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

HTTP Strict Transport Security

如果可能,你应该开启 HTTP Strict Transport Security (HSTS) ,它指示浏览器只通过HTTPS来访问你的站点。

HTTP Public Key Pinning Extension

你同样应该开启 HTTP Public Key Pinning Extension。

Public Key Pinning 意味着证书链必须包含处于白名单之中的公钥。它确保只在白名单中的CA可以对*.example.com进行签名,而不是浏览器中保存的任何一个CA。

我已经写了关于它的一篇文章,包含背景理论和配置实例,针对 Apache, Lighttpd 以及 NGINX:https://raymii.org/s/articles/HTTPPublicKeyPinningExtension_HPKP.html
配置示例
 

复制代码 代码如下:

server {
 
  listen [::]:443 default_server;
 
  ssl on;
  ssl_certificate_key /etc/ssl/cert/raymii_org.pem;
  ssl_certificate /etc/ssl/cert/ca-bundle.pem;
 
  ssl_ciphers 'AES128+EECDH:AES128+EDH:!aNULL';
 
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_session_cache shared:SSL:10m;
 
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.4.4 8.8.8.8 valid=300s;
  resolver_timeout 10s;
 
  ssl_prefer_server_ciphers on;
  ssl_dhparam /etc/ssl/certs/dhparam.pem;
 
  add_header Strict-Transport-Security max-age=63072000;
  add_header X-Frame-Options DENY;
  add_header X-Content-Type-Options nosniff;
 
  root /var/www/;
  index index.html index.htm;
  server_name raymii.org;
 
}

结论

如果你应用了上面的配置文件,你需要重启nginx:

复制代码 代码如下:

# Check the config first:
/etc/init.d/nginx configtest
# Then restart:
/etc/init.d/nginx restart

现在使用SSL 实验室测试(SSL Labs tes)看看你是否得到一个漂亮的A。同时,当然,拥有一个安全的,牢靠的,作为未来样例的SSL配置。

时间: 2024-10-22 00:58:30

Nginx服务器中关于SSL的安全配置详解_nginx的相关文章

使Nginx服务器支持中文URL的相关配置详解_nginx

关于中文URL已经是老话题了,到目前为止依然有很大一部分SEOer都会说不要使用中文URL,对搜索引擎不友好. 不过,那已经是以前的事了,谷歌很早就支持了中文URL,当时百度技术没有跟上,URL中会出现乱码. 在谷歌的算法中,URL包含关键字是会给页面赋予一定权重的,英文是,中文也是,朽木猜测百度之前没有给予中文URL权重,可能是因为识别的问题. 经过一些简单的测试,朽木发现中文URL中包含关键字,对百度SEO有很积极的影响. 不过需要注意的是最好使用UTF8编码,虽然百度有了"一定的识别能力&

Linux服务器下nginx的安全配置详解_nginx

Nginx是一个轻量级,高性能的Web服务器/反向代理和电子邮件 代理(IMAP/POP3),它可以运行在UNIX,GNU/Linux,BSD变种,MAC OS X,Solaris和Microsoft Windows上.根据Netcraft的调查数据显示,互联网上6%的域名都使用了Nginx Web服务器.Nginx是解决C10K问题的服务器之一,与传统服务器不一样,Nginx不依赖于线程处理请求,相反,它使用了一个更具扩展性的事件驱 动(异步)架构.Nginx在很多高流量网站上得到了应用,如W

Nginx服务器中为网站或目录添加认证密码的配置详解_nginx

nginx可以为网站或目录甚至特定的文件设置密码认证.密码必须是crypt加密的.可以用apache的htpasswd来创建密码. 格式为: htpasswd -b -c site_pass username password site_pass为密码文件.放在同nginx配置文件同一目录下,当然你也可以放在其它目录下,那在nginx的配置文件中就要写明绝对地址或相对当前目录的地址. 如果你输入htpasswd命令提示没有找到命令时,你需要安装httpd.如果是centos可以执行如下来安装,

Nginx服务器中强制使用缓存的配置及缓存优先级的讲解_nginx

nginx代理做好了,缓存也配置好了,但是发现css.js.jpg这些静态文件统统都cached成功.但是偏偏页面文件依旧到源服务器取.1. nginx不缓存原因默认情况下,nginx是否缓存是由nginx缓存服务器与源服务器共同决定的, 缓存服务器需要严格遵守源服务器响应的header来决定是否缓存以及缓存的时常.header主要有如下: Cache-control:no-cache.no-store 如果出现这两值,nginx缓存服务器是绝对不会缓存的 Expires:1980-01-01

Nginx服务器中的location配置详解_nginx

语法location  [=|~|~*|^~] /uri/  {...} 规则= : 表示精确的URI匹配(有兴趣的同学可以看一下url和uri的区别) -: 表示区分大小写的正则匹配 -*:表示不区分大小写的正则匹配 !~ && !~*:表示区分大小写不匹配的正则和不区分大小写的不匹配的正则 /:通用匹配,任何请求都会匹配到 location匹配目标location匹配测试只使用请求URI的部分,而不使用参数部分.(原因:参数的写法太多,无法精确匹配) location匹配顺序多个loc

Nginx服务器对数据传输速度限制的基本配置方法讲解_nginx

注意: nginx 1.1.8 之后的版本的语法改为limit_conn_zone $binary_remote_addr zone=NAME:10m; NAME 就是 zone 的名字详情请看这里 http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html 限制连接数: 要限制连接,必须先有一个容器对连接进行计数,在http段加入如下代码: "zone=" 给它一个名字,可以随便叫,这个名字要跟下面的 limit_con

Nginx+Tomcat的服务器端环境配置详解_nginx

Nginx+tomcat是目前主流的java web架构,如何让nginx+tomcat同时工作呢,也可以说如何使用nginx来反向代理tomcat后端均衡呢?直接安装配置如下: 1.JAVA JDK安装: #下载相应的jdk软件包,然后解压安装,我这里包名称为:jdk-7u25-linux-x64.tar.gz         tar -xzf jdk-7u25-linux-x64.tar.gz ;mkdir -p /usr/java/ ;mv jdk1.7.0_25/ /usr/java/

Nginx中的root&alias文件路径及索引目录配置详解_nginx

root&alias文件路径配置nginx指定文件路径有两种方式root和alias,这两者的用法区别,使用方法总结了下,方便大家在应用过程中,快速响应.root与alias主要区别在于nginx如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上. [root] 语法:root path 默认值:root html 配置段:http.server.location.if [alias] 语法:alias path 配置段:location 实例: locat

讲解Nginx服务器中设置本地浏览器缓存的简单方法_nginx

浏览器缓存(Browser Caching) 是为了加速浏览并节约网络资源,浏览器在用户磁盘上对最近请求过的文档进行存储. nginx可以通过 expires 指令来设置浏览器的Header 语法: expires [time|epoch|max|off] 默认值: expires off 作用域: http, server, location 使用本指令可以控制HTTP应答中的"Expires"和"Cache-Control"的头标,(起到控制页面缓存的作用).