大概是在4月11-13号的样子,我们的产品突然报告了一个bug。通过初步排查后,发现后端的nginx返回给前端404。正常情况下,应该返回200的http状态码。最近没有升级过任何软件,一时没有线索。仔细分析发现,这个返回404的接口是调用微信开发接口平台的,配置如下:
location /xxx/ {
proxy_set_header Host "hide.info.com";
proxy_pass https://api.weixin.qq.com;
}
这就很是奇怪,这个配置改成这样很久了,最少已经运行了1年,从来没有报告问题,应该不可能是微信开发接口平台的问题。其实稍微观察一下上面的配置,是有一个问题的,那就是Host设置的不合理,应该设置为
proxy_set_header Host "api.weixin.qq.com";
因为一直可以正常运行,也没有仔细审查这个地方配置有缺陷。但是为什么可以正常运行这么久,仔细想了想可能是微信的开放平台之前配置了默认的Host(不能匹配*.weixin.qq.com和SERVER_IP),如果Host设置的不正确,也可以正常响应。就在2018年4月11-13号的样子,微信团队修改了配置,如果遇到不匹配的Host配置,返回404错误码。
写个博客记录下自己的推测,有知道微信开发平台内情的小伙伴可以留言哦,本人感激不尽。
写在后面的
1 得出上面的猜想,我是走了一段弯路的。我从nginx的error_log贴出发往api.weixin.qq.com请求后,是替换了域名成IP的https请求url,直接使用curl "https://IP/hide/path/info?hideparams",报告了一个错误:
curl: (51) SSL: certificate subject name (mp.weixin.qq.com) does not match target host name '58.251.61.149'
这就把我引入到了一个错误的排查方向,以为是api.weixin.qq.com的证书是否有问题,但是通过chrome访问api.weixin.qq.com,然后查看证书,很正常。一想对,用Ip访问必然会得到这个提示,很正常,自己晕了。使用
curl https://api.weixin.qq.com/hide/path/info?hideparams
retry一下,就有了正常的repose.
2 为了弄清楚问题的原因,我还专门用wireshark抓了一下nginx和api.weixin.qq.com通信的数据包,从数据包的情况可以看出nginx(tengine/nginx1.6.2) 没有在proxy_pass中检查证书的合法性。查了nginx文档,,果然如此:
Syntax: proxy_ssl_verify on | off;
Default:
proxy_ssl_verify off;
Context: http, server, location
This directive appeared in version 1.7.0.
这个默认配置为off应该是为了兼容1.7以前的版本,也就是说我使用的nginx不支持这个配置,并且运行的效果等价于这个选项配置为off.