无论是产品类还是方案类,在实际项目中大部分都是部署在Linux服务器中,而再基于Nginx进行代理和负载均衡、域名解析等,最终实现外部访问和使用。而在实际的部署和使用过程中,出于安全性考虑,都会进行内外网交互,进行多层安全加固。而作为中间件类产品,IDM、ESB等产品往往需要内外网的不同访问方式,从而满足不同场景。

在最近的一个集成底座(IDM MDM ESB)项目中,由于IDM提供的统一认证,而考虑到外部访问以及内部系统的认证集成,所以需要集成底座提供内、外网两种访问入口,并且保证相互的访问不会互相冲突。

总体说明

出于安全性考虑,部署在内网的集成底座不能直接释放到外网,所以需要用Nginx代理的方式将集成底座的访问入口代理到外网,从而实现从外网访问各个产品,同时需要保证内网的各个产品、接口都是可用的,从而保证内网环境下业务系统与集成底座进行集成、认证的需要。

1.业务需求

1.保证集成底座在内网环境下是可用的,包括产品的访问、各个产品功能模块,以及产品预置、通过ESB开发的各个服务接口都是可用的;

2.集成底座需要提供外网的访问入口,能够通过IP或域名的方式进行集成底座产品访问,以及产品内相关功能的正常使用;

3.保证业务系统可以和IDM平台进行CAS、OAuth认证的配置和接口调用,包括外网地址跳转,内网认证、接口调用等。

2.配置方式

基于Nginx实现内外网的代理访问,由于集成底座平台本身采用云平台的部署方案,也是使用Nginx代理实现的内网虚拟IP访问各个平台,并且通过Nginx分别代理开发、测试、生产各个不同端口的访问,该Nginx定为内网Nginx。

考虑到外网访问的需要,在服务器DMZ区部署一台外网服务器,解析外网IP,在服务器上部署Nginx,通过Ngixn代理的方式代理集成底座内网的访问地址,改Nginx定为外网Nginx。

3.问题分析

在通过内、外网Nginx代理后,内网由于都是走的内网IP,所以无论是产品访问和功能使用都不存在问题,包括和业务系统对接时的内网接口调用都是可以的。但是由于外网访问的相关配置和Nginx代理问题,导致外网访问时存在问题,问题如下:

1.外网Nginx代理之后,通过OAuth进行统一认证的系统通过外网IP访问时,在跳转统一认证登录页面时显示外网IP 内网端口;

2.外网Nginx代理之后,通过CAS认证的系统在通过外网域名访问时跳转到了集成底座内网的CAS地址上;

3.通过外网IP访问IDM平台后,在第一次登录进行密码初始化修改时,会通过到内网IP打开修改密码页面。

网络架构

针对集成底座进行内外网代理时出现的内外网IP交叉跳转的问题,进行了问题定位与排查,由于集成底座内网访问交互是没问题,所以首先考虑从网络层面进行处理,所以在内部进行单机环境环境验证,并且尽量模拟项目的网络环境。

1.单机模式

集成服务器使用说明(集成底座内外网访问配置说明)(1)

由于本地资源有限,无法模拟现场环境基于云平台、DMZ数据隔离以及网络防火墙的处理,所以采用单机进行产品部署,同时Nginx也是采用内外网两个Nginx进行处理,从而复现项目上的问题。

2.云平台模式

集成服务器使用说明(集成底座内外网访问配置说明)(2)

集成底座现场环境采用云平台的部署方案,内部部署K8S集群和相关产品,通过内网Nginx对外提供统一的访问入口,并在Nginx中配置不同的端口从而实现开发、测试、生产环境的隔离访问;再通过外网Nginx代理内网Nginx,从而提供外网的访问入口。

访问时内网通过VPN接入(或者在本地局域网访问),通过内网IP和端口直接访问内网Nginx,从而访问各个产品;外网访问时通过外网IP和端口先访问到外网Nginx,再指向内网Nginx进行内部集群和产品的访问。

3.服务器配置

本地服务器

1.准备两台服务器,具备内网和外网IP;

2.两台服务器分别部署Linux和Window系统(需要安装浏览器进行访问);

3.Linux系统下部署idm(单机部署)、数据库和Nginx(内网);

4.Window系统下部署Nginx(外网)以及浏览器,主要通过这里进行访问测试;

5.Linux:只考虑内网IP,IP:10.0.0.9,产品端口 3030,内网Nginx代理端口8007;

6.Window:只考虑外网IP,101.101.81.156,外网Nginx代理端口8008;

7.10.0.0.9和101.101.81.156两台服务器已经完成了内网的互通,可以通过内网IP相互访问,并且相互开放了防火墙,不存在端口限制。

云平台

云平台采用标准的5台服务器高可用配置,在worker1和worker2上部署Nginx集群作为统一的访问入口(内网Nginx集群),具体配置参见K8S集群高可用配置文档,这里不做过多说明。

单机验证

在本地进行单机部署,参考现场环境的Nginx、产品进行相关文件配置,模拟并复现现场环境中出现的访问时内外网相互交叉的问题,并通过Fiddle、Wireshake等工具进行抓包分析,分析具体原因并进行修复。

1.产品配置

产品主要需要配置IDM的相关文件,包括web.xml、hotweb.properties,以及idm_server和server.xml文件,CAS以及数据库、Redis等连接信息均采用内网IP进行配置。

> > > >web.xml

配置casServerLogoutUrl参数,配置为内网CAS的登出地址:

集成服务器使用说明(集成底座内外网访问配置说明)(3)

配置CAS认证信息,CAS相关地址配置为内网IP(10.0.0.9:3030/cas),server地址配置为IDM的内网IP(10.0.0.9:3030)。

集成服务器使用说明(集成底座内外网访问配置说明)(4)

> > > >hotweb.properties

主要配置数据库和Redis:均配置内网地址,由于在同一台服务器,数据库直接只用localhost:3306,Redis配置为10.0.0.9:6379(Redis配置文件限制):

集成服务器使用说明(集成底座内外网访问配置说明)(5)

> > > >server.xml

server.xml主要时在Host中添加Value配置,remoteIpHeader、portHeader、protocolHeader、protocolHeaderHttpsValue参数会和Nginx的配置进行关联。

集成服务器使用说明(集成底座内外网访问配置说明)(6)

2.nginx配置

Nginx配置分为内网Nginx配置和外网Nginx配置,内网Nginx主要处理IDM产品的访问,模拟现场环境的内网Nginx,将产品的3030端口代理成8007端口;外网Nginx用于验证外部的访问,将内网Nginx代理到外网,并代理成8008端口。

> > > >内网Ngixn

集成服务器使用说明(集成底座内外网访问配置说明)(7)

内网Nginx的listen为8007端口,proxy_pass为http://10.0.0.9:3030,直接指向内网的IDM产品,并且代理端口为8007。

在101.101.81.156服务器上通过浏览器直接访问http://10.0.0.9:8007(两台服务器已经完成了内网互通),测试结果如下:

集成服务器使用说明(集成底座内外网访问配置说明)(8)

集成服务器使用说明(集成底座内外网访问配置说明)(9)

集成服务器使用说明(集成底座内外网访问配置说明)(10)

根据测试,通过内网Nginx进行访问、密码修改、页面跳转等,内网IP、端口均为Nginx代理的IP和端口,不会出现内外网、IP端口相互混合的问题。

> > > >外网Nginx

集成服务器使用说明(集成底座内外网访问配置说明)(11)

外网Nginx的listen为8008端口,proxy_pass为http://10.0.0.9:8007,指向内网的Nginx,以及Nginx的代理端口8007。

在101.101.81.156服务器上通过浏览器直接访问http://101.101.81.156:8008,测试结果如下:

集成服务器使用说明(集成底座内外网访问配置说明)(12)

在登录时,拦截到CAS页面时出现外网IP 内网Nginx端口的问题,导致访问出错。

3.抓包分析

为了分析访问时端口异常的问题,通过Fiddle和Wireshake抓包分析,分析前后端的返回信息,从而进一步定位问题。

> > > >Fiddle

集成服务器使用说明(集成底座内外网访问配置说明)(13)

1.先通过外网地址访问,通过8008端口访问到内网,请求到IDM;

集成服务器使用说明(集成底座内外网访问配置说明)(14)

2.IDM根据访问信息,跳转到IDM的index?Login,服务端根据CAS认证进行拦截,拦截到CAS认证地址,ip:8008/cas/login;

集成服务器使用说明(集成底座内外网访问配置说明)(15)

3.发起CAS对CAS的请求时,地址显示依然时8008端口,是正常的。

通过Fiddle抓包测试,通过外网访问时,前端请求均为8008端口,并且服务端返回到前端的信息和跳转路径均为8008端口,并未出现8007端口的异常。

> > > >Wireshake

集成服务器使用说明(集成底座内外网访问配置说明)(16)

1.先通过外网地址访问,通过8008端口访问到内网,请求到IDM;

集成服务器使用说明(集成底座内外网访问配置说明)(17)

2.IDM响应,返回跳转路径:index?Login;

集成服务器使用说明(集成底座内外网访问配置说明)(18)

3.跳转index?Login,再次发起请求,还是基于外网IP和8008端口访问;

集成服务器使用说明(集成底座内外网访问配置说明)(19)

4.服务端响应,服务端返回时将8008端口改成了8007端口。

经过Wareshake抓包测试,发现是由于CAS认证拦截跳转时,通过302永久重定向,拼接访问路径时在外网IP的基础上拼接了内网Nginx端口,从而导致地址访问异常。

4.调整验证

根据后端返回的信息,发现是由于服务端处理端口的问题,所以要进行端口处理,但根据Wireshake抓包测试,发现是由于服务端拼接了内网Nginx端口,而通过查找Nginx的相关配置,尝试通过proxy_redirect的方式实现外网Nginx的重定向,即内网返回response时,外网Nginx将ip和端口信息进行替换,替换为外网ip和端口。如图所示:

集成服务器使用说明(集成底座内外网访问配置说明)(20)

调整之后进行访问测试:

集成服务器使用说明(集成底座内外网访问配置说明)(21)

集成服务器使用说明(集成底座内外网访问配置说明)(22)

登录页和登录之后均可以正常访问,相关IP和端口也均为外网IP和端口,功能正常,测试通过。

集群验证

在内部测试通过后需要在现场环境,即云平台环境进行测试,由于云平台采用K8S部署,K8S内部还存在ingress-nginx,所以也要进一步进行测试,特别是现场环境涉及多个产品以及内外网的交叉访问,同时也会涉及到到其他系统对于接口的调用,所以会更加复杂。

1.IDM配置

web.xml

集成服务器使用说明(集成底座内外网访问配置说明)(23)

集成服务器使用说明(集成底座内外网访问配置说明)(24)

server.xml

集成服务器使用说明(集成底座内外网访问配置说明)(25)

2.Nginx配置

Nginx配置也是分为内网Nginx和外网Nginx,其中内网Nginx是在进行K8S集群部署时配置的,主要时通过Nginx配置vip,然后代理访问K8S集群内部的开发、测试、生产等不同的环境。

> > > >内网Nginx

集成服务器使用说明(集成底座内外网访问配置说明)(26)

内网Nginx通过指定82端口为生产环境端口,通过proxy_pass配置指向K8S集群的ingress-nginx地址,再基于K8S的集群管理访问到容器内的各个产品。

> > > >外网Nginx

集成服务器使用说明(集成底座内外网访问配置说明)(27)

外网Nginx直接配置外网访问的代理端口8008,location中通过proxy_pass指向内网Nginx下的82端口,并通过proxy_redirect进行重定向,将内网的82端口重定向成外网的8008。

注意:云平台模式和单据模式有一定不同,单据模式proxy_redirect时是将外网IP:内网Port重定向成外网IP:外网Port,但云平台需要内网IP:内网Port重定向成外网IP:外网Port,这个主要是由于内网的ingress-nginx做了处理,返回外网时是内网IP:内网Port。

3.抓包分析

由于现场环境都是部署再Linux服务器上,而Linux服务器是无法通过Wireshake进行抓包分析,所以采用Tcpdump进行抓包,并生成对应的文件,再将文件导入Wireshake进行分析。

tcpdump命令:tcpdump -c 5000 -i ens33 host xxx.xx.xx.69 and port 22 -w /opt/tcpdump.cap;

解释:tcpdump -c 抓抓取数据包量 -i 网卡 host IP地址and port 端口 -w 生成的文件路径。

抓包结果如下(Nginx调整前):

集成服务器使用说明(集成底座内外网访问配置说明)(28)

1.先通过外网地址访问,通过8008端口访问到内网,请求到IDM;

集成服务器使用说明(集成底座内外网访问配置说明)(29)

2.IDM响应,返回跳转路径:index?Login,显示的地址和端口依然是外网信息;

集成服务器使用说明(集成底座内外网访问配置说明)(30)

3.跳转index?Login,再次发起请求,还是基于外网IP和8008端口访问;

集成服务器使用说明(集成底座内外网访问配置说明)(31)

4.服务端响应,服务端返回时直接返回了内网IP和内网端口(这里和单机不一一致,通过定位确认是ingress进行了处理)。

集成服务器使用说明(集成底座内外网访问配置说明)(32)

5.再次发起请求,虽然能成功访问,但是直接跳转到了内网IP和端口上。

根据抓包分析以及在内部单机测试的结果,调整外网Nginx的配置文件,添加proxy_redirect的配置,将内网的IP和端口重定向到外网的IP和端口,即可正常访问,并且内外网访问时也不会出现冲突,相关的接口调用也正常,测试通过。

分析总结

本次工作时第一次在项目中碰到如此复杂的网络处理,之前在其他项目中,通过Nginx代理或者配置相关的域名都能很快解决问题,但是本次花费大量时间进行问题定位,不过收获也是比较大的,对于Fiddle、Wireshake、tcpdump都更加熟悉了,后续也能更加熟练地使用,对于集成底座在实际项目中内网的交互方式也更加清晰。

1.问题总结

服务器和网络问题一直都是实际项目工作中的薄弱项,在项目中经常会遇到类似的内外网交互、跳转、不同网络下的各业务系统接口调用、数据同步分发等场景,所以更多地掌握服务器和网络相关知识是非常有必要的,在项目中遇到相关问题也可以快速定位解决,避免因为这些外部因素影响项目的交付效果。

2.技术提升

本次定位处理过程不仅解决了项目上的问题,更重要的是对于相关的工具、网络等有了更深的认知,特别是Fiddle、Wireshake、tcpdump等,这是非常重要的,在后续的项目中如果遇到类似的问题,也能有更好的定位方案。

1.Fiddle:属于客户端抓包工具,可以直接对浏览器访问进行拦截和抓取,获取浏览器请求的相关信息,和浏览器开发模式获取网络信息类似,但Fiddle或更加直观和全面,不会被,出现网络等相关问题时,先考虑用Fiddle抓包查看;

2.Wireshake:属于服务端抓包工具,能够抓取服务端的数据包,对于Nginx反复交互的环境,由于返回到浏览器的数据包是经过了Nginx的,所以Fiddle抓包时是无法抓取服务端的原始响应的,所以就要通过Wireshake获取服务端原始响应数据,才能更好定位问题;

3.Tcpdump:和Wireshake类似,也是服务端的抓包工具,但是由于Wireshake只有Window客户端,不能直接在Linux下应用,而实际项目绝大部分都是部署在Linux服务器的,所以要通过Wireshake和Tcpdump结合的方式,通过Tcpdump抓取数据包并生成文件,再导入到Wireshake中进行图形化查看和分析。

3.个人总结

本次项目总结除了对个人技术能力进行了提升,对于自身暴露出来的问题,也做了总结,在项目中遇到棘手的问题一定要第一时间进行反馈,如果解决不了要及时协调资源,寻求他人协助时要将业务场景和问题描述清楚,像这次问题定位时实际在之前的项目中处理过类似的环境,但当时用域名的方式并未发生问题,所以在反馈没有及时反馈,导致前期调整时走了不少弯路,反复对产品进行调整,后续在工作中一定要避免类似的问题。

对于个人而言,本次工作对于个人能力短板的弥补是非常有用的,因为集成底座项目后续都会采用云平台的部署方案,基于云平台环境下网络、Nginx、产品等相关的配置和处理会显得非常重要,所以这方面能力的加强非常有利于后续项目的开展。作为一名技术人员,项目实施过程中对于产品、方案、环境等相关知识的熟练程度会直接影响项目交付的效果,影响客户的直观感受,有问题不可怕,能够快速定位、解决问题才能获得客户认可和肯定。

本文由@数通畅联原创,欢迎转发,仅供学习交流使用,引用请注明出处!谢谢~

,