🖊️ 前言
本文将以域名托管在 Cloudflare 为例,适用于所有需要开启 Https 的网站
如果你正在使用其他的域名服务商,只需照葫芦画瓢进行操作即可👩🏻💻🧑🏻💻。
⚠️ 注意事项
由于 ACME 脚本 和 GTS API 被墙,本文可能不适用于使用大陆境内的服务器申请 GTS 的证书,可能会遇到无法正常下发证书。
如果你仍坚持使用 GTS,那么可以尝试使用这些方法。
1、在境内服务器下载 acme.sh
1、参考官网文档 下载脚本
2、下载完毕后,配置别名
运行 nano ~/.bashrc
3、在文件末尾添加以下内容:
export PATH="$HOME/.acme.sh/:$PATH"
4、刷新
source ~/.bashrc
现在你可以直接使用 acme.sh 命令了
2、尝试使用 DNS-01 验证
由于 acme脚本中 GTS 的 API 域名: dv.acme-v02.api.pki.goog
已被大陆屏蔽,使用国内服务器的用户,可以尝试使用 dns_cf
(CloudFlare)、dns_ali
(阿里云)或 dns_dp
(腾讯云)进行 DNS-01 验证 模式申请。
不过 ACME 客户端仍然需要访问 GTS 的 ACME 端点(https://dv.acme-v02.api.pki.goog/directory
),以完成挑战请求的提交和证书申请。如果 ACME 服务器端点被墙,DNS-01 验证本身也无法完全避免这个问题,因为客户端无法与 GTS 的服务器正常通信。
3、为 ACME 脚本添加代理
如果你坚持使用 GTS 证书并且遇到被墙的问题,请为脚本添加代理
使用代理或 VPN
为 ACME 客户端配置代理,让它能通过 VPN 或 SOCKS5 代理访问 GTS 的服务器。
# 导入代理配置
export HTTPS_PROXY="http://proxy_ip:proxy_port"
export HTTP_PROXY="http://proxy_ip:proxy_port"
# 使用上述配置运行 acme
acme.sh --issue --dns <dns_provider> -d yourdomain.com
4、使用境外服务器申请证书后,将证书发送到境内服务器上(需要在证书过期前手动操作)
5、使用 GitHub Action 代申请证书,前提是你可以正常访问 GitHub。
我找到了两篇关于如何使用 GitHub Action 申请证书的文章,你需要根据实际情况替换详细配置。
6、如果上述操作你都觉得麻烦,请使用境外服务器托管网站;或使用境内服务器可访问的 CA 如 :
- ZeroSSL:
acme.zerossl.com/v2/DV90
- Let's Encrypt:
acme-v02.api.letsencrypt.org
👨🏻💻 准备步骤
在继续阅读前,你需要先了解以下知识
申请证书的保存在哪里?
证书默认存放在 .acme.sh 文件夹,你需要使用 ls -la
命令才能看到该文件夹。
使用 FinalShell 的 SFTP 时,可以直接看到该文件夹。
什么是泛域名SSL证书?
例如 baidu.com,有 zhidao.baidu.com,www.baidu.com,map.baidu.com 等很多 *.baidu.com 域名,这个时候,为每个子域名申请一张证书,显然太繁琐,成本也会增加很多,管理也相对麻烦。如果用一张泛域名SSL证书,则一证搞定全部二级子域名。
关于如何将 ip 与域名绑定请参考这篇文章:

与这篇文章不同的是,我们将帮源站申请自签证书,因此开启的模式为 完全
,即:
全程加密但不完全:如果用户发出的是 HTTP 请求,那么用户到 Cloudflare 和 Cloudflare 到源站均会使用 HTTP 协议;如果用户发出的是 HTTPS 请求,那么用户到 Cloudflare 会使用 Cloudflare 提供的证书进行加密,而 Cloudflare 到源站会使用源站的证书进行加密。
完全(严格)
,可能导致网站无法正常访问。必选项
- 服务器一台(已搭建网站);
- ssh 连接工具,例如:Xshell、FinalShell 、Termius 、Mac 终端 等;
- 域名一个:请确保你可以访问该域名的 DNS 配置;
- 提前安装 Nginx
# 安装 NGINX
sudo apt-get install -y nginx
可选项
- 提前安装 cron,用于生成为证书自动续期的定时任务(希望手动续期时可忽略)
# 安装 cron
sudo apt install cron -y
- 提前安装 socat (用于使用 standalone 模式验证域名)
# 安装 socat
sudo apt install socat -y
- 为 Docker 项目添加反向代理
假如你的项目基于 Docker 搭建的网站(以 RSSHub 为例),此方式不会在 Nginx 目录下生成配置。
不过,我们还是需要利用 Nginx 做反向代理,实现不带端口号直接访问域名。申请证书后再添加一个 302 跳转以实现 Htpps 访问。因此,我们需要手动填写一些配置。
以使用 sites-available
和 sites-enabled
管理网站为例:
# 进入 Nginx 配置文件夹
cd /etc/nginx/sites-available/
# 添加网站跳转配置
vi [Your Domains] # 也可以是你喜欢的编辑器
将[Your Domains]
替换为您的域名。
填入以下内容,并保存文件。
# HTTP配置
server {
listen 80;
#填写绑定证书的域名
server_name [Your Domains];
# 反向代理 1200 端口,实现 80 端口访问 RSSHub
location / {
proxy_pass http://localhost:1200;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
将[Your Domains]
替换为您的域名。
随后,我们需要将这份配置添加到 sites-enabled
以启用该配置。
# 添加软连接,激活该配置
sudo ln -s /etc/nginx/sites-available/[Your Domains] /etc/nginx/sites-enabled/
# 检查 Nginx 配置并重载:
sudo nginx -t
sudo systemctl reload nginx
将[Your Domains]
替换为您的域名。
如果提示找不到文件,请检查你的/etc/nginx/nginx.conf 文件
# 配置文件必须以 .conf 为后戳
include /etc/nginx/conf.d/*.conf;
# 无论文件后缀是什么(即使是 .doc、.txt 或者无后缀)。
include /etc/nginx/sites-enabled/*;
当 Nginx 重载成功后,你现在可以直接使用域名(不带端口号)进行 http 访问了
完全
或更高级别。你可以临时调整为
灵活
,或临时将域名的 DNS 解析状态从Proxied (云图标橙色) 改为 DNS only (灰色),来尝试是否配置成功。一、申请证书-获取EAB 密钥
通过 ACME 脚本申请 GTS 证书时,会要求你提供 b64MacKey
和 keyId
,以下是它的获取方法。
推荐大家直接通过
网页端
操作1、通过 Google Cloud Shell 获取 (网页端操作)
这是最简单,且提供可视化的一种方式。
1.1、前往 Google Cloud 页面,在右上角新建一个名为 Google Trust Services
的项目,并启用 Public Certificate Authority API

1.2、选择你刚刚创建的新项目
,点击右上角的"激活 Cloud Shell",成功授权后在Cloud Shell
输入
# 如需请求 EAB 密钥 ID 和 HMAC,请运行以下命令:
gcloud publicca external-account-keys create

此命令会返回对生产环境有效的 EAB 密钥 和公共 CA 环境中。在响应正文中,keyId
字段包含 EAB 密钥 ID,b64MacKey
字段包含 EAB HMAC。
Created an external account key
[b64MacKey: xxxxxx
keyId: xxxxxx]
您必须在获得 EAB 密钥后的 7 天内使用该密钥。如果 7 天内未使用 EAB Secret 则会失效。使用 EAB 密钥注册的 ACME 账号没有到期时间。
2、通过 gcloud cli 获取(服务器端操作)
与上面最终获取的内容一致,不过是在服务器上操作。(不适合新手操作)
2.1、安装 gcloud cli
请参考 Google Cloud 官方文档在服务器上 安装 gcloud cli

2.2、完成安装并执行 gcloud init
初始化后,执行以下命令
# 创建一个谷歌云项目
gcloud projects create PROJECT_ID
- 将
PROJECT_ID
替换为您正在创建的谷歌云项目的名称。
# 选择您创建的谷歌云项目:
gcloud config set project PROJECT_ID
- 将
PROJECT_ID
替换为您的谷歌云项目名称。
Tips: 确保您拥有所有者(roles/owner
)或公共CA外部帐户密钥创建者(publicca.externalAccountKeyCreator
)IAM角色。
如需授予公共CA外部帐户密钥创建者(publicca.externalAccountKeyCreator
)IAM角色,请运行以下命令:
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=user:USER \
--role=roles/publicca.externalAccountKeyCreator
替换以下内容:PROJECT_ID
:您的谷歌云项目的 IDUSER
:您要对其执行删除操作的用户的唯一标识符分配IAM角色
2.3、启用公共 CA API
gcloud services enable publicca.googleapis.com
2.4、请求 EAB 密钥 ID 和 HMAC
gcloud publicca external-account-keys create
此命令会返回对生产环境有效的 EAB 密钥 和公共 CA 环境中。在响应正文中,keyId
字段包含 EAB 密钥 ID,b64MacKey
字段包含 EAB HMAC。
Created an external account key
[b64MacKey: xxxxxx
keyId: xxxxxx]
您必须在获得 EAB 密钥后的 7 天内使用该密钥。如果 7 天内未使用 EAB Secret 则会失效。使用 EAB 密钥注册的 ACME 账号没有到期时间。
二、安装并配置 acme.sh
1、安装 acme.sh
如果你正在使用如 Oneinstack, LNMP.org, bt.cn, 1Panel 等服务器面板或管理脚本的话,对应程序可能已安装或集成了acme.sh。
# 安装acme脚本,指定邮箱用于接收证书过期通知
# 将[Your Mail]替换为您的邮箱地址。
curl https://get.acme.sh | sh -s email=[Your Mail]
# 重新加载当前用户的环境变量,确保 acme.sh 的命令可立即生效。
source ~/.bashrc
# 设置 ACME 脚本自动更新
acme.sh --upgrade --auto-upgrade
# 设置 Google 作为默认 CA
# 如果你一台服务器上有多个域名的 acme 任务,则可能自动更新失败
# 因此这里推荐使用 --accountconf 指定一个配置文件
acme.sh --set-default-ca --server google --accountconf /root/.acme.sh/account-custom.conf
如果你正在使用 ACME 脚本为多个域名,使用不同的账号/CA颁发证书,请善用--accountconf
命令为每个域名创建自己的配置。
account-custom.conf
可以自定义名称
2、注册 acme 账号
acme.sh --register-account \
--server google -m [Your Mail] \
--eab-kid [Your keyId] \
--eab-hmac-key [Your b64MacKey]
- 将
[Your Mail]
替换为您的邮箱地址。 - 将
[Your keyId]
、[Your b64MacKey]
替换为 步骤1️⃣申请到的keyId
和b64MacKey
。 - 你也可以将
--server google
替换为--server https://dv.acme-v02.api.pki.goog/directory
看到类似下面的输出内容,即代表注册成功
Registering account: https://dv.acme-v02.api.pki.goog/directory
Registered
ACCOUNT_THUMBPRINT='xxxxxxxxxxxxxxxxxxxxxxxx'
三、签发 Google Trust Service 证书
签发证书有两种方式:
- 通过公网 ip 验证域名所有权(Webroot 、 Nginx 以及 Standalone 模式);
- 假如你的服务器没有公网 ip ,那么只能通过 DNS 验证。
使用 Cloudfalre 解析的网站,推荐使用 DNS 模式。
当你使用支持的 DNS 服务商(如 Cloudflare、AliDNS 等)时,acme.sh 可以通过 API 自动创建和删除 _acme-challenge TXT 记录,从而完成验证和自动续期。
哪种验证模式最适合我?
1、Webroot 模式:
- 方式:在指定的 Web 服务器目录中创建验证文件。
- 适用场景:适合已有 Web 服务(如 Nginx/Apache)。
- 限制:需开放 HTTP 80 端口,不能申请泛域名证书。
2、Standalone 模式:
- 方式:临时启用 HTTP/HTTPS 服务。
- 适用场景:无 Web 服务器运行时使用。
- 限制:端口占用会冲突,需要短暂停止已有服务。
3、Nginx 模式:
- 方式:acme.sh 自动配置 Nginx 处理验证请求。
- 适用场景:Nginx 作为主要 Web 服务器。
- 限制:需 Nginx 完整权限。
4、DNS 模式:
- 方式:通过 API 自动添加 DNS TXT 记录。
- 适用场景:适合申请泛域名证书。
- 限制:需要 DNS 服务商 API 访问权限。(如 Cloudflare、AliDNS 等)
Webroot 模式 vs Nginx 模式
Webroot 模式
优点:
- 适合已有 Web 服务器(如 Nginx)运行的环境。
- 配置简单,适用于小型网站。
缺点:
- 必须暴露 HTTP 80 端口。
- 不支持自动管理 Nginx 配置,需要手动指定 Webroot 路径。
Nginx 模式
优点:
- 直接与 Nginx 集成,无需手动管理
.well-known/acme-challenge/
路径。 - 自动重载 Nginx 配置,适合复杂的网站。
缺点:
- 仅适用于使用 Nginx 作为服务器的环境。
- 更依赖 Nginx 的正常运行。
接下来,请选择最适合你的验证模式来申请证书以启用 https。
3.1、通过公网 ip 验证域名所有权
3.1.1、域名验证 : 请在下面三种模式中选择最适合你的
- Nginx 模式:
# 为主域名以及 www 子域名申请证书,按照个人需求即可
acme.sh --issue -d [Your Domains] -d www.[Your Domains] --nginx
# 若果脚本提示找不到 Nginx 的 conf 路径,可自定义路径。
# 具体路径和 .conf 文件名因人而异,这里为默认目录和默认文件名
acme.sh --issue -d [Your Domains] --nginx /etc/nginx/conf.d/nginx.conf
将[Your Domains]
替换为您的域名。
- Webroot 模式:
# 若已搭建网络服务,可使用 HTTP 验证
acme.sh --issue -d [Your Domains] -d www.[Your Domains] --webroot /home/wwwroot/[Your Domains]/
将[Your Domains]
替换为您的域名。
- Standalone 模式:
# 如果 80 端口空闲,ACME 脚本可临时监听在 80 端口完成验证
acme.sh --issue -d [Your Domains] -d www.[Your Domains] --standalone
将[Your Domains]
替换为您的域名。
如遇到问题,请查看 🛠️ 故障排查 章节
3.1.2、安装证书到指定文件夹
我们需要将安装证书到指定文件夹 ,以确保证书后期的自动更新。
acme.sh --install-cert
命令指定目标位置。# reloadcmd 命令意思是:证书更新后重启网络服务
acme.sh --install-cert -d [Your Domains] \
--key-file /path/to/ssl/[Your Domains] \
--fullchain-file /path/to/ssl/[Your Domains].pem \
--ca-file /path/to/ssl/ca.pem
--reloadcmd "service nginx force-reload"
- 将
[Your Domains]
替换为您的域名。 - 确保替换
/path/to/ssl/
为你实际想要存放证书的路径(如/etc/nginx/ssl/
)
如果目录不存在,运行下面命令。创建目录后再次安装证书。
# 创建目录
sudo mkdir -p /etc/nginx/ssl/
# 如问题仍存在,请检查权限问题;
# 授权文件夹
sudo chown -R www-data:www-data /etc/nginx/ssl/
完成以后,证书无需任何操作会在 证书到期前30天
自动更新,若想要停止某域名证书的自动更新使用acme.sh --remove -d [Your Domains]
命令,或者在安装目录中删除对应域名目录即可。
接下来只要修改 Nginx 配置即可。
如遇到问题,请查看 🛠️ 故障排查 章节
3.2、通过 DNS 验证域名所有权
以使用 Cloudflare 的 API 为例,通过 DNS 验证申请通配符证书。
3.2.1、获取并导入 API Token
你可以选择使用 全局 API
还是单域 API
,两者都可以在 Cloudflare API Token 获取。
创建单域 API :



查看全局 API :

我这里选择了单域 API,使用命令导入 API:
# 单域 API (只能控制这个域名)
export CF_Token="xxxxxxxxxxxxxxxxxxxxxxxx"
export CF_Account_ID="xxxxxxxxxxxxxxxxxxxxxxxx"
export CF_Zone_ID="xxxxxxxxxxxxxxxxxxxxxxxx"
# 全局 API (可以控制整个账号)
export CF_Key='xxxxxxxxxxxxxxxxxxxxxxxx'
export CF_Email="你的cloudflare邮箱"
CF_Token
为你获取到的用户 API 令牌
CF_Account_ID
和CF_Zone_ID
可以在你域名概述页面侧边栏的 API 分栏看到。

3.2.2、完成导入后,开始生成证书
# RSA 证书
acme.sh --issue --dns dns_cf -d [Your Domain] -d *.[Your Domain] --keylength 2048 --accountconf /root/.acme.sh/account-custom.conf
# ECC 证书
acme.sh --issue --dns dns_cf -d [Your Domain] -d *.[Your Domain] --ecc --accountconf /root/.acme.sh/account-custom.conf --dnssleep 30
- 将
[Your Domain]
替换为您需要申请证书的域名
。 - 自定义了
account-custom.conf
文件名的注意替换
命令解析
--dns dns_cf
:
使用 Cloudflare 的 DNS API 验证域名所有权。-d [Your Domain] -d *.[Your Domain]
:
申请[Your Domain]
及其所有子域名的泛域名证书。--accountconf /root/.acme.sh/account-custom
:
使用指定的account-custom
文件作为账户配置文件。该文件可以包含你的账户公钥、邮箱地址以及 CA 服务器的信息。--keylength 2048
:
生成 RSA 证书--ecc
:
生成ECC(椭圆曲线证书)--dnssleep 30
:
等待 30 秒,确保 DNS 记录已经传播。
执行上述命令后,将分为两种情况:
1、已配置受支持的 API (例如 Cloudflare)时,脚本会自动操作,无需人为干预。在导入 API Token
步骤操作正确的前提下,运行完毕后会自动发放证书。
你可以继续阅读 3.2.3、修改 Cron 任务
# 查看已生成的证书
acme.sh --list
输出结果中 KeyLength
一列应该包含该域名的 2048
和 ec-256
两种证书
2、假如你的 DNS 服务商不支持通过 API 添加 TXT 记录,那么只能手动添加。
(缺点是无法自动更新证书,每次都需要我们手动修改 TXT 记录并验证)
命令运行完毕后,你将会看到许多红色显示的字样。不用担心,只是需要我们添加一下 TXT 记录。添加后再次验证即可正常发放证书。

我们只需要留意以下片段
Add the following TXT record:
Domain: '_acme-challenge.rsshubtest.yummy.best'
TXT value: '_-xh0X6nm72QtRGIwS7HgoX_no8KqaNZBZ0gMSRd8k4'
以 CloudFlare 界面为例,添加到 DNS 类型为 TXT
,其余按照图片示例填写完毕后,保存即可。

添加 TXT 记录后,再次验证证书
# RSA 证书
acme.sh --server google --renew -d [Your Domain] \
--dns --yes-I-know-dns-manual-mode-enough-go-ahead-please
# ECC 证书
acme.sh --server google --renew -d [Your Domain] \
--ecc --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please
将[Your Domains]
替换为您的域名。
Success
字样即代表验证成功,证书已下发。如果显示失败可能是由于解析尚未生效导致,请稍后再试。

3.2.3、修改 Cron 任务
由于我们使用了--accountconf
参数指定了配置文件,此时你的 Cron 自动任务也要做出对应的修改
运行 crontab -e
进行修改(如果有多个域名则应该相应的会有多个任务)
# 自动续签 RSA 证书任务
30 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" --accountconf "/root/.acme.sh/account-custom.conf" --keylength 2048 > /dev/null
# 自动续签 ECC 证书任务
45 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" --accountconf "/root/.acme.sh/account-custom.conf" --ecc > /dev/null
原始命令不能同时续签 RSA 和 ECC 证书,因为它没有区分证书类型的参数。要同时续签 RSA 和 ECC 证书,你需要分别为每种类型创建定时任务。
3.2.4、安装证书
acme.sh --install-cert
命令指定目标位置。# 安装 RSA 证书
acme.sh --install-cert -d [Your Domain] --keylength 2048
--key-file /path/to/ssl/private.key
--fullchain-file /path/to/ssl/fullchain.pem
--ca-file /path/to/ssl/ca.pem
# 安装 ECC 证书
acme.sh --install-cert -d [Your Domain] --ecc
--key-file /path/to/ssl/ecc_private.key
--fullchain-file /path/to/ssl/ecc_fullchain.pem
确保替换 /path/to/ssl/
为你实际想要存放证书的路径(如 /etc/nginx/ssl/
)
- 将
[Your Domains]
替换为您的域名。 --ca-file
两种证书生成的 CA证书 都一样的,随便选择一份证书安装即可。
如果目录不存在,运行下面命令。创建目录后再次安装证书。
# 创建目录
sudo mkdir -p /etc/nginx/ssl/
# 如问题仍存在,请检查权限问题;
# 授权文件夹
sudo chown -R www-data:www-data /etc/nginx/ssl/
3.2.5、设置 Https 跳转,以及证书位置
我在 准备步骤-可选项 章节,提到过这份文件。
# HTTP配置
server {
listen 80;
#填写绑定证书的域名
server_name [Your Domain];
#(第一种)把http的域名请求转成https
return 301 https://$host$request_uri;
#(第二种)强制将http的URL重写成https
# rewrite ^(.*) https://$server_name$1 permanent;
}
# HTTPS使用SSL访问的配置
server {
listen 443 ssl;
server_name [Your Domain];
# RSA Cert
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/private.key;
# ECC Cert
ssl_certificate /etc/nginx/ssl/ecc_fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/ecc_private.key;
# 验证 ocsp( RAS 和 ECC 生成的内容相同)
ssl_trusted_certificate /etc/nginx/ssl/ca.pem;
# 为 Docker 项目(RSSHub)配置反向代理,不需要就删掉
location / {
proxy_pass http://localhost:1200;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
将[Your Domains]
替换为您的域名。
保存后,检查配置并重载 nginx
# 检查 Nginx 配置
sudo nginx -t
# 重载 nginx
sudo systemctl reload nginx
开启成功,Enjoy! 🎉 🎉🎉
四、查看证书
- 你可以通过命令行查看;
# 检查证书 和 OCSP
openssl s_client -connect [Your Domains]:443 -status
- 或通过浏览器查看

- 还可以在 myssl.com 查询
❓ 常见问题
Google CA SSL 和 Google Trust service 有区别吗
1. Google CA SSL
- 指代:Google CA SSL 通常指的是由 Google 自己签发的 SSL 证书,用于保护用户与服务器之间的数据传输。
- 功能:通过 SSL/TLS 加密协议确保网站通信的安全性,防止数据在传输过程中被窃听或篡改。
- 使用场景:Google 自己的服务(如 Gmail、Google Drive 等)以及部分第三方企业使用 Google 签发的 SSL 证书。
- 展示形式:你在浏览器地址栏看到 HTTPS 和绿色挂锁图标时,这表示网站使用了有效的 SSL 证书。
2. Google Trust Services (GTS)
- 指代:GTS 是 Google 提供的公共 CA(Certificate Authority,证书颁发机构)服务,是 Google 自家信任链的基础。
- 职责:
- GTS 负责签发、管理和吊销 SSL/TLS 证书。
- Google Trust Services 运营多个根证书(Root CA),并被主要浏览器和操作系统信任。
- 证书链:GTS 颁发的证书可以作为根证书或中间证书,为 Google 自身服务和第三方客户提供信任支持。
区别与联系
1.区别:
- Google CA SSL 更侧重指向特定证书(例如某个域名使用的 SSL 证书)。
- GTS 是一个证书颁发机构,为 Google 及第三方提供证书服务,是更大的体系。
2.联系:
- Google CA SSL 证书的签发背后,通常依赖于 GTS 的证书根链。这意味着当你使用 Google 的 SSL 证书时,这些证书是由 GTS 管理和签发的。
我的域名解析由 CloudFlare 负责,为什么显示的证书组织不是 Google Trust Service?
如果你的域名使用了 Cloudflare 作为 CDN 和安全加速服务,外部访问者通常只能看到 Cloudflare 发放的 SSL/TLS 证书,而不是你在源服务器上配置的证书。这是 Cloudflare 的代理机制和HTTPS 中间人架构导致的结果。
为什么访问者只能看到 Cloudflare 的证书?
1、反向代理的工作方式
- 当你启用 Cloudflare 后,所有用户访问你网站的请求会先经过 Cloudflare 的服务器,然后由 Cloudflare 服务器转发到你的源服务器。
- 为了保证传输的安全性,Cloudflare 会与用户之间建立一个独立的 HTTPS 加密连接,因此用户看到的证书是 Cloudflare 自己的。
2、双向 SSL 连接架构
Cloudflare 实现 HTTPS 是通过两个加密通道完成的:这种方式确保用户无法直接看到源服务器的证书。
- 用户 ↔️ Cloudflare:这段连接使用 Cloudflare 提供的 SSL 证书(由 Cloudflare 签发)。
- Cloudflare ↔️ 源服务器:这段连接可以使用你在源服务器上配置的 SSL 证书(自签、Let’s Encrypt、Google Trust Services 等)。
3、源站证书和 Cloudflare 证书的区别
- Cloudflare 证书:用户访问时看到的证书,通常签发自 Cloudflare,根证书可能来自 DigiCert 或其他 CA(如 "Cloudflare Inc ECC")。
- 源站证书:用于 Cloudflare 与源服务器之间的加密连接。
- 你可以使用常规的公共 CA(如 Let’s Encrypt 或 Google Trust Services)证书。
- 也可以使用 Cloudflare 提供的自签 SSL 证书(称为 Origin CA),这类证书专门用于 Cloudflare 与源站的安全连接。
4、如何控制 HTTPS 证书的显示?
1、Full 或 Full (strict) 模式:
- 如果你在 Cloudflare 上启用了 Full (strict) 模式,Cloudflare 会验证源站证书的合法性,这样即使用户看不到你的源站证书,你仍可使用有效的 CA 证书确保安全。
2、绕过 Cloudflare 查看源站证书:
- 你可以通过直接访问源服务器的 IP 地址,或将域名的 DNS 解析状态从 Proxied (云图标橙色) 改为 DNS only (灰色),让用户直接连接你的源服务器,这样他们会看到你配置的源站证书。
3、自定义 SSL 证书(Enterprise 计划):
- Cloudflare 的高阶计划(如 Enterprise)允许你上传自己的 SSL 证书,这样访问者可以看到你自定义的证书而不是 Cloudflare 默认的。
我正在使用 Adguard 拦截广告,为什么访问网页时显示的证书组织不是 Google Trust Service?
与上面的 CloudFlare 的情况类似;
当你开启 AdGuard 等网络过滤工具后,浏览网页时看到的证书被替换为 AdGuard 的证书,这是因为 AdGuard 实现了HTTPS 流量拦截和过滤。
1、HTTPS 流量的原理
- 正常情况下,浏览器访问 HTTPS 网站时,会通过 SSL/TLS 加密协议直接与网站服务器建立加密连接,浏览器会验证服务器提供的证书,确保通信安全且未被篡改。
2、AdGuard 如何拦截 HTTPS
- AdGuard 为了过滤广告、追踪脚本等内容,需要检查和修改数据包。然而,HTTPS 数据是加密的,AdGuard无法直接查看内容。因此,它会通过中间人(MITM)技术对加密流量进行处理。
3、证书替换的具体过程
- AdGuard在本地充当代理:
- 当你开启 AdGuard 后,浏览器发出的 HTTPS 请求会先经过 AdGuard,而不是直接到达网站服务器。
- AdGuard与目标网站建立安全连接:
- AdGuard 代表你与目标网站(比如 https://example.com)建立一条加密连接。
- AdGuard伪装成目标网站与浏览器通信:
- 为了继续保证浏览器的连接不会中断,AdGuard 会生成一个伪造的证书来替换网站的真实证书,这个证书在本地被AdGuard的根证书所签署。
- 浏览器信任 AdGuard 的证书:
- 为了让浏览器不会显示安全警告,AdGuard 在安装时会请求将它的根证书导入系统或浏览器的证书库。这使得 AdGuard 能成功伪装成任意 HTTPS 网站。
4、如何验证证书替换情况
- 访问一个 HTTPS 网站后,点击浏览器地址栏的锁标志,然后查看证书信息。如果显示的证书是“AdGuard Personal CA”或类似名称的证书,那就是 AdGuard 在进行中间人代理。
5、潜在风险与解决方法
- 风险:虽然 AdGuard 的中间人代理是为了拦截广告,但这种操作本质上带有一定风险。如果 AdGuard 或类似工具出现漏洞或被恶意利用,可能导致敏感信息泄露。
- 解决方案:如果你担心这种方式的风险,可以:
- 关闭 AdGuard 的 HTTPS 过滤功能。
- 或者,在设置中为一些敏感站点(如银行、支付网站)设置例外,不过滤它们的 HTTPS 流量。
🛠️ 故障排查
一、Webroot 模式下错误排查
1、证书到期未能正常自动更新:
运行以下命令,强制更新域名证书
acme.sh --renew -d [Your Domains] --force
如果更新失败并返回 Invalid status, ···/well-known/acme-challenge/··· was rejected. Our fetch received an HTTP status code of 404.
可以检查一下 Nginx 是否将所有 80 端口访问全部重定向至 443。
如果全部重定向至 443,需要保留 /.well-known/acme-challenge/
这个路径的 80 端口访问。
2、如果提示 HTTP 403 Forbidden 错误,则表示 Nginx 拒绝了这个请求。
常见原因可能是:
1、Nginx 配置问题:没有正确配置 .well-known/acme-challenge/
路径。
- 在 Nginx 配置中加入以下内容
# 配置 Webroot 用于 ACME Challenge
location /.well-known/acme-challenge/ {
root /var/www/html; # 确保目录存在
allow all;
}
- 若仍失败,可尝试提升优先级
# 优先匹配 /.well-known/acme-challenge/
location ^~ /.well-known/acme-challenge/ {
root /var/www/html;
allow all;
# 尝试匹配文件或返回 404
try_files $uri =404;
}
2、文件权限问题:Nginx 无法读取 Webroot 目录中的验证文件。
确保 Webroot 目录 /var/www/html/.well-known/acme-challenge/
存在,并且 Nginx 有权限读取该目录。
sudo mkdir -p /var/www/html/.well-known/acme-challenge/
sudo chown -R www-data:www-data /var/www/html/
3、防火墙或安全规则:阻止了 HTTP 请求。
如果你使用了 防火墙(ufw、iptables) 或 云服务的安全组(如 AWS、GCP),请确保 80 端口是开放的:
sudo ufw allow 80
sudo ufw allow 443
sudo ufw reload
4. 确保 Let's Encrypt 能访问验证路径
创建测试文件:
echo "test" | sudo tee /var/www/html/.well-known/acme-challenge/test
使用浏览器访问
http://[Your Domains]/.well-known/acme-challenge/test
或使用 curl
:
curl -I http://rsshub1.yummy.best/.well-known/acme-challenge/test
- 如果返回 HTTP 200,说明路径访问正常。
- 如果仍然返回 403,请检查 Nginx 日志文件。
# 查看 Nginx 错误日志
sudo tail -f /var/log/nginx/error.log
📖 参考文章
文章不分先后