nginx 反向代理及 https 證書配置
author: yunqimg(ccxtcxx0)
1. 編譯安裝nginx
- 從官網下載 nginx源碼, 並編譯安裝.
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
make && make install
- 編譯時注意添加 SSL 模塊, 否則配置 https 時會失敗.
- 安裝完成后, nginx 程序默認保存在 /usr/local/nginx/sbin/ 目錄下, 啟動 nginx 命令如下
/usr/local/nginx/sbin/nginx -c /home/nginx/nginx.conf
推薦使用指定 配置文件路徑方式啟動, 這樣在 docker 方式部署時方便修改配置文件.
2. 反向代理配置
- 基本配置范例:
## Basic reverse proxy server ##
upstream backend {
server 127.0.0.1:8080; # local server
}
server {
location / {
proxy_pass http://backend;
}
}
upstream 節點記錄后端服務器地址, backend 是節點名稱.
Nginx 反向代理的指令不需要新增額外的模塊,默認自帶 proxy_pass 指令,只需要修改配置文件就可以實現反向代理。
- Nginx 反向代理模板
## Basic reverse proxy server ##
upstream tornado {
server 127.0.0.1:8080; # local server
}
server {
listen 80;
server_name example.com;
access_log /home/nginx/log/access.log main;
error_log /home/nginx/log/error.log;
root html;
index index.html index.htm index.php;
## send request back to tornado ##
location / {
proxy_pass http://tornado;
# Proxy Settings
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_max_temp_file_size 0;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}
nginx反向代理配置模塊, 推薦使用獨立的文件保存配置, 例如: 將上面提到的模板保存 到tornado.conf 文件中, 再在 nginx.conf 文件中添加 include /home/nginx/tornado.conf; 即可將兩個配置文件關聯.
添加位置如下
http {
include mime.types;
default_type application/octet-stream;
# xxx
# xxx
# ...
include /home/nginx/tornado.conf;
}
如何獲取HTTPS證書
詳情說明請參考 NGINX 配置 HTTPS 服務器
主要參考 使用 OpenSSL 生成 SSL Key 和 CSR 文件 這一段
HTTPS 基礎配置
要開啟 HTTPS 服務,在配置文件信息塊(server block),必須使用監聽命令 listen 的 ssl 參數和定義服務器證書文件和私鑰文件,如下所示
server {
# ssl參數
listen 443 ssl;
server_name example.com;
# 證書文件
ssl_certificate example.com.crt;
# 私鑰文件
ssl_certificate_key example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
#...
}
example.com.crt 和 example.com.key 可以是任意名稱, 只要配置文件與實際文件名對應即可.
若只填寫證書文件和私鑰文件的文件名無法正常工作, 可嘗試填寫完整文件路徑. 如: ssl_certificate /home/nginx/example.com.crt
證書文件會作為公用實體發送到每台連接到服務器的客戶端,私鑰文件作為安全實體,應該被存放在具有一定權限限制的目錄文件,並保證 Nginx 主進程有存取權限。
私鑰文件也有可能會和證書文件同放在一個文件中,如下面情況:
ssl_certificate www.example.com.cert;
ssl_certificate_key www.example.com.cert;
這種情況下,證書文件的的讀取權限也應該加以限制,盡管證書和私鑰存放在同一個文件里,但是只有證書會被發送到客戶端
命令 ssl_protocols 和 ssl_ciphers 可以用來限制連接只包含 SSL/TLS 的加強版本和算法,默認值如下
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
加強 HTTPS 安全性
HTTPS 基礎配置采取的默認加密算法是 SHA-1,這個算法非常脆弱,安全性在逐年降低,在 2014 年的時候, Google 官方博客就宣布在 Chrome 瀏覽器中逐漸降低 SHA-1 證書的安全指示,會從 2015 年起使用 SHA-2 簽名的證書,可參閱 Rabbit_Run 在 2014 年發表的文章:《為什么Google急着殺死加密算法SHA-1》
為此,主流的 HTTPS 配置方案應該避免 SHA-1,可以使用 迪菲-赫爾曼密鑰交換(D-H,Diffie–Hellman key exchange)方案。
首先在目錄 /etc/ssl/certs 運行以下代碼生成 dhparam.pem 文件
openssl dhparam -out dhparam.pem 2048
然后加入 Nginx 配置
#優先采取服務器算法
ssl_prefer_server_ciphers on;
#使用DH文件
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#定義算法
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
如果服務器夠強大,可以使用更為復雜的 4096 位進行加密。
一般情況下還應該加上以下幾個增強安全性的命令
#減少點擊劫持
add_header X-Frame-Options DENY;
#禁止服務器自動解析資源類型
add_header X-Content-Type-Options nosniff;
#防XSS攻擊
add_header X-Xss-Protection 1;
這幾個安全命令在 Jerry Qu 大神的文章《一些安全相關的HTTP響應頭》有詳細的介紹。
優化后的綜合配置
worker_processes auto;
http {
#配置共享會話緩存大小,視站點訪問情況設定
ssl_session_cache shared:SSL:10m;
#配置會話超時時間
ssl_session_timeout 10m;
server {
listen 443 ssl;
server_name www.example.com;
#設置長連接
keepalive_timeout 70;
#證書文件
ssl_certificate www.example.com.crt;
#私鑰文件
ssl_certificate_key www.example.com.key;
#優先采取服務器算法
ssl_prefer_server_ciphers on;
#使用DH文件
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#定義算法
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
#減少點擊劫持
add_header X-Frame-Options DENY;
#禁止服務器自動解析資源類型
add_header X-Content-Type-Options nosniff;
#防XSS攻擊
add_header X-Xss-Protection 1;
#...
強制使用 HTTPS
為了兼容原來80端口的HTTP方式的訪問,可以將80端口的訪問請求全部轉發到443端口上,在 upstream 與 server 之間增加配置如下
## your-domain.com ##
server {
listen 80;
server_name your-domain.com;
location = / {
rewrite ^/(.*) https://your-domain.com/$1 permanent; # force redirect http to https
}
location / {
rewrite ^/(.*) https://your-domain.com/ permanent; # force redirect http to https
}
}
參考
https://www.cnblogs.com/ghjbk/p/6744131.html
HttpUpstream-Nginx中文文檔
nginx反向代理原理和配置講解
nginx反向代理
single_http_https_server
Nginx配置upstream實現負載均衡
Nginx安裝部署之反向代理配置與負載均衡
Nginx 配置 HTTPS 服務器
Nginx+Https配置
一些安全相關的HTTP響應頭
nginx強制使用https訪問(http跳轉到https)
Nginx配置HTTPS
nginx的location配置詳解
解決Nginx報錯The plain HTTP request was sent to HTTPS port
The plain HTTP request was sent to HTTPS port
SSL For Free網站獲取Let's Encrypt免費SSL證書
