mardi 5 mars 2013, 21:54:58 (UTC+0100)
Initiation au développement IPv4 + IPv6
La rubrique dev vient d'être enrichie d'un nouveau support sur l'Initiation au développement C sur les sockets IPv4 & IPv6.
Ce qui, au départ, ne devait être qu'un complément au précédent document utilisant seulement IPv4 a finalement abouti à une progression en quatre étapes ou programmes. J'ai conservé l'idée initiale d'échange de chaîne de caractères entre un client et un serveur. Cette forme rudimentaire de chat est très bien accueillie par les étudiants.
La première étape est un plagiat éhonté du programme showip du livre Beej's Guide to Network Programming. La technique de parcours des enregistrements addrinfo issus de l'appel à getaddrinfo() est ensuite reprise dans tous les autres programmes du document. À la deuxième étape, le programme client se contente d'ouvrir la première prise réseau ou socket disponible. Jusque là, tout va bien ! C'est avec le programme serveur que les choses se compliquent. Faut-il utiliser une ou deux prises réseau ?
Franchement, je n'ai pas le recul nécessaire pour prendre parti sur cette question. Ce qui est sûr, c'est que la solution «académique» est plus séduisante pour un prof. Le code de la couche application est indépendant des protocoles de la couche réseau et la quantité de code est plus réduite. Ça n'empêche pas de souffrir un peu sur l'utilisation de l'option bindv6only et sur l'interprétation des codes d'erreurs associés. J'ai fini par aboutir au tableau de tests suivant. Les deux étapes restantes proposent les programmes serveurs avec une puis deux prises réseau.
|
client ou talker |
Serveur ou listener socket unique
|
Serveur ou listener socket double
|
|---|---|---|
|
Client dual stack
|
IPv6 |
IPv6 |
|
Client single stack
|
IPv6 IPv4-mapped IPv6 addresses |
IPv4 |
Une fois la difficulté de gestion des options sur les sockets franchie, la dernière étape avec le codage d'un serveur dual stack à deux prises réseau permet de se familiariser avec l'utilisation de la fonction select() et des macros associées.
Pour conclure, l'utilisation conjointe des deux protocoles IPv4 et IPv6 entraîne un niveau de difficulté plus important dans la manipulation des enregistrements d'adresses IP. Ce pas supplémentaire peut être délicat à franchir pour un public débutant. C'est certainement la raison pour laquelle les enseignants préfèrent s'en remettre à des bibliothèques de plus haut niveau pour aborder les sockets. En Génie Électrique, les développements sont très proches de l'espace noyau et le langage C reste incontournable, ce qui rend le compromis délicat à négocier.
Comme d'habitude, si quelqu'un à le courage de s'attaquer à la lecture du document, je serais très content de lire toutes les remarques ou critiques !
Posté par Philippe Latu | permalien et commentaires | dans : dev, formations | Read it in english with Google
jeudi 7 février 2013, 17:45:15 (UTC+0100)
Architecture système et initiation au développement réseau
Avant les séances de travaux pratiques sur l'initiation au développement sur les sockets avec les étudiants de seconde année de DUT GE2I, j'ai voulu passer à une version dual stack IPv4 et IPv6 des programmes étudiés. L'évolution relativement récente consiste à remplacer les appels à 'gethostbyname' par l'utilisation de 'getaddrinfo' qui renvoie les adresses des deux versions du protocole IP via des pointeurs sur des enregistrements 'addrinfo' chaînés. Tout ceci fonctionne très bien et la façon dont les données sont structurées est très intéressante à étudier ... à mes yeux.
On constate une fois de plus que le niveau requis pour accéder à la compréhension d'une technique ou d'une technologie augmente sans cesse. Pour un débutant complet, il devient de plus en plus difficile de se hisser à un niveau permettant de s'accrocher au train en marche. L'argument qui vient immédiatement consiste à dire que les étudiants actuels sont nés avec l'intégration système et qu'ils utilisent très bien leur smartphone sans se soucier de l'encapsulation des paquets IP dans les réseaux radio numériques. Mon point de vue repose sur le fait que le niveau correspondant à «l'utilisation» des systèmes n'est pas suffisant pour accéder à un emploi et un niveau de revenus décent. Je tente donc à nouveau ma chance en présentant quelques éléments sur l'architecture système. L'idée est de montrer que les systèmes d'exploitation des «dispositifs mobiles» dont les étudiants sont friands ont une longue histoire chaotique mais continue. Suivant cette idée, les «petits programmes pour débuter» viennent bien s'intégrer dans les technologies utilisées au quotidien.
La présentation est disponible aux formats ODP et PDF. Si vous avez envie d'apporter des corrections, n'hésitez pas !
Posté par Philippe Latu | permalien et commentaires | dans : dev, réseau, formations | Read it in english with Google
jeudi 22 novembre 2012, 17:51:40 (UTC+0100)
Aire OSPF et passerelles multiples (2ème)
Suite à l'article Aire OSPF et passerelles multiples et au cycle de travaux pratiques des M1 STRI sur l'interconnexion des réseaux locaux et étendus, voici une variante d'utilisation du marquage de paquets avec des tables de routage multiples. L'idée est toujours d'implanter un mécanisme de tolérance aux pannes entre les passerelles d'une aire OSPF et un routeur de niveau «supérieur».
Ici, les trois routeurs protagonistes ont chacun une interface dans le même domaine de diffusion et on utilise un octet d'adresse MAC pour identifier et distinguer les passerelles.
Pour un nouveau flux sortant de l'aire OSPF, il y a ...
- Marquage du premier paquet en fonction de l'adresse MAC source dans la chaîne PREROUTING de la table mangle.
- Mémorisation du marquage de paquet dans le mécanisme de suivi d'état du système de filtrage (connmark)
- Entrée dans la table de routage dédiée au routeur de bordure à l'origine du flux.
Pour un flux retour dans l'aire OSPF, il y a ...
- Restauration du marquage de paquet en fonction des enregistrements effectués via le mécanisme de suivi d'état
- Entrée dans la table de routage dédiée au routeur de bordure vers lequel le flux doit être dirigé.
La configuration correspondante est alors obtenue avec ...
- Une table de routage par routeur de bordure :
# cat /etc/iproute2/rt_tables # # reserved values # 255 local 254 main 253 default 0 unspec # # local # #1 inr.ruhep 72 centares 79 naboo
# ip route add 10.0.16.0/20 via 172.16.1.1 table centares # ip route add 10.0.32.0/20 via 172.16.1.1 table centares # ip route add default dev bond0 table centares
# ip route add 10.0.16.0/20 via 172.16.4.1 table naboo # ip route add 10.0.32.0/20 via 172.16.4.1 table naboo # ip route add default dev bond0 table naboo
- Des règles de marquages utilisant la table mangle :
# iptables -t mangle -A PREROUTING -i bond0.1 -m mac --mac-source 00:1f:c6:01:26:72 -j MARK --set-mark 72 # iptables -t mangle -A PREROUTING -i bond0.1 -m mac --mac-source 00:1f:c6:01:26:79 -j MARK --set-mark 79 # iptables -t mangle -A PREROUTING -i bond0.1 -j CONNMARK --save-mark # iptables -t mangle -A PREROUTING -i bond0 -j CONNMARK --restore-mark
- Des règles d'entrée dans les tables de routage en fonction des marques :
# ip rule add fwmark 72 table centares # ip rule add fwmark 79 table naboo
Le plan d'adressage est donné dans le support Étude de cas sur l'interconnexion LAN/WAN.
Ici, l'interface bond0 correspond au lien vers l'Internet et l'interface bond0.1 appartient au même réseau local que les deux routeurs de bordure.
Voilà ! Cette configuration n'est qu'un exemple supplémentaire d'utilisation des tables de routage multiples sur les systèmes GNU/linux. Cette technique est trop souvent considérée à tort comme «effrayante». Dès lors que l'on accepte de traiter le problème pas à pas, la «représentation intellectuelle» de la gestion des flux se met plus facilement en place ;).
Une fois de plus, le «copié-collé de la mort» si cher aux étudiants ne rend pas service et ne permet pas de visualiser les mécanismes en jeu.
Posté par Philippe Latu | permalien et commentaires | dans : ospf, rpdb, failover, réseau, formations, travaux_pratiques | Read it in english with Google
dimanche 23 septembre 2012, 17:24:57 (UTC+0200)
Comment résoudre un problème d'accès à la configuration du service LDAP
En révisant le support de travaux pratiques sur l'introduction aux annuaires LDAP avec OpenLDAP, j'ai perdu un certain temps avant de pouvoir traiter la partie sur l'analyse de la configuration du service LDAP. Relativement à l'édition précédente, les versions du paquet source openldap ont évolué et un petit détail sur la résolution des noms m'avait échappé. Bien sûr, me direz-vous, dans la vraie vie tout le monde installe son service LDAP en ayant préalablement validé que le serveur est connu du service DNS. Eh bien, pas moi ! Dans un contexte de travaux pratiques, on cherche à isoler les services les uns des autres de façon à ne traiter qu'un seul problème bien identifié à la fois. Voyons donc comment on peut se fourvoyer facilement et quelle démarche aurait pu être suivie d'entrée de jeu.
Au début, il était question d'authentification ...
Pour valider les questions et les réponses du TP, on configure de façon très classique deux instances de machines virtuelles avec le système de base et le service SSH en Debian/testing : un serveur et un client. On effectue les mises à jour et on renomme les machines. On obtient avec la topologie suivante :
|eth0
_|____
(_______) noyau
|Routeur| <-- système hôte
(_______)
|br0 @IP: 198.51.100.1
___|______
| | <-- openvswitch
`-.------.-'
|tap0 |tap1
| --'.
| |' |hostname : vm-ldap-client
| |. |@IP : 198.51.100.3
--'. `--'
|' |hostname : vm-ldap-server
|. |@IP : 198.51.100.2
`--'
Après installation des deux paquets slapd et ldap-utils sur le serveur, on teste l'accès à la configuration.
Traitement des actions différées (« triggers ») pour « man-db »... Paramétrage de libltdl7:amd64 (2.4.2-1.1) ... Paramétrage de libodbc1:amd64 (2.2.14p2-5) ... Paramétrage de libperl5.14 (5.14.2-13) ... Paramétrage de libslp1 (1.2.1-9) ... Paramétrage de slapd (2.4.31-1) ... Creating new user openldap... done. Creating initial configuration... done. Creating LDAP directory... done. [ ok ] Starting OpenLDAP: slapd. Paramétrage de ldap-utils (2.4.31-1) ... localepurge: Disk space freed in /usr/share/locale: 0 KiB localepurge: Disk space freed in /usr/share/man: 0 KiB Total disk space freed by localepurge: 0 KiB # ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" dn ldap_sasl_interactive_bind_s: Local error (-2)
Eh paf ! C'est à partir de là que les choses ont mal tourné. Je me suis focalisé sur l'authentification SASL et non sur la partie interactive_bind_s du message. Pourtant, cette instruction est bien celle préconisée dans le fichier de documentation du paquet slapd : /usr/share/doc/slapd/README.Debian.gz
Je me suis lancé dans la configuration de l'authentification SASL avec le paquet sasl2-bin et le mécanisme PAM pour authentifier les utilisateurs locaux dont le super-utilisateur qui doit avoir accès sans restriction à la configuration du ou des annuaires LDAP configurés sur le serveur. Bien que cette authentification soit fonctionnelle, j'obtenais toujours le même message d'erreur. La situation était bloquée. Pas moyen de modifier le DIT.
À la fin, il n'était plus question que de résolution des noms
Au lieu de m'enfermer dans cette voie sans issue, j'aurais dû commencer par faire appel à strace.
# strace ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" dn
<snipped>
recvfrom(4, "h4\201\203\0\1\0\0\0\1\0\0\16vm-ldap-server\0\0\34\0\1"..., 2048, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("198.51.100.1")}, [16]) = 107
gettimeofday({1348409171, 770189}, NULL) = 0
poll([{fd=4, events=POLLIN}], 1, 4998) = 1 ([{fd=4, revents=POLLIN}])
ioctl(4, FIONREAD, [107]) = 0
recvfrom(4, "6\361\201\203\0\1\0\0\0\1\0\0\16vm-ldap-server\0\0\1\0\1"..., 1941, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("198.51.100.1")}, [16]) = 107
close(4) = 0
write(2, "ldap_sasl_interactive_bind_s: Lo"..., 47ldap_sasl_interactive_bind_s: Local error (-2)
) = 47
write(3, "0\5\2\1\1B\0", 7) = 7
close(3)
Voici à nouveau le message d'erreur consécutivement à une transaction réseau avec des sockets. Mais que diable vient faire cette requête réseau dans une manipulation locale au système ? On passe donc à l'analyse réseau sur le système hôte ; celui avec l'adresse IP 198.51.100.1.
# tshark -i br0 ! port 22 tshark: Lua: Error during loading: [string "/usr/share/wireshark/init.lua"]:45: dofile has been disabled Running as user "root" and group "root". This could be dangerous. Capturing on br0 0.000000 198.51.100.2 -> 198.51.100.1 DNS 74 Standard query 0x6213 A vm-ldap-server 0.000266 198.51.100.1 -> 198.51.100.2 DNS 149 Standard query response 0x6213 No such name 0.016816 198.51.100.2 -> 198.51.100.1 DNS 74 Standard query 0x2cd4 A vm-ldap-server 0.016885 198.51.100.2 -> 198.51.100.1 DNS 74 Standard query 0x28a4 AAAA vm-ldap-server 0.017050 198.51.100.1 -> 198.51.100.2 DNS 149 Standard query response 0x28a4 No such name 0.017110 198.51.100.1 -> 198.51.100.2 DNS 149 Standard query response 0x2cd4 No such name
Bingo ! la requête locale sur le DIT de l'annuaire à besoin de connaître la correspondance entre nom et adresse IP. On se jette sur l'édition du fichier /etc/hosts dans lequel on donne l'information manquante.
# head -4 /etc/hosts 127.0.0.1 localhost 127.0.1.1 vm-ldap-server 198.51.100.2 vm-ldap-server
Ouf ! Une nouvelle exécution de la commande ldapsearch ne produit plus d'erreur et on peut enfin modifier le DIT de l'annuaire.
# ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" dn SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 # extended LDIF # # LDAPv3 # base <cn=config> with scope subtree # filter: (objectclass=*) # requesting: dn # <snipped> # search result search: 2 result: 0 Success # numResponses: 12 # numEntries: 11
En guise de conclusion
C'est une nouvelle petite leçon d'humilité. On s'imagine être expérimenté et on se fait attraper comme un débutant sur un détail insignifiant en apparence.
Maintenant, pour rebondir sur le billet intitulé 7 astuces pour rapporter les bogues Debian efficacement et voir vos problèmes résolus, est-ce que le problème que je viens de rencontrer mérite un rapport de bug ? Il m'est déjà arrivé dans le passé d'émettre des rapports qui ont fait flop. Ils étaient soit hors sujet (#616487), soit sans aucun intérêt.
Posté par Philippe Latu | permalien et commentaires | dans : travaux_pratiques, système | Read it in english with Google
dimanche 16 septembre 2012, 00:59:03 (UTC+0200)
Présentation et support de travaux pratiques NFSv4
La présentation sur les systèmes de fichiers réseau et le support de travaux pratiques sur le protocole NFSv4 ont été mis à jour pour la session 2012 du module sur l'administration système en réseau. L'ensemble des documents du module devraient être Wheezy ready !.
Comme d'habitude, si les supports listés ci-dessus vous intéressent, toutes les relectures, les critiques et autres remarques sont les bienvenues.
Posté par Philippe Latu | permalien et commentaires | dans : nfs, formations | Read it in english with Google