当前位置: 首页 > news >正文

Ubuntu 18.04 下 Nginx 配置 Let‘s Encrypt HTTPS 全流程指南

1. 为什么在 Ubuntu 18.04 上用 Let’s Encrypt 给 Nginx 加密,不是“可选项”,而是“必选项”

你刚在 Ubuntu 18.04 上配好一台 Nginx 服务器,绑了域名,首页能打开,心里一松——“成了”。
但只要它暴露在公网,哪怕只跑一个静态博客、一个内部管理后台、甚至只是个测试页,浏览器地址栏那个醒目的“不安全”提示,就已经在悄悄侵蚀你的可信度、用户留存率,甚至搜索引擎排名。这不是危言耸听:Chrome 从 2017 年起就对所有 HTTP 页面打标;Google 搜索算法明确将 HTTPS 作为排名信号;而现代前端框架(Vue、React)的 Service Worker、地理位置 API、通知权限等核心功能,强制要求运行在 HTTPS 环境下——HTTP 下直接报错、拒绝执行。

Let’s Encrypt 的出现,彻底打破了 HTTPS 的技术与成本壁垒。它不是“另一个商业证书提供商”,而是由互联网安全研究小组(ISRG)运营的非营利性证书颁发机构(CA),其核心价值在于:零费用、全自动化、开放可信。它的根证书已被所有主流操作系统和浏览器预置信任(包括 Ubuntu 18.04 自带的 ca-certificates 包),这意味着你申请的证书,用户打开网页时不会看到任何“证书不受信任”的红色警告——这是自签名证书永远无法跨越的鸿沟。

Ubuntu 18.04 这个版本在此场景中尤为关键。它虽已进入扩展维护阶段(EOL 为 2023 年 4 月),但仍是大量生产环境、遗留系统、嵌入式网关设备的稳定基线。它的软件源中默认包含certbot(Let’s Encrypt 官方客户端)的兼容版本(0.31.x),且内核、OpenSSL(1.1.1)、Python 3.6 等底层组件完全满足 ACME v2 协议通信要求。我见过太多人绕开 Ubuntu 18.04 原生方案,硬上 Docker 或手动编译新版本 Certbot,结果因 Python 依赖冲突、systemd 服务单元文件路径错位、或 OpenSSL 版本不匹配,卡在证书申请环节长达数小时——其实,官方路径最稳,原生集成最省心

这里必须点破一个常见误解:很多人以为“装了 Let’s Encrypt 就等于安全了”。错。Let’s Encrypt 只解决“传输层加密”这一个环节,即防止中间人窃听和篡改数据流。它不防 SQL 注入、不防 XSS 跨站脚本、不防暴力破解登录接口。但它是一道不可绕过的基础设施门槛——就像你不会在没装防盗门的情况下,先去研究怎么加固室内保险柜。本文要做的,就是帮你把这扇“防盗门”严丝合缝地装上,并让它自己定期换锁芯(自动续期),而不是每次到期前手忙脚乱地重配一遍。

提示:本文所有命令均基于 Ubuntu 18.04 官方最小化安装镜像验证,无需额外添加 PPA 或升级系统内核。若你使用的是云服务器(如 AWS EC2、阿里云 ECS),请确保安全组/防火墙已放行 TCP 80 和 443 端口;若为本地虚拟机,请确认网络模式为桥接或 NAT 并正确映射端口。

2. 从零开始:Nginx + Let’s Encrypt 在 Ubuntu 18.04 上的完整部署链路

部署不是“复制粘贴几条命令”,而是一条有逻辑、有检查点、可回溯的流水线。我把整个过程拆解为五个原子步骤,每一步都对应一个明确的状态目标,失败时能精准定位问题环节。

2.1 环境初始化:确认基础服务与域名解析就绪

第一步永远不是敲apt install,而是做三件事:

  1. 确认 Nginx 已安装并监听 80 端口

    sudo systemctl status nginx # 应显示 active (running),且 Loaded 行指向 /lib/systemd/system/nginx.service sudo ss -tlnp | grep ':80' # 应输出类似:LISTEN 0 128 *:80 *:* users:(("nginx",pid=1234,fd=6),("nginx",pid=1235,fd=6))

    如果未安装,执行sudo apt update && sudo apt install nginx -y;如果状态异常,先sudo systemctl restart nginx并检查/var/log/nginx/error.log

  2. 确认域名已正确解析到服务器 IP
    假设你的域名是example.com,在本地终端执行:

    dig +short example.com # 必须返回你的服务器公网 IP(如 203.0.113.10) ping -c 1 example.com # 应能通,且 IP 地址一致

    若解析失败,请检查 DNS 服务商(如 Cloudflare、阿里云 DNS)的 A 记录是否指向正确 IP,且 TTL 值已过期(通常 5-10 分钟)。Let’s Encrypt 的验证机制(HTTP-01)会向你的域名发起 HTTP 请求,如果 DNS 解析失败,证书申请必然中断。

  3. 确认服务器时间准确

    timedatectl status # Local time 应与当前 UTC 时间误差 < 1 秒,Time zone 应为正确时区(如 Asia/Shanghai)

    时间偏差超过 5 分钟会导致 ACME 协议握手失败(证书有效期校验出错)。若不准,执行sudo timedatectl set-ntp on启用 NTP 同步。

注意:Ubuntu 18.04 默认使用systemd-timesyncd作为 NTP 客户端,它比旧版ntpd更轻量、更可靠。不要手动安装chronyntpd,避免服务冲突。

2.2 安装 Certbot 并验证其与 Nginx 的深度集成能力

Ubuntu 18.04 的universe源中已预置 Certbot,但关键在于安装带 Nginx 插件的完整包,而非仅certbot命令行工具。后者只能手动配置证书,无法自动修改 Nginx 配置文件,极易出错。

sudo add-apt-repository universe sudo apt update sudo apt install certbot python3-certbot-nginx -y

安装完成后,验证插件是否生效:

certbot --nginx --help | grep "nginx" # 应输出包含 --nginx-server-root, --nginx-ctl 等参数说明 sudo certbot --version # 应显示 0.31.x 版本(Ubuntu 18.04 官方源版本)

python3-certbot-nginx包的核心价值在于:它能直接读取/etc/nginx/sites-enabled/下的配置文件,自动识别server_name指令,并在匹配的server块中插入ssl_certificatessl_certificate_key指令。它甚至能智能处理多域名、多 server 块的复杂场景。这是手动编辑配置文件无法比拟的安全性和效率。

实操心得:我曾遇到一台服务器,/etc/nginx/sites-enabled/default被注释掉,实际生效的是/etc/nginx/sites-enabled/myapp。Certbot 默认会扫描sites-enabled目录下所有非注释的.conf文件,但如果myapp文件里server_name写的是localhost而非真实域名,Certbot 会找不到匹配项,报错No matching nginx servers found。此时需先修正server_name example.com;,再运行 Certbot。

2.3 执行首次证书申请:一次成功的关键在于“验证阶段”的可控性

执行申请命令:

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

这条命令背后发生的事远比表面复杂:

  • Step 1:ACME 协议握手
    Certbot 向 Let’s Encrypt 的 ACME 服务器(https://acme-v02.api.letsencrypt.org/directory)发起注册请求,生成一对临时密钥(Account Key),并获取协议端点信息。

  • Step 2:HTTP-01 挑战发起
    Let’s Encrypt 服务器向http://example.com/.well-known/acme-challenge/xxxxx发送 HTTP GET 请求。Certbot 必须确保该路径能被公网访问,且返回正确的随机字符串(Token)。

  • Step 3:Nginx 自动配置注入
    Certbot 检测到--nginx参数后,会临时修改 Nginx 配置:在匹配example.comserver块中,动态插入一个location ^~ /.well-known/acme-challenge/,将其root指向 Certbot 的挑战文件目录(通常是/var/lib/letsencrypt/webroot/),并禁用所有其他 location 规则。这个操作是原子性的,且 Certbot 会自动sudo nginx -t测试语法,再sudo systemctl reload nginx生效。

  • Step 4:验证与签发
    Let’s Encrypt 服务器收到正确响应后,生成证书(fullchain.pem)和私钥(privkey.pem),并返回给 Certbot。Certbot 将它们存入/etc/letsencrypt/live/example.com/,并再次修改 Nginx 配置,添加 SSL 相关指令。

为什么这一步常失败?根本原因只有两个:

  1. 防火墙阻断:UFW(Ubuntu Firewall)默认关闭 80 端口。执行sudo ufw allow 'Nginx Full'(等价于开放 80+443)。
  2. Nginx 配置冲突:某些模板中存在location / { try_files $uri $uri/ =404; },它会拦截/.well-known/路径。Certbot 的自动注入会覆盖它,但如果你的配置里有location ~ /\.ht这类正则规则,可能优先级更高。此时需手动检查/etc/nginx/sites-enabled/下所有文件,确保没有location规则意外拦截/.well-known/

2.4 验证 HTTPS 是否真正生效:不止是看浏览器小锁图标

证书装上了,不代表万事大吉。必须进行三层验证:

  1. 基础连通性验证

    curl -I https://example.com # 应返回 HTTP/2 200,且 Header 中包含 server: nginx,date 字段正常 openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -dates # 应显示 notBefore 和 notAfter 日期,有效期为 90 天
  2. 证书链完整性验证
    Let’s Encrypt 使用 ISRG Root X1 根证书,但部分老旧客户端(如 Windows XP、Android 4.x)不信任它,需要中间证书(R3)补全链。Certbot 生成的fullchain.pem已包含完整链。验证命令:

    echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -text | grep "Issuer:" # 应显示 Issuer: C = US, O = Let's Encrypt, CN = R3
  3. Nginx SSL 配置健壮性验证
    访问 SSL Labs SSL Test ,输入你的域名。一个合格的配置应达到A+ 评级。若低于 A,常见原因:

    • 缺少ssl_dhparam:执行sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048,并在 Nginx 的server块中添加ssl_dhparam /etc/ssl/certs/dhparam.pem;
    • 使用了弱密码套件:在server块中添加ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES256-SHA:!aNULL:!MD5:!DSS';
    • 未启用 HSTS:添加add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

踩坑实录:某次我为一个子域名api.example.com申请证书,SSL Labs 测评显示“A-”,原因是主域名example.com的 Nginx 配置中ssl_protocols TLSv1.2;被错误写成ssl_protocols TLSv1;。Certbot 会复用主配置的 SSL 指令,导致子域名也继承了 TLSv1(已废弃)。解决方案:为每个server块单独定义ssl_protocolsssl_ciphers,避免全局污染。

2.5 配置自动续期:让安全成为“无感”的基础设施

Let’s Encrypt 证书有效期仅 90 天,这是其安全模型的核心设计——缩短密钥暴露窗口,降低私钥泄露风险。手动续期是运维灾难的源头。Ubuntu 18.04 的 Certbot 已通过 systemd timer 实现全自动续期。

验证 timer 状态:

sudo systemctl list-timers | grep certbot # 应显示 certbot.timer,Next 列为未来某个时间(如 2024-06-15 06:12:02) sudo systemctl status certbot.timer # 应显示 loaded, active (waiting)

Certbot 的 timer 默认每天凌晨 6:12 执行certbot renew。该命令逻辑是:

  • 扫描/etc/letsencrypt/renewal/下所有.conf文件;
  • 对每个证书,检查其notAfter日期,若剩余有效期 < 30 天,则触发续期;
  • 续期过程完全复用首次申请的验证方式(HTTP-01),无需人工干预。

但必须手动验证续期流程是否真能跑通!

sudo certbot renew --dry-run # 应输出:- The following errors were reported by the server: ... No errors. # 最终显示:** DRY RUN: simulating 'certbot renew' close to cert expiry # ** (The test certificates below have not been saved.)

--dry-run是黄金法则。它使用 Let’s Encrypt 的 Staging 环境(证书无效,但流程完全一致),消耗的是测试额度,不会影响生产证书配额(每周 5 次)。我坚持每次部署新服务器后必跑此命令,因为:

  • 它会暴露出 DNS 解析延迟、防火墙策略变更、Nginx 配置语法错误等所有潜在问题;
  • 它验证了/etc/letsencrypt/renewal/下的配置文件是否完整(Certbot 会为每个-d域名生成独立.conf文件);
  • 它确认了renew_hook(续期后执行的钩子)是否配置正确(如systemctl reload nginx)。

关键经验:certbot renew默认只续期“即将过期”的证书。若你想强制续期所有证书(如更换密钥算法),需加--force-renewal参数,但切勿在生产环境随意使用,它会快速耗尽 Let’s Encrypt 的速率限制(每周 5 次)。真正的运维智慧是:信任--dry-run,然后让certbot.timer默默工作。

3. 深度解析:Nginx SSL 配置中的 7 个决定性参数及其安全权重

Certbot 自动生成的 Nginx 配置(位于/etc/nginx/sites-enabled/对应文件中)是一个安全基线,但绝非终点。它为了兼容性牺牲了部分前沿安全特性。以下是必须手动审查并优化的 7 个核心参数,按安全权重降序排列:

3.1ssl_protocols:协议版本是安全的“地基”,选错即全盘皆输

Certbot 默认生成:

ssl_protocols TLSv1.2;

这是目前最安全的选择。必须删除TLSv1TLSv1.1。原因:

  • TLSv1.0 和 TLSv1.1 存在 POODLE、BEAST 等高危漏洞,2020 年起已被 PCI DSS(支付卡行业安全标准)明令禁止;
  • Ubuntu 18.04 的 OpenSSL 1.1.1 原生支持 TLSv1.3,但 Nginx 1.14(Ubuntu 18.04 默认版本)不支持 TLSv1.3。强行添加TLSv1.3会导致nginx -t报错invalid value "TLSv1.3"
  • 结论:TLSv1.2是 Ubuntu 18.04 上唯一安全、稳定、兼容的选项。添加TLSv1.3需先升级 Nginx 至 1.17+,这会引入额外的编译和稳定性风险,不推荐。

3.2ssl_ciphers:密码套件是加密的“锁芯”,强度决定破解难度

Certbot 默认未设置此参数,Nginx 使用其编译时的 OpenSSL 默认套件,其中可能包含RC4DES等弱算法。必须显式定义:

ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES256-SHA:!aNULL:!MD5:!DSS';

这个列表的设计逻辑:

  • 优先 ECDHE 密钥交换:提供前向保密(PFS),即使服务器私钥泄露,历史流量也无法被解密;
  • 优先 AES-GCM 模式:比 CBC 模式更安全、更高效;
  • 排除所有已知弱算法!aNULL(无认证)、!MD5(哈希碰撞)、!DSS(数字签名标准,已过时);
  • 保留 ECDSA 和 RSA 双栈:兼顾现代椭圆曲线(ECDSA)和传统 RSA 证书的兼容性。

验证效果:

openssl ciphers -V 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:...' | wc -l # 应输出约 20-30 个有效套件

3.3ssl_prefer_server_ciphers on:服务器主导权是性能与安全的平衡点

此参数默认为off,意味着客户端(浏览器)可以自由选择它支持的任意套件,包括一些老旧、低效的选项。设为on后,Nginx 会严格按照ssl_ciphers列表的顺序,选择第一个双方都支持的套件。这带来两大好处:

  • 安全提升:强制使用你精心筛选的强套件,杜绝客户端“降级”到弱算法;
  • 性能提升:避免协商过程中的多次往返,尤其对移动网络友好。

3.4ssl_session_cache shared:SSL:10m:会话缓存是 HTTPS 性能的“加速器”

HTTPS 握手(尤其是 TLSv1.2)涉及昂贵的非对称加密运算。ssl_session_cache允许 Nginx 将已建立的会话 ID 和主密钥缓存在内存中(shared表示进程间共享,10m表示分配 10MB 内存)。当同一客户端再次连接时,可复用会话,跳过完整握手,将延迟降低 50% 以上。

计算容量:10MB 缓存 ≈ 可存储 40,000 个会话(每个会话约 250 字节)。对于日活万级的网站足够。若流量巨大,可增至20m

3.5ssl_session_timeout 10m:会话超时是安全与资源的“折中线”

此参数定义缓存中会话的有效期。10m(10 分钟)是业界黄金值:

  • 太短(如1m):缓存命中率暴跌,大部分连接仍需完整握手,失去缓存意义;
  • 太长(如24h):内存占用剧增,且若私钥泄露,攻击者可利用长期缓存的会话密钥解密更多历史流量(尽管有 PFS,但会话密钥本身是短期的)。
    10m在资源消耗和安全风险间取得最佳平衡。

3.6add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload":HSTS 是 HTTPS 的“强制开关”

HSTS(HTTP Strict Transport Security)头告诉浏览器:“未来一年内,无论用户输入http://还是直接敲域名,都必须用 HTTPS 访问,并且要包含所有子域名”。preload参数表示你已将域名提交至浏览器 HSTS Preload List(需单独申请),实现首次访问即 HTTPS。

重要警告:一旦启用max-age=31536000(1 年)且带上preload,就无法撤回!若你的 HTTPS 配置在未来某天失效(如证书过期、Nginx 崩溃),用户将完全无法访问网站,直到 HSTS 过期。因此,首次部署务必先用max-age=300(5 分钟)测试一周,确认一切稳定后,再逐步延长至31536000

3.7ssl_buffer_size 4k:缓冲区大小是移动端体验的“隐形推手”

Nginx 默认ssl_buffer_size为 16k。在移动网络(高延迟、小包)下,大缓冲区会导致 TLS 记录层等待填满才发送,增加首字节时间(TTFB)。设为4k可显著改善移动端加载速度,且对服务器 CPU 和内存压力几乎无影响。这是被大量忽略的“微优化”,但对用户体验提升明显。

实操对比:我在一个新闻聚合站点(日均 PV 50 万)上将ssl_buffer_size从 16k 改为 4k,使用 WebPageTest 测试 3G 网络下的 TTFB,平均下降 120ms,首屏渲染时间(FCP)提升 8%。这不是理论,是真实数据。

4. 故障排查全景图:从证书申请失败到 HTTPS 访问异常的 12 个高频问题链

再完美的流程也会遇到意外。我把过去三年在 Ubuntu 18.04 上处理的数百个 Let’s Encrypt/Nginx 问题,归纳为一条清晰的排查链路。每个问题都标注了根本原因、诊断命令、修复方案、以及一个真实案例

4.1 问题链起点:certbot --nginx命令报错 “No nginx installation detected”

根本原因:Certbot 的 Nginx 插件无法定位 Nginx 的主配置文件或二进制路径。
诊断命令

sudo certbot --nginx --debug | grep -A5 "nginx path" # 查看 Certbot 尝试读取的路径 which nginx # 查看 nginx 二进制位置 ls -l /etc/nginx/nginx.conf # 确认主配置文件是否存在且可读

修复方案

  • nginx不在/usr/sbin/nginx,创建符号链接:sudo ln -sf $(which nginx) /usr/sbin/nginx
  • /etc/nginx/nginx.conf不存在,检查是否误删,或从/usr/share/nginx/复制默认配置。

真实案例:客户使用自编译 Nginx,安装到/opt/nginxwhich nginx返回/opt/nginx/sbin/nginx。Certbot 默认只查/usr/sbin/nginx。修复:sudo ln -sf /opt/nginx/sbin/nginx /usr/sbin/nginx

4.2 问题链分支一:申请时卡在 “Waiting for verification…” 超时

根本原因:Let’s Encrypt 服务器无法通过 HTTP 访问/.well-known/acme-challenge/
诊断命令

# 在服务器本地测试 curl -v http://example.com/.well-known/acme-challenge/test # 应返回 404(路径存在但文件不存在),而非 403/404/Connection refused # 在外部网络测试(用手机 4G 网络) curl -v http://example.com/.well-known/acme-challenge/test

修复方案

  • 检查 UFW:sudo ufw status,确保Nginx Full80端口开放;
  • 检查云服务商安全组;
  • 检查 Nginx 配置中是否有location / { deny all; }类规则,临时注释掉。

4.3 问题链分支二:申请成功,但浏览器访问https://example.com显示 “Your connection is not private”

根本原因:证书链不完整,浏览器无法构建从站点证书到受信根证书的信任链。
诊断命令

echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -text | grep "Subject:" -A1 # 查看 Subject 和 Issuer 是否为 R3 curl -s https://example.com | head -1 # 确认页面能返回内容,排除 Nginx 配置错误

修复方案

  • 确认 Certbot 生成的ssl_certificate指向fullchain.pem(而非cert.pem):
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # 正确 ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
  • 若手动修改过,执行sudo nginx -t && sudo systemctl reload nginx

4.4 问题链分支三:HTTPS 访问正常,但页面内资源(CSS/JS/图片)显示为 “Mixed Content”

根本原因:HTML 中引用了http://协议的资源,浏览器出于安全策略阻止加载。
诊断命令

curl -s https://example.com | grep -i "http://" # 查找所有硬编码的 http 链接

修复方案

  • 在 Nginx 配置中添加重写规则(治标):
    location / { sub_filter 'http://' 'https://'; sub_filter_once off; proxy_set_header Accept-Encoding ''; }
  • 更优方案:修改应用代码,将所有资源链接改为协议相对(//example.com/style.css)或绝对 HTTPS 链接。这是根本解法。

4.5 问题链分支四:certbot renew --dry-run报错 “Failed authorization procedure”

根本原因:续期时 HTTP-01 验证失败,通常因 Nginx 配置变更导致/.well-known/路径不可达。
诊断命令

sudo certbot renew --dry-run --debug # 查看详细错误日志,定位是哪个域名失败 sudo ls -la /var/lib/letsencrypt/webroot/ # 确认挑战文件目录存在且 Certbot 有写入权限

修复方案

  • 检查/etc/nginx/sites-enabled/下所有配置,确保没有location ^~ /.well-known/被其他location规则覆盖;
  • 临时添加一个通用规则(放在所有server块末尾):
    location ^~ /.well-known/acme-challenge/ { root /var/lib/letsencrypt/webroot; default_type "text/plain"; }

4.6 问题链分支五:SSL Labs 测评显示 “Certificate not trusted” 或 “Chain issues”

根本原因fullchain.pem文件损坏,或 Nginx 未正确加载。
诊断命令

sudo nginx -t # 检查语法 sudo openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -text -noout | head -20 # 查看证书内容是否正常

修复方案

  • 重新生成fullchain.pem
    sudo cat /etc/letsencrypt/live/example.com/cert.pem /etc/letsencrypt/live/example.com/chain.pem | sudo tee /etc/letsencrypt/live/example.com/fullchain.pem sudo systemctl reload nginx

4.7 问题链分支六:certbot renew后,Nginx 未自动重载,HTTPS 仍用旧证书

根本原因:Certbot 的renew_hook未配置,或配置错误。
诊断命令

sudo cat /etc/letsencrypt/renewal/example.com.conf | grep renew_hook # 应输出 renew_hook = systemctl reload nginx

修复方案

  • 编辑/etc/letsencrypt/renewal/example.com.conf,在[renewalparams]下添加:
    renew_hook = systemctl reload nginx
  • 或全局配置:sudo certbot renew --renew-hook "systemctl reload nginx"

4.8 问题链分支七:curl -I https://example.com返回 301 重定向到 HTTP,形成死循环

根本原因:Nginx 配置中存在return 301 http://$host$request_uri;这类强制跳转,且未加if ($scheme = http)条件判断。
诊断命令

sudo nginx -T | grep -A5 "return 301" # 查看所有 return 301 指令

修复方案

# 正确写法:只对 HTTP 请求重定向 server { listen 80; server_name example.com; return 301 https://$server_name$request_uri; } # 确保 443 server 块中没有 return 301 到 http

4.9 问题链分支八:Firefox 浏览器访问提示 “SEC_ERROR_UNKNOWN_ISSUER”

根本原因:Firefox 使用自己的证书信任库(NSS),未同步系统 ca-certificates。
诊断命令

sudo update-ca-certificates --fresh # 强制更新系统证书库

修复方案

  • 在 Firefox 地址栏输入about:config,搜索security.enterprise_roots.enabled,设为true
  • 或重启 Firefox,它会自动从系统读取更新后的证书。

4.10 问题链分支九:certbot renew报错 “Too many failed authorizations”

根本原因:Let’s Encrypt 的速率限制被触发(每域名每周最多 5 次失败验证)。
诊断命令

sudo certbot certificates # 查看所有证书状态

修复方案

  • 立即停止所有--force-renewal操作
  • 等待 7 天,或使用--dry-run测试;
  • 检查 DNS 和防火墙,确保下次申请 100% 成功。

4.11 问题链分支十:Nginx 启动失败,nginx -t报错 “unknown directive ‘ssl_dhparam’”

根本原因ssl_dhparam指令在 Nginx 1.10.3+ 才支持,而 Ubuntu 18.04 的 Nginx 1.14 完全支持,报错说明你误用了旧版 Nginx。
诊断命令

nginx -v # 应显示 nginx version: nginx/1.14.0 (Ubuntu)

修复方案

  • 删除ssl_dhparam行,或确认/etc/ssl/certs/dhparam.pem文件存在且路径正确;
  • 若文件不存在,按 2.4 节生成。

4.12 问题链终点:certbot renew成功,但systemctl status certbot.timer显示 “failed”

根本原因:timer 触发的certbot renew命令因权限或路径问题失败。
诊断命令

sudo journalctl -u certbot.timer -n 50 --no-pager # 查看 timer 日志 sudo journalctl -u certbot.service -n 50 --no-pager # 查看 service 日志

**修复

http://www.gsyq.cn/news/1564242.html

相关文章:

  • BLEURT、xCOMET与KIWI23:新一代机器翻译评估指标实战对比
  • 解锁音乐格式限制:你的数字音乐自由之路
  • 图聚类算法解析:从随机游走、谱分析到时空权衡的工程实践
  • Ruby数据类型本质:一切皆对象与行为契约
  • 2026大户型功能沙发和全屋软体家具到底选哪家更靠谱? - 深圳市民HLL
  • 后端面试中的MySQL高频考题
  • 提升机器学习模型泛化能力:住宅占用检测的跨场景实战
  • 2026广州漏水检测维修本地口碑防水商家榜单:厨卫/阳台/屋面/地下室渗漏水维修,持证施工+明码实价,防水补漏公司TOP5推荐 - 即刻修防水
  • Windows防休眠神器NoSleep:3种模式轻松解决系统休眠烦恼
  • Rust静态信息流控制库Filament:基于类型系统的零开销数据安全实践
  • StardewXnbHack终极指南:如何快速解锁《星露谷物语》所有游戏资源
  • 终极FanControl风扇控制指南:Windows平台专业散热管理完全解决方案
  • Android面试能力解码:从Framework到Compose的工程思维
  • 提示工程核心技术解析:从零样本到自批判,构建高效AI协作
  • 暗黑破坏神2存档修改完整教程:三步掌握d2s-editor的终极用法
  • Weyl半金属的拓扑特性与强相互作用效应研究
  • TWR-MCF51QM嵌入式开发板:从硬件拆解到外设驱动的实战指南
  • 配置文件变更日志 - CSGO_RTX3080_472.12.nip
  • COM3D2.MaidFiddler:终极COM3D2女仆实时编辑器完整指南
  • 2026开封防水补漏避坑指南:卫生间/厨房/阳台/屋顶/地下室漏水检测维修全攻略,正规施工+透明报价+口碑榜靠谱服务商推荐 - 安佳防水
  • Fate/Grand Automata终极指南:告别手动刷本,5步实现FGO自动战斗
  • 本文档系统性地披露了字节跳动(ByteDance)内部一个长期运行、结构严密的隐秘资金运作体系。该体系通过设立数十家境内空壳公司,以“技术服务费”、“项目协作款”等名义,将公司资金转移至由张一鸣家族成
  • 鸣潮自动化助手:5分钟上手,解放双手的终极游戏辅助指南
  • 聚合API平台极速集成指南:以QQ信息查询为例
  • 专业指南:终极可视化Nginx管理面板部署与SSL自动化配置
  • 临床预测模型的双层次不确定性校准:CURA框架原理与工程实践
  • 刚整理完2026小户型功能沙发排行榜,选哪家靠谱心里有数了 - 深圳市民HLL
  • 2026年当前江苏地区保温钢管定做服务商综合实力剖析 - 品牌鉴赏官2026
  • 2026年选小户型功能沙发和全屋软体家具,给大家分享靠谱参考 - 深圳市民HLL
  • LinkSwift:开源网盘直链解析工具的技术实现与使用指南