在没有HTTPS的情况下访问启用了SSL的站点时,Apache会发送纯文本响应

我从来没有遇到过这样的事情。 我试图简单地redirect页面到HTTPS版本,如果它确定HTTPSclosures,而是显示一个HTML页面,而不是实际redirect; 甚至更奇怪,它显示为文本/平原!

VirtualHost声明(sorting):

ServerAdmin [email protected] DocumentRoot "/path/to/files" ServerName example.com SSLEngine On SSLCertificateFile /etc/ssh/certify/example.com.crt SSLCertificateKeyFile /etc/ssh/certify/example.com.key SSLCertificateChainFile /etc/ssh/certify/sub.class1.server.ca.pem <Directory "/path/to/files/"> AllowOverride All Options +FollowSymLinks DirectoryIndex index.php Order allow,deny Allow from all </Directory> RewriteEngine On RewriteCond %{HTTPS} off RewriteRule .* https://example.com:6161 [R=301] 

页面输出:

 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>301 Moved Permanently</title> </head><body> <h1>Moved Permanently</h1> <p>The document has moved <a href="https://example.com:6161">here</a>.</p> <hr> <address>Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/1.0.0e DAV/2 Server at example.com Port 443</address> </body></html> 

我试着把重写的东西放在SSL的东西上面,希望它能做些什么,什么都不会发生。 如果我通过HTTPS查看页面,它应该显示得很好。 很明显,我正在尝试重写path,但这不是在行动。

Apache的错误日志并不表示可能出错的任何东西。

当我删除重写规则时:

 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>400 Bad Request</title> </head><body> <h1>Bad Request</h1> <p>Your browser sent a request that this server could not understand.<br /> Reason: You're speaking plain HTTP to an SSL-enabled server port.<br /> Instead use the HTTPS scheme to access this URL, please.<br /> <blockquote>Hint: <a href="https://example.com/"><b>https://example.com/</b></a></blockquote></p> <p>Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.</p> <hr> <address>Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/1.0.0e DAV/2 Server at example.com Port 443</address> </body></html> 

我得到了标准的“你不能这样做,因为你不使用SSL”的响应,这也是在文本/平原提供,而不是呈现为HTML。 这是有道理的,它应该只适用于启用HTTPS的连接,但我仍然希望将它们redirect到HTTPS连接,当它确定它没有启用。

思考我可以绕过这个系统:

我试图添加ErrorDocument 400 https://example.com:6161到configuration文件,而不是使用RewriteRules,这只是给了我一个新的消息,仍然没有奶酪。

 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>302 Found</title> </head><body> <h1>Found</h1> <p>The document has moved <a href="https://example.com:6161">here</a>.</p> <hr> <address>Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/1.0.0e DAV/2 Server at example.com Port 443</address> </body></html> 

我如何强制Apache实际redirect,而不是显示以纯文本格式显示HTML的“301”页面?

首先:使用Apache,不能在同一端口上运行HTTPS和HTTP。

请参阅: Apache在同一个端口上同时回答HTTP和HTTPS

要处理SSL和非SSLstream量,您必须定义两个虚拟主机。

请参阅: 将httpredirect到不同端口上的https apache

对于从非SSL虚拟主机到SSL虚拟主机的redirect,我们使用这个:

 <VirtualHost *:80> RewriteEngine on RewriteCond %{HTTPS} !=on RewriteCond %{HTTP_HOST} ^(.*)$ RewriteRule ^(.*)/? https://%1$1 [L,R] </VirtualHost> 

仍然存在的问题是,向启用SSL的端口显式发送非SSL请求( http://mydomain.com:443/ )会导致:

 You're speaking plain HTTP to an SSL-enabled server port 

页面为纯文本(在Firefox浏览器中)。 将SSL请求显式发送到非SSL端口( https://mydomain.com:80/ )会给出:

 ssl_error_rx_record_too_long error 

(在Firefox浏览器中)。

为什么会发生?