HTTPS / SSL Certificates in Practice
Free DV certs, Letsencrypt automation, wildcard vs multi-domain, and the exact Nginx/Traefik/Docker configs to install and rotate them.
Certificate types and what to buy vs get free
| Type | Validation | Price feel | Use |
|---|---|---|---|
| DV (Domain Validation) | 验证域名所有权(DNS/文件) | 免费(Let's Encrypt/云厂商免费版) | 个人站、内部系统、绝大多数 API |
| OV (Organization) | 验证企业真实身份(人工) | 数百元/年 | 企业官网、需展示公司名 |
| EV (Extended) | 最严格企业验证 + 浏览器历史显示组织名 | 数千元/年 | 金融、支付、高信任场景 |
| Wildcard (*.example.com) | 保护一级子域名 | 云厂商免费额度常不含 | 子域名多 / 微服务平台 |
| Multi-domain (SAN) | 一张证书保护多个域名 | 按域名数计费 | 多品牌/多站点合并 |
- Five clouds each offer free DV certs (Tencent/Alibaba: 1-year per domain, or 3-month renewable; Huawei/Baidu similar) — apply in the console, one click to push to their CDN/SLB
- Self-hosted → Letsencrypt with certbot/acme.sh: 90-day certs, fully automatable via HTTP-01 or DNS-01
- DNS-01 works even when port 80 is closed or behind strict firewalls — perfect for internal services and wildcard certs
acme.sh with DNS-01: automatic wildcard certs
# 以腾讯云 DNS 为例(其他服务商换成对应 dnsapi)
curl https://get.acme.sh | sh -s email=me@example.com
# 配置 DNS API 密钥(控制台建子账号只给 DNS 权限)
export Tencent_SecretId="AKIDxxxxx"
export Tencent_SecretKey="xxxxxxxxxxxx"
# 签发泛域名证书(DNS-01)
~/.acme.sh/acme.sh --issue --dns dns_tencent -d example.com -d '*.example.com' --keylength ec-256
# 安装到 Nginx 并自动 reload:续期后自动生效
~/.acme.sh/acme.sh --install-cert -d example.com --ecc \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--reloadcmd "systemctl reload nginx"
Cert renewal does not fail loudly by default. Point acme.sh notifications at yourself (--notify-hook), and put a synthetic check on your monitoring: curl the HTTPS endpoint daily and alarm when the certificate is valid for less than 14 days.
Nginx / Traefik / Docker configs
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
add_header Strict-Transport-Security "max-age=31536000" always;
}
# 80 强制跳 443
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
# Traefik(Docker 标签自动申请+续期)
services:
traefik:
image: traefik:v3
command:
- --certificatesresolvers.le.acme.email=me@example.com
- --certificatesresolvers.le.acme.storage=/acme.json
- --certificatesresolvers.le.acme.dnschallenge.provider=tencentcloud
environment:
TENCENTCLOUD_SECRET_ID: ${SECRET_ID}
TENCENTCLOUD_SECRET_KEY: ${SECRET_KEY}
api:
labels:
- traefik.http.routers.api.rule=Host(`api.example.com`)
- traefik.http.routers.api.tls=true
- traefik.http.routers.api.tls.certresolver=le
- traefik.http.routers.api.tls.domains[0].main=example.com
- traefik.http.routers.api.tls.domains[0].sans=api.example.com
- TLSv1.0/1.1 are dead — disable them; PCI and modern browsers reject them anyway
- HSTS pins HTTPS for a year per browser — make sure every subdomain is HTTPS-ready before raising max-age
- Keep intermediate certs: a 'certificate not trusted' error on some devices is almost always a missing intermediate chain in fullchain.pem
证书类型与「哪些该买、哪些白嫖」
| 类型 | 验证方式 | 价格手感 | 用途 |
|---|---|---|---|
| DV (Domain Validation) | 验证域名所有权(DNS/文件) | 免费(Let's Encrypt/云厂商免费版) | 个人站、内部系统、绝大多数 API |
| OV (Organization) | 验证企业真实身份(人工) | 数百元/年 | 企业官网、需展示公司名 |
| EV (Extended) | 最严格企业验证 + 浏览器历史显示组织名 | 数千元/年 | 金融、支付、高信任场景 |
| Wildcard (*.example.com) | 保护一级子域名 | 云厂商免费额度常不含 | 子域名多 / 微服务平台 |
| Multi-domain (SAN) | 一张证书保护多个域名 | 按域名数计费 | 多品牌/多站点合并 |
- 五家云都提供免费 DV 证书(腾讯/阿里:每域名 1 年或 3 个月可续;华为/百度类似)——控制台申请,一键下发到自家 CDN/负载均衡
- 自托管 → Letsencrypt 配 certbot/acme.sh:90 天证书,HTTP-01 或 DNS-01 全自动续期
- DNS-01 即使 80 端口关闭或防火墙严格也能签发——最适合内部服务和泛域名证书
acme.sh + DNS-01:全自动泛域名证书
# 以腾讯云 DNS 为例(其他服务商换成对应 dnsapi)
curl https://get.acme.sh | sh -s email=me@example.com
# 配置 DNS API 密钥(控制台建子账号只给 DNS 权限)
export Tencent_SecretId="AKIDxxxxx"
export Tencent_SecretKey="xxxxxxxxxxxx"
# 签发泛域名证书(DNS-01)
~/.acme.sh/acme.sh --issue --dns dns_tencent -d example.com -d '*.example.com' --keylength ec-256
# 安装到 Nginx 并自动 reload:续期后自动生效
~/.acme.sh/acme.sh --install-cert -d example.com --ecc \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--reloadcmd "systemctl reload nginx"
证书续期失败默认不会大声叫。给 acme.sh 配通知钩子(--notify-hook),并在监控里加一条主动检查:每天 curl HTTPS 端点,剩余有效期不足 14 天就告警。
Nginx / Traefik / Docker 配置
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
add_header Strict-Transport-Security "max-age=31536000" always;
}
# 80 强制跳 443
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
# Traefik(Docker 标签自动申请+续期)
services:
traefik:
image: traefik:v3
command:
- --certificatesresolvers.le.acme.email=me@example.com
- --certificatesresolvers.le.acme.storage=/acme.json
- --certificatesresolvers.le.acme.dnschallenge.provider=tencentcloud
environment:
TENCENTCLOUD_SECRET_ID: ${SECRET_ID}
TENCENTCLOUD_SECRET_KEY: ${SECRET_KEY}
api:
labels:
- traefik.http.routers.api.rule=Host(`api.example.com`)
- traefik.http.routers.api.tls=true
- traefik.http.routers.api.tls.certresolver=le
- traefik.http.routers.api.tls.domains[0].main=example.com
- traefik.http.routers.api.tls.domains[0].sans=api.example.com
- TLSv1.0/1.1 已死——直接禁用,反正 PCI 规范和现代浏览器都拒绝了
- HSTS 会在浏览器里钉住 HTTPS 一年——提高 max-age 前确认所有子域名都已支持 HTTPS
- 保留中间证书:某些设备报「证书不可信」几乎都是 fullchain.pem 缺中间证书链