随着互联网快速发展,互联网信息安全越来越受到大家重视,HTTPS 应该是近两年各大厂商都在尽力普及的技术之一。国内大厂基本上已经全面普及了 HTTPS。

本文首发于我的个人网站:听说 - https://tasaid.com/,建议在我的个人网站阅读,拥有更好的阅读体验。

前端开发 QQ 群:377786580

HTTPS 现状

早在 2016 年底,我就写过 《 从 HTTP 到 HTTPS 系列 》文章来讲解 HTTPS。当时结合本站的部署经验,给大家详细介绍了 《 IIS 部署免费 HTTPS 》。

这篇文章就跟大家介绍一下 Node.js 如何部署免费 HTTPS 以及简单的部署 HTTP/2

截止 2018 年 03 月 13 日,由 Let's Encrypt 实时统计报告 显示,在统计的 6930 多万活跃网站中,已经有 5350 万(约 77%)的站点部署了 HTTPS 证书服务。

同时 Google 透明度报告 - 网络上的 HTTPS 加密 中,统计了使用 Chrome 浏览器,访问的站点统计中,HTTPS 使用率的增长情况:

而在今年 2 月份,Chrome 团队也宣布,将在 2018 年 7 月份发布的 Chrome 68 中,将没有部署 HTTPS 的网站标记为 "不安全"。

简而言之,HTTPS 大势所趋。

Node.js 部署 HTTPS

早在 《 从 HTTP 到 HTTPS - IIS 部署免费 HTTPS 》一文中,我就指出了 Let's Encrypt 免费证书的优势:

由 ISRG(Internet Security Research Group,互联网安全研究小组)提供服务,免费、访问速度快,稳定等。

所以这次部署的证书也是围绕 Let's Encrypt 展开。

greenlock-express

由于 js 生态圈的繁华,所以想找一个现有的包是件很轻松的事情,greenlock-express 这个包就帮助我们封装了 Let's Enctrypt 证书的部署,只需要引入这个包并使用,就可以:

  1. 自动注册 Let's Encrypt 证书
  2. 自动续订( 80 天左右),且服务器无需重启
  3. 支持虚拟主机

并且 greenlock 相关的证书生态圈十分完善,同样有支持 koagreenlock-koa

安装和使用

通过 npm 安装 greenlock-express

$ npm install --save greenlock-express@2.x

使用起来非常简单,这是 greenlock-express 默认提供的 demo:

const greenlock = require('greenlock-express')

require('greenlock-express').create({
// 测试
server: 'staging',
// 联系邮箱
email: 'john.doe@example.com',
// 是否同意 Let's Encrypt 条款... 这必须为 true 啊,不然走不下去
agreeTos: true,
// 申请的域名列表,不支持通配符
approveDomains: [ 'tasaid.com', 'www.tasaid.com' ],
// 绑定 express app
app: require('express')().use('/', function (req, res) {
res.end('Hello, World!');
})
}).listen(80, 443)

证书存在 ~/letsencrypt

当然上面代码只能用于测试/开发环境,因为它并没有申请一个有效的证书,而是生成了一个自签名的证书(跟以前的 12306 自签证书一样),用于在开发环境中调试。

API

greenlock-expresscreate(options) 函数参数签名如下:

interface Options {
/**
* Express app
*/
app: Express
/*
* 远程服务器
* 测试环境中可用为 staging
* 生产环境中为 https://acme-v01.api.letsencrypt.org/directory
*/
server: string
/**
* 用于接收 let's encrypt 协议的邮箱
*/
email: string
/**
* 是否同意协议
*/
agreeTos: boolean
/**
* 在注册域名获取证书前,会执行这个回调函数
* string[]: 一组需要注册证书的域名
* 函数: 第一个参数跟 Options 格式差不多,第二个参数是当前自动获取的域名信息,第三个参数是在处理完之后传递的回调函数
*/
approveDomains: string[] | (opts, certs: cb) => any
/**
* 更新证书最大天数 (以毫秒为单位)
*/
renewWithin: number
/**
* 更新证书的最小天数(以毫秒为单位)
*/
renewBy: number
}

经过测试,在真实的生产环境中, approveDomains 必须为函数,传数组的话不会生效。

生产环境

生产环境中部署还需要做一些配置改动和引入一些包。

更新包:

$ npm i --save greenlock-express@2.x
$ npm i --save le-challenge-fs
$ npm i --save le-store-certbot
$ npm i --save redirect-https

生产代码:

const greenlock = require('greenlock-express')
const express = require('express') const app = express() const lex = greenlock.create({
// 注意这里要成这个固定地址
server: 'https://acme-v01.api.letsencrypt.org/directory',
challenges: {
'http-01': require('le-challenge-fs').create({ webrootPath: '~/letsencrypt/var/acme-challenges' })
},
store: require('le-store-certbot').create({
webrootPath: '~/letsencrypt/srv/www/:hostname/.well-known/acme-challenge'
}),
approveDomains: (opts: any, certs: any, cb: any) => {
appLog.info('approveDomains', { opts, certs })
if (certs) {
/*
* 注意这里如果是这样写的话,一定要对域名做校验
* 否则其他人可以通过将域名指向你的服务器地址,导致你注册了其他域名的证书
* 从而造成安全性问题
*/
// opts.domains = certs.altnames
opts.domains = [ 'tasaid.com', 'www.tasaid.com' ]
} else {
opts.email = '你的邮箱@live.com'
opts.agreeTos = true
}
cb(null, { options: opts, certs: certs })
},
}) // 这里的 redirect-https 用于自动将 HTTP 请求跳到 HTTPS 上
require('http').createServer(
lex.middleware(
require('redirect-https')()
)
).listen(80, function () {
console.log('Listening', `for ACME http-01 challenges on: ${JSON.stringify(this.address())}`)
})
// 绑定 HTTPS 端口
require('https').createServer(
lex.httpsOptions,
lex.middleware(app)
).listen(443, function () {
console.log(('App is running at http://localhost:%d in %s mode'), app.get('port'), app.get('env'))
console.log('Press CTRL-C to stop\n')
})

如果没有生效,可以检查下 ~/letsencrypt 的证书信息,和 443 端口是否打开。

部署 HTTP/2

HTTP/2HTTP/1.1 的升级版,主要来说改进了这些地方:

  1. 二进制协议:采用二进制流
  2. 多路复用:一次请求多次复用管道
  3. 服务器推送:解决 HTTP/1.x 时代最大的痛点

值的注意的是,HTTP/2 是支持 HTTP 协议的,只不过浏览器厂商都不愿意支持 HTTP,所以基本上可以认为,用上 HTTP/2 的前置条件是必须部署 HTTPS。

SPDY

早在 2009 年,Google 开发了一个实验性协议,叫做 SPDY,目的解决 HTTP/1.x 中的一些设计缺陷。在 SPDY 发布几年后,这个新的实验性协议得到了 Chrome、Firefox 和 Opera 的支持,应用越来越广泛。然后 HTTP 工作组 (HTTP-WG) 在这个 SPDY 的基础上,设计了 HTTP/2,所以可以说 SPDY 是 HTTP/2 的前身。

关于 HTTP/2 的详情可以参考 这篇文章

部署 HTTP/2

引入 HTTP/2Node.js 中也十分简单,只需要引入 spdy 包即可:

$ npm i --save spdy

然后我们把上一节的代码做一点修改即可支持 HTTP/2:

const greenlock = require('greenlock-express')
const express = require('express')
// HTTP/2
const spdy = require('spdy') const app = express() const lex = greenlock.create({
// 注意这里要成这个固定地址
server: 'https://acme-v01.api.letsencrypt.org/directory',
challenges: {
'http-01': require('le-challenge-fs').create({ webrootPath: '~/letsencrypt/var/acme-challenges' })
},
store: require('le-store-certbot').create({
webrootPath: '~/letsencrypt/srv/www/:hostname/.well-known/acme-challenge'
}),
approveDomains: (opts: any, certs: any, cb: any) => {
appLog.info('approveDomains', { opts, certs })
if (certs) {
/*
* 注意这里如果是这样写的话,一定要对域名做校验
* 否则其他人可以通过将域名指向你的服务器地址,导致你注册了其他域名的证书
* 从而造成安全性问题
*/
// opts.domains = certs.altnames
opts.domains = [ 'tasaid.com', 'www.tasaid.com' ]
} else {
opts.email = '你的邮箱@live.com'
opts.agreeTos = true
}
cb(null, { options: opts, certs: certs })
},
}) // 这里的 redirect-https 用于自动将 HTTP 请求跳到 HTTPS 上
require('http').createServer(
lex.middleware(
require('redirect-https')()
)
).listen(80, function () {
console.log('Listening', `for ACME http-01 challenges on: ${JSON.stringify(this.address())}`)
}) // HTTP/2
spdy.createServer(lex.httpsOptions, lex.middleware(app)).listen(443, function () {
console.log('Listening https', `for ACME tls-sni-01 challenges and serve app on: ${JSON.stringify(this.address())}`)
})

至于 HTTP/2 相关的技术应用,会在后续篇幅中再为大家讲解。

本文首发于我的个人网站:听说 - https://tasaid.com/,建议在我的个人网站阅读,拥有更好的阅读体验。

前端开发 QQ 群:377786580

Node.js 部署免费/自动续订 HTTPS的更多相关文章

  1. [转]用Node.js创建自签名的HTTPS服务器

    用Node.js创建自签名的HTTPS服务器 创建自己的CA机构 创建服务器端证书 创建客户端证书 将证书打包 创建自己的CA机构 为CA生成私钥 openssl genrsa -out ca-key ...

  2. Node.js创建自签名的HTTPS服务器

    https://cnodejs.org/topic/54745ac22804a0997d38b32d  用Node.js创建自签名的HTTPS服务器  发布于 4 年前  作者 eeandrew  6 ...

  3. node.js使用免费的阿里云ip查询获取ip所在地

    在项目过程中,我们常常需要获取IP的所在地.而这一功能一般都是通过一些数据网站的对外接口来实现,这些接口一般情况下都是付费使用的.在这篇文章中我将记录,基于node.js的阿里云免费IP地址查询接口的 ...

  4. Node.js 优雅地自动审核团队的代码

    Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. 简介 在团队开发中,无论是写前端(js,css,htm ...

  5. Node.js 部署到 CentOs

    配置服务器环境 3.把yum更新到最新版本: yum -y update 4.我们将使用最新源代码构建Node.js,要进行软件的安装,需要一组用来编译源代码的开发工具: yum -y groupin ...

  6. Node.js 解析gzip网页(https)

    gzip网页指网页头字段Content-Encoding是gzip(GNU zip)内容编码方式.内容编码是指不丢失实体信息的前提下所进行的压缩. Node.js 代码如下: //========== ...

  7. 关于node.js和npm,cnpm的安装记录以及gulp自动构建工具的使用

    关于node.js和npm,cnpm的安装记录以及gulp自动构建工具的使用   工作环境:window下 在一切的最开始,安装node.js (中文站,更新比较慢http://nodejs.cn/) ...

  8. Node.js~在linux上的部署

    我们以centOS为例来说说如何部署node.js环境 一 打开centos,然后开始下载node.js包 curl --silent --location https://rpm.nodesourc ...

  9. Heroku + Node.js + HTTPS

    昨天把 biz-to-me 升级到支持 HTTPS 了,为此研究了一下如何让 Heroku 上跑的 Node.js 应用支持 HTTPS.我发现并没有任何文章描述这个具体的流程,只有零碎的信息,所以在 ...

随机推荐

  1. CentOS7 修改网卡名称为eth0

    前言 无论是RHEL 7.还是CentOS 7都使用了NetworkManager.service来进行网络管理,当然network服务还是可以继续使用的,但也将会是过渡期的残留品了. 除此之外7版本 ...

  2. DML、DDL、DCL的区别

    DML(data manipulation language): 它们是SELECT.UPDATE.INSERT.DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言DDL( ...

  3. TensorFlow实战之实现AlexNet经典卷积神经网络

    本文根据最近学习TensorFlow书籍网络文章的情况,特将一些学习心得做了总结,详情如下.如有不当之处,请各位大拿多多指点,在此谢过. 一.AlexNet模型及其基本原理阐述 1.关于AlexNet ...

  4. 2017年StackOverflow上最好的20个Python问题

    1.Python的 .. (点号 点号) 是什么语法? 答案地址:https://stackoverflow.com/questions/43487811/what-is-python-dot-dot ...

  5. Window Server 布署 WCF 服务 , 权限配置问题

    起因: 客户服务器运行环境要求提高安全性,建议数据连接串采取 加密措施 ,或改用 Window 验证 连接数据库服务 .于是我们打算选择后着,将后台服务(Window Server)数据库连接串调整为 ...

  6. MySQL体系结构及多实例

    MySQL客户端和服务器端模型 MySQL是一个典型C/S,服务器端与客户端两部分组成 服务器端程序  mysqld mysql自带的客户端(mysql mysqladmin  mysqldump等) ...

  7. c++ 回调函数使用

    普通回调 #include<stdio.h> void printWelcome(int len) { printf("welcome -- %d\n", len); ...

  8. TP5整合 WorkerMan 以及 GatewayWorker

    TP5整合GatewayWorker Windows版安装 a)使用composer create-project topthink/think testTG,来安装thinkphp5. b)进入t ...

  9. SDL 2.0 如何在 windows 上使用?

    https://wiki.libsdl.org/APIByCategory http://adolfans.github.io/sdltutorialcn/sdl-2-dot-0-tutorial-i ...

  10. linux Nagios监控

    监控目标 监控目标主机分为四个部分 硬件资源 操作系统 数据库 应用软件 监控目的: 进行服务器性能调整前,知道调整什么,系统瓶颈在什么地方 被一部分必须同时监控,内容包括吞吐量,反应时间,使用率等 ...