3

I would like to catch the Client IP Address inside my .NET application running behind GKE Ingress Controller to ensure that the client is permitted.

var requestIpAddress = request.HttpContext.Connection.RemoteIpAddress.MapToIPv4();

Instead of getting Client IP Address I get my GKE Ingress IP Address, due to The Ingress apply some forwarding rule.

The GKE Ingress controller is pointing to the Kubernetes service of type NodePort.

I have tried to add spec to NodePort service to preserve Client IP Address but it doesn't help. It is because the NodePort service is also runng behind the Ingress

externalTrafficPolicy: Local

Is it possible to preserve Client IP Address with GKE Ingress controller on Kubernetes?

NodePort Service for Ingress:

apiVersion: v1
kind: Service
metadata:
  name: api-ingress-service
  labels:
    app/name: ingress.api
spec:
  type: NodePort
  externalTrafficPolicy: Local
  selector:
    app/template: api
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: http

Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  namespace: default
  labels:
    kind: ingress
    app: ingress
  annotations:
    networking.gke.io/v1beta1.FrontendConfig: frontend-config
spec:
  tls:
  - hosts:
    - '*.mydomain.com'
    secretName: tls-secret
  rules:
  - host: mydomain.com
    http:
      paths:
      - path: /*
        pathType: ImplementationSpecific
        backend:
          service:
            name: api-ingress-service
            port:
              number: 80
Mikolaj
  • 1,231
  • 1
  • 16
  • 34
  • You need to get the socket on the server and access the remote endpoint. See : https://www.digitalocean.com/community/questions/how-can-i-get-socket-io-to-work-on-kubernetes-when-using-nginx-ingress-and-cert-manager?force_isolation=true – jdweng Jan 25 '22 at 13:20
  • Which Kubernetes version are you using? – Mikolaj S. Jan 25 '22 at 18:52
  • @MikolajS. Client Version: v1.21.3, Server Version: v1.21.6-gke.1500 – Mikolaj Jan 26 '22 at 06:00
  • Based on [this](https://stackoverflow.com/a/47917073/16391991) and [this answer](https://stackoverflow.com/questions/35246089/getting-orgin-ip-from-load-balancer/35278174#35278174) could you use `X-Forwarded-For` header in your app? – Mikolaj S. Jan 28 '22 at 13:52
  • The `X-Forwarded-For` header is easily modifiable. In my application, I want to use the client's IP address as a guarantee that I need to authorize a certain payment transaction. I cannot rely on a header that can be edited – Mikolaj Jan 28 '22 at 14:07

2 Answers2

1

Posted community wiki for better visibility. Feel free to expand it.


Currently the only way to get the client source IP address in GKE Ingress is to use X-Forwarded-For header. It's known limitation for all GCP HTTP(s) Load Balancers (GKE Ingress is using External HTTP(s) LB).

If it does not suit your needs, consider migrating to a third-party Ingress Controller which is using an external TCP/UDP network LoadBalancer, like NGINX Ingress Controller.

Mikolaj S.
  • 2,850
  • 1
  • 5
  • 17
0

I was able to get the client IP address with the following configurations.

Note: My application services are of type ClusterIP, have not valided with NodePort. Was using LB created by Ingress controller instead of NodePort.

Let's say you generate ingress-controller manifest using following

$ helm template ingress-nginx-ext \
    --namespace ingress-nginx-ext \
    --create-namespace \
    --version v4.7 \
    --repo https://kubernetes.github.io/ingress-nginx \
    ingress-nginx > ingress-nginx-ext.yaml

You will need to patch the Service LB. The following is the kustomization.yaml I used for the patch.

patches:
  - target:
      kind: ConfigMap
      name: ingress-nginx-ext-controller 
      namespace: ingress-nginx-ext
    patch: |-
      # Over-ride the default configmap with our own
      # Source: ingress-nginx/templates/controller-configmap.yaml
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: ingress-nginx-ext-controller  # This should match the name of the resource being patched
        namespace: ingress-nginx-ext
      data:
        # https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#access-log-params
        # error-log-level: "debug"  # Log level for controller logs
        # use-forwarded-headers: "true"  # Use the X-Forwarded-* headers to determine the client address
        enable-underscores-in-headers: "true"  # Allow underscores in headers
        proxy-body-size: "0"  # Allow unlimited request body size
        server-tokens: "false"  # Hide nginx version in error pages and Server header

  - target:
      kind: Service
      name: ingress-nginx-ext-controller
      namespace: ingress-nginx-ext
    patch: |-
      apiVersion: v1
      kind: Service
      metadata:
        name: ingress-nginx-ext-controller
        namespace: ingress-nginx-ext
      spec:
        externalTrafficPolicy: Local  # Use client IP address for load balancing

Here, we added a new patch for the Service with kind: Service that adds the externalTrafficPolicy: Local setting to preserve client IP addresses.

Didn't have to use use-forwarded-headers, but feel free to uncomment it and use if required.

codeaprendiz
  • 2,703
  • 1
  • 25
  • 49