负载均衡获得真实源IP的6种方法

除了X-FORWARD-FOR,负载均衡中获得真实源IP的方法还有很多种。
本文抛砖引玉,主要介绍获得真实源IP的多种方法,而不是具体配置。
负载均衡获得真实IP的方法有很多种,将形成专题文章。
本文为第一篇,主要做介绍和优劣对比。
小慢哥的原创文章,欢迎转载
获得真实IP的6种方法
当数据包从负载均衡器往后端转发时候,真实源IP可在L3、L4、L7实现,并且分别有2种方法可以获得真实IP,因此共有6种方法:
保持L3层源IP不变,根据连接次数可以分为
- 一次连接模式,如lvs
- 二次连接模式,如haproxy的透明模式
在L4层数据里,添加源IP信息,有2种模式
- 在4层的option字段里增加源IP信息,比如tcp option、udp option
- 在4层末尾和7层开头之间,增加proxy protocol信息
在L7层数据里,增加源IP信息,有2种模式
- 协议自带,例如HTTP的X-FORWARD-FOR
- 业务程序自行实现
一次连接与二次连接
一次连接:负载均衡器对数据包仅做转发,而不对后端重新发起三次握手
二次连接:和一次连接相对应,在tcp转发时候,对后端重新进行了三次握手。上面所讲的L4和L7方法的负载均衡,都是二次连接
可以通过对比源端口是否有改变来简单判断是一次连接还是二次连接,端口没改变,可以理解为一次连接,有改变就是二次连接
方法1: L3的一次连接模式
介绍:是指在网络层不对源IP做修改,直接将数据包转发给后端,当后端接收到数据的时候,源IP就是真实IP。
实现:LVS-DR、LVS-NAT、LVS-TUNNEL模式。其中LVS-TUNNEL比较特别,是在原有数据包的开头封装了IP头,当后端收到数据的时候,将封装的IP头进行解封装,获得的就是原有数据包。
优点:逻辑简单,当负载均衡器故障切换的时候,从客户端到后端的tcp连接不会中断
缺点:对网络架构有要求,比如DR模式,要求后端配VIP,并且回包要能直接回到客户机;NAT模式,要求回包经过负载均衡器;TUNNEL模式要求后端支持IPIP隧道
方法2: L3的二次连接模式
介绍:是指负载均衡器和后端重新进行三次握手,但保持数据包的源IP为真实IP。
实现:haproxy(开启tproxy透明代理模式)+ iptables(fwmark打标记)+ 策略路由这3者组合才能实现
优点:可以实现L7层(如HTTP/HTTPS)的负载均衡,而一次连接主要实现L4层的负载均衡
缺点:配置最复杂,同时要求回包经过负载均衡器
方法3: L4的toa模式
介绍:在4层的option字段里增加源IP信息,比如在tcp option里增加源IP信息(称为toa)、udp option里增加源IP信息(称为uoa)
实现:负载均衡器配置lvs-fullnat(只支持toa),iqiyi/dpvs(支持toa和uoa);后端要加载toa、uoa模块,这个模块的作用是替换了后端应用程序获取IP的系统接口的钩子
优点:对网络架构要求低
缺点:lvs-fullnat需要编译内核,且只支持rhel/centos 6的内核,另外多年未更新;iqiyi/dpvs功能强大,但需要dpdk的支持;后端都需要加载toa/uoa模块,且只支持linux系统。
方法4: L4的proxy protocol模式
介绍:在L7层开头增加proxy protocol数据(该协议是haproxy发明),目前有v1(明文)和v2(二进制)版本
实现:负载均衡器和后端同时开启proxy protocol,haproxy和nginx均支持,不过haproxy的配置颗粒度更小,另外nginx转发数据时候只支持v1
优点:对网络架构要求低,只要程序支持即可,因此理论上没有操作系统限制
缺点:目前支持proxy protocol的程序较少,且两端只能都开启或者都不开启该协议,不能一端开一端不开
方法5: L7协议自带,例如HTTP的X-FORWARD-FOR
介绍:最常见的方法,协议自带源IP信息,或者可定制插入
实现:例如HTTP协议有X-FORWARD-FOR,也可以自己将源IP插入到HTTP头部信息里
优点:对网络架构要求低,配置简便
缺点:容易被伪造
方法6: L7层业务程序自行实现
介绍:最好的方法,就是业务方自行实现
实现:业务自行实现,例如在client端插入源IP信息,带到server端
优点:对网络架构无要求,只要网络可通即可,只要安全做好,不容易被伪造
缺点:业务方要有一定开发能力
总结
如果能做到无状态,不需要真实源IP,是最好的。因为这样对底层架构没有要求,底层架构就可以做的更高级更弹性。
如果一定要获得真实源IP,推荐方案的顺序就是倒推,从L7到L3,即首选方法6,如果不行再选用方法5,以此类推到方法1
微信公众号(小慢哥Linux运维)
每周一文,轻松学Linux运维

个人网站fzxiaomange.com
个人邮箱cyent@163.com
负载均衡获得真实源IP的6种方法的更多相关文章
- 负载均衡获得真实源IP的6种方法 【转】
除了X-FORWARD-FOR,负载均衡中获得真实源IP的方法还有很多种, 本文抛砖引玉,主要介绍获得真实源IP的多种方法,而不是具体配置, 负载均衡获得真实IP的方法有很多种,将形成专题文章, 本文 ...
- 在容器服务中获取客户端真实源 IP
适用范围:腾讯云容器服务(Tencent Kubernetes Engine ,TKE), 以下简称 TKE. 为什么需要获取客户端真实源 IP? 当需要能感知到服务请求来源去满足一些业务需求时,就需 ...
- 某云负载均衡获取客户端真实IP的问题
某云负载均衡真实IP的问题,我们这边已经遇到过两次了.而且每次和售后沟通的时候都大费周折,主要是要给售后说明白目前文档的获取真实IP是有问题的,他们觉得文档上说明的肯定没问题,售后要是不明白,他们不会 ...
- f5源站获取http/https访问的真实源IP解决方案
1.背景 F5负载均衡设备,很多场景下需要采用旁挂的方式部署.为了保证访问到源站的数据流的request和response的TCP路径一致,f5采用了snat机制.但是这样导致源站上看到的来源IP都是 ...
- Nginx作为负载均衡把客户端真实IP发送给后端配置
Nginx作为负载均衡获取到客户端的真实IP,但是后端获取到的IP为nginx负载均衡的IP,需要修改配置使后端获取到客户端的真实IP 修改nginx配置增加3行 proxy_set_header H ...
- Nginx负载均衡服务器实现会话粘贴的几种方式
1. 使用Nginx 的ip_hash作为负载均衡服务并支持Session sticky 2. 使用nginx sticky第三方模块实现基于cookie的负载均衡 3.使用nginx的map指令根据 ...
- linux下配置ip地址四种方法(图文方法)
主要是用第四种方法 (1)Ifconfig命令 第一种使用ifconfig命令配置网卡的ip地址.此命令通常用来零时的测试用,计算机启动后 ip地址的配置将自动失效.具体用法如下.Ipconfig ...
- ASP.NET获取IP的6种方法
服务端: //方法一 HttpContext.Current.Request.UserHostAddress; //方法二 HttpContext.Current.Request.ServerVari ...
- suse下设置IP的两种方法
/Files/yzhxhwt/DB_51aspx.rar 第一种SUSE Linux IP设置方法ifconfig eth0 192.168.1.22 netmask 255.255.255.0 up ...
随机推荐
- 【技术累积】【点】【git】【10】.gitignore和.gitattributes
.gitignore 告诉git忽略一些文件,git status会显示不到这些文件的状态. 一般放在项目根目录,以对全局控制,当然可以放在module下: 具体规则主要是: 以行为单位定义忽略文件类 ...
- C# 网页内容获取
private string GetGeneralContent(string strUrl) { string strMsg = string.Empty; try { WebRequest req ...
- centos7下安装python3 解决openssl等一系列问题
最近折腾了下centos7,发现按正常方法安装python3.7后面会出现各种操蛋的问题. 主要的问题有三个,openssl版本过低,'_ctypes'缺失,以及安装后sqlite3缺失.下面我会贴出 ...
- Jenkins 定时 构建项目
选择要定时构建的 项目-->配置-->构建触发器 触发项目: Poll SCM:定时检查源码变更(根据SCM软件的版本号),如果有更新就checkout最新code下来,然后执行构建动作. ...
- webpack command not found 的意外的坑 - 原因是从node开始
写给自己做个记录: 弄了半天 执行了下面操作 npm install webpack -g 因为小白不懂原理,所以执行了好遍,结果还是如题, webpack command not found 网上搜 ...
- log日志模块得作用
import logginglogger=logging.getLogger()logger.setLevel(logging.DEBUG)#控制台输出日志'''consle=logging.Stre ...
- C#第十五节课
函数复习 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System. ...
- 【Leetcode】【简单】【14最长公共前缀】【JavaScript】
题目 14. 最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower",& ...
- DOM学习之图片库切换效果
addloadevent(prepareplaceholder()) addloadevent(prepareGallery()) //页面加载完时执行函数 function addloadevent ...
- 洛谷P1781 宇宙总统【排序+字符串】
地球历公元6036年,全宇宙准备竞选一个最贤能的人当总统,共有n个非凡拔尖的人竞选总统,现在票数已经统计完毕,请你算出谁能够当上总统. 输入输出格式 输入格式: president.in 第一行为一个 ...