>

适用场景:你有一台公网服务器(云服务器 / 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.comAPI 接口
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

当有人给 [email protected] 发邮件时,对方的邮件服务器会先查 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.7DNS only(灰云)Auto
Awww198.51.100.7DNS 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 ↔ 你的服务器说明
    Flexiblehttpshttp回源明文,不推荐(回源段可被窃听/劫持)
    Fullhttpshttps(接受自签名证书)服务器可以放自签证书,过渡可用
    Full (strict)httpshttps(必须真 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(过期提醒用,强烈建议填):[email protected]
    → 是否订阅 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 绕开本地缓存查真实状态;记住"你查到了 ≠ 全世界都查到了"
2certbot 失败:80 端口被占Failed authorizations via: http-01、bind: address already in use另一个服务(旧 nginx / apache / 面板 / 你的应用自己)占了 80sudo ss -tlnp \| grep :80 看谁占着 → 停掉它或让它换端口 → 重试;若应用必须占 80,改用 certbot certonly --webroot 或 DNS-01 验证
3CNAME 和 A 记录冲突面板报 “该主机已有记录,CNAME 不能与其他记录共存”RFC 规定 CNAME 不能与同名主机上的其他记录共存删掉该主机名下其他记录,只留 CNAME;根域想指第三方域名,用 CF 的 CNAME Flattening(伪装成 A,面板无感)
4Cloudflare 橙云循环(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 端口);或临时切灰云申请完再切回
680/443 被安全组挡住本机测试通、公网访问超时云安全组 / 路由器防火墙没放行云控制台安全组放行 TCP 80、TCP 443;家用宽带开端口转发
7www 能开、裸域不能开(或反过来)一个有证书一个报错只加了一条 A 记录 / certbot -d 只写了单个域名@ 和 www 两条 A 记录都加;certbot --nginx -d example.com -d www.example.com 两个域名都写;nginx 里 301 统一到一个
8NS 切换后原面板记录"消失"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 的邮件。完事。

(完)

— 感谢阅读 —

一起交流

分享你的思考,让讨论更进一步。