「Kubernetes」- 通过 GeoIP 特性来限制访问者地域 | Ingress Nginx Controller

结果

通过 Ingress Nginx Controller GeoIP 特性,来限制网站访问者的地域。如果非特定地域,则拒绝访问。如果是指定地域,则允许访问。

实现

通过启用 GeoIP2 支持

https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#use-geoip2
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#geoip2-autoreload-in-minutes

通过 MaxMind License 方式,需要进行如下配置:

  • controller.livenessProbe.initialDelaySeconds: 30
  • controller.livenessProbe.periodSeconds: 30
  • controller.config.use-geoip2: true
  • controller.config.geoip2-autoreload-in-minutes: 1440 # 无需单位
  • controller.maxmindLicenseKey: “xxxxxxx”

通过该方式,理论上是能够实现,但是受制于网络和政策,导致国内无法访问 MaxMind 下载 GeoLite 数据库。

通过挂载数据库文件实现

根据文档:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#use-geoip2

...
controller:
  ...
  extraVolumeMounts: 
  - name: etc-ingress-controller-geoip
    mountPath: /etc/ingress-controller/geoip
  ...
  extraVolumes:
  - name: etc-ingress-controller-geoip
    emptyDir: {}
  ...
  extraInitContainers: 
  - name: init-geoip-download
    image: ccr.ccs.tencentyun.com/d3rm-3rd/docker.io_library_busybox:1.37.0 # busybox
    command: ['sh', '-c']
    args: 
    - |
      cd /etc/ingress-controller/geoip/
      wget https://package.example.com/repository/static-resources/maxmind/20251124/GeoLite2-ASN_20251124.tar.gz
      wget https://package.example.com/repository/static-resources/maxmind/20251124/GeoLite2-City_20251121.tar.gz
      wget https://package.example.com/repository/static-resources/maxmind/20251124/GeoLite2-Country_20251121.tar.gz
      tar --strip-components=1 -xvf GeoLite2-ASN_20251124.tar.gz
      tar --strip-components=1 -xvf GeoLite2-City_20251121.tar.gz
      tar --strip-components=1 -xvf GeoLite2-Country_20251121.tar.gz
    volumeMounts:
    - name: etc-ingress-controller-geoip
      mountPath: /etc/ingress-controller/geoip
  ...
  config: 
    use-geoip2: true
    geoip2-autoreload-in-minutes: 1440
    http-snippet: |
      # geoip2 /etc/ingress-controller/geoip/GeoLite2-City.mmdb {
      #     $geoip2_data_city_name_en default=London city names en;
      # }
    server-snippet: |
      if ($geoip2_city_country_name != China) {
          return 200 $geoip2_city_country_name;
      }
      if ($geoip2_city !~* "Beijing|Shanghai") {
          return 200 $geoip2_city;
      }
...

http-snippet: 该参数无需配置,经过调试,我们发现 use-geoip2: true 将增加 geoip2 {} 配置。如果增加 http-snippet geoip2 配置,否则将提示 “Duplicate GeoIP2 mmdb” 错误。

$geoip2_city 其为其已预先定义的变量。

需要确保客户端能够取得真实的客户端地址(公网地址),externalTrafficPolicy: Local,否则无法解析出正确地理地址。