You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在Nginx Ingress前置AWS ELB场景下,如何基于客户端真实IP配置Ingress源地址白名单?

解决Nginx Ingress基于真实客户端IP(X-Forwarded-For)设置CIDR白名单的方案

结合你的架构(Client -> AWS ELB -> Nginx Ingress -> Pod)和需求,我推荐两个完全在Kubernetes内部实现的方案,都支持CIDR范围白名单,不需要切换NLB、修改安全组或依赖Cloudflare:

方案一:直接基于X-Forwarded-For头做白名单验证

这个方案不需要修改源IP,而是通过Nginx的自定义配置让白名单规则直接检查X-Forwarded-For里的真实客户端IP,灵活性更高。

操作步骤:

  1. 先确保Nginx Ingress信任ELB的IP
    不管用哪个方案,第一步都要让Ingress Controller认可ELB是可信代理,这样它才会信任X-Forwarded-For头的内容。如果是Helm部署的Ingress Controller,在values.yaml里添加以下配置:

    controller:
      config:
        use-forwarded-headers: "true"
        proxy-real-ip-cidr: "10.0.0.0/16" # 替换成你的ELB所在VPC的CIDR或ELB的公网IP段
    

    proxy-real-ip-cidr用来指定哪些上游IP是可信的,只有来自这些IP的请求,Nginx才会处理X-Forwarded-For头。

  2. 给目标Ingress添加自定义白名单规则
    使用nginx.ingress.kubernetes.io/configuration-snippet注解,写入Nginx规则检查X-Forwarded-For的第一个IP(也就是真实客户端IP)是否在白名单CIDR内:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: your-app-ingress
      annotations:
        nginx.ingress.kubernetes.io/configuration-snippet: |
          # 提取X-Forwarded-For中的第一个IP(处理多层代理场景)
          split $http_x_forwarded_for $client_real_ip;
          # 初始化标记为不允许
          set $allowed 0;
          # 匹配白名单CIDR,多个用|分隔
          if ($client_real_ip ~* ^(192.168.1.0/24|10.5.0.0/16)$) {
            set $allowed 1;
          }
          # 不匹配则返回403
          if ($allowed = 0) {
            return 403;
          }
    spec:
      ingressClassName: nginx
      rules:
        - host: your-app.example.com
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: your-app-service
                    port:
                      number: 80
    

    这里的split指令会把X-Forwarded-For按逗号分割,取第一个IP作为真实客户端IP;正则表达式里的CIDR可以根据你的需求自由添加,用|分隔即可。

方案二:让Nginx将源IP替换为X-Forwarded-For中的真实IP

如果你更想用Ingress原生的whitelist-source-range字段,这个方案可以让Nginx把请求的源IP替换成X-Forwarded-For里的真实IP,这样原生的白名单配置就会生效。

操作步骤:

  1. 配置Ingress Controller替换真实IP
    同样先信任ELB的IP,再添加real-ip-headerset-real-ip-from配置(Helm的values.yaml):

    controller:
      config:
        use-forwarded-headers: "true"
        proxy-real-ip-cidr: "10.0.0.0/16" # 替换成你的ELB CIDR
        real-ip-header: "X-Forwarded-For" # 指定从哪个头取真实IP
        set-real-ip-from: "10.0.0.0/16" # 和proxy-real-ip-cidr一致,指定可信代理范围
    

    配置后,Nginx会把请求的源IP替换为X-Forwarded-For中的第一个IP,后续所有基于源IP的规则(包括whitelist-source-range)都会使用这个真实IP。

  2. 使用原生的whitelist-source-range字段
    现在就可以像平时一样在Ingress里配置白名单CIDR了:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: your-app-ingress
    spec:
      ingressClassName: nginx
      whitelist-source-range: 192.168.1.0/24,10.5.0.0/16 # 直接填需要允许的CIDR
      rules:
        - host: your-app.example.com
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: your-app-service
                    port:
                      number: 80
    

关键注意事项

  • 一定要正确配置可信代理范围proxy-real-ip-cidrset-real-ip-from必须填你的ELB所在的IP范围,否则恶意请求可以伪造X-Forwarded-For头绕过白名单。你可以在AWS控制台查看ELB的IP,或者用VPC的CIDR(更稳妥)。
  • 关于Proxy Protocol:你的场景完全不需要用Proxy Protocol,因为AWS ALB已经通过X-Forwarded-For传递了真实IP,配置上面的参数就足够了,不用去碰你不熟悉的协议。
  • 两种方案的选择:方案一适合需要更复杂规则的场景(比如不同路径用不同白名单),方案二更简洁,适合用原生Ingress字段的场景。

内容的提问来源于stack exchange,提问作者Vitor Falcão

火山引擎 最新活动