标签归档:https

Http性能压测工具wrk

用过了很多压测工具,却一直没找到中意的那款。最近试了wrk感觉不错,命令及结果很类似ab,写下这份使用指南给自己备忘用,如果能帮到你,那也很好。

安装

wrk支持大多数类UNIX系统,不支持windows。需要操作系统支持LuaJIT和OpenSSL,不过不用担心,大多数类Unix系统都支持。安装wrk非常简单,只要从github上下载wrk源码,在项目路径下执行make命令即可。

git clone https://github.com/wg/wrk make

make之后,会在项目路径下生成可执行文件wrk,随后就可以用其进行HTTP压测了。可以把这个可执行文件拷贝到某个已在path中的路径,比如/usr/local/bin,这样就可以在任何路径直接使用wrk了。

默认情况下wrk会使用自带的LuaJIT和OpenSSL,如果你想使用系统已安装的版本,可以使用WITH_LUAJIT和WITH_OPENSSL这两个选项来指定它们的路径。比如:

make WITH_LUAJIT=/usr WITH_OPENSSL=/usr

基本使用

  1. 命令行敲下wrk,可以看到使用帮助
Usage: wrk <options> <url>                            
  Options:                                            
    -c, --connections <N>  Connections to keep open  -d, --duration    <T>  Duration of test  -t, --threads     <N>  Number of threads to use  -s, --script      <S>  Load Lua script file  -H, --header      <H>  Add header to request  --latency          Print latency statistics  --timeout     <T>  Socket/request timeout  -v, --version          Print version details  Numeric arguments may include a SI unit (1k, 1M, 1G) Time arguments may include a time unit (2s, 2m, 2h)

简单翻成中文:

使用方法: wrk <选项> <被测HTTP服务的URL> Options:                                            
    -c, --connections <N> 跟服务器建立并保持的TCP连接数量  
    -d, --duration <T> 压测时间           
    -t, --threads <N> 使用多少个线程进行压测   
                                                      
    -s, --script <S> 指定Lua脚本路径       
    -H, --header <H> 为每一个HTTP请求添加HTTP头      
        --latency          在压测结束后,打印延迟统计信息   
        --timeout <T> 超时时间     
    -v, --version          打印正在使用的wrk的详细版本信息 <N>代表数字参数,支持国际单位 (1k, 1M, 1G) <T>代表时间参数,支持时间单位 (2s, 2m, 2h)
  1. 看下版本
wrk -v 输出: wrk 4.0.2 [epoll] Copyright (C) 2012 Will Glozer

看到是4.0.2版本的wrk,使用了epoll。这意味着我们可以用少量的线程来跟被测服务创建大量连接,进行压测。

  1. 做一次简单压测,分析下结果
wrk -t8 -c200 -d30s --latency "http://www.bing.com" 输出:
Running 30s test @ http://www.bing.com 8 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency 46.67ms 215.38ms 1.67s 95.59% Req/Sec 7.91k 1.15k 10.26k 70.77% Latency Distribution 50%    2.93ms 75%    3.78ms 90%    4.73ms 99%    1.35s  1790465 requests in 30.01s, 684.08MB read
Requests/sec: 59658.29 Transfer/sec: 22.79MB

以上使用8个线程200个连接,对bing首页进行了30秒的压测,并要求在压测结果中输出响应延迟信息。以下对压测结果进行简单注释:

Running 30s test @ http://www.bing.com (压测时间30s) 8 threads and 200 connections (共8个测试线程,200个连接)
  Thread Stats   Avg      Stdev     Max   +/- Stdev
              (平均值) (标准差)(最大值)(正负一个标准差所占比例)
    Latency 46.67ms 215.38ms 1.67s 95.59% (延迟)
    Req/Sec 7.91k 1.15k 10.26k 70.77% (处理中的请求数)
  Latency Distribution (延迟分布) 50%    2.93ms 75%    3.78ms 90%    4.73ms 99%    1.35s (99分位的延迟) 1790465 requests in 30.01s, 684.08MB read (30.01秒内共处理完成了1790465个请求,读取了684.08MB数据)
Requests/sec: 59658.29 (平均每秒处理完成59658.29个请求)
Transfer/sec: 22.79MB (平均每秒读取数据22.79MB)

可以看到,wrk使用方便,结果清晰。并且因为非阻塞IO的使用,可以在普通的测试机上创建出大量的连接,从而达到较好的压测效果。

使用Lua脚本个性化wrk压测

以上两节安装并简单使用了wrk,但这种简单的压测可能不能满足我们的需求。比如我们可能需要使用POST METHOD跟服务器交互;可能需要为每一次请求使用不同的参数,以更好的模拟服务的实际使用场景等。wrk支持用户使用–script指定Lua脚本,来定制压测过程,满足个性化需求。

  1. 介绍wrk对Lua脚本的支持

wrk支持在三个阶段对压测进行个性化,分别是启动阶段、运行阶段和结束阶段。每个测试线程,都拥有独立的Lua运行环境。

启动阶段
function setup(thread)

在脚本文件中实现setup方法,wrk就会在测试线程已经初始化但还没有启动的时候调用该方法。wrk会为每一个测试线程调用一次setup方法,并传入代表测试线程的对象thread作为参数。setup方法中可操作该thread对象,获取信息、存储信息、甚至关闭该线程。

thread.addr             - get or set the thread's server address thread:get(name)        - get the value of a global in the thread's env thread:set(name, value) - set the value of a global in the thread's env thread:stop()           - stop the thread
运行阶段
function init(args) function delay() function request() function response(status, headers, body)

init由测试线程调用,只会在进入运行阶段时,调用一次。支持从启动wrk的命令中,获取命令行参数;

delay在每次发送request之前调用,如果需要delay,那么delay相应时间;

request用来生成请求;每一次请求都会调用该方法,所以注意不要在该方法中做耗时的操作;

reponse在每次收到一个响应时调用;为提升性能,如果没有定义该方法,那么wrk不会解析headers和body;

结束阶段
function done(summary, latency, requests)

该方法在整个测试过程中只会调用一次,可从参数给定的对象中,获取压测结果,生成定制化的测试报告。

自定义脚本中可访问的变量和方法

变量:wrk

 wrk = {
    scheme  = "http",
    host    = "localhost",
    port    = nil,
    method  = "GET",
    path    = "/",
    headers = {},
    body    = nil,
    thread  = <userdata>,
  }

一个table类型的变量wrk,是全局变量,修改该table,会影响所有请求。

方法:wrk.fomat wrk.lookup wrk.connect

 function wrk.format(method, path, headers, body) wrk.format returns a HTTP request string containing the passed parameters
    merged with values from the wrk table.
    根据参数和全局变量wrk,生成一个HTTP rquest stringfunction wrk.lookup(host, service) wrk.lookup returns a table containing all known addresses for the host and service pair. This corresponds to the POSIX getaddrinfo() function.
    给定hostserviceport/well known service name),返回所有可用的服务器地址信息。 function wrk.connect(addr) wrk.connect returns true if the address can be connected to, otherwise
    it returns false. The address must be one returned from wrk.lookup().
    测试与给定的服务器地址信息是否可以成功创建连接
  1. 示例
使用POST METHOD
wrk.method = "POST" wrk.body   = "foo=bar&baz=quux" wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"

通过修改全局变量wrk,使得所有请求都使用POST方法,并指定了body和Content-Type头。

为每次request更换一个参数
request = function() uid = math.random(1, 10000000) path = "/test?uid=" .. uid return wrk.format(nil, path) end

通过在request方法中随机生成1~10000000之间的uid,使得请求中的uid参数随机。

每次请求之前延迟10ms
function delay() return 10 end
每个线程要先进行认证,认证之后获取token以进行压测
token = nil path = "/authenticate" request = function() return wrk.format("GET", path) end response = function(status, headers, body) if not token and status == 200 then token = headers["X-Token"] path = "/resource" wrk.headers["X-Token"] = token end end

在没有token的情况下,先访问/authenticate认证。认证成功后,读取token并替换path为/resource。

压测支持HTTP pipeline的服务
init = function(args) local r = {}
   r[1] = wrk.format(nil, "/?foo")
   r[2] = wrk.format(nil, "/?bar")
   r[3] = wrk.format(nil, "/?baz")

   req = table.concat(r) end request = function() return req end

通过在init方法中将三个HTTP request请求拼接在一起,实现每次发送三个请求,以使用HTTP pipeline。

https://www.cnblogs.com/xinzhao/p/6233009.html

HTTPS 安全最佳实践(三)之服务器nginx,OpenSSL

我们在最佳实践文章中建议大家如何去配置协议和密码套件,但是如果服务器软件(nginx、apache等)所使用的ssl协议库存在SSL漏洞,或者不支持那些现代化的密码套件和特性,那么无论你如何去修改配置都无法改善现在的安全问题。

所以我们在配置前,或者发现按照推荐配置进行了调整《SSL/TLS安全评估报告》还是无法满足要求,那么可以检查下所使用的OpenSSL等加密库是否版本过低。

如何检查OpenSSL版本

nginx

nginx -V

nginx version: nginx/1.10.2
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled 

或者通过openssl命令查看(适用于非自己通过openssl源码编译的)

openssl version

推荐的OpenSSL版本

  1. OpenSSL 1.0.2用户需更新到1.0.2h 以上。
  2. OpenSSL 1.0.1用户需更新到1.0.1t 以上。
  3. OpenSSL官方已停止对 0.9.8和 1.0.0 两个版本的升级维护,请使用这两个版本的用户将其升级至1.0.2h版本以上。

OpenSSL 1.0.1以下不支持tls1.2

升级前请做好测试

漏洞事件

https://www.trustasia.com/openssl-heartbleed

OpenSSL 1.0.1g 已修复该漏洞

OpenSSL 1.0.0 分支版本不受此漏洞影响

OpenSSL 0.9.8 分支版本不受此漏洞影响

OpenSSL 1.0.2 Beta2 不受此漏洞影响

Heartbleed检测工具>>

https://www.trustasia.com/OpenSSL-DROWN-attack

OpenSSL 1.0.1h+

OpenSSL 1.0.0m+

OpenSSL 0.9.8za+

https://www.trustasia.com/OpenSSL-CVE-2016-2107-Padding-Oracle

1、OpenSSL 1.0.2用户需更新到1.0.2h 。

2、OpenSSL 1.0.1用户需更新到1.0.1t 。

3、使用包管理系统的用户可以直接更新到2016年5月3日 之后的版本。

CBC padding oracle检测 检测工具>>

OpenSSL CCS漏洞

此漏洞是 OpenSSL ChangeCipherSpec 设计缺陷造成,被称为 CCS 注入漏洞。

https://www.trustasia.com/openssl-ccs

OpenSSL 1.1.0 应升级到 1.1.0a 或更高版本。

OpenSSL 1.0.2 应升级到 1.0.2i 或更高版本。

OpenSSL 1.0.1 应升级到 1.0.1u 或更高版本。

OpenSSL CCS 检测工具>>

注意:

OpenSSL官方已停止对 0.9.8和 1.0.0 两个版本的升级维护,请使用这两个版本的用户将其升级至更高版本。

HTTPS 安全最佳实践(二)之安全加固

当你的网站上了 HTTPS 以后,可否觉得网站已经安全了?这里 提供了一个 HTTPS 是否安全的检测工具,你可以试试。

本篇正文讲述的是 HTTP 安全的最佳实践,着重在于 HTTPS 网站的 Header 的相关配置。

1 连接安全性和加密

1.1 SSL/TLS

传输层安全(TLS)及其前身安全套接字层(SSL),通过在浏览器和 web 服务器之间提供端到端加密来促进机密通信。没有 TLS,就谈不上什么安全。TLS 是 HTTP 安全性的基础。

想要部署 TLS 是非常容易的,但其难点在于如何使用安全的配置来保障站点的安全。

尤其是 Protocol 版本和 Cipher 需要小心选择和配置。你可以通过本站 工具 体检你的网站,发现并解决这些细节的问题。

建议

所有本地和链接的资源需要正确的配置,且要使用 TLS。

1.2 HTTP Strict Transport Security (HSTS)

指示浏览器只使用 HTTPS 连接到目标服务器。这可以防止一些潜在的中间人攻击,包括 SSL 剥离,会话 cookie 窃取(如果没有被 适当保护)。如果遇到任何与证书相关的错误,它还可以阻止浏览器连接到网站。当浏览器访问一个设置相应 HTTP header 的 HTTPS 网站时,HSTS 将被激活。

HSTS 有一个固定期限,由 max-age 字段值控制。这个值可以是静态的,也可以是相对于将来某个特定日期的,你可以设置成 SSL 证书的过期时间。

在浏览器中,HSTS 首选项可以通过提交到 Chromium’s HSTS preload list 来硬编码,这是所有实现 HSTS 使用的浏览器。

注意,HSTS 确实有陷阱。它提供了 include subdomains 选项,这在实践中可能是太宽泛了。此外,客户端错误可能会造成严重的后果——客户端错误的时钟导致它认为服务器的 SSL 证书无效或过期,或者缺少根 CA 证书——将不再导致浏览器中的证书错误。浏览器将完全拒绝访问页面,并且可能会显示让安全专家之外的完全无法理解的错误。

建议

设置 HSTS header 长的生命周期,最好是半年及以上。

Strict-Transport-Security: max-age=31536000 

1.3 Public Key Pins

HTTP PKP(HPKP)指示浏览器只与提供的 SSL/TLS 的 HASH 相符或存在于同一证书链的服务器相连接。换句话说,如果 SSL/TLS 证书以一种意想不到的方式发生了变化,浏览器就无法连接到主机。这主要是针对受信任证书颁发机构(CA)或流氓 CA 证书颁发的伪造证书,用户可能会被骗安装。

例如,浏览器连接到 https://example.com,它存在这个头。header 告诉浏览器,如果证书 key 匹配,或者在发出证书链中有一个 key 匹配,那么在将来才会再次连接。其他的指令组合是可能的。它们都极大地减少了攻击者在客户端和合法主机之间模拟主机或拦截通信的可能性。

像 HSTS 一样,HPKP 在实现之前需要仔细的思考和计划。错误可以将用户锁定在您的站点之外,并且不容易修复。

像 HSTS 一样,HPKP 在实现之前需要仔细的思考和计划。错误可以将用户锁定在您的站点之外,并且不容易修复。

建议

确定是否需要为您的站点使用 PKP。如果是这样的话,那么从一个较小的实践开始,如果在一段时间之后没有遇到问题,就增加它。如果 SSL/TLS 密钥需要更新,建立备份计划。优先创建备份密钥和离线存储。

示例HTTP头:

Public-Key-Pins: max-age=5184000; pin-sha256="+oZq/vo3Kcv0CQPjpdwyInqVXmLiobmUJ3FaDpD/U6c="; pin-sha256="47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=" 

1.4 Mixed HTTPS and HTTP Content

主站点通过 HTTPS 安全地服务,但是在 HTTP 上加载一些文件(images、js、css)。这是一个巨大的安全漏洞,破坏了 HTTPS 提供的安全性。受影响的站点可能会泄漏会话 cookie 或用户行为信息。它们也可能容易受到注入和其他 MITM 攻击的攻击,而 HTTPS 通常会阻止这种攻击。

建议

如果 HTTPS 部署在主站上,请将任何地方的所有内容都 HTTPS 化(全站 HTTPS)。

2 Content security

2.1 Content Security Policy

为浏览器提供关于网站内容类型和行为的明确说明。良好的内容安全策略(CSP)可以帮助抵御跨站点脚本(XSS)和其他注入攻击等攻击。CSP 支持所有主要的浏览器,尽管只是部分地之前在 IE 11。

一个好的 CSP 是基于白名单的方法,不允许任何东西,除了明确允许的内容。它还限制了 javascript 的来源和允许操作。

CSP 很难启用遗留代码库。为了简化实现,CSP 提供了一个 report-only 模式,在浏览器中,CSP 的违规被发送到一个网站端点,但是该策略没有被强制执行。

新项目应该从一开始就使用 CSP。

建议

从限制性政策开始,在必要时放松。禁止所有的例子:

Content-Security-Policy: default-src 'none'; 

现在让我们允许自托管 scripts、images、CSS、fonts 和 AJAX,以及 jQuery CDN 托管脚本和 Google Analytics:

Content-Security-Policy: default-src 'none'; script-src 'self' https://code.jquery.com https://www.google-analytics.com; img-src 'self' https://www.google-analytics.com; connect-src 'self'; font-src 'self'; style-src 'self'; 

要注意的是,不要让所有的东西都破坏你的网站,例如,如果你使用 child-src 指令,而浏览器不支持它。一个不那么严格的政策可能从以下开始:

Content-Security-Policy: default-src 'self'; 

甚至更少的限制性政策甚至可以使用 default-src '*',然后添加限制。我建议你不要这么做,除非你完全明白其中的含义。否则,你可能会依赖 CSP,它只会给你一种错误的安全感。

2.2 Frame Options

控制站点是否可以放置在 <iframe><frame> 或 <object> 标签。不允许使用框架可以防止 clickjacking 攻击。例如,从 2015 年 2 月起,Internet Explorer’s universal cross-site-scripting bug 就被这个消息头减轻了。

X-Frame-Options 是一个非标准的 header,在内容安全策略级别 2 中被 frame ancestor指令所取代。然而,frame ancestor 还没有得到普遍的支持,而 X-Frame-Options 得到了广泛的支持。

建议

确定你的网站是否需要被允许呈现在一个 frame 中。完全不允许使用 sameorigin 拒绝或允许同源框架的选项。避免由于受限或 bug 浏览器支持而允许的选项。示例 HTTP 头:

X-Frame-Options: deny 

2.3 XSS Protection

跨站点脚本(XSS 或 CSS)的保护被构建到大多数流行的浏览器中,除了 Firefox 之外。这种保护是用户可配置的,可以关闭。因此,明确要求浏览器在你的网站上使用它的 XSS 过滤器是个好主意。

相反,网站可以要求 XSS 保护在页面的基础上被禁用。这绝对不是一个好主意。

建议

使用入校 HTTP header:

X-Xss-Protection: 1; block 

2.4 Cache Control

表示缓存页面输出的首选项。适当的值随网站数据的性质而变化,但强烈推荐使用偏好。否则,它取决于浏览器和代理来选择是否缓存内容。不恰当的选择可能会导致性能问题、安全问题,或者两者都有。

建议

开发缓存策略,然后将缓存首选项包括为 HTTP 头。

Cache-Control: public* 

其中的一个 public,private,no-cache 或 no-store。如果允许缓存,则应该将 max-age 值包含在 Cache-Control 以及 Etag 头文件中,以允许客户端缓存验证。

2.5 Content Type Options

当浏览器以不同的方式处理来自服务器的文件时,MIME 嗅探就是服务器指令。当一个网站承载不受信任的内容(如用户提供的)时,这是很危险的。假设服务器允许用户上传 image。如果用户上传 HTML 文档,浏览器可能会将其呈现为 web 执行 scriptpage,即使服务器明确表示正在发送 image。非标准的标头 X-Content-Type-Options选项指示浏览器不做任何模仿指定类型的 MIME。

建议

总是设置 header:

X-Content-Type-Options: nosniff 

2.6 Subresource Integrity

浏览器通常从外部域加载大量资源、javascript 和样式表。内容交付网络经常被使用。如果外部资源被破坏,依赖站点的安全性也可以。子资源完整性允许浏览器验证 javascript 或样式表未被意外修改。

建议

设置外部 javascript 和样式表的完整性属性。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js" integrity="sha384-6ePHh72Rl3hKio4HiJ841psfsRJveeS+aLoaEf3BWfS+gTF0XdAqku2ka8VddikM"></script> 

注意

您应该始终提供外部脚本的本地副本,并实现一种方法,以便在外部负载失败的情况下重新加载它们。否则你的网站可能会崩溃。例子:

<script>window.jQuery || document.write('<script src="/jquery.min.js"><\/script>')</script> 

2.7 Iframe Sandbox

iframe 在 WWW 上随处可见。网站平均有 5.1 iframe,主要用于装载第三方内容。这些 iframe 有很多方法来伤害托管网站,包括运行脚本和插件和重新引导访问者。sandbox属性允许对 iframe 中可以进行的操作进行限制。

建议

设置 iframe 的 sandbox 属性,然后添加所需的权限。

<iframe src="https://example.com" sandbox="allow-same-origin allow-scripts"></script> 

2.8 Server Clock

服务器包括所有响应的时间戳。不准确的时钟不会给客户机浏览器带来问题。然而,当与其他系统或服务交互时,问题就会出现。

建议

使用网络时间协议(NTP)来保持服务器时钟的准确性。

3 Information disclosure

3.1 Server Banner

大多数 web 服务器设置报头来识别自己和他们的版本号。这只服务于信息目的和实际用途是非常有限的。去掉整个头,而完全可以接受,通常是不必要的。但是,建议从头中删除版本号。在特定 web 服务器版本中存在 bug 的情况下,包括版本号可以作为对脚本 kiddy 的邀请来尝试对服务器的攻击。

建议

包含服务器名称但去掉版本号;

Server: nginx 

3.2 Web Framework Information

许多 web 框架设置 HTTP 头,识别框架或版本号。除了满足用户的好奇心,而且主要作为技术堆栈的广告,这几乎没有什么作用。这些头是不标准的,对浏览器渲染站点的方式没有影响。

虽然它们没有什么实际用途,但对于搜索运行过时版本的软件的机器人或蜘蛛来说,这些标头是无价的,因为这些软件可能包含安全漏洞。如果没有定期更新,这些头文件可以使网站的目标变得容易。

建议

从服务器响应中删除这些标头: X-Powered-ByX-RuntimeX-Version 和 X-AspNet-Version

4 Cookies

4.1 Cookie Security

包含敏感信息的 cookie,特别是会话 id,需要标记为安全的,假设网站是通过 HTTPS 传输的。这会阻止 cookie 通过 HTTP 发送明文文本。另一种方法是通过 HSTS 来阻止非安全 cookie 在 HTTP 上传输。建议使用安全 cookie 和 HSTS。

会话 cookie 应该与 HttpOnly 值进行标记,以防止它们被 javascript 访问。这可以防止攻击者利用 XSS 窃取会话 cookie。其他 cookie 可能不需要这样标记。但是,除非有明确的需要从 javascript 中访问他们的值,否则最好还是呆在安全的一边,把所有cookie标记为 HttpOnly

建议

标记所有 cookie 安全和 HttpOnly

Set-Cookie: Key=Value; path=/; secure; HttpOnly, Key2=Value2; secure; HttpOnly

https://blog.myssl.com/https-security-best-practices/

HTTPS 安全最佳实践(一)之SSL/TLS部署

SSL/TLS 是一种简单易懂的技术,它很容易部署及运行。但想要部署的安全通常是不容易的。这也使系统管理员和开发者不得不去了解 SSL 和 TLS 相关的技术,掌握如何配置一个安全的 web 服务器或应用。无疑会耗费很大的精力去看相关的技术文档,乏味且宽泛。

本篇文档的目的在于如何让系统管理员或开发者用尽可能少的时间部署一个安全的 web 站点或应用,即 SSL 和 TLS 部署最佳实践。

1 证书和私钥

在TLS中,所有的安全性都从服务器的密码标识开始;需要一个强大的私钥来防止攻击者进行模拟攻击。同样重要的是要有一个有效的和强大的证书,这将授予私有密匙作为一个特定主机名的权利。没有这两个基本的构建块,就没有其他东西可以安全了。

1.1 使用 2048 位私钥

对于大多数的 web 站点,提供一个 2048 的 RSA key 是足够安全的。RSA 的公钥算法是被普遍支持的,这使得这个类型的 key 作为默认是足够安全的。对于 2048 位,这些 key 提供了大约 112 位的安全性。如果您想要比这更多的安全性,请注意 RSA key 的伸缩性不太好。想要获得 128 位的安全性,你需要 3072 位 RSA key,这会很大的影响性能。ECDSA key 提供了一种提供更好安全性和更好性能的替代方法。对于 256 位,ECDSA key 提供 128 位安全性。少数古董客户端不支持 ECDSA,但现代客户端是支持的。如果您不介意管理这样一个设置的开销,那么您可以同时部署 RSA 和 ECDSA 密钥。

1.2 保护你的私钥

把你的私钥视为一项重要的资产,尽可能最大的使用你的私钥,限制最小的员工的访问。建议的政策包括以下内容:

  • 在可信计算机上用足够的熵生成私有密钥。一些 CA 为您提供生成私钥的功能,请尽量不要这样做。
  • 密码保护 key 最初就不要存储在备份系统中。私钥密码在生产环境中起不了什么作用,因为有知识的攻击者总是能够从进程内存中检索密钥。有硬件设备(被称为硬件安全模块,或 HSMs),即使在服务器折衷的情况下,也可以保护私有密匙,但是它们是昂贵的,因此仅适用于具有严格安全性需求的组织。
  • 妥协后,撤销旧证书并生成新密钥。
  • 每年更新证书,如果您可以自动化过程,则更频繁。大多数网站都应该假定不可靠的妥协证书被撤销; 因此,具有较短使用寿命的证书在实践中更加安全。
  • 除非保持相同的密钥对于公钥密钥很重要,否则每当获得新证书时,还应该生成新的私钥。

1.3 覆盖您的域名

确保您的证书涵盖您希望与网站一起使用的所有名称。您的目标是避免无效的证书警告,这会混淆用户,削弱他们的信心。

即使您期望只使用一个域名,请记住,您无法控制用户到达该网站的方式或其他人如何链接到该网站。在大多数情况下,您应该确保该证书与 www 前缀有关(例如,它适用于 example.com 和

www.example.com )。经验法则是,安全的 Web 服务器应该具有对配置为指向它的每个 DNS 名称有效的证书。

通配符证书能满足更广泛的需求,但如果准备将密钥暴露给更多的人员,特别是跨团队或部门,则避免使用它们。换句话说,访问私钥的人越少越好。还要注意,证书共享会创建一个可以被滥用的将漏洞从一个网站或服务器传输到使用相同证书的所有其他站点和服务器(即使底层私钥不同,只要证书域名匹配)的绑定。

1.5 从可信 CA 获取证书

选择对其证书业务和安全性可靠和认真的认证中心(CA)。选择 CA 时,请考虑以下条件:

安全状态 所有CA都经过定期审核,但有些则比其他 CA 更为严重。弄清哪些在这方面做的更好并不容易,但一个选择是检查他们的安全历史,更重要的是,他们如何反应妥协,如果他们从错误中学到了经验,这将更有利。

业务重点 CA 的活动构成其业务的重要组成部分,如果事情发生严重错误,其所有事情都将丢失,并且在其他地方追逐潜在的更有利可图的机会可能不会忽视其证书部门。

提供的服务 至少,您选择的 CA 应提供对证书吊销列表(CRL)和在线证书状态协议(OCSP)撤销方法的支持,具有稳定的网络可用性和性能。许多网站对域验证的证书感到满意,但您也应该考虑是否需要扩展验证(EV)证书。在任一种情况下,您都应该选择公钥算法。大多数网站今天使用 RSA,但由于其性能优势,ECDSA 在未来可能会变得重要。

证书管理 选项如果您需要大量证书并在复杂环境中运行,请选择一个 CA,为您提供良好的管理工具。

支持选择一个 CA,如果需要的话可以给您很好的支持。

注意

为了获得最佳效果,请提前获得证书,并在部署到生产之前至少一周。这种做法(1)有助于避免在计算机上没有正确时间的一些用户的证书警告;(2)有助于避免与 CA 需要额外时间的 CA 失败的撤销检查,以向 OCSP 响应者传播有效的新证书。随着时间的推移,尝试将这个“热身”期延长至 1-3 个月。同样,不要等到你的证书即将到期以替换它们。留下额外的几个月也会帮助时钟不正确的人在另一个方向。

1.6 使用强签名算法

证书安全性取决于(1)用于签署证书的私钥的强度,(2)签名中使用的散列函数的强度。直到最近,大多数证书都依赖于 SHA1 散列函数,现在被认为是不安全的。因此,我们正在向 SHA256 转型。截至 2016

年 1 月,您无法从公共 CA 获取 SHA1 证书。现有的 SHA1 证书将继续工作(在某些浏览器中有警告),但只能到 2016 年底。

2 配置

使用正确的 TLS 服务器配置,您可以确保将凭据正确呈现给站点的访问者,仅使用安全的加密原语,并减轻所有已知的缺陷。

2.1 使用完整的证书链

在大多数部署中,仅服务器证书不够的; 需要两个或多个证书来建立完整的信任链。当部署具有有效证书但没有所有必要的中间证书的服务器时,会发生常见的配置问题。为避免这种情况,只需使用 CA 提供给您的所有证书。

无效的证书链有效地使服务器证书无效并导致浏览器警告。实际上,这个问题有时难以诊断,因为一些浏览器可以重构不完整的链,有些浏览器不能重建。所有浏览器都倾向于缓存和重用中间证书。

2.2 使用安全的协议

SSL/TLS 系列中有五种协议:SSL v2,SSL v3,TLS v1.0,TLS v1.1和TLS v1.2:

  • SSL v2 是不安全的,不能使用。此协议版本非常糟糕,即使它们位于完全不同的服务器(DROWN 攻击)上也可以用来攻击具有相同名称的RSA 密钥和站点。
  • 当与 HTTP(POODLE 攻击)一起使用时,SSL v3 是不安全的,当与其他协议一起使用时,SSL v3 是弱的。它也是过时的,不应该被使用。
  • TLS v1.0 也是不应该使用的传统协议,但在实践中通常仍然是必需的。其主要弱点(BEAST)在现代浏览器中得到缓解,但其他问题仍然存在。
  • TLS v1.1 和 v1.2 都没有已知的安全问题,只有 v1.2 提供了现代的加密算法。

TLS v1.2 应该是您的主要协议,因为它是唯一提供现代认证加密(也称为 AEAD)的版本。如果您今天不支持 TLS v1.2,则缺乏安全性。

为了支持较旧的客户端,您可能需要继续支持 TLS v1.0 和TLS v1.1。但是,您应该计划在不久的将来退出 TLS v1.0。例如,PCI DSS 标准将要求所有接受信用卡付款的网站在 2018 年 6 月之前移除对 TLS v1.0 的支持。

目前正在开展设计 TLS v1.3 的工作,其目的是消除所有过时和不安全的功能,并进行改进,以保持我们的通信在未来几十年内的安全。

2.3 使用安全的套件

为了安全通信,您必须首先确定您正在与所需方(而不是通过将窃听的其他人)直接沟通并安全地交换数据。在 SSL 和 TLS 中,密码套件定义了如何进行安全通信。它们由不同的建筑组成,通过多样性实现安全。如果发现其中一个构建块软弱或不安全,那么您应该可以切换到另一个。

您应该主要依靠提供强身份验证和密钥交换,前向保密和至少 128 位加密的 AEAD 套件。还有一些其他较弱的套房可能仍然得到支持,只要它们只能与不支持任何更好的老客户进行协商。

有几个过时的加密原语必须避免:

  • 匿名 Diffie-Hellman(ADH)套件不提供身份验证。
  • NULL 密码套件不提供加密。
  • 导出密码套件在连接中协商时不安全,但也可以针对更喜欢更强大的套件(FREAK攻击)的服务器使用。
  • 弱密码(通常为 40 和 56 位)的套件使用可以轻松破坏的加密。
  • RC4 是不安全的。
  • 3DES 缓慢而虚弱。

使用以RSA和ECDSA键为基础的以下套件配置,作为起点:

TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 

警告

我们建议您始终首先在分段环境中测试TLS配置,仅在确定所有内容按预期工作时将更改应用到生产环境。请注意,以上是一个通用列表,并不是所有系统(特别是较旧的)支持所有套件。这就是为什么测试很重要,推荐您使用《SSL/TLS安全评估》进行检查。

上述示例配置使用标准 TLS 套件名称。一些平台使用非标准名称; 有关详细信息,请参阅您的平台的文档。例如,以下套件名称将与OpenSSL 一起使用:

ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES128-SHA
ECDHE-ECDSA-AES256-SHA
ECDHE-ECDSA-AES128-SHA256
ECDHE-ECDSA-AES256-SHA384
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-RSA-AES128-SHA
ECDHE-RSA-AES256-SHA
ECDHE-RSA-AES128-SHA256
ECDHE-RSA-AES256-SHA384
DHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES256-GCM-SHA384
DHE-RSA-AES128-SHA
DHE-RSA-AES256-SHA
DHE-RSA-AES128-SHA256
DHE-RSA-AES256-SHA256 

2.4 选择合适的协议

在SSL v3及更高版本的协议版本中,客户端提交他们支持的密码套件列表,服务器从列表中选择一个用于连接的套件。然而,并不是所有的服务器都做得很好,有些将从客户端列表中选择第一个支持的套件。使服务器主动选择最佳可用加密套件对于实现最佳安全性至关重要。

2.5 使用 FS

前向保密(有时也称为完全前向保密)是一种协议功能,可实现不依赖服务器私钥的安全对话。对于不提前向保密的密码套件,可以恢复服务器的私钥的人就可以解密所有较早记录的加密对话(也就是可以先大量记录密文,再解密,比如您的证书到期后没有正确销毁,它的私钥就能用来解密非PFS的密文)。您需要支持并喜欢 ECDHE 套件,以便通过现代网络浏览器实现前向保密。为了支持更广泛的客户,您还应该使用 DHE 套件作为 ECDHE 后备。避免 RSA 密钥交换,除非绝对必要。我在2.3节中提出的默认配置只包含提供前向保密的套件。

2.6 使用强的密钥交换算法

对于密钥交换,公共站点通常可以选择经典的短暂的 Diffie-Hellman密钥交换(DHE)和其椭圆曲线变体 ECDHE。还有其他的密钥交换算法,但是它们通常是以某种方式不安全的。RSA 密钥交换仍然很受欢迎,但不提供前向保密。

2015 年,一批研究人员发表了对 DHE 的新攻击; 他们的工作被称为Logjam 攻击。[2] 研究人员发现,较低强度的 DH 密钥交换(例如768 位)容易被破坏,一些知名的 1024 位 DH 组可被国家机构破坏。为了安全起见,如果部署 DHE,请至少配置 2048 位的安全性。一些较老的客户端(例如Java 6)可能不支持这种强度。出于性能原因,大多数服务器应该更喜欢 ECDHE,这是更强大和更快。在这种情况下,secp256r1命名曲线(也称为 P-256)是一个很好的选择。

3 减轻已知问题

近几年来已经发生了几次严重的 SSL 和 TLS 攻击,但是如果您正在运行最新的软件并遵循本指南的建议,那么它们通常不会关心您。(如果没有,我建议您使用 MYSSL 测试您的系统,并从中进行测试)。但是,没有什么是完全安全的,所以为了保持对安全性的了解,这是一个很好的做法。如果供应商补丁可用,请及时提供; 否则,依靠解决方案进行缓解。

4 性能

安全是我们在本指南中的主要重点,但我们也要注意表现; 一个不符合性能标准的安全服务无疑将被丢弃。通过正确配置,TLS 可以相当快。使用现代协议(例如 HTTP/2),甚至可能比明文通信更快。

4.1 避免过度安全

用于建立安全连接的密码握手是一种操作,其费用受私钥大小的高度影响。使用太短的密钥是不安全的,但使用太长的密钥将导致“太多”的安全性和缓慢的操作。对于大多数网站,使用超过 2048 位的 RSA 密钥和强大于 256 位的 ECDSA 密钥会浪费 CPU 功耗,并可能会损害用户体验。类似地,增加短暂密钥交换的强度对于 DHE 为 2048 位以及 ECDHE 为 256 位几乎没有什么好处。使用高于 128 位的加密没有明显的好处。

4.2 使用 session 恢复

会话恢复是一种性能优化技术,可以节省昂贵的密码操作的结果,并重复使用一段时间。残疾或非功能性会话恢复机制可能会引起显着的性能损失。

4.3 使用 WAN 优化和 HTTP/2

这些天,TLS 开销不是来自 CPU 饥饿的加密操作,而是来自网络延迟。只有在 TCP 握手完成后才能启动TLS握手,需要进一步交换数据包,并且离开服务器的距离更远。最小化延迟的最佳方法是避免创建新的连接 – 换句话说,保持现有的连接长时间(keep-alives)。提供良好结果的其他技术包括支持现代协议(如HTTP / 2)和使用WAN优化(通常通过内容传送网络)。

4.4 隐藏公共内容

通过TLS进行通信时,浏览器可能会认为所有流量都是敏感的。它们通常会使用内存来缓存某些资源,但一旦关闭浏览器,所有内容可能会丢失。为了获得性能提升,并能够长期缓存一些资源,将公共资源(例如图像)标记为公开。

4.5 使用 OCSP Stapling

OCSP 装订是 OCSP 协议的扩展,可以直接从服务器提供撤销信息作为 TLS 握手的一部分。因此,客户端不需要联系 OCSP 服务器进行带外验证,并且总体 TLS 连接时间显着减少。OCSP 装订是一种重要的优化技术,但您应该注意,并不是所有的网络服务器都提供了可靠的 OCSP 装订实现。结合具有缓慢或不可靠的 OCSP 响应者的 CA,这样的 Web 服务器可能会产生性能问题。为了获得最佳效果,请模拟故障条件,看看它们是否会影响您的可用性。

4.6 使用快速加密

除了提供最佳的安全性,我推荐的密码套件配置也提供了最好的性能。尽可能使用支持硬件加速 AES 的 CPU。之后,如果您真的想要进一步的性能优势(大多数网站可能不需要),请考虑使用 ECDSA 密钥。

5 HTTP 和 应用安全

HTTP 协议和 Web 应用交付的周边平台在 SSL 诞生后继续快速发展。作为这一进化的结果,该平台现在包含可用于打败加密的功能。在本节中,我们列出了这些功能,以及安全使用它们的方法。

5.1 加密无处不在

加密是可选的事实可能是今天最大的安全问题之一。我们看到以下问题:

  • 没有 TLS 需要它的网站
  • 具有 TLS 但不执行 TLS 的站点
  • 混合 TLS 和非 TLS 内容的网站,有时甚至在同一网页内
  • 编程错误的网站会颠覆 TLS

尽管如果您确切了解您正在做的事情,许多这些问题可以被缓解,可靠地保护网站通信的唯一方法是无一例外地执行加密。

5.2 消除混合内容

混合内容页面是通过 TLS 传输但是包含不通过 TLS 传输的资源(例如,JavaScript 文件,images,CSS 文件)的页面。这样的页面不安全。一个活跃的中间人(MITM)攻击者可以搭载一个单独的未受保护的 JavaScript 资源,例如劫持整个用户会话。即使您遵循上一节的建议并对整个网站加密,您仍然可能会最终从第三方网站中检索未加密的一些资源。

5.3 使用可信第三方

网站通常使用通过从另一个服务器下载的 JavaScript 代码激活的第三方服务。这种服务的一个很好的例子是 Google Analytics(分析),用于 Web 的大部分。这种包含第三方代码创建一个隐含的信任连接,有效地使对方完全控制您的网站。第三方可能不是恶意的,但是这些服务的大型提供商越来越被视为目标。推理很简单:如果大型提供程序受到威胁,攻击者将被自动访问所有依赖该服务的站点。

如果您遵循第4.2节的建议,至少您的第三方链接将被加密,从而避免 MITM 攻击。但是,您应该进一步了解:了解您使用的服务和删除服务,将其替换为更安全的替代方案,或接受其继续使用的风险。一种称为子资源完整性(SRI)的新技术可用于通过第三方资源来减少潜在的风险。[3]

5.4 安全 cookie

要正确安全,网站需要 TLS,而且所有的 Cookie 在创建时都被明确标记为安全的。未能保护 cookies 可以让活跃的 MITM 攻击者通过聪明的技巧来挑逗一些信息,即使在 100% 加密的网站上也是如此。为了获得最佳效果,请考虑为您的 Cookie 添加加密完整性验证或甚至加密。

5.5 安全 HTTP 压缩

2012 年 CRIME 攻击显示 TLS 压缩无法安全实施。唯一的解决方案是完全禁用 TLS 压缩。次年,随后再发生两次攻击。TIME 和 BREACH 专注于使用 HTTP 压缩压缩的 HTTP 响应实体中的秘密。与 TLS 压缩不同,HTTP 压缩是必需的,不能关闭。因此,为了解决这些攻击,需要对应用程序代码进行更改。[4]

TIME 和 BREACH 攻击并不容易实现,但是如果某人有足够的动力使用它们,则这种影响大致相当于成功的跨站点请求伪造(CSRF)攻击。

5.5 部署 HSTS

HTTP 严格传输安全(HSTS)是 TLS 的安全网。它旨在确保即使在配置问题和实施错误的情况下,安全性仍然保持不变。要激活 HSTS 保护,您可以向您的网站添加一个新的响应头。之后,支持 HSTS(此时所有现代浏览器)的浏览器执行它。

HSTS 的目标很简单:激活后,它不允许与使用它的网站进行任何不安全的通信。通过自动将所有明文链接转换为安全的链接,实现了这一目标。作为奖励,它还会禁用点击式证书警告。(证书警告是活动的 MITM 攻击的指标,研究表明大多数用户点击这些警告,所以绝对不要让他们感兴趣)。

添加对 HSTS 的支持是您可以为您的网站的 TLS 安全性做出的最重要的改进。新站点始终应设计为 HSTS,旧站点转换为尽可能快地支持。为了获得最佳安全性,请考虑使用 HSTS 预加载[5],将HSTS配置嵌入到现代浏览器中,从而使您的网站的第一个连接安全。

以下配置示例将在主主机名及其所有子域上激活一段时间为一年的 HSTS,同时还允许预加载:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload 

5.6 部署 CSP

内容安全策略(CSP)是网站可以用来限制浏览器操作的安全机制。尽管最初旨在解决跨站点脚本(XSS),CSP 不断发展,并支持对增强TLS安全性有用的功能。特别地,它可以用于限制混合内容,当涉及到第三方网站,HSTS没有帮助。

要部署CSP以防止第三方混合内容,请使用以下配置:

Content-Security-Policy: default-src https: 'unsafe-inline' 'unsafe-eval';
                         connect-src https: wss: 

注意

这不是部署 CSP 的最佳方法。为了提供不破坏混合内容以外的任何内容的示例,我不得不禁用某些默认安全功能。随着时间的推移,当您了解 CSP 的更多信息时,您应该更改您的策略以使其恢复。

5.7 不要缓存敏感内容

所有敏感内容必须仅传达给预定方,并由所有设备进行相应处理。虽然代理没有看到加密的流量,并且不能在用户之间共享内容,但是使用基于云的应用交付平台正在增加,这就是为什么在指定什么是公共的时候需要非常小心的是什么。

5.8 考虑其它威胁

TLS 旨在仅解决安全机密和您与用户之间通信的完整性的一个方面,但还有许多其他威胁需要处理。在大多数情况下,这意味着确保您的网站没有其他弱点。

6 验证

有许多配置参数可用于调整,预先知道某些变化会产生什么影响。此外,有时会意外地进行更改; 软件升级可以静默地引入更改。因此,我们建议您最初使用全面的 SSL/TLS 评估工具来验证您的配置,以确保您开始安全,然后定期确保您保持安全。对于公共网站,我们建议您免费使用SSL实验室服务器测试。[6]

6.1 高级主题

以下高级主题目前不在我们的指南范围之内。他们需要更深入地了解 SSL/TLS 和公钥基础设施(PKI),而且他们仍然被专家辩论。

6.2 使用 HPKP

公共密钥固定旨在使网站运营商有权限制哪些 CA 可以为其网站颁发证书。Google 已经部署了这个功能了一段时间(硬编码到他们的浏览器,Chrome),并且已被证明是非常有用的,以防止攻击并使公众了解它们。在 2014 年,Firefox 还增加了对硬编码固定的支持。现在可以使用一种称为 HTTP [7]的公钥固定扩展标准。公钥绑定解决了 PKI 最大的弱点(事实上,任何 CA 都可以为任何网站发布证书),但是这是一个成本; 部署需要大量精力和专业知识,并造成失去对您站点控制的风险(如果最终导致无效的固定配置)。你应该考虑固定很大程度上只有当你

6.2 使用 DNSSEC 和 DANE

域名系统安全扩展(DNSSEC)是一种增加域名系统完整性的技术。今天,一个活跃的网络攻击者可以轻松地劫持任何 DNS 请求并伪造任意的响应。使用 DNSSEC,所有响应都可以加密地跟踪到 DNS 根目录。命名实体的基于 DNS 的身份验证(DANE)是建立在 DNSSEC 之上的单独标准,用于提供 DNS 和 TLS 之间的绑定。DANE 可用于增强现有基于 CA 的 PKI 生态系统的安全性,或者完全绕过它。

即使不是每个人都同意,DNSSEC 是互联网的一个很好的方向,但对其的支持仍在继续改善。浏览器还不支持 DNSSEC 或 DANE(更喜欢 HSTS 和 HPKP 提供的类似功能),但有一些迹象表明它们正在开始用于提高电子邮件传递的安全性。

Nginx配置支持HTTP2

从 2015 年 5 月 14 日 HTTP/2 协议正式版的发布到现在已经快有一年了,越来越多的网站部署了 HTTP2,HTTP2 的广泛应用带来了更好的浏览体验,只要是 Modern 浏览器都支持,所以部署 HTTP2 并不会带来太多困扰。

虽然 h2 有 h2c (HTTP/2 Cleartext) 可以通过非加密通道传输,但是支持的浏览器初期还是比较少的,所以目前部署 h2 还是需要走加密的,不过由于 Let’s Encrypt 大力推行免费证书和证书的廉价化,部署 h2 的成本并不高。

介绍

HTTP 2.0即超文本传输协议 2.0,是下一代HTTP协议。是由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis (httpbis)工作小组进行开发。是自1999年http1.1发布后的首个更新。

HTTP/2 协议是从 SPDY 演变而来,SPDY 已经完成了使命并很快就会退出历史舞台(例如 Chrome 将在「2016 年初结束对 SPDY 的支持」;Nginx、Apache 也已经全面支持 HTTP/2 ,并也不再支持 SPDY)。

一般的大家把 HTTP2 简称为 h2,尽管有些朋友可能不怎么愿意,但是这个简称已经默认化了,特别是体现在浏览器对 HTTP2 都是这个简写的。

配置

普通的 HTTPS 网站浏览会比 HTTP 网站稍微慢一些,因为需要处理加密任务,而配置了 h2 的 HTTPS,在低延时的情况下速度会比 HTTP 更快更稳定!

现在电信劫持事件频发,网站部署了 HTTPS 加密后可以杜绝大部分劫持,但不是完全。像电子商务行业对 HTTPS 加密可是标配啊,因此部署 h2 更是势在必行。

证书

这里是 免费和便宜 SSL 证书介绍 ,大家可以从这里购买或者申请免费的 SSL 证书,免得 Chrome 弹出红色的页面令人不悦,从而拒绝了大多数访客。

Web 服务器

说明

默认编译的 Nginx 并不包含 h2 模块,我们需要加入参数来编译,截止发文,Nginx 1.9 开发版及以上版本源码需要自己加入编译参数,从软件源仓库下载的则默认编译。 Tengine 可以同时部署 h2 和 SPDY 保证兼容性,Nginx 则是一刀切不再支持 SPDY。

安装/编译

如果你编译的 Nginx 不支持,那么在 ./configure 中加入:--with-http_v2_module ,如果没有 SSL 支持,还需要加入 --with-http_ssl_module

然后 make && make install 即可。

配置

主要是配置 Nginx 的 server 块, 。
修改相关虚拟机的 .conf 文件,一般在 /usr/local/nginx/conf/vhost/ 或者 /etc/nginx/conf/,具体参考你的环境指导,不懂请回复。

server { listen 443 ssl http2 default_server; server_name www.mf8.biz; ssl_certificate /path/to/public.crt; ssl_certificate_key /path/to/private.key; 

注:将 server_name www.mf8.biz; 中的 www.mf8.biz 替换为你的域名。

然后通过 /usr/local/nginx/sbin/nginx -t 或者 nginx -t 来检测是否配置正确,然后重启 Nginx ,即可。

检验

在 Chrome 浏览器上可以通过,HTTP/2 and SPDY indicator 来检验,如果地址栏出现蓝色的闪电就是 h2

也可以在 chrome://net-internals/#http2 中检查。注意版本要新,姿势要帅!

配置进阶

大家都知道去年的心血漏洞将 SSL 推到了风口浪尖,所以单单支持了 h2 ,我们任然需要对 SSL 做一些安全的优化!

配置赫尔曼密钥

openssl dhparam -out dhparam.pem 2048 // 在 ssh 运行, openssl 生成 2048 位的密钥而不是当作参数写入 nginx.conf 文件。 ssl_dhparam /path/to/dhparam.pem; //在 .conf 中配置 

禁止不安全的 SSL 协议,使用安全协议

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

禁止已经不安全的加密算法

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:!CAMELLIA:!DES:!MD5:!PSK:!RC4';

也可以参考:ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;

缓解 BEAST 攻击

ssl_prefer_server_ciphers on;``` **启用 HSTS**

此举直接跳过 301 跳转,还降低了中间人攻击的风险!配置在 .conf 中即可 `add_header Strict-Transport-Security max-age=15768000;` **301 跳转** 80 端口跳转到 443 端口

server {
listen 80;
add_header Strict-Transport-Security max-age=15768000;
return 301 https://www.yourwebsite.com$request_uri;
}

 **缓存连接凭据** 

ssl_session_cache shared:SSL:20m;
ssl_session_timeout 60m;

 **OCSP 缝合** 

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/cert/trustchain.crt;
resolver 119.29.29.29 233.6.6.6 valid=300s;

nginx支持http2,openssl 升级openssl-1.1.0h https A+

首先升级openssl 到 openssl-1.1.0h

wget https://www.openssl.org/source/openssl-1.1.0h.tar.gz

tar -zxvf openssl-1.1.0h.tar.gz
cd openssl-1.1.0h

./config –prefix=/usr

make

make install

openssl version -a

nginx配置参考:

listen 443 ssl http2;
add_header Strict-Transport-Security max-age=15768001;
ssl_certificate /usr/local/nginx/conf/vhost/Nginx/1_www.dnsdizhi.com_bundle.crt;
ssl_certificate_key /usr/local/nginx/conf/vhost/Nginx/2_www.dnsdizhi.com.key;
ssl_session_cache    shared:SSL:10m;
ssl_session_timeout  10m;
ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
ssl_prefer_server_ciphers   on;

完毕后可以用:https://www.ssllabs.com/ssltest/  或者 https://myssl.com/ 检查就是能达到A+,当然其实达到A就不错了。如facebook、v.qq.com、www.google.com都是A。区别在哪里?就是没有配置add_header Strict-Transport-Security max-age=15768001;,说真的就是不用配置的,没必要。

centos6.5升级安装openssl 1.0.1u(最后更新版本,官网不再维护)

1、查看源版本
[root@zj ~]# openssl version -a
OpenSSL 1.0.1e
2、下载openssl-1.0.1u.tar.gz
wget wget https://www.openssl.org/source/old/1.0.1/openssl-1.0.1u.tar.gz
3、更新zlib
yum install -y zlib
4、解压安装
tar zxf openssl-1.0.1u.tar.gz
cd openssl-1.0.1u.tar.gz
./config shared zlib
make
make install
mv /usr/bin/openssl /usr/bin/openssl.bak
mv /usr/include/openssl /usr/include/openssl.bak
ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/ssl/include/openssl /usr/include/openssl
echo /usr/local/ssl/lib” >> /etc/ld.so.conf
ldconfig -v
5、查看是否升级成功
[root@zj ~]# openssl version -a
OpenSSL 1.0.1u  22 Sep 2016
built on: Tue May  8 11:13:07 2018
platform: linux-x86_64
options:  bn(64,64) rc4(8x,char) des(idx,cisc,16,int) idea(int) blowfish(idx)
compiler: gcc -I. -I.. -I../include  -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -DL_ENDIAN -O3 -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM

OPENSSLDIR: "/usr/ssl"


wget https://www.openssl.org/source/old/1.0.1/openssl-1.0.1u.tar.gz;tar -zxvf openssl-1.0.1u.tar.gz ;cd openssl-1.0.1u;./config --prefix=/usr;make;make install;ldconfig -v;openssl version -a

privoxy安装

Privoxy是一款带过滤功能的代理服务器,针对HTTP、HTTPS协议,经常跟Tor组合使用。通过Privoxy的超级过滤功能,用户从而可以保护隐私、对网页内容进行过滤、管理cookies,以及拦阻各种广告等。Privoxy可以用作单机,也可以应用到多用户的网络。
Privoxy可以把socks5转换为HTTP代理,也就是俗称的APN。

下载
https://nchc.dl.sourceforge.net/project/ijbswa/Sources/3.0.26%20%28stable%29/privoxy-3.0.26-stable-src.tar.gz

添加用户给 Privoxy
echo ‘privoxy:*:7777:7777:privoxy proxy:/no/home:/no/shell’ >> /etc/passwd

分配组给 Privoxy
echo ‘privoxy:*:7777:’ >> /etc/group

编译
autoreconf -if
./configure –prefix=/usr/local/privoxy
make && make install

编写启动脚本
vim /usr/local/privoxy/sbin/start.sh
写入
#!/bin/sh
./privoxy /usr/local/privoxy/etc/config

Nginx下利用rewrite实现强制跳转https

Nginx下利用rewrite实现强制跳转https

if ($scheme = http) {
rewrite ^(.*) https://$server_name$1 permanent;
}

以上代码直接放入主机给的rewrite规则中即可,其中

scheme #HTTP的方法(如http,https)

$1 permanent #规则为http://domains/xxx 跳转到https://domains/xxx

项目前期使用http,后期为了安全方面的考虑,启用了https。

项目架构:前端使用nginx作为多个tomcat实例的反向代理和负载均衡。

实际上只需要在nginx上启用https即可,使客户端与nginx之后使用https方式通信,而nginx与tomcat之间依然以http方式通信。

现在需要将之前客户端所有的http请求全部都自动重定向为https,只需要在nginx上添加相应配置即可。

如下配置实现来源于Nginx HTTP 跳转至 HTTPS,但是我都实践验证过。

另外,也加入了一些自己的理解整理而成。

方式1:使用rewrite指令

server {
    listen 80;
    server_name domain.com;
    rewrite ^(.*) https://$server_name$1 permanent;
}
server {
    listen 443 ssl;
    server_name domain.com;
    ssl on;
    ssl_certificate     /etc/nginx/ssl/domain.com.crt;
    ssl_certificate_key /etc/nginx/ssl/domain.com.crt;
    # other
}

如果此时nginx作为Tomcat的前端反向代理的话,需要将相应配置放在配置ssl的server块中。

方式2:使用return指令

server {
    listen 80;
    server_name domain.com;
    return 301 https://$server_name$request_uri;
}
server {
    listen 443 ssl;
    server_name domain.com;
    ssl on;
    ssl_certificate     /etc/nginx/ssl/domain.com.crt;
    ssl_certificate_key /etc/nginx/ssl/domain.com.crt;
    # other
}

如果此时nginx作为Tomcat的前端反向代理的话,需要将相应配置放在配置ssl的server块中。

方式三:使用error_page指令

只允许HTTP来访问时,用HTTP访问会让Nginx报497错误,然后利用error_page将链接重定向至HTTPS上。

server {
    listen 80;
    listen 443 ssl;
    server_name domain.com;
    ssl on;
    ssl_certificate     /etc/nginx/ssl/domain.com.crt; 
    ssl_certificate_key /etc/nginx/ssl/domain.com.crt;
    # other
    error_page 497 https://$server_name$request_uri;
}

使用error_page指令时,将http和https的监听配置写在同一个server块中,对应的其他配置也需要在该server配置块中完成。

需要注意的是,此时需要将error_page指令语句写在最后,否则不能生效。

nginx强制使用https访问(http跳转到https)

nginx的497状态码

error code 497

[html] view plain copy

 print?

  1. 497 – normal request was sent to HTTPS  

解释:当此虚拟站点只允许https访问时,当用http访问时nginx会报出497错误码

思路

利用error_page命令将497状态码的链接重定向到https://test.com这个域名上

配置

[html] view plain copy

 print?

  1. server {  
  2.     listen       192.168.1.11:443;  #ssl端口  
  3.     listen       192.168.1.11:80;   #用户习惯用http访问,加上80,后面通过497状态码让它自动跳到443端口  
  4.     server_name  test.com;  
  5.     #为一个server{……}开启ssl支持  
  6.     ssl                  on;  
  7.     #指定PEM格式的证书文件   
  8.     ssl_certificate      /etc/nginx/test.pem;   
  9.     #指定PEM格式的私钥文件  
  10.     ssl_certificate_key  /etc/nginx/test.key;  
  11.       
  12.     #让http请求重定向到https请求   
  13.     error_page 497  https://$host$uri?$args;  
  14. }