Aller au contenu

Point de terminaison VPC ignoré : pourquoi le trafic passe encore par la NAT Gateway

Vous avez créé un point de terminaison VPC mais la facture NAT Gateway n'a pas bougé. Les points de terminaison de passerelle échouent sur l'association de tables de routage, ceux d'interface sur le DNS privé. Voici comment prouver lequel et le corriger.

Vous avez créé un point de terminaison VPC pour S3 ou un autre service AWS, mais les frais de traitement de la NAT Gateway n’ont pas baissé et les flow logs montrent encore du trafic sortant vers des IP publiques. Pour un point de terminaison de passerelle (S3, DynamoDB), la cause est presque toujours que le point de terminaison n’est pas associé aux tables de routage des sous-réseaux concernés, ou que le trafic est inter-régions. Pour un point de terminaison d’interface, c’est presque toujours que le DNS privé est désactivé — les clients continuent de résoudre les IP publiques du service et sortent par la NAT exactement comme avant.

Ce qui se passe

Les deux types de points de terminaison interceptent le trafic par des mécanismes complètement différents, et chacun a son échec classique.

Un point de terminaison de passerelle fonctionne par le routage : quand vous l’associez à une table de routage, AWS y insère une route dont la destination est une liste de préfixes gérée (pl-...) couvrant les plages IP publiques du service dans cette région, avec le point de terminaison (vpce-...) pour cible. Tout sous-réseau dont la table n’a pas cette entrée continue d’envoyer son trafic S3 vers sa route par défaut — la NAT Gateway. Deux corollaires. Les sous-réseaux ajoutés et les nouvelles tables n’héritent pas de l’association. Et la liste de préfixes ne couvre que la région du point de terminaison : une requête vers un compartiment d’une autre région résout vers des IP hors de la liste et emprunte la NAT quoi qu’il arrive.

Un point de terminaison d’interface fonctionne par le DNS : il crée des ENI avec des IP privées dans vos sous-réseaux, et — si le DNS privé est activé et que les attributs enableDnsSupport et enableDnsHostnames du VPC sont actifs — le nom d’hôte normal du service (sqs.ca-central-1.amazonaws.com) résout vers ces IP privées à l’intérieur du VPC. DNS privé désactivé, le nom continue de résoudre publiquement, et seuls les clients qui utilisent explicitement le nom DNS propre au point de terminaison (vpce-...amazonaws.com) l’empruntent. Les clients qui codent des IP publiques en dur, épinglent des points d’accès globaux ou passent par leur propre résolveur le contournent de la même façon. Le groupe de sécurité du point de terminaison doit aussi autoriser le 443 depuis les clients, sinon le trafic résout en privé puis fige — un autre échec, avec une autre signature.

Les politiques de point de terminaison sont la troisième couche, plus discrète : une politique restrictive peut refuser le compartiment ou l’action API en question, produisant des 403 que les équipes interprètent comme « le point de terminaison ne fonctionne pas » avant de contourner par la NAT.

Quoi vérifier en premier

  • Passerelle : la route pl- est-elle dans la table du sous-réseau source? Cherchez la route de liste de préfixes ciblant vpce-....
  • Interface : vers quoi le nom d’hôte résout-il depuis l’instance? Des réponses privées 10.x/172.x/192.168.x signifient que le point de terminaison joue; des réponses publiques, non.
  • Même région? Les appels S3/DynamoDB inter-régions n’utilisent jamais un point de terminaison de passerelle.
  • Le groupe de sécurité du point de terminaison autorise TCP 443 depuis les sous-réseaux ou groupes de sécurité clients.
  • Les attributs DNS du VPC sont actifs, puisque le DNS privé d’interface dépend des deux.

Comment vérifier

# Passerelle : à quelles tables de routage est-elle associée?
aws ec2 describe-vpc-endpoints \
  --filters "Name=vpc-id,Values=vpc-0abc123" \
  --query 'VpcEndpoints[].{Id:VpcEndpointId,Svc:ServiceName,Type:VpcEndpointType,RTs:RouteTableIds,PrivDns:PrivateDnsEnabled}'

# La table du sous-réseau source porte-t-elle la route de liste de préfixes?
aws ec2 describe-route-tables \
  --filters "Name=association.subnet-id,Values=subnet-0abc123" \
  --query 'RouteTables[].Routes[?starts_with(DestinationPrefixListId||``,`pl-`)]'

Depuis une instance du sous-réseau touché :

# Test d'interface : IP privées = point de terminaison utilisé
dig sqs.ca-central-1.amazonaws.com +short

# Test de passerelle pour S3 : ceci montre encore des IP publiques (normal!) —
# l'interception est à la couche ROUTE, alors vérifiez la route, pas le DNS
dig s3.ca-central-1.amazonaws.com +short

La preuve définitive, ce sont l’argent et les paquets : VPC > NAT gateways > Monitoring pour un BytesOutToDestination qui descend après le correctif, et les flow logs de l’ENI de la NAT où les plages de la liste de préfixes S3 disparaissent. La mécanique des points de terminaison est documentée dans la documentation Amazon VPC, et la décision passerelle-ou-interface elle-même est couverte dans points de terminaison VPC pour S3 et DynamoDB.

Le correctif

  1. Associez le point de terminaison de passerelle à chaque table de routage pertinente. VPC > Endpoints > sélectionner le point de terminaison > Route tables > Manage route tables, ou aws ec2 modify-vpc-endpoint --vpc-endpoint-id vpce-0abc123 --add-route-table-ids rtb-0aaa rtb-0bbb. La route de liste de préfixes apparaît automatiquement; vous ne l’écrivez jamais à la main.
  2. Activez le DNS privé sur le point de terminaison d’interface. aws ec2 modify-vpc-endpoint --vpc-endpoint-id vpce-0abc123 --private-dns-enabled, après avoir confirmé les deux attributs DNS du VPC. Les connexions longues existantes gardent leur ancienne résolution jusqu’à reconnexion — redémarrez les clients têtus.
  3. Ouvrez le groupe de sécurité du point de terminaison. Autorisez TCP 443 depuis les sous-réseaux applicatifs ou leurs groupes de sécurité. C’est le correctif quand le DNS retourne déjà des IP privées mais que les connexions figent.
  4. Ramenez le trafic inter-régions vers des ressources locales ou assumez la NAT. Répliquez le compartiment dans la région de la charge, ou utilisez le nom d’hôte régional précis et budgétez consciemment le chemin NAT pour ce qui reste.
  5. Sur des 403, corrigez la politique du point de terminaison, pas la route. Si les requêtes atteignent le service et sont refusées, élargissez la politique du point de terminaison (ou la condition aws:sourceVpce de la politique du compartiment) — contourner une politique par la NAT, c’est ainsi que naissent les constats d’audit.
  6. Redémarrez ou re-résolvez les clients après le changement. Les JVM avec un TTL de cache DNS infini et des connexions en pool utiliseront joyeusement l’ancien chemin public pendant des heures.

Quand c’est la mauvaise approche

Si le volume vers le service est négligeable, les frais horaires par AZ d’un point de terminaison d’interface plus le traitement au Go peuvent dépasser les frais NAT déplacés — des points de terminaison partout, c’est une posture, pas automatiquement une économie; faites l’arithmétique par service. Le trafic inter-régions et inter-partitions n’est pas réparable avec des points de terminaison de passerelle, point. Et si ce qu’il vous faut est un accès privé depuis le site via VPN ou Direct Connect, les points de terminaison de passerelle ne servent pas ce chemin — c’est le territoire des points de terminaison d’interface, par conception.

Erreurs fréquentes

  • Lancer dig contre S3, voir des IP publiques et conclure que le point de terminaison de passerelle est cassé — il ne change pas le DNS; c’est la route qui travaille.
  • Créer le point de terminaison dans le bon VPC mais n’associer que la table principale pendant que les charges utilisent des tables par AZ.
  • Laisser le DNS privé désactivé parce que l’avertissement de la console sur les attributs DNS a été fermé pendant la création.
  • Oublier les nouveaux sous-réseaux : la liste d’associations est statique, et le sous-réseau ajouté au dernier trimestre repasse par la NAT.

Prévention

  • Intégrez les associations de points de terminaison au module de sous-réseau dans Terraform/CloudFormation pour que les nouvelles tables soient attachées dès leur naissance.
  • Alertez sur BytesOutToDestination par passerelle NAT; un saut vers le haut est souvent une association de point de terminaison perdue ou contournée en silence.
  • Interrogez les flow logs chaque mois pour le trafic NAT correspondant aux listes de préfixes des services AWS — c’est la liste des points de terminaison que vous devriez avoir.
  • Standardisez le DNS privé activé pour chaque point de terminaison d’interface, sauf exception documentée.
  • Testez depuis un vrai sous-réseau de charge après chaque changement de point de terminaison, pas depuis le bastion qui vit ailleurs.

Un point de terminaison qui existe mais ne transporte rien est un coût pur sans bénéfice — cinq minutes de dig, une inspection de route et une métrique NAT vous disent quel côté du mécanisme a échoué. Si personne dans votre équipe ne possède vraiment l’environnement AWS de bout en bout, c’est la racine de la plupart de ces problèmes — Stack Harbor opère des comptes AWS au quotidien sous Opérations AWS, et vous pouvez réserver une revue AWS.