apache 在服务器上检测 HTTPS 与 HTTP 没有任何用处

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/552162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 17:16:36  来源:igfitidea点击:

Detecting HTTPS vs HTTP on server sending back nothing useful

phpapachesslhttps

提问by random

So kind of very similar to "Detecting https requests in php":

非常类似于“在 php 中检测 https 请求”:

Want to have https://example.com/pog.phpgo to http://example.com/pog.phpor even vice versa.

想要https://example.com/pog.phphttp://example.com/pog.php甚至反之亦然。

Problems:

问题:

  • Can't read anything from $_SERVER["HTTPS"] since it's not there
  • Server is sending both requests over port 80, so can't check for 443 on the HTTPS version
  • apache_request_headers()and apache_response_headers()are sending back the same thing
  • Can't tell the loadbalancer anything or have it send extra somethings
  • Server feedback data spat out by the page on both URL calls is exactly the same save for the session ID. Bummer.
  • 无法从 $_SERVER["HTTPS"] 读取任何内容,因为它不存在
  • 服务器正在通过端口 80 发送两个请求,因此无法在 HTTPS 版本上检查 443
  • apache_request_headers()并且apache_response_headers()正在发回同样的东西
  • 不能告诉负载均衡器任何东西或让它发送额外的东西
  • 页面在两个 URL 调用上输出的服务器反馈数据与会话 ID 完全相同。无赖。

Are there any on page ways to detect if it's being called via SSL or non-SSL?

是否有任何页面上的方法来检测它是通过 SSL 还是非 SSL 调用?

Edit: $_SERVER["HTTPS"]isn't there, switched on or not, no matter if you're looking at the site via SSL or non-SSL. For some reason the hosting has chosen to serve all the HTTPS requests encrypted, but down port 80. And thusly, the $_SERVER["HTTPS"]is never on, not there, just no helpful feedback on that server point. So that parameter is always be empty.

编辑$_SERVER["HTTPS"]不存在,无论您是通过 SSL 还是非 SSL 查看站点,都已打开或未打开。出于某种原因,主机选择为所有加密的 HTTPS 请求提供服务,但在端口 80 下。因此,$_SERVER["HTTPS"]永远不会打开,不在那里,只是在该服务器点上没有有用的反馈。因此该参数始终为空。

(And yeah, that means it gets flagged in say FF or Chrome for a partially invalid SSL certificate. But that part doesn't matter.)

(是的,这意味着它在 FF 或 Chrome 中被标记为部分无效的 SSL 证书。但这部分并不重要。)

Also, the most that can be gotten from detecting the URL is up to the point of the slashes. The PHP can't see if the request has httpsor httpat the front.

此外,从检测 URL 中可以获得的最多的是斜线点。该PHP无法查看该请求是否具有httpshttp在前面。

回答by gahooa

Keyword -- Load Balancer

关键字 -- 负载均衡器

The problem boils down to the fact that the load balancer is handling SSL encryption/decryption and it is completely transparent to the webserver.

问题归结为负载平衡器正在处理 SSL 加密/解密的事实,并且它对网络服务器完全透明。

Request:  Client -> 443or80 -> loadbalancer -> 80 -> php
Response: PHP -> 80 -> loadbalancer -> 443or80 -> Client

The real question here is "do you have control over the load balancer configuration?"

这里真正的问题是“您是否可以控制负载平衡器配置?”



If you do,there are a couple ways to handle it. Configure the load balancer to have seperate service definitions for HTTP and HTTPS. Then send HTTP traffic to port 80 of the web servers, and HTTPS traffic to port 81 of the webservers. (port 81 is not used by anything else).

如果你这样做,有几种方法可以处理它。将负载平衡器配置为具有针对 HTTP 和 HTTPS 的单独服务定义。然后将 HTTP 流量发送到 Web 服务器的端口 80,将 HTTPS 流量发送到 Web 服务器的端口 81。(端口 81 不被其他任何东西使用)。

In apache, configure two different virtual hosts:

在apache中,配置两个不同的虚拟主机:

<VirtualHost 1.2.3.4:80>
   ServerName foo.com
   SetEnv USING_HTTPS 0
   ...
</VirtualHost>

<VirtualHost 1.2.3.4:81>
   ServerName foo.com
   SetEnv USING_HTTPS 1
   ...
</VirtualHost>

Then, the environment variable USING_HTTPSwill be either 1|0, depending on which virtual host picked it up. That will be available in the $_SERVERarray in PHP. Isn't that cool?

然后,环境变量USING_HTTPS将是1| 0,取决于哪个虚拟主机拿起它。这将$_SERVER在 PHP的数组中可用。这不是很酷吗?



If you do not have access to the Load Balancer configuration, then things are a bit trickier. There will not be a way to definitively know if you are using HTTP or HTTPS, because HTTP and HTTPS are protocols. They specify how to connect and what format to send information across, but in either case, you are using HTTP 1.1 to make the request. There is no information in the actual request to say if it is HTTP or HTTPS.

如果您无权访问负载均衡器配置,那么事情就有点棘手了。没有办法明确知道您使用的是 HTTP 还是 HTTPS,因为 HTTP 和 HTTPS 是协议。它们指定如何连接以及通过什么格式发送信息,但在任何一种情况下,您都使用 HTTP 1.1 来发出请求。实际请求中没有信息说明是HTTP还是HTTPS。

But don't lose heart. There are a couple of ideas.

但不要灰心。有几个想法。

The 6th parameter to PHP's setcookie()function can instruct a client to send the cookie ONLY over HTTPS connections (http://www.php.net/setcookie). Perhaps you could set a cookie with this parameter and then check for it on subsequent requests?

PHPsetcookie()函数的第 6 个参数可以指示客户端仅通过 HTTPS 连接 ( http://www.php.net/setcookie)发送 cookie 。也许您可以使用此参数设置 cookie,然后在后续请求中检查它?

Another possibility would be to use JavaScript to update the links on each page depending on the protocol (adding a GET parameter).

另一种可能性是使用 JavaScript 根据协议更新每个页面上的链接(添加 GET 参数)。

(neither of the above would be bullet proof)

(以上都不是防弹的)

Another pragmatic option would be to get your SSL on a different domain, such as secure.foo.com. Then you could resort to the VirtualHost trick above.

另一个实用的选择是将 SSL 放在不同的域上,例如secure.foo.com. 然后你可以求助于上面的 VirtualHost 技巧。



I know this isn't the easiest issue because I deal with it during the day (load balanced web cluster behind a Cisco CSS load balancer with SSL module).

我知道这不是最简单的问题,因为我在白天处理它(负载均衡网络集群在带有 SSL 模块的 Cisco CSS 负载均衡器后面)。

Finally, you can always take the perspective that your web app should switch to SSL mode when needed, and trust the users NOT to move it back (after all, it is their data on the line (usually)).

最后,您始终可以认为您的 Web 应用程序应该在需要时切换到 SSL 模式,并相信用户不会将其移回(毕竟,这是他们在线上的数据(通常))。

Hope it helps a bit.

希望它有点帮助。

回答by nabrond

$_SERVER["HTTPS"] isn't there, switched on or not, no matter if you're looking at the site via SSL or non-SSL. For some reason the hosting has chosen to serve all the HTTPS requests encrypted, but down port 80. And thusly, the $_SERVER["HTTPS"] is never on, not there, just no helpful feedback on that server point. So that parameter is always be empty.
$_SERVER["HTTPS"] 不存在,无论是否打开,无论您是通过 SSL 还是非 SSL 查看站点。出于某种原因,主机选择为所有加密的 HTTPS 请求提供服务,但在端口 80 下。因此,$_SERVER["HTTPS"] 永远不会打开,不在那里,只是在该服务器点上没有有用的反馈。因此该参数始终为空。

You gotta make sure that the provider has the following line in the VHOST entry for your site: SSLOptions +StdEnvVars. That line tells Apache to include the SSL variables in the environment for your scripts (PHP).

您必须确保提供商在您站点的 VHOST 条目中包含以下行: SSLOptions +StdEnvVars. 该行告诉 Apache 在脚本 (PHP) 的环境中包含 SSL 变量。