在 Ubuntu 上为 Nginx 配置 Let's Encrypt 免费 SSL 证书

本教程将详细介绍如何在 Ubuntu 服务器上,使用 Certbot 工具为 Nginx Web 服务器获取免费的 Let's Encrypt SSL/TLS 证书,并配置证书自动续期,从而轻松启用 HTTPS 加密。

阅读时长: 4 分钟
共 1976字
作者: eimoon.com

给网站加上 HTTPS 已经不是什么新鲜事了,现在基本是标配。好在有 Let’s Encrypt 这样的免费证书颁发机构,以及 Certbot 这样的自动化工具,让整个过程变得非常简单。

今天我们就来完整走一遍,如何在 Ubuntu 服务器上,用 Certbot 给 Nginx 站点配上免费的 SSL 证书,并且让它自动续期,一劳永逸。

准备工作

在开始之前,确保你手头有这些东西:

  1. 一台 Ubuntu 服务器:已经完成了基础设置,包括一个有 sudo 权限的非 root 用户和防火墙。
  2. 一个域名:你得拥有一个域名,并且已经设置好 DNS 解析。本文会用 example.com 作为例子。
  3. DNS A 记录
    • 一条 A 记录,让 example.com 指向你服务器的公网 IP 地址。
    • 另一条 A 记录,让 www.example.com 也指向同一个 IP 地址。
  4. Nginx 已安装:服务器上需要装好 Nginx,并且为你的域名配置好了一个 server block。如果你还没做,可以参考 Nginx 的安装教程。

第一步:安装 Certbot

Certbot 官方现在主推用 snap 来安装,因为它更新最快,能及时跟上 Let’s Encrypt 的变化。Ubuntu 默认就带着 snapd,所以我们直接用就行。

首先,确保 snapd 核心组件是最新版本:

sudo snap install core; sudo snap refresh core

如果你的服务器上之前可能装过旧版的 Certbot (通过 apt 安装的),最好先卸载掉,免得冲突:

sudo apt remove certbot

接着,通过 snap 安装 Certbot:

sudo snap install --classic certbot

最后,创建一个符号链接,这样我们就可以直接在命令行里使用 certbot 命令了:

sudo ln -s /snap/bin/certbot /usr/bin/certbot

备选方案:使用 APT 如果你的环境不支持 snap,也可以用 apt 来安装,只是版本可能会旧一些: sudo apt update sudo apt install -y certbot python3-certbot-nginx

第二步:检查 Nginx 配置

Certbot 这家伙很聪明,它会自动扫描你的 Nginx 配置文件,找到匹配你申请域名的 server 块,然后把 SSL 相关的配置写进去。所以,咱们得先确保 Nginx 配置里 server_name 写对了。

打开你为域名准备的 Nginx 配置文件,通常在 /etc/nginx/sites-available/ 目录下:

sudo nano /etc/nginx/sites-available/example.com

找到 server_name 这一行,确认它包含了你的域名和 www 子域名:

...
server_name example.com www.example.com;
...

如果没问题,直接退出编辑器。如果有修改,保存文件后,记得检查一下配置语法有没有错误,然后重新加载 Nginx 服务。

sudo nginx -t
sudo systemctl reload nginx

只要 nginx -t 命令显示 syntax is oktest is successful,就说明配置没问题。这步主要是为了确保 Certbot 再后面能正确找到你的配置。

第三步:配置防火墙

如果你的服务器开了 ufw 防火墙(推荐这么做),那得给 HTTPS 流量放行。Nginx 在安装时已经贴心地为我们准备好了 ufw 配置文件。

先看看当前的防火墙状态:

sudo ufw status

你可能会看到类似下面的输出,只允许了 “Nginx HTTP”:

Output
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx HTTP                 ALLOW       Anywhere
...

我们需要允许 “Nginx Full” 这个配置,它同时包含了 HTTP (80端口) 和 HTTPS (443端口) 的流量。然后可以把只允许 HTTP 的规则删掉。

sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'

现在再看状态,应该就是 “Nginx Full” 了:

sudo ufw status
Output
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx Full                 ALLOW       Anywhere
...

防火墙搞定,可以去申请证书了。

第四步:获取 SSL 证书

激动人心的时刻到了。一条命令搞定证书申请、下载和自动配置。

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

这里解释一下:

  • --nginx:告诉 Certbot 使用 Nginx 插件,它会自动修改 Nginx 配置。
  • -d:后面跟着你要申请证书的域名,可以有多个。

运行命令后,Certbot 会跟你进行一些交互:

  1. 输入你的邮箱地址,用于接收续期提醒和安全通知。
  2. 同意 Let’s Encrypt 的服务条款。

一切顺利的话,你会看到一条成功信息,告诉你证书已经成功获取并安装,还说明了证书文件的存放位置。

Output
IMPORTANT NOTES:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/your_domain/fullchain.pem
Key is saved at: /etc/letsencrypt/live/your_domain/privkey.pem
This certificate expires on 2025-XX-XX.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
...

现在,刷新你的网站,应该就能看到地址栏的小锁标志了,表示网站已经成功启用了 HTTPS。你还可以用 SSL Labs Server Test 这样的工具来检测一下,通常能拿到 A 级评分。

第五步:验证自动续期

Let’s Encrypt 的证书有效期只有 90 天,这么做是为了鼓励大家自动化续期。Certbot 已经帮我们把这事儿安排的明明白白了的。

通过 snap 安装的 Certbot 会创建一个 systemd timer,每天运行两次,检查有没有证书快要到期(通常是 30 天内),如果有就会自动续期。

你可以用下面的命令查看这个定时器的状态:

sudo systemctl status snap.certbot.renew.service

虽然我们可以相信它能正常工作,但最好还是手动模拟一次续期过程来确认一下。--dry-run 参数可以在不实际更改任何文件的情况下进行测试。

sudo certbot renew --dry-run

如果命令执行完没有报错,就说明自动续期机制是正常的。以后就不用再管它了,Certbot 会默默地在后台帮你搞定一切。如果续期失败,Let’s Encrypt 会给你之前留的邮箱发邮件告警。

进阶配置:强化 HTTPS 安全性

拿到证书只是第一步,我们还可以进一步强化 Nginx 的 TLS 配置来提高安全性。

打开被 Certbot 修改过的 Nginx 配置文件,在 server 块的 listen 443 ssl 相关部分,可以加入以下配置:

  • 启用 HSTS (HTTP Strict Transport Security):强制浏览器只能通过 HTTPS 访问你的网站,防止降级攻击。

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    

    注意:preload 选项要谨慎开启,确保你的所有子域名都支持 HTTPS,否则可能导致它们无法访问。

  • 使用更安全的加密套件:禁用一些老旧且不安全的加密算法。可以从 Mozilla SSL Configuration Generator 获取推荐配置。

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
    

修改完配置后,别忘了检查语法并重新加载 Nginx。

sudo nginx -t
sudo systemctl reload nginx

至此,你的网站不仅用上了 HTTPS,而且安全配置也相当到位了。

关于

关注我获取更多资讯

公众号
📢 公众号
个人号
💬 个人号
使用 Hugo 构建
主题 StackJimmy 设计