13 10 月 2026

现在网站不上 HTTPS,浏览器会直接标"不安全",SEO 也会被降权,部分 API(摄像头、地理位置)在非 HTTPS 下根本用不了。

好消息是:证书早就免费了。这篇讲用 Let's Encrypt 申请免费证书、配置 Nginx、设置自动续期的完整流程。

需要一台带独立公网 IP 的服务器来部署对外网站?财富云计算 提供云服务器;做内网服务、测试环境可选 NAT 型(无独立公网 IP,价格比独立 IP 机型省一半以上)。

一、HTTPS 与证书的常识

三个概念

  • HTTP:明文传输,中间人能看到也改得了内容
  • HTTPS:HTTP + TLS 加密,防窃听、防篡改、验证身份
  • SSL/TLS 证书:由可信机构(CA)签发,证明"这个域名确实属于你"

严格说现在用的都是 TLS,但习惯上还叫 SSL 证书。

证书类型

类型验证内容签发速度适用
DV(域名验证)只验证域名控制权几分钟个人站、博客、API
OV(组织验证)验证企业身份数天企业官网
EV(扩展验证)严格验证数周金融、电商

Let's Encrypt 提供的是 DV 证书,免费、自动化、90 天有效期。 对个人和绝大多数网站完全够用。

为什么是 90 天

刻意设计:短有效期 + 强制自动续期,比长证书更安全(私钥泄露影响窗口小、促使运维自动化)。所以必须配自动续期。


二、申请前准备

  1. 域名已解析到服务器 IP:证书签发时要验证你对域名的控制权

    ping example.com       # 确认解析到了你的服务器
  2. 80 端口可访问(HTTP-01 验证方式需要)

    • 防火墙放行 80
    • 云平台安全组放行 80
    • 国内服务器注意:如果域名没备案,80/443 可能被阻断,需要用 DNS-01 方式
  3. Nginx 已安装并运行

三、安装 Certbot

Ubuntu / Debian

apt update
apt install certbot python3-certbot-nginx -y
certbot --version

CentOS / Rocky

yum install epel-release -y
yum install certbot python3-certbot-nginx -y

或者用 snap(版本最新)

snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot

四、申请证书(Nginx 插件方式,最省事)

前提:已有 Nginx 站点配置且 server_name 写对了域名。

certbot --nginx -d example.com -d www.example.com

交互式流程:

Enter email address (used for urgent renewal): you@example.com
Please read the Terms of Service...
(A)gree/(C)ancel: A
Would you like to share your email...: N
Which server blocks would you like to modify? → 选你的站点
Please choose whether to redirect HTTP traffic to HTTPS: 2 (强制跳转)

完成后 Certbot 会自动修改 Nginx 配置并 reload。检查:

systemctl status nginx
curl -I https://example.com

证书存放位置:

/etc/letsencrypt/live/example.com/
├── cert.pem         # 域名证书
├── chain.pem        # 中间证书
├── fullchain.pem    # cert + chain(Nginx 用这个)
└── privkey.pem      # 私钥(绝不能泄露)

五、只申请证书,不改配置(certonly)

想自己控制 Nginx 配置时用这个:

# 方式一:webroot(推荐,不用停服务)
certbot certonly --webroot -w /var/www/mysite -d example.com -d www.example.com

# 方式二:standalone(临时占用 80 端口,需要先停 nginx)
systemctl stop nginx
certbot certonly --standalone -d example.com
systemctl start nginx

然后自己写配置:

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;

    root /var/www/mysite;
    index index.html index.php;
}

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}
nginx -t && systemctl reload nginx

六、通配符证书(DNS-01 验证)

要签 *.example.com 这种通配符,必须用 DNS 验证:

certbot certonly --manual --preferred-challenges dns \
  -d example.com -d "*.example.com"

它会让你添加一条 TXT 记录:

Please deploy a DNS TXT record under the name:
_acme-challenge.example.com
with the following value:
AbCdEf123456...

去域名解析后台添加,等待生效后回车。

验证解析是否生效:

dig -t txt _acme-challenge.example.com +short
# 或
nslookup -type=txt _acme-challenge.example.com
通配符证书无法自动续期(除非用支持 API 的 DNS 插件),因为每次都要手动改 DNS。非必要不建议用。

如果你的 DNS 服务商支持 API(阿里云、腾讯云、Cloudflare 等),可以装对应插件实现自动续期:

# 例如 Cloudflare
apt install python3-certbot-dns-cloudflare
# 配置凭据后
certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.cf.ini -d "*.example.com"

七、自动续期(必须做)

Let's Encrypt 证书 90 天过期。Certbot 安装时通常会自带定时任务,先确认:

systemctl list-timers | grep certbot
# 或者
cat /etc/cron.d/certbot
ls /etc/systemd/system/certbot.timer

手动测试续期(不会真的续,只做演练):

certbot renew --dry-run

看到 "Congratulations, all simulated renewals succeeded" 就说明配置正确。

手动立即续期:

certbot renew
systemctl reload nginx

自己加 crontab(如果没有自带):

crontab -e
# 每天凌晨 3 点检查,证书剩余 30 天内才续
0 3 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx"

--deploy-hook 只在真正续期成功后才执行 reload,比直接 reload 更合理。

查看证书到期时间:

certbot certificates
# 或
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -dates
# 或用 openssl 看域名
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates

八、HTTPS 配置优化

一份完整的现代配置

server {
    listen 443 ssl;
    http2 on;                          # Nginx 1.25.1+ 写法
    server_name example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;

    # 协议
    ssl_protocols TLSv1.2 TLSv1.3;     # 禁用 TLS 1.0/1.1(已不安全)
    ssl_prefer_server_ciphers off;

    # 会话复用
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # HSTS:强制浏览器后续都用 HTTPS(谨慎,先小范围测试)
    add_header Strict-Transport-Security "max-age=63072000" always;

    # 安全头
    add_header X-Content-Type-Options nosniff always;
    add_header X-Frame-Options SAMEORIGIN always;

    # OCSP Stapling(加快握手)
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 1.1.1.1 valid=300s;
    resolver_timeout 5s;

    root /var/www/mysite;
    index index.html;
}
⚠️ HSTS 要小心:一旦浏览器记住了 max-age,在有效期内你的站点必须一直可用 HTTPS,否则用户会被彻底挡在外面。建议先用小值(如 300 秒)测试,确认没问题再加大。

在线检测

配完去 SSL Labs 测一下,目标是 A 或 A+。


九、常见问题

1)Connection refused during challenge

80 端口不通。检查:

ss -tulnp | grep :80
ufw status
# 云控制台安全组

2)Timeout during connect

域名解析没生效,或解析到了别的 IP:

dig example.com +short
curl -I http://example.com

3)unauthorized :: Invalid response

Nginx 配置的 server_name 与申请的域名不一致,或者 certbot --nginx 没能正确识别站点。改用 --webroot 方式。

4)国内服务器 80 端口被阻断

未备案域名无法用 HTTP-01 验证。解决:

  • 先完成备案再用 80 端口验证
  • 或用 DNS-01 方式(不需要 80 端口,但域名本身要能访问另说)
  • 或使用云厂商提供的免费证书(通常支持 DNS 验证)

5)Too many certificates already issued

Let's Encrypt 有速率限制:每个域名每周最多 50 张证书,重复申请(相同的域名集合)每周 5 次。

调试阶段请务必加 --dry-run(用测试环境签发,不计入限额)。

6)续期后证书没更新

certbot renew --force-renewal      # 强制续
systemctl reload nginx             # 别忘 reload

7)多站点共用证书

一个证书可以包含多个域名(SAN):

certbot --nginx -d a.com -d b.com -d c.com

或每个站点单独申请(更灵活,推荐)。


十、其他免费证书渠道

渠道有效期特点
Let's Encrypt90 天最主流,自动化程度高
ZeroSSL90 天支持 Web 面板管理,certbot 也支持
云厂商免费证书通常 1 年阿里云/腾讯云各有 20 张免费 DV,适合国内业务
Buypass Go SSL180 天挪威 CA,支持 ACME

云厂商的免费证书适合国内已备案业务(签发快、中文支持、可下载部署到非本平台服务器)。


十一、证书安全检查清单

  • [ ] 私钥文件权限 600,不上传代码仓库
  • [ ] 禁用 TLS 1.0 / 1.1
  • [ ] 开启 HTTP → HTTPS 301 跳转
  • [ ] 自动续期已配置并做过 --dry-run 测试
  • [ ] 有到期监控(证书到期前告警)
  • [ ] SSL Labs 评分达到 A 级以上
  • [ ] 站内资源(图片、JS、CSS)也都是 HTTPS(否则会有"混合内容"警告)

检查混合内容:打开网站按 F12 看 Console,有 Mixed Content 警告说明还有 HTTP 资源,通常是文章里的旧图片链接。


十二、一句话总结流程

# 1. 装工具
apt install certbot python3-certbot-nginx -y

# 2. 申请(自动改配置)
certbot --nginx -d example.com -d www.example.com

# 3. 验证续期
certbot renew --dry-run

# 4. 确认定时任务存在
systemctl list-timers | grep certbot

# 5. 在线检测
# https://www.ssllabs.com/ssltest/

部署对外网站需要带独立公网 IP 的云服务器,财富云计算 提供多种配置可选;如果只是做内网服务、测试环境、游戏服务端,NAT 型云服务器(无独立公网 IP)价格比独立 IP 机型省一半以上,性价比更高。

相关阅读:

  • 《Nginx 安装与配置入门》
  • 《Nginx 反向代理与多站点配置》
  • 《域名解析与 DNS 记录详解》
延伸阅读
  1. 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
  2. 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
  3. 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
  4. 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
  5. 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
  6. RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
  7. 短链接服务搭建:Shlink 自托管,链接数据自己掌握
  8. 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道
更多阅读
  1. 上一篇:Nginx 安装与配置入门:从零搭建一个能访问的网站
  2. 下一篇:Nginx 反向代理与多站点配置:一台服务器跑十个网站
发表评论 17

取消回复