Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Derriere un proxy inverse

Servir console, explorateur, API de fichiers et interface Swagger sous https://hote/craft/, le proxy retirant le prefixe ou le transmettant.

ModeLe proxyLa configuration
retrait (Traefik StripPrefix, rewrite-target d’un Ingress, nginx proxy_pass http://up/;)recoit /craft/x, transmet /x, ecrit X-Forwarded-Prefix: /craftles chemins apres le retrait : souvent ceux par defaut
transmissiontransmet /craft/x tel quelbase_path, prefix et [api.ui] path sous /craft

Retirer le prefixe

[admin]
listen = "0.0.0.0:8080"

[admin.ban]
trusted_proxies = ["10.42.0.0/16"]   # le proxy

[api]
enabled = true
openapi = true

[api.ban]
trusted_proxies = ["10.42.0.0/16"]   # le meme : un seul ecouteur

[api.ui]
enabled = true

Le navigateur ouvre la console sur https://hote/craft/, l’explorateur sur https://hote/craft/files/, l’interface Swagger sur https://hote/craft/api/docs/ ; l’API repond sous https://hote/craft/api/v1/files/. Ouvrez le prefixe avec son / final : nginx et la redirection Traefik ci-dessous renvoient /craft vers /craft/.

nginx :

location /craft/ {
    proxy_pass http://craft-file-gate:8080/;
    proxy_set_header X-Forwarded-Prefix /craft;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_buffering off;       # les flux de la console
    client_max_body_size 0;    # les depots
}

Traefik (configuration dynamique ; stripPrefix ecrit X-Forwarded-Prefix et X-Forwarded-For) :

http:
  middlewares:
    craft-slash:
      redirectRegex:
        regex: "^(https?://[^/]+/craft)$"
        replacement: "${1}/"
    craft-strip:
      stripPrefix:
        prefixes: ["/craft"]
  routers:
    craft:
      rule: "PathPrefix(`/craft`)"
      middlewares: [craft-slash, craft-strip]
      service: craft
  services:
    craft:
      loadBalancer:
        servers:
          - url: "http://craft-file-gate:8080"

Kubernetes, ingress-nginx, devant le Service <release>-api du chart :

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: craft-file-gate
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/x-forwarded-prefix: /craft
    nginx.ingress.kubernetes.io/proxy-buffering: "off"
    nginx.ingress.kubernetes.io/proxy-body-size: "0"
spec:
  ingressClassName: nginx
  rules:
    - host: files.example.com
      http:
        paths:
          - path: /craft/(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: craft-file-gate-api
                port:
                  name: admin

Le proxy pose ou efface X-Forwarded-Prefix, il ne transmet jamais celui du client. trusted_proxies nomme les adresses du proxy : sous Kubernetes, le CIDR des pods de l’ingress, voir Derriere un ingress.

Transmettre le chemin

[admin]
listen = "0.0.0.0:8080"
base_path = "/craft/console"

[api]
enabled = true
prefix = "/craft/api/v1/files"

[api.ui]
enabled = true
path = "/craft/files"
location /craft/ {
    proxy_pass http://craft-file-gate:8080;
    proxy_set_header X-Forwarded-Prefix "";
    proxy_buffering off;
    client_max_body_size 0;
}

La console est sur https://hote/craft/console/, l’explorateur sur https://hote/craft/files/. Le proxy efface X-Forwarded-Prefix : il ne transmet jamais celui du client (ingress-nginx sans l’annotation x-forwarded-prefix le transmet ; HAProxy : http-request del-header X-Forwarded-Prefix). L’interface Swagger reste a /api/docs du serveur : routez /api/docs et /api/openapi.json a part, ou retirez le prefixe.

Ce que le serveur ecrit

URLDerriere un proxy qui retire le prefixe
pages, fichiers, polices, appels a l’API, flux de la console, redirections (/files vers files/, /api/docs vers docs/)relatives a leur page : rien a regler
URL d’un ticket de telechargement, entree servers du document OpenAPIprecedees de X-Forwarded-Prefix, quand le pair TCP est dans trusted_proxies
/livez, /readyz, /metricslues sur le pod par le kubelet et Prometheus, hors du prefixe

Le prefixe est un chemin de lettres, chiffres, -, _, ., ~, en une ligne d’en-tete, 256 octets au plus. X-Forwarded-Host et X-Forwarded-Proto ne sont pas lus : aucune URL ecrite ne porte d’hote ni de schema. Le routage du serveur ne change pas : seules les URL qu’il ecrit suivent le prefixe.