Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Adresse IP vers nom

19 réponses
Avatar
Olivier Miakinen
[diapublication, avec suivi vers fr.comp.reseaux.ip seul]

Bonjour,

Pour remplacer un gethostbyaddr en C, je voudrais savoir si les deux
méthodes suivantes sont équivalentes, et sinon quelle différence
il y a entre les deux :

1) faire un getaddrinfo suivi d'un getnameinfo du premier résultat ;

2) faire un getaddrinfo avec AI_CANONNAME et récupérer le ai_canonname.

Cordialement,
--
Olivier Miakinen

9 réponses

1 2
Avatar
jca+news
Olivier Miakinen <om+ writes:

Le 27/01/2013 03:04, Jérémie Courrèges-Anglas m'a rép ondu :

C'est là que je m'aperçois que j'avais oublié un dé tail important dans
ma question : je ne m'intéresse qu'au cas où la requête porte sur une
adresse IP (v4 ou v6) et pas sur un nom DNS. Est-ce que dans ce cas
le getnameinfo pourrait retourner un nom sans suffixe DNS, ou un alias,
au lieu de l'adresse canonique ?





Bon, ma question n'a plus lieu d'être puisque, au moins sur Linux,
je constate que getaddrinfo(adresse IP, AI_CANONNAME) me retourne
l'adresse IP et pas un nom canonique. Je n'ai donc pas le choix,
je fais un getaddrinfo suivi de getnameinfo. Et tant que j'y suis
j'ai rajouté un AI_NUMERICHOST au getaddrinfo puisque l'adresse
est numérique, ça ne mange pas de pain.



Oups, je m'aperçois que je n'ai lu que la première partie de la r éponse
initiale, et que du coup j'ai répondu à côté. Déso lé…

[...]

Il peut retourner à peu près tout ce qui est une valeur accept able pour
un enregistrement PTR, une entrée de table hosts, etc. Exemple (g4 est
une machine sur mon lan).

~$ # avant modifs
~$ ./gani g4
getaddrinfo + AI_CANONNAME: g4.wxcvbn.org
getnameinfo: g4.wxcvbn.org
~$ # bidouillage du /etc/hosts
~$ ./gani g4
getaddrinfo + AI_CANONNAME: foo
getnameinfo: foo



En l'occurrence, ces deux tests retournaient la même valeur.

~$ # bidouillage du PTR
~$ ./gani g4
getaddrinfo + AI_CANONNAME: g4.wxcvbn.org
getnameinfo: bar



Mais là, effectivement, c'est différent.



Ces tests n'avaient pour but que de montrer le cas « classique » ainsi
que les bizarreries auxquelles on peut s'attendre.

La plupart du temps, quand une application vérifie le nom d'un clie nt,
elle récupère le reverse avec getnameinfo() puis fait une requ ête sur ce
reverse avec getaddrinfo(), et regarde si l'adresse obtenue est la mà ªme.



Oui, ok. Je ne suis pas sûr d'avoir ce besoin, mais cela pourrait
arriver (j'ai un certain nombre de programmes à migrer ou faire
migrer vers la nouvelle interface).

C'est simplifié, car un système peut avoir plusieurs adresses et une
adresse peut avoir plusieurs enregistrements PTR.



À ce propos, existe-t-il avec la nouvelle interface un moyen de
récupérer la liste de tous les alias, comme avec le h_aliases
de l'ancienne structure hostent ? Il me semble que c'est devenu
impossible, n'est-ce pas ?

Cordialement,



En effet cela paraît difficile, mais je ne suis pas sûr que ce so it bien
grave. À quoi cela pourrait-il servir ?

--
Jérémie Courrèges-Anglas
Empreinte GPG : 61DB D9A0 00A4 67CF 2A90 8961 6191 8FBF 06A1 1494
Avatar
jca+news
Olivier Miakinen <om+ writes:

Le 28/01/2013 17:07, je répondais à Jérémie Courrà ¨ges-Anglas :

[...] par contre
les adresses v6 mappées font un peu moins consensus[1] et cette va leur
par défaut (AI_V4MAPPED) n'a pas de sens[2].



[1] http://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful
[2] http://sourceware.org/bugzilla/show_bug.cgi?id415



Deux liens très intéressants, un grand merci pour cela.



Je n'avais fait que survoler le premier lien avant de répondre.
Je viens maintenant de le lire plus attentivement, et en réalité
le plus grand problème serait qu'une adresse IPv4-Mapped transite
telle quelle sur le réseau. Certes, ce draft explique que si on
éradique complètement ces adresses, y compris dans l'API de bas e,
cela diminue le risque qu'elles se baladent sur le réseau. Mais
si on peut les interdire sur le réseau, cela suffit.



Je n'interprète pas ce draft ainsi. Il s'agit de recommander de ne pas
utiliser ces adresses « on wire », mais aussi et surtout de se pr otéger
contre elles.

Il n'y a que le dernier paragraphe qui dit :

An alternate solution is to deprecate IPv4-mapped addresses from the
basic API. Due to the wide deployment of applications that use IPv6
basic API, further study of this option's feasibility is required.
This solution is not mutually exclusive with the recommended solution.

Point de vue avec lequel je suis d'accord, car SIIT (depuis remplacé)
aurait pu utiliser un autre préfixe, et l'avantage de pouvoir utiliser
une socket v6 au lieu de deux sockets est selon moi dérisoire au vu de
l'ambiguité ajoutée.

Il est amusant de lire combien le point de vue de itojun est clair, et
combien les gens en plus ou moins grand désaccord avec lui s'embourbent
dans la complexité des specs. Je n'ai pas le début du fil de la
discussion, mais :

http://www.atm.tut.fi/list-archive/ngtrans/msg01871.html

Cordialement,



Bonne soirée,
--
Jérémie Courrèges-Anglas
Empreinte GPG : 61DB D9A0 00A4 67CF 2A90 8961 6191 8FBF 06A1 1494
Avatar
Olivier Miakinen
Le 28/01/2013 19:24, Jérémie Courrèges-Anglas a écrit :

À ce propos, existe-t-il avec la nouvelle interface un moyen de
récupérer la liste de tous les alias, comme avec le h_aliases
de l'ancienne structure hostent ? Il me semble que c'est devenu
impossible, n'est-ce pas ?



En effet cela paraît difficile, mais je ne suis pas sûr que ce soit bien
grave. À quoi cela pourrait-il servir ?



Bonne question. Je me la suis posée également, mais je n'ai pas encore
examiné en détail le code source des composants qui utilisent h_aliases
pour savoir si cela leur sert à quelque chose ou pas. ;-)
Avatar
Olivier Miakinen
Le 28/01/2013 20:03, Jérémie Courrèges-Anglas a écrit :

[1] http://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful







[...]



Je n'interprète pas ce draft ainsi. Il s'agit de recommander de ne pas
utiliser ces adresses « on wire »,



Oui, ça c'est bien ce que j'ai compris.

mais aussi et surtout de se protéger contre elles.



Et c'est là que je ne suis pas sûr de comprendre ce que dit le draft,
ou ce que tu dis.

Il est entendu qu'il faut interdire que les adresses IPv4-Mapped
soient utilisées ailleurs que dans l'API interne d'un host (ailleurs
qu'entre la pile TCP/IP et les fonctions socket). Cela veut dire :
- qu'un hôte ne doit pas émettre de paquet IPv6 comportant une telle
adresse ;
- qu'un routeur ne doit pas router un tel paquet (il doit le jeter
purement et simplement) ;
- qu'un hôte ne doit pas accepter un tel paquet (idem, il doit le
jeter).

Mais tout ceci concerne le noyau. À partir du moment où il est
programmé correctement et qu'il est étanche aux transmissions
de ces adresses en dehors du cas prévu, je ne vois pas pourquoi
on devrait interdire cet usage de la « Basic API ».

Il n'y a que le dernier paragraphe qui dit :

An alternate solution is to deprecate IPv4-mapped addresses from the
basic API. Due to the wide deployment of applications that use IPv6
basic API, further study of this option's feasibility is required.
This solution is not mutually exclusive with the recommended solution.

Point de vue avec lequel je suis d'accord, car SIIT (depuis remplacé)
aurait pu utiliser un autre préfixe,



Je n'ai pas trop étudié SIIT, mais effectivement ce ne sont pas les
préfixes possibles qui manquent ! Soit dit en passant, on dirait
qu'ils voulaient déjà en utiliser trois différents...

https://tools.ietf.org/html/rfc2765#section-2.1

et l'avantage de pouvoir utiliser
une socket v6 au lieu de deux sockets est selon moi dérisoire au vu de
l'ambiguité ajoutée.



D'accord pour tout nouveau programme. Mais quand tu dois reprendre
des centaines de composants dont certains font plusieurs dizaines
de milliers de ligne, et que la plupart des développeurs d'origine
sont partis faire carrière ailleurs (ou sont en retraite depuis
des années), plus la transition sera simple et mieux ce sera.


Cordialement,
--
Olivier Miakinen
Avatar
jca+news
Olivier Miakinen <om+ writes:

Le 28/01/2013 20:03, Jérémie Courrèges-Anglas a écrit :

[1] http://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful







[...]



Je n'interprète pas ce draft ainsi. Il s'agit de recommander de ne pas
utiliser ces adresses « on wire »,



Oui, ça c'est bien ce que j'ai compris.

mais aussi et surtout de se protéger contre elles.



Et c'est là que je ne suis pas sûr de comprendre ce que dit le draft,
ou ce que tu dis.

Il est entendu qu'il faut interdire que les adresses IPv4-Mapped
soient utilisées ailleurs que dans l'API interne d'un host (ailleurs
qu'entre la pile TCP/IP et les fonctions socket). Cela veut dire :
- qu'un hôte ne doit pas émettre de paquet IPv6 comportant une telle
adresse ;
- qu'un routeur ne doit pas router un tel paquet (il doit le jeter
purement et simplement) ;
- qu'un hôte ne doit pas accepter un tel paquet (idem, il doit le
jeter).



C'est bien ce qui est dit dans le draft.

Mais tout ceci concerne le noyau. À partir du moment où il est
programmé correctement et qu'il est étanche aux transmissions
de ces adresses en dehors du cas prévu, je ne vois pas pourquoi
on devrait interdire cet usage de la « Basic API ».



Le "cas prévu" introduit lui aussi une ambiguité : ais-je affaire à un
hôte v4 ou v6 ? Est-ce qu'une application utilisant uniquement une
socket v6 doit pouvoir être contactée par un hôte v4 ? etc...

La section 2.2 ("IPv6-Mapped IPv4 addresses") de la RFC 4942[1] commence
ainsi :

Overloaded functionality is always a double-edged sword: it may yield
some deployment benefits, but often also incurs the price that comes
with ambiguity.

Ce qui résume bien le problème, je pense. De toute façon, c' est trop
tard pour être retiré des RFC ainsi que des implémentations. .. Donc on
doit toujours garder ces adresses IPv4-mapped en tête dès qu'on p ense
ACL.

Il n'y a que le dernier paragraphe qui dit :

An alternate solution is to deprecate IPv4-mapped addresses from the
basic API. Due to the wide deployment of applications that use IPv6
basic API, further study of this option's feasibility is required.
This solution is not mutually exclusive with the recommended solution.

Point de vue avec lequel je suis d'accord, car SIIT (depuis remplacà ©)
aurait pu utiliser un autre préfixe,



Je n'ai pas trop étudié SIIT, mais effectivement ce ne sont pas les
préfixes possibles qui manquent ! Soit dit en passant, on dirait
qu'ils voulaient déjà en utiliser trois différents...

https://tools.ietf.org/html/rfc2765#section-2.1



Argl.

et l'avantage de pouvoir utiliser
une socket v6 au lieu de deux sockets est selon moi dérisoire au vu de
l'ambiguité ajoutée.



D'accord pour tout nouveau programme. Mais quand tu dois reprendre
des centaines de composants dont certains font plusieurs dizaines
de milliers de ligne, et que la plupart des développeurs d'origine
sont partis faire carrière ailleurs (ou sont en retraite depuis
des années), plus la transition sera simple et mieux ce sera.



Je n'ai pas encore vu de gens reposer sur ce méchanisme, mais ma foi je
comprends que ça puisse parfois être utile comme solution "d'urge nce".
La RFC 4038[2] parle de cette utilisation, et met en garde contre le
champ d'application limité ainsi que les différentes contraintes
(section 4.2).

Autre lecture potentiellement intéressante : "Protocol Independence
Using the Sockets API"[3], en libre accès.


Cordialement,



[1] http://tools.ietf.org/html/rfc4942 "IPv6 Transition/Coexistence
Security Considerations"
[2] http://tools.ietf.org/html/rfc4038 "Application Aspects of IPv6
Transition"
[3] http://static.usenix.org/event/usenix2000/freenix/metzprotocol.html
"Protocol Independence Using the Sockets API"
Avatar
Olivier Miakinen
Le 29/01/2013 13:17, Jérémie Courrèges-Anglas m'a répondu :

[plein de choses]



Pardon si je ne te réponds pas tout de suite, mais tu m'as donné des
liens vers trois documents assez longs (en anglais qui plus est), et
il me faut un peu de temps pour tout lire. C'est très intéressant
en tout cas, et je te remercie déjà pour ça.

À plus tard !
Avatar
Olivier Miakinen
Salut !

Le 29/01/2013 13:17, Jérémie Courrèges-Anglas m'avait répondu :

Mais tout ceci concerne le noyau. À partir du moment où il est
programmé correctement et qu'il est étanche aux transmissions
de ces adresses en dehors du cas prévu, je ne vois pas pourquoi
on devrait interdire cet usage de la « Basic API ».



Le "cas prévu" introduit lui aussi une ambiguité : ai-je affaire à un
hôte v4 ou v6 ?



Dans le « cas prévu », donc hors mécanisme bugué style SIIT, la seule
ambiguïté c'est qu'on ne sait pas si l'application sur l'hôte distant
a utilisé une socket native IPv4 ou une socket mappée. Mais ça, on
s'en fiche complètement, c'est un détail d'implémentation. La seule
réalité qui compte, c'est que le hôte distant est en tout point un
hôte IPv4 : il a une adresse IPv4, et la connexion s'est faite en
utilisant IPv4 sur le réseau.

Est-ce qu'une application utilisant uniquement une
socket v6 doit pouvoir être contactée par un hôte v4 ? etc...



Encore une fois, la socket (côté applicatif) on s'en fiche pas mal.
La vraie question est : est-ce que les hôtes dialoguent en IPv4 ou
en IPv6. Dans le premier cas, ils ont tous deux une adresse v4 et
ils sont sur un réseau v4 (réseau « logique », je ne parle pas des
tunnels qui sont un autre problème).

La section 2.2 ("IPv6-Mapped IPv4 addresses") de la RFC 4942[1] commence
ainsi :

Overloaded functionality is always a double-edged sword: it may yield
some deployment benefits, but often also incurs the price that comes
with ambiguity.

Ce qui résume bien le problème, je pense.



Sauf que la section continue en expliquant que c'est SIIT qui définit
la surcharge de fonctionnalité posant problème. Tant qu'on reste dans
le « cas prévu » hors SIIT, la fonctionnalité d'accès à IPv4 via une
socket IPv6 n'est pas surchargée, et elle n'est pas dangereuse.

De toute façon, c'est trop
tard pour être retiré des RFC ainsi que des implémentations... Donc on
doit toujours garder ces adresses IPv4-mapped en tête dès qu'on pense
ACL.



Oui, il faut absolument les filtrer à chaque fois qu'une telle adresse
est présente dans un paquet sur le réseau, que ce soit en sortie de
hôte, en transit dans un routeur ou en arrivée sur le hôte destination.
Je ne dis pas que c'est simple, puisque des infos de routage peuvent
se trouver dans des entêtes IPv6 autres que source et destination,
mais bon, encore une fois ça ne remet pas en cause l'utilisation de
base.

Soit dit en passant, même si une application utilise deux sockets
séparées pour IPv4 et IPv6, et pourrait donc détecter l'utilisation
frauduleuse d'une adresse de type ::ffff:a.b.c.d, ce n'est pas à elle
de le faire puisque l'on recherche dans les applis l'indépendance
vis à vis du protocole !

[IPv4-mapped IPv6 pour éviter de tout recoder avec plusieurs sockets,
ajout de select(), etc.]



Je n'ai pas encore vu de gens reposer sur ce mécanisme, mais ma foi je
comprends que ça puisse parfois être utile comme solution "d'urgence".
La RFC 4038[2] parle de cette utilisation, et met en garde contre le
champ d'application limité ainsi que les différentes contraintes
(section 4.2).



Vu.

Autre lecture potentiellement intéressante : "Protocol Independence
Using the Sockets API"[3], en libre accès.



Excellent. Il n'y a rien, je crois, que je n'aie vu ailleurs, mais
voir résumer tout ça en si peu de pages, exemples de code inclus, en
fait un document à garder précieusement.

Il n'y a qu'un seul point où je reste sur ma faim, et je vais peut-être
lancer un nouveau fil à ce sujet : les sockets non connectées.

[1] http://tools.ietf.org/html/rfc4942 "IPv6 Transition/Coexistence
Security Considerations"
[2] http://tools.ietf.org/html/rfc4038 "Application Aspects of IPv6
Transition"
[3] http://static.usenix.org/event/usenix2000/freenix/metzprotocol.html
"Protocol Independence Using the Sockets API"



Encore merci pour tous ces liens. Au passage, je voulais dire que
j'apprécie beaucoup la clarté de ta façon de donner des références,
et je pense que je vais tâcher d'adopter cette technique.

Cordialement,
--
Olivier Miakinen
Avatar
jca+news
Olivier Miakinen <om+ writes:

Salut !

Le 29/01/2013 13:17, Jérémie Courrèges-Anglas m'avait rà ©pondu :

Mais tout ceci concerne le noyau. À partir du moment où il est
programmé correctement et qu'il est étanche aux transmissions
de ces adresses en dehors du cas prévu, je ne vois pas pourquoi
on devrait interdire cet usage de la « Basic API ».



Le "cas prévu" introduit lui aussi une ambiguité : ai-je affai re à un
hôte v4 ou v6 ?



Dans le « cas prévu », donc hors mécanisme bugué style SIIT, la seule
ambiguïté c'est qu'on ne sait pas si l'application sur l'hà ´te distant
a utilisé une socket native IPv4 ou une socket mappée. Mais à §a, on
s'en fiche complètement, c'est un détail d'implémentation.



Ce n'est pas ce dont je parle.

La seule réalité qui compte, c'est que le hôte distant est en tout
point un hôte IPv4 : il a une adresse IPv4, et la connexion s'est
faite en utilisant IPv4 sur le réseau.



Et comment vérifie t'on cela ?

Est-ce qu'une application utilisant uniquement une
socket v6 doit pouvoir être contactée par un hôte v4 ? et c...



Encore une fois, la socket (côté applicatif) on s'en fiche pas mal.



On ne s'en fiche pas. Si je fais sciemment écouter une application en
IPv6 (uniquement) sur un hôte dual-stack, je ne souhaite pas que des
clients v4 s'y connectent. Or c'est le comportement par défaut spà ©cifié
par la RFC 3493[1].

La vraie question est : est-ce que les hôtes dialoguent en IPv4 ou
en IPv6. Dans le premier cas, ils ont tous deux une adresse v4 et
ils sont sur un réseau v4 (réseau « logique », je ne parle pas des
tunnels qui sont un autre problème).



Comment détermine t'on que le client communique en IPv6 avec le
processus décrit ci-dessus ? On regarde à l'intérieur d e la sockaddr
client, si l'adresse « commence par » ::ffff:, c'est u n client v4. Une
macro - IN6_IS_ADDR_V4MAPPED() - peut faciliter le boulot, mais il faut
le garder à l'esprit. Or tout le monde ne lis pas des RFC sur son temps
libre…

La section 2.2 ("IPv4-Mapped IPv6 addresses") de la RFC 4942[1] commence
ainsi :

Overloaded functionality is always a double-edged sword: it may yield
some deployment benefits, but often also incurs the price that comes
with ambiguity.

Ce qui résume bien le problème, je pense.



Sauf que la section continue en expliquant que c'est SIIT qui définit
la surcharge de fonctionnalité posant problème. Tant qu'on rest e dans
le « cas prévu » hors SIIT, la fonctionnalité d'acc ès à IPv4 via une
socket IPv6 n'est pas surchargée, et elle n'est pas dangereuse.



Plus loin dans la même section :

Using the basic API behavior has some security implications in that
it adds additional complexity to address-based access controls. The
main issue that arises is that an IPv6 (AF_INET6) socket will accept
IPv4 packets even if the node has no IPv4 (AF_INET) sockets open.
This has to be taken into account by application developers and may
allow a malicious IPv4 peer to access a service even if there are no
open IPv4 sockets. This violates the security principle of "least
surprise".

De toute façon, c'est trop
tard pour être retiré des RFC ainsi que des implémentatio ns... Donc on
doit toujours garder ces adresses IPv4-mapped en tête dès qu'o n pense
ACL.



Oui, il faut absolument les filtrer à chaque fois qu'une telle adres se
est présente dans un paquet sur le réseau, que ce soit en sorti e de
hôte, en transit dans un routeur ou en arrivée sur le hôte
destination.



Je ne parle pas de ceci, que je considère comme acquis.

Je ne dis pas que c'est simple, puisque des infos de routage peuvent
se trouver dans des entêtes IPv6 autres que source et destination,
mais bon, encore une fois ça ne remet pas en cause l'utilisation de
base.



Le cas d'utilisation de base, c'est encourager les gens à remplacer
AF_INET par AF_INET6 et leur dire qu'ainsi ils ont réussi à rendr e leur
application compatible IPv6. Ce qui ne fait que poursuivre le
hard-coding d'une version spécifique d'IP dans les applications.

Soit dit en passant, même si une application utilise deux sockets
séparées pour IPv4 et IPv6, et pourrait donc détecter l'ut ilisation
frauduleuse d'une adresse de type ::ffff:a.b.c.d, ce n'est pas à elle
de le faire puisque l'on recherche dans les applis l'indépendance
vis à vis du protocole !



Si une application binde sur 0.0.0.0 puis [::], la socket v6 n'acceptera
pas de connections v4 (l'OS se charge de ça). Si l'application a d'abo rd
bindé sur [::] et que la fonctionnalité dont on discute est activ ée,
elle ne pourra probablement pas binder ensuite sur 0.0.0.0. Donc l'ordre
des familles d'adresses retournées par getaddrinfo() est détermin ant.
Niveau indépendance par rapport au protocole, on a fait mieux.

Si on ne veut pas de ce comportement, on peut le désactiver soit
system-wide, soit au niveau de la socket (IPV6_V6ONLY), mais là encore,
doit on utiliser setsockopt() avant ou après l'appel à bind()  ?

Même problématique : en voulant faciliter l'évolution d 'applications
triviales (gestion d'une seule socket d'écoute pour gérer IPv4 et IPv6),
on introduit des knobs qui empêchent l'indépendance par rapport au
protocole.

Maintenant si tu me dis que tu n'as que faire des moyens de vérificati on
de l'adresse cliente, de la complexification requise dans le cas
d'applications portables, et plus généralement du flou artistique
introduit, alors je pense qu'on aurait pû économiser deux posts. ;)

[...]

[1] http://tools.ietf.org/html/rfc3493#section-3.7 "Basic Socket
Interface Extensions for IPv6"
--
Jérémie Courrèges-Anglas
Empreinte GPG : 61DB D9A0 00A4 67CF 2A90 8961 6191 8FBF 06A1 1494
Avatar
Olivier Miakinen
Bonjour,

Le 03/02/2013 19:33, Jérémie Courrèges-Anglas m'a répondu :

Dans le « cas prévu », donc hors mécanisme bugué style SIIT, la seule
ambiguïté c'est qu'on ne sait pas si l'application sur l'hôte distant
a utilisé une socket native IPv4 ou une socket mappée. Mais ça, on
s'en fiche complètement, c'est un détail d'implémentation.



Ce n'est pas ce dont je parle.



Ok. J'essaye de comprendre, ça m'intéresse vraiment, et je suis désolé
si tu me trouves lent à la comprenette.

La seule réalité qui compte, c'est que le hôte distant est en tout
point un hôte IPv4 : il a une adresse IPv4, et la connexion s'est
faite en utilisant IPv4 sur le réseau.



Et comment vérifie-t-on cela ?



Au niveau interface réseau ? Soit il y a vraiment un truc que je
n'ai pas compris, soit on le vérifie simplement au fait que l'on
reçoit un paquet IPv4 sur une de nos adresses IPv4. Je tiens encore
une fois pour acquis que les couches basses mettent à la poubelle
tout paquet IPv6 reçu s'il contient une adresse IPv4-mapped.

Est-ce qu'une application utilisant uniquement une
socket v6 doit pouvoir être contactée par un hôte v4 ? etc...



Encore une fois, la socket (côté applicatif) on s'en fiche pas mal.



On ne s'en fiche pas. Si je fais sciemment écouter une application en
IPv6 (uniquement) sur un hôte dual-stack, je ne souhaite pas que des
clients v4 s'y connectent.



Si tu as cette exigence, c'est ton droit : il te suffit alors de
n'ouvrir qu'une socket IPv6, en y forçant l'option IPV6_V6ONLY.

Je me demande juste pourquoi tu pourrais avoir cette exigence. C'est
pour forcer le passage à IPv6 en interdisant IPv4 ? Ou bien parce que
tu craindrais que le filtrage IPv4 soit fait moins soigneusement que
le filtrage IPv6 sur les routeurs, et qu'il te semble plus sûr
d'interdire complètement IPv4 ?

Or c'est le comportement par défaut spécifié par la RFC 3493[1].



Je conteste juste le « par défaut ». C'est un comportement spécifié
par la RFC3493 comme étant une possibilité offerte, et certains
systèmes l'activent par défaut alors que d'autres le désactivent
par défaut... du coup, les docs bien faites rappellent qu'il faut
toujours faire le setsockopt() soi-même.

Cela dit, je suis d'accord que c'est en soi un problème : il aurait
fallu que le comportement par défaut soit clairement précisé, et
qu'il soit pour IPV6_V6ONLY.

La vraie question est : est-ce que les hôtes dialoguent en IPv4 ou
en IPv6. Dans le premier cas, ils ont tous deux une adresse v4 et
ils sont sur un réseau v4 (réseau « logique », je ne parle pas des
tunnels qui sont un autre problème).



Comment détermine-t-on que le client communique en IPv6 avec le
processus décrit ci-dessus ? On regarde à l'intérieur de la sockaddr
client, si l'adresse « commence par » ::ffff:, c'est un client v4. Une
macro - IN6_IS_ADDR_V4MAPPED() - peut faciliter le boulot, mais il faut
le garder à l'esprit. Or tout le monde ne lit pas des RFC sur son temps
libre...



Il me semble (mais je peux me tromper puisque tu sembles penser le
contraire) que tout le monde n'a pas *besoin* de déterminer si le
protocole utilisé était IPv4 ou IPv6. Dans le document parlant de
l'indépendance du protocole dont tu m'as donné le lien (je le
cite ici avec le même numéro [3]), il est même question de pouvoir
utiliser d'autres protocoles qui ne sont ni IPv4 ni IPv6.

Mais bien sûr, si tu as besoin de connaître le protocole utilisé, tu
peux alors vouloir faire des trucs plus spécifiques comme d'utiliser
la macro IN6_IS_ADDR_V4MAPPED(). Mais quelqu'un qui veut entrer à un
tel niveau de détail devra forcément lire les docs qui en parlent.

[La section 2.2 ("IPv4-Mapped IPv6 addresses") de la RFC 4942[1] ]
continue en expliquant que c'est SIIT qui définit
la surcharge de fonctionnalité posant problème. Tant qu'on reste dans
le « cas prévu » hors SIIT, la fonctionnalité d'accès à IPv4 via une
socket IPv6 n'est pas surchargée, et elle n'est pas dangereuse.



Plus loin dans la même section :

Using the basic API behavior has some security implications in that
it adds additional complexity to address-based access controls. The
main issue that arises is that an IPv6 (AF_INET6) socket will accept
IPv4 packets even if the node has no IPv4 (AF_INET) sockets open.
This has to be taken into account by application developers and may
allow a malicious IPv4 peer to access a service even if there are no
open IPv4 sockets. This violates the security principle of "least
surprise".



Ok, je suis d'accord pour la violation du principe de « moindre
surprise » dans le cas d'une application qui autoriserait sans le
savoir les adresses IPv4-mapped dans sa socket IPv6. Et je crois
que je commence à comprendre ce qui te tarabuste : c'est le fait
que le programmeur puisse ne pas savoir s'il est ou non dans le
mode IPV6_V6ONLY. Effectivement c'est un problème.

Voyons si nous sommes d'accord avec ceci :
1) Il y a un problème de sécurité dû au fait qu'on ne sache pas
forcément si l'on est en V6ONLY ou pas quand on ne le demande
pas explicitement, et en plus que le comportement puisse
changer d'un hôte à un autre pour un même programme.
2) Si en revanche un programmeur est conscient de ce problème, et
qu'il précise toujours explicitement dans quel mode il veut
fonctionner (V6ONLY ou V4-MAPPED), alors le mécanisme en soi
du V4-MAPPED n'est pas plus dangereux que l'utilisation de
deux sockets et de V6ONLY.
J'ai bon, là ?

De toute façon, c'est trop
tard pour être retiré des RFC ainsi que des implémentations... Donc on
doit toujours garder ces adresses IPv4-mapped en tête dès qu'on pense
ACL.



Oui, il faut absolument les filtrer à chaque fois qu'une telle adresse
est présente dans un paquet sur le réseau, que ce soit en sortie de
hôte, en transit dans un routeur ou en arrivée sur le hôte
destination.



Je ne parle pas de ceci, que je considère comme acquis.



Ok.

Je ne dis pas que c'est simple, puisque des infos de routage peuvent
se trouver dans des entêtes IPv6 autres que source et destination,
mais bon, encore une fois ça ne remet pas en cause l'utilisation de
base.



Le cas d'utilisation de base, c'est encourager les gens à remplacer
AF_INET par AF_INET6 et leur dire qu'ainsi ils ont réussi à rendre leur
application compatible IPv6. Ce qui ne fait que poursuivre le
hard-coding d'une version spécifique d'IP dans les applications.



Ok, on ne parlait en fait pas de la même chose. J'avais en tête
l'utilisation éclairée d'un programmeur qui a bien compris comment
choisir entre les différentes possibilités (sockets séparées IPv4
et IPv6, socket IPv6 seule et IPv4 interdit, ou socket IPv6 avec
adresses IPv4-mapped autorisées), alors que tu pensais plutôt à
un programmeur cherchant à aller au plus vite, et tombant dans le
piège d'une configuration qu'il ne maîtrise pas.

C'est dans le premier cas que, en supposant SIIT écarté, je ne
voyais pas de danger particulier. Dans le second cas, je suis en
effet d'accord avec toi.

[...]



Si une application binde sur 0.0.0.0 puis [::], la socket v6 n'acceptera
pas de connections v4 (l'OS se charge de ça). Si l'application a d'abord
bindé sur [::] et que la fonctionnalité dont on discute est activée,
elle ne pourra probablement pas binder ensuite sur 0.0.0.0. Donc l'ordre
des familles d'adresses retournées par getaddrinfo() est déterminant.



Oui. La différence est donc entre un programmeur éclairé un qui ne
l'est pas. Et tu as raison de le souligner, pardon de ne pas avoir
compris tout de suite.

[...]

Même problématique : en voulant faciliter l'évolution d'applications
triviales (gestion d'une seule socket d'écoute pour gérer IPv4 et IPv6),
on introduit des [boutons] qui empêchent l'indépendance par rapport au
protocole.



C'est vrai. À la décharge des spécifieurs, je pense qu'il faut
reconnaître que le défi était difficile : comment faire accepter
un changement dans un protocole si répandu, alors même que plein
de gens sont encore convaincus qu'il reste toujours suffisamment
d'adresses IPv4 et qu'il sera toujours temps de migrer plus tard ?

Maintenant si tu me dis que tu n'as que faire des moyens de vérification
de l'adresse cliente, de la complexification requise dans le cas
d'applications portables, et plus généralement du flou artistique
introduit, alors je pense qu'on aurait pû économiser deux posts. ;)



:-D

Je suis vraiment désolé si tu as pu penser cela !

[1] http://tools.ietf.org/html/rfc3493#section-3.7 "Basic Socket
Interface Extensions for IPv6"



[3] http://static.usenix.org/event/usenix2000/freenix/metzprotocol.html
"Protocol Independence Using the Sockets API"

Cordialement,
--
Olivier Miakinen
1 2