为什么需要获取客户端真实ip

ip地址是按地域分布的,服务器获取到客户端ip后可以做流量统计和分析,服务器也可以针对客户端ip做一些定制化的功能,比如限流和黑白名单。
网络环境十分复杂,客户端发出的一个请求至少要经过cdn和负载均衡后才可以到达服务器。报文经过负载均衡的时候往往会做FNAT(lvs的一种转发模式,被普遍用于各种厂商的lb,该转发模式会对所有报文做源地址转换和目的地址转换),所以报文经过lb后,源地址就被删除了,这样服务器看到的源地址都是lb的地址,无法获取到客户端的真实ip了。
各大lb厂商都有自己的办法来实现这个功能,具体的实现方式需要区分四层lb和七层lb。

四层负载均衡

四层负载均衡支持的协议一般是tcp和udp,四层负载均衡实现获取客户端真实ip功能的方法一般是toa/uoa和proxy protocol。

toa/uoa

我们知道tcp报文头部有个扩展字段tcp option,这个字段非常常用,比如mss、sack、timestamps、窗口扩大系数等都是放在这个字段里的。lb本身是可以获取到源ip和源端口的,所以lb可以把客户端ip和端口封装到tcp option里面,然后将报文转发给后端。后端需要安装特殊的toa模块,并将toa模块加载到内核,后端可以依靠toa内核模块获取到客户端的真实ip。toa的特点主要有以下几点:

  1. 不需要改造后端服务,但是需要根据lb功能的实现编写toa/uoa模块。
  2. udp报文头部没有option字段,所以针对udp,一般会把客户端ip放到ip option里面。
  3. 由于tcp option的长度最多只有40个字节,而tcp option又很常用,toa至少需要8个字节,如果lb收到报文时,tcp option剩下的空间已经不够存放toa了,那获取客户端真实ip这个功能就会失效,所以有的厂商也会把toa放到不常用的ip option里面。
  4. 对于ipv6的场景,toa至少需要占用20个字节(16字节的ip地址,2字节端口,1字节length,1字节类型),所以也经常会被放到ipv6报文头部的扩展报文头里。
  5. toa增加的报文长度,为了增大带宽利用率,我们往往只在握手阶段插入toa;对于uoa而言,就是只对同一条流的前几个报文插入uoa。

proxy protocol

proxy protocol是HAProxy的作者Willy Tarreau于2010年开发和设计的一个Internet协议,通过为tcp添加一个很小的头信息,来方便的传递客户端信息(协议栈、源IP、目的IP、源端口、目的端口等)。其本质就是在三次握手后的第一个数据包中的tcp头部后面的payload添加了proxy protocol协议规定的内容,来向服务端传送客户端信息。udp当然也可以支持proxy protocol,只需将同一条流的第一个udp报文进行改造即可。proxy protocol的特点如下:

  1. 需要对后端服务代码进行改造,nginx天然支持proxy protocol,但是如果是自己实现的服务,则需要自己来实现解析proxy protocol的功能。
  2. nginx的一个端口无法既支持proxy protocol,又支持普通的http请求。

七层负载均衡

七层负载均衡支持的主要服务是http,七层负载均衡支持获取客户端真实ip的方法就比较简单且灵活,一般是通过插入一个http头部来实现,比如X-Forwarded-For字段,服务端可以直接通过这个http头部获取到客户端真实ip。

获取客户端真实ip的方法相关推荐

  1. PHP获取客户端真实IP的方法

    摘要: 利用getenv获取获取用户真实ip可以获取相当可观的用户数据,不管是做大数据还是数据备份查找来源,都是不错的选择. 好处: 一个网站,获取用户是非常有必要的,你获得了ip可以干嘛?简单了说, ...

  2. Java从代理服务器中获取客户端真实IP的方法

    概要 一般在单机版的tomcat获取请求来源的ip,可以使用下面方式这么干,下文的request是HttpServletRequest对象. String remoteAddr = request.g ...

  3. python获取客户端ip_各种脚本语言获取客户端真实IP的方法

    各种语言获取客户端真是ip的方法 1.PHP脚本获取客户端真实ip的方法 整体思路:需要依次检查HTTP_CLIENT_IP.HTTP_X_FORWARDED_FOR.REMOTE_ADDR这三个是否 ...

  4. 获取客户端真实 IP

    Tomcat + Nginx 反向代理获取客户端真实IP.域名.协议.端口 Nginx 反向代理后,Servlet 应用通过 request.getRemoteAddr() 取到的 IP 是 Ngin ...

  5. Java正确获取客户端真实IP方法整理

    转载自 干货:Java正确获取客户端真实IP方法整理 在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apach ...

  6. PHP获取客户端真实IP地址的方法

    php获取客户端IP地址有四种方法,这五种方法分别为 1 2 3 4 REMOTE_ADDR HTTP_CLIENT_IP HTTP_X_FORWARDED_FOR HTTP_VIA REMOTE_A ...

  7. 获取客户端真实IP方法

    2019独角兽企业重金招聘Python工程师标准>>> 我们经常会记录审计日志,那么如何获取客户端真实IP呢?让我们了解一下HTTP协议头吧. 在讨论获取客户端IP 地址前,我们首先 ...

  8. 获取客户端真实IP地址

    Java-Web获取客户端真实IP: 发生的场景:服务器端接收客户端请求的时候,一般需要进行签名验证,客户端IP限定等情况,在进行客户端IP限定的时候,需要首先获取该真实的IP. 一般分为两种情况: ...

  9. 如何获取客户端真实 IP?从 Gin 的一个 Bug 说起

    1. 背景 请求 IP 作为用户的身份标识属性之一,是一种非常重要的基础数据.在很多场景下,我们会基于客户端请求 IP 去做网络安全攻击防范或访问风险控制.通常我们可以通过 HTTP 协议 Reque ...

最新文章

  1. 无线网络未来十年十大产业趋势
  2. java web 默认页面配置文件_Tomcat中配置全局的错误页面(如404)+删除Tomcat中webapps目录下的自带项目,防止Tomcat默认文件泄露...
  3. 热电偶校验仪使用说明_热电偶冷端补偿方法
  4. 【解决方案】npm安装vue超时(ERR! errno ETIMEDOUT)
  5. qt显示echart_Qt配置,载入html,Echart, 交互
  6. 【贪心】奶牛晒衣服(ybtoj 贪心-1-1)
  7. 【Python CheckiO 题解】Count Consecutive Summers
  8. 设置本地yum源优先
  9. 添加控制器 提示找到不到上下文_JS局部上下文和全局上下文
  10. 消息称Face++明年上市,还曝光了财务数据
  11. linkedblockingqueue 后 take 不消化_消化不良的症状原因有哪些?
  12. php两个数组递归排序,PHP数组递归排序实现方法示例
  13. c++万能头文件包含的头文件
  14. labelimg安装教程(小白都会)
  15. 计算机主机号怎么产看,怎么查看笔记本电脑出厂编号
  16. 手动给tabcontrol的tabPage加图标图片方法
  17. 关于用指针实现输入字符串以单词为元素反转输出思路
  18. GitHub干货分享
  19. 星号下三角形python答案_Python利用for循环打印星号三角形的案例
  20. 《文法俱乐部》读书笔记之动词时态--LG二进制

热门文章

  1. 语言 英语名称 中文名称 国家码
  2. 天嵌科技TQ2440的uboot启动流程分析学习笔记
  3. 设计模式04——Factory Method模式
  4. 初学者必读VRay 2.0材质设置(1)——VRay材质设置基础
  5. VirtualBox 虚拟机系统的三种启动方式
  6. loj10155:数字转换:树的直径问题
  7. HYPEREAL带来突破性的深度感知摄像头,在虚拟世界睁开真实之眼
  8. 绕过CDN查找真实IP方法
  9. 电子科大2020计算机考研真题,2021电子科技大学考研历年真题复习资料
  10. 一周活动速递|深入浅出第8期;Meetup成都站报名进行中