【问题标题】:Nginx real_ip_header through a GCE ingress?Nginx real_ip_header 通过 GCE 入口?
【发布时间】:2018-07-17 18:07:18
【问题描述】:

我的目标是通过 GCE 入口通过 nginx 服务的 Kubernetes Engine 上部署的 Angular 应用的 IP 地址过滤访问。

但在我的 nginx 上,remote_addr 不正确。

$LB_IP 是这里定义的 ip:kubernetes.io/ingress.global-static-ip-name: app-angular

我在 nginx 上使用 set_real_ip_from 从 X-Forwarded-For 设置 ip

set_real_ip_from $LB_IP;
real_ip_header X-Forwarded-For;

原始 ip 出现在 X-Forwarded-For 标头中,正如谷歌文档中所预期的那样:https://cloud.google.com/compute/docs/load-balancing/http/#components

我可以看到 X-Forwarded-For 包含 $CLIENT_IP 但 remote_addr 不正确,顺便说一下我的 IP 过滤器不起作用。有什么想法吗?

我的 nginx 日志:

10.40.40.40 - - [07/Feb/2018:11:29:48 +0000] "GET /styles.bundle.css HTTP/1.1" 200 35908 "http://MY_URL/home" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36" "$CLIENT_IP, $LB_IP"

但我想要:

$CLIENT_IP - - [07/Feb/2018:11:29:48 +0000] "GET /styles.bundle.css HTTP/1.1" 200 35908 "http://MY_URL/home" "Mozilla/5.0 (Macintosh; Intel Mac) OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36" "$CLIENT_IP, $LB_IP"

我的 Ingress 配置:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: app-angular
spec:
  rules:
    - host: MY_URL
      http:
        paths:
        - backend:
            serviceName: app-backend
            servicePort: 80

我的后端配置:

apiVersion: v1
kind: Service
metadata:
  name: app-backend
spec:
  type: NodePort
  selector:
    app: app-angular
  ports:
  - port: 80
    targetPort: 80

我的部署配置:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: app-angular
spec:
  replicas: 2
  revisionHistoryLimit: 2
  template:
    metadata:
      labels:
        app: app-angular
        tier: frontend
    spec:
      containers:
      - name: app-angular
        image: gcr.io/MY_PROJECT/app-angular:MY_TAG
        imagePullPolicy: Always
        ports:
          - containerPort: 80

我的 nginx 配置:

server {
  listen 80;

  root /usr/share/nginx/html;

  location / {

    set_real_ip_from $LB_IP;
    real_ip_header X-Forwarded-For;

    allow 130.211.0.0/22; #Google IP
    allow $CLIENT_IP; # FILTERED IP
    allow 10.0.0.0/8; #internal network
    deny all;

    index index.html index.htm;
    try_files $uri $uri/ /index.html =404;
  }

}

有什么想法吗?

【问题讨论】:

    标签: nginx kubernetes google-cloud-platform google-compute-engine kubernetes-ingress


    【解决方案1】:

    它们是两种解决方案(感谢 gcbirzan 帮助我解决 GCP 松弛问题):

    1) 使用来自 IP 地址范围的良好 IPS 更新我的 nginx 配置:

    IP 地址范围可在此处找到:https://console.cloud.google.com/networking/networks/list。 您可以为一个区域或所有需要的区域添加 set_real_ip_from。 不要忘记 real_ip_recursive on;

    server {
      listen 80;
    
      root /usr/share/nginx/html;
    
      location / {
    
        set_real_ip_from 10.128.0.0/20;
        ...
        real_ip_header X-Forwarded-For;
        real_ip_recursive on;
    
        allow 130.211.0.0/22; #Google IP
        allow $CLIENT_IP; # FILTERED IP
        allow 10.0.0.0/8; #internal network
        deny all;
    
        index index.html index.htm;
        try_files $uri $uri/ /index.html =404;
      }
    
    }
    

    2) 更新我的后端配置:

    externalTrafficPolicy:本地

    apiVersion: v1
    kind: Service
    metadata:
      name: app-backend
    spec:
      type: NodePort
      selector:
        app: app-angular
      ports:
      - port: 80
        targetPort: 80
      externalTrafficPolicy: Local
    

    更新 nginx 配置:

    现在 $remote_addr 中显示的 IP 将设置为您的客户端请求的负载均衡器 IP 和 google Infra IPS:130.211.0.0/22,35.191.0.0/16

    别忘了real_ip_recursive on;

    server {
      listen 80;
    
      root /usr/share/nginx/html;
    
      location / {
    
        set_real_ip_from $LB_IP;
        set_real_ip_from 130.211.0.0/22;
        set_real_ip_from 35.191.0.0/16;
        real_ip_header X-Forwarded-For;
        real_ip_recursive on;
    
        allow 130.211.0.0/22; #Google IP
        allow 35.191.0.0/16; #Google IP
        allow $CLIENT_IP; # FILTERED IP
        allow 10.0.0.0/8; #internal network
        deny all;
    
        index index.html index.htm;
        try_files $uri $uri/ /index.html =404;
      }
    
    }
    

    【讨论】:

      【解决方案2】:

      您提供的链接专门针对 GCP 负载平衡器。 至于 nginx 负载均衡器,您应该考虑将 ExternalTrafficPolicy annotation 添加到您的 NodePort 服务以保留客户端 IP。

      我还发现了一个可追溯到 2017 年年中的类似问题,表明 certain versions of the nginx controller 存在问题,请确保您使用的图像没有此问题。

      最后,您可能需要添加 use-proxy-protocol: "true" with the configuration ConfigMap,因为您使用的入口充当使用代理的 HTTP(S) 负载均衡器。

      【讨论】:

      • 感谢您的帮助,我找到了解决方案。 ExternalTrafficPolicy 是一个好方法。最后一点是不可能的:use-proxy-protocol: "true" ,因为我没有使用 nginx-ingress,所以我使用 gce ingress 和 nginx 作为我的 Angular 应用程序的 http 服务器。
      【解决方案3】:

      我们在nginx ingress 前面使用HTTP GCLB ingress。为了让RealIP 工作,我添加了

      kind: ConfigMap
      apiVersion: v1
      metadata:
        name: ingress-nginx
        labels:
          k8s-addon: ingress-nginx.addons.k8s.io
      data:
        ##
        ## Google Infra Blocks needed
        ##  130.211.0.0/22,35.191.0.0/16
        ##
        ## Google Cloud Load Balancer
        ##  GCLB-IP/32
        proxy-real-ip-cidr: 130.211.0.0/22,35.191.0.0/16,[YOUR-GCLB-IP]/32
      

      这允许nginx 信任来自 Google 基础架构的X-Forwarded-For

      【讨论】:

      • 感谢您的帮助,我找到了解决方案。但我没有使用 nginx-ingress,我使用 gce ingress 和 nginx 作为我的 Angular 应用程序的 http 服务器。
      • 啊。谢谢你的澄清。我将nginx with GCE ingress 的提及混为一谈GCLB Ingress in front of nginx Ingress
      猜你喜欢
      • 1970-01-01
      • 2019-03-24
      • 2021-02-12
      • 1970-01-01
      • 1970-01-01
      • 2015-12-27
      • 2018-10-04
      • 1970-01-01
      • 2016-10-28
      相关资源
      最近更新 更多