2026年3月5日

HTTPS 证书配置 - Let's Encrypt 免费证书指南

HTTPS 已成为网站标配,Let’s Encrypt 提供免费的 SSL 证书。本文介绍如何配置 HTTPS 证书。

HTTPS 简介

什么是 HTTPS

HTTPS(Hyper Text Transfer Protocol Secure)是 HTTP 的安全版本,通过 SSL/TLS 协议加密传输数据。

HTTPS 的好处

  • 数据加密传输
  • 防止数据篡改
  • 提升用户信任
  • SEO 排名提升
  • 支持 HTTP/2

证书类型

类型 验证方式 适用场景
DV 域名验证 个人网站、博客
OV 组织验证 企业网站
EV 扩展验证 金融、电商

Let’s Encrypt 简介

特点

  • 完全免费
  • 自动化申请
  • 90 天有效期
  • 支持通配符证书
  • 广泛信任

申请限制

  • 每周最多 50 张证书
  • 每周最多 5 次失败验证
  • 每个证书最多 100 个域名

Certbot 安装

Ubuntu/Debian

# 安装 Certbot
sudo apt update
sudo apt install certbot python3-certbot-nginx

# 或使用 snap
sudo snap install certbot --classic

CentOS/RHEL

# 安装 EPEL
sudo yum install epel-release

# 安装 Certbot
sudo yum install certbot python3-certbot-nginx

macOS

brew install certbot

Docker

docker run -it --rm --name certbot \
  -v "/etc/letsencrypt:/etc/letsencrypt" \
  -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
  certbot/certbot certonly

申请证书

Nginx 插件方式

# 自动配置 Nginx
sudo certbot --nginx

# 指定域名
sudo certbot --nginx -d example.com -d www.example.com

# 申请通配符证书
sudo certbot --nginx -d example.com -d "*.example.com"

Webroot 方式

# 指定网站根目录
sudo certbot certonly --webroot \
  -w /var/www/html \
  -d example.com \
  -d www.example.com

Standalone 方式

# 需要停止 Web 服务器
sudo systemctl stop nginx
sudo certbot certonly --standalone -d example.com
sudo systemctl start nginx

DNS 验证方式

# 通配符证书需要 DNS 验证
sudo certbot certonly --manual --preferred-challenges dns \
  -d example.com -d "*.example.com"

DNS 插件

# 阿里云 DNS
pip install certbot-dns-aliyun
sudo certbot certonly --authenticator dns-aliyun \
  --dns-aliyun-credentials /etc/letsencrypt/dns-aliyun.ini \
  -d example.com -d "*.example.com"

# Cloudflare
sudo apt install python3-certbot-dns-cloudflare
sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d example.com -d "*.example.com"

证书文件

文件位置

/etc/letsencrypt/
├── live/
│   └── example.com/
│       ├── cert.pem        # 证书
│       ├── chain.pem       # 中间证书
│       ├── fullchain.pem   # 完整证书链
│       └── privkey.pem     # 私钥
├── archive/
└── renewal/

文件说明

文件 说明
cert.pem 服务器证书
chain.pem 中间证书
fullchain.pem 完整证书链(推荐使用)
privkey.pem 私钥文件

Nginx 配置

基础 HTTPS 配置

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 ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;
    
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    
    root /var/www/html;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

# HTTP 重定向 HTTPS
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

SSL 优化配置

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;

完整配置示例

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

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 ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
    root /var/www/html;
    index index.html index.htm;
    
    location / {
        try_files $uri $uri/ =404;
    }
    
    location ~ /\.(?!well-known) {
        deny all;
    }
}

Apache 配置

<VirtualHost *:443>
    ServerName example.com
    DocumentRoot /var/www/html
    
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
    
    <Directory /var/www/html>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

<VirtualHost *:80>
    ServerName example.com
    Redirect permanent / https://example.com/
</VirtualHost>

自动续期

测试续期

# 测试续期(不实际执行)
sudo certbot renew --dry-run

自动续期

Certbot 会自动添加定时任务:

# 查看定时任务
systemctl list-timers | grep certbot

# 手动续期
sudo certbot renew

# 续期后重载 Nginx
sudo certbot renew --post-hook "systemctl reload nginx"

Cron 定时任务

# 编辑 crontab
sudo crontab -e

# 每天检查续期
0 3 * * * certbot renew --quiet --post-hook "systemctl reload nginx"

Systemd Timer

# /etc/systemd/system/certbot-renew.service
[Unit]
Description=Certbot Renew

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"
# /etc/systemd/system/certbot-renew.timer
[Unit]
Description=Certbot Renew Timer

[Timer]
OnCalendar=daily
RandomizedDelaySec=1h

[Install]
WantedBy=timers.target
sudo systemctl enable certbot-renew.timer
sudo systemctl start certbot-renew.timer

证书管理

查看证书

# 列出所有证书
sudo certbot certificates

# 查看证书详情
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -text -noout

# 检查证书有效期
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates

撤销证书

# 撤销证书
sudo certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem

# 撤销并删除
sudo certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem --delete-after-revoke

删除证书

# 删除证书
sudo certbot delete --cert-name example.com

常见问题

Q: 验证失败?

检查:

  1. 域名解析是否正确
  2. 80 端口是否可访问
  3. 防火墙是否放行

Q: 证书不被信任?

检查:

  1. 是否使用 fullchain.pem
  2. 中间证书是否正确
  3. 系统时间是否正确

Q: 自动续期失败?

检查:

  1. Cron/systemd 任务是否运行
  2. 80 端口是否可访问
  3. 日志中的错误信息

Q: 如何检查 SSL 配置?

使用 SSL Labs 测试:

https://www.ssllabs.com/ssltest/

其他证书方案

商业证书

  • DigiCert
  • GeoTrust
  • Comodo
  • GlobalSign

免费证书

  • Let’s Encrypt
  • ZeroSSL
  • SSL For Free

总结

HTTPS 配置要点:

  1. 使用 Let’s Encrypt 免费证书
  2. 配置 Nginx/Apache SSL
  3. 设置自动续期
  4. 优化 SSL 配置
  5. 定期检查证书状态

HTTPS 是网站安全的基础,建议所有网站都启用 HTTPS。