跳到主要内容

nginx 反向代理 + Let\u0027s Encrypt:生产环境 HTTPS 完整配置

nginx 反向代理 + Let’s Encrypt:生产环境 HTTPS 完整配置

这篇教程会带你用 nginx 给 WordPress 站点配 HTTPS,包含自动续期、HSTS、性能优化。看完之后你能直接复制粘贴到自己的服务器上。

前置条件

  • 一台 Linux 服务器(Ubuntu 22.04 或 Debian 12 推荐)
  • 一个域名,DNS 已经解析到服务器 IP
  • nginx 已安装(nginx -v 应有输出)
  • 80 和 443 端口没被占用

安装 acme.sh(自动签发 Let’s Encrypt 证书)

acme.sh 比官方 certbot 简单,不依赖 Python:

curl https://get.acme.sh | sh -s email=your@email.com

source ~/.bashrc

acme.sh --version

安装完成后 ~/.acme.sh/ 是工作目录,所有证书都存在这里。

签发第一个证书

最简单的方式是 HTTP 验证(acme.sh 在你服务器上启动一个临时服务,Let’s Encrypt 来访问):

acme.sh --issue -d yourdomain.com -d www.yourdomain.com --nginx

--nginx 会自动读取你的 nginx vhost,找到 server_name 匹配的块做验证。

签发成功后证书会存到:

~/.acme.sh/yourdomain.com/

├── fullchain.cer # 服务器证书 + 中间证书

├── yourdomain.com.cer

├── yourdomain.com.key

└── ca.cer

安装证书到 nginx 目录

不要直接 cp,用 acme.sh 的 --install-cert 命令,它会自动创建 reload hook:

acme.sh --install-cert -d yourdomain.com \

--cert-file /etc/nginx/ssl/yourdomain.com.crt \

--key-file /etc/nginx/ssl/yourdomain.com.key \

--fullchain-file /etc/nginx/ssl/yourdomain.com.fullchain.crt \

--reloadcmd "systemctl reload nginx"

这样以后每次快过期时,acme.sh 会自动重新签发并 reload nginx。

nginx vhost 配置(HTTPS + 性能)

完整的 /etc/nginx/conf.d/yourdomain.com.conf

# 强制 HTTPS

server {

listen 80;

server_name yourdomain.com www.yourdomain.com;

return 301 https://$host$request_uri;

}

HTTPS server

server {

listen 443 ssl http2;

server_name yourdomain.com www.yourdomain.com;

# SSL 证书

ssl_certificate /etc/nginx/ssl/yourdomain.com.fullchain.crt;

ssl_certificate_key /etc/nginx/ssl/yourdomain.com.key;

# SSL 协议 + 加密套件(强安全)

ssl_protocols TLSv1.2 TLSv1.3;

ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';

ssl_prefer_server_ciphers on;

ssl_session_cache shared:SSL:10m;

ssl_session_timeout 1d;

ssl_session_tickets off;

# HSTS(强制浏览器用 HTTPS)

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

add_header X-Frame-Options "SAMEORIGIN" 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;

# 根目录

root /www/wwwroot/yourdomain.com;

index index.php index.html;

# WordPress 路由

location / {

try_files $uri $uri/ /index.php?$args;

}

# 静态资源缓存 + CORS

location ~ \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {

expires 30d;

add_header Cache-Control "public, max-age=2592000";

access_log off;

}

# PHP-FPM(BT 面板用 sock,其他系统用 127.0.0.1:9000)

location ~ \.php$ {

include fastcgi-php.conf;

fastcgi_pass unix:/tmp/php-cgi-82.sock;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

fastcgi_read_timeout 60s;

}

# 拒绝访问敏感文件

location ~ /\.(ht|git|env) {

deny all;

}

# WordPress 主题静态资源(如果是 Sage 11 主题)

location ^~ /app/themes/sage/public/build/ {

expires 30d;

add_header Cache-Control "public, max-age=2592000";

access_log off;

}

# 安全 headers

add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data: https:; font-src 'self' https://cdn.jsdelivr.net;" always;

# 日志

access_log /var/log/nginx/yourdomain.com.access.log;

error_log /var/log/nginx/yourdomain.com.error.log;

}

启用 HTTP/2(性能提升 30%+)

新版 nginx 已经默认开启 HTTP/2(在 listen 后加 http2)。检查:

nginx -V 2>&1 | grep -o 'http_v2_module'

测试

# 1. nginx 配置语法检查

nginx -t

2. 重载

systemctl reload nginx

3. 测试 HTTPS

curl -I https://yourdomain.com

4. SSL Labs 测试(A 级评分)

https://www.ssllabs.com/ssltest/analyze.html?d=yourdomain.com

性能优化(进阶)

启用 OCSP Stapling

ssl_stapling on;

ssl_stapling_verify on;

ssl_trusted_certificate /etc/nginx/ssl/yourdomain.com.fullchain.crt;

resolver 8.8.8.8 8.8.4.4 valid=300s;

Brotli 压缩(比 gzip 再省 20%)

# Ubuntu/Debian

apt install nginx-module-brotli

# /etc/nginx/nginx.conf

load_module modules/ngx_http_brotli_filter_module.so;

load_module modules/ngx_http_brotli_static_module.so;

在 http {} 块里

brotli on;

brotli_comp_level 6;

brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

启用 HTTP/3(QUIC,最快)

需要 nginx 1.25+,并编译 quiche:

git clone https://github.com/cloudflare/quiche

cd quiche

cargo build --release --features=openssl

然后 nginx listen 加 quic

listen 443 ssl http2;

listen 443 quic;

add_header Alt-Svc 'h3=":443"; ma=86400';

自动续期

acme.sh 默认会创建一个 cron 任务每天检查一次,快过期(30 天内)时自动重新签发:

crontab -l | grep acme

0 0 "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

如果你修改了 vhost(新增域名),记得手动跑一次:

acme.sh --renew -d yourdomain.com --force

常见问题

1. nginx reload 失败

通常是配置语法错。先 nginx -t 检查:

nginx -t

nginx: [emerg] unknown directive "..." in /etc/nginx/conf.d/xxx.conf:23

2. acme.sh 验证失败

检查 80 端口是否被占用(特别是 BT 面板默认会装 Apache 占 80):

netstat -tlnp | grep ':80 '

3. SSL Labs 评分低

通常是 TLS 1.0/1.1 没禁用,或者加密套件太弱。我上面的配置能拿到 A+。

4. WordPress 后台样式丢失

通常是 HTTPS 混合内容(页面是 https,但 CSS 是 http)。在 wp-config.php 加:

$_SERVER['HTTPS'] = 'on';

define('FORCE_SSL_ADMIN', true);

总结

生产级 HTTPS 配置没那么复杂,关键是:

  1. 用 acme.sh 自动签发 + 续期
  2. nginx 配置强 TLS 协议 + 现代加密套件
  3. HSTS + 安全 headers 防 XSS/clickjacking
  4. HTTP/2 + Brotli + OCSP Stapling 性能优化

下一篇会讲怎么用 nginx 反向代理把 WordPress 跟其他服务(如 Node.js API、Go 微服务)一起托管。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注