一.环境
Centos:
$ cat /etc/redhat-releas
CentOS Linux release 7.3.1611 (Core)
非必须,配置方式都一样,编译安装nginx过程也一样,熟悉哪个用哪个就好
nginx:
$ /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.9.9
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-file-aio --with-http_realip_module
configure arguments
里的with-http_ssl_module
是必须的,在./configure
时必须添上该选项启用ssl模块,否则比较麻烦(没有类似于phpize
这种东西,只能添上参数重新编译按需覆盖)
免费SSL证书:
https://letsencrypt.org/getting-started/
Let’s Encrypt相对更可靠一些,非盈利组织,旨在推动HTTPS化进程,所以用这个为世界和平出一份力(虽然主要就图个免费~)
P.S.证书3个月有效期,到期需要续命,可以通过工具自动续,不很麻烦
node:
$ nvm ls
v6.10.0
-> v7.9.0
default -> stable (-> v7.9.0)
node -> stable (-> v7.9.0) (default)
stable -> 7.9 (-> v7.9.0) (default)
非必须,用来验证nginx配置完毕后反向代理是否正常,其它任何能起HTTP server的方式都行
二.申请免费SSL证书
去https://letsencrypt.org/getting-started/,一步一步来,推荐With Shell Access方式。提供了一个命令行工具certbot,交互式配置,傻瓜式下一步,非常好用
另外,用命令行工具的好处是证书到期可以自动续,执行一条命令的事情,添到cron
任务里,就可以免打扰了。甚至可以每天自动来一发,官方也推荐这么做,作用是心跳包,表示健在,不会被筛查撤回:
Note:
if you’re setting up a cron or systemd job, we recommend running it twice per day (it won’t do anything until your certificates are due for renewal or revoked, but running it regularly would give your site a chance of staying online in case a Let’s Encrypt-initiated revocation happened for some reason). Please select a random minute within the hour for your renewal tasks.
按照certbot
一步一步来,比如本文环境的步骤是:
# 添yum源
yum -y install yum-utils
yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
# 安装certbot
sudo yum install certbot
# 只求证书,不自动配置
certbot certonly
一切正常的话,最后会得到类似这样的提示:
Generating key (2048 bits): /etc/letsencrypt/keys/0000_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0000_csr-certbot.pem
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/<mydomain>/fullchain.pem. Your cert will
expire on 2017-07-17. To obtain a new or tweaked version of this
certificate in the future, simply run certbot again. To
non-interactively renew *all* of your certificates, run "certbot
renew"
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
证书和私钥都放在/etc/letsencrypt/live/<mydomain>/
下:
$ ls /etc/letsencrypt/live/<mydomain>/
cert.pem chain.pem fullchain.pem privkey.pem README
其中cert.pem
是证书(服务端证书),privkey.pem
是私钥,有这两个就够了。另外,chain.pem
是根证书和中间证书等除服务端证书外的其它的,认证流程证书链需要的。fullchain.pem
是完整的证书链,包括cert.pem
和chain.pem
的内容
最后开启自动续命:
# 更新测试
certbot renew --dry-run
一切正常的话,添加cron
任务:
crontab -e
# 每天1.11更新证书
1 1 * * * certbot renew >> ~/cron/cert.log --renew-hook "/usr/local/nginx/sbin/nginx -s reload"
# 查看所有任务
crontab -l
注意:必须添上--renew-hook
证书更新后自动重启nginx,否则还会一直用过期的证书,虽然证书更新了,但不会生效
三.配置nginx HTTPS反向代理
检查ssl模块:
$ /usr/local/nginx/sbin/nginx -V
configure arguments
里有with-http_ssl_module
表示已经有ssl模块了,否则需要添上参数重新编译一份,覆盖掉现有的nginx可执行文件,具体步骤请查看nginx重新编译添加ssl模块
修改配置文件:
# 备份
cp /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf_
# 编辑
vi /usr/local/nginx/conf/nginx.conf
# 修改HTTPS server下的内容为
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/letsencrypt/live/<mydomain>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<mydomain>/privkey.pem;
ssl_session_timeout 5m;
location / {
proxy_pass http://localhost:7777;
}
}
# 测试配置语法
/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
# 重启nginx
/usr/local/nginx/sbin/nginx -s reload
一切正常的话,到这里就配置好了整站HTTPS请求都转发到7777端口
P.S.如果需要配置指定路径转发,修改location路径匹配规则就好,具体可以参考Nginx 配置简述
四.起HTTP server确认代理生效
由nginx来维护HTTPS连接,身后的HTTP服务几乎不需要做任何改动,因为收到的仍然是HTTP请求,只不过是经nginx转发的(但cookie
等经转发可能会出问题,需要配置proxy_cookie_path
,以后遇到再说)
const http = require('http');
const PORT = 7777;
http.createServer((req, res) => {
res.end('hoho, ' + PORT);
}).listen(PORT);
console.log('server is ready, listening ' + PORT);
访问https:<mydomain>/
看到hoho, 7777
,说明代理生效
地址栏已经挂上了一把漂亮的小绿锁,另外,一般还需要配置DNS解析规则,HTTP请求强制重发HTTPS,或者更合理的HSTS方式等等,都是后话
/站长,可以帮帮我吗