使用Nginx开启HTTPS和HTTP2

之前写过一篇有关HTTP2.0的文章:关于HTTP/2协议的那些事后,尝试使用koa2的app.callback()返回的函数内嵌到Node.js原生HTTP2模块的ALPN中.但是这种方法有个缺点是:应用程序必须将自己限制为HTTP/1的公共API,却无法使用HTTP2模块的高级特性。
所以决定使用Nginx辅助项目应用程序开启HTTPS和HTTP2。
这样做的原理是 Nginx 接收到 HTTPS或HTTP2.0的请求后反向代理到后端程序的端口上,从而达到了项目应用程序开启 HTTPS或HTTP2 服务的目的。

安装

本人开发环境是MacOS系统,所以使用Brew快捷安装Nginx。
在命令行中输入如下命令:

brew install nginx

基本配置

生成自签发的秘钥和证书

cd /usr/local/etc/nginx
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' -keyout ./localhost-privkey.pem -out ./localhost-cert.pem

修改默认配置文件

修改Nginx的默认配置文件,配置地址为:/usr/local/etc/nginx/nginx.conf。
添加如下代码并保存:

server {
        listen       443 ssl http2;
        server_name  localhost;

        ssl_certificate      localhost-cert.pem;
        ssl_certificate_key  localhost-privkey.pem;

        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:4566;
        }
    }

启动nginx

在终端中输入如下命令:

sudo brew services start nginx

由于监听的默认端口443,所以需要添加sudo启动命令。如果没有添加,将会导致nginx启动失败,请执行如下命令:

sudo nginx -s stop

然后再重新启动nginx

打开浏览器,输入https://localhost 即可查看转发的内容。
由于使用自签发的秘钥和证书,浏览器会提示不安全,点击信任即可。

配置优化

使用HSTS策略强制浏览器使用HTTPS

在Nginx配置文件添加如下信息即可:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains;preload" always;

浏览器在获取该响应头后,在 max-age 的时间内,如果遇到 HTTP 连接,就会通过 307 跳转強制使用 HTTPS 进行连接,并忽略其它的跳转设置(如 301 重定向跳转)。
当HSTS头设置的过期时间到了,后面通过HTTP的访问恢复到正常模式,不会再自动跳转到HTTPS。
每次浏览器接收到Strict-Transport-Security头,它都会更新这个网站的过期时间,所以网站可以刷新这些信息,防止过期发生。
Chrome、Firefox等浏览器里,当您尝试访问该域名下的内容时,会产生一个307 Internal Redirect(内部跳转),自动跳转到HTTPS请求。