Nginx 反向代理与 SSL 证书配置完全指南:从纯 Nginx 到宝塔面板配置的ssl证书一次讲清
本文最后更新于 8 天前,如有失效请评论区留言。

有些问题,真的不是证书没有装上,而是“它到底被谁在用”没有弄清楚。 前几天我在整理几个子域名的时候,就碰到了一件很容易让人迷糊的事:明明宝塔里已经装好了 SSL 证书,面板上看起来也一切正常,可浏览器依然提示“您的连接不是私密连接”。后来顺着 Nginx 配置和证书路径一点点看,才发现问题并不在“有没有证书”,而是在“当前 Nginx 实际引用的是哪一份证书文件”。 

这篇文章,我想把整个过程梳理一遍。 如果你也正好在折腾: 

– 域名解析 

– 免费 SSL 证书 

– Nginx 反向代理 

– 宝塔面板 SSL 配置 

– 阿里云前置证书和源站证书的区别 

那希望这篇文章能帮你少走一点弯路。

先理解一个核心问题:浏览器看到的证书,不一定是源站证书

这是最容易踩坑的地方,也是很会绕很久的地方。 如果你的访问链路是这样的: `用户浏览器 -> 阿里云 CDN / WAF / 负载均衡 -> Nginx 源站` 那么浏览器优先校验的,是**阿里云前面这一层返回的证书**,而不是源站 Nginx 里的那张证书。 也就是说: 

– 阿里云前置层证书过期了,浏览器会报错。 

– 即使源站宝塔里的证书是新的,浏览器也可能依然提示“不安全”。 

– 如果你直接访问的是源站,才会真正用到源站 Nginx 配置的那份证书。 

所以后面排障时,一定要先问自己一句: 

当前这个域名,到底是直连 Nginx,还是前面还有阿里云那一层在处理 HTTPS? 这一步想明白了,很多问题就不会越修越乱。

域名解析是什么,A 记录又是什么

在开始配置网站前,域名解析一定要先做好。

A 记录是什么

A 记录就是把一个域名指向服务器的 IPv4 地址。 比如: 

– `www.example.cn -> 111.15.17.29` 

– `ai.example.cn -> 111.15.17.29` 

当浏览器访问相应的域名时,会先通过 DNS 查到这个 IP,然后再去连接这台服务器。 也就是说,A 记录负责“让人找到服务器”。

TXT 记录是什么

TXT 记录不是拿来访问网站的,它更像是一张“说明纸条”。 常见用途有: 

– 证书签发时做 DNS 验证 

– 域名归属验证 

– 邮件系统 SPF / DKIM / DMARC 配置 

– 某些平台的接入验证 

比如: 

– `_acme-challenge.xxx` 

– `_dnsauth.xxx` 

这类 TXT 记录通常都是为了验证域名控制权,不负责网站访问。 

你可以这样记:

– A 记录:告诉大家“网站在哪台服务器(IP)” 

– TXT 记录:告诉平台“这个域名确实是我的”

纯 Nginx 环境:不安装宝塔,如何配置 SSL 证书和反向代理

如果你没有安装宝塔,其实也完全可以把 HTTPS 和反向代理配好。 而且这种方式更清晰,更适合喜欢自己掌控配置的人。

安装 Nginx

以 Debian / Ubuntu 为例:

sudo apt update
sudo apt install -y nginx

安装完成后,可以先检查一下:

nginx -v
systemctl status nginx

准备域名解析

在域名解析后台添加 A 记录,例如:

主机记录:git(主域名前的次级域名,如git.example.cn)

记录类型:A

记录值:你的服务器公网 IP

 

如果你要配置多个站点,就分别添加:

git -> 你的公网 IP

www -> 你的公网 IP

ai -> 你的公网 IP

 

注意两点: 1. 域名必须已经解析到当前服务器; 2. 80 和 443 端口需要放行

通过终端配置Let's Encrypt 免费 SSL 证书

更建议直接在服务器上使用 `acme.sh` 或 `certbot` 申请 Let’s Encrypt 免费证书。下面以 `acme.sh` 为例。

curl https://get.acme.sh | sh -s email=my@example.com
source ~/.bashrc

设置默认证书机构为 Let’s Encrypt:

~/.acme.sh/acme.sh --set-default-ca --server letsencrypt

使用 webroot 方式签发证书

假设你的网站目录是:

/www/wwwroot/www.example.cn

执行:

~/.acme.sh/acme.sh --issue -d www.example.cn --webroot /www/wwwroot/www.example.cn

把证书安装到指定目录

把证书统一放在:

/etc/nginx/ssl/域名/
# 先创建目录:
mkdir -p /etc/nginx/ssl/www.example.cn
# 然后安装到该目录
~/.acme.sh/acme.sh --install-cert -d git.ganglitm.cn \
--key-file       /etc/nginx/ssl/git.ganglitm.cn/privkey.pem \
--fullchain-file /etc/nginx/ssl/git.ganglitm.cn/fullchain.pem \
--reloadcmd      "systemctl reload nginx"

这样做的好处是: 路径统一 、续期后自动覆盖、Nginx 不需要反复改路径

从阿里云申请的免费证书

阿里云服务器每年给了一定额度的免费证书,证书有效期3个月。

直接在阿里云的数字证书管理服务控制台申请免费的证书(个人测试证书),选择创建证书,填入:

域名: 如 www.example.cn

选择快捷签发,填写信息即可。等到审核完成,下载ssl证书,对于nginx服务,选择nginx对应的证书,里面包括后缀为key和pem的文件,接下来进行证书的安装。

在服务器终端输入:

nginx -t

里面包含了nginx的默认目录,即nginx.conf的目录,一般的路径为/etc/nginx/nginx.conf,那么/etc/nginx/就是需要安装证书的位置,在这个目录下创建cert文件夹并上传证书文件:

cd /etc/nginx/
# 创建cert文件夹
mkdir -p cert

将证书(key和pem)上传到cert目录下。在nginx.conf文件里面写入:

cd /etc/nginx/
vim nginx.conf
# 填入以下内容
server {
    listen 80;
    server_name www.example.cn;  # 修改为自己的域名
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name www.example.cn;  # 修改为自己的域名

    ssl_certificate     /etc/nginx/cert/www.example.cn/xxx.key; # 修改为自己的文件名
    ssl_certificate_key /etc/nginx/cert/www.example.cn/xxx.pem;# 修改为自己的文件名

    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;

        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_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

保存后检查配置:

nginx -t

没有报错就重载:

systemctl reload nginx

宝塔面板环境:配置 SSL 证书和反向代理时,要特别注意证书路径

如果安装的是宝塔面板,那么很多事情会更省心一点。宝塔可以直接给网站设置ssl证书。但也正因为它帮我们做了很多自动化,所以路径问题特别容易被忽略。

宝塔的 SSL 证书为什么会“看起来装了,实际上没生效”

这类问题最常见的原因有两个:

– 站点配置文件仍然引用旧证书路径

– 宝塔重新申请了新证书,但 Nginx 实际用的不是宝塔维护的那份文件

比如一种容易踩坑的写法:

ssl_certificate /www/server/nginx/conf/cert/www.example.cn;
ssl_certificate_key /www/server/nginx/conf/cert/www.example.cn;

这种写法不一定绝对错误,但它很容易出现下面的情况:

– 文件还是旧的

– 不是宝塔续期时维护的文件

– 路径和面板里的当前证书不一致

如果之前是在服务器里面申请的ssl证书,那么在nginx里面的证书文件路径配置需要惊醒修改。

宝塔自动申请证书时,更推荐使用面板实际维护的路径

如果证书是宝塔自动签发、自动部署的,那么更稳妥的方式,是引用宝塔当前站点实际使用的证书目录。 例如类似这样的路径(实际上这些都可以,随便选择一种即可):

/www/server/panel/vhost/letsencrypt/www.example.cn/fullchain.pem;
/www/server/panel/vhost/letsencrypt/www.example.cn/privkey.pem;

/www/server/panel/vhost/cert/www.example.cn/fullchain.pem;
/www/server/panel/vhost/cert/www.example.cn/privkey.pem;

/www/server/panel/vhost/ssl/www.example.cn/fullchain.pem;
/www/server/panel/vhost/ssl/www.example.cn/privkey.pem;

这个时候需要在nginx.conf文件里面修改相应的部分为:


server 
    {
        listen 80;
        server_name www.example.cn;
    
        # 将 HTTP 请求重定向到 HTTPS
        location / {
            return 301 https://$server_name$request_uri;
        }
    }
server 
    {
        listen 443 ssl;
        http2 on;
        server_name www.example.cn;
    
        ssl_certificate /www/server/panel/vhost/letsencrypt/www.example.cn/fullchain.pem; # 修改为自己的域名,路径可任意选择一个(见上面部分)
        ssl_certificate_key /www/server/panel/vhost/letsencrypt/www.example.cn/privkey.pem; # 修改为自己的域名,路径可任意选择一个(见上面部分)
    
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384';
        ssl_prefer_server_ciphers on;
        
        location ^~ /.well-known/acme-challenge/ {
        root /www/wwwroot/www.example.cn;    # 换成你这个站点的真实目录
        try_files $uri =404;
        default_type text/plain;
        }
        
        location / {
        proxy_pass http://127.0.0.1:13000/;
        proxy_ssl_server_name on;
        proxy_ssl_name 127.0.0.1;

        # WebSocket(必需)
        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;
        client_max_body_size 200m;
        # proxy_set_header X-Forwarded-Prefix  /jellyfin;
    
        # 播放长连
        proxy_read_timeout 3600;
        proxy_send_timeout 3600;
        proxy_buffering off;
        proxy_request_buffering off;
    
        # 不让上游改写 Location
        proxy_redirect off;
        }
        
    }
# 保存后检查配置:
nginx -t
# 重载
systemctl reload nginx

宝塔环境下正确的检查思路

打开站点配置,检查:

ssl_certificate

ssl_certificate_key

是不是都指向当前有效证书。并检查对应目录是否存在证书文件。

 

改完后重新加载 Nginx

如果改了路径却没重载,浏览器看到的还是旧内容。

怎么判断当前网站到底返回的是哪张证书

打开域名网站后,查看证书详情(可在浏览器里面网站的前端有个锁(不安全时会有红线)的图标,点击即可查看连接安全部分),重点看:

– 证书主题(Subject / CN)

– 颁发者(Issuer)

– 到期时间(Not After)

– SHA-256 指纹

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇