🔒 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 · 🛡️ 服务器加固 · 🏗️ 返回首页