前言
本篇文章是前一篇《Linux源进源出》的后续,有些场景在那里有更详细的介绍,为能更方便的读懂本文,建议先阅读 《Linux源进源出》。
负载均衡介绍
负载均衡英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器。常用的负载均衡软件有Nginx,HAProxy,他们功能不在这里复述。
负载均衡部署时一般使用反射代理方式,即由负载均衡代理真实的服务器,用户需要访问业务时,首先访问的是负载均衡,再由负载代理用户去访问服务器。在整个代理过程中,服务器收到请求的源IP都为负载均衡的IP,等于服务器无法感知用户的真实源IP,可能会出现无法溯源等的安全隐患。虽然在大数场景下可以通过在HTTP头中添加X-Forwarded-For字段以记录用户的真实IP,但是仍有部分场景的需求无法解决。
下面介绍一种方式,在完全保留负载均衡功能的情况下,让服务器收到请求的源IP都为用户的真实IP,无需额外添加X-Forwarded-For字段,完全解决服务器获取用户的真实源IP的需求。
下面只介绍HAProxy的实现方式,Nginx暂不讨论。
HAProxy配置
HAproxy组件要求
为实现HAProxy保持客户源IP,一定包含USE_LINUX_TPROXY组件,通过 haproxy -vv | grep USE_LINUX_TPROXY 命令可以查询,输出USE_LINUX_TPROXY=1表示包含该组件:

如果HAProxy不包含USE_LINUX_TPROXY组件,可通过源码编译安装的方式包含USE_LINUX_TPROXY组件:
HAProxy配置
要实现保持客户的源IP,HAProxy的只在后端服务的配置中添加 source 0.0.0.0 usesrc clientip 配置,表示针对全部源IP都使用用户客户端IP,其它的配置有功能没有任何匹配

HAProxy回包处理
针对这个场景,HAProxy还需要配置回包的处理,按照报文转发过程分析,将在后面章节介绍HAProxy回包处理。
后端服务器配置
在业务的访问场景中有三个角色:用户,HAProxy,服务器。针对请求流量,访问路径为 用户 -> HAProxy -> 服务器,而且在HAProxy环节中,有SSL卸载、URL分流等关键操作,并不是简单的转发处理,所以针对服务器发出的回应流量,必须回到HAProxy,这样才能保证业务的访问正常。这也是HAProxy发往服务器时源IP为HAProxy的原因之一。
在这个场景中,我们要使HAProxy发往服务器时源IP保持为客户端的IP,这样服务器发出的回应流量就直接转发到网关,并由网关转发到互联网,这样回应流量就回不到HAProxy,可以把服务器的网关设置成HAProxy解决此问题,但是服务器的全部都会转发到HAProxy,增加HAProxy的负载,所以这个方式也不合适。

结合上面的转发流程图和之前的Linux源进源出实验,在服务器识别出从HAProxy转发过来的流量,并把对应回报文转发到HAProxy就可以实现。作为一个应用服务器一般只有一接口,通过报文入接口区分报文不现实,这里通过在prerouting链匹配请求报文的源MAC来识别从HAProxy转发过来的流量:
请求报文经过prerouting链设置ct mark后,其它转发流程都一样,最终通过input链进入本地程序。本地程序处理完后进行回应,参照上面的流程图,本地程序的回包经过outpug和postrouting链直接出网,并不经过prerouting链和Routing,所以无法按之前的源进源出实验处理。
针对这个场景,在output链中新增了一个route表(这个表只在output链中有),在route表中匹配ct mark,并通过ip rule规则查找路由表:
设置成报文的meta mark后,添加ip rule规则:
修改rt_tables 文件,在里面添加路由表table_haproxy,每个路由表要有一个唯一的ID,修改之后的文件如下:

报文在转发过程中通过ip rule规则进入路由表查找路由,所以我们需要在对应路由表中添加对应的路由:
HAProxy回报处理
经过上面的流程,服务器的回应报文已经返回到HAProxy,但是回应报文的目的IP为客户端真实,而非HAProxy的本机IP,这样HAProxy会把这报文直接转发出去,不会送到本机的HAProxy进程处理,这样肯定是不行的,所以针对服务器的回应报文,需要经过特殊处理。
在这里,需要针对服务器到HAProxy的回应报文进行特殊处理,为精确识别回应报文,而不是全部从服务器发过来的报文,继续使用ct mark标识,而且是在HAProxy往服务器发报文的时候就设置ct mark,这样就可以精确识别出对应的回应报文。在HAProxy的OUTPUT链添加route表设置ct mark:
通过以上设置,全部从HAProxy发送后端服务器的请求报文,都设置了ct mark,针对回应报文,在prerouting链中把ct mark复制到meta mark:
设置成报文的meta mark后,添加ip rule规则:
修改rt_tables 文件,在里面添加路由表table_loop,每个路由表要有一个唯一的ID,修改之后的文件如下:

报文在转发过程中通过ip rule规则进入路由表查找路由,所以我们需要在对应路由表中添加对应的路由,使回就报文能上送到本机处理:
互此,HAProxy保持客户源IP的配置已经完成。
场景限制说明:
HAProxy保持客户源IP在使用中有两个限制:
1。HAProxy和后端服务器要在同一网段,只有在同一网段才可以控制后端服务器到HAProxy的回报;
2。在云计算场景下,有的云服务厂家为保障安全会限制云服务器出入流量:入流量的目的IP必须为本机,出流量的源IP必须为本机。在本场景中,HAProxy转发给服务器的流量,在HAProxy上属于出流量,但是源IP不本机的,所以在云计算平台上会把这个报文丢弃;反之,从服务器到HAProxy的流量也到不了HAProxy,因为目的IP不是HAProxy本机。
以上两个场景限制,可以通过GRE等隧道技术解决。
888

被折叠的 条评论
为什么被折叠?



