背景:由于apache某版本的安全漏洞问题,要求把生产环境所有apache全部替换成nginx。
环境:apache2.2.31-->nginx1.16.0, 项目服务器部分在不同的地理位置,当用户登陆时会根据IP自动选择就近服务器。所以当一个美国用户在中国的网段登陆时,他会先登陆到中国服务器,而后根据一定条件(eg:cookie中language字段为en_us),代理到美国服务器上。
----------------------------翻车开始--------------------------------
直接切入翻车点,由于疏忽在配置location时,添加header字段时,添加了两次$host:
中国区服务器nginx配置:
location ~* ^/us(.*)$ {
proxy_set_header Host $host;(1)
proxy_set_header Host $host;(2)
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://us1-xxx.com
}
测试时,没有考虑只替换了一边服务器的情况,即nginx请求代理到的us1服务器上还运行的apache。一来我就把两台服务器(ch和us都部署好了nginx),nginx可以识别多字段的host,并选择最后一个host(2)传给us1,所以在测试环境,两台nginx通信没有问题。但是生产环境不能两台服务器一起断开,只有一台一台替换,没有问题,再下一台,这样就出现了nginx代理到apache服务器的场景,apache不会这样处理多host的情况,他会原原本本把所有host以逗号拼接起来,传给us1的domain为"(1),(2)",tomcat默认是无法识别包含逗号的分隔符的,域名带逗号分来也是非法域名,故在代理时会报400 bad request错误。
排查了好久,甚至想到会不会因为apache ssh证书和nginx ssl证书不兼容导致,还想去安装抓包工具抓包看- -,后面同事一句惊醒:如果SSL有问题,浏览器就显示的图标就会不一样啊!(chrome浏览器在URL处会是一把叉掉的锁)。
配置文件一定要仔细啊,以上的问题,nginx -t也检查不出来,还是要仔细仔细再仔细!翻车翻在阴沟里太酸爽了哈哈哈哈。