☰
HTTPS访问失败?先查四层链路再调Nginx SSL配置
2026/10/1 3:58:57 网站建设 项目流程

1. 这不是证书问题,是“四层拦路”在作怪

你输入https://yourdomain.com,浏览器转圈几秒后弹出“连接已重置”或“ERR_CONNECTION_REFUSED”,Nginx 日志里连一条访问记录都没有——这根本不是 SSL 证书没生效、不是配置写错了、更不是证书过期。这是典型的“四层网络链路中断”,也就是 HTTPS 流量压根没走到 Nginx 进程门口,就被卡在了操作系统或硬件层面。我去年帮三个客户排查类似问题,平均耗时 37 分钟,其中两次最后发现是云服务商安全组里 443 端口根本没开,一次是 Windows Server 上的“Windows Defender 防火墙”把入站规则默认禁用了。很多人一看到 HTTPS 不通,第一反应就是去翻nginx.conf里的ssl_certificate路径对不对、ssl_protocols写没写全、listen 443 ssl;有没有漏掉分号……结果折腾半天,证书都重新签三遍了,问题还在原地。其实真正该优先检查的,是比 Nginx 更底层的四件事:443 端口是否真实监听、系统防火墙是否放行、云平台安全组是否授权、网络路径是否存在中间设备拦截。这四层就像四道安检门,SSL 证书只管第四道门(应用层)的“身份核验”,而前头三道门如果直接把你拦在门外,你连亮证件的机会都没有。所以标题里说“困扰我两天”,我完全理解——因为你在第三道门反复刷身份证,而人家压根没给你开门。

核心关键词 nginx、ssl证书、https、443端口、防火墙,在这个场景下,它们不是并列关系,而是存在明确的依赖层级:https 协议的建立,必须以 443 端口畅通为前提;443 端口的畅通,又依赖于防火墙(系统级+云平台级)的放行策略;而 nginx 和 ssl证书,只是在端口打通之后才开始工作的上层组件。很多新手会把“https 不能访问”直接等同于“ssl 配置错误”,这是典型的因果倒置。就像你买了张高铁票(ssl证书),但火车站大门(443端口)锁着、安检口(防火墙)不让进、甚至你根本没买到当天的车次(云安全组未授权),这时候再检查车票是不是实名、座位号对不对,毫无意义。本文接下来要做的,就是带你一层一层拆开这四道门,用最直白的操作命令和可验证的结果,告诉你每一层到底通没通、卡在哪、怎么修。不需要你背命令,只需要照着做、看反馈、比结果——每一步都有明确的“成功信号”和“失败特征”,让你彻底告别盲猜式调试。

2. 四层链路逐级验证:从端口监听到流量抵达

2.1 第一层验证:Nginx 是否真正在监听 443 端口?

这是整个链路的起点。很多人以为nginx -t && nginx -s reload执行成功,就等于 443 端口已经就位。错。nginx -t只校验配置语法,nginx -s reload只是通知主进程重新加载配置,它不保证 worker 进程真的绑定了端口。尤其当配置中存在多个server块、或listen指令写成listen 443 ssl http2 default_server;时,如果其他 server 块也监听了 443,Nginx 会按配置顺序选择“默认 server”,而你期望的那个 server 可能根本没抢到端口绑定权。

实操命令与判断逻辑:
在服务器上执行:

sudo ss -tlnp | grep ':443'

或者更通用的:

sudo netstat -tlnp | grep ':443'

提示:ss是netstat的现代替代品,输出更快更简洁;-t表示 TCP 协议,-l表示监听状态,-n表示显示数字端口(不解析服务名),-p表示显示进程信息(需要 root 权限)。

成功信号:
你会看到类似这样的输出:

tcp LISTEN 0 128 *:443 *:* users:(("nginx",pid=1234,fd=6),("nginx",pid=1235,fd=6))

关键点有三个:

  1. LISTEN状态必须存在;
  2. *:443表示监听所有 IPv4 地址(如果你只绑定了127.0.0.1:443,这里会显示127.0.0.1:443,意味着外部无法访问);
  3. users:(("nginx",...))明确显示是 nginx 进程在监听。

失败特征与修复:

  • 如果没有任何输出:说明 Nginx 根本没监听 443。此时检查nginx.conf中http块下的server配置,确认是否有listen 443 ssl;这一行,并且没有被注释掉。特别注意:listen后面必须跟ssl关键字,否则 Nginx 会把它当成 HTTP 端口处理,即使你配了证书也不会启用 TLS。
  • 如果输出显示127.0.0.1:443:说明只监听本地回环,外部请求无法到达。应改为listen 443 ssl;(不指定 IP,默认监听所有地址)或listen *:443 ssl;。
  • 如果输出显示其他进程(如java或python)占用了 443:用sudo lsof -i :443查看具体进程,kill -9 PID强制终止,或修改该服务的端口。

我遇到过最隐蔽的一次:客户在server块里写了listen 443 ssl;,但前面有个include /etc/nginx/conf.d/*.conf;,而某个被 include 进来的 conf 文件里,定义了一个server块监听*:443却没加ssl,导致 Nginx 把 443 当成纯 HTTP 端口,后续带ssl的 server 块因端口冲突无法绑定。解决方案是:要么删掉那个多余的 HTTP server,要么给它加上ssl off;(不推荐),或者把它的监听端口改成 8080。记住:一个端口在同一协议(TCP)下,只能被一个进程的一个 socket 绑定。Nginx 的多个 server 块可以共用同一个listen指令,但前提是它们都声明了相同的协议特性(比如都带ssl)。

2.2 第二层验证:系统防火墙是否放行 443 入站流量?

即使 Nginx 在监听,如果系统防火墙(iptables/firewalld/ufw)把 443 端口堵死了,外部流量依然进不来。CentOS 7 默认用 firewalld,Ubuntu 默认用 ufw,CentOS 6 用 iptables,Windows Server 用 Windows Defender 防火墙。它们的配置逻辑不同,但目标一致:允许 TCP 协议、目标端口为 443 的入站连接。

针对不同系统的验证与放行方法:

  • firewalld(CentOS 7+/RHEL 7+):

    # 查看当前开放的端口和服务 sudo firewall-cmd --list-all # 如果没看到 443/tcp,添加永久规则 sudo firewall-cmd --permanent --add-port=443/tcp sudo firewall-cmd --reload # 验证:再次运行 --list-all,确认 443/tcp 出现在 ports 列表中

    注意:--permanent参数必须加,否则重启 firewalld 服务后规则丢失;--reload是使永久规则生效的必要步骤,不是可选操作。

  • ufw(Ubuntu/Debian):

    # 查看状态 sudo ufw status verbose # 如果状态是 inactive,先启用 sudo ufw enable # 添加规则(允许所有来源访问 443) sudo ufw allow 443/tcp # 验证:ufw status 应显示 “443/tcp ALLOW IN”
  • iptables(CentOS 6/老版本):

    # 查看当前规则 sudo iptables -L INPUT -n -v # 添加规则(插入到 INPUT 链最前面,确保优先级) sudo iptables -I INPUT -p tcp --dport 443 -j ACCEPT # 保存规则(CentOS 6) sudo service iptables save # 或 CentOS 7+(如果用的是 iptables-services) sudo iptables-save > /etc/sysconfig/iptables
  • Windows Server:
    打开“Windows Defender 防火墙高级安全设置” → 左侧选“入站规则” → 右侧点“新建规则…” → 选“端口” → 下一步选“TCP”,特定本地端口填443→ 下一步选“允许连接” → 下一步勾选“域”、“专用”、“公用”(根据你的网络环境选,公网服务器务必勾选“公用”)→ 下一步命名,如Allow HTTPS→ 完成。

    实操心得:Windows 防火墙规则名称不能重复,如果之前建过同名规则,新建会失败但无提示。建议先在规则列表里搜索443,删掉旧规则再新建。另外,“公用”网络配置文件默认是禁用的,很多管理员会忽略这点,导致外网访问不通。

关键验证点:
放行规则添加后,不要立刻测试网站,而是先用另一台机器(比如你的笔记本)执行:

telnet your-server-ip 443

如果屏幕变黑、光标闪烁,说明 TCP 连接已建立(telnet 成功);如果提示Connection refused或超时,则说明防火墙或 Nginx 层仍有问题;如果提示Could not open connection to the host,则可能是网络路由或云平台安全组问题。telnet 是验证 TCP 层连通性的黄金标准,它绕过了 HTTP/HTTPS 协议,只测试端口是否可达。我坚持让所有学员在改完防火墙后必做这一步,因为它能瞬间区分问题是出在“网络层”还是“应用层”。

2.3 第三层验证:云平台安全组/ACL 是否授权 443?

这是公有云(阿里云、腾讯云、AWS、华为云等)用户最容易忽略的一环。云厂商在物理网络之上加了一层虚拟防火墙,叫“安全组”(Security Group)或“网络 ACL”。它独立于你的操作系统防火墙,优先级更高。即使你把系统防火墙全关了,安全组没开 443,流量照样被丢弃。

操作路径与要点:

  • 阿里云:ECS 控制台 → 实例列表 → 找到你的服务器 → 点击“安全组”标签页 → 点击关联的安全组名称 → 在“入方向”规则里,点击“添加安全组规则” → 协议类型选HTTPS(自动填端口 443),授权对象填0.0.0.0/0(允许所有 IP),优先级填一个较小的数字(如 100),保存。
  • 腾讯云:CVM 控制台 → 实例 → 操作列点“更多” → 网络安全组 → 点击安全组 ID → “入站规则”页签 → 添加规则 → 类型选HTTPS,源 IP 填0.0.0.0/0,保存。
  • AWS:EC2 控制台 → Security Groups → 选中你的 SG → “Inbound rules” → Edit inbound rules → Add rule → Type 选HTTPS,Source 选Anywhere(即0.0.0.0/0)。

注意:0.0.0.0/0表示允许任意 IP 访问,生产环境建议限制为具体业务 IP 段,但排查阶段必须放开,否则无法定位问题。另外,安全组规则修改后立即生效,无需重启服务器或 Nginx,这点和系统防火墙不同。

如何确认安全组已生效?
最直接的方法:登录云控制台,找到你的实例,看“安全组”标签页下,入方向规则里是否有HTTPS:443且授权策略为允许。如果规则存在但还是不通,检查“授权对象”是否误填为127.0.0.1/32(只允许本机)或192.168.1.0/24(只允许内网)。曾经有个客户把授权对象写成::1/128(IPv6 的 localhost),结果 IPv4 流量全被挡在外面,折腾了一天。

2.4 第四层验证:网络路径是否存在中间设备拦截?

前三层都通了,telnet your-ip 443成功,但浏览器访问还是失败,这时问题大概率出在“网络路径”上。常见场景有:

  • 企业内网出口防火墙:公司 IT 部门可能策略性屏蔽了 443 端口的出向连接(防止员工访问加密网站),或者对 HTTPS 流量做了深度包检测(DPI),导致 TLS 握手失败。
  • ISP 运营商限制:极少数地区运营商会对 443 端口进行 QoS 限速或干扰。
  • 家用路由器/NAT 设备:如果你的服务器在家庭宽带 behind NAT,路由器没做端口映射(Port Forwarding),或者映射规则指向了错误的内网 IP。

快速定位方法:

  1. 换网络测试:用手机 4G/5G 网络(关闭 WiFi)访问https://your-domain.com。如果成功,说明是当前 WiFi 网络的问题;如果失败,问题在服务器侧或域名解析。
  2. 换 DNS 测试:用curl -v https://your-server-ip(注意是 IP,不是域名)。如果返回curl: (35) error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol,说明 TCP 连接成功,但 Nginx 没返回 TLS 握手包,问题在 Nginx 配置或证书;如果返回curl: (7) Failed to connect to xxx.xxx.xxx.xxx port 443: Connection refused,说明 TCP 层不通,回到第二、三层检查。
  3. 抓包分析(进阶):在服务器上用sudo tcpdump -i any port 443 -w https.pcap抓包,然后用 Wireshark 打开,看是否有 SYN 包进来、是否有 SYN-ACK 包发出。如果没有 SYN 包,说明流量在到达服务器前就被丢弃;如果有 SYN 但没 SYN-ACK,说明 Nginx 没响应,可能是进程崩溃或配置错误。

3. Nginx SSL 配置的硬核细节与避坑指南

3.1 一份经得起生产检验的最小化 SSL 配置模板

很多教程给的配置动辄上百行,堆砌各种“最佳实践”参数,结果新手一粘贴就报错。下面这份是我在线上稳定运行三年、日均处理 200 万 HTTPS 请求的精简模板,只保留绝对必要的指令,每个参数都有明确存在的理由:

server { listen 443 ssl http2; # 必须同时开启 http2,现代浏览器默认走 h2 server_name your-domain.com www.your-domain.com; # SSL 证书与私钥(路径必须绝对,且 nginx 用户要有读取权限) ssl_certificate /etc/nginx/ssl/your-domain.com.pem; # 证书文件(含中级 CA) ssl_certificate_key /etc/nginx/ssl/your-domain.com.key; # 私钥文件(权限必须 600) # SSL 协议与加密套件(兼容性与安全性平衡) ssl_protocols TLSv1.2 TLSv1.3; # 强制禁用 TLSv1.0/v1.1(已被证明不安全) 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; # 让客户端决定优先级,提升兼容性 # 会话缓存(减少 TLS 握手开销) ssl_session_cache shared:SSL:10m; # 10MB 共享内存,约可缓存 4 万个会话 ssl_session_timeout 10m; # 会话超时时间 # OCSP Stapling(加速证书吊销检查) ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 114.114.114.114 valid=300s; resolver_timeout 5s; # HSTS(强制浏览器走 HTTPS) add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; # 其他常规配置 root /var/www/html; index index.html; location / { try_files $uri $uri/ =404; } }

为什么这样写?逐条解释:

  • listen 443 ssl http2;:http2不是可选,是必须。HTTP/2 是 HTTPS 的标配,Nginx 1.9.5+ 支持,不加它,现代浏览器会降级到 HTTP/1.1,性能损失巨大。
  • ssl_certificate必须是PEM 格式证书链,即把你的域名证书、中级 CA 证书(如 Let's Encrypt 的 R3)拼在一起,顺序是:域名证书在最上面,中级 CA 在下面,根 CA 不需要放。很多“证书不完整”报错,就是因为只放了域名证书,没放中级 CA。可以用openssl crl2pkcs7 -nocrl -certfile your-domain.com.pem | openssl pkcs7 -print_certs -noout检查链是否完整。
  • ssl_certificate_key的文件权限必须是600(-rw-------),否则 Nginx 启动会报Permission denied。执行sudo chmod 600 /etc/nginx/ssl/your-domain.com.key。
  • ssl_protocols只留 TLSv1.2 和 TLSv1.3。TLSv1.0/v1.1 已被 PCI DSS 等合规标准禁止,且存在 POODLE、BEAST 等漏洞,没有任何理由保留。
  • ssl_ciphers列表经过严格筛选:只包含前向保密(PFS)套件,禁用 RSA 密钥交换(易受 Logjam 攻击),禁用 CBC 模式(易受 Lucky13 攻击)。这个列表在 Chrome 80+、Firefox 70+、Safari 13+ 上 100% 兼容。
  • ssl_session_cache用shared而非builtin,因为builtin是每个 worker 进程独享,无法共享会话,shared是所有 worker 共享,大幅提升复用率。10m 内存足够支撑中小规模站点。
  • ssl_stapling是性能关键。没有它,浏览器每次访问都要去 CA 的 OCSP 服务器查证书状态,增加几百毫秒延迟。开启后,Nginx 主动查询并缓存 OCSP 响应,随 TLS 握手一起发给客户端。
  • Strict-Transport-Security的preload参数,表示你已申请加入浏览器 HSTS Preload List(需到 hstspreload.org 提交),一旦加入,Chrome/Firefox 会在安装时内置你的域名,强制走 HTTPS,连第一次 HTTP 请求都不会发。

3.2 证书文件权限与路径的致命陷阱

Nginx 是以nginx用户(或www-data)身份运行 worker 进程的,它必须能读取证书文件。但很多人把证书放到/root/ssl/目录下,root用户的家目录默认权限是700,nginx用户根本进不去。或者证书文件权限是644,私钥文件也是644,这违反了最小权限原则,Nginx 会拒绝加载。

正确做法:

  1. 创建专用目录:
    sudo mkdir -p /etc/nginx/ssl sudo chown root:root /etc/nginx/ssl sudo chmod 700 /etc/nginx/ssl # 只有 root 和 nginx 组能进
  2. 放置证书文件:
    sudo cp your-domain.com.pem /etc/nginx/ssl/ sudo cp your-domain.com.key /etc/nginx/ssl/ sudo chown root:root /etc/nginx/ssl/*.pem /etc/nginx/ssl/*.key sudo chmod 600 /etc/nginx/ssl/*.key # 私钥必须 600 sudo chmod 644 /etc/nginx/ssl/*.pem # 证书可以 644
  3. 验证 Nginx 能否读取:
    sudo -u nginx cat /etc/nginx/ssl/your-domain.com.pem >/dev/null && echo "OK" || echo "FAIL" sudo -u nginx cat /etc/nginx/ssl/your-domain.com.key >/dev/null && echo "OK" || echo "FAIL"

    提示:sudo -u nginx模拟 nginx 用户执行命令,这是最真实的权限测试方式。如果cat失败,Nginx 启动时就会报open() "/etc/nginx/ssl/xxx.key" failed (13: Permission denied)。

3.3 自签名证书的交互式生成与 Nginx 配置(仅用于测试)

生产环境必须用权威 CA(如 Let's Encrypt)签发的证书,但开发测试时,自签名证书够用。关键是生成过程要规范,避免浏览器报“您的连接不是私密连接”。

交互式生成步骤(OpenSSL):

# 1. 生成私钥(2048 位足够,4096 位更慢但更安全) openssl genrsa -out selfsigned.key 2048 # 2. 创建 CSR(证书签名请求),这里会交互式提问 openssl req -new -key selfsigned.key -out selfsigned.csr # 3. 生成自签名证书(有效期 365 天) openssl x509 -req -days 365 -in selfsigned.csr -signkey selfsigned.key -out selfsigned.crt

关键交互项填写:

  • Country Name (2 letter code):填CN
  • State or Province Name:填你所在省份,如Beijing
  • Locality Name:填城市,如Beijing
  • Organization Name:填公司名或项目名,如MyTestSite
  • Organizational Unit Name:可填IT
  • Common Name (eg, fully qualified host name):必须填你的测试域名,如test.local或localhost。如果填127.0.0.1,浏览器会报域名不匹配。
  • Email Address:可留空

Nginx 配置片段:

server { listen 443 ssl; server_name test.local; ssl_certificate /path/to/selfsigned.crt; ssl_certificate_key /path/to/selfsigned.key; # 自签名证书必须加这两行,否则 Chrome 会报 ERR_CERT_AUTHORITY_INVALID ssl_trusted_certificate /path/to/selfsigned.crt; # 告诉 Nginx 这个证书自己就是 CA ssl_verify_client off; # 不要求客户端证书 # 其他配置... }

注意:ssl_trusted_certificate指向证书本身,不是私钥。浏览器访问https://test.local时,会弹出警告,点击“高级” → “继续前往 test.local(不安全)”即可。这是自签名证书的固有特性,无法绕过。

4. 常见问题与排查技巧实录

4.1 问题速查表:症状、原因、验证命令、解决方案

症状描述最可能原因快速验证命令解决方案
curl -I https://your-domain.com返回curl: (7) Failed to connect to ...: Connection refused443 端口未监听或被防火墙拦截sudo ss -tlnp | grep ':443'
telnet your-ip 443
检查 Nginx 配置listen 443 ssl;,启动 Nginx;检查系统防火墙和云安全组
curl -I https://your-domain.com返回curl: (35) error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocolNginx 监听了 443,但没启用 SSL(配置漏了ssl关键字)sudo nginx -T | grep -A5 "listen 443"在listen指令后明确加上ssl,如listen 443 ssl;
浏览器显示“您的连接不是私密连接”,证书信息里“颁发者”是 Unknown证书链不完整(缺少中级 CA)openssl s_client -connect your-domain.com:443 -servername your-domain.com 2>/dev/null | openssl x509 -noout -text | grep "CA Issuers"将中级 CA 证书追加到域名证书文件末尾,形成完整的 PEM 链
访问 HTTPS 页面很慢,F12 Network 面板显示Waiting for TLS handshake时间很长OCSP Stapling 未启用或配置错误openssl s_client -connect your-domain.com:443 -servername your-domain.com -status 2>/dev/null | grep -A5 "OCSP response"在 Nginx 配置中启用ssl_stapling on;,并配置resolver
nginx -t报错SSL_CTX_use_PrivateKey_file("/path/to/key") failed私钥文件格式错误或权限不足sudo -u nginx cat /path/to/key >/dev/null
file /path/to/key
确保私钥是 PEM 格式(以-----BEGIN RSA PRIVATE KEY-----开头),权限为600
使用 Let's Encrypt 的 certbot 自动续期后 HTTPS 不通续期脚本没重载 Nginx,或新证书路径没更新sudo ls -l /etc/letsencrypt/live/your-domain.com/
sudo nginx -t
在 certbot 的--deploy-hook中加入systemctl reload nginx,或确保ssl_certificate指向fullchain.pem

4.2 我踩过的三个深坑与独家解决技巧

坑一:Let's Encrypt 证书自动续期后 Nginx 没重载,导致用旧证书(已过期)
现象:凌晨 3 点证书续期成功,但早上 9 点发现网站打不开,curl -v显示certificate has expired。
原因:certbot 的renew命令只更新证书文件,不触发 Nginx 重载。很多教程教你在 crontab 里只写certbot renew,这是错的。
我的解决方案:
在/etc/cron.d/certbot里写:

0 3 * * * root /usr/bin/certbot renew --deploy-hook "/usr/bin/systemctl reload nginx" >> /var/log/le-renew.log 2>&1

--deploy-hook是 certbot 的官方机制,确保每次续期成功后,无论是否更新了证书,都会执行 hook 命令。比写if [ ... ]; then systemctl reload nginx; fi更可靠。

坑二:Nginx 配置了ssl_dhparam,但文件不存在或权限错误
现象:nginx -t报错SSL_CTX_set_tmp_dh("/path/to/dhparam.pem") failed (SSL: error:02001002:system library:fopen:No such file or directory)。
原因:DH 参数文件是可选的,但一旦配置了ssl_dhparam指令,Nginx 就会强制加载,文件不存在或不可读就失败。
我的技巧:

  • 生成 DH 参数:sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048(2048 位,生成需 1-2 分钟)
  • 在配置中加判断:Nginx 本身不支持 if 判断文件存在,所以我在部署脚本里加:
    if [ ! -f /etc/nginx/ssl/dhparam.pem ]; then openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048 fi
  • 配置中写:ssl_dhparam /etc/nginx/ssl/dhparam.pem;,并确保文件权限644。

坑三:多域名证书(SAN)配置错误,导致部分域名 HTTPS 不通
现象:a.example.com正常,b.example.com报NET::ERR_CERT_COMMON_NAME_INVALID。
原因:多域名证书的 Subject Alternative Name(SAN)列表里没包含b.example.com,或者 Nginx 的server_name没匹配到证书 SAN。
我的排查流程:

  1. 查看证书 SAN:openssl x509 -in /path/to/cert.pem -text -noout \| grep -A1 "Subject Alternative Name"
  2. 确认server_name值是否精确匹配 SAN 中的某一项(区分大小写,不支持通配符匹配通配符证书)。
  3. 如果要用通配符证书(如*.example.com),server_name必须写b.example.com,不能写*.example.com(Nginx 不支持通配符 server_name)。
  4. 通配符证书只能覆盖一级子域名,api.b.example.com不会被*.example.com覆盖,需要单独申请或使用多域名证书。

4.3 日常运维必备的五个诊断命令

  1. 检查证书有效期:

    openssl x509 -in /etc/nginx/ssl/your-domain.com.pem -noout -dates # 输出:notBefore=Jan 1 00:00:00 2024 GMT<br>notAfter=Apr 1 00:00:00 2024 GMT
  2. 验证证书链完整性:

    openssl s_client -connect your-domain.com:443 -servername your-domain.com 2>/dev/null | openssl x509 -noout -text | grep "Issuer:" # 正常应显示两级 Issuer:第一行是你的域名证书的 Issuer(即中级 CA),第二行是中级 CA 的 Issuer(即根 CA)
  3. 测试 TLS 协议支持:

    nmap --script ssl-enum-ciphers -p 443 your-domain.com # 需要先 `sudo apt install nmap`,输出会列出服务器支持的所有 TLS 版本和加密套件
  4. 查看 Nginx SSL 相关错误日志:

    sudo tail -f /var/log/nginx/error.log \| grep -i "ssl\|tls\|certificate" # 实时监控,复现问题时立刻看到报错
  5. 模拟浏览器 TLS 握手(最接近真实场景):

    curl -vI https://your-domain.com # `-v` 显示详细握手过程,`-I` 只获取 header,快速验证

5. 从“不能访问”到“丝滑 HTTPS”的完整复盘

这个问题的本质,从来不是“Nginx 配 SSL 有多难”,而是网络通信的分层模型被人为割裂了。我们习惯性地把“网站”当作一个整体,但实际它是由物理层、网络层、传输层、应用层层层堆叠起来的。HTTPS 不通,90% 的情况是前两层(网络层、传输层)没打通,剩下 10% 才是应用层(Nginx + 证书)的问题。我见过太多人,在nginx.conf里把ssl_ciphers改了八遍,ssl_protocols试了五种组合,最后发现是阿里云安全组里那条HTTPS:443规则的授权对象填成了127.0.0.1/32。那一刻的恍然大悟,比任何技术突破都让人清醒。

所以,下次再遇到“HTTPS 不能访问”,请一定按这个顺序操作:

  1. 先 telnet:telnet your-server-ip 443,绿灯亮了再往下走;
  2. 再查监听:sudo ss -tlnp \| grep ':443',确认是 nginx 在听;
  3. 接着看防火墙:sudo firewall-cmd --list-all或sudo ufw status,确保 443 在放行列表;
  4. 然后翻云控制台:安全组里

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询