Thomas Martin I/O

Programming, Sysadmin, Open Source

CFEngine 3 : Couldn't look up address v6 for : Temporary failure in name resolution

2012-09-24 SYSADMIN CFGMGMT CFENGINE


Il m'a fallu du temps pour diagnostiquer la cause de l'erreur ci-dessous.

Il y a peu d'informations sur internet à ce sujet, donc je publie la solution ici, dans l'espoir que cela puisse aider d'autres personnes.

J'ai rencontré l'erreur suivante en utilisant la commande cf-runagent fourni par le logiciel de gestion de configuration CFEngine 3 :

Couldn't look up address v6 for : Temporary failure in name resolution
 !! Id-authentication for admin1 failed
Unable to establish connection with host1.example.com

IPv6 est totalement désactivé sur toutes les machines de l'infra en question, car non utilisé.

La référence à une adresse v6 est donc étrange.

La suite du message d'erreur fait également référence à un problème de résolution DNS et d'identification de la machine admin1 (le serveur CFEngine de l'infra, à partir duquel est lancé la commande cf-runagent).

Je consulte alors le code source de CFEngine en recherchant le message :

debian1:~/git/cfengine$ grep -iIrn "Couldn't look up address v6 for" .
./src/client_protocol.c:108:            CfOut(cf_error, "", "Couldn't look up address v6 for %s: %s\n", dnsname, gai_strerror(err));

Ce qui fait référence à ce bloc de code :

if ((err = getnameinfo((struct sockaddr *) &myaddr, len, dnsname, CF_MAXVARSIZE, NULL, 0, 0)) != 0)
{
    CfOut(cf_error, "", "Couldn't look up address v6 for %s: %s\n", dnsname, gai_strerror(err));
    return false;
}

Et à ce commentaire :

/* First we need to find out the IP address and DNS name of the socket
   we are sending from. This is not necessarily the same as VFQNAME if
   the machine has a different uname from its IP name (!) This can
   happen on poorly set up machines or on hosts with multiple
   interfaces, with different names on each interface ... */

Je constate alors que c'est la fonction getnameinfo qui échoue et provoque l'erreur. D'après la page de man, cette fonction de la libc permet d'identifier l'adresse IP et le nom DNS associés à une socket. Dans notre cas, le code ci-dessus cherche à identifier le nom DNS correspondant à l'adresse IP de l'interface réseau utilisée pour contacter les agents CFEngine des machines de l'infra.

Conclusion : je vérifie alors, et... cette correspondance n'existe effectivement pas dans le système de résolution des noms de l'infra. En effet, le serveur CFEngine dispose de plusieurs interfaces réseaux, et seul l'interface principale disposait d'un nom défini dans son fichier hosts. Une fois cet oubli corrigé, cf-runagent fonctionne alors correctement.