🪐前言
你的网站终于能打开了,但浏览器地址栏上刺眼的"不安全"三个字让你坐不住了。没有 SSL 证书,不仅访客信任度直线下降,Google 排名也会受到影响——Chrome 从 2017 年就开始对 HTTP 网站标红警告了。
好消息是,你不用花钱买证书。Let's Encrypt 提供的免费 SSL 证书跟收费版功能完全一样。这篇文章带你用两种方式部署:命令行 Certbot 和宝塔面板,顺便搞定通配符证书。再送你一套混合内容(Mixed Content)的四步排查修复法,以及续期失败时的应急处理方案。
一、两种部署方式速查
| 方式 | 适用场景 | 操作方式 | 难度 | 耗时 |
|---|---|---|---|---|
| 🖥️ Certbot 命令行 | 裸 VPS(无面板)、有 SSH 权限 | 全命令行 | 中 | 10 分钟 |
| 📦 宝塔面板 | 已安装宝塔面板的服务器 | 图形界面,点击操作 | 低 | 3 分钟 |
| ☁️ Cloudflare | 域名已接入 Cloudflare | 自动颁发免费边缘证书 | 极低 | 自动(接入即生效) |
⚠️ Let's Encrypt 的证书有效期只有 90 天。不管是 Certbot 还是宝塔,都必须配置自动续期——不然证书一过期,客户就看到浏览器的安全警告了。
二、方式一:Certbot 命令行部署
Certbot 是 EFF(电子前哨基金会)官方推荐的 Let's Encrypt 客户端,也是社区最主流的方案。下面以 Ubuntu 22.04 + Nginx 为例。
🔧 安装 Certbot
// 1. 更新包列表
apt update
// 2. 安装 Certbot 和 Nginx 插件
apt install certbot python3-certbot-nginx -y
// 3. 验证安装
certbot --version
⚠️ 建议用 snap 装最新版,apt 仓库的版本可能落后。snap 安装命令:
snap install --classic certbot ln -s /snap/bin/certbot /usr/bin/certbot
🚀 申请标准域名证书
如果你的域名解析已经生效(A 记录指向服务器 IP 且 80 端口能正常访问),一条命令搞定:
certbot --nginx -d 你的域名.com -d www.你的域名.com
Certbot 会自动:
- 验证域名所有权(通过 HTTP-01 质询,在服务器上临时放一个文件让 Let's Encrypt 验证)
- 生成证书并存入
/etc/letsencrypt/live/你的域名.com/ - 自动修改 Nginx 配置,加上 SSL 的
listen 443 ssl配置块
完成后会提示:
Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/你的域名.com/fullchain.pem
🔄 配置自动续期
Certbot 安装时会自动创建一个 systemd 定时任务。确认一下:
systemctl status certbot.timer
如果显示 active (waiting),说明定时器在跑。默认每天检查两次,证书到期前 30 天内自动续。
手动测试续期流程(加上 --dry-run 不会真续,只验证配置对不对):
certbot renew --dry-run
没有报错就说明自动续期配置正常。
📁 证书文件路径速查
| 文件 | 路径 | 用途 |
|---|---|---|
| 完整证书链 | /etc/letsencrypt/live/域名/fullchain.pem |
Nginx/Traefik 引用这个 |
| 公钥 | /etc/letsencrypt/live/域名/cert.pem |
服务器身份验证 |
| 私钥 | /etc/letsencrypt/live/域名/privkey.pem |
绝不要泄露 |
| 证书链 | /etc/letsencrypt/live/域名/chain.pem |
中间证书 |
⚠️
/etc/letsencrypt/live/下面的文件其实是符号链接,指向/etc/letsencrypt/archive/里的真实文件。不要直接改 archive 里的文件,只读 live 下的。

三、方式二:宝塔面板部署
如果你在用宝塔面板,SSL 证书部署不到一分钟。
🔐 宝塔自带 Let's Encrypt
- 登录宝塔面板 → 点击左侧 "网站"
- 找到你的站点,点击右侧的 "设置"
- 切换到 "SSL" 标签页
- 选择 "Let's Encrypt" 证书类型
- 勾选你要的域名(默认会勾选已绑定的所有域名)
- 勾选 "强制 HTTPS"(自动把 HTTP 请求 301 重定向到 HTTPS)
- 点击 "申请"
宝塔会自动完成域名验证和证书部署。证书会显示在 SSL 页面上,能看到颁发者、到期时间等信息。
🔄 宝塔自动续期
宝塔默认会在证书到期前 30 天自动续期。检查方法是:
宝塔面板 → 左侧 "计划任务" → 检查是否有名为 "Let's Encrypt 续期" 的任务。如果没有,手动添加:
- 任务类型:Shell 脚本
- 任务名称:
Let's Encrypt 续期 - 执行周期:每周一次(选一个凌晨时间点)
- 脚本内容:宝塔会自动生成,你不用改

四、通配符证书配置
标准证书只涵盖你指定的域名(如 你的域名.com 和 www.你的域名.com)。如果你需要 *.你的域名.com 覆盖所有子域名(比如 blog.你的域名.com、shop.你的域名.com、api.你的域名.com),就要申请通配符证书。
通配符证书必须用 DNS-01 验证(而非 HTTP-01),这意味着你得在 DNS 解析里临时加一条 TXT 记录来证明你拥有这个域名。
🔑 Certbot 通配符证书申请
以 Cloudflare DNS 为例:
// 1. 安装 Cloudflare DNS 插件
apt install python3-certbot-dns-cloudflare -y
// 2. 创建 Cloudflare API token 文件
mkdir -p /root/.secrets
nano /root/.secrets/cloudflare.ini
文件内容(在 Cloudflare 后台 → 我的个人资料 → API 令牌 创建一个 DNS Zone 编辑权限的 token):
dns_cloudflare_api_token = "你的API令牌"
// 3. 保护文件权限
chmod 600 /root/.secrets/cloudflare.ini
// 4. 申请通配符证书
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
-d '你的域名.com' \
-d '*.你的域名.com' \
--preferred-challenges dns-01
完成后证书路径跟标准证书一样,在 /etc/letsencrypt/live/你的域名.com/。
🔄 通配符证书续期
Certbot 装了 DNS 插件后,续期命令跟标准证书完全一样:
certbot renew
前提是你的 API token 没过期。
📦 宝塔面板通配符证书
宝塔面板也支持通配符证书,但需要手动 DNS 验证:
- SSL → Let's Encrypt → 勾选 "通配符域名(泛域名)"
- 宝塔会提示你在 DNS 里加一条 TXT 验证记录
- 去域名 DNS 管理后台添加这条 TXT 记录
- 等 DNS 生效后(可以用
dig _acme-challenge.你的域名.com TXT验证),回宝塔点"验证" - 验证通过后证书自动部署
💡 通配符证书是好用,但大多数外贸站不需要。通常一个主域名 +
www就够。泛域名的核心场景是你要创建很多子域名(多语言子站、API 子域名等),不然标准证书完全够用。
五、混合内容(Mixed Content)四步排查修复法
证书部署完、地址栏出现了小锁——你以为搞定了。但一刷页面,小锁没了,或者变成"⚠️ 不安全"。这就是混合内容(Mixed Content)问题:页面用 HTTPS 加载,但里面某个图片、CSS、JS 文件还在用 HTTP 引用。
下面是一套四步排查修复法,从快到慢、从简到繁。
🔍 第一步:浏览器控制台定位
打开你的网站,按 F12 打开开发者工具 → Console(控制台) 标签。你会看到类似这样的报错:
Mixed Content: The page at 'https://你的域名.com/' was loaded over HTTPS,
but requested an insecure image 'http://你的域名.com/wp-content/uploads/logo.png'.
This request has been blocked; the content must be served over HTTPS.
控制台会告诉你是哪个文件、哪一行代码导致的。记下所有报错的文件 URL。
🔧 第二步:常规修复(批量替换数据库)
大多数混合内容问题都是 WordPress 数据库里存了旧的 http:// URL。用 SQL 批量替换:
// 备份数据库
mysqldump -u root -p wordpress > /backup/wp_backup_before_http_fix.sql
// 把所有 http://你的域名.com 替换成 https://你的域名.com
UPDATE wp_posts SET post_content = REPLACE(post_content, 'http://你的域名.com', 'https://你的域名.com');
UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, 'http://你的域名.com', 'https://你的域名.com');
UPDATE wp_options SET option_value = REPLACE(option_value, 'http://你的域名.com', 'https://你的域名.com');
⚠️ 先备份数据库再执行 UPDATE。如果对命令行不熟练,用 Better Search Replace 插件在后台做同样的事——它能预览要替换的内容,还支持 Dry Run。
🛠️ 第三步:固定资源修复
有些混合内容不是数据库里的,而是写死在主题或插件代码里的。这种需要用 WP-CLI 的 search-replace 来统一处理序列化数据:
// 替换所有 WordPress 表里的 http URL(处理序列化数据)
wp search-replace 'http://你的域名.com' 'https://你的域名.com' --all-tables --precise
// 清除缓存
wp cache flush
如果这还不行,那就是主题或插件的 PHP 文件里硬编码了 http:// 的引用了。定位到具体文件——第一步的控制台报错会告诉你大致来自哪个插件——然后找到对应文件,把 http:// 改成 https://。
🔒 第四步:强制安全策略(最后兜底)
如果前三步做完还有个别顽固的资源(比如第三方引用的图片),可以在 Nginx 配置里加安全标头强制浏览器升级:
add_header Content-Security-Policy "upgrade-insecure-requests;";
这行会让浏览器把所有 HTTP 请求自动升级为 HTTPS。注意:这只是兜底方案,不是根治手段。如果第三方资源确实不支持 HTTPS,这个规则会导致那部分资源加载失败——用的时候要测试一下。
四步走完,绝大多数混合内容问题都能解决。如果还有问题,大概率是 CDN 缓存没清干净——去 Cloudflare 面板 → 缓存 → 配置 → "清除所有内容",等几分钟再测。

六、续期失败应急处理
证书到期了但续期失败——这是最让人焦虑的情况。别慌,下面按可能的原因排优先级。
❌ 常见原因一:80 端口不可达
Let's Encrypt 的 HTTP-01 验证要求 80 端口能被 Let's Encrypt 的验证服务器访问。如果你的 Nginx 配置把 80 端口关了、或者防火墙/安全组没开 80:
// 检查 80 端口
ufw status verbose
// 检查 Nginx 是否监听 80
nginx -T | grep "listen 80"
如果之前为了安全把 80 关了,临时打开,续完再关:
ufw allow 80/tcp
certbot renew
ufw delete allow 80/tcp
❌ 常见原因二:DNS 记录变更
如果你新加了一个子域名、或者 DNS 记录有变动,Certbot 可能不知道该怎么验证。
// 查看 Certbot 当前的证书配置
certbot certificates
如果列出的域名和实际解析不一致,单独对这个证书重新申请:
certbot --nginx -d 新的域名.com -d www.新的域名.com
❌ 常见原因三:磁盘空间满了
Let's Encrypt 的证书文件不大,但如果磁盘满了,Certbot 写不了新证书。
// 检查磁盘空间
df -h
// 清理 Certbot 旧证书备份
certbot delete --cert-name 你的域名.com
谨慎执行 certbot delete——这会删掉证书,删完要立刻重新申请。
🆘 应急方案一:手动申请一次新的证书
如果自动续期流程彻底坏了,直接手动申请一次新证书是最快的方式。90 天后再查续期问题:
certbot certonly --nginx -d 你的域名.com -d www.你的域名.com --force-renewal
--force-renewal 强制执行,即便旧证书还没到期。
🆘 应急方案二:切换到 Cloudflare 免费证书
如果你的域名已经在 Cloudflare 上,Cloudflare 会自动给你的域名颁发免费的边缘证书(Edge Certificate),有效期长达 15 年。这可以作为 Let's Encrypt 的紧急替代方案:
Cloudflare 面板 → SSL/TLS → 边缘证书 → 确保证书状态是"有效"。如果没有,Cloudflare 在你添加域名后的几分钟内就会自动颁发。
但注意:Cloudflare 的证书是 CDN 边缘层的,你服务器端还是需要一份证书来保证 Cloudflare 到服务器 这段是加密的(Full strict 模式)。所以 Cloudflare 证书只是兜底,不能替代 Let's Encrypt。
🆘 应急方案三:crontab 手工续期
如果 systemd timer 不工作,直接用 crontab 兜底:
// 编辑 crontab
crontab -e
// 加一行:每月 1 号凌晨 3 点执行续期
0 3 1 * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"
// 验证 crontab 写入成功
crontab -l
--post-hook 让 Certbot 续期成功后自动重载 Nginx,新证书即刻生效。
七、SSL 持续监控
证书部署完不是终点,你得知道它什么时候到期。推荐两个监控方式:
📧 方式一:Certbot 证书到期邮件提醒
在 /etc/letsencrypt/cli.ini 中加入:
email = 你的邮箱@你的域名.com
不过这个功能在某些 Certbot 版本中不太稳定。我更推荐方式二。
📊 方式二:UptimeRobot 免费 SSL 监控
UptimeRobot 免费版支持 SSL 证书监控。添加域名后会提前 30 天、14 天、7 天、1 天各发一次邮件提醒你证书快到期了。完全免费,设一次就不用管了。

如果遇到无法解决的问题:
- Let's Encrypt 官方文档:letsencrypt.org/docs
- Certbot 官方文档:certbot.eff.org/docs
- 宝塔 SSL 教程:www.bt.cn/bbs/forum-36-1.html
- Mixed Content 排查指南:developer.mozilla.org/en-US/docs/Web/Security/Mixed_content
- SSL Labs 在线检测(测试你的 SSL 配置评分):www.ssllabs.com/ssltest



宝塔那段适合我这种懒人,点点点就完事
80端口这个坑真遇到过,续期失败查半天
通配符证书是不是必须用DNS验证?普通验证不行吧
混合内容最烦,明明有小锁一刷新又没了
Certbot用snap装会不会跟apt装的冲突啊
Cloudflare那个只能救急吧,源站没证书我还是不太敢开Full strict
之前WP换https,数据库替换前没备份,差点把站搞崩
看完只想说,证书过期真的能把人吓醒
UptimeRobot提醒这个可以搞,不然90天太容易忘
有点细,先照着dry-run跑一遍看看报不报错