Korzen
Bot Protection

Kubernetes

Bot Protection desde una app en Kubernetes: la API key como Secret, la IP del visitante a través del load balancer e ingress-nginx, y la salida de red.

Kubernetes cambia tres cosas en la llamada desde tu servidor: dónde vive la API key, cómo sobrevive la dirección del visitante al load balancer y al ingress, y si el pod puede siquiera llegar a korzen.dev. La llamada en sí es la de tu framework: usa la guía de tu stack.

La clave

Guarda la API key en un Secret, nunca en la imagen ni en un ConfigMap, y pásala al contenedor como variable de entorno:

kubectl create secret generic korzen --from-literal=api-key=ak_your_key
# deployment.yaml, in your app's container
env:
  - name: KORZEN_API_KEY
    valueFrom:
      secretKeyRef:
        name: korzen
        key: api-key

La IP del visitante

Por defecto, el load balancer de la nube esconde al visitante tras su propia dirección, y el ingress también. Dos ajustes la conservan: externalTrafficPolicy: Local en el Service del ingress controller, y que ingress-nginx confíe en la cabecera que añade el load balancer. Tu aplicación lee entonces X-Real-IP, o la última entrada de X-Forwarded-For, que pone ingress-nginx; detrás de Cloudflare, CF-Connecting-IP.

# The ingress controller's Service: keep the visitor's address on the way in.
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
# ingress-nginx's ConfigMap: trust the load balancer in front, pass the address on.
apiVersion: v1
kind: ConfigMap
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
data:
  use-forwarded-headers: "true"     # only if a load balancer you control is in front
  compute-full-forwarded-for: "true"
  # use-proxy-protocol: "true"      # instead, if your cloud's load balancer speaks PROXY protocol

Tráfico de salida

Si el cluster bloquea el tráfico de salida de un namespace por defecto, el pod debe poder llegar al puerto 443:

# Only if your cluster blocks egress by default: let the app reach HTTPS.
# A plain NetworkPolicy matches addresses, not names, and korzen.dev answers from
# Cloudflare's ranges; with Cilium, an FQDN rule can name korzen.dev itself.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: app-egress-https
spec:
  podSelector:
    matchLabels:
      app: shop
  policyTypes: [Egress]
  egress:
    - ports:
        - port: 443
          protocol: TCP
    - ports:
        - port: 53
          protocol: UDP

En producción

  • Un cliente HTTP por pod, reutilizado; que cada réplica abra su propia conexión es normal.
  • Nunca hagas que un readiness o liveness probe dependa de Bot Protection: cuando vaya lento, los pods deben seguir en servicio y hacer fail open.
  • El timeout de tu SDK depende de dónde corre el cluster: uno en el oeste de EE. UU. necesita unos 300 ms.

Errores comunes

  • Enviar la dirección del propio ingress como la del visitante: todas las decisiones comparten una IP, y Bot Protection ve un único visitante muy ocupado.
  • use-forwarded-headers activado sin nada tuyo delante: el visitante escribe X-Forwarded-For y elige su dirección.
  • La clave en un ConfigMap o dentro de la imagen, donde la ve cualquiera que lea el namespace o el registry.