近期遇到某一线上系统突然爆出400错误,此系统是由OpenResty进行反向代理,并做了OIDC的单点登录配置,正常运行已经一年有余。突然报错,首先想到会不会是Openresty/Lua模块有Bug导致的问题,于是进行了重启,问题依然存在。但是被反向代理的目标网站在内网中确是可以被访问的。
接着从Chrome浏览器的开发者工具中拷贝出这个请求的curl命令:
curl -I 'https://xxx.xxx.cn/' \
-H 'authority: xxx.xxx.cn' \
-H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9' \
-H 'accept-language: zh-CN,zh;q=0.9' \
-H 'cache-control: no-cache' \
-H 'cookie: AWSALB=xxxxxx; AWSALBCORS=xxxxxx; session=xxxxxx......; session_2=xxxxxx....' \
-H 'pragma: no-cache' \
-H 'sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="102", "Google Chrome";v="102"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "macOS"' \
-H 'sec-fetch-dest: document' \
-H 'sec-fetch-mode: navigate' \
-H 'sec-fetch-site: none' \
-H 'sec-fetch-user: ?1' \
-H 'upgrade-insecure-requests: 1' \
-H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36' \
--compressed
直观的发现请求的Cookie中session以及session_2非常长,这个session的生成有可能是AWS ELB、Okta升级或OpenResty OIDC模块产生,转而考虑是否由请求体太大导致请求失败,于是调整了请求体参数“client_max_body_size”为100M,但是依然报400错误。于是登录内网请求源网站,发现400错误是由源站返回。
由于Openresty实现了OIDC,因此源站是使用header确定登录用户的,所以源站不需要保持session header,有了这个前提,便可以看看是否能够直接删除这两个巨大的cookie:
set $altered_cookie $http_cookie;
# check if the "session_2" cookie is present
if ($http_cookie ~ '(.*)(^|;\s)session_2=("[^"]*"|[^\s]*[^;]?)(\2|$|;$)(?:;\s)?(.*)') {
set $altered_cookie $1$4$5;
}
# check if the "session" cookie is present
if ($http_cookie ~ '(.*)(^|;\s)session=("[^"]*"|[^\s]*[^;]?)(\2|$|;$)(?:;\s)?(.*)') {
set $altered_cookie $1$4$5;
}
# hide original "Cookie" header
proxy_hide_header Cookie;
# set "Cookie" header to the new value
proxy_set_header Cookie $altered_cookie;
通过如上命令删除Cookie后,网站访问正常。最终这两个巨大的Cookie从何而来并没有深究(极大概率是OIDC插件导致的),其原因在于这个系统是一个Legacy的系统,使用频率也不高,它的生命周期已经到了后期,很快就会下线。记录这次排查经历,希望对遇到类似问题的人们有所帮助。