Date de publication du RFC : Septembre 2025
Auteur(s) du RFC : S. Hollenbeck (Verisign Labs), W. Carroll (Verisign), G. Akiwate (Stanford University)
Réalisé dans le cadre du groupe de travail IETF regext
Première rédaction de cet article le 5 octobre 2025
Dans un registre de noms de domaine, il existe une classe d'objets pour les domaines et parfois une pour les serveurs de noms (hosts). C'est en se basant sur les objets de ces classes que des informations sont ensuite publiées dans le DNS. Que se passe-t-il si on retire un objet de ces classes, alors que d'autres objets en dépendaient ? Va-t-on scier une branche sur laquelle quelqu'un est assis ? Ce RFC fait le point sur les solutions existantes, notant que certaines sont moins bonnes que d'autres, notamment pour la sécurité.
Prenons un exemple simple : le domaine
monbeaudomaine.example
est enregistré auprès du
registre
du TLD .example
. Ses
serveurs de noms sont ns1.domaine-d-un-copain.example
et
ns1.hébergeur.example
et on va supposer que le
registre de .example
traite les serveurs de
noms comme une classe distincte dans sa base de données. Maintenant,
supposons que le domaine
domaine-d-un-copain.example
soit supprimé parce
que son titulaire n'en voit plus l'utilité. Que va devenir le
serveur de noms
ns1.domaine-d-un-copain.example
? Il existe de
nombreuses façons de traiter ce problème, et c'est le rôle de ce RFC
de les analyser toutes.
Ainsi, la section 3.2.2 du RFC 5731 dit que
ce n'est pas bien de détruire un domaine si des objets de type
serveur de noms sont sous ce domaine. Dans l'exemple précédent, le
registre de .example
aurait refusé la
suppression de
domaine-d-un-copain.example
. Mais cela laisse
le problème entier : si le titulaire ne veut plus payer et donc veut
supprimer le domaine, que faire ?
Un cas similaire se produit si on veut supprimer un serveur de
noms. Si le client EPP demande au serveur EPP
du registre de .example
la suppression de
l'objet ns1.domaine-d-un-copain.example
, que
doit faire le registre, sachant que ce serveur de noms est utilisé
par monbeaudomaine.example
? La section 3.2.2
du RFC 5732 dit que le registre devrait
refuser la suppression. C'est d'autant plus gênant que, dans le
modèle RRR (Registrant-Registrar-Registry), domaine et serveur(s) peuvent
être gérés par des BE différents, n'ayant
pas le droit de toucher aux objets des autres BE.
Vous pouvez trouver des bonnes explications et des exemples réels dans les supports d'une présentation qui avait été faite à l'IETF.
Quelles sont donc les recommandations concrètes de ce RFC ? La section 6 les résume. Au choix :
sacrificial.invalid
,
utilisant un TLD existant,
est recommandé.Le protocole EPP permet de changer le nom
d'un serveur de noms (section 3.2.5 du RFC 5732). Une pratique déjà observée est donc de renommer les
serveurs de noms. Dans l'exemple ci-dessus, recevant la demande de
suppression de domaine-d-un-copain.example
, le
registre (ou le BE s'il le peut) renommerait
ns1.domaine-d-un-copain.example
en, mettons,
ns1.domaine-d-un-copain.renamed.invalid
. Ici,
.invalid
, TLD réservé
par le RFC 6761, ne poserait pas vraiment de
problème mais renommer dans un domaine ouvert à l'enregistrement
pourrait créer un risque de sécurité, si le domaine de destination
n'existe pas, un méchant pouvant alors l'enregistrer et être ainsi en
mesure de répondre aux requêtes DNS.
La section 3 du RFC explique brièvement pourquoi les RFC 5731 et RFC 5732 déconseillent fortement de permettre la suppression d'un domaine tant que des serveurs de noms dans ce domaine existent. Il y a deux risques de sécurité si on détruisait le domaine en laissant les serveurs de noms tels quels dans la base de donnés du registre : un de déni de service (le nom ne se résout plus et le serveur va donc être inutile) et un de détournement (si un méchant peut ré-enregistrer le nom de domaine supprimé). Il y a aussi le problème de la colle orpheline, décrit dans le rapport du SSAC, « Comment on Orphan Glue Records in the Draft Applicant Guidebook ».
Si la clé qui identifie un serveur de noms est un numéro quelconque et pas son nom, on peut renommer le serveur sans changer les délégations, ce qui est particulièrement utile si le client EPP n'a pas le droit de changer des délégations qui appartiennent à un autre client du registre. Le nouveau nom ne va en général pas être associé à un serveur opérationnel : on sacrifie un serveur pour pouvoir supprimer le domaine parent. Mais cela entraine quelques risques (section 4 du RFC et l'article d' Akiwate, G., Savage, S., Voelker, G., et K. Claffy, « Risky BIZness: Risks Derived from Registrar Name Management »). Si on renomme vers un nom actuellement inexistant, le domaine peut être détourné si un malveillant enregistre ensuite ce domaine.
Compte tenu de tout cela, la section 5 du RFC étudie les différentes pratiques possibles, leurs avantages et leurs inconvénients. Pour les illustrer, je vais utiliser une base de données simple, décrite en SQL (les essais ont été faits avec PostgreSQL). Voici par exemple une création d'une telle base :
CREATE TABLE Domains (name TEXT UNIQUE); -- Ici, la table Nameservers n'offre aucune valeur ajoutée par rapport -- au fait de tout mettre dans Domains. Mais ce ne sera pas le cas par -- la suite. CREATE TABLE Nameservers (name TEXT UNIQUE); CREATE TABLE Delegation (domain TEXT REFERENCES Domains(name), server TEXT REFERENCES Nameservers(name)); INSERT INTO Domains VALUES ('monbeaudomaine.example'); INSERT INTO Domains VALUES ('domaine-d-un-copain.example'); INSERT INTO Nameservers VALUES ('ns1.domaine-d-un-copain.example'); INSERT INTO Nameservers VALUES ('ns1.hébergeur.example'); INSERT INTO Delegation VALUES ('monbeaudomaine.example', 'ns1.domaine-d-un-copain.example'); INSERT INTO Delegation VALUES ('monbeaudomaine.example', 'ns1.hébergeur.example');
Dans ce premier cas très simple, la suppression du domaine
domaine-d-un-copain.example
est triviale :
registry=> DELETE FROM Domains WHERE name='domaine-d-un-copain.example'; DELETE 1
Mais elle laisse la possibilité de colle
orpheline et surtout d'un détournement de monbeaudomaine.example
si
quelqu'un ré-enregistre
domaine-d-un-copain.example
. Ce premier essai
n'est pas conforme aux exigences des RFC 5731
et RFC 5732. On va essayer de
faire mieux.
Si on interdit (à juste titre) la suppression d'un domaine lorsque des serveurs de noms sont nommés dans ce domaine, on peut arriver à supprimer un domaine en supprimant d'abord les serveurs de noms qui sont nommés dans ce domaine (section 5.2) :
CREATE TABLE Domains (name TEXT UNIQUE); -- Ajout d'une dépendance au domaine parent, pour éviter les suppressions. CREATE TABLE Nameservers (name TEXT UNIQUE, parent TEXT REFERENCES Domains(name)); CREATE TABLE Delegation (domain TEXT REFERENCES Domains(name), server TEXT REFERENCES Nameservers(name)); INSERT INTO Domains VALUES ('monbeaudomaine.example'); INSERT INTO Domains VALUES ('domaine-d-un-copain.example'); INSERT INTO Domains VALUES ('hébergeur.example'); -- Pour une vraie base, on écrirait du code SQL qui extrait le parent -- automatiquement. INSERT INTO Nameservers VALUES ('ns1.domaine-d-un-copain.example', 'domaine-d-un-copain.example'); INSERT INTO Nameservers VALUES ('ns1.hébergeur.example', 'hébergeur.example'); INSERT INTO Delegation VALUES ('monbeaudomaine.example', 'ns1.domaine-d-un-copain.example'); INSERT INTO Delegation VALUES ('monbeaudomaine.example', 'ns1.hébergeur.example'); registry=> DELETE FROM Domains WHERE name='domaine-d-un-copain.example'; ERROR: update or delete on table "domains" violates foreign key constraint "nameservers_parent_fkey" on table "nameservers" DETAIL: Key (name)=(domaine-d-un-copain.example) is still referenced from table "nameservers". -- Ce comportement est ce que recommandent les RFC 5731 et 5732. -- Cela oblige le client à supprimer les serveurs de noms d'abord, ce qui à -- son tour nécessite potentiellement de changer les délégations : registry=> DELETE FROM Delegation WHERE server = 'ns1.domaine-d-un-copain.example'; DELETE 1 registry=> DELETE FROM Nameservers WHERE name='ns1.domaine-d-un-copain.example'; DELETE 1 registry=> DELETE FROM Domains WHERE name='domaine-d-un-copain.example'; DELETE 1
Ici, il y a eu suppression explicite des serveurs de noms par le
client (section 5.2.2.1). Cela peut poser des problèmes de permission, dans le cadre du
système RRR, si tous les objets ne sont pas
chez le même BE. Mais la suppression explicite est
une des trois solutions recommandées, notamment si on ajoute la
possibilité de rétablir l'état précédent (commande EPP
<restore>
, RFC 3915).
On peut aussi envisager une suppression implicite (section 5.2.1.1), le registre se
chargeant du nettoyage (c'est le rôle
de la directive SQL ON DELETE
CASCADE
) :
CREATE TABLE Domains (name TEXT UNIQUE); CREATE TABLE Nameservers (name TEXT UNIQUE, parent TEXT REFERENCES Domains(name) ON DELETE CASCADE); CREATE TABLE Delegation (domain TEXT REFERENCES Domains(name) ON DELETE CASCADE, server TEXT REFERENCES Nameservers(name) ON DELETE CASCADE); INSERT INTO Domains VALUES ('monbeaudomaine.example'); INSERT INTO Domains VALUES ('domaine-d-un-copain.example'); INSERT INTO Domains VALUES ('hébergeur.example'); -- Pour une vraie base, on écrirait du code SQL qui extrait le parent -- automatiquement. INSERT INTO Nameservers VALUES ('ns1.domaine-d-un-copain.example', 'domaine-d-un-copain.example'); INSERT INTO Nameservers VALUES ('ns1.hébergeur.example', 'hébergeur.example'); INSERT INTO Delegation VALUES ('monbeaudomaine.example', 'ns1.domaine-d-un-copain.example'); INSERT INTO Delegation VALUES ('monbeaudomaine.example', 'ns1.hébergeur.example'); registry=> SELECT Domains.name,Nameservers.name FROM Domains,Delegation,Nameservers WHERE Delegation.domain=Domains.name AND Delegation.server=Nameservers.name; name | name ------------------------+--------------------------------- monbeaudomaine.example | ns1.domaine-d-un-copain.example monbeaudomaine.example | ns1.hébergeur.example (2 rows) registry=> DELETE FROM Domains WHERE name='domaine-d-un-copain.example'; DELETE 1 -- Serveur de noms et délégation ont été détruits en cascade. Ce n'est -- pas déraisonnable mais c'est quand même un peu effrayant. registry=> SELECT Domains.name,Nameservers.name FROM Domains,Delegation,Nameservers WHERE Delegation.domain=Domains.name AND Delegation.server=Nameservers.name; name | name ------------------------+----------------------- monbeaudomaine.example | ns1.hébergeur.example (1 row)
Cette solution est simple et efficace mais détruire implicitement des objets de la base de données peut inquiéter les responsables de cette base. Et cela peut laisser un domaine avec trop peu de serveurs de noms pour assurer sa continuité de service voire, dans le pire des cas, sans serveurs du tout. Et il serait bon de prévenir le client de cette suppression implcite, par exemple par le mécanisme de poll d'EPP (RFC 8590).
Si on interdit (à juste titre, le RFC le recommande) la suppression d'un
domaine lorsque des serveurs de noms sont nommés dans ce domaine, une
solution possible est de
renommer les serveurs avant de supprimer le domaine (section 5.1). Le nouveau nom
permet d'indiquer clairement la raison du renommage. Mais ce
renommage laisse dans la base des « déchets » qu'il faudra nettoyer
un jour. Cette catégorie
contient de nombreuses variantes. Par exemple, on peut renommer dans
un TLD spécial (RFC 6761), ici, .invalid
:
CREATE TABLE Domains (name TEXT UNIQUE); -- On introduit un identificateur du server de noms qui n'est *pas* -- son nom, pour permettre le renommage. CREATE TABLE Nameservers (id SERIAL UNIQUE, name TEXT UNIQUE, parent TEXT REFERENCES Domains(name)); CREATE TABLE Delegation (domain TEXT REFERENCES Domains(name), server INTEGER REFERENCES Nameservers(id)); INSERT INTO Domains VALUES ('monbeaudomaine.example'); INSERT INTO Domains VALUES ('domaine-d-un-copain.example'); INSERT INTO Domains VALUES ('hébergeur.example'); -- Pour le renommage, un nom qui indique clairement le but : INSERT INTO Domains VALUES ('renamed.invalid'); -- Pour une vraie base, on écrirait du code SQL qui extrait le parent -- automatiquement. INSERT INTO Nameservers (name, parent) VALUES ('ns1.domaine-d-un-copain.example', 'domaine-d-un-copain.example'); INSERT INTO Nameservers (name, parent) VALUES ('ns1.hébergeur.example', 'hébergeur.example'); INSERT INTO Delegation VALUES ('monbeaudomaine.example', (SELECT id FROM Nameservers WHERE name='ns1.domaine-d-un-copain.example')); INSERT INTO Delegation VALUES ('monbeaudomaine.example', (SELECT id FROM Nameservers WHERE name='ns1.hébergeur.example')); registry=> SELECT Domains.name,Nameservers.name FROM Domains,Delegation,Nameservers WHERE Delegation.domain=Domains.name AND Delegation.server=Nameservers.id; name | name ------------------------+--------------------------------- monbeaudomaine.example | ns1.domaine-d-un-copain.example monbeaudomaine.example | ns1.hébergeur.example (2 rows) registry=> UPDATE Nameservers SET name='ns1.domaine-d-un-copain.example.renamed.invalid', parent='renamed.invalid' WHERE id=1; UPDATE 1 registry=> DELETE FROM Domains WHERE name='domaine-d-un-copain.example'; DELETE 1 registry=> SELECT Domains.name,Nameservers.name FROM Domains,Delegation,Nameservers WHERE Delegation.domain=Domains.name AND Delegation.server=Nameservers.id; name | name ------------------------+------------------------------------------------- monbeaudomaine.example | ns1.domaine-d-un-copain.example.renamed.invalid monbeaudomaine.example | ns1.hébergeur.example (2 rows)
Par contre, il ne faut pas utiliser .alt
, qui
est explicitement réservé aux protocoles non-DNS (RFC 9476). Notez que certains serveurs EPP peuvent tester le
nom des serveurs de noms et refuser des TLD « inconnus ».
Dans la nature, on a pu observer d'autres pratiques, comme de
renommer dans un sous-domaine de as112.arpa
, nom
garanti ne pas exister (RFC 7535), mais qui
n'est pas censé servir à cela (RFC 6305). On a
vu aussi des renommages vers des résolveurs DNS publics, ce qui est
également une horreur, la délégation doit être faite vers des serveurs faisant
autorité, pas des résolveurs.
Certains clients EPP maintiennent des serveurs de noms actifs qui
servent pour le renommage. Cela fait davantage de travail mais cela
protège contre le détournement. Le DNS va continuer à fonctionner
normalement. On pourrait aussi imaginer des serveurs de noms actifs, répondant
NXDOMAIN (« ce domaine n'existe pas »), qui soient
gérés collectivement (section 5.1.4.4) ; un tel service serait
certainement utile. On pourrait même créer un nom de domaine pour ce
service (sacrificial.arpa
?) mais personne ne
l'a encore fait. Pour l'instant, la solution des serveurs maintenus
par le client EPP (section 5.1.3.4) fait partie des trois solutions
recommandées. Le client prudent doit bien verrouiller le domaine dans
lequel ces serveurs sont nommés (enregistrement multi-années,
verrouillage par le registre, etc).
On peut aussi renommer les serveurs de noms vers un nom
non-existant dans un TLD existant. Ça s'est déjà vu mais il ne faut
surtout pas faire cela : un attaquant pourrait enregistrer le nom et
capter ainsi le trafic (.invalid
n'a pas ce
problème). Idem si le nom n'est pas sous votre contrôle. Un exemple
est donné par le domaine lenvol.re
: ses
serveurs de noms étaient ns.hostin.io
,
ns.hostin.mu
et
ns.hostin.re
. Lors de la suppression de
hostin.re
en octobre 2024, le dernier serveur
de noms a été renommé
host1.renamedbyregistry.com
(et, en dépit du
nom, pas par le registre). Ce domaine
renamedbyregistry.com
étant enregistré, et par
un autre BE, on voit le risque.
% whois lenvol.re domain: lenvol.re status: ACTIVE … nserver: host1.renamedbyregistry.com nserver: ns.hostin.io nserver: ns.hostin.mu
D'autres noms qui utilisaient ce même serveur ont également le problème :
% dig @d.nic.fr savanna.re. NS … ;; AUTHORITY SECTION: savanna.re. 3600 IN NS host1.renamedbyregistry.com. savanna.re. 3600 IN NS ns.hostin.mu. savanna.re. 3600 IN NS ns.hostin.io. ;; Query time: 8 msec ;; SERVER: 2001:678:c::1#53(d.nic.fr) (UDP) ;; WHEN: Tue Jun 24 14:33:32 CEST 2025
En lecture supplémentaire, notre RFC recommande le rapport « SSAC 125 "Report on Registrar Nameserver Management" », ainsi que l'article « Risky BIZness: Risks Derived from Registrar Name Management ».
Version PDF de cette page (mais vous pouvez aussi imprimer depuis votre navigateur, il y a une feuille de style prévue pour cela)
Source XML de cette page (cette page est distribuée sous les termes de la licence GFDL)