Nginx 反向代理與 SSL 證書配置完整教程 2026

Nginx 是當今最流行的 Web 服務器和反向代理服務器之一,以其高性能、高併發處理能力和低資源消耗著稱。本文將帶你從基礎配置到高級優化,全面掌握 Nginx 的核心技能。
本文涵蓋:
- ✅ 反向代理基礎配置
- ✅ Let's Encrypt SSL 證書自動配置與續期
- ✅ HTTP/2 與 HTTPS 安全配置
- ✅ 虛擬主機多域名配置
- ✅ 負載均衡與健康檢查
- ✅ WebSocket 代理支持
- ✅ 安全頭部與性能優化
一、Nginx 基礎安裝與配置
1.1 安裝 Nginx
# Debian / Ubuntu
sudo apt update && sudo apt install -y nginx
# CentOS / RHEL
sudo dnf install -y nginx
# 驗證安裝
nginx -v
# 輸出示例: nginx version: nginx/1.25.3
# 啟動並設置開機自啟
sudo systemctl enable --now nginx
# 檢查狀態
sudo systemctl status nginx1.2 基礎配置文件結構
# Nginx 配置文件結構
/etc/nginx/
├── nginx.conf # 主配置文件
├── conf.d/ # 額外配置目錄
│ └── *.conf # 站點配置文件
├── sites-available/ # 可用站點配置
│ └── example.com # 站點配置文件
├── sites-enabled/ # 啟用的站點(軟鏈接)
│ └── example.com -> ../sites-available/example.com
└── ssl/ # SSL 證書目錄
├── example.com.crt
└── example.com.key1.3 基礎反向代理配置
# /etc/nginx/sites-available/example.com
server {
listen 80;
server_name example.com www.example.com;
# 重定向到 HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL 證書配置
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 反向代理到後端應用
location / {
proxy_pass http://localhost:3000;
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_set_header X-Forwarded-Proto $scheme;
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# 靜態文件直接服務
location /static/ {
root /var/www/example.com;
expires 30d;
add_header Cache-Control "public, immutable";
}
}1.4 啟用站點配置
# 創建軟鏈接啟用站點
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
# 測試配置文件語法
sudo nginx -t
# 輸出: nginx: configuration file /etc/nginx/nginx.conf test is successful
# 重新加載配置(不中斷服務)
sudo systemctl reload nginx二、Let's Encrypt SSL 證書配置
2.1 安裝 Certbot
# 安裝 Certbot 和 Nginx 插件
sudo apt update && sudo apt install -y certbot python3-certbot-nginx
# CentOS / RHEL
sudo dnf install -y certbot python3-certbot-nginx
# 驗證安裝
certbot --version2.2 自動獲取 SSL 證書
# 方法1: 自動配置(推薦)
sudo certbot --nginx -d example.com -d www.example.com
# 方法2: 僅獲取證書(手動配置)
sudo certbot certonly --nginx -d example.com -d www.example.com
# 方法3: 手動模式(無服務器)
sudo certbot certonly --manual -d example.com
# 證書文件位置
/etc/letsencrypt/live/example.com/
├── cert.pem # 證書
├── chain.pem # 證書鏈
├── fullchain.pem # 完整證書鏈(包含證書和鏈)
└── privkey.pem # 私鑰2.3 自動續期配置
# 檢查自動續期配置
sudo systemctl status certbot.timer
# 測試續期
sudo certbot renew --dry-run
# 如果需要手動續期
sudo certbot renew
# 強制續期(如果有問題)
sudo certbot renew --force-renewal
# 配置自動續期後重新加載 Nginx
echo "0 3 * * * certbot renew --quiet --deploy-hook 'systemctl reload nginx'" | sudo tee -a /etc/crontab2.4 完整 SSL 配置示例
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL 證書
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL 優化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on;
ssl_stapling_verify on;
# 安全頭部
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 反向代理配置
location / {
proxy_pass http://localhost:3000;
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_set_header X-Forwarded-Proto $scheme;
}
}三、HTTP/2 配置與性能優化
3.1 HTTP/2 配置
# 在 server 塊中啟用 HTTP/2
server {
listen 443 ssl http2;
# HTTP/2 優化
http2_push_preload on;
http2_max_concurrent_streams 100;
http2_idle_timeout 60s;
}3.2 性能優化配置
# /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 1024;
multi_accept on;
use epoll;
}
http {
# 基礎優化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip 壓縮
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# Brotli 壓縮(需要編譯支持)
# brotli on;
# brotli_types text/plain text/css application/json application/javascript text/xml application/xml+rss text/javascript;
# 緩存控制
expires 1y;
add_header Cache-Control "public, immutable";
# 日誌優化
access_log /var/log/nginx/access.log combined buffer=16k;
error_log /var/log/nginx/error.log warn;
# 包含站點配置
include /etc/nginx/sites-enabled/*;
}3.3 客戶端緩存配置
server {
# 靜態資源緩存
location ~* \.(jpg|jpeg|png|gif|ico|svg|webp|css|js|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header ETag "";
# 禁止緩存敏感文件
if ($request_uri ~* "(\.php|\.py|\.sh)$") {
expires off;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
}
# HTML 文件不緩存
location ~* \.(html|htm)$ {
expires -1;
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
}
}四、虛擬主機配置
4.1 多域名配置
# /etc/nginx/sites-available/example.com
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# /etc/nginx/sites-available/api.example.com
server {
listen 80;
server_name api.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}4.2 泛域名配置
# 泛域名配置(需要通配符證書)
server {
listen 80;
server_name *.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name *.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 根據子域名路由到不同後端
location / {
if ($host = "api.example.com") {
proxy_pass http://localhost:8000;
break;
}
if ($host = "app.example.com") {
proxy_pass http://localhost:3000;
break;
}
# 默認後端
proxy_pass http://localhost:8080;
}
}4.3 獲取泛域名證書
# 使用 DNS 驗證獲取泛域名證書
sudo certbot certonly \
--manual \
--preferred-challenges=dns \
-d example.com \
-d *.example.com五、負載均衡配置
5.1 基礎負載均衡
# /etc/nginx/conf.d/upstream.conf
upstream backend {
server backend1.example.com:8080;
server backend2.example.com:8080;
server backend3.example.com:8080;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}5.2 負載均衡策略
# 輪詢(默認)
upstream backend {
server backend1.example.com;
server backend2.example.com;
}
# 最小連接數
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
}
# IP 哈希(同一 IP 始終路由到同一服務器)
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}
# 加權輪詢
upstream backend {
server backend1.example.com weight=3; # 30% 的流量
server backend2.example.com weight=7; # 70% 的流量
}
# 健康檢查(需要 nginx-plus 或第三方模塊)
upstream backend {
server backend1.example.com max_fails=3 fail_timeout=30s;
server backend2.example.com max_fails=3 fail_timeout=30s;
# nginx-plus 健康檢查
# zone backend 64k;
# health_check;
}5.3 備用服務器配置
upstream backend {
server backend1.example.com;
server backend2.example.com;
# 備用服務器(主服務器都不可用時使用)
server backup.example.com backup;
}六、WebSocket 代理配置
6.1 基礎 WebSocket 代理
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# WebSocket 代理
location /ws/ {
proxy_pass http://localhost:8080;
# WebSocket 必需的頭信息
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 超時設置
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
# 客戶端 IP 傳遞
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
}
}6.2 Socket.IO 代理
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Socket.IO 代理
location /socket.io/ {
proxy_pass http://localhost:3000;
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 長輪詢支持
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_set_header X-Forwarded-Proto $scheme;
# 超時設置
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
# 緩衝區設置
proxy_buffers 8 32k;
proxy_buffer_size 64k;
}
}七、安全配置與防護
7.1 安全頭部配置
server {
# HSTS(強制 HTTPS)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# 防止點擊劫持
add_header X-Frame-Options DENY always;
# MIME 類型嗅探防護
add_header X-Content-Type-Options nosniff always;
# XSS 保護
add_header X-XSS-Protection "1; mode=block" always;
# 內容安全策略(根據需要調整)
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'" always;
# 權限策略
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
# 引薦來源策略
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 跨域資源共享
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
}7.2 限制請求速率
# 限制單 IP 請求速率
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
location /api/ {
# 限制每秒 10 個請求,最多延遲處理 50 個請求
limit_req zone=api burst=50 nodelay;
proxy_pass http://localhost:8000;
}
}
# 限制連接數
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
location / {
# 限制單 IP 最多 10 個併發連接
limit_conn conn_limit 10;
proxy_pass http://localhost:3000;
}
}7.3 禁止訪問敏感文件
server {
# 禁止訪問隱藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# 禁止訪問配置文件
location ~* (config\.json|config\.yml|\.env|\.git) {
deny all;
access_log off;
log_not_found off;
}
# 禁止訪問日誌文件
location ~* \.(log|sql|bak)$ {
deny all;
access_log off;
log_not_found off;
}
}7.4 允許特定 IP 訪問
server {
# 僅允許特定 IP 訪問管理後臺
location /admin/ {
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
proxy_pass http://localhost:3000;
}
}八、日誌配置與分析
8.1 日誌格式配置
# /etc/nginx/nginx.conf
http {
# 自定義日誌格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$request_time $upstream_response_time';
log_format json '{ "time": "$time_local", '
'"remote_addr": "$remote_addr", '
'"remote_user": "$remote_user", '
'"request": "$request", '
'"status": "$status", '
'"body_bytes_sent": "$body_bytes_sent", '
'"http_referer": "$http_referer", '
'"http_user_agent": "$http_user_agent", '
'"request_time": "$request_time" }';
# 訪問日誌
access_log /var/log/nginx/access.log main;
# 錯誤日誌
error_log /var/log/nginx/error.log warn;
}8.2 日誌分析示例
# 統計訪問最多的頁面
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
# 統計狀態碼分佈
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr
# 統計訪問最多的 IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
# 查找 4xx 和 5xx 錯誤
awk '$9 >= 400' /var/log/nginx/access.log | head -20
# 計算平均響應時間
awk '{sum+=$14} END {print "Average response time: " sum/NR "ms"}' /var/log/nginx/access.log九、常見問題與解決方案
Q1:SSL 證書過期怎麼辦?
# 檢查證書過期時間
openssl x509 -enddate -noout -in /etc/letsencrypt/live/example.com/fullchain.pem
# 手動續期
sudo certbot renew
# 如果續期失敗,嘗試強制續期
sudo certbot renew --force-renewal
# 檢查自動續期定時器
sudo systemctl status certbot.timerQ2:Nginx 啟動失敗怎麼辦?
# 檢查配置語法
sudo nginx -t
# 查看錯誤日誌
tail -f /var/log/nginx/error.log
# 檢查端口是否被佔用
sudo ss -tlnp | grep :80
sudo ss -tlnp | grep :443
# 檢查權限問題
ls -la /etc/nginx/ssl/
ls -la /etc/letsencrypt/live/example.com/Q3:反向代理後獲取不到真實客戶端 IP?
# 確保配置了以下頭信息
location / {
proxy_pass http://localhost:3000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}在後端應用中讀取 X-Forwarded-For 或 X-Real-IP 頭來獲取真實客戶端 IP。
Q4:WebSocket 連接失敗?
# 確保配置了正確的頭信息
location /ws/ {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}Q5:如何配置 HTTP/3?
# HTTP/3 需要特殊配置(需要編譯支持或使用 nginx-plus)
# 檢查是否支持 HTTP/3
nginx -V 2>&1 | grep quic
# 如果支持,配置示例
server {
listen 443 ssl http2 http3;
listen [::]:443 ssl http2 http3;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# QUIC 配置
ssl_quic on;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.3;
}十、完整配置示例
10.1 生產環境完整配置
# /etc/nginx/sites-available/example.com
# HTTP -> HTTPS 重定向
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
# ACME 挑戰(用於 Let's Encrypt 驗證)
location /.well-known/acme-challenge/ {
root /var/www/html;
allow all;
}
# 其他請求重定向到 HTTPS
return 301 https://$server_name$request_uri;
}
# HTTPS 主站點
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
# SSL 配置
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL 優化
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on;
ssl_stapling_verify on;
# 安全頭部
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 靜態文件緩存
location ~* \.(jpg|jpeg|png|gif|ico|svg|webp|css|js|woff|woff2|ttf|eot)$ {
root /var/www/example.com;
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# WebSocket 代理
location /ws/ {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
}
# 主應用代理
location / {
proxy_pass http://localhost:3000;
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_set_header X-Forwarded-Proto $scheme;
# 緩存控制
expires -1;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# 錯誤頁面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}結語
Nginx 是一個功能強大的工具,掌握好它可以為你的網站提供高性能、高安全性的服務。本文涵蓋了從基礎配置到高級優化的大部分內容,但 Nginx 的能力遠不止這些。
推薦學習路徑:
- 掌握基礎配置和反向代理
- 配置 SSL 證書和安全頭部
- 學習負載均衡和健康檢查
- 深入瞭解性能優化和日誌分析
推薦閱讀:
🚀 提示: 定期更新 Nginx 和 Certbot,保持你的服務器安全和性能處於最佳狀態。
延伸阅读
免责声明
本文仅供技术交流和学习参考。涉及第三方服务的链接可能包含 sponsored 标记,请自行核实服务条款、价格和可用性,并遵守当地法律法规。