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é?
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:
-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.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.