HSTS VS 301 redirect

以前基于nginx为网站配置了HTTPS服务,配置过程当中涉及到两个知识点:php

  • 301 永久重定向
  • HTST(HTTP Transport Security Protocol)

本文主要是经过梳理一下相关概念,理清这两种配置的目的。html

HTTPS

HTTPS,也称做HTTP over TLS,TLS的前身是SSL。HTTPS 相比 HTTP 提供了数据完整性、 数据隐私性和身份认证的功能。nginx

SSL通讯过程 web

  • 客户端发起一个HTTPS请求,提供客户端支持的加密算法和一个客户端随机数 client_random 给服务器
  • 服务器返回给客户端配置好公钥的证书和服务器随机数 server_random
  • 客户端验证公钥证书、好比是否在有效期内、域名是否匹配等;若是证书有效,客户端使用服务器提供的公钥加密加密随机数 premaster secret,发送给服务器
  • 服务器使用本身的私钥解密 premaster secret
  • 客户端和服务器将前面阶段的三个随机数,使用协商好的算法进行加密生成 master secret,后面双方通讯使用这个对称密钥进行加密;

在nginx中的配置方法算法

  • 申请证书
  • 在nginx.conf中配置
    server {
        listen 443;
        server_name www.example.com; #填写绑定证书的域名
        ssl on;
        ssl_certificate /etc/nginx/sslconfig/1_www.example.com_bundle.crt;
        ssl_certificate_key /etc/nginx/sslconfig/2_www.example.com.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
        ssl_prefer_server_ciphers on;
        location / {
            root   html; #站点目录
            index  index.html index.htm;
            # proxy_pass http://$server_name:8920;
    }
    复制代码

中间人攻击(MitM)

中间人攻击(Man-in-the-middle attack,缩写:MITM)是指攻击者与通信的两端分别创建独立的联系,并交换其所收到的数据,使通信的两端认为他们正在经过一个私密的链接与对方直接对话,但事实上整个会话都被攻击者彻底控制并进行数据篡改和嗅探。浏览器

  • 代理服务器(mitmproxy):代理服务器 在HTTP和HTTPS通讯中担任中间人的角色,在和客户端通讯时它假装成服务器,在和服务器通讯时假装成客户端,对两边的通讯内容进行解码。代理服务器会生成伪造证书欺骗客户端,要使客户端信任伪造证书而不发出警告,须要在客户端手动将代理服务器注册为受信任的 CA。
  • SSL剥离(SSLsplit):SSL剥离中,攻击者 SSLStrip 也是担任中间人的角色,中间人和服务器之间维持HTTPS链接,而和客户端维持HTTP链接,也就是将 HTTPS 降级为 HTTP。因为 HTTP 是明文传输的,所以攻击者能够窃取通讯内容。
  • 会话劫持(Session Hijacking):攻击者经过窃取或预测有效的会话令牌来破坏会话令牌,以得到对Web服务器的未受权访问。经常使用的窃取Cookie/会话令牌的方法有会话嗅探和跨站点脚本攻击等。
  • 防护:对于实际生活中的信件沟通和线上的信息交流来讲,中间人攻击都是很难防范的,一些小建议:
    • 不要忽视浏览器弹出的证书警告!你可能访问的是钓鱼网站或者假冒的服务器
    • 公共网络环境下(例如公共WiFi),没有HTTPS加密的敏感网站不要随便登陆,通常不可信
    • 在任何网站上登陆本身的帐号前确保网址是走的HTTPS加密协议

HSTS

HSTS,即HTTP Strict-Transport-Security。 当站点经过 HTTPS 运行的时候,服务器经过返回一个响应头部 Strict-Transport-Security ,强制浏览器之后使用 HTTPS 进行通讯。缓存

Strict-Transport-Security: max-age=<expire-time>
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains
Strict-Transport-Security: max-age=<expire-time>; preload
复制代码

一个网站接受一个 HTTP 的请求,而后跳转到 HTTPS ,用户可能在开始跳转前,经过没有加密的方式和服务器对话,这样存在中间人攻击潜在威胁,跳转过程可能被恶意网站利用来直接接触用户信息,而不是原来的加密信息。
HTST 是在初次经过访问 HTTPS 链接并返回安全头以后,浏览器记录下这些信息。有效期内,当浏览器再次试图经过 HTTP 与服务器创建链接只会返回307 Temporary Redirect ,浏览器禁止加载 HTTP 信息,并将链接重定向到 HTTPS 。一个测试的结果以下:安全

在nginx中配置响应信息bash

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
复制代码

浏览器返回结果 服务器

307
200
注意 HTST 是经过 HTTPS 响应头设置的,若是使用 HTTP 则会被忽略。一种解决的策略是 preload HTST。HSTS预加载是把你的网站和或域名放在一个被承认的hsts列表上,这个列表其实是内置在浏览器中的。Google提供了这个列表服务,并由Chrome、Firefox、Opera、Safari、IE11和Edge使用,能够将你的站点提交到官方的HSTS预加载列表。

301 redirect

HTTP 301 永久重定向说明请求的资源已经被移动到了由 Location 头部指定的url上,是固定的不会再改变,搜索引擎会根据该响应修正,在 SEO 中301跳转对网站的权重会产生影响。
咱们注意到,咱们已经在nginx中已经配置了return 301 https://$server_name$request_uri,将HTTP请求重定向到HTTPS。可是,在前面的浏览器测试结果中,经过HTTP访问并无显示301永久重定向,而是307临时重定向。实际上,301 仍然是发生的,301是服务器层面上的重定向,而307是浏览器层面上的重定向。咱们经过 httpstatus 进行测试,能够看到直观的结果:

咱们已经说明了HSTS和301的做用,可是咱们可能仍然有些困惑:

  • 为何已经使用 301重定向,还要使用 HSTS ?
  • 为何大多数网站使用301重定向,而不用预加载HSTS替代?

区别与联系

  • HSTS覆盖域名,而301 redirect针对特定的URL Path;
  • HSTS设计的意义是为了解决安全问题,而301更可能是为了解决重定向问题,后来被普遍用在从 HTTP 升级到 HTTPS 的过程当中,并对网站搜索权重形成影响;
  • HSTS起做用是在至少访问过一次HTTPS且证书验证成功的状况下,在安全性要求较高的状况下咱们强制使用 HTTPS,这须要进行预加载或者强制重定向;若是攻击者一直阻止网站创建HTTPS链接,HTST将不起做用;
  • 目前大多数网站使用HSTS时是结合301 redirect使用的而不是预加载,这多是出于兼容考虑;
  • HSTS相比301 redirect,在性能和安全上可能有一些优点。301缓存和其余请求同样都是保存在浏览器缓存中,重定向会消耗性能;而HSTS保留在另外一个单独的缓存列表中,能够保留更长时间而不被浏览器清除;
  • 中间人攻击可能利用重定向的时机进行介入,而HSTS 能够有效应对SSL剥离(HTTPS降级)致使的安全问题,可是对于其余类型的中间人攻击可能不起做用。
  • HSTS 常和 HPKP(HTTP Public Key Pinning) 结合使用, HPKP 容许 HTTPS 网站指定其信任的证书,并指示浏览器不容许任何链接到由任何其余证书保护的站点。

总之,中间人攻击不可能简单地经过某一种策略来彻底阻止,可是聊胜于无,HSTS 仍然是个可行的安全策略。


参考了一些博客和讨论,若有错误欢迎指正。

参考资料

相关文章
相关标签/搜索