域名、DNS、HTTPS 证书 30 分钟搞懂:从买域名到 https 访问你的服务器
适用场景:你有一台公网服务器(云服务器 / VPS / 有公网 IP 的家用 NAS),想把访问方式从 http://1.2.3.4:3000 变成 https://example.com
前置:零网络基础也能看;只需要一台能 SSH 登上去的服务器 + 30 分钟
核心目标:买域名 → DNS 托管切到 Cloudflare → 加解析记录 → 申请免费 HTTPS 证书 → 确认自动续期,全程命令可复制
—
0. 概念速查表(先读一遍,后面随时回来查)
| 概念 | 类比 | 一句话解释 |
| 域名 | 人名 | 好记的名字,如 example.com |
| IP 地址 | 门牌号 | 机器认的"地址",如 198.51.100.7 |
| DNS | 电话本 / 114 查号台 | 查名字 → 得到门牌号 |
| NS 记录 | 电话本的"编辑人" | 声明这个域名的记录由谁维护 |
| A / AAAA 记录 | 条目里的门牌号 | 域名 → IP 的对应关系(IPv4 / IPv6) |
| CNAME 记录 | 别名 | “此条指向另一个名字” |
| MX 记录 | 收邮件的收发室 | 这个域名的邮件由哪台服务器收 |
| TXT 记录 | 备注栏 | 放验证字符串 / 邮件防伪造(SPF) |
| HTTP | 写明信片 | 路上任何人都能看到、能改 |
| HTTPS | 信封 + 火漆 | 加密 + 防冒充 + 防篡改 |
| 证书 | 官方发的身份证 | 证明"这个网站真的属于这个域名" |
| CA | 公安局 / 公证处 | 签发并担保证书的权威机构 |
| Let’s Encrypt | 免费的身份证发放处 | 免费、自动、90 天一张 |
| 反向代理 (nginx) | 大楼前台 | 前台收信、核身份证,再转给里面的员工 |
—
1. 域名是什么?域名和 IP 是什么关系?
1.1 IP 是门牌号
互联网就像一个巨大的城市,每台联网设备的"门牌号"就是 IP 地址:
- IPv4:
198.51.100.7(四段数字,全球已快用完)
- IPv6:
2001:db8:0:1234:5678:9abc:def0:1(超长,基本用不完)
浏览器里直接敲 http://198.51.100.7:3000 也能访问你的服务器——IP 是"真正干活的东西"。
1.2 域名 = 电话本里的人名
但没人记得住 198.51.100.7:3000,于是互联网搞了套 “名字 + 电话本” 系统:
域名 = 人名(example.com,好记)
IP = 门牌号(198.51.100.7,机器认)
DNS = 电话本(输入名字 → 查出门牌号)
你访问 example.com,实际发生的事是:先查电话本,查出 198.51.100.7,再按门牌号上门。
1.3 域名的结构:顶级域 / 二级域 / 子域
以 api.example.com 为例,从右往左拆:
api . example . com
子域 二级域 顶级域
| 部分 | 术语 | 说明 |
com | 顶级域 (TLD) | 后缀分类:com(公司)、org(组织)、net、io、dev、cn(国家域)等 |
example | 二级域 (SLD) | 你真正买下来的那一段 |
example.com | 主域 / 注册域 | 顶级域 + 二级域,是注册单位 |
api / www | 子域(三级及以上) | 你自己随便加,免费,想加多少加多少 |
常见子域约定:
| 名字 | 用途 |
www.example.com | 网站入口(历史习惯,不是必须,现在很多人直接用 example.com) |
api.example.com | API 接口 |
mail.example.com | 邮箱服务 |
blog.example.com | 博客 |
@(DNS 面板里) | 表示主域本身,即 example.com,不带前缀 |
*.example.com | 泛解析,所有子域都指向同一个目标 |
1.4 为什么不能直接用 IP?
| 问题 | 说明 |
| 记不住 | 谁会背 198.51.100.7:3000? |
| IP 会变 | 换云服务器、续费迁移,IP 就变了;域名不用变,改一条 A 记录 1 分钟搞定 |
| 没有身份 | IP 不能证明"你是谁",HTTPS 证书要挂在域名上 |
| 一 IP 多服务 | 一台服务器可以挂多个域名(www、api、blog 全在一台机器上),靠域名区分 |
| 品牌 | 域名是你的牌子,IP 是租来的门牌 |
—
2. DNS 是什么?一个域名怎么变成 IP?
2.1 电话本不是一本,而是"三级"的
世界上不可能存在一本装下所有域名的电话本,所以 DNS 是分层的:
| 层级 | 角色 | 类比 | 知道什么 |
| 根服务器 | 全球 13 组(. 根) | 总目录 | 只知道".com 归谁管" |
| 顶级域服务器 | .com / .org / .cn… | 区局 | 知道"每个主域的 NS(编辑人)是谁" |
| 权威服务器 | 你域名的 NS(Cloudflare / 注册商) | 你的物业 | 存着真正的记录(A / CNAME / MX / TXT…) |
你改解析记录,改的就是"权威服务器"上的数据;改完要不要立刻生效,取决于各级的缓存。
2.2 完整解析过程(一张图讲清)
你在浏览器输入 https://example.com 回车
│
▼
① 浏览器查自己的缓存(刚解析过?直接用)
│ 没有
▼
② 操作系统查 /etc/hosts(本地绑定的,如 127.0.0.1 本地测试域)
│ 没有
▼
③ 操作系统问"本地 DNS 解析器"(一般是你的路由器 / systemd-resolved,如 192.168.1.1)
│ 缓存里没有,它替你开始递归查询:
▼
④ 问根服务器(.):"example.com 的 .com 归谁管?"
根答:去找 a.gtld-servers.net(.com 顶级域服务器)
▼
⑤ 问 .com 顶级域服务器:"example.com 的 NS 是谁?"
顶级域答:去找 aria.ns.cloudflare.com(NS 记录指到 Cloudflare)
▼
⑥ 问 aria.ns.cloudflare.com:"example.com 的 A 记录是多少?"
权威服务器答:198.51.100.7
│
▼
⑦ 答案层层返回,每一级都按 TTL 缓存一份
│
▼
⑧ 浏览器拿到 198.51.100.7
→ 建 TCP 连接 → TLS 握手(HTTPS 在这里验证证书、协商加密)→ 发 HTTP 请求 → 返回页面
两个关键认知:
- 浏览器不亲自跑一趟根服务器。替它跑腿的是"本地 DNS 解析器"(你光猫/路由器里配的那个,如
192.168.1.1 或 223.5.5.5)。你看到的永远是"一问一答",递归过程是解析器在背后干的。
- TTL(Time To Live,生存时间)= 答案的"保鲜期"。TTL 设 300 秒,各级最多缓存 5 分钟就作废重查;设 1 小时,最多缓存 1 小时。改完记录要等多久,基本就看 TTL。
—
3. 六大主流 DNS 记录类型(看懂这张表,什么面板都能配)
| 记录 | 干什么 | 类比 | 例子 |
| A | 域名 → IPv4 地址 | 条目里写门牌号 | example.com A 198.51.100.7 |
| AAAA | 域名 → IPv6 地址 | 新制式门牌号 | example.com AAAA 2001:db8::7 |
| CNAME | 域名 → 另一个域名(别名) | “此人另有外号,查那条” | api.example.com CNAME myapp.up.railway.app |
| MX | 指定邮件服务器 | “邮件收发室在这个地址” | example.com MX 10 mail.example.com |
| TXT | 放一段文本(验证/防伪造) | “备注栏” | example.com TXT "v=spf1 mx a -all" |
| NS | 这个域名的记录归谁维护 | “这段电话本的编辑人” | example.com NS aria.ns.cloudflare.com |
下面逐个展开。
3.1 A 记录(最常用)
把一个域名直接指向一个 IPv4 地址。
Name Type Content
@ A 198.51.100.7 ← example.com 指向你的服务器
www A 198.51.100.7 ← www.example.com 也指向它
@ 是面板里的写法,代表主域本身(example.com)。
- 你的服务器公网 IP 是多少,就填多少。这是整篇教程里你亲手改得最多的一条。
3.2 AAAA 记录
作用和 A 完全一样,只是指向 IPv6 地址。服务器有公网 IPv6(光猫/云厂商都普遍下发了)就顺手加一条,访问者有 IPv6 网络时会优先走它,速度快、不走 IPv4 的 NAT。
@ AAAA 2001:db8:0:1234:5678:9abc:def0:1
3.3 CNAME 记录(别名)
“我不写门牌号,我只告诉你去看另一个名字”,最终解析结果 = 那个名字的解析结果。
blog CNAME www.example.com ← 子域指向主域
api CNAME myapp.up.railway.app ← 子域指向第三方托管平台
典型用途:
- 把子域指到第三方托管(GitHub Pages、Vercel、Railway、对象存储桶),平台会告诉你"加一条 CNAME 指到 xxx"。
- 主域改 IP 时,所有指向主域的 CNAME 自动跟着变,不用一个个改——这是 CNAME 最大的好处。
⚠️ 限制(后面第 9 节还会坑你):CNAME 是"指向别处"的别名,RFC 规定同一个主机名上,CNAME 不能和其他记录共存——都指到别人家了,你这条下还能写什么?所以根域(@)一般不能直接挂 CNAME(Cloudflare 等面板会用 “CNAME Flattening” 把它伪装成 A 记录,面板不报错,但原理要懂)。
3.4 MX 记录(邮件)
Mail Exchange,声明"这个域名的邮件由哪台服务器收",带优先级(数字越小越优先,类似备胎顺序):
example.com MX 10 mail.example.com
当有人给 postmaster@example.com 发邮件时,对方的邮件服务器会先查 example.com 的 MX 记录,把信投递到 mail.example.com 的 25 端口。
- 你自己不发邮件、不建邮箱,MX 可以不管。
- 但部分服务(Cloudflare Email Routing、企业邮箱接入)会要求你配 MX,到时候照抄对方给的数字即可。
3.5 TXT 记录(备注栏)
一个自由文本槽,三个最常见的用途:
① 域名归属验证(最高频)
申请 Let's Encrypt 的 DNS 验证、接入 Cloudflare、GitHub Pages 托管子域…
都是先让你加一条 TXT:
example.com TXT "verification=AbCdEfGh1234"
对方去查这条记录,查到了 = "你确实管着这个域名"。
② SPF 防邮件伪造
example.com TXT "v=spf1 mx a -all"
含义:只有我的 MX 服务器和 A 记录上的 IP 才能冒这个域名发邮件,
其他一律拒绝(-all = 硬性拒绝)。
③ DMARC / DKIM(更进阶的防伪造,零基础先跳过)
3.6 NS 记录(托管权)
声明"这个域名的记录由哪家公司维护",是整条链路的总开关:
- 注册域名时,注册商给你一套默认 NS(如
ns1.registrar-servers.com)。
- 把 NS 改成 Cloudflare 的两条(如
aria.ns.cloudflare.com + ben.ns.cloudflare.com)= 把这本"电话本"的编辑权交给 Cloudflare。
- NS 切过去之后,所有记录必须在 Cloudflare 面板里改,原注册商面板里的记录就失效了(见第 4.3 节步骤)。
- NS 变更是全链路广播,传播最慢:快则几分钟,慢则 48 小时(极端情况),一般几小时内完成。
—
4. 买域名:四家服务商 + 注册流程 + 把 DNS 托管切到 Cloudflare
4.1 服务商怎么选
| 服务商 | .com 价格(约) | 特点 | 备注 |
| Namesilo | $1012/年 | 便宜、WHOIS 隐私免费、界面简单 | 新手友好,支持信用卡/PayPal,本教程用它举例 |
| Cloudflare Registrar | ~$10.4/年 | 成本价零加价、自带 DDoS 防护 | 主要做"续费 + 管理",部分后缀不能新购,需先有域名 |
| 阿里云 | ¥5575/年 | 国内支付方便、实名+备案一站式 | .cn 等强制实名认证;大陆服务器对外提供网站服务必须 ICP 备案(见第 9 节坑 10) |
| 腾讯云(DNSPod) | ¥5575/年 | 同阿里云,DNSPod 是国内老牌 DNS | 同上 |
本教程的推荐组合:在 Namesilo(或任意家)买域名 + 把 DNS 托管切到 Cloudflare 免费版。
理由:注册商只管"注册"(付钱、拥有名字),Cloudflare 免费给你全球 DNS、DDoS 防护和免费 SSL(第 7 节),职责分离,且 CF 面板是全行业最好用的之一。
4.2 注册流程(以 Namesilo 为例,其他家流程大同小异)
- 打开 namesilo.com,搜索你想买的域名(如
example.com),确认"Available"。
- 加入购物车 → 结算 → 支付(信用卡 / PayPal / 加密货币)。
- 登录后台 My Products,域名出现在列表里,顺手做三件事:
- Auto Renew(自动续费)打开——忘记续期域名过期被抢,比什么都坑;
- 确认 WHOIS Privacy 是开启的(Namesilo 默认免费);
- 记下到期时间,设个手机日历提醒。
- 完成。域名现在是"你的",但它的 DNS 还挂在注册商默认 NS 上——接下来切给 Cloudflare。
4.3 把 DNS 托管切到 Cloudflare(关键 7 步)
注册/登录 cloudflare.com(免费)。
面板点 Add a site(添加站点)→ 输入 example.com → 选 Free 套餐 → Continue。
CF 自动扫描该域名现有的 DNS 记录 → 检查一遍(一般没有或很少)→ Continue。
CF 会显示两条 NS 记录,类似:
aria.ns.cloudflare.com
ben.ns.cloudflare.com
抄下来。
回到域名注册商(Namesilo):My Products → Manage → 找到 Domain Nameservers 区块 → 选择 Use custom nameservers → 删掉原来的默认 NS → 填入 CF 给你的两条 → 保存。
回到 CF,点 Check Nameservers(检查)。状态变为 active 即完成——几分钟到 48 小时,通常会发邮件通知你(一般几小时内)。
激活后,example.com 的 DNS 就归 CF 管了,之后加/改记录全部在 CF 面板操作。
为什么非要切 CF? 免费版就白送你:全球快速解析、DDoS 防护、免费 SSL 证书(第 7.1 节)、好用的 API。哪怕你最后不用它的橙色云代理,单当 DNS 用也比注册商默认 NS 快。
—
5. 加一条 A 记录:让域名指向你的服务器
5.1 添加记录(Cloudflare 面板)
CF 面板 → 点进 example.com → DNS → Records → Add record:
| 类型 | 名称 (Name) | 内容 (Content) | 代理状态 (Proxy) | TTL |
| A | @ | 198.51.100.7 | DNS only(灰云) | Auto |
| A | www | 198.51.100.7 | DNS only(灰云) | Auto |
@ = example.com 本身;www = www.example.com。两条都加,否则总有一个访问不了(坑 7)。
- 服务器公网 IP 在哪看:云控制台里看,或 SSH 上服务器执行
curl ifconfig.me。
- 第一次先用灰云(DNS only):流量直连你的服务器,你在服务器上自己用 certbot 申请证书(第 7.2 节)。验证一切正常后,随时可以一键切橙云(Proxied),让 CF 代管 HTTPS(第 7.1 节)。
5.2 验证解析生效
# 方法 1:ping(最直观,顺便测连通性)
ping -c 4 example.com
# 输出里出现 198.51.100.7 → 解析对了
# 方法 2:dig(最专业。Debian/Ubuntu 先装:sudo apt install -y dnsutils)
dig +short A example.com # 只输出 IP,干净:198.51.100.7
dig +short A www.example.com
dig example.com @8.8.8.8 # 直接问 Google 的 DNS,绕过你本地缓存
# 方法 3:nslookup(Windows 自带,Linux 一般也有)
nslookup example.com
# 方法 4:不装工具,浏览器直接查(Google DoH 接口)
# https://dns.google/resolve?name=example.com&type=A
# 返回 JSON,看 "Answer" 里的 Data 是不是 198.51.100.7
# 方法 5:curl 看"实际用哪个 IP 连的"(网站跑起来后最有用)
curl -v http://example.com 2>&1 | grep -m1 Trying
# * Trying 198.51.100.7:80... ← 客户端实际敲的门牌
# 网站跑起来后,完整验证:
curl -I https://example.com
# HTTP/2 200 ← 看到 200 就通了
5.3 加了记录却没生效?——DNS 传播延迟
记录已经写进 CF 了,但"全世界不是立刻都看得到",因为解析链上每一级都缓存了旧答案:
| 缓存位置 | 缓存多久 | 说明 |
| 浏览器 | 几分钟 ~ 本次会话 | 开新标签/重启浏览器可清 |
| 本地 DNS(路由器 / 223.5.5.5 等) | 最长到 TTL | 主要延迟来源,别人家路由器你管不着 |
| 顶级域 / 根 | 按 TTL | 一般影响小 |
所以:
- TTL = 300 秒 → 最多等 5 分钟;TTL 越大,最坏情况等越久。
- 等不及可以清自己机器的缓存,用
dig @8.8.8.8 直接问外部 DNS 验证真实状态:
# Linux(systemd-resolved,Debian/Ubuntu 默认)
sudo systemd-resolve --flush-caches # 新系统也可用:sudo resolvectl flush-caches
# Windows
ipconfig /flushdns
# macOS
sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder
- 关键认知:清缓存只对你自己这台机器生效。“你这里查到了新 IP” ≠ “全世界都查到了”;反过来"你这里还没变"通常 = 还在传播中,等等就好。大改 DNS 前,如果业务允许,先把 TTL 调小(如 300 秒),等几分钟再改,传播就会很快。
—
6. HTTPS 与证书:为什么 HTTP 明文不行?
6.1 HTTP 到底风险在哪
HTTP 是明文协议——浏览器和服务器的每一句话,中间路径上的路由器、咖啡店 WiFi、运营商设备都能直接读懂。相当于寄明信片:收件人地址看得见,内容也看得见,路上谁都能瞄一眼,甚至偷换掉。
| 风险 | 攻击者怎么做 | 后果 |
| 窃听 | 直接读明文 | 你输入的密码、cookie、聊天记录全被看到 |
| 篡改 | 在响应里插东西 | 网页被加广告/挂马/改转账金额 |
| 冒充 | 搭个假站把流量引过去 | 假的 “bank.com” 登录页骗你的账号 |
6.2 HTTPS = HTTP + TLS:信封 + 火漆
TLS 干两件事:
- 加密:内容加密,窃听者只看到乱码(信封封口)。
- 身份验证:怎么确定对面是真
example.com 而不是冒充者?——靠证书。
为什么不能"浏览器和服务器私下约定一个密码"?因为双方素不相识、从没说过话。所以需要全世界都信任的第三方来担保,这个第三方就是 CA(Certificate Authority,证书颁发机构)——类比"公安局":它给你的网站发"身份证"。
6.3 证书是什么
证书 = CA 签发的一张官方公函,里面写着:
- 属于哪个域名(
example.com、www.example.com);
- 服务器的公钥(TLS 握手时用来协商加密密钥);
- CA 的数字签名(证明这函是真的 CA 发的,没被伪造);
- 有效期(Let’s Encrypt 的证书 = 90 天)。
浏览器/操作系统出厂预装了一批"根 CA 证书"(相当于全国公安局的公章样式)。你的证书要能通过签名链一路追溯回某个预装根证书,浏览器才信任;否则就是大家熟悉的红屏警告 “⚠ 您的连接不是私密连接”。
你的证书(example.com)
↑ 由它签发并签名
中间 CA(Let's Encrypt R11 / E13)
↑ 由它签发并签名
根 CA(ISRG Root X1) ← 预装在浏览器/系统里,"公章样式"
Let’s Encrypt:非营利组织,证书免费、全自动、90 天一张。有效期短不是坑,是特性——证书万一泄露,最多 3 个月就作废重签。今天互联网上绝大多数 🟢 小绿锁都是它发的。
6.4 不做 HTTPS 的代价
- 浏览器标"不安全",带表单的 http 页面甚至红色警告,用户直接关页;
- 支付、推送、各类 Web API 基本强制 https;
- 证书免费,没有理由不做。
—
7. 免费证书两种申请方式
7.0 共同前提:把 80/443 端口开出去
Let’s Encrypt 最常用的验证方式(HTTP-01)原理是:CA 会访问你服务器的 80 端口,检查一个随机文件——证明"你确实管着这个域名"。所以 80 和 443 必须对公网可达:
# 服务器上:看 80/443 是否有人在监听
sudo ss -tlnp | grep -E ':(80|443)\b'
# 云服务器:去控制台【安全组】确认 TCP 80、TCP 443 入方向放行(这是最常忘的一步!)
# 家用宽带:路由器要开端口转发 / 防火墙放行
7.1 方式 A:Cloudflare 橙云代理(最简单,零命令行)
把 A 记录打开橙云(Proxied):用户的流量先到 CF 边缘节点,CF 自动为你的域名签发免费证书,再由 CF 回源到你的服务器。
步骤:
CF 面板 → DNS → 点你的 A 记录 → 代理状态选 Proxied(橙色云图标)→ 保存。
等几分钟,SSL/TLS 区域会显示已签发证书(自动的,不用申请)。
SSL/TLS → Overview 选回源模式:
| 模式 | CF ↔ 用户 | CF ↔ 你的服务器 | 说明 |
| Flexible | https | http | 回源明文,不推荐(回源段可被窃听/劫持) |
| Full | https | https(接受自签名证书) | 服务器可以放自签证书,过渡可用 |
| Full (strict) | https | https(必须真 CA 证书) | 最稳:服务器上再用 7.2 节 certbot 申请一张 |
浏览器访问 https://example.com → 出现小绿锁。用户看到的是 CF 签发的证书(域名是你的是你的)。
优点:零操作、白送 DDoS 防护、全球加速。
代价:流量绕道 CF(CF 在中国大陆没有节点,国内访问速度取决于 CF 边缘到大陆的回源质量);服务器上那张证书不再是"用户直接看到的那张"。
注意:开了橙云后,你服务器上的 certbot 用 HTTP-01 验证会出问题(CA 的验证请求被 CF 拦截/转发,见第 9 节坑 5)。但你本来就不用申请——CF 已经发好了;若想要 Full (strict),用 DNS-01 验证(--dns-plugin dns-.cloudflare,走 TXT 记录,不依赖端口)。
7.2 方式 B:服务器上 certbot 申请(Debian/Ubuntu + nginx)
适用:灰云直连、或你想让"用户直接看到真实证书"。一条命令搞定申请 + 配置:
# 前提:nginx 已安装运行,且 80 端口有一个 server_name 是你域名的站点
# (刚装完 nginx 时默认有个 default 站点,把它删掉并改成你的域名站点,见第 8 节)
# 1. 安装 certbot 和 nginx 插件
sudo apt update
sudo apt install -y certbot python3-certbot-nginx
# 2. 一键:申请证书 + 自动改 nginx 配置(加 443 ssl 监听 + http→https 重定向)
sudo certbot --nginx -d example.com -d www.example.com
交互过程长这样(照着选):
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address(过期提醒用,强烈建议填):you@example.com
→ 是否订阅 EFF 邮件列表:No
→ 同意服务条款 Terms of Service:yes
→ 是否重定向 http → https:
1) 不重定向
2) 全部重定向 ← 选 2
Your choice is: 2
成功后发生了什么:
- 证书文件:
/etc/letsencrypt/live/example.com/fullchain.pem(证书链)和 privkey.pem(私钥,绝不能外传);
- nginx 配置被自动改写:增加
listen 443 ssl、ssl_certificate 指向上面的文件、return 301 https://...;
- nginx 自动 reload,无需手动重启。
验证:
curl -I https://example.com
# HTTP/2 200
# server: nginx
# 看证书的签发者和有效期
curl -sIv https://example.com 2>&1 | grep -E 'subject:|issuer:|expire date'
# subject=CN = example.com
# issuer=C = US, O = Let's Encrypt, CN = R11 ← 看到 Let's Encrypt 就对
浏览器里点地址栏小锁 → 查看证书 → 颁发者是 Let’s Encrypt,完事。
7.3 自动续期:certbot 已装好定时任务,你只需确认它活着
Let’s Encrypt 证书 90 天到期。certbot 的 apt 包会自动安装 systemd 定时器(每天 06 点之间随机跑两次 certbot renew,只有"距到期不足 30 天"才真正续):
# 确认定时任务在(应能看到 certbot.timer 一行)
sudo systemctl list-timers | grep certbot
# 模拟续期一次(dry-run 走测试环境,不动真证书,随时可跑)
sudo certbot renew --dry-run
# 看到 "Congratulations, all renewals succeeded" 就高枕无忧
# 手动触发续期(紧急情况 / dry-run 通过后想立即执行)
sudo certbot renew
# 续期成功后自动 reload nginx
# 随时查看所有证书的到期时间
sudo certbot certificates
如果 dry-run 失败,90% 是 80 端口被占(见第 9 节坑 2)。
—
8. 反向代理:为什么 nginx 拿到证书后还要转发到后端端口?
一句话:nginx 是大楼的前台——用户只认大楼地址(域名)和前台窗口(443),前台拿着"身份证"(证书)核完身份,再把请求转给里面的员工(后端应用,比如 3000 端口的 Node/Django/Go 服务);员工本人从不对接公网。
为什么必须这样:
- 后端应用只监听
127.0.0.1:3000——本机才能访问,安全;
- nginx 监听
0.0.0.0:443——唯一对外的门,专门负责 TLS 加解密;
- 一台 nginx 可以按域名把流量转到多个端口:一台服务器挂多个站。
先写好这个最小反向代理站点(在跑 certbot 之前,certbot --nginx 会在它基础上加 443 和重定向):
sudo nano /etc/nginx/sites-available/example.com
server {
listen 80;
server_name example.com www.example.com;
location / {
# 反向代理:把请求转发给后端应用(示例:监听 3000 端口)
proxy_pass http://127.0.0.1:3000;
# 把真实域名和客户端 IP 透传给后端,否则后端看到的永远是 127.0.0.1
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# 启用站点(软链到 enabled 目录)
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
# 删掉默认站点,避免两个站点抢 80 端口
sudo rm -f /etc/nginx/sites-enabled/default
# 检查配置语法(必须这一步!)
sudo nginx -t
# 重载生效
sudo systemctl reload nginx
之后回到 7.2 节跑 certbot --nginx,前台就"持证上岗"了。
—
9. 常见坑与避坑表
| # | 坑 | 症状 | 原因 | 解法 |
| 1 | 解析不生效,要等 | dig 还是旧 IP | 浏览器/本地 DNS/顶级域各级都有缓存,受 TTL 约束 | 等 TTL 过期;或清本地缓存(systemd-resolve --flush-caches / ipconfig /flushdns);用 dig +short A 域名 @8.8.8.8 绕开本地缓存查真实状态;记住"你查到了 ≠ 全世界都查到了" |
| 2 | certbot 失败:80 端口被占 | Failed authorizations via: http-01、bind: address already in use | 另一个服务(旧 nginx / apache / 面板 / 你的应用自己)占了 80 | sudo ss -tlnp \| grep :80 看谁占着 → 停掉它或让它换端口 → 重试;若应用必须占 80,改用 certbot certonly --webroot 或 DNS-01 验证 |
| 3 | CNAME 和 A 记录冲突 | 面板报 “该主机已有记录,CNAME 不能与其他记录共存” | RFC 规定 CNAME 不能与同名主机上的其他记录共存 | 删掉该主机名下其他记录,只留 CNAME;根域想指第三方域名,用 CF 的 CNAME Flattening(伪装成 A,面板无感) |
| 4 | Cloudflare 橙云循环(Error 1002) | 浏览器显示 CF 的 1002 错误页 | 源站 A 记录指回了 Cloudflare 自己的边缘 IP,CF 回源 → 又回到 CF → 死循环 | A 记录内容必须是源站真实公网 IP,不能是 CF 边缘 IP;检查 SSL/TLS 设置正确 |
| 5 | 开橙云后 certbot HTTP-01 一直失败 | 验证永远不过 | 橙云模式下流量先到 CF,CA 的验证请求被代理拦截/转发,到不了源站 | 用橙云就不用再申请源站证书(CF 已发);确需要时用 certbot --dns-plugin dns-.cloudflare 走 DNS-01(写 TXT 验证,不依赖 80 端口);或临时切灰云申请完再切回 |
| 6 | 80/443 被安全组挡住 | 本机测试通、公网访问超时 | 云安全组 / 路由器防火墙没放行 | 云控制台安全组放行 TCP 80、TCP 443;家用宽带开端口转发 |
| 7 | www 能开、裸域不能开(或反过来) | 一个有证书一个报错 | 只加了一条 A 记录 / certbot -d 只写了单个域名 | @ 和 www 两条 A 记录都加;certbot --nginx -d example.com -d www.example.com 两个域名都写;nginx 里 301 统一到一个 |
| 8 | NS 切换后原面板记录"消失" | CF 里找不到原有记录 | NS 切走后记录归 CF 管,没导入就要重填 | Add a site 时 CF 会自动抓取现有记录,检查是否漏抓;NS 切换是整体生效,旧记录不会"慢慢消失",是切换瞬间全部换管 |
| 9 | 证书明明有效,个别浏览器仍报错 | 少数用户报红屏 | 老系统根证书库过旧,不认较新的中间证书 | 极少见;升级用户系统/浏览器;或重新申请一张证书(新证书用更新证书链) |
| 10 | 大陆服务器域名被断 | 国内用户打不开,海外正常 | 中国大陆服务器未 ICP 备案,80/443 和域名被运营商封 | 大陆服务器必须备案;或改用海外服务器(海外无此要求) |
三个最高频坑的 30 秒自检命令:
# ① 80 端口被谁占了?
sudo ss -tlnp | grep :80
# ② 全球解析到底解析到哪了?(绕开本地缓存)
dig +short A example.com @8.8.8.8
# ③ 证书状态 / 到期时间?
sudo certbot certificates
—
10. 「域名 + 证书上线」完整步骤清单(打勾跟着做)
□ 01 买域名(Namesilo/CF/阿里云/腾讯云),保存登录账号、记下续费日期
□ 02 Cloudflare 注册 → Add a site → Free 套餐 → 记下给你的 2 条 NS
□ 03 回注册商后台,把域名的 NS 改成 CF 那 2 条,保存
□ 04 等 CF 显示 active(几分钟~48 小时,会发邮件)
□ 05 CF → DNS → 加 A 记录:@ → 服务器公网 IP(灰云 DNS only)
□ 06 CF → DNS → 加 A 记录:www → 服务器公网 IP(灰云 DNS only)
□ 07 验证解析:dig +short A example.com @8.8.8.8 → 应输出你的 IP
□ 08 服务器:云安全组放行 TCP 80 / 443(家用宽带则配端口转发)
□ 09 服务器:装 nginx,写好 server 块(listen 80 + proxy_pass 到后端端口),nginx -t 通过
□ 10 服务器:sudo apt install -y certbot python3-certbot-nginx
□ 11 sudo certbot --nginx -d example.com -d www.example.com(选 2 重定向)
□ 12 验证:curl -I https://example.com 返回 200,且 issuer 是 Let's Encrypt
□ 13 确认定时续期:sudo certbot renew --dry-run → all renewals succeeded
□ 14 (可选)A 记录切橙云 Proxied → SSL/TLS 设 Full / Full (strict)
□ 15 (可选)有公网 IPv6:加 AAAA 记录
□ 16 (可选)换个网络/找朋友 curl 一次,确认全球传播到位
—
最后把整条链路收成一句话:
买个名字(域名)→ 电话本交给 CF(NS)→ 条目里写上你的门牌号(A 记录)
→ 前台 nginx 拿着免费身份证上岗(certbot)→ 用户看到小绿锁(https)
之后唯一的日常就是:偶尔看一眼 certbot certificates,收到 CF 的邮件。完事。
(完)