β

nginx HTTPS反向代理

黯羽轻扬 149 阅读

一.环境

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 * * * certbot renew >> ~/cron/cert.log
# 查看所有任务
crontab -l

三.配置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方式等等,都是后话

作者:黯羽轻扬
原文地址:nginx HTTPS反向代理, 感谢原作者分享。

发表评论