DEV Community

Cover image for Restricting Access by Geographical Location using NGINX with Helm
Pascal Gillet
Pascal Gillet

Posted on • Edited on

Restricting Access by Geographical Location using NGINX with Helm

This article explains how you can restrict content distribution to a particular country from services in your Kubernetes cluster, using the GeoIP2 dynamic module.

Prerequisites

  • Install NGINX Ingress Controller in your Kubernetes cluster using Helm.

Getting the GeoLite2 databases from MaxMind

The MaxMind company provides the GeoLite2 free IP geolocation databases. You need to create an account on the MaxMind website and generate a license key.

Configuring the NGINX Ingress Controller

Override the NGINX Helm chart with the following values:

controller:
  # Maxmind license key to download GeoLite2 Databases
  maxmindLicenseKey: ""
  extraArgs:
    # GeoLite2 Databases to download (default "GeoLite2-City,GeoLite2-ASN")
    maxmind-edition-ids: GeoLite2-Country
  service:
    # Preserve source IP...
    externalTrafficPolicy: Local
    # ...Which is only supported if we enable the v2 proxy protocol for the OVH load balancer (specific to OVH Cloud provider)
    annotations:
      service.beta.kubernetes.io/ovh-loadbalancer-proxy-protocol: "v2"
  config:
    use-proxy-protocol: "true"
    # Enable Ingress to parse and add -snippet annotations/directives
    allow-snippet-annotations: "true"
    # Enable geoip2 module
    use-geoip: "false"
    use-geoip2: "true"
    # Configure access by geographical location.
    # Here, we create a variable $allowed_country whose values 
    # depend on values of GeoIP2 variable $geoip2_country_code,
    # which lists all ISO 3166 country codes.
    # Map directives are only allowed at Ingress Controller level.
    http-snippet: |
      map $geoip2_country_code $allowed_country {
        default no;
        FR yes;
        US yes;
      }
Enter fullscreen mode Exit fullscreen mode

Example Ingress

A minimal Ingress resource example:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    # Restrict access by geographical location
    nginx.ingress.kubernetes.io/server-snippet: |
      if ($allowed_country = no) {
        return 451;
      }
spec:
  ingressClassName: nginx-example
  rules:
  - http:
      paths:
      - path: /testpath
        pathType: Prefix
        backend:
          service:
            name: test
            port:
              number: 80
Enter fullscreen mode Exit fullscreen mode

Note: The HTTP status code 451 was chosen as a reference to the novel
"Fahrenheit 451".

References

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay