将 HTTP 流量从 443 端口重定向到 SSL

Redirect HTTP traffic from 443 port to SSL

我有一个网站 www.example.com 使用 RewriteEngine 将 HTTP 流量重定向到 HTTPS:

<VirtualHost *:80>
    ServerAdmin webmaster@example.com
    ServerName example.com
    ServerAlias www.example.com

    DocumentRoot /var/www/example.com/
    ....

    RewriteEngine on
    RewriteCond %{HTTP_HOST}   ^example.com [NC]
    RewriteRule   ^(.*)$ https://www.example.com  [L]
    RewriteCond %{SERVER_PORT} ^80$
    RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
</VirtualHost>

我发现的问题是 google 已经索引了这个 URL:

http://www.example.com:443

出现此错误:

我尝试重定向流量,添加来自 80 和 443 虚拟主机的永久重定向:

<VirtualHost *:80>
    ...
    RewriteEngine on
    #RewriteCond %{HTTP_HOST}   ^example.com [NC]
    #RewriteRule   ^(.*)$ https://www.example.com  [L]
    #RewriteCond %{SERVER_PORT} ^80$
    RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
</VirtualHost>

<VirtualHost *:443>
    ...
    RewriteEngine on
    RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
</VirtualHost>

没有成功。从 http://www.example.com:443 (and derived pages) to https://www.example.com 重定向所有流量的正确方法是什么?

What's the right way to redirect all traffic from http://www.example.com:443 (and derived pages) to https://www.example.com?

没有这样的方法:

  • http://www.example.com:443表示建立TCP连接到443端口,然后直接讲HTTP
  • https://www.example.com:443 表示建立到端口 443 的 TCP 连接,进行 TLS 握手,然后在该 TLS 连接内使用 HTTP。

如您所见,两种访问都使用到同一端口的 TCP 连接,但一个访问服务器使用 HTTP,而另一个使用 TLS 访问同一服务器(相同的主机和端口意味着相同的服务器)。虽然理论上可以区分 HTTP 请求(http://...:443)和 TLS 握手的开始(https://...:443)并分别处理它们,但服务器通常不支持这种功能,因为通常的方法是将端口 80 用于 http,将端口 443 用于 https。

这意味着,服务器期望在端口 443 进行 TLS 握手。服务器检测到它没有获得 TLS 握手,而是收到 HTTP 请求,并且 returns "Bad Request" 消息发送到客户端,解释说这是对该端口的错误请求。