web-dev-qa-db-fra.com

Linux NetFilter: Comment la connexion Connection est-elle modifiée par NAT?

Pour le moment, je plonge dans les détails de l'architecture NetFilter de Linux. Je connais déjà des crochets NetFilter, des tables, des chaînes, des différents modules de noyau, etc.
[.____] mais il y a un détail de NAT en combinaison avec le suivi de la connexion que je ne comprends pas.

J'essaie d'expliquer mon problème avec un petit exemple de Snat. Dans cet exemple, je vais ignorer la couche de transport parce que je pense qu'il n'est pas nécessaire de comprendre mon problème. S'il vous plait corrigez moi si je me trompe!

Il existe un ordinateur client sur le réseau local avec l'adresse IP 192.168.2.55 et une passerelle NAT avec l'adresse IP externe 193.157.56.3. Maintenant, le client souhaite communiquer avec un serveur et l'adresse IP 217.254.1.76 sur Internet.
Donc, le client envoie un paquet avec SRC = 192.168.2.55/dst = 217.254.1.76 à la passerelle NAT qui est également la passerelle par défaut. Le suivi de la connexion suit cette nouvelle connexion et crée deux nouveaux tuples:

Ip_ct_dir_original: SRC = 192.168.2.55, DST = 217.254.1.76
IP_CT_DIR_REPLY: SRC = 217.254.1.76, DST = 192.168.2.55

Ip_ct_dir_original et ip_ct_dir_reply sont des macros pour accéder à un tableau de deux tuples.

Au crochet de posTourting NAT Demandons le suivi de la connexion pour une connexion existante et, si cela réussit, modifie l'adresse source dans l'en-tête du paquet. Il crée également une règle de DNAT pour revenir à la destination. Adresse des réponses.
Maintenant, je vais au point de mon poblem. NAT modifie l'adresse de destination dans ip_ct_dir_reply à son adresse IP externe 193.157.56.3. Ainsi, les tuples ressemblent à ceci:

Ip_ct_dir_original: SRC = 192.168.2.55, DST = 217.254.1.76
[.____] IP_CT_DIR_REPLY: SRC = 217.254.1.76, DST = 193.157.56.3

C'est pourquoi le suivi de la connexion peut suivre les réponses dans le crochet préalable car il existe un tuple existant pour la réponse. Mais après avoir suivi le paquet NAT modifie l'adresse de destination à l'adresse du client, 192.168.2.55.
Maintenant ma question: Comment la connexion de la connexion peut-elle suivre ce paquet dans le crochet postrait? Il n'y a pas de tuple de réponse avec src = 217.254.1.76/dst = 192.168.2.55 parce que NAT l'a changé.
[.____] Y a-t-il quelque chose que j'ai manqué?

5
idlmn89

Vous devez installer la commande conntrack _ généralement emballée comme Conntrack ou Conntrack-Tools, à partir de http://conntrack-tools.netfilter.org/ . Il affichera surtout le même contenu que /proc/net/nf_conntrack mais peut faire plus.

Exécutez Conntrack en mode événement sur le NAT passerelle: conntrack -E (ou vous pouvez choisir conntrack -E --proto tcp --orig-port-dst 443 Limiter à HTTPS). Maintenant, votre exemple précédent avec une demande HTTPS donnerait quelque chose de similaire à celui-ci:

    [NEW] tcp      6 120 SYN_SENT src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 [UNREPLIED] src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798
 [UPDATE] tcp      6 60 SYN_RECV src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798
 [UPDATE] tcp      6 432000 ESTABLISHED src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798 [ASSURED]
 [UPDATE] tcp      6 120 FIN_WAIT src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798 [ASSURED]
 [UPDATE] tcp      6 60 CLOSE_WAIT src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798 [ASSURED]
 [UPDATE] tcp      6 30 LAST_ACK src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798 [ASSURED]
 [UPDATE] tcp      6 120 TIME_WAIT src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798 [ASSURED]
[DESTROY] tcp      6 src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798 [ASSURED]

La table NAT est spéciale, en ce qu'elle est tilisée uniquement une fois par écoulement *, lorsque le [NEW] L'état est créé. Tout le reste est court-circuité par l'entrée Conntrack trouvée. La règle de Snat en position postrait n'a pas "créé silencieusement une règle de DNAT" pour la réponse. Il a modifié l'entrée Conntrack pour avoir une réponse DST = 193.157.56.3 et a déclaré à NetFilter "J'ai changé quelque chose", c'est la majeure partie. Tout le reste (y compris l'altération IP source) est géré par Conntrack (modules NF_Connrack, NF_Conntrack_IPV4) et NAT (modules nf_nat, nf_nat_ipv4 et peut-être quelques-uns d'autres ici), pas par IPTABLES. Considérez les entrées sont une base de données d'État de connexion.

Lorsqu'un paquet de réponse est reçu, le paquet, sans association stockée, est examiné par les entrées Conntrack (regardant une association à la fois, soit dans la partie d'origine, soit dans la partie de la réponse, cela n'a pas d'importance) et un Match est trouvé parce que l'entrée a été créée auparavant. Ensuite, les informations emballées sont mises à jour avec cette association de connexion. Il n'est pas nécessaire de rechercher ce paquet bien que les entrées plus tard, même si certaines de ses propriétés (source ou destination ...) sont modifiées, les informations sont directement disponibles. Certaines des fonctions macro/lignes de traitement de la macro/en ligne sont définies dans Skbuff.h . Chercher _nfct et nfct. Le paquet (alias le Skbuff), après la recherche, reçoit cette valeur en skb->_nfct.

Donc, les rares choses que vous auriez pu manquer:

  • iptables n'est pas NetFilter. C'est un utilisateur de NetFilter. NFTABLES est un autre utilisateur de NetFilter. Conntrack et Nat (par exemple, le module nf_nat) font partie de NetFilter.
  • le crochet postrait ne verra jamais le paquet de réponse car la connexion n'est pas nouvelle: la table NAT n'est plus appelée pour ce flux et les paquets identifiés comme faisant partie de ce flux.
  • la majeure partie de la manipulation de Conntrack et de NAT se fait ... par Conntrack et Nat, non par IPtables. iptables peut utiliser les ressources de Conntrack (par exemple: -m conntrack --ctstate ESTABLISHED) ou NAT (tout dans la table NAT doit). Pour l'exemple ci-dessus, l'entrée Conntrack a à elle seule les informations sur "DE-SNAT" le paquet et, en effet, il ressemble à un DNAT avec une connexion à l'origine entrante.
  • Il n'est généralement pas nécessaire de rechercher les entrées Conntrack plus d'une fois pour une partie de paquets d'une connexion existante, l'indice "est attaché au paquet après la recherche.

Vous pouvez être convaincu que la table NAT ne constate pas d'autres paquets après la première en fonctionnant quelques fois iptables-save -c Et en regardant comment les compteurs augmentent les règles dans la table NAT: uniquement pour le premier paquet.

* Regardez le NAT Partie:

Cette table est légèrement différente de la table `Filtre ', en ce sens que seul le premier paquet d'une nouvelle connexion traversera la table: le résultat de cette traversée est ensuite appliqué à tous les futurs paquets de la même connexion.

8
A.B