# Vercel 自定义域名 SSL：DNS 记录、CAA 与报错排查

> Vercel 如何给自定义域名自动签 Let's Encrypt 证书：根域名 A 记录和 www CNAME 的区别、CAA 怎么写、通配符和上传证书的限制，以及常见状态和报错的处理。

Source: https://ssl.sh/zh/guides/vercel-custom-domain-ssl/
Last updated: 2026-11-10

Vercel 会给项目里的每个自定义域名免费签发 Let's Encrypt 证书：DNS 指向 Vercel 之后自动申请，到期前 14 到 30 天自动续期，不需要你做任何操作。普通域名用 HTTP-01 验证；通配符域名只能用 DNS-01，所以 Vercel 必须能控制 `_acme-challenge` 这个名字。只有 Enterprise 团队才能上传自己的证书。

步骤和菜单名称以 Vercel 官方文档为准（截至 2026 年 11 月），示例域名为 `example.com`。

## 速查表

| 问题 | Vercel 的做法 |
|---|---|
| 自动证书的 CA | Let's Encrypt |
| 验证方式 | 普通域名 HTTP-01，通配符 DNS-01 |
| 根域名 `example.com` | `A` 记录，值看 **Settings > Domains** |
| `www` 和其他子域名 | `CNAME` 指向项目专属地址，如 `d1d4fc829fe7bc7c.vercel-dns-017.com` |
| CAA 要放行 | `letsencrypt.org` |
| 通配符证书 | 支持，需要用 Vercel 的 NS，或把 `_acme-challenge` 委派给 Vercel |
| 上传自有证书 | 仅 Enterprise |
| 续期 | 自动，到期前 14 到 30 天 |

## 国内访问说明

Vercel 在中国大陆没有服务器和 CDN 节点，官方知识库文章也承认从大陆访问可能很慢甚至打不开，而且 Vercel 不提供境内托管和 ICP 备案支持。拿它做海外站、文档站没问题；如果网站主要面向国内用户，或者业务需要备案，建议用阿里云、腾讯云等国内云托管，证书可以看 [阿里云 SSL 证书](https://ssl.sh/zh/guides/aliyun-ssl-certificate/) 或 [腾讯云 SSL 证书](https://ssl.sh/zh/guides/tencent-cloud-ssl-certificate/)。

## 第一步：把域名加到项目里

打开项目，进入 **Settings > Domains**，点 “Add Existing”；也可以用命令行：

```bash
vercel domains add example.com my-project
```

添加根域名时，Vercel 会提示顺便加上 `www`。建议两个都加，再把其中一个重定向到另一个。Vercel 推荐把 `www` 设为主域名，因为 `www` 可以用 CNAME，路由上比固定 IP 的 A 记录更灵活。

## 第二步：添加 DNS 记录

记录值要从当前项目的控制台复制，不要照抄别的项目或旧教程。Vercel 按项目分配任播 IP，很多项目显示 `76.76.21.21`，新项目可能是 `216.198.79.1` 这类地址。填错旧 IP，域名状态会变成 DNS Change Recommended、DNS Change Required 或 Invalid Configuration。

| 类型 | 主机记录 | 记录值 |
|---|---|---|
| `A` | `@` | 控制台给 `example.com` 显示的 IP |
| `CNAME` | `www` | 控制台给 `www.example.com` 显示的地址 |

在阿里云解析、DNSPod 里添加时，主机记录分别填 `@` 和 `www`。添加前先删掉根域名上其他所有 `A` 和 `AAAA` 记录：Vercel 对外部 DNS 的域名还不支持 IPv6，留着 `AAAA` 只会把一部分访客带到别处。根域名之所以用 A 而不是 CNAME，是因为 RFC 1034 不允许 CNAME 和根域名上必有的 `NS`、`MX` 记录共存。

如果这个域名已经被别的 Vercel 账号占用，控制台会要求你在 `_vercel.example.com` 加一条 `TXT` 记录证明你有权使用。也可以选择把整个域名的 NS 改到 Vercel，不过改之前要先把 `MX`、各种验证用的 `TXT` 记录搬过去，否则邮箱会收不到信。

## 第三步：检查 CAA 记录

没有任何 CAA 记录时，所有 CA 都能签发，不需要处理。如果你设了 CAA，就必须包含 Let's Encrypt：

```dns
example.com.  3600  IN  CAA  0 issue "letsencrypt.org"
example.com.  3600  IN  CAA  0 issuewild "letsencrypt.org"
```

只有在你本来就设了 `issuewild` 的情况下才需要第二行，因为通配符证书优先看 `issuewild`。还有一点容易忽略：CAA 查询会跟着 CNAME 走。`www.example.com` CNAME 到 Vercel 后，生效的是 Vercel 那个目标地址上的 CAA 策略，你改不了。如果某个子域名必须用别家 CA，Vercel 的建议是把 CNAME 换成控制台推荐的 A 记录，再在这个名字上写自己的 CAA。可以用 [CAA 检测工具](https://ssl.sh/zh/tools/caa-checker/) 或下面的命令确认：

```bash
dig CAA example.com +noall +answer
dig CAA www.example.com +noall +answer
```

## 通配符证书和自有证书

`*.example.com` 这类通配符只能走 DNS-01 验证。最简单的做法是把 NS 改到 Vercel；如果 DNS 必须留在阿里云或 DNSPod，可以只委派验证用的名字：在团队 **Domains** 页面选中域名，点 “Enable Vercel DNS”（注册商处的 NS 保持不变），然后在原 DNS 服务商添加：

| 类型 | 主机记录 | 记录值 |
|---|---|---|
| `NS` | `_acme-challenge` | `ns1.vercel-dns.com.` |
| `NS` | `_acme-challenge` | `ns2.vercel-dns.com.` |
| `CNAME` | `*` | `cname.vercel-dns-0.com.` |

两条 NS 记录要长期保留，每次续期都要用。委派之后，其他服务商就不能再用同一个 `_acme-challenge` 名字做验证了，同一域名同时给别的平台签通配符的要注意。

上传自有证书是 Enterprise 功能，可以在控制台、REST API 或命令行上传：

```bash
vercel certs add --crt certificate.pem --key private-key.pem --ca ca.pem
```

上传的证书必须带 SAN 扩展；可以是通配符证书；同一子域名既有精确证书又有通配符时，优先用精确的那张。Vercel 不会续期上传的证书，距离到期不足 5 天时会自动换回它自己签的证书，避免网站挂掉。

## 验证

没上传自有证书时，返回证书的颁发者是 Let's Encrypt 的中间证书。用 [SSL 证书检查](https://ssl.sh/zh/tools/ssl-checker/) 从外部检查，或在终端运行：

```bash
curl ssl.sh/example.com
```

用 OpenSSL 看实际返回的证书：

```bash
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -issuer -subject -ext subjectAltName -dates
```

想确认 HTTP-01 验证路径能到达 Vercel，可以请求一个随便编的 token，返回 `404` 且响应头里有 `server: Vercel` 就是正常的：

```bash
curl -sS -D - -o /dev/null http://example.com/.well-known/acme-challenge/test-token
```

## 自动续期

Vercel 在到期前 14 到 30 天之间尝试续期，具体哪天不固定，所以剩 30 天还没续上不一定是故障。续期失败时，团队 Owner 会收到 **Configuration - Certificate renewal failed** 通知，常见原因是 DNS 不再指向 Vercel、代理挡住了验证路径，或者改了 CAA。

Let's Encrypt 从 2025 年 6 月 4 日起不再发到期提醒邮件；默认证书有效期 2027 年 2 月 10 日缩短到 64 天，2028 年 2 月 16 日再缩短到 45 天。Vercel 能应对更短的有效期，但 DNS 被误改时没人提醒你，建议把域名加到 [ssl.sh 监控](https://ssl.sh/zh/monitor/)（开发中）。

## 常见状态和报错

- **Invalid Configuration**：DNS 记录和控制台不一致，或 CAA 挡住了 Let's Encrypt，或通配符域名没给 Vercel DNS 验证权限。用 `dig A example.com +short`、`dig CNAME www.example.com +short` 对照 Settings > Domains 页面。
- **DNS Change Recommended / DNS Change Required**：用了别的项目或旧教程里的 Vercel IP，换成本项目显示的值。
- **前面有代理时证书一直签不下来**：把 `/.well-known/acme-challenge/*` 不缓存、不鉴权、不改写地转发到 Vercel 的 80 端口，或者把 Cloudflare 记录改成 DNS only。在 Vercel 上 `/.well-known` 路径是保留的，不能重定向或重写。
- **CAA 报错**：见 [CAA 记录阻止签发](https://ssl.sh/zh/errors/caa-record-prevents-issuance/)，Vercel 也建议用 Let's Debug、DNSViz 排查。
- **旧服务商留下的 `_acme-challenge` 记录**：可能把 DNS-01 验证导向别处，用 `dig -t TXT _acme-challenge.example.com` 检查。
- **`ERR_SSL_PROTOCOL_ERROR`**：先用同一浏览器打开部署的 `vercel.app` 地址对比，再换手机流量等其他网络试。只有某个网络打不开，多半是该网络的过滤或 TLS 检查，见 [ERR_SSL_PROTOCOL_ERROR](https://ssl.sh/zh/errors/err-ssl-protocol-error/)。
- **套了 Cloudflare 后 `ERR_TOO_MANY_REDIRECTS`**：常见原因是 Cloudflare 的 SSL 模式设成了 Flexible。
