Administrator
发布于 2026-10-05 / 2 阅读
0
0

Nginx反代安装成功经验的总结

完整项目流程:宿主机Nginx + acme.sh(Cloudflare DNS) + Halo博客反向代理搭建全记录

目标:搭建 https://blog.myfamily2027.top ,子域名 stockapi.myfamily2027.top,后端Halo运行在8090端口,库管API预留8888端口,宿主机Nginx做HTTPS反向代理,acme.sh申请Let’s Encrypt证书

一、前期准备

  1. 域名:myfamily2027.top,域名托管在Cloudflare,已申请Cloudflare DNS API令牌(仅DNS编辑权限)
  2. 服务器:Racknerd VPS,宿主机安装Nginx(不是Docker Nginx)
  3. 后端服务:Halo博客部署在VPS本机,监听127.0.0.1:8090;库管API预留127.0.0.1:8888
  4. 计划:使用acme.sh DNS验证方式申请SSL证书,Nginx反向代理,关闭裸端口8090对外暴露

二、证书申请阶段

执行acme.sh签发多域名证书命令,成功:

~/.acme.sh/acme.sh --issue --dns dns_cf -d blog.myfamily2027.top -d stockapi.myfamily2027.top

证书默认路径:~/.acme.sh/blog.myfamily2027.top/

证书安装(关键步骤)

  1. 创建证书存放目录
mkdir -p /etc/ssl/myfamily2027
  1. acme.sh执行install-cert,复制证书到固定目录,并配置证书续期后重载Nginx
~/.acme.sh/acme.sh --install-cert -d blog.myfamily2027.top \
--key-file       /etc/ssl/myfamily2027/private.key  \
--fullchain-file /etc/ssl/myfamily2027/fullchain.cer \
--reloadcmd     "systemctl reload nginx"

作用:acme.sh自动检测证书到期,自动续证并执行reload加载新证书

三、Nginx站点配置文件创建

宿主机Nginx,配置文件存放路径:/etc/nginx/conf.d/blog.conf

宿主机Nginx两种方案:
方案1:/etc/nginx/sites-available/ + sites-enabled软链接
方案2(本次选用):直接放在/etc/nginx/conf.d/,nginx主配置自带include /etc/nginx/conf.d/*.conf;,自动加载所有conf

blog.conf完整配置:

server {
    listen 80;
    server_name blog.myfamily2027.top;
    # http强制跳转https
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name blog.myfamily2027.top;

    ssl_certificate      /etc/ssl/myfamily2027/fullchain.cer;
    ssl_certificate_key  /etc/ssl/myfamily2027/private.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

    location / {
        proxy_pass http://127.0.0.1:8090; # Halo博客
        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;
    }
}

# stockapi子域名,库管API
server {
    listen 80;
    server_name stockapi.myfamily2027.top;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name stockapi.myfamily2027.top;
    ssl_certificate      /etc/ssl/myfamily2027/fullchain.cer;
    ssl_certificate_key  /etc/ssl/myfamily2027/private.key;

    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://127.0.0.1:8888; #库管API端口
        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;
    }
}

检查配置语法:

nginx -t

输出test is successful代表语法无错误。

四、遇到核心故障:浏览器访问 blog.myfamily2027.top 返回 ERR_CONNECTION_REFUSED

现象:

  1. ping域名可以正常解析到VPS公网IP;Cloudflare代理关闭(灰色云)
  2. Nginx只监听80端口,443端口没有监听
  3. nginx -T查看配置,443 ssl的server块配置语法正常,nginx -t检测通过
  4. 查看nginx error.log,只有notice日志,无error报错

故障根因

acme.sh生成的private.key私钥文件属主是root,Nginx运行用户www-data没有读取私钥权限
重点坑:nginx -t仅校验语法,不会真实读取证书文件;systemctl reload nginx遇到证书读取失败时,不会直接崩溃,会静默丢弃443监听,仅保留80端口。

修复证书权限命令

chmod 755 /etc/ssl/myfamily2027
chmod 644 /etc/ssl/myfamily2027/fullchain.cer
chown www-data:www-data /etc/ssl/myfamily2027/private.key
chmod 600 /etc/ssl/myfamily2027/private.key

安全规范:私钥600权限,仅属主可读;证书链fullchain.cer允许全局可读

完整重启Nginx(不能只用reload)

systemctl stop nginx
systemctl start nginx

查看nginx启动日志确认无报错:

journalctl -u nginx --since "1 minute ago"

检查端口监听:

ss -tlnp | grep nginx

✅修复成功:输出同时包含0.0.0.0:80 和 0.0.0.0:443监听。

五、后续待验证步骤(当前Nginx侧全部就绪)

  1. Racknerd服务商后台防火墙放行TCP 443入站(独立于系统ufw,Racknerd默认拦截,是外部访问443拒绝连接最常见原因)
  2. VPS本机测试Halo后端连通性
curl -v http://127.0.0.1:8090
  1. 本地电脑测试VPS的443端口连通性:telnet VPS公网IP 443
  2. 浏览器访问 https://blog.myfamily2027.top
    • 成功进入网站:部署完成
    • 出现502 Bad Gateway:Nginx HTTPS正常,无法连接后端Halo服务,排查Halo
  3. Cloudflare设置:SSL/TLS → 模式改为Full,关闭Flexible
  4. 证书自动续期:acme.sh自带crontab定时任务,每日自动检测证书到期,自动续证并重载Nginx
# 查看定时任务
crontab -l
# 手动测试续期
~/.acme.sh/acme.sh --cron
  1. 安全收尾:Racknerd安全组关闭8090端口对外暴露,外部访问全部走443反向代理

六、踩坑总结清单

  1. ❌坑:nginx -t语法正常 ≠ 证书可以正常加载;reload遇到证书权限问题会静默丢弃443监听
  2. ❌坑:Racknerd防火墙分两层:系统ufw + 服务商后台防火墙,二者互相独立,80放行不代表443放行
  3. ❌坑:私钥权限root:root,www-data无法读取,不会直接在error.log抛错,隐蔽性极强
  4. ❌坑:listen 443 ssl; 必须带ssl关键字,漏写会导致443工作异常
  5. ✅好习惯:修改证书相关配置后,使用stop+start完整重启nginx,不要只用reload

需要我把这份文档导出为纯文本,方便你直接保存成txt下载吗?


评论