现象:
老架构:
nginx:10.25.198.254
auth:10.26.106.225
新架构:
nginx:172.31.10.48
auth:172.31.10.43 10.136.22.3(容器IP)
auth:172.31.10.44 10.136.23.3(容器IP)
新架构迁移后,在配置程序完全一样的情况下,出现https 协议无法传输。
排查过程
1、仔细比对 tomcat配置,nginx 配置,采用复制等方式,发现问题依旧
2、分析网络结构对 该问题的影响,并未发现问题
3、抓包分析传递的协议头,并未发现问题
4、逐行修改可修改(更换同等效力)的配置行 ,发现了影响点
5、验证影响点,确定影响点为 upstream 中 server 地址会影响https 协议传输
验证该问题,编写python 服务后端,和 jsp 服务后端,发现python可以正常传递,jsp 无法正常传递
6、咨询 tengine 和 阿里云,双方均表示没见过此问题无法解决。
验证:
以新架构 tengine (nginx)服务器为镜像,新建服务器,安装tomcat7 (和docker 容器版本一致),部署auth 程序,新增 tgauth.gstarcad.com
在upstream 中
当 server 为本地 eth0 地址的时候 即:
upstream tgauth {
server 172.31.10.56:8080;
}
https 协议无法传输
当 server 为 localhost 、127.0.0.1 的时候 即:
upstream tgauth {
server localhost:8080;
}
upstream tgauth {
server 127.0.0.1:8080;
}
是可以正常传递https
怀疑tomcat 本身有什么机制,升级至tomcat8,发现无论是什么地址 https 协议均可正常传输,
去 tomcat 官方寻找线索,找到一篇文章(源码):
tomcat8:
http://tomcat.apache.org/tomcat-8.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html
tomcat7:
http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html
简单描述
tomcat7 在 https 协议传出的时候 是有ip白名单的
tomcat7 仅支持 IP 为
10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}| 169\.254\.\d{1,3}\.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}| 0:0:0:0:0:0:0:1|::1
By default, 10/8, 192.168/16, 169.254/16, 127/8 and ::1 are allowed.
的ip 传输 https 协议,我累个大擦。
tomcat8 支持IP为
10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}| 169\.254\.\d{1,3}\.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}| 172\.1[6-9]{1}\.\d{1,3}\.\d{1,3}|172\.2[0-9]{1}\.\d{1,3}\.\d{1,3}| 172\.3[0-1]{1}\.\d{1,3}\.\d{1,3}| 0:0:0:0:0:0:0:1|::1
By default, 10/8, 192.168/16, 169.254/16, 127/8, 172.16/12, and ::1 are allowed.
由此可见 tomcat 7 不允许 172.31.10.0/24 段传输https 协议
问题找到,根据官方建议升级tomcat7 或者使用临时参数
internalProxies="172\.31\.10\.56" protocolHeader="X-Forwarded-Proto"/>
解决。
总结:
诡异问题还是官方靠谱,没事多看看官方文档。
该升级的升级为 新的jdk 和 tomcat,要适应潮流。