skip to Main Content

Hello anyone who reads this,

I’m looking for a way to restrict access to a publically exposed service (type LoadBalancer) at 234.234.234.234:1234 to a specific trusted IP at 123.123.123.123.

The way to do this seems to be via
nginx.ingress.kubernetes.io/whitelist-source-range: 123.123.123.123/32
as described in articles such as this: https://medium.com/@maninder.bindra/using-nginx-ingress-controller-to-restrict-access-by-ip-ip-whitelisting-for-a-service-deployed-to-bd5c86dc66d6

However, this runs into a problem because the default externalTrafficPolicy being set to "Cluster" obfuscates the sender IP to some local bs even for the bloody Ingress controller.

The solution to this appears to be to set controller.service.externalTrafficPolicy to Local, but I’m not sure about the ramifications of that since it changes the entire way of addressing pods and I’ve read some posts about performance issues with this approach.
There is also the problem that the resource in question already exists and I’d have to recreate it fully, apparently. Every post I’ve read on this seems to assume your resource doesn’t exist yet.

I wonder if there is a way to lift the source IP obfuscation without a change as large-looking as that.

2

Answers


  1. Chosen as BEST ANSWER

    "Setting the externalTrafficPolicy to Local comes with potential downsides such as Load Distribution: Traffic is only sent to nodes with relevant pods or in case of pod failures, the service won't reroute traffic to other nodes unless a relevant pod is available on those nodes." - Arko

    This explanation resolved my doubts about using externalTrafficPolicy: Local in my specific use case.


  2. To implement IP whitelisting in a public Kubernetes service with the Nginx Ingress controller, you need to configure the externalTrafficPolicy to Local to preserve the client’s IP address. By default, the externalTrafficPolicy is set to Cluster, which means that traffic from the client is routed to any node in the cluster, and this can obfuscate the original client IP address.

    To retain the client’s IP address, set the externalTrafficPolicy to Local for your LoadBalancer service:

    example

    apiVersion: v1
    kind: Service
    metadata:
      name: myapp-service
    spec:
      selector:
        app: myapp
      ports:
      - protocol: TCP
        port: 1234
        targetPort: 5678
      type: LoadBalancer
      externalTrafficPolicy: Local
    

    This setting ensures that external traffic is routed directly to the nodes where the pods are running, preserving the client’s IP address.

    enter image description here

    You can update an existing service by applying this configuration, or you can patch the service using

    kubectl patch service myapp-service -p '{"spec":{"externalTrafficPolicy":"Local"}}'
    

    Next, configure the Ingress resource for IP whitelisting using the nginx.ingress.kubernetes.io/whitelist-source-range annotation:

    example

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: myapp-ingress
      annotations:
        nginx.ingress.kubernetes.io/whitelist-source-range: "123.123.123.123/32"
    spec:
      rules:
      - host: example.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myapp-service
                port:
                  number: 1234
    

    enter image description here

    This configuration restricts access to the Ingress to the specified IP address 123.123.123.123 and will use IP whitelisting in Nginx Ingress for a public service, setting externalTrafficPolicy to Local and preserve the client IP.

    Another way to restrict access to a publicly exposed service in AKS is you can use the nginx.ingress.kubernetes.io/whitelist-source-range annotation to whitelist a specific trusted IP. However, the default externalTrafficPolicy being set to "Cluster" can obfuscate the sender IP, even for the Ingress controller. To lift the source IP obfuscation without changing the externalTrafficPolicy, you can use the nginx.ingress.kubernetes.io/real-ip-header annotation to specify the header that contains the real IP address of the client. Set the value to X-Forwarded-For to use the X-Forwarded-For header.

    example-

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: example-ingress
      annotations:
        nginx.ingress.kubernetes.io/whitelist-source-range: "123.123.123.123/32"
        nginx.ingress.kubernetes.io/real-ip-header: "X-Forwarded-For"
    spec:
      rules:
      - host: example.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: example-service
                port:
                  name: http
    

    This example uses the nginx.ingress.kubernetes.io/real-ip-header annotation to specify the X-Forwarded-For header as the header that contains the real IP address of the client. This allows you to lift the source IP obfuscation without changing the externalTrafficPolicy.

    Using either externalTrafficPolicy: Local or the real-ip-header annotation with X-Forwarded-For approach to achieve IP whitelisting with Nginx Ingress in AKS are valid, and the choice between them depends on the specific requirements and network architecture.

    References:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search