欢迎光临
IDC人自己的网站

Let’s Encrypt IP 证书(TLS‑ALPN‑01)完整原理与生产实践


📘 知识库

Let’s Encrypt IP 证书(TLS‑ALPN‑01)完整原理与生产实践


1️⃣ 背景与目标

在以下场景中,需要为 IP 地址(IPv4 / IPv6) 签发 TLS 证书:

  • 无法绑定域名
  • IPv6‑only 主机
  • API / 设备直连
  • 临时实例
  • 内部或受控公网服务

Let’s Encrypt 提供了 IP 证书支持,但其使用方式与传统域名证书完全不同


2️⃣ IP 证书的基本事实(必须理解)

项目结论
CALet’s Encrypt
Profileshortlived
有效期≈ 6 天
验证方式仅 TLS‑ALPN‑01
HTTP‑01❌ 不支持
DNS‑01❌ 不支持
CN 包含 IP❌ 禁止
SAN 包含 IP✅ 必须
IPv4 + IPv6✅ 同一证书支持

3️⃣ TLS‑ALPN‑01 的协议本质

3.1 验证目标

TLS‑ALPN‑01 的验证目标是:

证明你控制了该 IP 在 TCP 443 上的 TLS 握手

不是:

  • HTTP 服务
  • DNS 记录
  • 某个端口
  • 某个进程

3.2 为什么强制 TCP 443

  • 443 是 TLS 的事实标准入口
  • IP 没有 DNS 作为额外信任层
  • 唯一可信锚点是 公网 TLS 握手

✅ 这是 安全边界,不是实现限制


4️⃣ 为什么不会影响正常 443 业务

4.1 ALPN 的关键作用

客户端ALPN
浏览器 / APIh2, http/1.1
ACME 验证acme-tls/1

ALPN 在 TLS ClientHello 中明文可见


4.2 协议级隔离

  • TLS‑ALPN‑01 在 TLS 握手阶段 即可区分
  • 不解密
  • 不终止 TLS
  • 不影响业务连接

5️⃣ 为什么不能直接让 Nginx listen 443

5.1 根本原因(协议层)

  • TLS 只能被 终止一次
  • ALPN 只能在 第一次握手 中判断
  • lego 必须直接参与 TLS 握手

👉 Nginx http 层 listen 443 = 已终止 TLS = ACME 无法验证


6️⃣ 唯一的无停机方案:Nginx stream + ssl_preread

6.1 架构模型

Internet
   |
   | TCP 443
   v
Nginx stream (ssl_preread)
   |
   |-- ALPN=acme-tls/1  → lego (843)
   |
   |-- ALPN=h2/http1.1 → HTTPS 服务 (4430)

6.2 生产级 Nginx 配置(完整)

stream {
    map $ssl_preread_alpn_protocols $backend {
        ~\bacme-tls/1\b  acme_backend;
        default          https_backend;
    }

    upstream acme_backend {
        server 127.0.0.1:843;
    }

    upstream https_backend {
        server 127.0.0.1:4430;
    }

    server {
        listen 443;
        listen [::]:443;
        proxy_pass $backend;
        ssl_preread on;
    }
}

7️⃣ lego 的正确使用方式(IP 证书)

7.1 自动获取 IPv4 + IPv6

IPV4=$(curl -fsS https://api.ipify.org)
IPV6=$(curl -fsS https://api64.ipify.org)

7.2 正确签发命令(必须参数)

lego \
  --accept-tos \
  --email [email protected] \
  --tls \
  --tls.port 843 \
  --domains "$IPV4" \
  --domains "$IPV6" \
  --disable-cn \
  run \
  --profile shortlived

关键参数说明

参数作用
--tls启用 TLS‑ALPN‑01
--tls.portlego 本地监听端口
--disable-cn防止 IP 出现在 CN
--profile shortlivedIP 证书专用

8️⃣ 证书存储位置

默认路径:

/opt/.lego/certificates/

文件命名规则:

  • 使用第一个 --domains(通常是 IPv4)

9️⃣ 为什么不能用 firewalld / iptables 实现分流

9.1 层级不匹配

层级能看到
L3/L4(防火墙)IP / 端口
❌ L4看不到 ALPN
✅ L7可解析 TLS ClientHello

👉 ALPN 在 TLS 层,防火墙无法判断


9.2 防火墙只能做什么

  • ✅ 无条件 DNAT
  • ❌ 条件转发(基于 ALPN)

🔟 是否存在设计缺陷?

10.1 工程体验角度

✅ 是的,不优雅
✅ 部署复杂
✅ 心智负担高


10.2 协议安全角度

❌ 不是缺陷
✅ 是刻意选择的安全边界
✅ 防止 IP 证书被滥发


1️⃣1️⃣ 可选方案对比

方案停机复杂度推荐
stream + ssl_preread✅✅✅
秒级停机
firewalld
HTTP‑01
DNS‑01

✅ 最终结论(工程级)

TLS‑ALPN‑01 强制 443 是安全边界,不是逻辑缺陷

IP 证书是高级能力,设计上刻意提高使用门槛

✅ stream 分流是唯一无停机解法
✅ 防火墙层无法替代
✅ IPv4 + IPv6 同证书完全支持


赞(1)
未经允许不得转载:IDC头条 » Let’s Encrypt IP 证书(TLS‑ALPN‑01)完整原理与生产实践

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

全国首家专注IDC行业的垂直自媒体

我要投稿互帮互助