在上一篇文章中我们已经实现了本地node服务使用https访问了,看上一篇文章 效果可以看如下:

但是如果我们现在使用http来访问的话,访问不了。如下图所示:

因此我现在首先要做的是使用nginx配置下,当用户在浏览器下输入http请求的时候使用nginx重定向到https下即可。因此我们现在需要做一个简单的nginx重定向功能。想要深入了解nginx重定向功能,可以看这篇文章.

因此在我们的nginx中需要加如下重定向配置:

server {
listen xxx.abc.com;
server_name xxx.abc.com;
rewrite ^/(.*)$ https://$host$1 permanent;
}

因此nginx主要的配置代码如下:

server {
listen xxx.abc.com;
server_name xxx.abc.com;
rewrite ^/(.*)$ https://$host$1 permanent;
}
server {
listen 443 ssl;
server_name xxx.abc.com; ssl_certificate cert/server.crt;
ssl_certificate_key cert/server.key; ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on; location / {
proxy_pass http://localhost:3001;
}
}

如上配置后,我们需要重新启动下nginx即可生效,我们在浏览器下输入域名 http://xxx.abc.com 后 会自动重定向到 https://xxx.abc.com/ 了,我们再来看下 我们网络上的请求有2个请求,如下所示:

如上请求可以看到,浏览器首先会向网站发起一次http请求(http://xxx.abc.com), 在得到一个重定向响应后,再会发起一次https请求并得到最终的响应内容。对用户来讲,它的操作是透明的,用户体验也是不错的,但是在https链接之前会存在一次明文的http请求和重定向。那么攻击者可以以中间人的方式劫持http请求。来进行后续的攻击。比如窃听数据。篡改请求或响应、跳转到钓鱼网站等操作。因此http请求是不够安全的,所以最近几年所有的网站都要以https来访问的。

那么以劫持http请求并跳转到钓鱼网站类为列子,来看看大致的劫持流程是如下这个样子的。

操作步骤如下:
1. 浏览器会发起一次http请求(比如http://xxx.abc.com). 发出请求后,攻击者会以中间人的身份来劫持该http请求。
2. 攻击者劫持该http请求后,会把当前请求转发给钓鱼网站(比如 http://xxx.yyy.com)。
3. 钓鱼网站会返回假冒的网页内容。
4. 最后攻击者把假冒的网页内容返回给浏览器。

如上http请求根本就没有重定向到https网站到,而是攻击者直接劫持了http请求,最终把钓鱼网站返回给浏览器了。因此如果直接http重定向的话,会存在一次http请求明文的问题,因此直接使用http重定向是不安全的,因此就出现了HSTS来解决这个问题。下面我们来认识下HSTS吧。

2. 认识下HSTS

如上使用重定向的方式,把http重定向到https存在安全性问题,因为在重定向https之前会存在一次http明文的请求,那么攻击者很容易劫持http请求,因此现在我们想当用户浏览器发起http请求的时候,浏览器直接转换成https请求。然后通过https请求页面,这样的话,攻击者就一般很难进行攻击了。我们可以请看如下示意图,如下所示:

步骤可以理解为如下:

1. 用户在浏览器输入 http://xxx.abc.com 的时候,浏览器知道该域名需要使用https来进行通信。
2. 因此浏览器直接向网站发起https请求(比如https://xxx.abc.com) 这样的。
3. 网站返回响应的内容。

那么现在的问题就是说,浏览器怎么知道该域名需要使用https呢?因此这个时候我们出现了HSTS了。

HSTS是啥?

HSTS的全称是 HTTP Strict-Transport-Security. 它是国际互联网工程组织IETF发布的一种互联网安全策略机制。采用HSTS策略的网站将保证浏览器始终链接到该网站的https加密版本。不需要用户手动在URI地址栏中输入加密地址,来减少会话被劫持的风险。

HSTS的基本语法如下:

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

max-age 是必须的参数,它是一个以秒为单位的数值,它代表着HSTS Header的过期时间,一般设置为1年,即 31536000秒。
includeSubDomains 是可选参数,如果设置该参数的话,那么意味着当前域名及其子域名均开启HSTS的保护。
preload是可选参数,只有当你申请将自己的域名加入到浏览器内置列表的时候才需要使用到它。

下面我们先来看下百度的也是这样处理的,我们先在浏览器URI输入 http://www.baidu.com/ 后回车,浏览器会自动转化成 https://www.baidu.com/ 这样的请求了,但是我们使用chrome浏览器看网络下的请求可以看到如下会发送2次请求,如下所示:

第二次是https请求,如下所示:

我们可以看到如上,第一次请求状态码是307,并且请求头有这样的标识 "Provisional headers are shown", 具体的含义可以理解为浏览器拦截了该请求,并且该请求并没有发送出去。因此浏览器发现该域名需要使用https来请求,所以就发了第二次https请求了。

nginx下配置HSTS

在nginx配置文件上设置HSTS响应头部,代码如下:

add_header Strict-Transport-Security "max-age=172800; includeSubDomains"

因此nginx的配置如下:

server {
listen xxx.abc.com;
server_name xxx.abc.com;
rewrite ^/(.*)$ https://$host$1 permanent;
}
server {
listen 443 ssl;
server_name xxx.abc.com;
add_header Strict-Transport-Security "max-age=172800; includeSubDomains";
ssl_certificate cert/server.crt;
ssl_certificate_key cert/server.key; ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on; location / {
proxy_pass http://localhost:3001;
}
}

然后nginx配置保存,然后重启。

当我重启后,第一次使用https方式访问我的网站,nginx会告诉客户端浏览器,以后如果用户输入的是http,也要让浏览器以https来访问我的nginx服务器,如下所示:

但是如果nginx重启后,第一次使用http访问的话,虽然跳转了,但是并没有使用HSTS了,因为要跳转到https,才会使用HSTS。但是当我再输入http了就会有307状态码,并且有 "Provisional headers are shown" 这样的提示。

理解HSTS Preload List

HSTS虽然可以解决HTTPS的降级攻击,但是对于HSTS生效前首次的http请求,依然是无法避免http请求被劫持的问题,比如我们第一次浏览器清除缓存,然后第一次使用http请求的话,第一次http也是明文传输的,当跳转到https后会使用HSTS的,以后只要浏览器缓存不清除的话,nginx不重启的话,都会使用HSTS保护的。因此为了解决第一次http请求的问题,浏览器厂商们为了解决这个问题,提出了 HSTS Preload List 的方案,内置一份可以定期更新的表,对于列表中的域名,即使用户之前没有访问过,也会使用https协议请求的。

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

1. 拥有合法的证书(如果使用SHA-1证书,过期时间必须早于2016年);

2. 将所有HTTP流量重定向到HTTPS;
3. 确保所有子域名都启用了HTTPS;
4. 输出HSTS响应头:
5. max-age不能低于18周(10886400秒);
6. 必须指定includeSubdomains参数;
7. 必须指定preload参数;

即便满足了上述所有条件,也不一定能进入HSTS Preload List,更多信息可以查看:https://hstspreload.org/。

通过Chrome的chrome://net-internals/#hsts工具,可以查询某个网站是否在PreloadList之中,还可以手动把某个域名加到本机Preload List。

HSTS缺点

HSTS并不是HTTP会话劫持的完美解决方案。用户首次访问某网站是不受HSTS保护的。这是因为首次访问时,浏览器还未收到HSTS,所以仍有可能通过明文HTTP来访问。

如果用户通过HTTP访问HSTS保护的网站时,以下几种情况存在降级劫持可能:

1. 以前从未访问过该网站。
2. 最近重新安装了其操作系统。
3. 最近重新安装了其浏览器。
4. 切换到新的浏览器。
5. 删除浏览器的缓存。
6. 最近没访问过该站并且max-age过期了。
那么解决该问题的方法,可以使用上面介绍的 HSTS Preload List 方法。

支持HSTS浏览器

目前主流浏览器都已经支持HSTS特性,具体可参考下面列表:

Google Chrome 4及以上版本
Firefox 4及以上版本
Opera 12及以上版本
Safari从OS X Mavericks起
Internet Explorer及以上版本

nginx开启HSTS让浏览器强制跳转HTTPS访问的更多相关文章

  1. 开启HSTS让浏览器强制跳转HTTPS访问

    开启HSTS让浏览器强制跳转HTTPS访问 来源 https://www.cnblogs.com/luckcs/articles/6944535.html 在网站全站HTTPS后,如果用户手动敲入网站 ...

  2. nginx安装SSL证书,并强制跳转https访问

    网站最初是nginx代理80端口,实现http访问的.现在要安装SSL证书,使用https访问. 我的nginx根目录是/usr/local/nginx,将申请的SSL证书和key放在/usr/loc ...

  3. nginx配置http强制跳转https

    nginx配置http强制跳转https 网站添加了https证书后,当http方式访问网站时就会报404错误,所以需要做http到https的强制跳转设置. 一.采用nginx的rewrite方法 ...

  4. windwos下nginx 配置https并http强制跳转https

    windwos下nginx  配置https并http强制跳转https 一.首先配置证书文件 申请证书文件,这里就不做详细过程了,直接看证书文件结果. 这是两个证书的关键文件 打开ngxin下con ...

  5. Nginx配置http跳转https访问

    Nginx强制http跳转https访问有以下几个方法 nginx的rewrite方法 可以把所有的HTTP请求通过rewrite重写到HTTPS上 配置 方法一 server{ listen ; s ...

  6. 解决:ngxin做http强制跳转https,接口的POST请求变成GET

    域名配置了http强制跳转htpps后发现app发起post请求会出现405错误. 所以怀疑是http强制跳转https出现了问题.修改nginx配置如下即可解决: server { listen ; ...

  7. ngxin做http强制跳转https,接口的POST请求变成GET

    http强制跳转https出现了问题.修改nginx配置如下即可解决: server { listen 80; server_name *.snsprj.cn; return 307 https:// ...

  8. 服务器 apache配置https,http强制跳转https(搭建http与https共存)

    公司linux服务器上的nginx的已经改成https了,现在还剩下一个windows云服务器没配置. 环境 windows wampserver2.5 64位 1.腾讯云申请的ssl 包含三个文件: ...

  9. tomcat配置https 和 http强制跳转https

    https是http+ssl的可进行加密传输,身份认证的网络协议,防止数据在传输过程中被窃取.因此,https将得到越来越广泛的应用,下面是如何配置tomcat服务器让http自动转到https的步骤 ...

随机推荐

  1. JWT(JSON WEB TOKEN) / oauth2 / SSL

    1: JWT: 为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景.JWT的声明一般被 ...

  2. 【java并发编程艺术学习】(五)第二章 java并发机制的底层实现原理 学习记录(三) 原子操作的实现原理学习

    章节介绍 主要包括 术语定义.处理器如何实现原子操作.Java如何实现原子操作: 原子(atomic)本意是 不能再进一步分割的最小粒子,“原子操作” 意为 不可被中断的一个或一系列操作. 术语定义 ...

  3. linux命令-bzip2压缩

    gzip和bzip2 都是压缩命令  区别是压缩算法不一样  一般bzip2压缩的效率高  都不能压缩目录 bzip2 压缩 [root@wangshaojun ~]# bzip2 install.l ...

  4. linux命令-vim一般模式下复制剪切粘贴

    删除光标后的一个字符 x 删除光标前的一个字符 shift+x 删除指定个数的字符 数字+x 删除一行字符 dd 剪切指定行数  数字dd  3dd 剪切3行 其实并没有删掉而是保存着剪切板里 粘贴在 ...

  5. python变量、类型、运算、输出

    1.变量.类型.运算.输出等 # -*- coding: utf-8 -*- a=2 b=3 c=a+b print u'结果是=%i'%c #加u显示中文 str=unicode(s,"u ...

  6. win7下在eclipse3.7中使用hadoop1.2.1插件运行MadReduce例子

    环境 win7+hadoop_1.2.1+eclipse 3.7+maven 3 1.在win7下下载hadoop_1.2.1 2.安装hadoop的eclipse插件,注意eclipse 4.x版本 ...

  7. 树莓派 Learning 003 --- GPIO 000 --- GPIO引脚图

    树莓派 Learning 003 - GPIO 000 - GPIO引脚图 我的树莓派型号:Raspberry Pi 2 Model B V1.1 装机系统:NOOBS v1.9.2 Raspberr ...

  8. vmware克隆Centos网卡修改方法

    vmware克隆Centos网卡修改方法 1,查看网卡信息,获得eth编号和MAC地址 # dmesg | grep eth  e1000 0000:02:00.0:eth0:(PCI:66MHz:3 ...

  9. 20169219 linux内核原理与分析第二周作业

    "linux内核分析"的第一讲主要讲了计算机的体系结构,和各寄存器之间对数据的处理过程. 通用寄存器 AX:累加器 BX:基地址寄存器 CX:计数寄存器 DX:数据寄存器 BP:堆 ...

  10. [WIP]JavaScript import, export

    创建: 2019/06/14 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/import h ...