🔒 SSL & 域名
Let's Encrypt 自动续签、Cloudflare DNS API、多域名管理、通配符证书——HTTPS 不是选项,是底线
🔐 SSL/TLS 基础
2024 年,没有 HTTPS 的网站会被 Chrome 标记为"不安全",Google 搜索排名也会降低。Let's Encrypt 提供免费 SSL 证书,搭配自动续签,零成本实现全站 HTTPS。
| 方案 | 成本 | 通配符 | 自动化 | 推荐 |
| Let's Encrypt + Traefik | 免费 | ✅ (DNS challenge) | 全自动 | ⭐⭐⭐⭐⭐ |
| Let's Encrypt + Certbot | 免费 | ✅ (DNS challenge) | 自动续签 | ⭐⭐⭐⭐ |
| Cloudflare Origin Cert | 免费 | ✅ | 手动(15年有效) | ⭐⭐⭐ |
| 付费 CA (DigiDoc等) | $100+/年 | ✅ | 手动 | ⭐ |
🌐 方案 1:Traefik + Let's Encrypt(推荐)
# Traefik 自动获取 SSL 证书
# 在 docker-compose.yml 中配置
services:
traefik:
image: traefik:v3.0
command:
# 入口点
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
# HTTP → HTTPS 重定向
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
# Let's Encrypt
- "--certificatesresolvers.letsencrypt.acme.email=you@example.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/ssl/acme.json"
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
# 通配符证书需要 DNS challenge
- "--certificatesresolvers.cloudflare.acme.email=you@example.com"
- "--certificatesresolvers.cloudflare.acme.storage=/ssl/acme.json"
- "--certificatesresolvers.cloudflare.acme.dnschallenge=true"
- "--certificatesresolvers.cloudflare.acme.dnschallenge.provider=cloudflare"
environment:
CF_DNS_API_TOKEN: ${CLOUDFLARE_API_TOKEN}
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik-ssl:/ssl
# 单域名证书(TLS challenge)
app:
labels:
- "traefik.http.routers.app.rule=Host(`app.example.com`)"
- "traefik.http.routers.app.tls.certresolver=letsencrypt"
# 通配符证书(DNS challenge)
api:
labels:
- "traefik.http.routers.api.rule=Host(`api.example.com`)"
- "traefik.http.routers.api.tls.certresolver=cloudflare"
🖥️ 方案 2:Certbot 独立模式
# 安装 Certbot
apt install certbot python3-certbot-nginx # Nginx 插件
# 或
apt install certbot python3-certbot-apache # Apache 插件
# 获取证书(standalone 模式,需要停止 web 服务器)
certbot certonly --standalone -d example.com -d www.example.com
# 获取通配符证书(需要 DNS 验证)
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
-d "*.example.com" \
-d "example.com"
# ~/.secrets/cloudflare.ini
dns_cloudflare_api_token = your_api_token_here
# 自动续签(Certbot 自带 systemd timer)
systemctl enable certbot.timer
systemctl start certbot.timer
# 查看续签计划
systemctl list-timers certbot.timer
# 手动续签测试
certbot renew --dry-run
# 续签后自动重载 Nginx
# /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
#!/bin/bash
systemctl reload nginx
☁️ Cloudflare DNS API
# Cloudflare 作为 DNS 的优势
# 1. 免费 CDN + DDoS 防护
# 2. API 管理 DNS 记录
# 3. DNS challenge 自动验证
# 4. 缓存规则自定义
# 用 Terraform 管理 Cloudflare DNS
resource "cloudflare_record" "app" {
zone_id = var.cloudflare_zone_id
name = "app"
value = digitalocean_droplet.main.ipv4_address
type = "A"
proxied = true # 开启 Cloudflare 代理
ttl = 1 # 自动 TTL
}
resource "cloudflare_record" "api" {
zone_id = var.cloudflare_zone_id
name = "api"
value = digitalocean_droplet.main.ipv4_address
type = "A"
proxied = false # API 不走 CDN(延迟敏感)
}
# Cloudflare SSL 设置
resource "cloudflare_zone_settings_override" "ssl" {
zone_id = var.cloudflare_zone_id
settings {
ssl_mode = "full_strict" # 端到端加密
always_use_https = "on"
automatic_https_rewrites = "on"
min_tls_version = "1.2"
}
}
# Cloudflare Page Rules(强制 HTTPS)
resource "cloudflare_page_rule" "https" {
zone_id = var.cloudflare_zone_id
target = "http://*.${var.domain}/*"
actions {
ssl = "flexible"
always_use_https = true
}
}
🌐 多域名管理
# 多域名架构示例
# 主域名: example.com
# 子域名分配:
app.example.com → 主应用 (Next.js)
api.example.com → API (FastAPI)
docs.example.com → 文档 (Docusaurus)
status.example.com → 状态页 (Uptime Kuma)
admin.example.com → 管理后台
db.example.com → 数据库管理 (Adminer)
# 第二域名: project.io
project.io → 开源项目官网
docs.project.io → 开源项目文档
# Traefik 路由规则
labels:
# 多域名路由
- "traefik.http.routers.app.rule=Host(`app.example.com`) || Host(`app.example.org`)"
# 基于路径的路由
- "traefik.http.routers.api.rule=Host(`example.com`) && PathPrefix(`/api/`)"
# 基于 Header 的路由(灰度发布)
- "traefik.http.routers.app-canary.rule=Host(`app.example.com`) && Header(`X-Canary`, `true`)"
🔑 通配符证书
# 通配符证书:一张证书覆盖所有子域名
# *.example.com → app.example.com, api.example.com, ...
# 方案 1: Traefik + Cloudflare DNS Challenge(推荐)
# docker-compose.yml
services:
traefik:
command:
- "--certificatesresolvers.cloudflare.acme.dnschallenge=true"
- "--certificatesresolvers.cloudflare.acme.dnschallenge.provider=cloudflare"
environment:
CF_DNS_API_TOKEN: ${CLOUDFLARE_API_TOKEN}
# 使用通配符证书
app:
labels:
- "traefik.http.routers.app.rule=Host(`app.example.com`)"
- "traefik.http.routers.app.tls.certresolver=cloudflare"
- "traefik.http.routers.app.tls.domains[0].main=example.com"
- "traefik.http.routers.app.tls.domains[0].sans=*.example.com"
# 方案 2: Certbot + Cloudflare
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
-d "*.example.com" -d "example.com" \
--server https://acme-v02.api.letsencrypt.org/directory
# ⚠️ 注意
# Let's Encrypt 通配符证书只支持 DNS-01 验证
# 不支持 HTTP-01 验证
# 证书有效期 90 天,需要自动续签
💡 SSL 最佳实践
1. 永远开启 HSTS(HTTP Strict Transport Security)2. 使用 full_strict 模式(Cloudflare 到源站也加密)3. 证书自动续签比手动管理更重要 4. 通配符证书减少证书数量,但 DNS challenge 配置更复杂 5. 不要把证书文件提交到 Git——Let's Encrypt 证书可以随时重新获取。
🔗 相关专题
🐳 Docker Compose · 🏗️ Terraform · 🛡️ 服务器加固 · 🏗️ 返回首页