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 标记,请自行核实服务条款、价格和可用性,并遵守当地法律法规。