Défi geek
Ce défi est une expérience, il n'y aucun prix pour le moment. Si la sauce prend, il est envisagé d'organiser des concours dans un cadre plus intéressant.
Ce problème a été soulevé par une grosse entreprise. La solution est déjà connue, je ne le pose ici que pour le jeu. Bien entendu le problème a été ramené à un cas d'école pour faciliter la compréhension et la réflexion.
Il est inutile de tester votre solution et vous pouvez en proposer plusieurs via les commentaires. Ces derniers sont modérés pour garder le secret quelques jours. Bien sûr cela ne vous empêche pas de commenter que je suis une personne excécrable ou que le multicast marche mieux sous NetBSD. Quiconque laisse un commentaire sera averti par E-mail de la mise en ligne de la solution.
Une version de ce problème correspondant à l'environnement réel de l'entreprise arrivera peu après la résolution de ce premier problème. La complexité et la difficulté seront supérieures.
Objectif :
Les clients envoient des requêtes en broadcast, un service déjà configuré sur le serveur doit y répondre.
Contexte :
- Serveur Linux avec une carte Ethernet, configuré comme suit :
- Distribution moderne générique (Debian, Ubuntu, Fedora, etc.) dont noyau Linux 2.6 ;
- La carte Ethernet est configurée avec
ifconfig eth0 10.0.0.1 netmask 255.255.255.0, addresse de broadcast par défaut soit 10.0.0.255 ; - L'interface de loopback (lo) est disponible ;
- Chaînes netfilter vides, politique par défaut ACCEPT, le reste de la configuration est celle de l'installation par défaut de la distribution ;
- Les clients sont sur le même segment Ethernet (i.e. aucun routeur), sur 10.0.0.0/16, addresse broadcast par défaut soit 10.0.255.255 ;
- Les ports utilisés ne sont pas connus (par exemple rpc.bootparamd).
Contraintes :
- Le serveur ne peut écouter que sur 10.0.0.0/24 et 10.0.255.255, ne peut émettre que sur 10.0.0.0/24 (les raisons pour ce type de contraintes seront plus claires dans la version complexe) ;
- La configuration réseau du serveur est librement modifiable tant que la règle précédente est respectée et assurée dans l'espace noyau ;
- La configuration réseau des clients ne peut pas être changée ;
- Pas de patchs ou de paquets ésotériques ;
- La solution tient sur 3 commandes exécutées en root. Elles ne peuvent reposer que sur des outils disponibles sur toute distribution moderne générique. Inutile de faire en sorte que les changements persistent après un redémarrage, de toute façon un serveur ne crashe pas et n'a pas besoin de redémarrer.
Si vous autorisez le serveur à émettre sur 10.0.255.255 et acceptez d'êtres crades (mais compatibles avec au moins Solaris et Linux), une commande suffit.
Edit du 17 avril 2010, aka « La soluce »
Xav l'emporte avec sauf erreur de ma part 2 fautes d'étourderie sur iptables (il faudrait utiliser -A au lieu de -l et –to-destination au lieu de -to) !
Je préfère ne pas créer de VLAN et reposer sur du SNAT pour que les logiciels « voient » l'adresse de destination des requêtes, c'est plus transparent et ça pourrait jouer un rôle avec une implémentation de bootparamd par exemple (puisque le client demande entre autres quel routeur utiliser).
On peut attacher des IP individuelles à une interface existante sans créer d'interface virtuelle (eg eth0:1) et avec un masque implicite de /32 avec ip addr add.
Ma solution favorite est donc (avec :0-1023 pour désactiver le mécanisme de changement de ports) :
# ip addr add 10.0.255.255 dev eth0
# iptables -t nat -A POSTROUTING -s 10.0.255.255 -j SNAT –-to-source 10.0.0.1:0-1023
14 Comments to “Défi geek”
Leave a Reply

je mise sur un problème de route mais je vais me coucher, je poste juste pour avoir la réponse plus tard :p
ifconfig eth0 down
ifconfig eth0 10.0.0.1 netmask 255.255.0.0
ifconfig eth0 up
?
ifconfig ethx:1 10.0.255.255/32
Salut,
à première vue, il suffirait simplement de changer le masque de sous-réseau du serveur, en gros mettre un masque de classe A (sur 8 bits).
Ainsi, l’adresse 10.0.255.255 devient une adresse d’hôte dans le contexte serveur, mais reste bien une adresse de diffusion pour les clients.
Cordialement,
@marquez, @daboule, “Le serveur ne peut écouter que sur 10.0.0.0/24 et 10.0.255.255, ne peut émettre que sur 10.0.0.0/24″ : bien tenté mais vous êtes trop permissifs !
alors il faut changer l’adresse IP du serveur et mettre 10.0.255.255.
Ainsi, l’adresse de broadcast du serveur reste bien 10.0.0.255, il écoute toujours sur 10.0.0.0/24.
Les clients vont emettre sur leur adresse de diffusion 10.0.255.255, et le trafic est à la fois du broadcast (pour les clients) et de l’unicast (pour le serveur).
@daboule: il écouterait sur 10.0.255.0/24 au lieu de 10.0.0.0/24 ; il y a plein d’autres raisons pour ne pas faire ça…
Pourquoi 3 lignes de commandes ?
Un bête
route add -net 10.0.0.0 netmask 255.255.0.0 dev ethx
ne va pas suffire ?
Pas de modif chez les clients.
Le serveur ne change rien a ses ports d’écoute
Il émet toujours depuis son adresse à lui sur son sous réseau à lui.
Je suis passé à coté de quelque chose ?
N.B : j’ai fait les tests avec du freebsd
(route add -net 10.0.0.0/16 -iface inx) Je reçois les broadcast et j’y répond.
Je pense que j’ai trouvé les deux autres lignes à rentrer.
J’imagine que la première consiste à créer une adresse IP alias sur la bon carte réseau vers l’adresse de broadcast :
ifconfig ethx:n netmask 255.255.0.0 10.0.255.255
Petit commentaire personnel : BEURK
Et que l’autre ligne est de créer une règle IP netfilter qui interdit à la machine d’émettre sur cette nouvelle adresse. (Mais là je vais même pas essayer de créer la ligne, netfilter et moi on est fâché – Et puis PF c’est tellement mieux)
ifconfig eth0:0 10.0.255.255 netmask 255.255.255.255
iptables -t nat -I PREROUTING -d 10.0.255.255 -j DNAT –to 10.0.0.1
@kane ça ne marche pas sous Linux :
# route add -net 192.168.0.0 netmask 255.255.0.0 dev wlan0; route
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.0.0 * 255.255.255.0 U 0 0 0 wlan0
192.168.0.0 * 255.255.0.0 U 0 0 0 wlan0
default dir-615 0.0.0.0 UG 0 0 0 wlan0
Je ne me réponds pas quand je ping -b 192.168.255.255.
Oui, c’est lié à une mauvaise compréhension de l’énnoncé de ma part. Je pensais que le serveur écoutait déjà sur le port broadcast en /16 de base et que seule la réponse était problématique.
D’ou mon post supplémentaire qui attribue l’adresse de broadcast en dur à l’interface.
Mais bon comme je ne connais pas le serveur ca complique la tache.
Sinon un grab des paquets par tcpdump et reroutage est envisageable aussi. C’est discutablement moins sale que de donner en dur une adresse de broadcast d’un sous réseau à une interface unique d’un autre sous réseau.
Encore une autre possibilité consiste à monter un tunnel SSH avec une des machines du sous réseau /16 au hasard pour rediriger la fameuse adresse de broadcast en /16. Limite aussi au niveau propreté.
Moins sale mais casse gueule, utiliser le mode promiscous… Il va falloir filtrer pour éviter le tout et n’importe quoi.
Carrément ignoble et non testé : la liaison point à point vers 10.0.255.255. Tous les commutateurs vont pas forcément aimer, mais c’est utilisé par de grandes marques d’ISP pour faire des tambouilles internes.
J’imagine que la solution doit utiliser une loopback (genre ifconfig lo1 10.0.255.255 netmask 255.255.255.255), et du proc/sys arp_ignore arp_annouce pour affiner ??
Pourquoi tu n’as pas validé mon post ? ce n’est une bonne idée d’utiliser une interface de loopback ?