港囧720P和1080P1.88G高清国语字幕分享【种子下载】可离线-防和谐

00.png

港囧---720P--国语--中文字幕

不是高清哈 不过手机看还是比较清晰的。欢迎大家下载观看。

别的就不多说了。大家可以关注我的网盘,最新分享动态随时掌握!

下面放两张截图:01.jpg

02.jpg

720P地址:链接:http://pan.baidu.com/s/1gd97X5p 密码:fp65  

1080P地址:链接: http://pan.baidu.com/s/1qWmpePY 密码: 9wqp  http://pan.baidu.com/s/1gd2Mv2F  自己修改后缀为MP4

防止和谐地址 : 种子下载,可离线!mrxn.net分享[G囧 人再囧途之G囧][HD-TC.1080P.MP4]1.88GB[国语中字].rar

更新地址:http://pan.baidu.com/s/1hqB9vBA    链接:http://pan.baidu.com/s/1pJ9toM3 密码:xpzx

如果地址失效 请及时回复通知我!分享快乐!各位看官中秋快乐!


Mrxn 发布于 2015-9-27 08:40

95533发来积分换现金短信--小把戏-已举报-已日

今天媳妇儿手机收到一条95533发来的短信,说什么积分兑换,我媳妇儿还好很聪明,说自己的工行卡压根儿就没用过 -_-| 估计骗子也是醉了 哈哈  我也是醉了:Screenshot_com.miui.gallery_2015-09-26-10-40-35.png看着网址,就不是官方的。。。可是我还是好奇。进去看了一下:

Screenshot_com.mmbox.xbrowser_2015-09-26-10-37-08.pngScreenshot_com.mmbox.xbrowser_2015-09-26-10-37-31.png

Screenshot_com.mmbox.xbrowser_2015-09-26-10-37-53.pngScreenshot_com.mmbox.xbrowser_2015-09-26-10-37-53.png

看到底部的那个51la统计代码图片,我就笑了。。。工行官方的网站会这样的页面么!。。。再看他的所谓的要闻,点进去全是跳转到了工行官网。。。地址栏的变化还不足以证明它是假的么!然后搜索百度,发现还真有人上当的:QQ截图20150926115042.png

。。。随便看了一下。。。服务器是Windows server2003的,000044-2015-09-26.jpg

账号:lmobch95533 密码:955wap.lmobch.com33  不谢!已爆菊。。。(在我写文章这会儿不知道回复没有啊)

已举报!我是好孩子!:QQ截图20150926105016.png

最后提醒大家,遇到这些天上掉馅饼的好事,还是问问度娘,问问你身边的人,别一看见馅饼就两眼放光啥都不顾了。。。这些钓鱼,欺诈,只要你稍微细心一点就不会上当了。

最后想说的是,工行你为何这么伤!最近好多工行被欺诈的事。。。不说了,说多了都是泪。


Mrxn 发布于 2015-9-26 02:41

SSL证书与Https应用部署小结

为了提高网站的安全性,一般会在比较敏感的部分页面采用https传输,比如注册、登录、控制台等。像Gmail、网银等全部采用https传输。

https/ssl 主要起到两个作用:网站认证、内容加密传输和数据一致性。经CA签发的证书才起到认证可信的作用,所有有效证书均可以起到加密传输的作用。


浏览器与SSL证书
SSL应用部署小结 - hanguokai - 韩国恺的博客
上图是IE和Chrome上对https的不同表现。

SSL最主要应用是在浏览器和Web服务器之间,尽管不限于此。当然,安全本身是重要的内在属性。但在表面上看,部署SSL 就是为了让用户浏览器里看起来更安全一些,以增加用户的信任感。所以很多企业更把它当作门面,而签发机构也为此卖高价,尤其是国内的价格明显高于国外的。

实际上SSL证书也可以做客户端认证,用户拥有自己特有的证书,用它可以证明自己的身份,当然也就用不着用户名和密码了。但这种用的很少,一般web服务器也不支持。

内容加密传输更安全,如果只是为了加密,使用自签发的证书也可以,但浏览器无法验证证书,所以会给出一个非常吓人的警告,所以自签发证书不适合给外人使用,只适合内部使用,把这个证书 加入到自己的信任列表或忽略证书验证即可,以后就不会继续拦截了。

证书需要被少数一级或二级 CA 认证才有效。计算机安全中的信任就是一个信任链的关系,信任链最顶端的被称为根证书。
自签发的证书在技术上是完全一样的,仅用于加密传输是没问题的。但是不能被外人信任,所以一般仅用于内部使用。除了自签发不被信任,如果证书过期、已被吊销或者非证书所代表的域名也都是不被信任的,导致证书验证出错。

用于网站的证书需要被大众信任,所以不能自签发的证书,那就申请(购买)一个吧。


申请证书

1.证书类别
按证书包含域名数量分为:
  • 单域名:只针对这个域名有效,不能用在其它域名下。
  • 多域名:只针对列出的多个域名有效。
  • 通配符域名(wildcard):对任意子域名有小,显示的是 *.example.com。
注意:SSL所说的单个域名是一个完整的域名,一个子域名就算一个,而非一个顶级域名。
如果网站有很多子域名,只需要申请真正需要的域名证书。

按验证的类别分:
  • 域名认证(Domain Validation):认证你的域名所有权和网站,申请验证简单,几分钟即可。
  • 组织机构认证(Organization Validation):认证的域名和公司信息,需要提交公司资料认证。
  • 扩展认证(Extended Validation,简称EV):这种证书会在浏览器中出现“很明显”的绿色地址栏,给用户的可信度最高。有安全评估保证。
个人或小站点可用一类或二类,企业一般用二类认证,少数企业会用到EV认证。

2. 证书价格
看了看网上SSL证书的价格,便宜的一般都是10美元左右一个子域名/每年,按不同类别、不同品牌等价格在几十美元到几百美元一年。比如能显示绿色地址栏的EV证书和通配符证书贵一些。国内自己的或代理的,比国外贵不少,动辄几千元。其实就是由可信源认证了一下,类似于办证,用起来没什么差别,并非越贵越好。

3. 签发机构(“卖家”)

SSL应用部署小结 - hanguokai - 韩国恺的博客
国外常见的SSL提供商有:Thawte,Go Daddy,VeriSign,RapidSSL,GeoTrust(QuickSSL),StartSSL,Comodo。
StartSSL、Go Daddy的比较便宜,GeoTrust、Comodo的价格适中,Thawte和VeriSign的价格较贵。

VeriSign现在归属赛门铁克,在国内是由天威诚信代理的。世界真小,天威诚信就在我很多年以前的东家(启明星辰)大楼里,地下一层是他们的机房,我还进去过一次。

4. 免费的StartSSL
唯一免费的是StartSSL,其它的一般只提供30免费试用。

但 StartSSL 提供的免费证书是一类的、仅对域名和email进行验证,不对组织做验证(也就是面向自然人的,非面向组织机构的),不过
仅作为域名验证和数据加密也够了,并且浏览器也认它,一般人也不会去看你的证书级别。适合个人和初创网站使用,以后有钱了再申请个收费的替换即可。

我很顺利地申请到了免费的StartSSL证书,分别用在两个子域上。

最后,证书签发给你后,最主要是保护好私钥证书,这个丢失或泄漏就完了。因为如果被别人利用也就毫无安全性了,需要向证书签发机构申请撤销证书并申请新的证书,这当然也是要收费的。


应用规划、配置和调整
并不是说有了SSL证书就没事了,还要考虑应用中的使用问题,需要规划、服务器配置、应用调整等多个环节。

SSL比 http 要消耗更多cpu资源(主要是在建立连接的阶段,之后还要对内容加密),所以对一般网站,只需要对部分地方采用https,大部分开放内容是没必要的,具体取决于你的业务要求。比如对于很多安全要求较低的网站,完全不用https也是可接受的。

某些页面是同时支持 http 和 https ,还是只支持 https、强制 https?
同时支持就是用户用什么协议访问都可以,那么用户的请求主要就是由页面本身的链接引导来的,因为一般用户不会自己特意去修改地址栏的。
一般我们的网站可以做成同时支持http和https,都可以访问。但是这就容易有后面说的混合内容或混合脚本的问题。

还可以规划为部分页面支持 https,一般公开页面不用https,只是将部分地方的链接改为 https 就可以了。专门期望以 https 访问的页面中,引用的绝对URL可以明确的使用 https链接。

是否强制 https ?对于安全性高的网站或网站中的部分页面,可以强制使用https访问, 即使用户在地址栏里手工把 https 改为 http, 也会被自动重定向回 https 上。比如可以通过配置web服务器 rewrite 规则将这些 http url 自动重定向到对应的 https url 上(这样维护比较简单),而不用改应用

解决混合内容问题(http和https)

混合内容是指:在https的页面中混合了非https的资源请求,比如图片、css、js 等等。如果是混合了非 https 的 js 代码,则被称为混合脚本。
混合内容的危害:如果只是混合了不安全的图片和css,那么受中间人攻击篡改,一般只会影响页面的显示,危害相对小一点。如果是混合了不安全的 js 代码,则这个不安全的 js 可以完全访问和修改页面中的任何内容,这是非常危险的。

另请参看,Chrome对混合脚本危害的说明与提示:Trying to end mixed scripting vulnerabilities

所以,只有页面本身和所有引用的资源都是 https 的浏览器才认为是安全的,只要其中引用了非安全资源(即使图片),浏览器都会给出不安全的提示,特别是有 js 的情况。如果浏览器提示不安全,那样我们就达不到原来目的了。我们费了半天功夫去申请 SSL 证书,配置Web服务器,最后如果因为混合内容而前功尽弃就太糟了。咱继续努力吧,想办法让所有引用资源都是安全的。

理论上,混合了第三方的内容,即使是SSL的第三方内容也不是很好。因为用户信任的是你,而不是第三方,即使第三方也支持https,但你能保证第三方就绝对安全吗。不引用任何第三方才是绝对安全的,但这样太严格了,安全其实也是一个 tradeoff 的问题,需要考虑很多方面的平衡。还好,起码现在浏览器认为已经是安全的了。

引用第三方文件的问题(如 CDN 分发的文件)

简单地说,这个问题要么有第三方提供 https 支持,要么不用它(用自己本地的)。

一般我们会引用由 CDN 分发的文件,比如某个 js 库文件,而不用访问自己网站上的,这样借助 CDN 网络可以加快速度,这当然很好。
但是,如果我们在页面中使用绝对 URL 直接引用这个文件就无法自动使用 https 了!出现了混合协议内容,浏览器又该“变脸”了。

当SSL 遇上CDN 或 其它第三方文件就有点麻烦,因为很多CDN还不支持SSL。如果支持 https 的话就可以直接用 https 的绝对URL了,即使是同时支持http 和 https 的页面,这样做也不算太浪费,起码解决了问题。

因为CDN的云文件提供者,一般为每个cdn用户创建一个单独的子域名来使用,这样的话,CDN提供者要想支持 https 就必须支持所有可能的子域名,因此要求CDN提供方使用那种通配符子域名的证书。

相对 URL、绝对 URL 与 只缺协议的URL(Protocol Relative URL)
相对路径比较简单,自动匹配用户请求的 http 或 https 协议。

但是绝对 url 则不成,因为绝对 url 已经明确地写上了协议: http://www.example.com/jquery.js 。
这个问题还有一个办法解决,你一定没见过这种形式: //www.example.com/jquery.js
哈哈,一个缺少协议的URL(实际上还算是相对URL),这种形式可以在浏览器中被正确补充上合适的协议!很多人都用这种方法。
但是,这里有点小问题,IE7 和 IE8 处理这种缺少协议的URL的css 文件时,同一个css文件会下载两次,详见Steve的文章 。

JS 自动判断当前协议
现在我们经常用 js 来加载其它 js 文件或 其它别的文件,如果是请求是相对URL则没问题,如果是绝对URL怎么办?
其实 js 脚本可以这样:document.location.protocol 等于 'http:' 还是 'https:' 来判断。例如在 Google Analytics 的嵌入代码中:
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';

应用程序中如何判断访问协议
对于动态页面,如 jsp、php等,也是可以动态判断当前是否使用了 https 协议的。所以应用可以根据动态判断,来生成不同的引用 URL。这样虽然有点麻烦,但也算是解决了自动识别协议的问题,当然相对路径总是不需要处理的。
比如在 jsp 中:
  • request.isSecure() 为true 表示当前为 https ,false表示 http 访问
  • request.getScheme() 返回字符串 https 或 http
注意,如果 tomcat 部署在其它web服务器代理的后面,需要正确配置好才能返回正确结果,见本文最后一部分。

同源策略的问题
最后提醒一点:http 和 https是不同源的!即使后面的内容都一样。所以 ajax 发请求的时候要使用正确协议的绝对URL才行。
相对URL的 ajax 请求没关系。


Nginx 配置
小结一下 Nginx 配置SSL注意的问题,详细安装配置内容请参考其它资料,如官方 SSL模块 和 https配置文档
1. 首先检查一下是否已安装了 SSL模块,因为默认是不包含的。

用 nginx -V 命令检查一下。如果没有ssl模块则需要重新安装(建议升级到最新版本),注意安装时加上ssl 选项:
./configure --with-http_ssl_module

另外,nginx需要依赖 openssl 提供ssl支持,这个也要有。

2. nginx.conf 中的典型配置示例
listen     80;
listen    443 ssl;
ssl_certificate      cert.pem; #修改具体文件
ssl_certificate_key  ssl.key; #修改具体文件

ssl_session_cache    shared:SSL:10m;
ssl_session_timeout  10m;

ssl_protocols  SSLv2 SSLv3 TLSv1;
ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers   on;

上面第2-4项是关键。这些配置放在 server 块就可以对其中的所有 location 生效了,并且同时支持 http 和 https 。或者把 http 和 https 分开配置也很常见。

3. 合并证书配置文件
和Apache配置不同,Nginx需要将服务器证书和ca证书链合并到一个文件中,作为 ssl_certificate 配置的内容。
例如,按照证书链从下向上的顺序,我有三个证书:
  1. ssl.crt(自己域名的服务器证书)
  2. sub.class1.server.ca.pem(startssl 的一类证书)
  3. ca.pem(startssl 的根证书)
把它们的内容按顺序连接到的一个文件中,每个内容另起一行,中间没有空行或空格。

4. 避免启动时输入密码
配好之后,启动nginx 要你输入密钥的密码。这是因为 ssl_certificate_key 配置对应的文件(也就是 startssl 给你的私钥文件)内容是加密的,需要输入你创建这个时设置的密码才能解密。这样私钥虽然很安全,但是每次重启服务都要输入一次密码也太麻烦了。其实,只要证书改为解密了的内容,就可以避免每次输入密码。用如下命令即可:
openssl rsa -in ssl.key -out newssl.key  输入密码,就生成了解密后的私钥内容,使用这个就OK了。

但是就像前面说的,一定要在服务器上保护好它,例如:
chmod 400 ssl.key (仅root可读)

5. 优化SSL配置
SSL 很消耗 CPU 资源,尤其是在建立连接的握手阶段。一是通过开启 keepalive 可以重用连接。二是可以重用和共享ssl session,见上面ssl_session相关配置。



独立Tomcat+SSL
Tomcat 是很常见的 Java应用服务器,当然也可以作为独立的 Web服务器,所有用户请求直接访问 tomcat。

如果 Tomcat 作为独立的Web服务器,那么就需要配置Tomcat就可以了,文档参考这里 和 这个。主要是配置存放证书的 Keystore 和 连接器Connector。

Java的keystore
keystore 是 Java 中专用并内置的一个类似于 openssl 的工具,一个 keystore 文件就是一个“保险箱”(database),专门存放证书和密钥,和相关的管理功能:生成自签发的证书、密钥、导入导出等。可以通过 keytool 命令或 Java api 交互。
利用keytool 命令将你的证书导入进去。

Tomcat中Connector
tomcat中有三种 Connector 实现:block、nio 和 APR。前两者使用Java SSL(这需要 keystore 的配置 ),APR使用OpenSSL(不需要用keystore,直接指定证书),配置略有不同。



Nginx+Tomcat+SSL
实际上,规模的网站都有很多台Web服务器和应用服务器组成,用户的请求可能是经由 Varnish、HAProxy、Nginx之后才到应用服务器,中间有好几层。而中小规模的典型部署常见的是 Nginx+Tomcat 这种两层配置,而Tomcat 会多于一台,Nginx 作为静态文件处理和负载均衡。

如果Nginx作为前端代理的话,则Tomcat根本不需要自己处理 https,全是Nginx处理的。用户首先和Nginx建立连接,完成SSL握手,而后Nginx 作为代理以 http 协议将请求转给 tomcat 处理,Nginx再把 tomcat 的输出通过SSL 加密发回给用户,这中间是透明的,Tomcat只是在处理 http 请求而已。因此,这种情况下不需要配置 Tomcat 的SSL,只需要配置 Nginx 的SSL 和 Proxy。

在代理模式下,Tomcat 如何识别用户的直接请求(URL、IP、https还是http )?
在透明代理下,如果不做任何配置Tomcat 认为所有的请求都是 Nginx 发出来的,这样会导致如下的错误结果:
  • request.getScheme()  //总是 http,而不是实际的http或https
  • request.isSecure()  //总是false(因为总是http)
  • request.getRemoteAddr()  //总是 nginx 请求的 IP,而不是用户的IP
  • request.getRequestURL()  //总是 nginx 请求的URL 而不是用户实际请求的 URL
  • response.sendRedirect( 相对url )  //总是重定向到 http 上 (因为认为当前是 http 请求)

如果程序中把这些当实际用户请求做处理就有问题了。解决方法很简单,只需要分别配置一下 Nginx 和 Tomcat 就好了,而不用改程序。
配置 Nginx 的转发选项:

proxy_set_header       Host $host;
proxy_set_header  X-Real-IP  $remote_addr;
proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto  $scheme;

配置Tomcat server.xml 的 Engine 模块下配置一个 Value:
<Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="X-Forwarded-For" protocolHeader="X-Forwarded-Proto" protocolHeaderHttpsValue="https"/>

配置双方的 X-Forwarded-Proto 就是为了正确地识别实际用户发出的协议是 http 还是 https。X-Forwarded-For 是为了获得实际用户的 IP。

这样以上5项测试就都变为正确的结果了,就像用户在直接访问 Tomcat 一样。

原文地址:http://han.guokai.blog.163.com/blog/static/136718271201211631456811/


Mrxn 发布于 2015-9-24 14:51

nginx配置location总结及rewrite规则写法

1. location正则写法

一个示例:

location  = / {
  # 精确匹配 / ,主机名后面不能带任何字符串
  [ configuration A ] 
}
location  / {
  # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
  # 但是正则和最长字符串会优先匹配
  [ configuration B ] 
}
location /documents/ {
  # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
  # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
  [ configuration C ] 
}
location ~ /documents/Abc {
  # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
  # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
  [ configuration CC ] 
}
location ^~ /images/ {
  # 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
  [ configuration D ] 
}
location ~* \.(gif|jpg|jpeg)$ {
  # 匹配所有以 gif,jpg或jpeg 结尾的请求
  # 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则
  [ configuration E ] 
}
location /images/ {
  # 字符匹配到 /images/,继续往下,会发现 ^~ 存在
  [ configuration F ] 
}
location /images/abc {
  # 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在
  # F与G的放置顺序是没有关系的
  [ configuration G ] 
}
location ~ /images/abc/ {
  # 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用
    [ configuration H ] 
}
location ~* /js/.*/\.js


  • =开头表示精确匹配
    如 A 中只匹配根目录结尾的请求,后面不能带任何字符串。
  • ^~ 开头表示uri以某个常规字符串开头,不是正则匹配
  • ~ 开头表示区分大小写的正则匹配;
  • ~* 开头表示不区分大小写的正则匹配
  • / 通用匹配, 如果没有其它匹配,任何请求都会匹配到

顺序 no优先级:
(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)

上面的匹配结果
按照上面的location写法,以下的匹配示例成立:

  • / -> config A
    精确完全匹配,即使/index.html也匹配不了
  • /downloads/download.html -> config B
    匹配B以后,往下没有任何匹配,采用B
  • /images/1.gif -> configuration D
    匹配到F,往下匹配到D,停止往下
  • /images/abc/def -> config D
    最长匹配到G,往下匹配D,停止往下
    你可以看到 任何以/images/开头的都会匹配到D并停止,FG写在这里是没有任何意义的,H是永远轮不到的,这里只是为了说明匹配顺序
  • /documents/document.html -> config C
    匹配到C,往下没有任何匹配,采用C
  • /documents/1.jpg -> configuration E
    匹配到C,往下正则匹配到E
  • /documents/Abc.jpg -> config CC
    最长匹配到C,往下正则顺序匹配到CC,不会往下到E

实际使用建议

所以实际使用中,个人觉得至少有三个匹配规则定义,如下:
#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
    proxy_pass http://tomcat:8080/index
}
# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
    root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}
#第三个规则就是通用规则,用来转发动态请求到后端应用服务器
#非静态文件请求就默认是动态请求,自己根据实际把握
#毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了
location / {
    proxy_pass http://tomcat:8080/
}



http://tengine.taobao.org/book/chapter_02.html

http://nginx.org/en/docs/http/ngx_http_rewrite_module.html

2. Rewrite规则

rewrite功能就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。rewrite只能放在server{},location{},if{}中,并且只能对域名后边的除去传递的参数外的字符串起作用,例如http://seanlook.com/a/we/index.php?id=1&u=str 只对/a/we/index.php重写。语法rewrite regex replacement [flag];

如果相对域名或参数字符串起作用,可以使用全局变量匹配,也可以使用proxy_pass反向代理。

表明看rewrite和location功能有点像,都能实现跳转,主要区别在于rewrite是在同一域名内更改获取资源的路径,而location是对一类路径做控制访问或反向代理,可以proxy_pass到其他机器。很多情况下rewrite也会写在location里,它们的执行顺序是:

  1. 执行server块的rewrite指令
  2. 执行location匹配
  3. 执行选定的location中的rewrite指令

如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件;循环超过10次,则返回500 Internal Server Error错误。

2.1 flag标志位

  • last : 相当于Apache的[L]标记,表示完成rewrite
  • break : 停止执行当前虚拟主机的后续rewrite指令集
  • redirect : 返回302临时重定向,地址栏会显示跳转后的地址
  • permanent : 返回301永久重定向,地址栏会显示跳转后的地址

因为301和302不能简单的只返回状态码,还必须有重定向的URL,这就是return指令无法返回301,302的原因了。这里 last 和 break 区别有点难以理解:

  1. last一般写在server和if中,而break一般使用在location中
  2. last不终止重写后的url匹配,即新的url会再从server走一遍匹配流程,而break终止重写后的匹配
  3. break和last都能组织继续执行后面的rewrite指令

2.2 if指令与全局变量

if判断指令
语法为if(condition){...},对给定的条件condition进行判断。如果为真,大括号内的rewrite指令将被执行,if条件(conditon)可以是如下任何内容:

  • 当表达式只是一个变量时,如果值为空或任何以0开头的字符串都会当做false
  • 直接比较变量和内容时,使用=!=
  • ~正则表达式匹配,~*不区分大小写的匹配,!~区分大小写的不匹配

-f!-f用来判断是否存在文件
-d!-d用来判断是否存在目录
-e!-e用来判断是否存在文件或目录
-x!-x用来判断文件是否可执行

例如:

if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;
} //如果UA包含"MSIE",rewrite请求到/msid/目录下
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;
 } //如果cookie匹配正则,设置变量$id等于正则引用部分
if ($request_method = POST) {
    return 405;
} //如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302
if ($slow) {
    limit_rate 10k;
} //限速,$slow可以通过 set 指令设置
if (!-f $request_filename){
    break;
    proxy_pass  http://127.0.0.1; 
} //如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查
if ($args ~ post=140){
    rewrite ^ http://example.com/ permanent;
} //如果query string中包含"post=140",永久重定向到example.com
location ~* \.(gif|jpg|png|swf|flv)$ {
    valid_referers none blocked www.jefflei.com www.leizhenfang.com;
    if ($invalid_referer) {
        return 404;
    } //防盗链
}


全局变量
下面是可以用作if判断的全局变量

  • $args : #这个变量等于请求行中的参数,同$query_string
  • $content_length : 请求头中的Content-length字段。
  • $content_type : 请求头中的Content-Type字段。
  • $document_root : 当前请求在root指令中指定的值。
  • $host : 请求主机头字段,否则为服务器名称。
  • $http_user_agent : 客户端agent信息
  • $http_cookie : 客户端cookie信息
  • $limit_rate : 这个变量可以限制连接速率。
  • $request_method : 客户端请求的动作,通常为GET或POST。
  • $remote_addr : 客户端的IP地址。
  • $remote_port : 客户端的端口。
  • $remote_user : 已经经过Auth Basic Module验证的用户名。
  • $request_filename : 当前请求的文件路径,由root或alias指令与URI请求生成。
  • $scheme : HTTP方法(如http,https)。
  • $server_protocol : 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
  • $server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。
  • $server_name : 服务器名称。
  • $server_port : 请求到达服务器的端口号。
  • $request_uri : 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
  • $uri : 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
  • $document_uri : 与$uri相同。

例:http://localhost:88/test1/test2/test.php
$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:/var/www/html
$request_filename:/var/www/html/test1/test2/test.php

2.3 常用正则

  • . : 匹配除换行符以外的任意字符
  • ? : 重复0次或1次
  • + : 重复1次或更多次
  • * : 重复0次或更多次
  • \d :匹配数字
  • ^ : 匹配字符串的开始
  • $ : 匹配字符串的介绍
  • {n} : 重复n次
  • {n,} : 重复n次或更多次
  • [c] : 匹配单个字符c
  • [a-z] : 匹配a-z小写字母的任意一个

小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是\转义特殊字符。

2.4 rewrite实例

例1

http {
    # 定义image日志格式
    log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
    # 开启重写日志
    rewrite_log on;

    server {
        root /home/www;

        location / {
                # 重写规则信息
                error_log logs/rewrite.log notice; 
                # 注意这里要用‘’单引号引起来,避免{}
                rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
                # 注意不能在上面这条规则后面加上“last”参数,否则下面的set指令不会执行
                set $image_file $3;
                set $image_type $4;
        }

        location /data {
                # 指定针对图片的日志格式,来分析图片类型和大小
                access_log logs/images.log mian;
                root /data/images;
                # 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,如果还不在就跳转到最后一个url里
                try_files /$arg_file /image404.html;
        }
        location = /image404.html {
                # 图片不存在返回特定的信息
                return 404 "image not found\n";
        }
}


对形如/images/ef/uh7b3/test.png的请求,重写到/data?file=test.png,于是匹配到location /data,先看/data/images/test.png文件存不存在,如果存在则正常响应,如果不存在则重写tryfiles到新的image404 location,直接返回404状态码。

例2

rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;


对形如/images/bla_500x400.jpg的文件请求,重写到/resizer/bla.jpg?width=500&height=400地址,并会继续尝试匹配location。

例3
见 ssl部分页面加密 。

参考


原文地址:http://seanlook.com/2015/05/17/nginx-location-rewrite/



Mrxn 发布于 2015-9-24 14:29

基于OpenSSL自建CA和颁发SSL证书

关于SSL/TLS介绍见文章 SSL/TLS原理详解
关于证书授权中心CA以及数字证书等概念,请移步 OpenSSL 与 SSL 数字证书概念贴 。

openssl是一个开源程序的套件、这个套件有三个部分组成:一是libcryto,这是一个具有通用功能的加密库,里面实现了众多的加密库;二是libssl,这个是实现ssl机制的,它是用于实现TLS/SSL的功能;三是openssl,是个多功能命令行工具,它可以实现加密解密,甚至还可以当CA来用,可以让你创建证书、吊销证书。

默认情况ubuntu和CentOS上都已安装好openssl。CentOS 6.x 上有关ssl证书的目录结构:

/etc/pki/CA/
            newcerts    存放CA签署(颁发)过的数字证书(证书备份目录)
            private     用于存放CA的私钥
            crl         吊销的证书
/etc/pki/tls/
             cert.pem    软链接到certs/ca-bundle.crt
             certs/      该服务器上的证书存放目录,可以房子自己的证书和内置证书
                   ca-bundle.crt    内置信任的证书
             private    证书密钥存放目录
             openssl.cnf    openssl的CA主配置文件


1. 颁发证书

1.1 修改CA的一些配置文件

CA要给别人颁发证书,首先自己得有一个作为根证书,我们得在一切工作之前修改好CA的配置文件、序列号、索引等等。

vi /etc/pki/tls/openssl.cnf

...
[ CA_default ]
dir             = /etc/pki/CA           # Where everything is kept
certs           = $dir/certs            # Where the issued certs are kept
crl_dir         = $dir/crl              # Where the issued crl are kept
database        = $dir/index.txt        # database index file.
#unique_subject = no                    # Set to 'no' to allow creation of
                                        # several ctificates with same subject.
new_certs_dir   = $dir/newcerts         # default place for new certs.
certificate     = $dir/cacert.pem       # The CA certificate
serial          = $dir/serial           # The current serial number
crlnumber       = $dir/crlnumber        # the current crl number
                                        # must be commented out to leave a V1 CRL
crl             = $dir/crl.pem          # The current CRL
private_key     = $dir/private/cakey.pem # The private key
RANDFILE        = $dir/private/.rand    # private random number file
...
default_days    = 3650                  # how long to certify for
...
# For the CA policy
[ policy_match ]
countryName             = match
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
...
[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = CN
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = GD
...
[ req_distinguished_name ] 部分主要是颁证时一些默认的值,可以不动



一定要注意[ policy_match ]中的设定的匹配规则,是有可能因为证书使用的工具不一样,导致即使设置了csr中看起来有相同的countryName,stateOrProvinceName等,但在最终生成证书时依然报错:

Using configuration from /usr/lib/ssl/openssl.cnf
Check that the request matches the signature
Signature ok
The stateOrProvinceName field needed to be the same in the
CA certificate (GuangDong) and the request (GuangDong)



touch index.txt serial

在CA目录下创建两个初始文件:

# touch index.txt serial
# echo 01 > serial


1.2 生成根密钥

# cd /etc/pki/CA/
# openssl genrsa -out private/cakey.pem 2048


为了安全起见,修改cakey.pem私钥文件权限为600或400,也可以使用子shell生成( umask 077; openssl genrsa -out private/cakey.pem 2048 ),下面不再重复。

1.3 生成根证书

使用req命令生成自签证书:

# openssl req -new -x509 -key private/cakey.pem -out cacert.pem


会提示输入一些内容,因为是私有的,所以可以随便输入(之前修改的openssl.cnf会在这里呈现),最好记住能与后面保持一致。上面的自签证书cacert.pem应该生成在/etc/pki/CA下。

1.4 为我们的nginx web服务器生成ssl密钥

以上都是在CA服务器上做的操作,而且只需进行一次,现在转到nginx服务器上执行:

# cd /etc/nginx/ssl
# openssl genrsa -out nginx.key 2048


这里测试的时候CA中心与要申请证书的服务器是同一个。

1.5 为nginx生成证书签署请求

# openssl req -new -key nginx.key -out nginx.csr
...
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:GD
Locality Name (eg, city) []:SZ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:COMPANY
Organizational Unit Name (eg, section) []:IT_SECTION
Common Name (e.g. server FQDN or YOUR name) []:your.domain.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
...


同样会提示输入一些内容,其它随便,除了Commone Name一定要是你要授予证书的服务器域名或主机名,challenge password不填。

1.6 私有CA根据请求来签署证书

接下来要把上一步生成的证书请求csr文件,发到CA服务器上,在CA上执行:

# openssl ca -in nginx.csr -out nginx.crt
另外在极少数情况下,上面的命令生成的证书不能识别,试试下面的命令:
# openssl x509 -req -in server.csr -CA /etc/pki/CA/cacert.pem -CAkey /etc/pki/CA/private/cakey.pem -CAcreateserial -out server.crt


上面签发过程其实默认使用了-cert cacert.pem -keyfile cakey.pem,这两个文件就是前两步生成的位于/etc/pki/CA下的根密钥和根证书。将生成的crt证书发回nginx服务器使用。

到此我们已经拥有了建立ssl安全连接所需要的所有文件,并且服务器的crt和key都位于配置的目录下,剩下的是如何使用证书的问题。

2. 使用ssl证书

2.1 一般浏览器

浏览器作为客户端去访问https加密的服务器,一般不用去手动做其他设置,如https://www.google.com.hk,这是因为Chrome、FireFox、Safari、IE等浏览器已经内置了大部分常用的CA的根证书,但自建CA的根证书就不再浏览器的信任列表中,访问时会提示如下:
IE浏览器

openssl-https-browser-ie.png

谷歌浏览器openssl-https-browser.png

安装网站证书后(同时也有信任的根证书),地址栏一般会显示绿色小锁openssl-https-12306.png

证书信息openssl-https-browser-cert.png

导入证书到浏览器的方法:http://cnzhx.net/blog/self-signed-certificate-as-trusted-root-ca-in-windows/

2.2 为linux系统添加根证书

这一步不是必须的,一般出现在开发测试环境中,而且具体的应用程序应该提供添加证书的方法。

curl工具可以在linux上模拟发送请求,但当它去访问https加密网站时就会提示如下信息:

# curl https://sean:[email protected]:8000/
curl: (60) Peer certificate cannot be authenticated with known CA certificates
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.
提示上面的信息说明curl在linux的证书信任集里没有找到根证书,你可以使用curl --insecure来不验证证书的可靠性,这只能保证数据是加密传输的但无法保证对方是我们要访问的服务。使用curl --cacert cacert.pem可以手动指定根证书路径。我们也可以把根证书添加到系统(CentOS 5,6)默认的bundle:
# cp /etc/pki/tls/certs/ca-bundle.crt{,.bak}    备份以防出错
# cat /etc/pki/CA/cacert.pem >> /etc/pki/tls/certs/ca-bundle.crt
# curl https://sean:[email protected]:8000
"docker-registry server (dev) (v0.8.1)"

2.3 nginx

在nginx配置文件(可能是/etc/nginx/sites-available/default)的server指令下添加:


ssl on;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;

同时注意 server_name 与证书申请时的 Common Name 要相同,打开443端口。当然关于web服务器加密还有其他配置内容,如只对部分URL加密,对URL重定向实现强制https访问,请参考其他资料。

3 关于证书申请

注意,如果对于一般的应用,管理员只需生成“证书请求”(后缀大多为.csr),它包含你的名字和公钥,然后把这份请求交给诸如verisign等有CA服务公司(当然,连同几百美金),你的证书请求经验证后,CA用它的私钥签名,形成正式的证书发还给你。管理员再在web server上导入这个证书就行了。如果你不想花那笔钱,或者想了解一下原理,可以自己做CA。从ca的角度讲,你需要CA的私钥和公钥。从想要证书的服务器角度将,需要把服务器的证书请求交给CA。

如果你要自己做CA,别忘了客户端需要导入CA的证书(CA的证书是自签名的,导入它意味着你“信任”这个CA签署的证书)。而商业CA的一般不用,因为它们已经内置在你的浏览器中了。

参考

原文地址:http://seanlook.com/2015/01/18/openssl-self-sign-ca/


Mrxn 发布于 2015-9-24 14:13

OpenSSL 与 SSL 数字证书概念贴

SSL/TLS 介绍见文章 SSL/TLS原理详解
如果你想快速自建CA然后签发数字证书,请移步 基于OpenSSL自建CA和颁发SSL证书 

首先简单区分一下HTTPS、SSL、OpenSSL三者的关系:

SSL是在客户端和服务器之间建立一条SSL安全通道的安全协议,而OpenSSL是TLS/SSL协议的开源实现,提供开发库和命令行程序。常说的HTTPS是HTTP的加密版,底层使用的加密协议是SSL。

1. PKI、CA与证书

PKI 就是 Public Key Infrastructure 的缩写,翻译过来就是公开密钥基础设施。它是利用公开密钥技术所构建的,解决网络安全问题的,普遍适用的一种基础设施;是一种遵循既定标准的密钥管理平台,它能够为所有网络应用提供加密和数字签名等密码服务及所必需的密钥和证书管理体系。

PKI既不是一个协议,也不是一个软件,它是一个标准,在这个标准之下发展出的为了实现安全基础服务目的的技术统称为PKI。可以说CA(认证中心)是PKI的核心,而数字证书是PKI的最基本元素,还有如apache等服务器、浏览器等客户端、银行等应用,都是pki的组件。这篇文章可以帮助理解:PKI/CA 技术的介绍 。

1.1 CA

为保证用户之间在网上传递信息的安全性、真实性、可靠性、完整性和不可抵赖性

CA 机构,又称为证书认证中心 (Certificate Authority) 中心,是一个负责发放和管理数字证书的第三方权威机构,它负责管理PKI结构下的所有用户(包括各种应用程序)的证书,把用户的公钥和用户的其他信息捆绑在一起,在网上验证用户的身份。CA机构的数字签名使得攻击者不能伪造和篡改证书。

认证中心主要有以下5个功能:

  1. 证书的颁发:接收、验证用户(包括下级认证中心和最终用户)的数字证书的申请。可以受理或拒绝
  2. 证书的更新:认证中心可以定期更新所有用户的证书,或者根据用户的请求来更新用户的证书
  3. 证书的查询:查询当前用户证书申请处理过程;查询用户证书的颁发信息,这类查询由目录服务器ldap来完成
  4. 证书的作废:由于用户私钥泄密等原因,需要向认证中心提出证书作废的请求;证书已经过了有效期,认证中心自动将该证书作废。认证中心通过维护证书作废列表 (Certificate Revocation List,CRL) 来完成上述功能。
  5. 证书的归档:证书具有一定的有效期,证书过了有效期之后就将作废,但是我们不能将作废的证书简单地丢弃,因为有时我们可能需要验证以前的某个交易过程中产生的数字签名,这时我们就需要查询作废的证书。

1.2 Certificate

1.2.1 X.509标准

“SSL证书”这个词是一个相对较大的概念,整个PKI体系中有很多SSL证书格式标准。PKI的标准规定了PKI的设计、实施和运营,规定了PKI各种角色的”游戏规则”,提供数据语法和语义的共同约定。x.509是PKI中最重要的标准,它定义了公钥证书的基本结构,可以说PKI是在X.509标准基础上发展起来的:

  • SSL公钥证书
  • 证书废除列表CRL(Certificate revocation lists 证书黑名单)

参考 http://en.wikipedia.org/wiki/X.509 。

另外一个常用的标准是PKCS#12,通常采用pfx,p12作为文件扩展名,openssl和java的keytool工具都可以用作生产此类格式的证书。

1.2.2 ssl公钥证书格式

1. 证书版本号(Version)
版本号指明X.509证书的格式版本,现在的值可以为:
    1) 0: v1
    2) 1: v2
    3) 2: v3
也为将来的版本进行了预定义
2. 证书序列号(Serial Number)
序列号指定由CA分配给证书的唯一的"数字型标识符"。当证书被取消时,实际上是将此证书的序列号放入由CA签发的CRL中,
这也是序列号唯一的原因。
3. 签名算法标识符(Signature Algorithm)
签名算法标识用来指定由CA签发证书时所使用的"签名算法"。算法标识符用来指定CA签发证书时所使用的:
    1) 公开密钥算法
    2) hash算法
example: sha256WithRSAEncryption
须向国际知名标准组织(如ISO)注册
4. 签发机构名(Issuer)
此域用来标识签发证书的CA的X.500 DN(DN-Distinguished Name)名字。包括:
    1) 国家(C)
    2) 省市(ST)
    3) 地区(L)
    4) 组织机构(O)
    5) 单位部门(OU)
    6) 通用名(CN)
    7) 邮箱地址
5. 有效期(Validity)
指定证书的有效期,包括:
    1) 证书开始生效的日期时间
    2) 证书失效的日期和时间
每次使用证书时,需要检查证书是否在有效期内。
6. 证书用户名(Subject)
指定证书持有者的X.500唯一名字。包括:
    1) 国家(C)
    2) 省市(ST)
    3) 地区(L)
    4) 组织机构(O)
    5) 单位部门(OU)
    6) 通用名(CN)
    7) 邮箱地址
7. 证书持有者公开密钥信息(Subject Public Key Info)
证书持有者公开密钥信息域包含两个重要信息:
    1) 证书持有者的公开密钥的值
    2) 公开密钥使用的算法标识符。此标识符包含公开密钥算法和hash算法。
8. 扩展项(extension)
X.509 V3证书是在v2的基础上一标准形式或普通形式增加了扩展项,以使证书能够附带额外信息。标准扩展是指
由X.509 V3版本定义的对V2版本增加的具有广泛应用前景的扩展项,任何人都可以向一些权威机构,如ISO,来
注册一些其他扩展,如果这些扩展项应用广泛,也许以后会成为标准扩展项。
9. 签发者唯一标识符(Issuer Unique Identifier)
签发者唯一标识符在第2版加入证书定义中。此域用在当同一个X.500名字用于多个认证机构时,用一比特字符串
来唯一标识签发者的X.500名字。可选。
10. 证书持有者唯一标识符(Subject Unique Identifier)
持有证书者唯一标识符在第2版的标准中加入X.509证书定义。此域用在当同一个X.500名字用于多个证书持有者时,
用一比特字符串来唯一标识证书持有者的X.500名字。可选。
11. 签名算法(Signature Algorithm)
证书签发机构对证书上述内容的签名算法
example: sha256WithRSAEncryption
12. 签名值(Issuer's Signature)
证书签发机构对证书上述内容的签名值



example:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 9 (0x9)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, ST=GuangDong, L=ShenZhen, O=COMPANY Technologies Co., Ltd, OU=IT_SECTION, CN=registry.example.com.net/[email protected]
        Validity
            Not Before: Feb 11 06:04:56 2015 GMT
            Not After : Feb  8 06:04:56 2025 GMT
        Subject: C=CN, ST=GuangDong, L=ShenZhen, O=TP-Link Co.,Ltd., OU=Network Management, CN=172.31.1.210
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:a4:b0:dd:eb:c1:cf:5d:47:61:a6:ea:ef:8b:aa:
                    4b:f0:b4:2c:d8:96:c7:7c:ac:fa:c7:35:88:53:d0:
                    ...
                    8a:76:dc:8f:8c:44:c8:0b:3c:36:88:5f:01:f0:44:
                    4e:81:e6:7a:2b:ff:ba:da:33:a5:27:11:c6:f0:08:
                    6e:f3
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                07:C6:87:B7:C1:1E:28:E8:96:3F:EB:40:1E:82:41:45:CA:81:B6:3D
            X509v3 Authority Key Identifier: 
                keyid:A4:C2:14:6A:39:D1:95:1E:BD:DF:3B:92:4A:5C:12:42:1B:BC:53:B8
    Signature Algorithm: sha256WithRSAEncryption
         0c:c6:81:70:cd:0a:2d:94:4f:cb:a4:1d:ef:9e:8e:e4:73:ae:
         50:62:a8:9c:64:ef:56:0f:41:fe:6b:b4:d3:07:37:39:2c:ed:
         ...
         6f:62:61:b8:03:d7:97:31:ab:05:44:20:07:65:8b:ad:e2:cc:
         ad:65:73:f6:82:0f:9e:65:d0:ae:b7:1e:fd:9f:c1:d7:41:6c:
         0f:06:95:ee
-----BEGIN CERTIFICATE-----
MIIEMDCCAxigAwIBAgIBCTANBgkqhkiG9w0BAQsFADCBtTELMAkGA1UEBhMCQ04x
EjAQBgNVBAgMCUd1YW5nRG9uZzERMA8GA1UEBwwIU2hlblpoZW4xJjAkBgNVBAoM
...
ujwwRar6pPzusO95WuS93HsNmL2ZFZ63DS4LcW9iYbgD15cxqwVEIAdli63izK1l
c/aCD55l0K63Hv2fwddBbA8Gle4=
-----END CERTIFICATE-----


2. 附:数据加密的基础知识

对称密钥加密

对称密钥加密(一个密钥),也叫做共享密钥加密或机密密钥加密,使用发件人和收件人共同拥有的单个密钥。这种密钥既用于加密,也用于解密,叫做机密密钥。对称密钥加密是加密大量数据的一种行之有效的方法。

对称密钥加密有许多种算法如DES,RC4,IDEA等,但所有这些算法都有一个共同的目的:以可还原的方式将明文 (未加密的数据转换为暗文。暗文使用加密密钥编码,对于没有解密密钥的任何人来说它都是没有意义的。由于对称密钥加密在加密和解密时使用相同的密钥,所以这种加密过程的安全性取决于是否有未经授权的人获得了对称密钥。

衡量对称算法优劣的主要尺度是其密钥的长度。密钥越长,在找到解密数据所需的正确密钥之前必须测试的密钥数量就越多。需要测试的密钥越多,破解这种算法就越困难。

公钥加密

公钥加密使用两个密钥:一个公钥和一个私钥,这两个密钥在数学上是相关的。为了与对称密钥加密相对照,公钥加密有时也叫做不对称密钥加密。在公钥加密中,公钥可在通信双方之间公开传递,或在公用储备库中发布,但相关的私钥是保密的。只有使用私钥才能解密用公钥加密的数据。使用私钥加密的数据只能用公钥解密。下图中,发件人拥有收件人的公钥,并用它加密了一封邮件,但只有收件人掌握解密该邮件的有关私钥。

03.gif


公钥算法的主要局限在于,这种加密形式的速度相对较低。实际上,通常仅在关键时刻才使用公钥算法,如在实体之间交换对称密钥时,或者在签署一封邮件的散列时(散列是通过应用一种单向数学函数获得的一个定长结果,对于数据而言,叫做散列算法)。将公钥加密与其它加密形式(如对称密钥加密)结合使用,可以优化性能,如数字签名和密钥交换。

常用公钥算法:

  • RSA:适用于数字签名和密钥交换。 是目前应用最广泛的公钥加密算法,特别适用于通过 Internet 传送的数据,RSA算法以它的三位发明者的名字命名。
  • DSA:仅适用于数字签名。 数字签名算法 (Digital Signature Algorithm, DSA) 由美国国家安全署 (United States National Security Agency, NSA) 发明,已作为数字签名的标准。DSA 算法的安全性取决于自计算离散算法的困难。这种算法,不适用于数据加密。
  • Diffie-Hellman:仅适用于密钥交换。 Diffie-Hellman 是发明的第一个公钥算法,以其发明者 Whitfield Diffie 和 Martin Hellman 的名字命名。Diffie-Hellman 算法的安全性取决于在一个有限字段中计算离散算法的困难。

单向散列算法

散列,也称为散列值或消息摘要 ,是一种与基于密钥(对称密钥或公钥)的加密不同的数据转换类型。散列就是通过把一个叫做散列算法的单向数学函数应用于数据,将任意长度的一块数据转换为一个定长的、不可逆转的数字,其长度通常在128~256位之间。所产生的散列值的长度应足够长,因此使找到两块具有相同散列值的数据的机会很少。如发件人生成邮件的散列值并加密它,然后将它与邮件本身一起发送。而收件人同时解密邮件和散列值,并由接收到的邮件产生另外一个散列值,然后将两个散列值进行比较。如果两者相同,邮件极有可能在传输期间没有发生任何改变。

下面是几个常用的散列函数:

  • MD5:是RSA数据安全公司开发的一种单向散列算法,MD5被广泛使用,可以用来把不同长度的数据块进行暗码运算成一个128位的数值。
  • SHA-1:与 DSA 公钥算法相似,安全散列算法1(SHA-1)也是由 NSA 设计的,并由 NIST 将其收录到 FIPS 中,作为散列数据的标准。它可产生一个 160 位的散列值。SHA-1 是流行的用于创建数字签名的单向散列算法。
  • MAC(Message Authentication Code):消息认证代码,是一种使用密钥的单向函数,可以用它们在系统上或用户之间认证文件或消息,常见的是HMAC(用于消息认证的密钥散列算法)。
  • CRC(Cyclic Redundancy Check):循环冗余校验码,CRC校验由于实现简单,检错能力强,被广泛使用在各种数据校验应用中。占用系统资源少,用软硬件均能实现,是进行数据传输差错检测地一种很好的手段(CRC 并不是严格意义上的散列算法,但它的作用与散列算法大致相同,所以归于此类)。

数字签名:结合使用公钥与散列算法

数字签名是邮件、文件或其它数字编码信息的发件人将他们的身份与信息绑定在一起(即为信息提供签名)的方法。对信息进行数字签名的过程,需要将信息与由发件人掌握的秘密信息一起转换(使用私钥)为叫做签名的标记。数字签名用于公钥环境(任何人都可以拥有)中,它通过验证发件人确实是他或她所声明的那个人,并确认收到的邮件与发送的邮件完全相同。

散列算法处理数据的速度比公钥算法快得多。散列数据还缩短了要签名的数据的长度,因而加快了签名过程。

密钥交换:结合使用对称密钥与公钥

对称密钥算法非常适合于快速并安全地加密数据。但其缺点是,发件人和收件人必须在交换数据之前先交换机密密钥。结合使用加密数据的对称密钥算法与交换机密密钥的公钥算法可产生一种既快速又灵活的解决方案。

参考

原文地址:http://seanlook.com/2015/01/15/openssl-certificate-encryption/



Mrxn 发布于 2015-9-24 14:10

SSL/TLS原理详解

本文大部分整理自网络,相关文章请见文后参考。

关于证书授权中心CA以及数字证书等概念,请移步 OpenSSL 与 SSL 数字证书概念贴 ,如果你想快速自建CA然后签发数字证书,请移步 基于OpenSSL自建CA和颁发SSL证书 

SSL/TLS作为一种互联网安全加密技术,原理较为复杂,枯燥而无味,我也是试图理解之后重新整理,尽量做到层次清晰。正文开始。

1. SSL/TLS概览

1.1 整体结构

SSL是一个介于HTTP协议与TCP之间的一个可选层,其位置大致如下:

00.png 

  • SSL:(Secure Socket Layer,安全套接字层),为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取。当前版本为3.0。它已被广泛地用于Web浏览器与服务器之间的身份认证和加密数据传输。
    SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层: SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。

  • TLS:(Transport Layer Security,传输层安全协议),用于两个应用程序之间提供保密性和数据完整性。
    TLS 1.0是IETF(Internet Engineering Task Force,Internet工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本,可以理解为SSL 3.1,它是写入了 RFC 的。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面。

SSL/TLS协议提供的服务主要有:

  1. 认证用户和服务器,确保数据发送到正确的客户机和服务器;
  2. 加密数据以防止数据中途被窃取;
  3. 维护数据的完整性,确保数据在传输过程中不被改变。

1.2 TLS与SSL的差异

  1. 版本号:TLS记录格式与SSL记录格式相同,但版本号的值不同,TLS的版本1.0使用的版本号为SSLv3.1。
  2. 报文鉴别码:SSLv3.0和TLS的MAC算法及MAC计算的范围不同。TLS使用了RFC-2104定义的HMAC算法。SSLv3.0使用了相似的算法,两者差别在于SSLv3.0中,填充字节与密钥之间采用的是连接运算,而HMAC算法采用的是异或运算。但是两者的安全程度是相同的。
  3. 伪随机函数:TLS使用了称为PRF的伪随机函数来将密钥扩展成数据块,是更安全的方式。
  4. 报警代码:TLS支持几乎所有的SSLv3.0报警代码,而且TLS还补充定义了很多报警代码,如解密失败(decryption_failed)、记录溢出(record_overflow)、未知CA(unknown_ca)、拒绝访问(access_denied)等。
  5. 密文族和客户证书:SSLv3.0和TLS存在少量差别,即TLS不支持Fortezza密钥交换、加密算法和客户证书。
  6. certificate_verify和finished消息:SSLv3.0和TLS在用certificate_verify和finished消息计算MD5和SHA-1散列码时,计算的输入有少许差别,但安全性相当。
  7. 加密计算:TLS与SSLv3.0在计算主密值(master secret)时采用的方式不同。
  8. 填充:用户数据加密之前需要增加的填充字节。在SSL中,填充后的数据长度要达到密文块长度的最小整数倍。而在TLS中,填充后的数据长度可以是密文块长度的任意整数倍(但填充的最大长度为255字节),这种方式可以防止基于对报文长度进行分析的攻击。

TLS的主要增强内容

TLS的主要目标是使SSL更安全,并使协议的规范更精确和完善。TLS 在SSL v3.0 的基础上,提供了以下增强内容:

  1. 更安全的MAC算法
  2. 更严密的警报
  3. “灰色区域”规范的更明确的定义

TLS对于安全性的改进

  1. 对于消息认证使用密钥散列法:TLS 使用“消息认证代码的密钥散列法”(HMAC),当记录在开放的网络(如因特网)上传送时,该代码确保记录不会被变更。SSLv3.0还提供键控消息认证,但HMAC比SSLv3.0使用的(消息认证代码)MAC 功能更安全。
  2. 增强的伪随机功能(PRF):PRF生成密钥数据。在TLS中,HMAC定义PRF。PRF使用两种散列算法保证其安全性。如果任一算法暴露了,只要第二种算法未暴露,则数据仍然是安全的。
  3. 改进的已完成消息验证:TLS和SSLv3.0都对两个端点提供已完成的消息,该消息认证交换的消息没有被变更。然而,TLS将此已完成消息基于PRF和HMAC值之上,这也比SSLv3.0更安全。
  4. 一致证书处理:与SSLv3.0不同,TLS试图指定必须在TLS之间实现交换的证书类型。
  5. 特定警报消息:TLS提供更多的特定和附加警报,以指示任一会话端点检测到的问题。TLS还对何时应该发送某些警报进行记录。

2. 密钥协商过程——TLS握手

SSL协议分为两部分:Handshake Protocol和Record Protocol。其中Handshake Protocol用来协商密钥,协议的大部分内容就是通信双方如何利用它来安全的协商出一份密钥。 Record Protocol则定义了传输的格式。

由于非对称加密的速度比较慢,所以它一般用于密钥交换,双方通过公钥算法协商出一份密钥,然后通过对称加密来通信,当然,为了保证数据的完整性,在加密前要先经过HMAC的处理。

SSL缺省只进行server端的认证,客户端的认证是可选的。以下是其流程图(摘自TLS协议)。

000040-2015-09-24.jpg


2.1 客户端发出请求(ClientHello)

由于客户端(如浏览器)对一些加解密算法的支持程度不一样,但是在TLS协议传输过程中必须使用同一套加解密算法才能保证数据能够正常的加解密。在TLS握手阶段,客户端首先要告知服务端,自己支持哪些加密算法,所以客户端需要将本地支持的加密套件(Cipher Suite)的列表传送给服务端。除此之外,客户端还要产生一个随机数,这个随机数一方面需要在客户端保存,另一方面需要传送给服务端,客户端的随机数需要跟服务端产生的随机数结合起来产生后面要讲到的 Master Secret 。

综上,在这一步,客户端主要向服务器提供以下信息:

  1. 支持的协议版本,比如TLS 1.0版
  2. 一个客户端生成的随机数,稍后用于生成"对话密钥"
  3. 支持的加密方法,比如RSA公钥加密
  4. 支持的压缩方法

2.2 服务器回应(SeverHello)

上图中,从Server Hello到Server Done,有些服务端的实现是每条单独发送,有服务端实现是合并到一起发送。Sever Hello和Server Done都是只有头没有内容的数据。

服务端在接收到客户端的Client Hello之后,服务端需要将自己的证书发送给客户端。这个证书是对于服务端的一种认证。例如,客户端收到了一个来自于称自己是www.alipay.com的数据,但是如何证明对方是合法的alipay支付宝呢?这就是证书的作用,支付宝的证书可以证明它是alipay,而不是财付通。证书是需要申请,并由专门的数字证书认证机构(CA)通过非常严格的审核之后颁发的电子证书。颁发证书的同时会产生一个私钥和公钥。私钥由服务端自己保存,不可泄漏。公钥则是附带在证书的信息中,可以公开的。证书本身也附带一个证书电子签名,这个签名用来验证证书的完整性和真实性,可以防止证书被串改。另外,证书还有个有效期。

在服务端向客户端发送的证书中没有提供足够的信息(证书公钥)的时候,还可以向客户端发送一个 Server Key Exchange,

此外,对于非常重要的保密数据,服务端还需要对客户端进行验证,以保证数据传送给了安全的合法的客户端。服务端可以向客户端发出 Cerficate Request 消息,要求客户端发送证书对客户端的合法性进行验证。比如,金融机构往往只允许认证客户连入自己的网络,就会向正式客户提供USB密钥,里面就包含了一张客户端证书。

跟客户端一样,服务端也需要产生一个随机数发送给客户端。客户端和服务端都需要使用这两个随机数来产生Master Secret。

最后服务端会发送一个Server Hello Done消息给客户端,表示Server Hello消息结束了。

综上,在这一步,服务器的回应包含以下内容:

  1. 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信
  2. 一个服务器生成的随机数,稍后用于生成"对话密钥"
  3. 确认使用的加密方法,比如RSA公钥加密
  4. 服务器证书

2.3 客户端回应(Certificate Verify)

Client Key Exchange

如果服务端需要对客户端进行验证,在客户端收到服务端的 Server Hello 消息之后,首先需要向服务端发送客户端的证书,让服务端来验证客户端的合法性。

Certificate Verify
接着,客户端需要对服务端的证书进行检查,如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。如果证书没有问题,客户端就会从服务器证书中取出服务器的公钥。然后,向服务器发送下面三项信息:

  1. 一个随机数。该随机数用服务器公钥加密,防止被窃听
  2. 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送
  3. 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验

上面第一项的随机数,是整个握手阶段出现的第三个随机数,它是客户端使用一些加密算法(例如:RSA, Diffie-Hellman)产生一个48个字节的Key,这个Key叫 PreMaster Secret,很多材料上也被称作 PreMaster Key。

ChangeCipherSpec
ChangeCipherSpec是一个独立的协议,体现在数据包中就是一个字节的数据,用于告知服务端,客户端已经切换到之前协商好的加密套件(Cipher Suite)的状态,准备使用之前协商好的加密套件加密数据并传输了。

在ChangecipherSpec传输完毕之后,客户端会使用之前协商好的加密套件和Session Secret加密一段 Finish 的数据传送给服务端,此数据是为了在正式传输应用数据之前对刚刚握手建立起来的加解密通道进行验证。

2.4 服务器的最后回应(Server Finish)

服务端在接收到客户端传过来的 PreMaster 加密数据之后,使用私钥对这段加密数据进行解密,并对数据进行验证,也会使用跟客户端同样的方式生成 Session Secret,一切准备好之后,会给客户端发送一个 ChangeCipherSpec,告知客户端已经切换到协商过的加密套件状态,准备使用加密套件和 Session Secret加密数据了。之后,服务端也会使用 Session Secret 加密一段 Finish 消息发送给客户端,以验证之前通过握手建立起来的加解密通道是否成功。

根据之前的握手信息,如果客户端和服务端都能对Finish信息进行正常加解密且消息正确的被验证,则说明握手通道已经建立成功,接下来,双方可以使用上面产生的Session Secret对数据进行加密传输了。

2.5 几个secret

Secret Keys
上面的分析和讲解主要是为了突出握手的过程,所以PreMaster secret,Master secret,session secret都是一代而过,但是对于Https,SSL/TLS深入的理解和掌握,这些Secret Keys是非常重要的部分。所以,准备把这些Secret Keys抽出来单独分析和讲解。

我们先来看看这些Secret Keys的生成过程以及作用流程图:

000041-2015-09-24.jpg



PreMaster secret
PreMaster Secret是在客户端使用RSA或者Diffie-Hellman等加密算法生成的。它将用来跟服务端和客户端在Hello阶段产生的随机数结合在一起生成 Master Secret。在客户端使用服务端的公钥对PreMaster Secret进行加密之后传送给服务端,服务端将使用私钥进行解密得到PreMaster secret。也就是说服务端和客户端都有一份相同的PreMaster secret和随机数。

PreMaster secret前两个字节是TLS的版本号,这是一个比较重要的用来核对握手数据的版本号,因为在Client Hello阶段,客户端会发送一份加密套件列表和当前支持的SSL/TLS的版本号给服务端,而且是使用明文传送的,如果握手的数据包被破解之后,攻击者很有可能串改数据包,选择一个安全性较低的加密套件和版本给服务端,从而对数据进行破解。所以,服务端需要对密文中解密出来对的PreMaster版本号跟之前Client Hello阶段的版本号进行对比,如果版本号变低,则说明被串改,则立即停止发送任何消息。

关于PreMaster Secret(Key)的计算请参考 Https SSL/TLS PreMaster/Master Secret(Key)计算

Master secret
上面已经提到,由于服务端和客户端都有一份相同的PreMaster secret和随机数,这个随机数将作为后面产生Master secret的种子,结合PreMaster secret,客户端和服务端将计算出同样的Master secret。

Master secret是有系列的hash值组成的,它将作为数据加解密相关的secret的 Key Material 的一部分。Key Material最终解析出来的数据如下:

000042-2015-09-24.jpg



其中,write MAC key,就是session secret或者说是session key。Client write MAC key是客户端发数据的session secret,Server write MAC secret是服务端发送数据的session key。MAC(Message Authentication Code),是一个数字签名,用来验证数据的完整性,可以检测到数据是否被串改。

关于Session Secret(Key)的计算请参考 Https SSL/TLS Session Secret(Key)计算

2.6 应用数据传输

在所有的握手阶段都完成之后,就可以开始传送应用数据了。应用数据在传输之前,首先要附加上MAC secret,然后再对这个数据包使用write encryption key进行加密。在服务端收到密文之后,使用Client write encryption key进行解密,客户端收到服务端的数据之后使用Server write encryption key进行解密,然后使用各自的write MAC key对数据的完整性包括是否被串改进行验证。

2.7 总结

SSL客户端(也是TCP的客户端)在TCP链接建立之后,发出一个ClientHello来发起握手,这个消息里面包含了自己可实现的算法列表和其它一些需要的消息,SSL的服务器端会回应一个ServerHello,这里面确定了这次通信所需要的算法,然后发过去自己的证书(里面包含了身份和自己的公钥)。Client在收到这个消息后会生成一个秘密消息,用SSL服务器的公钥加密后传过去,SSL服务器端用自己的私钥解密后,会话密钥协商成功,双方可以用同一份会话密钥来通信了。

3. 附:密钥协商的形象化比喻

如果上面的说明不够清晰,这里我们用个形象的比喻,我们假设A与B通信,A是SSL客户端,B是SSL服务器端,加密后的消息放在方括号[]里,以突出明文消息的区别。双方的处理动作的说明用圆括号()括起。

A:我想和你安全的通话,我这里的对称加密算法有DES,RC5,密钥交换算法有RSA和DH,摘要算法有MD5和SHA。

B:我们用DES-RSA-SHA这对组合好了。
这是我的证书,里面有我的名字和公钥,你拿去验证一下我的身份(把证书发给A)。
目前没有别的可说的了。

A:(查看证书上B的名字是否无误,并通过手头早已有的CA的证书验证了B的证书的真实性,如果其中一项有误,发出警告并断开连接,这一步保证了B的公钥的真实性)
(产生一份秘密消息,这份秘密消息处理后将用作加密密钥,加密初始化向量(IV)和hmac的密钥。将这份秘密消息-协议中称为per_master_secret-用B的公钥加密,封装成称作ClientKeyExchange的消息。由于用了B的公钥,保证了第三方无法窃听)
我生成了一份秘密消息,并用你的公钥加密了,给你(把ClientKeyExchange发给B)
注意,下面我就要用加密的办法给你发消息了!
(将秘密消息进行处理,生成加密密钥,加密初始化向量和hmac的密钥)
[我说完了]

B:(用自己的私钥将ClientKeyExchange中的秘密消息解密出来,然后将秘密消息进行处理,生成加密密钥,加密初始化向量和hmac的密钥,这时双方已经安全的协商出一套加密办法了)
注意,我也要开始用加密的办法给你发消息了!
[我说完了]

A: [我的秘密是...]

B: [其它人不会听到的...]

4. SSL安全性

SecurityPortal在2000年底有一份文章《The End of SSL and SSH?》激起了很多的讨论, 目前也有一些成熟的工具如dsniff(http://www.monkey.org/~dugsong/dsniff/)可以通过man in the middle攻击来截获https的消息。

从上面的原理可知,SSL的结构是严谨的,问题一般出现在实际不严谨的应用中。常见的攻击就是middle in the middle攻击,它是指在A和B通信的同时,有第三方C处于信道的中间,可以完全听到A与B通信的消息,并可拦截,替换和添加这些消息。

  1. SSL可以允许多种密钥交换算法,而有些算法,如DH,没有证书的概念,这样A便无法验证B的公钥和身份的真实性,从而C可以轻易的冒充,用自己的密钥与双方通信,从而窃听到别人谈话的内容。
    而为了防止middle in the middle攻击,应该采用有证书的密钥交换算法。
  2. 有了证书以后,如果C用自己的证书替换掉原有的证书之后,A的浏览器会弹出一个警告框进行警告,但又有多少人会注意这个警告呢?
  3. 由于美国密码出口的限制,IE,netscape等浏览器所支持的加密强度是很弱的,如果只采用浏览器自带的加密功能的话,理论上存在被破解可能。

5. 代理

下面探讨一下SSL的代理是怎样工作的
当在浏览器里设置了https的代理,而且里输入了https://www.example.com之后,浏览器会与proxy建立tcp链接,然后向其发出这么一段消息:

 CONNECT server.example.com:443 HTTP/1.1
   Host: server.example.com:443 

然后proxy会向webserver端建立tcp连接,之后,这个代理便完全成了个内容转发装置。浏览器与web server会建立一个安全通道,因此这个安全通道是端到端的,尽管所有的信息流过了proxy,但其内容proxy是无法解密和改动的(当然要由证书的支持,否则这个地方便是个man in the middle攻击的好场所,见上面的安全部分)。

CA证书以及如何使用OpenSSL自签署,见文章OpenSSL自签署证书 。

6. 参考

原文链接地址:http://seanlook.com/2015/01/07/tls-ssl-understand/ (国外,需要梯子请在本博客搜索,关键字:查资料)



Mrxn 发布于 2015-9-24 13:58

nginx配置ssl加密(单双向认证、部分https)

nginx下配置ssl本来是很简单的,无论是去认证中心买SSL安全证书还是自签署证书,但最近公司OA的一个需求,得以有个机会实际折腾一番。一开始采用的是全站加密,所有访问http:80的请求强制转换(rewrite)到https,后来自动化测试结果说响应速度太慢,https比http慢慢30倍,心想怎么可能,鬼知道他们怎么测的。所以就试了一下部分页面https(不能只针对某类动态请求才加密)和双向认证。下面分节介绍。

默认nginx是没有安装ssl模块的,需要编译安装nginx时加入--with-http_ssl_module选项。

关于SSL/TLS原理请参考 这里,如果你只是想测试或者自签发ssl证书,参考 这里 。

提示:nignx到后端服务器由于一般是内网,所以不加密。

1. 全站ssl

全站做ssl是最常见的一个使用场景,默认端口443,而且一般是单向认证。

server {
        listen 443;
        server_name example.com;
        root /apps/www;
        index index.html index.htm;
        ssl on;
        ssl_certificate ../SSL/ittest.pem;
        ssl_certificate_key ../SSL/ittest.key;
#        ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
#        ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
#        ssl_prefer_server_ciphers on;
}



如果想把http的请求强制转到https的话:

server {
  listen      80;
  server_name example.me;
  rewrite     ^   https://$server_name$request_uri? permanent;
### 使用return的效率会更高 
#  return 301 https://$server_name$request_uri;
}


ssl_certificate证书其实是个公钥,它会被发送到连接服务器的每个客户端,ssl_certificate_key私钥是用来解密的,所以它的权限要得到保护但nginx的主进程能够读取。当然私钥和证书可以放在一个证书文件中,这种方式也只有公钥证书才发送到client。

ssl_protocols指令用于启动特定的加密协议,nginx在1.1.13和1.0.12版本后默认是ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2,TLSv1.1与TLSv1.2要确保OpenSSL >= 1.0.1 ,SSLv3 现在还有很多地方在用但有不少被攻击的漏洞。

ssl_ciphers选择加密套件,不同的浏览器所支持的套件(和顺序)可能会不同。这里指定的是OpenSSL库能够识别的写法,你可以通过 openssl -v cipher 'RC4:HIGH:!aNULL:!MD5'(后面是你所指定的套件加密算法) 来看所支持算法。

ssl_prefer_server_ciphers on设置协商加密算法时,优先使用我们服务端的加密套件,而不是客户端浏览器的加密套件。

https优化参数

  • ssl_session_cache shared:SSL:10m; : 设置ssl/tls会话缓存的类型和大小。如果设置了这个参数一般是sharedbuildin可能会参数内存碎片,默认是none,和off差不多,停用缓存。如shared:SSL:10m表示我所有的nginx工作进程共享ssl会话缓存,官网介绍说1M可以存放约4000个sessions。 详细参考serverfault上的问答ssl_session_cache
  • ssl_session_timeout : 客户端可以重用会话缓存中ssl参数的过期时间,内网系统默认5分钟太短了,可以设成30m即30分钟甚至4h

设置较长的keepalive_timeout也可以减少请求ssl会话协商的开销,但同时得考虑线程的并发数了。

提示:在生成证书请求csr文件时,如果输入了密码,nginx每次启动时都会提示输入这个密码,可以使用私钥来生成解密后的key来代替,效果是一样的,达到免密码重启的效果:

 
openssl rsa -in ittest.key -out ittest_unsecure.key


导入证书

如果你是找一个知名的ssl证书颁发机构如VeriSign、Wosign、StartSSL签发的证书,浏览器已经内置并信任了这些根证书,如果你是自建C或获得二级CA授权,都需要将CA证书添加到浏览器,这样在访问站点时才不会显示不安全连接。各个浏览的添加方法不在本文探讨范围内。

2. 部分页面ssl

一个站点并不是所有信息都是非常机密的,如网上商城,一般的商品浏览可以不通过https,而用户登录以及支付的时候就强制经过https传输,这样用户访问速度和安全性都得到兼顾。

但是请注意不要理解错了,是对页面加密而不能针对某个请求加密,一个页面或地址栏的URL一般会发起许多请求的,包括css/png/js等静态文件和动态的java或php请求,所以要加密的内容包含页面内的其它资源文件,否则就会出现http与https内容混合的问题。在http页面混有https内容时,页面排版不会发生乱排现象;在https页面中包含以http方式引入的图片、js等资源时,浏览器为了安全起见会阻止加载。

下面是只对example.com/account/login登录页面进行加密的例子:

root /apps/www;
index index.html index.htm;
server {
    listen      80;
    server_name example.com;
    location ^~ /account/login {
        rewrite ^ https://$server_name:443$request_uri? permanent;
    }
    location / {
        proxy_pass  http://localhost:8080;

        ### Set headers ####
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect     off; 
    }
}
server {
    listen 443 ssl;
    server_name example.com;
    ssl on;
    ssl_certificate ../SSL/ittest.pem;
    ssl_certificate_key ../SSL/ittest.key;
    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers on;
    location ^~ /account/login {
        proxy_pass  http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect     off; 
        ### Most PHP, Python, Rails, Java App can use this header -> https ###
        proxy_set_header X-Forwarded-Proto  $scheme;
    }
    location / {
        rewrite  ^  http://$server_name$request_uri? permanent;
    }
}


关于rewrite与location的写法参考这里。当浏览器访问http://example.com/account/login.xx时,被301到https://example.com/account/login.xx,在这个ssl加密的虚拟主机里也匹配到/account/login,反向代理到后端服务器,后面的传输过程是没有https的。这个login.xx页面下的其它资源也是经过https请求nginx的,登录成功后跳转到首页时的链接使用http,这个可能需要开发代码里面控制。

  • 上面配置中使用了proxy_set_header X-Forwarded-Proto $scheme,在jsp页面使用request.getScheme()得到的是https 。如果不把请求的$scheme协议设置在header里,后端jsp页面会一直认为是http,将导致响应异常。
  • ssl配置块还有个与不加密的80端口类似的location /,它的作用是当用户直接通过https访问首页时,自动跳转到不加密端口,你可以去掉它允许用户这样做。

3. 实现双向ssl认证

上面的两种配置都是去认证被访问的站点域名是否真实可信,并对传输过程加密,但服务器端并没有认证客户端是否可信。(实际上除非特别重要的场景,也没必要去认证访问者,除非像银行U盾这样的情况)

要实现双向认证HTTPS,nginx服务器上必须导入CA证书(根证书/中间级证书),因为现在是由服务器端通过CA去验证客户端的信息。还有必须在申请服务器证书的同时,用同样的方法生成客户证书。取得客户证书后,还要将它转换成浏览器识别的格式(大部分浏览器都认识PKCS12格式):

openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12


然后把这个client.p12发给你相信的人,让它导入到浏览器中,访问站点建立连接的时候nginx会要求客户端把这个证书发给自己验证,如果没有这个证书就拒绝访问。

同时别忘了在 nginx.conf 里配置信任的CA:(如果是二级CA,请把根CA放在后面,形成CA证书链)

proxy_ignore_client_abort on;
    ssl on;
    ...
    ssl_verify_client on;
    ssl_verify_depth 2;
    ssl_client_certificate ../SSL/ca-chain.pem;
# 在双向location下加入:
    proxy_set_header X-SSL-Client-Cert $ssl_client_cert;


拓展:使用geo模块

nginx默认安装了一个ngx_http_geo_module,这个geo模块可以根据客户端IP来创建变量的值,用在如来自172.29.73.0/24段的IP访问login时使用双向认证,其它段使用一般的单向认证。

geo $duplexing_user {
    default 1;
    include geo.conf;  # 注意在0.6.7版本以后,include是相对于nginx.conf所在目录而言的
}



语法 geo [$address] $variable { … },位于http段,默认地址是$reoute_addr,假设 conf/geo.conf 内容:

127.0.0.1/32    LOCAL;  # 本地
172.29.73.23/32 SEAN;   # 某个IP
172.29.73.0/24  1;      # IP段,可以按国家或地域定义后面的不同的值




需要配置另外一个虚拟主机server{ssl 445},里面使用上面双向认证的写法,然后在80或443里使用变量$duplexing_user去判断,如果为1就rewrite到445,否则rewrite到443。具体用法可以参考nginx geo使用方法

参考

原文地址:http://seanlook.com/2015/05/28/nginx-ssl/



Mrxn 发布于 2015-9-24 13:48

一段代码让nginx实现网站资源防盗链

000038-2015-09-24.jpg

很多人喜欢复制粘贴别人的东西,这没啥,说明有价值,作者应该高兴,但是呢,不留出处,这就不好了,于是呢,可以再服务器段简单的设置一下实现防盗链。


 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv)$
        {
            expires      30d;
            valid_referers none blocked *.mrxn.net *.emlog.net *.qq.com;
            if ($invalid_referer) {
            rewrite ^/ http://i11.tietuku.com/0783ef75758999f8.gif;
            #return 404;
            }//防盗链
        }

资源类型可以自己增加或者是删除,第二句 expires 30d; 是资源在客服端浏览器缓存的时间为30天,这样可以加速网站打开速度,减轻服务器负担,更具实际情况做适当调整。下面几句就是防盗链的白名单,支持正则匹配,只是修改有点麻烦,每次添加或者是删除都需要修改配置文件。


具体的nginx配置专业术语可参考相关文章:

nginx配置location总结及rewrite规则写法

nginx配置ssl加密(单双向认证、部分https)

NginxRewrite规则判断普通用户与搜索引擎爬虫(UA)实现https跳转

SSL/TLS原理详解

OpenSSL 与 SSL 数字证书概念贴

基于OpenSSL自建CA和颁发SSL证书


Mrxn 发布于 2015-9-24 13:36

个人资料

    blogger

    Mrxn

    一个关注网络安全,热爱黑客技术的好青年!

搜索

最新评论