网站建设

利用HSTS安全协议柔性解决全站HTTPS的兼容性问题

导读:目前,很多站都开始实现HTTPS了,而且其中的大部分强迫症站长还会开启强制HTTPS机制,对于网站的HTTP请求全部301跳转到HTTPS,从而实现全站HTTPS。这明显是一个粗暴的做法,下面张戈博客就分享一下目前正在使用的柔性做法,告别粗暴。 一、HSTS协议 这里我们要借助一个新的安全协议:HSTS HSTS(HTTP Strict Transport Security)国际互联网工程组织IETE正在推行一种新的Web安全协议,作用是强制客户端(如浏览器)使用HTTPS与服务器创建连接。 主要目的是为了解决HTTPS网站首次请求时使用的是未加密的HTTP协议,也就说用户一般访问我们的网站都是直接在浏览器输入域名,比如 zhang.ge,然后我们的服务器检测到是HTTP请求,就301跳转到HTTPS页面。那么前半程采用的就是未加密的HTTP请求,同样存在被劫持的可能,那么HTTPS说好的安全性也就大打折扣了! 在我看来,HSTS还有另外一层好处:增强网站的兼容性。 以往分享的全站HTTPS都是采用301强制性跳转,而且还会区分下低版本IE、不支持HTTPS的搜索引擎来忽略301跳转,很明显这样做无法照顾到所有情况。那么如果是用HSTS呢? 采用HSTS后,支持这个协议的浏览器会自动跳转到HTTPS页面,返回码为307: 而不支持HSTS的浏览器访问我们的网站,则不会产生跳转,从而提高了兼容性。这个机制对于不支持HTTPS的搜索引擎来说是非常友好的做法了! 二、开启HSTS 开启HSTS很简单,只要在我们网站的响应头里面新增HSTS即可,下面简单说下 ①、Nginx服务器 只需要在站点server模块内插入如下配置并重启: ②、Apache服务器 Apache如下配置并重启: ③、LigHttpd 将下述配置增加到你的 Lighttpd 配置文件(一般是 /etc/lighttpd/lighttpd.conf)并重启: ④、通用方法 如果你用的虚拟主机,或者不会折腾WEB软件,那么可以采用更简单的通用方法。原理很简单,通过代码来新增响应头即可,这里只分享一下php的做法,其他语言自行参考: 将如下代码插入到网站根目录的index.php即可: 三、相对链接 当然,为了兼容不支持HTTPS的客户端,我们还需要将网站的所有超链接都改成相对模式: 比如,正常的页面链接如下所示: 改成相对模式: 好处就是,不管是HTTP还是HTTPS请求,页面中的地址都是和请求协议保持一致,避免出现页面是HTTP,而页面中的链接却是HTTPS的情况,那么前面的做法也就没了意义。 如何修改为相对模式,估计有同学又玩不转了。万变不离其宗,和以前纯代码启用七牛CDN一样! 直接粗暴替换前台输出的代码即可: 将以上代码新增到 WordPress 主题的functions.php中即可。以上代码只会替换和网站主域名有关系的超链接,八竿子打不着的外部超链接就不管了,有需求自行参考解决。 四、提交HSTS 上文已介绍了HSTS,主要是为了解决HTTP请求301跳转到HTTPS这个过程被劫持问题,而实际上就算加上HSTS响应头,用户请求的前半程依然是HTTP,并没有什么L用。 提出这个协议的砖家们就想出了一个解决办法:将支持HSTS的网站全部加入一个Preload的清单,支持HSTS协议的浏览器请求网站前会查询当前网站是否在清单中,如果是那么直接转换为HTTPS请求!从而解决前半程为HTTP的问题(不专业,但说人话。。。)。 那么,如果我们的网站启用了HSTS,还得将网站提交到这个Preload清单才行了 提交地址:https://hstspreload.appspot.com/  (需要扶墙访问) 提交直到批准,我们的网站必须强制301跳转到HTTPS,否则无法通过,完成审核后再取消301即可。 当然,提交后会显示正在提交到preload list,快的话两三天,慢的话一两个月都是有可能的: 好了,罗里吧嗦分享了一大堆,自行参考吧! 20170205最新补充:经过漫长的等待,偶然查询发现已经是preload状态了,可真不容易:
阅读全文
WEB应用

解决Nginx配置http2不生效,谷歌浏览器仍然采用http1.1协议问题

昨天一个网友通过QQ联系我,说按照我博客之前分享的http2配置教程不能生效,想请我帮忙看看。 经过测试,使用谷歌浏览器访问他的测试站点,确实没有开启http2,但他的配置和编译参数都正确的,这有点奇怪了。 不过昨天太忙就没有继续帮他分析,他只好将服务器账号和密码都留言给了我。今天中午我抽空在他服务器重新编译测试了一把,才发现原来是这么一个梗! 他在编译Nginx之前,使用的是yum安装的openssl,可能是他的yum源太陈旧,或者没配置EPEL导致yum安装的openssl版本过低!而他在编译Nginx的时候并没有使用--with-openssl=DIR的选项来静态编译,所以他编出来的Nginx用的系统低版本的openssl,导致谷歌访问时并不会开启http2! 找了段专业解释如下: Chrome 在最近的更新中放弃了对 NPN 的支持,如果想要继续在 Chrome 上支持 HTTP/2 ,则需要安装最新 1.0.2 版的 OpenSSL,并且用 1.0.2 的 OpenSSL 重新编译 Nginx。 参考资料: 新版Chrome下滚回HTTP/1.1 Supporting HTTP/2 for Google Chrome Users 所以,解决方法就非常简单了,从openssl官网下载最新源码包,然后新增如下参数重新编译即可: --with-openssl=源码包解压目录 比如: 当然,我们也可以先更新yum源,比如改用EPEL源,使用 yum update openssl 升级后重新编译。这里我个人建议使用源码静态编译。 重新编译安装后,再利用谷歌浏览器访问如下网址: 测试他的网站已经成功开启http2了: 事后突然想起,其实自己之前折腾网站的时候其实遇到过同样的问题,就因为没有记录导致重复造轮子。所以这次记录分享一下,权当是备忘吧!
阅读全文
网站建设

全站启用SSL之后,如何兼容不支持https抓取的搜索引擎?

还是在今年5月份,百度就跳出来,宣布成为国内首个支持https的搜索引擎,结果呢?呵呵... 一、案例 ①、抓取诊断 全站开启并强制https之后,在百度站长平台使用抓取诊断发现,其实百度并不会识别强制跳转的301状态,至少不会友好的反馈给用户: 抓取并没有出现跳转提示: 其实,后台日志显示是正常的301跳转: ②、真是打脸 2017年05月25日更新:偶尔进入站长平台看了一把,居然给我博客自动做了https认证,然后去百度搜索site了一把我的网站,基本已全部换成了https,看来百度对https的收录已全面展开! 百度发公告说,已全面支持https,并推荐各个网站开启https,得到优先展示,结果呢? 我们先百度site一下www.baidu.com,然后复制收录里面的链接: http://www.baidu.com/link?url=f3Fbk5cL6W_Hz0jtf6JY991vn1teNTzZ1WBHaqnOmCO&wd=&eqid=aab2bf1f0009872d000000055687e679 然后用网页内容抓取工具看下百度收录自己的是什么: 真是呵呵了,自己收录自己的也是http,说好的https呢?你5月份就发公告支持了,这大半年了自己对自己的收录都没更新过来,何况其他网站?? 其实,要看百度对自己的收录是否是https还有一种更简单的方法:直接在百度搜索https://www.baidu.com即可: 再次呵呵下。。。 ③、配套设施缺憾 百度搜索确实是全站启用了https,可你的配套设施呢??搞了半天,也就是百度搜索支持了https,百度的其他产品几乎都不支持! 比如,做网站喜欢用到的百度分享,不支持https,还得自行处理【相关文章】; 比如,大部分网站的经济来源,百度广告不支持https,搞个蛋哟; 还好,百度统计还能凑合用下,不是那么一无是处。。。 二、正能量 国内各个搜索引擎都看了下,结果意外的发现搜狗居然已经正常收录我博客的https了: 其他基本都未收录,而国外的几个搜索引擎基本不用看,换https数日之后就全局替换成https收录了,而且目测给了更好的排名,比如谷歌、必应等。 百度一直以来都是蜗牛般的反应,真不知是技术不行还是故意设置的?百度的索引服务器再多能多过谷歌?全局刷新一下感觉如登天一般麻烦! 三、解决 吐槽了那么多,还是来说说如何缓解一下各种不支持的窘迫吧! 支持https的有:谷歌、必应、搜狗、百度(持怀疑态度)以及用户 不支持的有:    360、神马(宜搜)以及百度(有待验证)等 那我们全站强制https就行不通了,必须对这些来路做规则判断,然后针对性的跳转或不跳转才行。 只分享下Nginx的做法,其他就自行参考研究吧! ①、http和https不在同一个server模块的做法: Ps:分别监听80和443端口是大部分网站的做法。 在监听80的server模块中添加如下规则: ②、http和https在同一个server模块的做法(注意修改实际域名): 最后,重载或重启nginx即可生效。 简单解释下:若不是百度、360或神马蜘蛛进行的http协议请求,将全部跳转到https。即强制https对360、百度、神马开了白名单模式,不强制跳转。规则是通用的,你可以把第一条规则中的UA标识换成任意不想强制跳转的请求源。 时间有限,就分享这么多了,希望各大搜索引擎尽快兼容https,希望百度搜索的联动反应能快点,而且不行就别再打肿脸充胖子,要对得起国内搜索第一的地位! 2016/01/05 内容补充:早上看到了WP酷的分享,才拍脑袋想起还有XP系统不支持SNI,导致网页无法打开,所以上述新增的规则可以改成如下代码: 场景①适用: 场景②适用: 2016/01/09 内容补充:突然想到,既然要兼容那些不支持的请求者,那么当请求到https时,是不是应该跳回http呢? 比如,使用XP系统访问到了http,我们可以不跳转到https,但我们全站都是改造成https的,所以页面内的链接都是https的,那他进一步还是不能访问! 所以,继续加规则,如果是特殊用户,则强制http访问: ①、http和https不在同一个server模块的做法: Ps:分别监听80和443端口是大部分网站的做法。 在监听80的server模块中添加如下规则: ②、http和https在同一个server模块的做法(注意修改实际域名): 最后,重载或重启nginx即可生效。
阅读全文
WEB应用

升级Nginx1.9.5以上版本,开启博客网站http2.0时代

最近给张戈博客全站开启了https,所以对这块关注比较多。昨天脑补的时候发现http2.0只支持SSL加密的网站,即https。于是心血来潮,给张戈博客开启了http 2.0,尝尝鲜。 查了下资料,发现Nginx不久前发布的 1.9.5版本支持http2.0,而1.8.x时代只是对SPDY进行了支持。一直用的1.62稳定版,此次为了测试http2.0,直接进行了版本跳跃,升级到了1.9.5版本,下面简单的分享下部署分解。 Ps:特别说明的是,http2.0只支持开启了https的网站,所以没开启https的网站就只能看看了! 一、编译Nginx 编译Nginx是我博客老生常谈的问题,之前都不想赘述的内容,这次还是耐着性子说一下在已有Nginx的服务器上重新编译一个Nginx的做法。 ①、下载Nginx最新版 目前Nginx最新版是今年11月份发布的 1.9.7 版本,反正1.9+是没有稳定版,所以干脆弄个最新版: 话说1.9+版本还支持TCP负载均衡呢,感兴趣的可以看下张戈博客之前的分享: Nginx发布1.9.0版本,新增支持TCP代理和负载均衡的stream模块 ②、编译Nginx 在已有环境下编译Nginx,一般做法是先取得目前运行的Nginx的运行参数,然后在这个参数的基础上加上本次编译想新增的参数即可。所以,我们先执行 nginx -V 查看它的编译参数是什么: 可以看到张戈博客目前用的是1.6.2版本,当然也是淘宝定制过的Tengine。 如果你发现参数里面也存在 --add-module=../xxx 这种使用相对路径的参数,就得注意了。你重新编译的时候得保证新的Nginx编译文件夹的相对路径存在对应的模块,否则请重新指定一个正确的路径,比如上面代码中出现的 ngx_cache_purge-2.3,否则会提示找不到路径啦! 既然知道了老的Nginx的编译参数,那么直接按照下面操作,解压、编译、平滑升级搞定Nginx1.9x: 二、配置http2.0 配置Nginx开启http 2.0特别简单,只要在Nginx配置文件中找到你要开启http2.0的域名server模块,然后将 listen 443 ssl;改成 listen 443 ssl http2; 即可。 比如,张戈博客之前的Server模块配置如下: 直接改成: Tips:开启http2.0后,谷歌浏览器无法访问,显示如下信息? 无法显示此网页 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY 网址为 https://zhang.ge/ 的网页可能暂时无法连接,或者它已永久性地移动到了新网址。 吐下苦水,张戈博客配置好http2.0之后,得知谷歌浏览器支持http2.0,于是访问看了下,居然提示以上错误!关掉http2之后,又正常了!!搜遍了都没找到为什么!最终,鬼使神差的把SSL额外配置全部屏蔽,只剩下指定证书和key部分,发现居然好了? 后来发现Nginx官方给出的SSL中都用到了 TLSv1.2,而我的配置还停留在TLSV1! 保存配置文件之后,重启或重载Nginx即可生效:/usr/local/nginx/sbin/nginx -s reload 三、测试http2.0 配是配好了,到底有没有生效呢?还需要测试下才行。 ①、在线测试 直接访问 https://spdycheck.org/#你的域名 即可测试是否成功开启 http2.0: 比如访问:https://spdycheck.org/#zhang.ge,可以看到如下信息: 发现居然是SPDY有木有?想了半天为什么,才想起来我用了腾讯云的CDN,这个SPDY肯定是腾讯云CDN为了优化https启用的!跟上文的操作没有半毛钱关系!所以,目前张戈博客虽然开启了http2.0,但是走了CDN之后,就只有SPDY了,本次权当测试。。。 于是,试着搜了下http2 check,没想到还真有!不过可惜功能不可用,测任何网站都是失败: https://www.h2check.org/ ②、浏览器测试 看来要得到确切的结果,还得借助谷歌、火狐等浏览器了。 打开谷歌浏览器,先访问一下你的网站,比如访问下张戈博客 然后,在谷歌浏览器地址栏输入 chrome://net-internals/#http2 并回车,列表里面即为已支持http2.0的域名: 没错,开启成功! 进一步看一下Nginx日志,可以很明显的发现刚刚的访问是走的http2.0协议: 四、简单总结 上文仅仅是简单配置,http2.0其实还有其他几个优化参数,感兴趣的朋友可以前往Nginx官方文档查看:http://nginx.org/en/docs/http/ngx_http_v2_module.html http2.0是下一代http协议,现在还没普及,而且大部分浏览器都不支持使用http2.0访问。只有少数浏览器,比如谷歌、火狐,貌似IE10也在蠢蠢欲动,具体行不行有待测试。所以,测试这个功能也只是抱着尝鲜和学习的目的。 对http2.0感兴趣,并希望了解http2.0优点特性的朋友,可以看下开源中国对http2.0的详细介绍。当然,网上还有很多对HTTP1.0、SPDY及HTTP2.0详细测试对比的技术文章,都可以很明显看出http2.0绝对是以后互联网的主流趋势! 开启http2.0的前提是你的网站已经支持了https,所以开启https是第一步! 以下是相关文章: 借助腾讯云CDN开启全站https及问题解决分享 分享一个免费SSL证书申请网站,给网站开启https协议 Linux+Nginx/Apache/Tomcat新增SSL证书,开启https访问教程 不长不短,又是一篇折腾分享,希望你能用得上~
阅读全文
网站建设

借助腾讯云CDN开启全站https及问题解决分享

“眼尖”的朋友,已经看到张戈博客已全面启用 https 了,当然这几天站点502也是常用的事情。不过到我写这篇文章为止,应该算是安定了下来。 自从百度推荐全站 https 以来,一直就想让博客跟上这个节奏。可惜,国内所有的免费CDN都不支持https。所以要开启https势必要暴露网站真实ip,按照现在张戈博客被攻击的节奏,估计一暴露就没有了安生的日子! 偶尔的心血来潮,百度了一把支持https的CDN,打开了腾讯云的一个Q&A: 1.3CDN支持https吗? https目前处在邀请测试阶段,暂时还不提供申请,还请谅解。我们正在完善此特性,一旦产品成熟,我们会第一时间公布,敬请期待。 呵呵,邀请测试是么?既然是自家的产品,那还是毛遂自荐吧! 于是找到了公司腾讯云的产品经理,说了我这个想法,于是有幸就用上了国内这个为数不多的特权。 虽然,走的是后门,但是测试责任还是得尽好才是,因此也和产品经理没少交流。博客全面https化也遇到了非常多的问题,下面就让我来细细道来。 一、http回源 腾讯云CDN默认是http回源,这样就有一个问题:因为我们要全站https,不想有http, 那么势必需要将http的请求301到https上。这时腾讯云通过http过来请求源站,那么请求到的就是301了!这也是前些天张戈博客时不时来一个502的原因了。大部分请求对301的支持不是很完善。。。 刚开始还无法自行设置回源模式,还好我用上不久,就发布了新版本,支持回源选择。妥妥的选择了https回源。然后静态文件我没有做强制https,因此静态文件我选择http回源,略微优化一下负载。 二、微信公众号 如上设置之后,又发现了一个新问题,微信粉丝跟我反馈,公众号不能自动回复了! 检查了下,原来是因为公众号只支持http模式的token请求,因此微信公众号的http请求得到的也是301结果,导致自动回复失败! 看来全部跳到https也是行不通的。测试了半天,最后用如下nginx规则搞定: 另外值得说明的是,如果开启了强制https的站点被其他域名反向代理(比如张戈博客用到的res.zgboke.com),那么proxy_pass 也需要指向https才行: 比如:proxy_pass https://zhang.ge; 否则反向代理可能会502!和之前腾讯云不支持https回源选择一样的结果。 三、http被缓存 虽然CDN对301的缓存支持不好,但是不代表不能缓存301!因此,腾讯云CDN偶尔会缓存网站的http结果,导致强制跳转https失效!结果就是访问http页面也不会自动跳转了。 而现在腾讯云还不支持在节点直接设置强制https跳转,实在没办法,在网页的header里面加入如下js代码搞定这个问题: 三、各种跳转 https之后,发现以前的文章外链自动跳转出问题了,把文章中的内链也当成了外链!而且评论中我自己的链接也变成了跳转。 看了下,原来是之前的函数并没有兼容https,于是改了下,搞定。 四、外部资源 众所周知,要全站https,那么所有页面都不能存在非https资源,否则浏览器就会拦截这些内容,并显示惊叹号! 于是大把的问题迎面而来: ①、百度分享不支持https 这个问题最终我用最苦逼的方法解决了,那就是将百度分享代码中的js,已经js会请求到的其他js/css资源全部都下载到本地(具体会请求到哪些资源,我都是在浏览器开发者模式中获取的),并修改其中的链接指向到本地,搞定了百度分享的大部分功能。 比如,分享到QQ空间、微博,分享到微信显示二维码都搞定了,唯独那个“更多”选择恕我无能为力: 最后,我将修改好的文件上传到支持https的七牛CDN,所以有需要的人可以将百度的分享链接修改如下,即可使用: 说白了,就是将之前的百度分享代码中的js修改为七牛镜像js地址即可: https://dn-iyz-file.qbox.me/static/api/js/share.js 如此解决之后,浏览器https就是绿色了,不会有黄色的惊叹号! Ps:最近,我在瞎逛时,在一个博客那看到了一个更完善的利用七牛解决百度分享不支持https的办法,推荐大家使用:传送门 (本文已更新为代码,更完善) ②、新浪微博关注按钮 好吧,这个问题我暂时没时间处理,直接屏蔽了这个功能,估计参考上面的方法可以解决。 五、整理总结 全站https已有3天,总体还是不错的!不过,腾讯云CDN的https功能目前还在邀请测试阶段,所以想尝鲜的小伙伴就只能耐心等待正式公测了。相信这个国内唯一支持https的CDN会大受欢迎的! 不知不觉已经写了这么长了!暂时就整理这么多,后续有新的问题再更新到这篇文章当中,敬请期待!
阅读全文
资源分享

分享一个SSL证书在线转换工具,以及IIS7环境下开通https的方法

衔接上一篇文章,提到了公司只能提供Nginx下的SSL证书,却要在IIS里面开启https这个问题。本来想去申请上次分享的沃通免费SSL证书。结果发现我并没有域名控制权,只好作罢。 转念一想,既然没有那我就生成一个好了!于是在百度搜索:pem to pfx (pem是nginx下的证书格式,pfx是IIS7下的证书格式)、SSL证书转换等关键词。结果只搜到从pfx到pem的转换,而且是通过openssl和一大堆麻烦的步骤! 我是一个很懒的人,所以并不想在这棵树上吊死,于是到谷歌搜一下老外的工具。我深知在谷歌搜老外的最好是用英文,于是直接搜索pem to pfx,果然一下就被我找到了: Ps:要是不会翻谷歌,可以用谷粉搜搜引擎(自己百度地址),和谷歌一样的结果。 一、证书转换 我随便点开第一个发现就可以成功转换!下面是简单分享: 工具地址:https://www.sslshopper.com/ssl-converter.html 简单步骤: ①、选择转换后的格式(Type To Convert To),这里我选择IIS专用的pfx: ②、选择后栏位即刻发生改变,这时候需要上传nginx下的*.pem和*.key2个证书相关文件,然后输入你自定义的证书密码,最后点击最下面的蓝色按钮(Convert Certificate)即可下载到转换后的pfx证书了! 二、导入证书 之前分享过在Linux服务器下开启https的方法,而这次是IIS,所以也简单分享一下。 ①、添加证书管理 IIS服务器->开始->运行->输入MMC->确定后弹出如下界面->点击文件->选择添加/删除管理单元: ②、下拉左边列表,找到证书并添加: ③、选择计算机账户: ④、跟着向导继续下一步并完成后,刚刚的MMC控制界面就可以看到【证书】选项了,如图点开个人选项,并右键证书,在所有任务里面选择导入: ⑤、在弹出的界面的右下角,选择个人信息交换pfx格式,并选择刚刚通过在线转换得到的pfx证书:   ⑥、后面继续跟着向导操作直到导入成功(导入时需要输入之前设置的证书密码),刷新管理界面看到证书即可。 三、分配证书 ①、打开IIS7.0管理器面板,找到待部署证书的站点,点击“绑定”如图: ②、选择“绑定”->“添加”->“类型选择https” ->“端口443” ->“ssl证书【导入的证书名称】” ->“确定”,SSL缺省端口为443端口,如图: 确定后,就成功了,你可以通过https访问该站点测试效果。当然https页面里面是不允许出现http资源的,否则浏览器会自动拦截。解决方法就是讲这些http资源全改成https资源或者将 http://**.js 改成 ://**.js 这种灵活的相对路径,当然前提是这个资源支持https协议。 好了,就分享这么多,比较简单的经验,希望能节省不少苦逼的转换和设置时间!
阅读全文