通过 http 为 443 端口提供服务会产生 400 Bad Request Error,而不是重定向

通过 http 为 443 端口提供服务会产生 400 Bad Request Error,而不是重定向

因此,为了后代的利益,我正在尝试配置我的服务器,以便即使有人尝试访问 http://domain.com:443,他们也会被正确地重定向到该站点的 https 版本(https://domain.com)。

当测试类似 http://domain.com:443 的内容时,它无法正确重定向到 https://domain.com,而是会出现一个 400 错误请求页面,内容如下:

错误的请求

您的浏览器发送了一个此服务器无法理解的请求。原因:您正在向启用 SSL 的服务器端口发送纯 HTTP 请求。请使用 HTTPS 方案访问此 URL。

Apache/2.4.18 (Ubuntu) 服务器位于 sub.domain.com 端口 443

000-default.conf我尝试在我的中包含以下几行<VirtualHost *:80>

RewriteEngine On 
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{SERVER_NAME}/$1 [R,L]

但它没有起作用。

此问题发生在所有域、子域和服务器 IP 本身上。

可能相关,尝试执行 letsencrypt 的试运行将返回以下内容:

   Domain: domain.com
   Type:   connection
   Detail: Failed to connect to 123.123.123.123:443 for TLS-SNI-01
   challenge

对于 sites-enabled 文件夹中列出的每个域。

答案1

TL;TR:您不能在同一个端口(443)上同时提供 HTTP 和 HTTPS 服务。

虽然理论上可以根据来自客户端的第一个数据判断客户端是否正在发送 HTTP 请求(例如GET ..或类似请求)或正在启动 TLS 握手(\x16\x03...),但大多数 Web 服务器不会这样做。相反,它们希望客户端能够正常运行,即在一个端口(通常为 80)上使用纯 HTTP,在另一个端口(通常为 443)上使用 HTTPS。

您的 URLhttp://example.com:443导致浏览器向端口 443 发出纯 HTTP 请求。但服务器在那里期待 TLS,这意味着您的纯 HTTP 请求是意外的。在这种情况下,Apache 至少足够好地检查纯 HTTP 请求的传入数据,以便它可以为您提供更有用的描述:

原因:您正在使用纯 HTTP 向启用 SSL 的服务器端口发送信息。请使用 HTTPS 方案来访问此 URL。

如果您尝试使用其他服务器发出此类请求,那么他们要么会关闭连接而完全不出现任何错误,要么只是挂起,因为他们仍然希望从客户端获得 TLS 握手。

答案2

我遇到了同样的错误,罪魁祸首是我的配置试图在非 SSL 端口上启用 SSL。任何以 开头的网站地址http://都将通过端口 80 ( ) 进行传输<VirtualHost *:80>,而该主机不想知道有关 SSL 的任何信息。任何以 开头的网站都将通过端口 443 ( )https://进行传输<VirtualHost *:443>

更直接的问题是,我的*:80主机下有以下 SSL 详细信息,这使得 Apache 尝试为非 SSL 连接启用 SSL。

SSLEngine on
SSLCertificateFile /bla.crt
SSLCertificateKeyFile /bla.key
SSLCertificateChainFile /bla.crt

从中删除这些行*:80(并确保它们存在于<VirtualHost *:443>)后,我的服务器再次弹出。

因此,以下是我的<VirtualHost>s(全部,/etc/apache2/sites-available/http.conf但可能因您的设置而有所不同):

<VirtualHost *:80>

    -- snip --

    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

</VirtualHost>


<VirtualHost *:443>

    -- snip --

    SSLEngine on
    SSLCertificateFile /var/www/ssl/STAR_iconcierge_net_au.crt
    SSLCertificateKeyFile /var/www/ssl/STAR_iconcierge_net_au.key
    SSLCertificateChainFile /var/www/ssl/STAR_iconcierge_net_au.crt

</VirtualHost>

注意*:80(http) 如何对 (https) 进行重写*:443,然后使用SSLEngine on指令强制执行 SSL。

答案3

您实际上需要做的是将 Web 服务器的 HSTS 标头发送回给用户,以告知浏览器始终使用 TLS 访问网站。301从任何浏览器中的开发工具中都可以看到,这里没有发生任何重定向。

例如,Google 就发生过这种情况。当您第一次访问 Google 时,它​​会向您发送 HSTS 标头,而您的浏览器会将该标头保存到列表中。之后,当您尝试使用 连接到 时google.comhttp://浏览器会自动将连接方法更改为 ,而https://无需与远程 Web 服务器进行任何通信。

这是防止对安全层进行攻击的进一步安全机制。

答案4

<VirtualHost *:80>当您使用端口 443 访问该站点时,该部分内的任何内容都不会被处理。

测试启用 apache2 附带的默认站点的 SSL 版本,并尝试其中的 conf<VirtualHost *:443>

相关内容