Ray's Blog

Nginx 获取免费 HTTPS 证书方法记录

1. 前置检查 (Pre-requisites)

在执行任何命令前,请确保满足以下条件,否则后续步骤必败:

  1. 域名解析

    :域名(如

    example.com
    

    )必须已 A 记录解析到当前服务器的公网 IP。

    • 验证命令:ping example.comdig example.com
  2. 端口开放

    服务器防火墙及云服务商安全组必须放行 TCP 80 和 TCP 443。

    • Ubuntu (UFW): sudo ufw allow 'Nginx Full'
    • CentOS (Firewalld): sudo firewall-cmd --permanent --add-service=http && sudo firewall-cmd --permanent --add-service=https && sudo firewall-cmd --reload
  3. Nginx 运行中

    :确保 Nginx 正在监听 80 端口。

    • 验证命令:sudo systemctl status nginx

2. 安装 Certbot

Certbot 是 Let’s Encrypt 的官方客户端,能自动处理证书申请和部分 Nginx 配置。

Ubuntu / Debian

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

CentOS / RHEL / Rocky Linux

# 安装 EPEL 源 (如果未安装)
sudo yum install epel-release -y
# 安装 Certbot 及 Nginx 插件
sudo yum install certbot python3-certbot-nginx -y

3. 获取证书并配置 (核心步骤)

方法 A:全自动模式 (推荐首选)

尝试让 Certbot 自动修改 Nginx 配置。

sudo certbot --nginx -d your_domain.com -d www.your_domain.com
  • 交互提示

    1. 输入邮箱(用于过期提醒)。
    2. 同意条款。
    3. 重定向选择:选择 2: Redirect (强制 HTTP 跳转 HTTPS)。

⚠️ 常见错误处理:Could not automatically find a matching server block

如果运行上述命令报错:

Could not automatically find a matching server block for your_domain.com. Set the server_name directive to use the Nginx installer.

原因:Certbot 在 Nginx 配置文件中找不到包含该域名的 server_name 指令。 解决方案

  1. 查找配置文件

    sudo grep -r "your_domain.com" /etc/nginx/
    
    • 若未找到:说明你还没为该域名创建 Nginx 配置。需先创建一个基础的 HTTP 配置(见下文“附录:基础 Nginx 配置模板”)。
    • 若找到文件路径(如 /etc/nginx/conf.d/blog.conf):编辑该文件。
  2. 手动修正配置

    sudo nano /etc/nginx/conf.d/你的配置文件名.conf
    

    确保 server 块中包含正确的 server_name

    server {
        listen 80;
        server_name your_domain.com www.your_domain.com; # 必须包含此行
        root /var/www/your_site_path;
        # ...其他配置
    }
    
  3. 测试并重试

    sudo nginx -t               # 测试语法
    sudo systemctl reload nginx # 重载配置
    sudo certbot --nginx -d your_domain.com -d www.your_domain.com # 再次运行
    

方法 B:半自动模式 (当方法 A 始终失败时)

如果自动插件无法工作,可以手动申请证书,然后手动修改 Nginx。

  1. 仅申请证书 (不修改 Nginx): 使用 --webroot 模式(需指定网站根目录):

    # 将 /var/www/html 替换为你实际的网站根目录
    sudo certbot certonly --webroot -w /var/www/html -d your_domain.com -d www.your_domain.com
    

    成功后,证书位于 /etc/letsencrypt/live/your_domain.com/

  2. 手动修改 Nginx 配置: 编辑你的站点配置文件,添加 SSL 部分:

    server {
        listen 443 ssl http2;
        server_name your_domain.com www.your_domain.com;
    
        # 证书路径 (certbot 自动生成)
        ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;
    
        # 推荐的安全配置
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        ssl_ciphers HIGH:!aNULL:!MD5;
    
        root /var/www/your_site_path;
        index index.html index.php;
    
        # ... 其他原有配置 ...
    }
    
    # 强制 HTTP 跳转 HTTPS
    server {
        listen 80;
        server_name your_domain.com www.your_domain.com;
        return 301 https://$host$request_uri;
    }
    
  3. 重启 Nginx

    sudo nginx -t
    sudo systemctl reload nginx
    

4. 验证与自动续期

验证配置

  1. 本地测试:浏览器访问 https://your_domain.com,查看是否有小锁图标。
  2. 在线检测:访问 SSL Labs 输入域名进行评分(目标 A 或 A+)。

自动续期 (至关重要)

Let’s Encrypt 证书有效期为 90 天。Certbot 安装时会自动创建定时任务(systemd timer 或 cron)。

  1. 检查定时任务状态

    sudo systemctl status certbot.timer
    

    应显示 active (waiting)

  2. 手动测试续期流程 (不会真正续期,除非快过期,但会跑一遍逻辑):

    sudo certbot renew --dry-run
    

    若输出 Congratulations, all renewals succeeded,则自动续期正常。


附录:基础 Nginx 配置模板

如果你是因为没有配置文件导致报错,请先创建 /etc/nginx/conf.d/your_domain.conf

server {
    listen 80;
    server_name your_domain.com www.your_domain.com;
    
    root /var/www/your_site_path; # 修改为你的实际路径
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}

创建后执行 sudo nginx -tsudo systemctl reload nginx,然后再运行 Certbot。


故障排查速查表 (Troubleshooting)

错误现象可能原因解决方案
Could not find matching server blockNginx 配置缺 server_name手动编辑 conf 文件添加 server_name 域名;
Failed authorization procedure... Connection refused80 端口被防火墙拦截检查云服务器安全组和本地防火墙 (ufw/firewalld)
Port 80 is already in use其他程序占用 80 端口sudo lsof -i :80 查找占用进程并停止,或暂时停止 Nginx 用 standalone 模式
Certificate not yet due for renewal证书未快过期正常现象,renew 命令只在过期前 30 天内生效。测试请用 --dry-run