Korzen
Bot Protection

Kubernetes

Bot Protection depuis une application sur Kubernetes : l'API key en Secret, l'IP du visiteur à travers le load balancer et ingress-nginx, et l'egress.

Kubernetes change trois choses à l'appel depuis votre serveur : où vit l'API key, comment l'adresse du visiteur survit au load balancer et à l'ingress, et si le pod peut même joindre korzen.dev. L'appel lui-même relève de votre framework : prenez-le dans le guide de votre stack.

La clé

Gardez l'API key dans un Secret, jamais dans l'image ni dans une ConfigMap, et passez-la au conteneur comme variable d'environnement :

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

L'IP du visiteur

Par défaut, un load balancer cloud cache le visiteur derrière sa propre adresse, et l'ingress aussi. Deux réglages préservent l'adresse du visiteur : externalTrafficPolicy: Local sur le Service du contrôleur d'ingress, et ingress-nginx qui fait confiance à l'en-tête qu'ajoute le load balancer. Votre application lit alors X-Real-IP, ou la dernière entrée de X-Forwarded-For, que pose ingress-nginx ; derrière 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

Egress

Si le cluster bloque par défaut le trafic sortant d'un namespace, le pod doit être autorisé à joindre le port 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 production

  • Un client HTTP par pod, gardé ouvert ; chaque réplique ouvre sa propre connexion, et c'est très bien.
  • Ne faites jamais dépendre une sonde readiness ou liveness de Bot Protection : quand il est lent, les pods doivent rester en service et être fail-open.
  • Le timeout de votre SDK se choisit selon l'endroit où tourne le cluster : un cluster dans l'ouest des États-Unis a besoin d'environ 300 ms.

Erreurs fréquentes

  • L'adresse de l'ingress envoyée comme celle du visiteur : chaque décision partage alors une IP, et Bot Protection voit un seul visiteur très occupé.
  • use-forwarded-headers activé sans rien devant que vous contrôliez : un visiteur écrit X-Forwarded-For et choisit son adresse.
  • La clé dans une ConfigMap ou intégrée à l'image, où toute personne ayant accès en lecture au namespace ou au registre la voit.