V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wzxjohn
V2EX  ›  SSL

SSL 安全设置 HSTS 带来的坑

  •  
  •   wzxjohn · 2014-11-01 09:24:37 +08:00 · 16594 次点击
    这是一个创建于 3457 天前的主题,其中的信息可能已经有所发展或是发生改变。
    之前看到有V有发了用 https://www.ssllabs.com 等检测工具检测你的网站并优化设置的帖子,于是也把自己的网站弄了一下。弄完之后除了因为证书书SHA1签名以外,都是合格的,成功搞了一个A+的分,还挺高兴的。。。
    然后,今天登陆了一下后台发了一篇新文章,然后问题就来了。
    之前我的博客设计的是只有后台走HTTPS,前台访问不强制HTTPS。但是在我发完文章之后我发现无论我怎么弄,前台也都会走HTTPS。为了解决这个问题,我排查了一晚上,关了各种插件,搭了一个全新的WP进行尝试,一直都没发现问题所在。
    最后,在用Google Chrome Canary的时候发现了问题,在Chrome Canary的开发者控制台中,会看到访问http://xxxxx.xxx的请求直接被307了,而Response Headers一栏赫然写着:
    Non-Authoritative-Reason:HSTS
    这一下让我想到了问题所在。HSTS指的是HTTP Strict Transport Security,可以理解为服务器告诉浏览器这个网站支持HTTPS,以后的访问都给我强制转到HTTPS上去,不准使用HTTP。于是将apache的设置中的
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
    改成
    Header always set Strict-Transport-Security "max-age=1; includeSubDomains"
    然后再访问一下HTTPS的链接,然后等待这个Header在浏览器中过期,就可以正常的访问非HTTPS的网站了。

    然后来说说为啥我说这玩意坑:
    1.目前就我的测试来看,没有任何一个浏览器的安全模式会隔离这个HSTS头,比如Google,Google Dev分支,FireFox,Safari等。也就是说,如果你一不小心在安全模式中访问了HTTPS的网站设置了这个头,非安全模式也受影响,反之亦然。这直接导致我在网站本事查了几个小时问题,因为我天真的认为安全模式应该不会出现这个问题。
    2.目前就我的测试来看,只有Chrome Canary的开发者控制台会显示Non-Authoritative-Reason:HSTS,别的浏览器包括Chrome的Stable分支,不会显示这个Response Header,你能看到的就是你访问http://xxx.xxx,然后莫名其妙的被307了。什么原因都没有。这也是我在服务器查了半天没找到问题,看了httpd的access.log才发现这个请求根本没到服务器。
    3.目前就我的测试来看,在浏览器中清除这个头的方法最有效的是重置整个浏览器,删除所有本地数据。CTRL+F5啊打开开发者控制台禁用Cache啊什么的完全不好使,没有效果。
    4.对于使用了强制前台HTTP的网站来说,比如我的博客,这个头可能会直接导致重定向循环。因为浏览器死活要把你307到HTTPS,但是博客死活要把你307到HTTP,然后就循环了,导致网页打不开。
    5.最诡异的是有时候还会遇到访问前几个页面都是好的,都是走的HTTP,然后突然一下点了一个链接就跑到HTTPS上去了。这个现象直接导致我认为是WP Super Cache的问题,在这上耽误了不少时间。

    基本上就这5个坑,如果有V友遇到了类似情况,可以先从我说的这点查起,看看是否是跟我一样的情况~
    第 1 条附言  ·  2014-11-01 11:16:07 +08:00
    补充一句我昨天用IE死活测不出问题因为暂时IE不支持HSTS。。。
    20 条回复    2014-11-01 21:24:52 +08:00
    anjunecha
        1
    anjunecha  
       2014-11-01 09:33:45 +08:00 via Android
    你这一说我倒是想起来以前也出现过这一情况,在控制台中看到有一个资源死活307,一直不清楚原因…
    msg7086
        2
    msg7086  
       2014-11-01 09:33:55 +08:00 via iPhone
    结论就是根本没必要跟着照做。又不是啥金融敏感站点…
    wzxjohn
        3
    wzxjohn  
    OP
       2014-11-01 09:39:44 +08:00 via iPhone
    @msg7086 你这么说也没错,但是大家都希望自己的站点安全一点不是么~
    Quaintjade
        4
    Quaintjade  
       2014-11-01 09:39:49 +08:00 via Android
    HSTS本来就是为全HTTPS站设计的,非强制https不应该设这个。
    火狐要去掉的话,可以试试在历史里找到这个站,右键-忘掉这个站点,然后重启浏览器。错误301也可以用类似方法重置(另一个方法就像你这样,301回来形成刷新)。

    没必要追求ssllabs的分数。我可以达到全100分,但没几个浏览器能兼容。
    wzxjohn
        5
    wzxjohn  
    OP
       2014-11-01 09:42:28 +08:00 via iPhone
    @Quaintjade 确实如此,我只是告诉那些跟我一样不明真相的群众跟着它的指示做弄出了这个问题的话应该如何查因。。。
    sanddudu
        6
    sanddudu  
       2014-11-01 09:58:21 +08:00
    @Quaintjade 的确,cipher 设置的少一点弄挂一堆设备
    更不要说只开 TLS1.2 之后满江红的样子了
    msg7086
        7
    msg7086  
       2014-11-01 09:59:21 +08:00 via iPad
    @wzxjohn 不是。安全性并不是我的首要目标。安全性会牺牲很多东西,比如解密影响加载速度,协议限制会影响许多平台的兼容性。
    wzxjohn
        8
    wzxjohn  
    OP
       2014-11-01 10:12:05 +08:00 via iPhone
    @msg7086 这么说也对~够用的安全就足够了。
    aliuwr
        9
    aliuwr  
       2014-11-01 10:15:23 +08:00
    关于你说的第1点,不知道你说的安全模式是不是指 HTTPS 链接。会出现这样的误解是因为你没有弄清楚 HSTS 的应用场景。他原本是为了解决 HTTPS 链接在初次访问 HTTP 时就被劫持的情况。

    关于第3点,Chrome 可以直接在 chrome://net-internals/#hsts 进行相关设置,除了 preload 的规则不能修改。

    其它更多 Chrome 请求的信息可以在 chrome://net-internals/#events 查看。
    TrustyWolf
        10
    TrustyWolf  
       2014-11-01 10:45:15 +08:00
    前几天刚刚设置了HSTS...拿到了A+...关闭了TLS1.0...
    不过我准备全站HTTPS啦,个人的小站点对搜索引擎也没什么要求。
    wzxjohn
        11
    wzxjohn  
    OP
       2014-11-01 11:12:47 +08:00 via iPhone
    @aliuwr 我说错了。。。手抖打错了。。。是隐私模式。还有HSTS似乎并不是为了解决初次HTTP就被劫持,而是保证HTTPS不被降回HTTP,保证访问期间一直使用HTTPS。
    aliuwr
        12
    aliuwr  
       2014-11-01 13:02:14 +08:00
    wzxjohn
        13
    wzxjohn  
    OP
       2014-11-01 13:35:25 +08:00 via iPhone
    @aliuwr 你理解的基本正确,但是忽略了一点,HSTS头必须在HTTPS下设置,也就是说如果我的博客没有做任何修改还保留原来的样子,尽管我自己访问被强制https了,但是你来访问则并不会。所以说HSTS并不是防止第一次访问时HTTP就被中间人,而是用来防止访问中回落回HTTP。这个访问中的时间段指的是头中设置的时间,而并不一定是连续的时间。
    也就是说,如果我在你从来没访问过某个站点的时候直接劫持了你,那么就算这个站点设置了HSTS头也没有任何作用,因为你根本就从来没有真正的访问到过这台服务器,一直访问的都是我劫持的那台假的。
    wzxjohn
        14
    wzxjohn  
    OP
       2014-11-01 13:38:15 +08:00 via iPhone
    @aliuwr 如果你仔细看看的话就会发现谷歌也发现了我所说的问题,所以弄出了一个Preload List。
    msg7086
        15
    msg7086  
       2014-11-01 13:58:17 +08:00
    @wzxjohn 「HTTPS 链接在初次访问 HTTP 时」 审题
    aarwwefdds
        16
    aarwwefdds  
       2014-11-01 14:11:05 +08:00
    @wzxjohn 没有规定HSTS只能在HTTPS下发送吧。我看到的配置范例都是HTTP和HTTPS都发送HSTS

    这样HTTP接收到HSTS也会跳到HTTPS。不过攻击者倒是可以很轻易就把这个头去掉

    有了HSTS,只要客户端接收到一次HSTS,很长时间内就会强制HTTPS,这样就不给HTTPS前端劫持多少机会了。毕竟此类(HTTPS前端劫持)中间人攻击多数情况下只发生在一些公共WiFi等计算机不会长时间停留的网络接入上(长城除外,HSTS不是用来防长城的),多数计算机在接入此类网络前都已经访问过“易被攻击站点”获得过HSTS头了。(就例如支付宝,难道你新买一台电脑 二话不说先到公共WiFi上去登录支付宝么。多数情况下都应该在较安全的网络环境里登录过了)

    为了完全杜绝攻击可能就有了Preload List。

    说到底还是因为楼主没提前弄明白HSTS就按照教程上HSTS导致的杯具,其实现在全HTTPS也未尝不可,在国外早已经推荐全HTTPS了,只是百度这种蛋疼搜索引擎可能会不收录比较恶心。如果不在乎百度完全可以全HTTPS。
    aliuwr
        17
    aliuwr  
       2014-11-01 14:41:43 +08:00
    @wzxjohn 如楼上所说, HSTS 是为了避免中间人攻击,preload 则是为了完全杜绝这种情况。

    @aarwwefdds https://developer.mozilla.org/en-US/docs/Web/Security/HTTP_strict_transport_security#Enabling_Strict_Transport_Security
    注意 Note 部分,浏览器会忽略 HTTP 里指定的 HSTS。
    奇怪的是 https://hstspreload.appspot.com/ 却强制要求 HTTP 页面里也包含 HSTS 头。
    wzxjohn
        18
    wzxjohn  
    OP
       2014-11-01 15:39:37 +08:00 via iPhone
    @msg7086 明白了,我们对链接一词的理解不同,导致了这个分歧。
    @aarwwefdds 你说的基本没错,我也承认了是我没有了解清楚就配置了导致了这个问题。写这个只是告诉跟我一样没搞清楚就配置结果悲剧的人。。。
    @aliuwr 我已经发现了我理解错了你的链接一词的意思,之前你说的没有问题。
    xierch
        19
    xierch  
       2014-11-01 20:37:41 +08:00 via Android
    只能为为后台单独指定一个域名,然后启用 HSTS 了吧。
    wzxjohn
        20
    wzxjohn  
    OP
       2014-11-01 21:24:52 +08:00
    @xierch 是啊。但是又懒得搞了,所以算了。。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2309 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 00:45 · PVG 08:45 · LAX 17:45 · JFK 20:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.