Une machine Linux multirésidente peut-elle implémenter un véritable modèle Strong ES ?
Cas d'utilisation spécifique
J'ai un système avec cinq interfaces différentes, chacune connectée au même sous-réseau, donc à la même passerelle vers Internet.
- Je voudrais écouter sur chaque interface séparément sur le même port, et m'assurer que les paquets sortent toujours de la même interface qu'ils sont entrés, et m'assurer que les paquets essayant d'arriver dans la "mauvaise" interface sont rejetés.
- J'aimerais pouvoir me lier à chaque interface et établir des connexions sortantes vers des destinations Internet qui proviennent toujours de la même adresse IP source à laquelle je me suis lié. Par exemple,
curl --interface interface_ip http://ipecho.net/plain
devrait toujours afficher la même adresse IP à laquelle je me suis lié avec
--interface
. - Les routes statiques peuvent être problématiques en raison de l'utilisation de DHCP sur l'une de ces interfaces.
RFC 1122
De RFC 1122 - Exigences pour les hôtes Internet - Couches de communication, Section 3.3.4.2 - Exigences de multihoming :
Les implémenteurs d'hôtes Internet ont utilisé deux
modèles conceptuels différents pour le multi-hébergement, brièvement résumés
dans la discussion suivante. Ce document ne prend
aucune position sur le modèle préféré ; chacun semble avoir une
place. Cette ambivalence se traduit par le fait que les questions (A)
et (B) sont facultatives.
Modèle ES fort
Le modèle Strong ES (End System, c'est-à-dire hôte)
met l'accent sur la distinction hôte/passerelle (ES/IS),
et remplacerait donc MUST par MAY dans
les problèmes (A ) et (B) ci-dessus. Il a tendance à modéliser un
hôte multirésident comme un ensemble d'hôtes logiques au sein
du même hôte physique.En ce qui concerne (A), les partisans du modèle Strong ES
notent que les mécanismes de routage Internet automatique
ne pourraient pas acheminer un datagramme vers une
interface physique qui ne correspondait pas à la
adresse de destination.Sous le modèle Strong ES, le calcul de route
pour un datagramme sortant est le mappage :route(src IP addr, dest IP addr, TOS) -> gateway
Ici, l'adresse source est incluse en paramètre
afin de sélectionner une passerelle directement
accessible sur l'interface physique correspondante.
Notez que ce modèle requiert logiquement qu'en
général il y ait au moins une passerelle par défaut, et
de préférence plusieurs par défaut, pour chaque adresse IP source
.Modèle ES faible
Cette vue atténue la distinction ES/IS, et
remplacerait donc NE DOIT PAS pour MAY dans
les questions (A) et (B). Ce modèle peut être le plus
naturel pour les hôtes qui écoutent les protocoles de routage de passerelle
et est nécessaire pour les hôtes qui ont
une fonctionnalité de passerelle intégrée.Le modèle ES faible peut entraîner l'échec du mécanisme de redirection
. Si un datagramme est envoyé sur une interface physique
qui ne correspond pas à l'adresse de destination, la passerelle de premier saut
ne réalisera pas quand elle doit envoyer une redirection. D'
d'autre part, si l'hôte dispose d'une fonctionnalité de passerelle
intégrée, il dispose d'informations de routage
sans écouter les redirections.Dans le modèle Weak ES, le calcul de route pour un
datagramme sortant est le mappage :route(dest IP addr, TOS) -> gateway, interface
Linux est un modèle Weak ES par défaut, alors que FreeBSD et d'autres variétés Unix agissent comme des systèmes Strong ES. Existe-t-il un moyen de le faire se comporter davantage comme un système Strong ES ?
Qu'est-ce que sysctl
ou la configuration au moment de la compilation devrait être définie pour qu'elle se comporte comme un Strong ES par défaut, sans ajouter de règles de routage spécifiques pour toute nouvelle interface que vous ajoutez ? Je sais que nous pouvons faire un filtrage strict de la route source via net.ipv4.conf.default.rp_filter = 1
, mais il semble y avoir bien plus que cela. Comment puis-je utiliser le routage basé sur la source par défaut ?
Réponse acceptée :
Le simple fait d'ajouter des règles de pare-feu ne suffira pas pour celui-ci. Vous voulez que le système achemine le trafic comme s'il s'agissait de deux systèmes indépendants partageant le même matériel et les mêmes processus :c'est ce qu'est le modèle Strong ES.
Connexes :Linux - la page de manuel n'a été trouvée qu'après avoir été exécutée avec root ?Lorsque vous visez le modèle Strong ES sous Linux, vous aurez d'abord besoin de ces paramètres sysctl :
net.ipv4.conf.all.arp_filter=1
net.ipv4.conf.all.arp_ignore=1 # or even 2
net.ipv4.conf.all.arp_announce=2
Ces paramètres permettront à ARP de se comporter de manière appropriée avec le modèle Strong ES, c'est-à-dire que lorsqu'une requête ARP est reçue, seule l'interface avec l'adresse exacte demandée répondra, et seulement si le trafic vers l'adresse d'origine serait en fait envoyé via cette adresse spécifique. interface.
Ensuite, puisque vous avez cinq interfaces dont vous souhaitez qu'elles se comportent différemment en termes de routage, vous devrez configurer cinq tables de routage personnalisées. Vous pouvez utiliser des numéros pour les identifier, mais il est généralement plus clair de leur attribuer des noms. Alors, choisissez des numéros pour chacun d'eux entre 1 et 252, et quelques noms appropriés. (Les numéros 0, 253, 254 et 255 sont réservés.)
Par exemple, choisissons 100 =rtable0, 101 =rtable1, 102 =rtable2, 103 =rtable3 et 104 =rtable4. Ajoutez ces numéros et noms à la fin de /etc/iproute2/rt_tables
fichier :
# ...default stuff above...
100 rtable0
101 rtable1
102 rtable2
103 rtable3
104 rtable4
Ensuite, remplissez chaque table de routage personnalisée avec un ensemble minimal d'entrées de route appropriées pour chaque interface. (Je remplace les valeurs réelles par des noms de variables d'environnement nommés de manière descriptive, espérons-le.)
ip route add $ETH0_NET dev eth0 proto static src $ETH0_IP table rtable0
ip route add default via $ETH0_GW dev eth0 proto static src $ETH0_IP table rtable0
ip route add $ETH1_NET dev eth1 proto static src $ETH1_IP table rtable1
ip route add default via $ETH1_GW dev eth1 proto static src $ETH1_IP table rtable1
# ... and so on, for all 5 interfaces
Enfin, ajoutez des règles de routage avancées qui vérifieront l'adresse source de chaque package et choisiront la table de routage à utiliser en conséquence :
ip rule add from $ETH0_IP table rtable0
ip rule add from $ETH1_IP table rtable1
#...
Pour rendre toute cette configuration persistante lors des redémarrages, vous devrez peut-être écrire des scripts de démarrage personnalisés (ou éventuellement ifup-pre
ou ifup-post
scripts) en fonction des conventions de votre distribution Linux.
Pour une assurance supplémentaire, vous pouvez ajouter des règles iptables par interface pour supprimer silencieusement tous les paquets entrants susceptibles d'être reçus sur la mauvaise interface. Si tout va bien, le nombre de paquets pour ceux-ci devrait rester zéro :s'ils commencent à augmenter, vous avez peut-être manqué quelque chose dans la configuration.
iptables -A INPUT -m addrtype --dst-type UNICAST -i eth0 ! -d $ETH0_IP -j DROP
iptables -A INPUT -m addrtype --dst-type UNICAST -i eth1 ! -d $ETH1_IP -j DROP
# ... and so on for each interface
Remarque : J'ai déjà mis en place une configuration comme celle-ci basée sur une ancienne discussion sur Internet de Rick Jones et d'autres gourous du réseautage. Ils ont dit, paraphrasés, "alors que tout cela est clairement nécessaire pour obtenir un comportement Strong Host Model sous Linux, je ne peux pas garantir qu'il soit suffisant pour tous les cas d'utilisation possibles ». Cela a fonctionné parfaitement pour moi; cela peut vous suffire ou non, en fonction de l'utilisation que vous en ferez.
Avertissement : assurez-vous que vous disposez d'une sorte d'accès à la console locale ou distante au système lors de la configuration de cette configuration. Cette configuration est extrêmement susceptible de gâcher complètement votre accès au réseau alors qu'elle n'est qu'à moitié terminée.
Bien qu'il soit possible de configurer N interfaces avec seulement (N-1) tables de routage personnalisées, ma préférence personnelle est de déplacer toute la configuration de routage vers des tables personnalisées lors de l'utilisation du routage avancé. Avoir route -n
ou ip route show
apparaître essentiellement vide alors que le système a clairement des connexions réseau sera un très gros indice que quelque chose de très spécial se passe. Néanmoins, à l'époque où j'ai mis en place un système comme celui-ci, j'ai également mis en place une notice permanente dans /etc/motd
sur le routage avancé en vigueur et les emplacements des scripts réels qui le configurent.