HTTPS笔记
Google、Apple 等大公司在大力推动 HTTPS,把自己的网站武装上 HTTPS 已经是势在必行。SSL证书有付费的,也有免费的。当然能用付费的更好,但对于自己的小站,免费SSL足矣。免费证书来源挺多,笔者选择了腾讯家的(DV SSL)。另外,阿里家也提供免费证书申请。
下面就记录了从申请证书到部署上 Nginx 的过程。
一、申请证书
访问腾讯云的SSL证书管理页面,通过 申请证书 渠道,按照提示步骤很快就会完成申请。
腾讯云 证书管理下载证书压缩包,文件结构如下:
├ Apache
│ ├ 1_root_bundle.crt
│ ├ 2_www.domain.com.crt
│ └ 3_www.domain.com.key
├ IIS
│ └ www.domain.com.pfx
└ Nginx
├ 1_www.domain.com_bundle.crt
└ 2_www.domain.com.key
二、部署到 Nginx
server {
listen 443;
server_name www.domain.com;
ssl on;
ssl_certificate /etc/nginx/cert/1_www.domain.com_bundle.crt;
ssl_certificate_key /etc/nginx/cert/2_www.domain.com.key;
ssl_session_timeout 5m;
location / {
# ...
}
}
HTTP 与 HTTPS 共存:
server {
listen 80;
listen 443 ssl;
server_name www.domain.com;
# ssl on;
ssl_certificate /etc/nginx/cert/1_www.domain.com_bundle.crt;
ssl_certificate_key /etc/nginx/cert/2_www.domain.com.key;
ssl_session_timeout 5m;
location / {
# ...
}
}
注意 # ssl on;
* 相关概念
从 菩提树下的杨过.Net 的博客 openssl、x509、crt、cer、key、csr、ssl、tls 这些都是什么鬼? 中摘抄:
-
TLS:传输层安全协议 Transport Layer Security 的缩写
-
SSL:安全套接字层 Secure Socket Layer 的缩写
TLS 与 SSL 对于不是专业搞安全的开发人员来讲,可以认为是差不多的,这二者是并列关系,详细差异见 http://kb.cnblogs.com/page/197396/
-
KEY:通常指私钥
-
CSR:Certificate Signing Request 的缩写,即证书签名请求,这不是证书,可以简单理解成公钥,生成证书时要把这个提交给权威的证书颁发机构。
-
CRT:Certificate 的缩写,即证书
-
X.509:一种证书格式。对 X.509 证书来说,认证者总是 CA 或由 CA 指定的人,一份 X.509 证书是一些标准字段的集合,这些字段包含有关用户或设备及其相应公钥的信息。
X.509 的证书文件,一般以
.crt
结尾,根据该文件的内容编码格式,可以分为以下二种格式:- PEM:Privacy Enhanced Mail,打开看是文本格式,以“-----BEGIN...”开头,“-----END...”结尾,内容是 BASE64 编码。Apache和 Nginx 服务器偏向于使用这种编码格式。
- DER:Distinguished Encoding Rules,打开看是二进制格式,不可读。Java 和 Windows 服务器偏向于使用这种编码格式。
-
OpenSSL:相当于 SSL 的一个实现,如果把 SSL 规范看成 OO 中的接口,那么 OpenSSL 则认为是接口的实现。接口规范本身是安全没问题的,但是具体实现可能会有不完善的地方,比如之前的“心脏出血”漏洞,就是 OpenSSL 中的一个 BUG。
* 自建证书
通过 Linux 的 openssl
创建证书:
openssl genrsa 1024 > server.key
openssl req -new -key server.key -out csr.pem
openssl x509 -req -days 365 -in csr.pem -signkey server.key -out server.crt
* 部署到 Nodejs
对基于 express
框架的 Nodejs 进行改造。
var express = require('express');
var app = express();
// ...
var server = app.listen(80, function() {
var host = server.address().address;
var port = server.address().port;
if (host == '::') {
host = 'localhost';
}
logger.info('http://%s:%s/test/', host, port);
});
logger.info('Server is running...');
var express = require('express');
var https = require('https');
var fs = require('fs');
var app = express();
// ...
var key4Https = fs.readFileSync('./cert/2_www.domain.com.key', 'utf-8');
var crt4Https = fs.readFileSync('./cert/1_www.domain.com_bundle.crt', 'utf-8');
var credentials = { key: key4Https, cert: crt4Https };
var httpsServer = https.createServer(credentials, app);
httpsServer.listen(80, function() {
logger.info('https://localhost/test/');
});
logger.info('Server is running...');