TLS et sécurité avec Envoy Gateway : configurer HTTPS et éviter que votre API tourne à nu
Faire fonctionner HTTP n'est que l'échauffement. À moins que votre service ne vive à l'âge de pierre, la production a presque certainement besoin de HTTPS. Cet article couvre les fondamentaux TLS d'Envoy Gateway pour que vos API cessent de circuler en clair.
Comment TLS fonctionne dans Gateway
L'approche la plus courante : terminer TLS au niveau du listener du Gateway.
Cela signifie :
- Le client se connecte en HTTPS
- Le Gateway gère la négociation et le certificat
- Le trafic est ensuite transféré à votre Service sans chiffrement en interne
Un listener HTTPS de base ressemble à ceci :
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: eg
spec:
gatewayClassName: eg
listeners:
- name: http
protocol: HTTP
port: 80
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- kind: Secret
group: ""
name: example-certDeux choses comptent ici :
protocol: HTTPStls.mode: Terminate
Autrement dit : TLS se termine ici, et le Gateway gère le certificat.
HTTPS + HTTPRoute vs TLSRoute : quelle différence
C'est important, parce que beaucoup de gens voient TLSRoute et demandent immédiatement :
"Un listener HTTPS ne suffit-il pas déjà ? Pourquoi a-t-on besoin d'un TLSRoute séparé ?"
La différence tient à la question de savoir si le Gateway termine TLS :
| Scénario | Combinaison courante | Description |
|---|---|---|
| Le Gateway termine TLS, puis applique des règles HTTP | HTTPS listener + HTTPRoute |
Le cas le plus courant pour les sites web et les API |
| Le Gateway ne déchiffre pas, il route seulement le trafic chiffré selon le SNI | TLS listener + TLSRoute |
Scénario de TLS passthrough |
Autrement dit :
- Si vous voulez inspecter
path,header,methodau niveau du Gateway, vous devez d'abord terminer TLS, puis utiliserHTTPRoute - Si vous voulez conserver un chiffrement de bout en bout et ne pas déchiffrer au niveau du Gateway,
TLSRouteest le bon chemin
Aucune des deux approches n'est "plus avancée" : l'essentiel est de savoir ce que vous voulez, entre "terminer TLS et faire du routage L7" ou "garder le chiffrement intact et faire du routage basé sur SNI".
Préparer le Secret de certificat
Pour les environnements de test, un certificat auto-signé suffit. Les exemples officiels utilisent exactement cette approche :
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \
-subj '/O=example Inc./CN=example.com' \
-keyout example.com.key \
-out example.com.crt
openssl req -out www.example.com.csr -newkey rsa:2048 -nodes \
-keyout www.example.com.key \
-subj "/CN=www.example.com/O=example organization"
openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key \
-set_serial 0 -in www.example.com.csr -out www.example.com.crtStockez le certificat et la clé sous forme de Secret Kubernetes :
kubectl create secret tls example-cert \
--key=www.example.com.key \
--cert=www.example.com.crtLe Gateway pourra ensuite référencer ce Secret via certificateRefs.
⚠️ Les certificats auto-signés servent uniquement au test. En production, utilisez cert-manager ou votre processus existant de gestion de certificats. Ne transportez pas tel quel le setup de démonstration en production, sinon c'est comme vivre de nouilles instantanées : acceptable de temps en temps, mais impossible à tenir sur la durée.
Ajouter un listener HTTPS à un Gateway existant
Si vous avez déjà un Gateway eg depuis l'article précédent, vous pouvez le patcher directement :
kubectl patch gateway eg --type=json --patch '
- op: add
path: /spec/listeners/-
value:
name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- kind: Secret
group: ""
name: example-cert
'Vérifiez le status :
kubectl get gateway/eg -o yamlSi le listener semble sain, testez HTTPS :
curl -v -HHost:www.example.com \
--resolve "www.example.com:443:${GATEWAY_HOST}" \
--cacert example.com.crt \
https://www.example.com/getCette commande est excellente pour une validation locale, surtout lorsque le DNS n'est pas encore câblé.
Un Gateway, plusieurs domaines HTTPS
Si vous avez plusieurs domaines, ajoutez plusieurs listeners HTTPS au même Gateway.
Par exemple, pour ajouter foo.example.com :
listeners:
- name: https-main
protocol: HTTPS
port: 443
hostname: www.example.com
tls:
mode: Terminate
certificateRefs:
- name: example-cert
- name: https-foo
protocol: HTTPS
port: 443
hostname: foo.example.com
tls:
mode: Terminate
certificateRefs:
- name: foo-certN'oubliez pas de mettre à jour le HTTPRoute correspondant avec le bon hostname ; sinon, le listener peut bien écouter, mais la route ne saura pas où envoyer le trafic.
Modèle mental pour TLSRoute
Pour le TLS passthrough, voyez TLSRoute ainsi :
💡 L'
apiVersiondeTLSRoutepeut différer selon la version des CRD Gateway API installée. L'exemple ci-dessous sert à illustrer le concept ; vérifiez la version installée dans votre cluster avant de l'appliquer.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: eg-tls
spec:
gatewayClassName: eg
listeners:
- name: tls
protocol: TLS
port: 443
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: passthrough-route
spec:
parentRefs:
- name: eg-tls
hostnames:
- "db.example.com"
rules:
- backendRefs:
- name: db-service
port: 5432Cas d'usage courants pour ce pattern :
- Routage uniquement selon le hostname SNI
- Conservation du chiffrement jusqu'au backend
- Pas d'analyse des paths/headers HTTP au niveau du Gateway
Donc la plus grande différence entre TLSRoute et HTTPRoute n'est pas seulement le nom : ils opèrent à des couches de trafic complètement différentes.
Références de certificats inter-namespace
La documentation officielle met en avant une capacité utile :
Un Gateway peut référencer des Secrets de certificats d'autres namespaces, mais cela nécessite un ReferenceGrant.
Par exemple, si l'équipe plateforme stocke les certificats de manière centralisée dans envoy-gateway-system, mais que le Gateway applicatif se trouve dans default, vous ne pouvez pas simplement faire une référence à travers les namespaces sans autorisation explicite.
Exemple :
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-default-to-read-cert
namespace: envoy-gateway-system
spec:
from:
- group: gateway.networking.k8s.io
kind: Gateway
namespace: default
to:
- group: ""
kind: SecretCela signifie :
- Un
Gatewaydans le namespacedefault - Est autorisé à référencer des ressources
Secretdansenvoy-gateway-system
Sans ReferenceGrant, cette référence inter-namespace est considérée comme invalide. C'est un mécanisme de protection, pas un excès de rigidité de Gateway API.
Résumé en une ligne
Le TLS d'Envoy Gateway n'est pas aussi mystérieux qu'il en a l'air : préparez le Secret de certificat, configurez le listener HTTPS, vérifiez que votre route et votre hostname sont alignés — et c'est essentiellement tout.
💡 L'erreur de débutant la plus courante n'est pas que TLS soit difficile, c'est que trois éléments ne sont pas alignés :
hostname,certificateRefsetHTTPRoute hostnames. Si un seul de ces trois points dévie, le trafic commence à mal se comporter.
Étape suivante
Maintenant que vous avez couvert l'installation, les concepts, le routage et TLS, l'article suivant condense tout cela en un ensemble de pratiques moins susceptibles d'exploser en production : 👉 Bonnes pratiques