zoukankan      html  css  js  c++  java
  • k8s中ingress以及nginx获取客户端真实IP

     

    1.背景信息

      公司游戏官网的项目,集群使用ingress开放出去,后端由于是php语言编写,所以在php的pod里面也需要一个nginx来开放连接。所以本次的路由顺序就如以下:

          腾讯云LB → ingress → nginx

      所以本次环境,ingress和nginx都需要获取客户端的真实IP。所以本篇文档还是主要讲解一下使用方式和注意事项。

     

    2.基本概念

      以上讲解了ingress和nginx获取真实IP的方式,这里还是简单的了解一下基本概念。

     

      (1)remote_addr

      代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的

      当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)

      就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站

      这样web服务器就会把remote_addr设为这台代理机器的IP,除非代理将你的IP附在请求header中一起转交给web服务器

     

      (2)X-Forwarded-For(简称XFF)

      X-Forwarded-For 是一个 HTTP 扩展头部,HTTP协议并没有对它的定义,它最开始是由 Squid 这个缓存代理软件引入

      用来表示 HTTP 请求端真实 IP,如今它已经成为事实上的标准,被各大 HTTP 代理、负载均衡等转发服务广泛使用

      并被写入 RFC 7239(Forwarded HTTP Extension)标准之中

      XFF的格式为X-Forwarded-For: client, proxy1, proxy2

     

      XFF 的内容由「英文逗号 + 空格」隔开的多个部分组成,最开始的是离服务端最远的设备 IP,然后是每一级代理设备的 IP

      (注意:如果未经严格处理,可以被伪造)

      如果一个 HTTP 请求到达服务器之前,经过了三个代理 Proxy1、Proxy2、Proxy3,IP 分别为 IP1、IP2、IP3,用户真实 IP 为 IP0

      那么按照 XFF 标准,服务端最终会收到以下信息

      X-Forwarded-For: IP0, IP1, IP2

      Proxy3 直连服务器,它会给 XFF 追加 IP2,表示它是在帮 Proxy2 转发请求

      列表中并没有 IP3,IP3 可以在服务端通过 Remote Address 字段获得

     

      (3)X-Real-IP

      这又是一个自定义头部字段,通常被 HTTP 代理用来表示与它产生 TCP 连接的设备 IP

      这个设备可能是其他代理,也可能是真正的请求端,这个要看经过代理的层级次数或是是否始终将真实IP一路传下来

      (注意:如果未经严格处理,可以被伪造)

     

    3.Ingress 获取客户端真实IP

      通常,用户ip的传递依靠的是X-Forwarded-*参数。但是默认情况下,ingress是没有开启的。

      ingress的文档还比较详细,这里介绍一下可能用到的这3个参数:

      ingress官方文档: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#use-forwarded-headers

      以上有三个比较重要的参数。下面一一解释

     

    3.1 use-forwarded-headers

    • 如果Nginx在其他7层代理或负载均衡后面,当期望Nginx将X-Forwarded-*的头信息传递给后端服务时,则需要将此参数设为true
    • 如果设为false(默认为false),Nginx会忽略掉X-Forwarded-*的头信息。false设置适用于Nginx直接对外或前面只有3层负载均衡的场景

      由于ingress的主配置是从configmap中获取的,更新参数则需要修改名为nginx-configuration的configmap的配置:在data配置块下添加use-forwarded-headers: "true"

      修改后,ingress nginx会自动加载更新nginx.conf主配置文件。下图为更新前后配置文件变化对比:

      注意:左边为开启use-forwarded-headers后ingress nginx主配置文件,右边为开启前

     

    3.2 forwarded-for-header

      用来设置识别客户端来源真实ip的字段,默认是X-Forwarded-For。如果想修改为自定义的字段名,则可以在configmap的data配置块下添加:forwarded-for-header: "THE_NAME_YOU_WANT"。通常情况下,我们使用默认的字段名就满足需求,所以不用对这个字段进行额外配置。当然,你想显示的配置也可以。

     

    3.3 compute-full-forwarded-for

      如果只是开启了use-forwarded-headers: "true"的话,会发现还是没能获取到客户端来源的真实ip,原因是当前X-Forwarded-For变量是从remote_addr获取的值,每次取到的都是最近一层代理的ip。为了解决这个问题,就要配置compute-full-forwarded-for字段了,即在configmap的data配置块添加:compute-full-forwarded-for: "true"。其作用就是,将客户端用户访问所经过的代理ip按逗号连接的列表形式记录下来。

      待ingress nginx加载configmap并更新主配置文件后,对比更新前后变化如下:

      注:左边是未开启compute-full-forwarded-for配置的ingress nginx主配置文件,右边是开启了的

     

    3.4 举例说明

      如果从客户端ip0发起一个HTTP请求到达服务器之前,经过了三个代理proxy1、proxy2、proxy3,对应的ip分别为ip1、ip2、ip3,那么服务端最后得到的X-Forwarded-For值为:ip0,ip1,ip2。列表中并没有ip3,ip3可以在服务端通过remote_addr来获得。这样应用程序通过获取X-Forwarded-For字段的第一个ip,就可以得到客户端用户真实ip了。

     

    3.5 注意项

      值得注意的是,并不是所有的场景都能通过X-Forwarded-For来获取用户正式ip。

      比如,当服务器前端使用了CDN的时候,X-Forwarded-For方式获取到的可能就是CDN的来源ip了,

      这种情况,可以根CDN厂商约定一个字段名来记录用户真实ip,然后代理将这个字段逐层传递,最后到服务端。

     

    4.Nginx获取客户端真实IP

      先讲解ingress在讲解nginx原因是因为,在架构图里面,nginx在ingress后面,这里有一个非常需要注意的点就是,如果ingress不先拿到客户端的真实IP,nginx不管怎么配置都拿不到,因为在ingress那一层就没有真实的客户端IP了。往后面nginx传递的也就没有真实IP了。

     

    4.1 配置

    #放在http模块等,个人比较喜欢放在http
    
    set_real_ip_from 192.168.1.0/24; #真实服务器上一级代理的IP地址或者IP段,可以写多行。 
    
    real_ip_header   X-Forwarded-For;  #从哪个header头检索出所要的IP地址。
    
    real_ip_recursive on;      #递归的去除所配置中的可信IP。排除set_real_ip_from里面出现的IP。如果出现了未出现这些IP段的IP,那么这个IP将被认为是用户的IP。

      Nginx使用以上的配置就可以了

     

    参考:https://www.cnblogs.com/yudai/p/10974444.html

    作者:小家电维修

    相见有时,后会无期。

  • 相关阅读:
    【总结】设备树语法及常用API函数【转】
    【转】ios蓝牙开发学习笔记(四)ios蓝牙应用的后台处理 -- 不错
    SQL存储过程相关信息查看
    DBCC CHECKIDENT
    SQL CAST与CONVERT区别
    SQl查询数据库库名,表名、表的列名
    SQL语句资料
    SQL中rownum和order by的执行顺序的问题
    完整的ASP.NET存储过程分页,排序,鼠标移至变色
    最简单删除SQL Server中所有数据的方法(不用考虑表之间的约束条件,即主表与子表的关系)
  • 原文地址:https://www.cnblogs.com/lizexiong/p/15204071.html
Copyright © 2011-2022 走看看