接口403问题没这么容易解决

2020-09-22 16:09:03 浏览数 (1)

最近一同事反馈在后台保存某业务数据时一直报403,该数据由运营人员在后台录入,然后向后端发送POST请求保存数据;现象是如果内容过长如几十K则报403,如果只输入几个字符则没问题,多方排查无解。

这是一个典型的LNMP应用架构,WEB是Nginx,后端应用是PHP,数据库是Mysql。

出现问题第一反应是查日志,按这些链路查:

1、Nginx错误日志

一般403、502之类的Nginx错误日志中中相应记录;

每个server有error_log的配置,查找日志中是否有无线索;

2、PhpFpm日志

Php用的是PhpFpm作为容器,其也有error_log指令,可以查看这个日志有无响应线索;

3、应用日志

这个根据应用自己的情况搜索。

通过上述排查,都无线索。

日志不行再查配置,Nginx对body有些限制参数:

代码语言:javascript复制
client_max_body_size           8M;

但上述场景才几十K,所以这个可能性排除。

再看Php的配置,Php也有相关Post参数,如

代码语言:javascript复制
post_max_size = 25M
max_input_var=5000

post_max_size是限制请求体大小,而max_input_var是限制post中有多少个key的,案例也没有超过这些限制。

这些都不行,只能抓包了,nginx和php-fpm之间是通过fastcgi协议传输的,因为配置的upstream是127.0.0.1,因此要抓下本地回环的包:

代码语言:javascript复制
tcpdump -i lo port 9000 -w /tmp/php.pcap

先看下正常的包,即只输入几个字符的情况:

上述场景我们输入的是123456789,抓包发现nginx是有将相应内容传递给PHP的,这里涉及到fastcgi协议的格式,因重点不是这个,有兴趣的同学可以自行百度下。

然后抓下输入为几十k的请求:

发现内容根本就没传递过去,因为我们的Nginx上有很多配置,为了调试方便先把一些不用的配置去掉,再删掉2处Lua的配置后重新启动Nginx,接口提交成功了。

再仔细分析一下其中一行Lua配置,原来是Lua防火墙,对一些敏感关键字做了处理,如果发现在相应内容会将内容清空,并返回错误,奇怪的是这些异常情况竟然没有错误日志。

短期解决办法是将防火墙相关配置关闭,长期还是需要对防火墙结合业务场景进行梳理,提高拦截的准确率,并且在拦截时提供相应日志便于快速定位问题。

最后总结下,主要问题是Lua防火墙对输入内容进行了拦截,但是拦截后没有明显的日志,导致排查问题比较麻烦。

本次排查问题的思路:

1、查日志

先中间件,如Nginx、PhpFpm,然后是应用日志

2、分析中间件配置

3、抓包分析

主要是验证传输链路有没问题,快速定位出问题的环节

如果上述还是无法解决问题,只有Debug源代码了。

0 人点赞