> 免费SSL证书申请与Nginx配置:Let's Encrypt实战

为什么必须上HTTPS

2026年了,网站还在用HTTP?浏览器会直接标记为"不安全",搜索引擎也会降低排名。好消息是,Let’s Encrypt提供完全免费的SSL证书,配置过程也不复杂。

我所有的网站都用Let’s Encrypt,从来没花过一分钱在SSL证书上。

前提条件

在开始之前,确保:

条件说明
域名已解析A记录指向服务器IP
Nginx已安装参考Nginx安装教程
80端口已开放Let’s Encrypt需要通过80端口验证
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 检查域名解析是否生效
$ dig example.com +short
203.0.113.10  # 应该显示你的服务器IP

# 检查Nginx状态
$ sudo systemctl status nginx
● nginx.service - A high performance web server
     Active: active (running)

# 检查防火墙
$ sudo ufw status
80/tcp                     ALLOW       Anywhere
443/tcp                    ALLOW       Anywhere

安装Certbot

Certbot是Let’s Encrypt官方推荐的证书管理工具。

Ubuntu 22.04 / Debian

1
2
3
4
5
$ sudo apt update
$ sudo apt install -y certbot python3-certbot-nginx
Reading package lists... Done
Setting up certbot (2.1.0-2) ...
Setting up python3-certbot-nginx (2.0.0-1) ...

CentOS / Rocky Linux

1
2
$ sudo dnf install -y epel-release
$ sudo dnf install -y certbot python3-certbot-nginx

申请证书(自动模式)

Certbot的Nginx插件可以自动完成证书申请和Nginx配置修改:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$ sudo certbot --nginx -d example.com -d www.example.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for example.com and www.example.com

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/example.com/privkey.pem
This certificate expires on 2026-04-30.

Deploying certificate
Successfully deployed certificate for example.com to /etc/nginx/sites-enabled/mysite
Successfully deployed certificate for www.example.com to /etc/nginx/sites-enabled/mysite

Certbot会自动修改你的Nginx配置,添加SSL相关配置。

手动配置Nginx HTTPS

如果你想自己控制Nginx配置,可以只申请证书不自动配置:

1
2
# 只申请证书
$ sudo certbot certonly --nginx -d example.com -d www.example.com

然后手动配置Nginx:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# /etc/nginx/sites-available/mysite
server {
    listen 80;
    server_name example.com www.example.com;
    # HTTP自动跳转HTTPS
    return 301 https://$server_name$request_uri;
}

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

    # SSL证书
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # SSL安全配置
    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;

    # HSTS(强制HTTPS,建议在确认没问题后开启)
    add_header Strict-Transport-Security "max-age=63072000" always;

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;

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

    location / {
        try_files $uri $uri/ =404;
    }
}
1
2
3
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
$ sudo systemctl reload nginx

SSL安全配置参考

配置项推荐值说明
ssl_protocolsTLSv1.2 TLSv1.3禁用旧协议
ssl_ciphersMozilla推荐配置安全的加密套件
ssl_session_cacheshared:SSL:10m减少SSL握手开销
ssl_session_timeout1dSession缓存时间
HSTSmax-age=63072000强制浏览器使用HTTPS
OCSP Staplingon加速证书验证

自动续期

Let’s Encrypt证书有效期只有90天,但Certbot会自动设置续期:

1
2
3
4
5
6
7
# 测试自动续期是否正常
$ sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Processing /etc/letsencrypt/renewal/example.com.conf
Simulating renewal of an existing certificate for example.com and www.example.com
Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/example.com/fullchain.pem (success)
1
2
3
4
5
6
7
# 查看Certbot的自动续期定时任务
$ systemctl list-timers | grep certbot
Mon 2026-02-02 04:23:00 UTC  certbot.timer  certbot.service

# 或者查看crontab
$ cat /etc/cron.d/certbot
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew

手动设置续期

如果自动续期没有设置,手动添加:

1
2
3
$ sudo crontab -e
# 每天凌晨2点检查并续期
0 2 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx"

验证SSL配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 测试HTTPS是否正常
$ curl -I https://example.com
HTTP/2 200
server: nginx/1.18.0 (Ubuntu)
strict-transport-security: max-age=63072000
content-type: text/html

# 检查证书信息
$ echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
notBefore=Jan 30 00:00:00 2026 GMT
notAfter=Apr 30 23:59:59 2026 GMT

# 检查HTTP到HTTPS跳转
$ curl -I http://example.com
HTTP/1.1 301 Moved Permanently
Location: https://example.com/

通配符证书

如果你有多个子域名,可以申请通配符证书:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 通配符证书需要DNS验证
$ sudo certbot certonly --manual --preferred-challenges dns \
  -d example.com -d "*.example.com"

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

# 去DNS控制面板添加TXT记录后按回车确认

多站点证书管理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 查看所有已申请的证书
$ sudo certbot certificates
Found the following certs:
  Certificate Name: example.com
    Serial Number: 1234567890abcdef
    Key Type: RSA
    Domains: example.com www.example.com
    Expiry Date: 2026-04-30 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/example.com/privkey.pem

  Certificate Name: blog.example.com
    Domains: blog.example.com
    Expiry Date: 2026-05-15 (VALID: 104 days)

常见问题

Challenge failed

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 错误:验证域名失败
# 原因1:DNS还没生效
$ dig example.com +short
# 确保返回的是你的服务器IP

# 原因2:80端口被占或被防火墙挡
$ sudo ufw allow 80/tcp
$ ss -tlnp | grep :80

# 原因3:Nginx配置问题
$ sudo nginx -t

证书过期了

1
2
3
4
5
# 手动续期
$ sudo certbot renew
# 如果失败,强制续期
$ sudo certbot renew --force-renewal
$ sudo systemctl reload nginx

总结

HTTPS配置一共三步:安装Certbot、申请证书、配置Nginx。整个过程不到10分钟。Let’s Encrypt免费又好用,没有理由不上HTTPS。

配置完SSL后,建议去SSL Labs测试一下你的SSL评分,争取拿到A+。

Nginx基础配置可以回顾Nginx安装与配置入门。如果你还要配置反向代理,可以看Nginx反向代理配置详解

SSL HTTPS Let's Encrypt Nginx
cd ..