关于启用HTTPS的一些经验分享

  随着国内网络环境的持续恶化,各种篡改和劫持层出不穷,越来越多的网站选择了全站 HTTPS。就在今天,免费提供证书服务的 Let's Encrypt 项目也正式开放,HTTPS 很快就会成为 WEB 必选项。HTTPS 通过 TLS 层和证书机制提供了内容加密、身份认证和数据完整性三大功能,可以有效防止数据被查看或篡改,以及防止中间人冒充。本文分享一些启用 HTTPS 过程中的经验,重点是如何与一些新出的安全规范配合使用。至于 HTTPS 的部署及优化,之前写过很多,本文不重复了。

 理解 Mixed Content

  HTTPS 网页中加载的 HTTP 资源被称之为 Mixed Content(混合内容),不同浏览器对 Mixed Content 有不一样的处理规则。

  早期的 IE

  早期的 IE 在发现 Mixed Content 请求时,会弹出「是否只查看安全传送的网页内容?」这样一个模态对话框,一旦用户选择「是」,所有 Mixed Content 资源都不会加载;选择「否」,所有资源都加载。

  比较新的 IE

  比较新的 IE 将模态对话框改为页面底部的提示条,没有之前那么干扰用户。而且默认会加载图片类 Mixed Content,其它如 JavaScript、CSS 等资源还是会根据用户选择来决定是否加载。

  现代浏览器

  现代浏览器(Chrome、Firefox、Safari、Microsoft Edge),基本上都遵守了 W3C 的 Mixed Content 规范,将 Mixed Content 分为 Optionally-blockable 和 Blockable 两类:

  Optionally-blockable 类 Mixed Content 包含那些危险较小,即使被中间人篡改也无大碍的资源。现代浏览器默认会加载这类资源,同时会在控制台打印警告信息。这类资源包括:

  • 通过 <img> 标签加载的图片(包括 SVG 图片);
  • 通过 <video> / <audio> 和 <source> 标签加载的视频或音频;
  • 预读的(Prefetched)资源;

  除此之外所有的 Mixed Content 都是 Blockable,浏览器必须禁止加载这类资源。所以现代浏览器中,对于 HTTPS 页面中的 JavaScript、CSS 等 HTTP 资源,一律不加载,直接在控制台打印错误信息。

  移动浏览器

  前面所说都是桌面浏览器的行为,移动端情况比较复杂,当前大部分移动浏览器默认允许加载所有 Mixed Content。也就是说,对于移动浏览器来说,HTTPS 中的 HTTP 资源,无论是图片还是 JavaScript、CSS,默认都会加载。

  补充:上面这段结论源自于我大半年前的测试,本文评论中的 ayanamist 同学反馈现状已经有所变化。我又做了一些测试,果然随着操作系统的升级,移动浏览器都开始遵循 Mixed Content 规范了。最新测试表明,对于 Blockable 类 Mixed Content:

  • iOS 9 以下的 Safari,以及 Android 5 以下的 Webview,默认会加载;
  • Android 各版本的 Chrome,iOS 9+ 的 Safari,Android 5+ 的 Webview,默认不会加载;

  一般选择了全站 HTTPS,就要避免出现 Mixed Content,页面所有资源请求都走 HTTPS 协议才能保证所有平台所有浏览器下都没有问题。

 合理使用 CSP

  CSP,全称是 Content Security Policy,它有非常多的指令,用来实现各种各样与页面内容安全相关的功能。这里只介绍两个与 HTTPS 相关的指令,更多内容可以看我之前写的《Content Security Policy Level 2 介绍》。

  block-all-mixed-content

  前面说过,对于 HTTPS 中的图片等 Optionally-blockable 类 HTTP 资源,现代浏览器默认会加载。图片类资源被劫持,通常不会有太大的问题,但也有一些风险,例如很多网页按钮是用图片实现的,中间人把这些图片改掉,也会干扰用户使用。

  通过 CSP 的 block-all-mixed-content 指令,可以让页面进入对混合内容的严格检测(Strict Mixed Content Checking)模式。在这种模式下,所有非 HTTPS 资源都不允许加载。跟其它所有 CSP 规则一样,可以通过以下两种方式启用这个指令:

  HTTP 响应头方式:

Content-Security-Policy: block-all-mixed-content

  <meta> 标签方式:

<meta http-equiv=Content-Security-Policy content=block-all-mixed-content>

  upgrade-insecure-requests

  历史悠久的大站在往 HTTPS 迁移的过程中,工作量往往非常巨大,尤其是将所有资源都替换为 HTTPS 这一步,很容易产生疏漏。即使所有代码都确认没有问题,很可能某些从数据库读取的字段中还存在 HTTP 链接。

  而通过 upgrade-insecure-requests 这个 CSP 指令,可以让浏览器帮忙做这个转换。启用这个策略后,有两个变化:

  • 页面所有 HTTP 资源,会被替换为 HTTPS 地址再发起请求;
  • 页面所有站内链接,点击后会被替换为 HTTPS 地址再跳转;

  跟其它所有 CSP 规则一样,这个指令也有两种方式来启用,具体格式请参考上一节。需要注意的是 upgrade-insecure-requests 只替换协议部分,所以只适用于 HTTP/HTTPS 域名和路径完全一致的场景。

 合理使用 HSTS

  在网站全站 HTTPS 后,如果用户手动敲入网站的 HTTP 地址,或者从其它地方点击了网站的 HTTP 链接,依赖于服务端 301/302 跳转才能使用 HTTPS 服务。而第一次的 HTTP 请求就有可能被劫持,导致请求无法到达服务器,从而构成 HTTPS 降级劫持。

  HSTS 基本使用

  这个问题可以通过 HSTS(HTTP Strict Transport Security,RFC6797)来解决。HSTS 是一个响应头,格式如下:

Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]

  max-age,单位是秒,用来告诉浏览器在指定时间内,这个网站必须通过 HTTPS 协议来访问。也就是对于这个网站的 HTTP 地址,浏览器需要先在本地替换为 HTTPS 之后再发送请求。

  includeSubDomains,可选参数,如果指定这个参数,表明这个网站所有子域名也必须通过 HTTPS 协议来访问。

  preload,可选参数,后面再介绍它的作用。

  HSTS 这个响应头只能用于 HTTPS 响应;网站必须使用默认的 443 端口;必须使用域名,不能是 IP。而且启用 HSTS 之后,一旦网站证书错误,用户无法选择忽略。

  HSTS Preload List

  可以看到 HSTS 可以很好的解决 HTTPS 降级攻击,但是对于 HSTS 生效前的首次 HTTP 请求,依然无法避免被劫持。浏览器厂商们为了解决这个问题,提出了 HSTS Preload List 方案:内置一份列表,对于列表中的域名,即使用户之前没有访问过,也会使用 HTTPS 协议;列表可以定期更新。

  目前这个 Preload List 由 Google Chrome 维护,Chrome、Firefox、Safari、IE 11 和 Microsoft Edge 都在使用。如果要想把自己的域名加进这个列表,首先需要满足以下条件:

  • 拥有合法的证书(如果使用 SHA-1 证书,过期时间必须早于 2016 年);
  • 将所有 HTTP 流量重定向到 HTTPS;
  • 确保所有子域名都启用了 HTTPS;
  • 输出 HSTS 响应头:
    • max-age 不能低于 18 周(10886400 秒);
    • 必须指定 includeSubdomains 参数;
    • 必须指定 preload 参数;

  即便满足了上述所有条件,也不一定能进入 HSTS Preload List,更多信息可以看这里。通过 Chrome 的 chrome://net-internals/#hsts 工具,可以查询某个网站是否在 Preload List 之中,还可以手动把某个域名加到本机 Preload List。

  对于 HSTS 以及 HSTS Preload List,我的建议是只要你不能确保永远提供 HTTPS 服务,就不要启用。因为一旦 HSTS 生效,你再想把网站重定向为 HTTP,之前的老用户会被无限重定向,唯一的办法是换新域名。

 CDN 安全

  对于大站来说,全站迁移到 HTTPS 后还是得用 CDN,只是必须选择支持 HTTPS 的 CDN 了。如果使用第三方 CDN,安全方面有一些需要考虑的地方。

  合理使用 SRI

  HTTPS 可以防止数据在传输中被篡改,合法的证书也可以起到验证服务器身份的作用,但是如果 CDN 服务器被入侵,导致静态文件在服务器上被篡改,HTTPS 也无能为力。

  W3C 的 SRI(Subresource Integrity)规范可以用来解决这个问题。SRI 通过在页面引用资源时指定资源的摘要签名,来实现让浏览器验证资源是否被篡改的目的。只要页面不被篡改,SRI 策略就是可靠的。

  有关 SRI 的更多说明请看我之前写的《Subresource Integrity 介绍》。SRI 并不是 HTTPS 专用,但如果主页面被劫持,攻击者可以轻松去掉资源摘要,从而失去浏览器的 SRI 校验机制。

  了解 Keyless SSL

  另外一个问题是,在使用第三方 CDN 的 HTTPS 服务时,如果要使用自己的域名,需要把对应的证书私钥给第三方,这也是一件风险很高的事情。

  CloudFlare 公司针对这种场景研发了 Keyless SSL 技术。你可以不把证书私钥给第三方,改为提供一台实时计算的 Key Server 即可。CDN 要用到私钥时,通过加密通道将必要的参数传给 Key Server,由 Key Server 算出结果并返回即可。整个过程中,私钥都保管在自己的 Key Server 之中,不会暴露给第三方。

  CloudFlare 的这套机制已经开源,如需了解详情,可以查看他们官方博客的这篇文章:Keyless SSL: The Nitty Gritty Technical Details

  好了,本文先就写到这里,需要注意的是本文提到的 CSP、HSTS 以及 SRI 等策略都只有最新的浏览器才支持,详细的支持度可以去 CanIUse 查。切换到 HTTPS 之后,在性能优化上有很多新工作要做,这部分内容我在之前的博客中写过很多,这里不再重复,只说最重要的一点:既然都 HTTPS 了,赶紧上 HTTP/2 才是正道。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


起步 处理器架构,参考 x86是指intel的开发的一种32位指令集 intel和amd早期的cpu都支持这种指令集 AMD比Intel率先制造出了商用的兼容x86的CPU,AMD称之为AMD64 Intel选择了设计一种不兼容x86的全新64为指令集,称之为IA-64,后来支持AMD64的指令集,
pscp pscp -P 22 C:\work\test.txt root@192.168.1.5:/home/data pscp -P 22 root@192.168.1.5:/home/data/test.txt C://work// 检索 find / -name default.config
文件处理 ls -a # 显示所有文件 ls -l # 显示详细信息 ls -d # 显示路径 mkdir /目录名称 # 创建目录 cd /目录名称 # 切换目录 pwd # 显示当前路径 rmdir /目录名称 # 删除目录 cp -rp [目录名称] [目标目录] # 复制目录到目标目录 cp
准备一台电脑(我就用联想拯救者r7000演示) 参考博客制作启动盘 插上U盘,启动电脑,一直按F2 进入如下页面后,将U盘设置为第一启动项,点击exit,保存并退出 之后进入如下页面,选择第三项 进入如下页面,选择第四项 进入如下页面,选择第一项,选中后,先不要点Enter 按e键,将inst.st
认识 Linux系统是参考了UNIX系统作为模板开发的,但没有使用UNIX的代码;是UNIX的一种,但不是衍生版 在Linux内核的基础上开发是发行版 分区 逻辑分区永远从5开始 步骤 挂载:可理解为分配盘符,挂载点即是盘符名;不同之处:Linux中是以空目录名称作为盘符 Hda 第一块硬盘 Hda
文件处理命令 以 . 开头的文件是隐藏文件 以 - 开头表示这是一个文件 以 d 开头表示是一个目录 以 l 开头表示是一个软链接 第一个root是所有者,第二个root是所属组 ls -h 以文件默认大小后缀 显示 ls -i 查看i节点(唯一标识) 所有者:只能有一个,可变更 所属组:只能有一个
参考 01 02 03 前提环境 本地安装VirtualBox,并安装CentOS8,配置网络后,window系统上putty能连接到CentOS8服务器 配置步骤 右键服务器复制 启动复制后的服务器,查看ip和hostname发现和原来的服务器一样,需要修改 hostname # 查看主机名 vi
文件搜索命令 星号匹配任意字符,问号匹配任意单个字符 -iname 根据文件名查找且不区分大小写 -ok 命名会有一个询问的步骤 如果没有找到指定文件,可输入命令:updatedb 更新文件资料库;除tmp目录不在文件资料库收录范围之内 locate -i 文件名 # 检索时不区分大小写 which
安装环境 安装最新版的Virtual Box,点击安装 下载centos8镜像 创建虚拟机,可参考 选择下载到本地的镜像 设置启动顺序 点击启动 启动过程中报错:“FATAL:No bootable medium found!” 1.没有选择iso镜像 2.光驱没有排在第一位置 3.镜像只能选择x8
Linux严格区分大小写 所有内容文件形式保存,包括硬件 Linux不靠扩展名区分文件类型 挂载:将设备文件名和挂载点(盘符)连接的过程 Linux各个目录的作用 bin表示二进制 服务器注意事项 远程服务器不允许关机,只能重启 重启时应该关闭服务 不要在服务器访问高峰运行高负载命令 远程配置防火墙
IDE连接Linux,上传下载文件 参考1 参考2 连接Linux 上传下载文件 本地项目打包后上传 查看是否上传成功,右键下载 补充 后端项目开发完成后,需clean掉临时文件target文件夹,且只推送修改过的文件 前端项目开发的过程中,需要在每个子组件中使用scoped,确保每个子组件中的编码
起步 LTS与普通版本的区别 LTS版本的发布周期更长,更加稳定 安装jdk sudo mkdir /usr/lib/jvm # 在Ubuntu中创建目录 pscp D:\安装包\linux源码包\jdk-8u291-linux-x64.tar.gz chnq@192.168.0.102:/tmp
前言 最近在b站上看了兄弟连老师的Linux教程,非常适合入门:https://www.bilibili.com/video/BV1mW411i7Qf 看完后就自己来试着玩下,正好手上有台空闲的电脑就尝试不使用虚拟机的方式安装Linux系统 安装步骤 制作启动盘 下载ISO镜像,我这里下载的是Cen
新建虚拟电脑 设置内存和处理器 设置硬盘大小 完成 设置 查看光驱 设置启动顺序 点击启动 选择第1项 进入图形安装界面 选择安装位置,开始安装 设置root密码 重启 登录 查看本地文件夹 配置网络,点击设置 查看宿主机ip C:\Users\ychen λ ipconfig 无线局域网适配器 W
源码包安装需手动下载后安装 二进制包则在package目录下 rpm命令管理rpm包 若某个rpm包依赖于某个模块,需要到网站www.rpmfind.net查询该模块依赖的包,安装这个包后自动安装模块,之后就能安装rpm包了 安装升级时使用包全名 查询卸载时使用包名 虚拟机中的Linux系统安装rp
首先进入命令模式,再输入以下命令 命令模式用于输入命令 插入模式可对文件编写操作 编辑模式下的命令是在冒号后输入 :12, 15d # 删除指定范围的行,这里是删除12到15行 :n1,n2s/old/new/g ## 表示从n1行到n2行,old表示旧的字符串 vim使用小技巧:自定义快捷键,如快
使用源码包安装,需要自己指定安装位置,通常是 /usr/local/软件名/ linux中要想启动执行文件,应使用绝对路径 /绝对路径/rpm包名 start ## 执行方式一 service rpm包名 start ## 执行方式二 使用源码包安装后,由于自定义安装路径,就不能使用service命
网络命令 在收邮件的用户中,输入 mail 可查看邮件信息,输入序列号查看详细信息 在mail命令下,输入h 查看所有邮件的列表 输入:d 序列号 # 删除邮件 last # 统计所有用户登录或重启时间,用于日志查询 lastlog # 显示包括未登录用户的登录时间 lastlog -u 用户id
若要使用yum管理,必须能连接网络,首先配置网络IP 进入yum源文件中启动容器 使用yum源头安装rpm包不需要进入package路径,同时也不需要使用包全名,会有yum自动管理 安装软件组
简介 client即是本机安装的docker,相当于git Docker_host相当于centos系统 registry则是docker仓库,相当于GitHub 镜像用于创建docker容器,一个镜像可以创建多个docker容器 容器是由镜像创建的运行实例,(镜像相当于类,容器相当于类创建的对象)