一个奇怪的问题定位——https服务丢失post信息

背景

我有个网站A,其中一些功能,考虑到其他的网站可能也会使用,所以抽取出来,做成了服务形式,部署到了域名B上。

网站A是对外可供访问的,出于SEO、安全等各方面的考虑,部署成了https访问的方式,例如 "https://www.poisonbian.com/"  这样的形式。

服务B,说是服务,但实际上也是通过http方式提供服务的,只是代码、域名、数据库等,是剥离开的。这个服务本身不对用户提供访问,主要是内部使用,因此为了提高访问速度,并没有使用https。例如 "http://api.poisonbian.com/Service/abc"  这样。实际上,网站A会通过POST的方式,传一些参数给服务B,以获得结果。


其中,网站A和服务B,都是部署在百度云的BCH(虚拟主机)上的。有一天,突然发现网站A的一些功能出问题了。


排查过程

经过排查,发现网站A的页面访问没有问题,但是调用服务B的时候出错了。

到apifox里面,去直接测试服务B的接口 http://api.poisonbian.com/Service/abc ,发现返回的结果确实和预期不符合。报了一个我自定义的错误信息,叫做“id”参数缺失。


这个服务接口有一个逻辑,会从$_POST中去获取“id”参数进行校验。可是我在apifox中,设置了POST的参数呀?


进一步,我尝试写了一个最简单的代码:

<?php
var_dump($_POST);


继续在apifox中测试,是否能够打印出来我传的POST参数。结果,无论我怎么传参,打印出来的结果都是一个空数组。


思路和解决方案

尝试了一些方式,比如reload或重启服务,都没有解决问题。试了一下百度云的其他服务器,并没有这样的问题。


本来都发起了一个工单,打算让百度云的工程师帮助定位问题了。提交了问题之后,继续去想,出问题的那个时间点,到底做过什么操作。

突然想到,当时有做过一个操作,是更新了所有网站的https证书(证书3个月过期,因此需要重新更新一次)。是否是证书出什么问题了呢?


可是,我这个网站并没有开启https访问,不应该受到影响啊。


但毕竟是个思路,还是先看看服务面板里面的域名绑定。

image.png

不检查不要紧,一检查,发现了问题。不知道这个SSL状态,为什么也是个“已启用”状态。

也就是说,我访问的虽然是 http://api.poisonbian.com/Service/abc 这样的http服务,但实际上最后是落到了 https://api.poisonbian.com/Service/abc 这个url上。


而且,因为我是在apifox里面测试的,实际上我并没有注意到http已经被转到https了。


好,那先赶紧把这个域名的https访问关闭。关闭之后,果然服务正常了,能够获得$_POST的内容了!


继续验证

所以,问题其实是出现在http转https的过程中。


这个过程,对我们来说其实是不可见的。可是,我们可以验证一下,http转https时,是否真的有问题。


于是,我到nginx配置文件中增加了这样一些代码:


set $flag2 "${scheme}|${request_method}";
add_header orz_flag2 "${flag2}";


继续测试,例如,给 https://api.poisonbian.com 发POST请求,看响应的header。这个显示的是“http|POST”。

再试试给http开头的url发POST请求,结果显示的是“http|GET”。


这样的话,其实有两个问题:

  1.  http还是https,正常来说,应该能够通过scheme变量来判断。根据百度云的文档,也是这么说的。可是,看起来并不行。

  2.  如果开启了https访问,误访问到http时,如果是POST请求,被转到https地址时,POST的内容会丢失。


因此,有了一些推测:

BCH实际是有一些用户不可访问、修改的Nginx配置。个人猜测,BCH可能是直接对开启了https访问的域名,做了rewrite跳转,而我们收到的请求响应,是跳转后的。而且,对于POST请求,也是通过rewrite实现的,这就会导致POST、DELETE等非GET类型请求的参数丢失。


正确的做法,应该是判断request_method为POST后,通过proxy_pass的方式进行设置,而非rewrite。


这个问题排查后的结论推测,我也在百度云上面发起了一个工单,作为建议提给他们了。如果后续有进展,我会再写一下。

本文链接:https://www.poisonbian.com/post/5042.html 转载需授权!

分享到:
原文链接:,转发请注明来源!
「一个奇怪的问题定位——https服务丢失post信息」评论列表
poisonbian
poisonbian
发布于 2023-04-25 11:15:52  回复
不得不说,百度云的工程师,回复还是很快的。
一开始给我的回复是:
1. 问题1($scheme变量区分不出来http还是https)受限于产品架构,短期内无法解决。(那好歹改下文档吧。。)
2. 问题2(http到https,POST被转成了GET),建议我用自定义的proxy_pass配置来做覆盖。
看起来还挺用心,但是呢,问题2一细想,这个也依赖问题1啊!如果说,我都区分不出来现在的请求是https,那我咋走proxy_pass?于是继续追问,过了阵子答复是,他们重新理了下逻辑,确实没错,所以也解决不了啦。。

发表评论