修复 Fly.io www 子域名 SSL 错误与 Cloudflare(Error 525)

Fred· AI Engineer & Developer Educator4 min read

将应用部署到 Fly.io 后根域名工作正常,但 www.yoursite.com 抛出 SSL 握手错误?你不是一个人。这个 Error 525 发生是因为 Fly.io 需要为每个主机名单独的 SSL 证书——大多数部署指南完全跳过这一步。

以下是修复方法,已在生产部署中测试和验证。

问题

你已经部署到 Fly.io,添加了自定义域名,一切看起来都很好。然后你尝试访问 www.yoursite.com 并得到:

Error 525: SSL handshake failed

与此同时,yoursite.com(没有 www)工作正常。怎么回事?

为什么会发生这种情况

Fly.io 使用 Let's Encrypt 提供 SSL 证书,但这里有个问题:example.com 添加证书不会自动覆盖 www.example.com

它们被视为完全独立的主机名。你需要明确为 www 子域名添加证书。

解决方案(5 步)

步骤 1:安装 Fly.io CLI

如果你还没有,安装 flyctl:

# 安装 flyctl
curl -L https://fly.io/install.sh | sh

# 添加到 PATH
export FLYCTL_INSTALL="$HOME/.fly"
export PATH="$FLYCTL_INSTALL/bin:$PATH"

# 使其永久生效(添加到 ~/.bashrc 或 ~/.zshrc)
echo 'export FLYCTL_INSTALL="$HOME/.fly"' >> ~/.bashrc
echo 'export PATH="$FLYCTL_INSTALL/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

# 验证是否工作
flyctl version

步骤 2:检查你当前的证书

首先,查看你已有的证书:

flyctl certs list -a YOUR_APP_NAME

你可能会看到类似这样的内容:

Host Name                 Added                Status
example.com              1 month ago          Ready
api.example.com          1 month ago          Ready

注意到缺少什么了吗?www 子域名。

步骤 3:添加 www 证书(这解决了问题)

这是解决问题的关键命令:

flyctl certs add www.example.com -a YOUR_APP_NAME

Fly.io 将自动为你的 www 子域名提供 Let's Encrypt SSL 证书。你会看到类似这样的输出:

You are creating a certificate for www.example.com
We are using Let's Encrypt for this certificate.

Your certificate for www.example.com is being issued.
You can validate your ownership of www.example.com by:

1: Adding an AAAA record to your DNS service which reads:
    AAAA @ 2a09:8280:1::X:XXXX

不用担心 DNS 验证——如果你的根域名已经在工作,www 子域名将自动验证。

步骤 4:验证证书已准备好

等待 1-2 分钟,然后检查证书状态:

flyctl certs show www.example.com -a YOUR_APP_NAME

查找 "Status: Ready"。如果它显示"Awaiting certificates",再等一分钟然后再次检查。

一旦准备好,你的证书列表应该显示:

flyctl certs list -a YOUR_APP_NAME
Host Name                 Added                Status
example.com              1 month ago          Ready
www.example.com          13 seconds ago       Ready

完美。

步骤 5:配置 Cloudflare SSL/TLS 模式

如果你使用 Cloudflare 进行 DNS(你应该这样做),这一步至关重要。

  1. 登录你的 Cloudflare 仪表板
  2. 选择你的域名
  3. 前往 SSL/TLS概述
  4. 将加密模式设置为 "完全"(不是"灵活"或"完全(严格)")

为什么选择"完全"?

  • 灵活:Cloudflare 对访客使用 HTTPS,但对 Fly.io 使用 HTTP(不安全,会导致问题)
  • 完全:Cloudflare 对访客和 Fly.io 都使用 HTTPS(正确)
  • 完全(严格):需要受信任的证书颁发机构,但 Fly.io 管理自己的证书(会导致错误)

配置你的 DNS 记录(Cloudflare)

确保你的 DNS 记录设置正确:

根域名 (example.com):

  • 类型AAAAA
  • 名称@(或留空)
  • 内容:你的 Fly.io IP 地址(来自 flyctl ips list
  • 代理状态已代理(橙色云启用)

www 子域名 (www.example.com):

  • 类型CNAME
  • 名称www
  • 目标example.com(指向根域名)
  • 代理状态已代理(橙色云启用)

橙色云(已代理)很重要——它通过 Cloudflare 的 CDN 路由流量并启用 SSL。

测试一切

验证两个域名都工作:

# 测试根域名
curl -I https://example.com

# 测试 www 子域名
curl -I https://www.example.com

两者都应该返回 HTTP/2 200(或 HTTP/1.1 200)。如果你遇到错误,请参阅下面的故障排除部分。

常见错误和修复

Error 525:SSL 握手失败

症状:www 子域名抛出 Error 525,根域名工作正常

原因

  1. Fly.io 上缺少 www 证书
  2. Cloudflare SSL/TLS 模式设置为"灵活"或"完全(严格)"

修复

# 添加 www 证书
flyctl certs add www.example.com -a YOUR_APP_NAME

# 等待 2 分钟让证书颁发
sleep 120

# 验证是否准备好
flyctl certs show www.example.com -a YOUR_APP_NAME

还要验证 Cloudflare SSL/TLS 模式设置为 "完全"

www 子域名返回连接超时

症状:www 子域名根本不加载,没有错误页面

原因

  1. DNS CNAME 记录缺失或不正确
  2. DNS 未通过 Cloudflare 代理
  3. DNS 传播未完成

修复

  1. 检查 Cloudflare DNS 设置中的 www CNAME 记录
  2. 确保橙色云(已代理)已启用
  3. 等待 5-15 分钟让 DNS 传播
  4. 清除浏览器缓存或在隐身模式下测试

证书显示"Awaiting Certificates"超过 5 分钟

症状flyctl certs show 一直显示"Awaiting certificates"

原因

  1. DNS 记录未正确指向 Fly.io
  2. Cloudflare 代理干扰证书验证

修复

# 验证你的 DNS 记录正确
dig www.example.com

# 检查 DNS 是否解析到 Fly.io
nslookup www.example.com

# 如果卡住,删除并重新添加证书
flyctl certs delete www.example.com -a YOUR_APP_NAME
flyctl certs add www.example.com -a YOUR_APP_NAME

为什么单独的证书很重要

在传统的共享托管中,通配符 SSL 证书(*.example.com)覆盖所有子域名。但 Fly.io 通过 Let's Encrypt 单独提供证书。

这给你更多控制,但需要为每个子域名明确设置:

  • example.com → 需要自己的证书
  • www.example.com → 需要自己的证书
  • api.example.com → 需要自己的证书
  • blog.example.com → 需要自己的证书

你明白了。

Fly.io + Cloudflare 最佳实践

  1. 在上线前为所有计划使用的子域名添加证书
  2. 为 Fly.io 部署使用 Cloudflare 的"完全"SSL/TLS 模式
  3. 启用 Cloudflare 代理(橙色云)以获得 CDN 和 DDoS 保护
  4. 在宣布你的网站之前测试 www 和非 www 版本
  5. 如果你想强制使用一个版本而不是另一个,在你的应用中设置重定向

故障排除的有用命令

# 列出你应用的所有证书
flyctl certs list -a YOUR_APP_NAME

# 查看特定证书的详细信息
flyctl certs show www.example.com -a YOUR_APP_NAME

# 删除证书(如果你需要重新开始)
flyctl certs delete www.example.com -a YOUR_APP_NAME

# 检查你应用的 IP 地址
flyctl ips list -a YOUR_APP_NAME

# 检查 DNS 解析
dig example.com
dig www.example.com

# 使用详细输出测试 SSL 连接
curl -vI https://www.example.com

# 检查应用状态
flyctl status -a YOUR_APP_NAME

# 查看应用日志(用于调试)
flyctl logs -a YOUR_APP_NAME

为什么大多数指南跳过这个

大多数 Fly.io 部署教程专注于让你的应用运行并添加单个自定义域名。他们假设你只会使用 example.comwww.example.com——不是两者都用。

但实际上,用户会输入两个版本。搜索引擎会索引两者。你不希望一半的流量遇到 SSL 错误。

添加 www 证书需要 30 秒,但可以节省数小时的后续调试时间。

替代方案:将 www 重定向到非 www(或反之)

如果你不想维护两个版本,你可以在应用中设置重定向。

选项 1:将 www 重定向到非 www

大多数框架都有中间件来实现这个。例如,在 Express.js 中:

app.use((req, res, next) => {
  if (req.hostname.startsWith('www.')) {
    return res.redirect(301, `https://${req.hostname.slice(4)}${req.url}`)
  }
  next()
})

选项 2:将非 www 重定向到 www

app.use((req, res, next) => {
  if (!req.hostname.startsWith('www.')) {
    return res.redirect(301, `https://www.${req.hostname}${req.url}`)
  }
  next()
})

但即使你重定向,你仍然需要两个证书,否则重定向不会工作(用户会在你的应用可以重定向他们之前遇到 SSL 错误)。

结论

Fly.io www 子域名 SSL 问题是那些即使是有经验的开发者也会遇到的"坑"之一。一旦你知道修复方法就很简单:

  1. 为 www 添加单独的证书:flyctl certs add www.example.com -a YOUR_APP_NAME
  2. 将 Cloudflare SSL/TLS 设置为"完全"模式
  3. 等待 1-2 分钟让证书准备好
  4. 测试两个域名

就这样。没有复杂的配置,没有服务器重启,没有编辑配置文件。只是一个大多数部署指南忘记提到的命令。

现在你的用户可以使用或不使用 www 访问你的网站,两者都能正常工作。


相关指南:

资源:

Fred

Fred

AUTHOR

Full-stack developer with 10+ years building production applications. I've been deploying to Cloudflare's edge network since Workers launched in 2017.

Need a developer who gets it?

POC builds, vibe-coded fixes, and real engineering. Let's talk.

Hire Me →