Skip to content

域名与 DNS 基础

大白话解释: 域名就像"网站的门牌号"。用户输入 example.com,浏览器通过 DNS(域名系统)找到对应的服务器 IP 地址,然后加载网站。

为什么要了解 DNS?

  • 绑定域名:买了域名后,需要配置 DNS 指向你的服务器
  • HTTPS 配置:需要验证域名所有权才能申请 SSL 证书
  • 子域名管理:API、后台、CDN 等用不同子域名

DNS 记录类型速查:

  • A 记录:域名 → IP 地址(最常用)
  • CNAME 记录:域名 → 另一个域名(用于 CDN、Vercel 等)
  • MX 记录:邮件服务器配置
  • TXT 记录:域名验证、SPF 配置

DNS 传播时间: DNS 修改不是即时生效的,需要等待各级缓存过期。最快几分钟,最慢 24-48 小时。

前端部署必备的域名和 DNS 知识,包括域名购买、DNS 解析、HTTPS 配置。


域名基础

域名结构

www.example.com
 ↑      ↑      ↑
 子域名  主域名  顶级域名
类型示例说明
顶级域名.com.cn.io域名后缀
主域名example.com注册的域名
子域名www.example.com主域名下的分支
二级域名api.example.comAPI 服务
三级域名v2.api.example.com更细的分支

域名购买

平台特点
Cloudflare Registrar成本价,无溢价
Namesilo便宜,免费隐私保护
阿里云万网国内域名首选
腾讯云国内域名可选

DNS 解析

记录类型

类型说明示例
A将域名指向 IPv4 地址example.com192.168.1.1
AAAA将域名指向 IPv6 地址example.com2001:db8::1
CNAME将域名指向另一个域名www.example.comexample.com
MX邮件服务器example.commail.example.com
TXT文本记录(验证、SPF 等)example.com"v=spf1 ..."
NS域名服务器指向 DNS 服务商

常见配置

text
# 主域名指向服务器 IP
example.com     A       76.76.21.21

# www 指向主域名
www             CNAME   example.com

# API 子域名指向后端服务器
api             A       192.168.1.10

# Vercel 托管
www             CNAME   cname.vercel-dns.com

# Netlify 托管
www             CNAME   your-site.netlify.app

# GitHub Pages
www             CNAME   your-username.github.io

DNS 传播时间

DNS 变更不是即时生效的,因为各级缓存需要等待 TTL 过期后才会重新查询。

阶段耗时说明
权威 DNS 更新秒级在 DNS 服务商控制台修改后立即生效
递归 DNS 缓存TTL 时间等待旧记录 TTL 过期
ISP DNS 缓存数分钟 ~ 数小时部分 ISP 可能忽略 TTL
浏览器缓存数分钟浏览器自带 DNS 缓存
text
# 传播时间估算
# 最快 = TTL 过期时间(如果各级都遵循 TTL)
# 最慢 = 24 ~ 48 小时(部分 ISP 不遵循 TTL)

# 加速传播的方法:
# 1. 修改 DNS 记录前,先将 TTL 调低(如 60s)
# 2. 等待旧 TTL 过期后再做变更
# 3. 变更完成后恢复原 TTL

dig 命令详解

bash
# 基本查询
dig example.com

# 查询特定记录类型
dig example.com A          # IPv4 地址
dig example.com AAAA       # IPv6 地址
dig example.com CNAME      # CNAME 记录
dig example.com MX         # 邮件服务器
dig example.com TXT        # TXT 记录
dig example.com NS         # NS 记录
dig example.com SRV        # SRV 记录
dig example.com CAA        # CAA 记录

# 简洁输出(只显示结果)
dig +short example.com
dig +short example.com A

# 追踪完整解析路径(排查解析链路问题)
dig +trace example.com

# 验证新记录是否已生效:对比不同 DNS 服务器的响应
dig @8.8.8.8 example.com A      # Google DNS
dig @1.1.1.1 example.com A      # Cloudflare DNS
dig @223.5.5.5 example.com A    # 阿里 DNS
# 如果返回的 IP 一致,说明记录已全球生效

# 指定 DNS 服务器查询
dig @8.8.8.8 example.com
dig @1.1.1.1 example.com

# 反向查询(IP 查域名)
dig -x 192.168.1.1

# 查看 TTL 值
dig example.com | grep -A 1 "ANSWER SECTION"

nslookup 命令详解

bash
# 基本查询
nslookup example.com

# 查询特定记录类型
nslookup -type=A example.com
nslookup -type=CNAME example.com
nslookup -type=MX example.com
nslookup -type=TXT example.com
nslookup -type=NS example.com

# 指定 DNS 服务器
nslookup example.com 8.8.8.8
nslookup example.com 1.1.1.1

# 交互模式
nslookup
> set type=A
> example.com
> set type=MX
> example.com
> exit

whois 域名查询

bash
# 查询域名注册信息
whois example.com

# 输出包含:
# - 注册商(Registrar)
# - 注册/过期日期
# - DNS 服务器
# - 域名状态
# - 注册人信息(可能被隐私保护隐藏)

# 安装 whois
# Ubuntu/Debian
sudo apt install whois

# macOS
brew install whois

# Windows(使用在线工具或安装 whois 客户端)

泛解析配置

text
# 泛解析(Wildcard DNS)匹配所有未明确配置的子域名
# 使用 * 通配符

# A 记录泛解析
*.example.com    A    192.168.1.1

# CNAME 泛解析
*.example.com    CNAME    example.com
匹配结果
www.example.com(有单独 A 记录)使用单独的 A 记录
api.example.com(无单独记录)泛解析到 192.168.1.1
any.example.com(无单独记录)泛解析到 192.168.1.1
sub.api.example.com❌ 不匹配(泛解析只匹配一级)
text
# 泛解析适用场景
# 1. SaaS 平台(每个租户一个子域名)
# 2. 短链接服务
# 3. 动态预览环境

# 注意事项
# 1. 泛解析优先级低于具体记录
# 2. 可能被滥用(垃圾邮件、钓鱼)
# 3. 部分 DNS 服务商不支持

SRV 记录

text
# SRV 记录用于指定服务的位置(主机 + 端口)
# 格式:_service._protocol.name  TTL  IN  SRV  priority  weight  port  target
text
# SRV 记录示例
_sip._tcp.example.com.    3600  IN  SRV  10  60  5060  sip1.example.com.
_sip._tcp.example.com.    3600  IN  SRV  10  40  5060  sip2.example.com.
_minecraft._tcp.example.com.  3600  IN  SRV  0  5  25565  mc.example.com.
字段说明
priority优先级,值越小优先级越高
weight权重,相同优先级时按权重比例分配
port服务端口号
target服务所在主机名

CAA 记录

text
# CAA(Certificate Authority Authorization)
# 限制哪些 CA 可以为该域名颁发证书
# 格式:domain  TTL  IN  CAA  flags  tag  value
text
# CAA 记录示例
example.com.  IN  CAA  0  issue "letsencrypt.org"          # 允许 Let's Encrypt 签发
example.com.  IN  CAA  0  issue "digicert.com"             # 允许 DigiCert 签发
example.com.  IN  CAA  0  issuewild "letsencrypt.org"      # 允许 Let's Encrypt 签发通配符
example.com.  IN  CAA  0  iodef "mailto:[email protected]" # 违规通知邮箱
tag说明
issue允许为该域名颁发证书
issuewild允许为通配符域名颁发证书
iodef违规时的通知方式(邮箱或 URL)
text
# CAA 检查
dig example.com CAA

# Cloudflare 配置
# 控制台 → DNS → 添加记录 → 类型选择 CAA

DNS 服务商

Cloudflare(推荐)

  • 免费 DNS 服务
  • CDN 加速
  • DDoS 防护
  • 自动 HTTPS

配置步骤

  1. 注册 Cloudflare 账号
  2. 添加域名
  3. 修改域名的 NS 记录指向 Cloudflare
  4. 在 Cloudflare 添加 DNS 记录

阿里云 DNS

  • 国内域名推荐
  • 需要备案

配置步骤

  1. 登录阿里云控制台
  2. 进入域名解析
  3. 添加解析记录

DNSPod(腾讯云)

  • 国内主流 DNS 服务商
  • 腾讯云旗下,与腾讯云生态深度集成
  • 免费版支持基础解析,付费版支持更多记录和更高 QPS

配置步骤

  1. 注册 DNSPod 账号(可直接用腾讯云账号登录)
  2. 添加域名
  3. 修改域名的 NS 记录指向 DNSPod 提供的服务器
  4. 添加解析记录
text
# DNSPod 特有功能
# 1. 智能解析(按运营商、地域返回不同 IP)
# 2. URL 转发(显性/隐性转发)
# 3. DDoS 防护(付费版)

HTTPS 配置

免费 SSL 证书

Let's Encrypt

bash
# 使用 certbot 申请 SSL 证书
sudo apt install certbot                                         # 安装 certbot 工具
sudo certbot certonly --standalone -d example.com -d www.example.com  # 申请证书(需先停止 nginx)

# 证书文件位置
/etc/letsencrypt/live/example.com/fullchain.pem    # 完整证书链(服务器证书 + 中间证书)
/etc/letsencrypt/live/example.com/privkey.pem      # 私钥文件

# 自动续期配置(推荐每天执行两次,Let's Encrypt 证书有效期 90 天)
sudo crontab -e
0 0,12 * * * certbot renew --quiet     # 每天 0:00 和 12:00 检查并续期,--quiet 静默无变更时不发邮件

Cloudflare SSL

  1. 进入 Cloudflare 控制台
  2. 选择域名 → SSL/TLS
  3. 选择模式:
    • Flexible:HTTP 到 Cloudflare,Cloudflare 到源站 HTTP
    • Full:全程 HTTPS(源站需配置证书)
    • Full (Strict):全程 HTTPS(源站需有效证书)

nginx HTTPS 配置

nginx
# HTTPS 服务器配置
server {
    listen 443 ssl http2;                          # 监听 443 端口,启用 SSL + HTTP/2
    server_name example.com;                       # 你的域名

    # SSL 证书路径(Let's Encrypt 申请的证书)
    ssl_certificate /etc/nginx/ssl/cert.pem;       # 证书文件(含中间证书链)
    ssl_certificate_key /etc/nginx/ssl/key.pem;    # 私钥文件

    # SSL 协议和加密套件配置(安全优化)
    ssl_protocols TLSv1.2 TLSv1.3;                # 只允许 TLS 1.2 和 1.3
    ssl_ciphers HIGH:!aNULL:!MD5;                  # 高强度加密套件
    ssl_prefer_server_ciphers on;                  # 优先使用服务器端加密套件

    # Vue/React SPA 配置
    location / {
        root /var/www/dist;                        # 构建产物目录
        try_files $uri $uri/ /index.html;          # SPA history 路由
    }
}

# HTTP 自动跳转 HTTPS
server {
    listen 80;                                     # 监听 80 端口
    server_name example.com;                       # 你的域名
    return 301 https://$server_name$request_uri;   # 301 永久重定向到 HTTPS
}

备案(国内)

需要备案的情况

  • 域名指向国内服务器
  • 使用国内 CDN

备案流程

  1. 购买域名和服务器(同一服务商)
  2. 登录服务商备案系统
  3. 填写备案信息
  4. 上传资料(身份证、照片)
  5. 等待审核(约 1-2 周)

不需要备案的情况

  • 域名指向海外服务器
  • 使用 Cloudflare CDN
  • 使用 Vercel/Netlify 托管

常见问题

DNS 解析不生效

bash
# 检查 DNS 解析
nslookup example.com
dig example.com

# 清除本地 DNS 缓存
# Windows
ipconfig /flushdns

# macOS
sudo dscacheutil -flushcache

# Linux
sudo systemd-resolve --flush-caches

证书过期

bash
# 检查证书有效期
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates

# 续期 Let's Encrypt
sudo certbot renew

域名被墙

bash
# 检查域名是否被墙
# 使用在线工具:https://www.itdog.cn/

# 解决方案:
# 1. 使用 Cloudflare CDN
# 2. 更换域名
# 3. 使用海外服务器

DNS 解析流程详解

从输入 URL 到页面加载的完整流程

用户输入 URL


浏览器缓存 ──命中──→ 直接使用 IP
    │未命中

操作系统缓存(hosts 文件)──命中──→ 直接使用 IP
    │未命中

本地 DNS 服务器(ISP)──命中──→ 返回 IP
    │未命中

递归查询

    ├─→ 根域名服务器(.)
    │       │
    │       ▼
    │   顶级域名服务器(.com)
    │       │
    │       ▼
    │   权威域名服务器(example.com)
    │       │
    │       ▼
    │   返回 IP 地址


本地 DNS 缓存结果


浏览器发起 HTTP 请求


TCP 连接 → TLS 握手 → 发送请求 → 服务器响应 → 页面渲染

各级缓存及 TTL

缓存层级位置清除方式
浏览器缓存Chrome/Edge 内部清除浏览器数据、chrome://net-internals/#dns
操作系统缓存系统 DNS 缓存ipconfig /flushdns(Windows)
本地 DNS 缓存路由器 / ISP DNS等待 TTL 过期或更换 DNS 服务器
权威 DNS域名注册商修改 DNS 记录

TTL(Time To Live)

text
# DNS 记录的 TTL 决定缓存时间
example.com.  300  IN  A  192.168.1.1

              TTL = 300秒(5分钟)
TTL 值适用场景优缺点
60s频繁切换、故障转移解析快更新快,但查询频率高
300s一般网站平衡方案
3600s稳定服务减少查询,但更新慢
86400s极少变动查询最少,但切换慢

Cloudflare 详细配置

代理状态(橙色云朵)

Cloudflare 的 Proxy status 开启(橙色云朵)时,dignslookup 返回的是 Cloudflare 的 Anycast IP,而非源站真实 IP。这是正常现象,不影响访问。

bash
# 开启代理后,dig 返回 Cloudflare IP
dig example.com A
# → 104.18.x.x(Cloudflare IP,非源站)

# 如需查看源站 IP,临时关闭代理(灰色云朵)后再查询
# 或在 Cloudflare 控制台 → DNS → Records 中直接查看

⚠️ 开启代理后,源站 IP 被隐藏,这是 CDN 的正常行为。不要误以为 DNS 配置未生效。

SSL/TLS 模式详解

模式浏览器 → CFCF → 源站适用场景
OffHTTPHTTP不推荐,仅调试
FlexibleHTTPSHTTP源站无证书,快速启用 HTTPS
FullHTTPSHTTPS(不验证证书)源站有自签名证书
Full (Strict)HTTPSHTTPS(验证有效证书)推荐,源站有可信证书
# 模式选择决策树
源站有有效证书?
  ├─ 是 → Full (Strict)
  └─ 否 → 源站有自签名证书?
              ├─ 是 → Full
              └─ 否 → Flexible(临时方案)

Page Rules 配置

规则URL 模式设置作用
强制 HTTPShttp://example.com/*Always Use HTTPSHTTP 自动跳转 HTTPS
缓存级别example.com/static/*Cache Level: Cache Everything静态资源全缓存
浏览器缓存example.com/assets/*Browser Cache TTL: 1 year长期缓存静态资源
跳过缓存example.com/api/*Cache Level: BypassAPI 请求不缓存
重定向example.com/old/*Forwarding URL (301)永久重定向
text
# Page Rules 优先级
# 顺序很重要,从上到下匹配,命中即停止
1. example.com/api/*    → Bypass Cache
2. example.com/static/* → Cache Everything
3. example.com/*        → Always Use HTTPS

Caching 配置

配置项说明推荐值
Caching Level缓存级别Standard
Browser Cache TTL浏览器缓存时间Respect Existing Headers
Crawler Hints爬虫提示开启
Always Online源站宕机时提供缓存页面开启
text
# 缓存状态码
200 OK              → 默认缓存
301 Moved Permanently → 缓存
302 Found           → 不缓存
404 Not Found       → 缓存(短时间)
500 Server Error    → 不缓存

Workers(边缘计算)

js
// Cloudflare Worker 示例:自定义响应头
export default {
  async fetch(request) {
    const response = await fetch(request)
    const newResponse = new Response(response.body, response)
    newResponse.headers.set('X-Processed-By', 'Cloudflare-Worker')
    return newResponse
  }
}
js
// Worker 示例:URL 重写
export default {
  async fetch(request) {
    const url = new URL(request.url)
    if (url.pathname === '/api') {
      url.hostname = 'backend.example.com'
      return fetch(url.toString(), request)
    }
    return fetch(request)
  }
}
js
// Worker 示例:A/B 测试
export default {
  async fetch(request) {
    const cookie = request.headers.get('Cookie')
    const variant = cookie?.includes('variant=B') ? 'B' : 'A'
    const url = new URL(request.url)
    url.pathname = `/variant-${variant}${url.pathname}`
    return fetch(url.toString(), request)
  }
}

Workers 路由配置

text
# Worker 路由决定哪些 URL 请求由 Worker 处理
# 控制台 → Workers & Pages → 你的 Worker → Settings → Triggers → Routes

# 路由格式
example.com/api/*          # 匹配 /api/ 下所有路径
example.com/admin/*        # 匹配 /admin/ 下所有路径
*.example.com/*            # 匹配所有子域名的所有路径
example.com/static/*.js    # 匹配 /static/ 下所有 .js 文件
路由模式匹配不匹配
example.com/api/*/api/users/api/v2/items/api(无尾斜杠)
example.com/*所有路径
*.example.com/*www.example.comapi.example.comexample.com(无子域名)
js
// wrangler.toml 配置路由
name = "my-worker"
main = "src/index.js"
compatibility_date = "2024-01-01"

routes = [
  { pattern = "example.com/api/*", zone_name = "example.com" },
  { pattern = "example.com/admin/*", zone_name = "example.com" }
]

自定义域名邮箱转发

text
# Cloudflare 免费邮箱路由配置
# 步骤:
# 1. 进入 Cloudflare 控制台 → Email → Email Routing
# 2. 添加路由规则

# 配置示例
# catch-all → 转发到个人邮箱
*            → [email protected]

# 指定地址转发
hello@       → [email protected]
support@     → [email protected]
text
# 需要添加的 DNS 记录(Cloudflare 自动添加)
example.com  MX   10  route1.mx.cloudflare.net
example.com  MX   20  route2.mx.cloudflare.net
example.com  MX   30  route3.mx.cloudflare.net

CDN 加速原理

CDN 工作原理

用户(北京)                    源站(美国)
    │                              │
    ▼                              │
CDN 边缘节点(北京)──缓存命中──→ 直接返回
    │缓存未命中

CDN 中间层(亚太)
    │缓存未命中

源站(美国)──返回内容──→ CDN 缓存──→ 用户
概念说明
边缘节点(Edge)离用户最近的 CDN 服务器
中间层(Mid-Tier)边缘与源站之间的缓存层
回源(Origin Pull)CDN 未命中时向源站请求
预热(Preheat)主动将内容推送到 CDN 节点

回源与缓存

text
# 缓存命中流程
客户端请求 → CDN 边缘节点
  ├─ 缓存命中且未过期 → 直接返回(HIT)
  ├─ 缓存命中但已过期 → 向源站验证(REVALIDATED)
  │     ├─ 内容未变 → 返回 304,延长缓存
  │     └─ 内容已变 → 返回新内容,更新缓存
  └─ 缓存未命中 → 回源拉取(MISS)
响应头作用示例
Cache-Control缓存策略max-age=31536000, immutable
ETag内容标识"abc123"
Last-Modified最后修改时间Wed, 21 Oct 2015 07:28:00 GMT
Expires过期时间Thu, 01 Dec 2025 16:00:00 GMT
CDN-Cache-ControlCDN 专用缓存策略max-age=604800

缓存刷新策略

方式说明适用场景
自然过期等待 TTL 到期常规更新
手动刷新在 CDN 控制台主动刷新紧急更新
版本化 URL文件名加 hash前端构建产物
Purge Tag按标签批量刷新分类内容更新
text
# 版本化 URL 示例(推荐)
/assets/main.abc123.js      # 构建时生成 hash
/assets/main.def456.js      # 更新后 hash 变化,CDN 自动回源

# nginx 配置长缓存 + 版本化
location /assets/ {
    add_header Cache-Control "max-age=31536000, immutable";
}

域名重定向

301 vs 302 重定向

类型状态码含义SEO 影响浏览器行为
301301 Moved Permanently永久重定向传递权重缓存重定向
302302 Found临时重定向不传递权重每次重新请求
307307 Temporary Redirect临时重定向(保持方法)不传递权重不改变请求方法
308308 Permanent Redirect永久重定向(保持方法)传递权重缓存重定向

www 与非 www 统一

nginx
# 方案一:www 跳转到非 www(推荐)
server {
    listen 80;
    server_name www.example.com;
    return 301 https://example.com$request_uri;
}

server {
    listen 443 ssl;
    server_name www.example.com;
    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;
    return 301 https://example.com$request_uri;
}
nginx
# 方案二:非 www 跳转到 www
server {
    listen 80;
    server_name example.com;
    return 301 https://www.example.com$request_uri;
}
text
# Cloudflare 配置
# Rules → Redirect Rules → Create Rule
# 表达式:http.host eq "www.example.com"
# 操作:Dynamic redirect to https://example.com

HTTP 到 HTTPS 重定向

nginx
# nginx 配置
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
}
apache
# Apache .htaccess
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
text
# Cloudflare 配置
# SSL/TLS → Edge Certificates → Always Use HTTPS: ON
# 或 Page Rules: Always Use HTTPS

旧域名到新域名

nginx
# nginx 配置:旧域名跳转新域名
server {
    listen 80;
    listen 443 ssl;
    server_name old-domain.com www.old-domain.com;
    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;
    return 301 https://new-domain.com$request_uri;
}
js
// Cloudflare Worker:保留路径的域名跳转
export default {
  async fetch(request) {
    const url = new URL(request.url)
    url.hostname = 'new-domain.com'
    return Response.redirect(url.toString(), 301)
  }
}

SSL/TLS 深入

TLS 握手过程(TLS 1.3)

客户端                                服务器
  │                                    │
  │──── ClientHello ─────────────────→│
  │     (支持的密码套件、随机数)         │
  │                                    │
  │←─── ServerHello ─────────────────│
  │     (选定密码套件、随机数)           │
  │←─── 证书 ────────────────────────│
  │←─── CertificateVerify ──────────│
  │←─── Finished ───────────────────│
  │                                    │
  │──── Finished ────────────────────→│
  │                                    │
  │←═══ 加密通信 ═══════════════════→│
版本握手往返次数特点
TLS 1.22 次 RTT广泛支持
TLS 1.31 次 RTT更快更安全,移除不安全算法

证书类型

类型全称验证级别签发时间价格适用场景
DVDomain Validation域名所有权分钟级免费/低价个人网站、API
OVOrganization Validation组织真实性1-3 天中等企业网站
EVExtended Validation严格验证1-2 周较高金融、电商

通配符证书

text
# 通配符证书覆盖同级所有子域名
*.example.com  →  有效
  www.example.com  ✅
  api.example.com  ✅
  mail.example.com ✅
  sub.api.example.com ❌(不覆盖三级子域名)

# Let's Encrypt 申请通配符证书(需要 DNS 验证)
sudo certbot certonly --manual --preferred-challenges dns \
  -d example.com -d *.example.com

多域名证书(SAN)

text
# SAN(Subject Alternative Name)证书
# 一张证书覆盖多个不同域名

DNS: example.com
DNS: www.example.com
DNS: example.net
DNS: api.example.org

# Let's Encrypt 申请
sudo certbot certonly --standalone \
  -d example.com -d www.example.com \
  -d example.net -d api.example.org

证书链和中间证书

根证书(Root CA)


中间证书(Intermediate CA)


服务器证书(End Entity)
text
# 完整证书链文件
fullchain.pem = 服务器证书 + 中间证书
cert.pem      = 仅服务器证书
privkey.pem   = 私钥

# nginx 配置(使用 fullchain)
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;

# 验证证书链
openssl s_client -connect example.com:443 -servername example.com

OCSP Stapling

text
# OCSP Stapling:由服务器代替客户端向 CA 验证证书状态
# 优点:加速 TLS 握手,保护用户隐私

# 无 OCSP Stapling
客户端 ──→ CA 服务器(验证证书状态)──→ 客户端

# 有 OCSP Stapling
服务器 ──→ CA 服务器(定期获取状态)──→ 缓存
客户端 ──→ 服务器(附带 OCSP 响应)──→ 客户端
nginx
# nginx 启用 OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/fullchain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

HSTS 配置

text
# HSTS(HTTP Strict Transport Security)
# 告诉浏览器只能通过 HTTPS 访问

# 响应头
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
参数说明推荐值
max-age有效期(秒)31536000(1年)
includeSubDomains包含子域名建议开启
preload加入浏览器预加载列表慎重开启(难以撤销)
nginx
# nginx 配置 HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
text
# HSTS Preload List
# 提交到 https://hstspreload.org/
# 一旦加入,浏览器强制 HTTPS,无法轻易撤销
# 申请条件:
# 1. 有效 SSL 证书
# 2. 所有子域名支持 HTTPS
# 3. max-age 至少 31536000
# 4. 包含 includeSubDomains 和 preload

DNS 安全

DNSSEC

text
# DNSSEC(DNS Security Extensions)
# 为 DNS 响应提供签名验证,防止 DNS 劫持

# 无 DNSSEC
客户端 ──→ DNS 服务器 ──→ 返回结果(可能被篡改)

# 有 DNSSEC
客户端 ──→ DNS 服务器 ──→ 返回结果 + 数字签名
客户端验证签名 ✅ → 使用结果
客户端验证签名 ❌ → 拒绝结果
记录类型作用
RRSIG资源记录签名
DNSKEY公钥
DS委托签名(父区域存储)
NSEC/NSEC3不存在证明
text
# Cloudflare 启用 DNSSEC
# 控制台 → DNS → Settings → Enable DNSSEC
# Cloudflare 自动处理签名和密钥管理

DNS over HTTPS (DoH)

text
# 传统 DNS:明文 UDP/TCP 53 端口
# DoH:加密 HTTPS 443 端口,防止中间人窥探
协议端口加密说明
传统 DNS53 (UDP/TCP)可被监听和篡改
DoT (DNS over TLS)853TLS 加密
DoH (DNS over HTTPS)443HTTPS 加密,不易被封锁
text
# 常用 DoH 服务商
Cloudflare  https://cloudflare-dns.com/dns-query
Google      https://dns.google/dns-query
Quad9       https://dns.quad9.net/dns-query
bash
# 浏览器启用 DoH
# Chrome: chrome://settings/security → 使用安全 DNS
# Firefox: settings → Privacy → DNS over HTTPS

# curl 测试 DoH
curl -s -H 'accept: application/dns-json' \
  'https://cloudflare-dns.com/dns-query?name=example.com&type=A'

防 DNS 劫持

text
# DNS 劫持方式
1. 本地 hosts 文件篡改
2. 路由器 DNS 劫持
3. ISP DNS 劫持(运营商广告)
4. 中间人攻击(中间网络设备)
防护措施说明操作
使用可信 DNS避免使用 ISP 默认 DNS切换到 1.1.1.1 或 8.8.8.8
启用 DoH/DoT加密 DNS 查询浏览器或系统级配置
启用 DNSSEC验证 DNS 响应签名DNS 服务商开启
定期检查监控 DNS 解析结果使用 dig 或在线工具
HTTPS即使 DNS 被劫持也安全确保网站启用 HTTPS
bash
# 检查 DNS 是否被劫持
# 对比不同 DNS 服务器的解析结果
nslookup example.com 1.1.1.1
nslookup example.com 8.8.8.8
nslookup example.com 运营商DNS

# 如果结果不一致,可能被劫持

参考

个人学习笔记,部分内容借助 AI 辅助整理,仅供查阅参考,请以官方文档为准