我的浏览器不会显示 http://[sub.]example.com

Bob*_*Bob 6 ssl nginx web-server apache-2.4 hsts

当我在浏览器中访问时,http://sub.example.com我收到“连接被拒绝” 消息或“无效证书”错误,但我什至不想通过 https 进行连接。

据我所知:

  • Web 服务器已正确配置sub.example.com
  • TCP 端口 80 在防火墙/安全组中打开
  • URL 中使用纯 HTTP 而不是 HTTPS
  • DNS 记录sub.example.com指向 Web 服务器的正确 IP 地址
  • Web 服务器已使用新配置重新启动
  • 日志不显示启动或任何其他错误

我该如何调试以及存在什么问题?

Bob*_*Bob 20

首先要注意的是,现代 Web 浏览器可能不是调试此类问题的最佳工具。浏览器甚至可能是造成这些问题的原因,因为服务器可以完全正确配置,并且问题可能 100% 是客户端。

内容:

  • 测试(使用curl隐身/匿名浏览器)
  • 两个测试都显示预期的内容
  • curl可以,但私有浏览器窗口不显示正确的内容
  • 两个测试都没有显示预期的内容

测试

不仅尝试使用 FQDN 进行测试http://sub.example.com,还尝试使用更完整的 URL,例如http://sub.example.com/some-page.html. 当您知道自己位于代理后面时,添加其他参数通常会绕过缓存内容,即添加并递增计数器,例如http://sub.example.com/some-page.html?test=3

  • 从“私人/隐身”浏览器窗口进行测试。
    这减少了根据缓存对象得出错误结论的可能性。

  • 例如,从命令行(在测试服务器上)进行测试curl -vv http://sub.example.com/some-page.html,或者使用telnet并模拟 Web 请求

    telnet sub.example.com 80

    GET /some-page.html HTTP/1.1
    主机:sub.example.com

在输出中寻找的内容curl

  • 代理设置绝对是一个危险信号,也是调试服务器问题时的真正障碍。代理服务器可以缓存(DNS 记录和 Web 内容)、限制您的访问,甚至替换 TLS 证书。

    curl -vv http://sub.example.com/some-page.html
    * Uses proxy env variable no_proxy == 'localhost,127.0.0.1,.corp.example.net'
    * Uses proxy env variable http_proxy == 'http://[user]:[pass]@proxy.corp.example.net:8080/'
    *   Trying 10.2.0.80:8080...
               ^^^ Danger - Proxy server
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果您想正确测试互联网 Web 服务器的配置,请从不依赖代理服务器的(测试)系统进行测试。我通常没有支持成熟浏览器的测试系统,但我通常可以管理一个从命令行运行curl命令的系统。

    curl -vv http://sub.example.com/some-page.html
    * About to connect() to sub.example.com port 80 (#0)
    *   Trying 192.168.2.119...
    * Connected to sub.example.com (192.168.2.119) port 80 (#0)
                                    ^^^ CHECK is this the correct IP-address 
                                        of your webserver?
    > GET /some-page.html HTTP/1.1
    > User-Agent: curl/7.29.0
    > Host: sub.example.com
    > Accept: */*
    
    Run Code Online (Sandbox Code Playgroud)

您会发现已成功建立与 Web 服务器的正确 IP 地址和端口的连接。该> 标记位于由curl 生成的请求标头之前。

服务器响应标头用< 标记进行标记,然后在空行之后,服务器发送响应正文:

< HTTP/1.1 302 Found
  |         ^^^ The server HTTP STATUS response code 
   `^^ the HTTP protocol version

< Date: Mon, 07 Feb 2022 13:58:11 GMT
< Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/5.4.16
< Location: https://sub.example.com/some-page.html
< Content-Length: 216
< Content-Type: text/html; charset=iso-8859-1
<
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
...
Run Code Online (Sandbox Code Playgroud)

第一个协议头之后 HTTP/1.1是 服务器生成的HTTP 状态代码。响应2xx意味着某种形式的成功,3xx响应是重定向(见此处),4xx并且5xx是错误。

在本示例中,服务器发送的其他标头Location:指示重定向响应的目标。

两个测试都显示预期的内容

结论: Web 服务器配置正确,问题与浏览器有关。

最可能的原因:在更改 Web 服务器配置之前可能配置了永久重定向,并且浏览器缓存了永久重定向 (301)。相当常见的是缓存损坏的重定向或缓存到 https 的重定向,并且尚未sub.example.com配置证书和 https 站点。

解决方案 1:清除浏览器缓存,网站应按预期加载。
解决方案 2:获取 sub.example.com 的 SSL 证书并启用 TLS。

原因 2:与缓存重定向到 https 的根本原因不完全相同,但实际上具有相似的因果关系,由域设置的HTTP 严格传输安全example.com(HSTS) 策略也适用于示例的所有(新)子域。 com. 任何相当现代的浏览器都会存储并遵守 HSTS 策略,并且会拒绝通过纯 http 连接到端口 80,并且会默默地重写 URLhttp://sub.example.comhttps://sub.example.com尝试使用 TLS 连接到端口 443。

解决方案:获取 sub.example.com 的 SSL 证书并启用 TLS。
清除 HSTS 浏览器缓存可以暂时起作用,但只有当您同时从 example.com 中删除包含子域 HSTS 策略时才有效(不建议这样做)。

curl可以,但私有浏览器窗口不显示正确的内容

结论: Web 服务器配置正确,问题与浏览器或客户端相关。

原因 1:与缓存的HTTP 严格传输安全(HSTS) 策略的根本原因不完全相同,但实际上相似的因果关系是HSTS 预加载列表上的域。但是,如果在“私有/隐身”窗口中不应遵守缓存的 HSTS 策略,则应始终应用 HSTS 预加载列表,即使在私有/隐身窗口中也是如此。

请参阅此问答,了解有关如何确定您的域或 TLD 是否位于 HSTS 预加载列表中的概述:
需要 HTTPS 连接的顶级域 (TLD) 列表,例如 .dev

解决方案:获取 sub.example.com 的 SSL 证书并启用 TLS。

原因 2:尽管 DNS 记录配置正确,但客户端解析程序(运行浏览器的桌面)可能指向不同的 IP 地址。检查例如nslookup客户dig端名称服务器解析的内容,不要忘记sub.example.com 的主机文件条目将覆盖 DNS。

解决方案:删除sub.example.com 的主机文件条目,或进一步调查 DNS 差异。

两个测试都没有显示预期的内容

结论:问题出在服务器端,而不是客户端。

没有反应

请参阅 导致“连接被拒绝”消息的原因是什么?当 Web 服务器在端口 80 上根本没有响应时。

重定向响应

当 Web 服务器响应时,请仔细查看该响应:

< HTTP/1.1 302 Found
< Date: Mon, 07 Feb 2022 13:58:11 GMT
< Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/5.4.16
< Location: https://sub.example.com/some-page.html
< Content-Length: 216
< Content-Type: text/html; charset=iso-8859-1
<
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
...
Run Code Online (Sandbox Code Playgroud)

对于配置为将纯 HTTP 重定向到 HTTPS 的 Web 服务器来说,这是一个相当典型的响应。

第一个标头中的状态代码302 Found表示临时重定向。对于永久重定向,这将是301 Moved Permanentlyhttp 状态标头。

Location:头显示客户端重定向到的位置。

原因:当 Web 服务器配置中未定义时,Web 应用程序生成重定向到 https 或完全不同的域是很常见的。
在 Apache Web 服务器(允许它们)上,.htaccess文件也可以是重定向的源。

解决方案:调整或删除重定向,或者确保重定向变得有效并且某些内容在重定向的目标上做出响应。
经常:获取 SSL 证书并启用 TLS!

原因:重定向的目标经常被破坏,也要检查那里是否存在细微的拼写错误,我已经看到缺少/重定向到的sub.example.comsome-page.html以及错误使用的参数重定向到http://some-page.htmlhttp://wwww.example.com/http://sub.example.com/some-page.html类似的内容。
还可以通过向多个重定向级别发出请求来测试循环,Location:通常也表明配置已损坏并删除循环。

来自不同网站的内容

当您看到来自您托管的其他站点的内容而不是要查看的内容时,sub.example.com请注意,大多数 Web 服务器在无法将主机名与特定站点匹配时将显示来自默认站点的内容。

解决方案:重新检查您的配置是否有拼写错误,并确认 Web 服务器已使用更新的配置重新启动。

  • 啊,那么请将其添加到答案中 - 或者建议在“测试”部分中从不同的计算机运行“curl”,或者只是解释由于在不同的计算机上运行浏览器和curl而导致的dns差异。我不会想到默认使用跳转服务器 (3认同)