跳到主要內容
黯羽輕揚每天積累一點點

nginx HTTPS 反向代理

免費2017-04-23#Node#Solution#免费HTTPS证书推荐#nginx添加https模块#nginx反向代理https#nginx node https#nodejs https

不來把免費的小綠鎖嗎?

一。環境

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.pemchain.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 方式等等,都是後話

評論

暫無評論,快來發表你的看法吧

提交評論