web-dev-qa-db-fra.com

Définition du nom d'hôte: FQDN ou nom abrégé?

J'ai remarqué que la méthode "préférée" pour définir le nom d'hôte du système est fondamentalement différente entre les systèmes Red Hat/CentOS et Debian/Ubuntu.

documentation CentOS et le guide de déploiement RHEL disent que le nom d'hôte devrait être le nom de domaine complet:

HOSTNAME=<value>, où <value> doit être le nom de domaine complet (FQDN), tel que hostname.example.com, mais peut être le nom d'hôte nécessaire.

Le guide d'installation RHEL est légèrement plus ambigu:

Le programme d'installation vous invite à fournir un nom d'hôte pour cet ordinateur, soit en tant que nom de domaine complet (FQDN) au format hostname.domainname ou en tant que nom d'hôte court au format hostname.

La référence Debian dit que le nom d'hôte ne doit pas utiliser le FQDN:

3.5.5. Le nom d'hôte

Le noyau maintient le nom d'hôte du système . Le script d'initialisation dans le niveau d'exécution S qui est lié à "/etc/init.d/hostname.sh " définit le nom d'hôte du système au démarrage (en utilisant le hostname command) au nom stocké dans "/etc/hostname " . Ce fichier doit contenir uniquement le nom d'hôte du système, pas un nom de domaine complet.

Je n'ai vu aucune recommandation spécifique d'IBM à utiliser, mais certains logiciels semble avoir une préférence.

Mes questions:

  • Dans un environnement hétérogène, est-il préférable d'utiliser la recommandation du fournisseur, ou d'en choisir une et d'être cohérent sur tous les hôtes?
  • Quel logiciel avez-vous rencontré qui est sensible au fait que le nom d'hôte est défini sur le nom de domaine complet ou le nom court?
187
Cakemox

Je choisirais une approche cohérente dans tout l'environnement. Les deux solutions fonctionnent bien et resteront compatibles avec la plupart des applications. Il existe cependant une différence de gestion.

Je choisis le nom court comme paramètre HOSTNAME et je définis le FQDN comme première colonne dans /etc/hosts pour l'IP du serveur, suivi du nom court.

Je n'ai pas rencontré beaucoup de progiciels qui appliquent ou affichent une préférence entre les deux. Je trouve que le nom court est plus propre pour certaines applications, en particulier la journalisation. J'ai peut-être été malchanceux de voir des domaines internes comme server.northside.chicago.rizzomanufacturing.com. Qui veut voir cela dans les journaux ou un invite du shell?

Parfois, je suis impliqué dans des acquisitions ou des restructurations d'entreprises où les domaines et/ou sous-domaines internes changent. J'aime utiliser le nom d'hôte court dans ces cas, car la journalisation, les démarrages, l'impression, la surveillance des systèmes, etc. n'ont pas besoin d'une reconfiguration complète pour tenir compte des nouveaux noms de domaine.

Une configuration de serveur RHEL/CentOS typique pour un serveur nommé "rizzo" avec le domaine interne "ifp.com", ressemblerait à:

/etc/sysconfig/network:
HOSTNAME=rizzo
...

-

/etc/hosts:
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

172.16.100.13   rizzo.ifp.com rizzo

-

[root@rizzo ~]# hostname 
rizzo

-

/var/log/messages snippet:
Dec 15 10:10:13 rizzo proftpd[19675]: 172.16.100.13 (::ffff:206.15.236.182[::ffff:206.15.236.182]) - Preparing to               
 chroot to directory '/app/upload/GREEK'
Dec 15 10:10:51 rizzo proftpd[20660]: 172.16.100.13 (::ffff:12.28.170.2[::ffff:12.28.170.2]) - FTP session opened.
Dec 15 10:10:51 rizzo proftpd[20660]: 172.16.100.13 (::ffff:12.28.170.2[::ffff:12.28.170.2]) - Preparing to chroot                
to directory '/app/upload/ftp/SRRID'
110
ewwhite

Presque tous les logiciels sont sensibles à la définition correcte du nom d'hôte. Pendant que je travaillais chez Digg, j'ai une fois réduit tout le site pendant 2 heures en raison d'un changement apparemment innocent dans /etc/hosts qui a affecté la notion de nom d'hôte du système. Marchez légèrement. Cela dit, vous pouvez être légèrement confus ici. Je ne pense pas que le HOSTNAME= le paramètre est directement équivalent à la façon dont les distributions basées sur Debian utilisent /etc/hostname.

Ce qui fonctionne pour moi dans un environnement hétérogène, c'est:

  1. Définissez le nom d'hôte de la manière recommandée par le vendeur, en utilisant une condition dans votre logiciel de gestion de configuration.
  2. Utilisez la commande hostname pour définir le nom d'hôte utilisé par le noyau, etc.
  3. Dans /etc/hosts:

    127.0.0.1    localhost
    10.0.0.1     hostname.example.com     hostname
    

Cette configuration ne m'a pas encore échoué.

39
Paul Lathrop

Vous n'aurez certainement aucun problème à trouver des références en ligne qui vous diront de le faire d'une manière ou d'une autre. Il me semble cependant qu'avoir un nom court comme nom d'hôte et avoir le nom complet dans/etc/hosts est certainement beaucoup plus répandu. Cela semble être le moyen le plus sensé, car les services qui ont besoin d'un nom complet peuvent être adaptés pour appeler hostname --fqdn au lieu.

Je n'ai rencontré qu'un seul logiciel récemment qui nécessite de manière rigide un fqdn à renvoyer par hostname, qui était ganeti. Ils documentent cela ici . Je ne vois aucune raison pour laquelle ils ne peuvent pas s'adapter à hostname --fqdn, cependant.

36
stew

De façon quelque peu tangentielle, lors de mes recherches sur cette question, je suis devenu assez fou pour vérifier le code source de "hostname" et écrire un script pour imprimer les résultats de l'enquête (Fedora 19). Ce qui manque, c'est un regard sur "/ etc/hosts", qui à mon humble avis devrait être tenu à l'écart de tout cela en premier lieu.

#!/bin/bash

function pad {
   if [[ $1 == '?' ]]; then
      printf "%-23s" "?"
   else
      printf "%-23s" "'$1'"
   fi
}

# ----- Kernel -----

# Two ways to configure the kernel values: 
# 1) Put FQDN into "kernel.hostname" and nothing into "kernel.domainname"
# 2) Put machine name into "kernel.hostname" and DNS domain name into "kernel.domainname" (makes more sense)

echo "== Kernel values =="
echo

H=`/sbin/sysctl -n kernel.hostname`
D=`/sbin/sysctl -n kernel.domainname`

echo "Kernel hostname: '$H'"
echo "Kernel domainname: '$D'"

# ----- What does bash say -----

echo
echo "== According to bash =="
echo

echo "HOSTNAME = '$HOSTNAME'"

# ----- Hostname config file ------

echo
echo "== Hostname config file =="
echo

ETCH="/etc/hostname"

if [[ -f $ETCH ]]; then
   CONTENTS=`cat $ETCH`
   echo "File '$ETCH' contains: '$CONTENTS'"
else
   echo "File '$ETCH' does not exist"
fi

# ----- Network config file ------

echo
echo "== Network config file =="
echo

SYSN="/etc/sysconfig/network"

if [[ -f $SYSN ]]; then
   LINE=`grep -e "^HOSTNAME=" $SYSN`
   if [[ -n $LINE ]]; then
      echo "File '$SYSN' contains: '$LINE'"
   else 
      echo "File '$SYSN' exists but does not contain a line for 'HOSTNAME'"
   fi
else
   echo "File '$SYSN' does not exist"
fi

# ----- Nodename -------

echo
echo "== Nodename =="
echo

UNAME=`uname --nodename` # On Linux, this is the hostname

echo "The 'nodename' given by 'uname --nodename' is: '$UNAME'"

# ----- The 'hostname' mess ------

THE_HOSTNAME=`hostname`
SHORT_NAME=`hostname --short`
NIS_DNAME=`domainname`     
YP_DNAME=`hostname --yp`    # Same as `nisdomainname` ; this may fail with "hostname: Local domain name not set"

if [[ $? != 0 ]]; then
   YP_DNAME="?"
fi

echo
echo "== 'hostname' directly obtained values =="
echo
echo "The result of gethostname();"
echo "...obtained by running 'hostname'"
echo "Hostname: $(pad $THE_HOSTNAME)"
echo
echo "The part before the first '.' of the value returned by gethostname();"
echo "...obtained by running 'hostname --short'"
echo "Short name: $(pad $SHORT_NAME)"
echo
echo "The result of getdomainname(); the code of 'hostname' seems to call this the 'NIS domain name';"
echo "...on Linux, this is the kernel-configured domainname;"
echo "...obtained by running 'domainname'"
echo "NIS domain name: $(pad $NIS_DNAME)"
echo
echo "The result of yp_get_default_domain(), which may fail;"
echo "...obtained by running 'ĥostname --yp'"
echo "YP default domain: $(pad $YP_DNAME)"

DNS_DNAME=`hostname --domain`  # Same as `dnsdomainname`'
FQDN_NAME=`hostname --fqdn`
ALIAS_NAME=`hostname --alias`

echo
echo "== 'hostname' values obtained via DNS =="
echo
echo "The part after the first '.' of the 'canonical name' value returned by getaddrinfo(gethostname());"
echo "...obtained by running 'hostname --domain'"
echo "DNS domain name: $(pad $DNS_DNAME)"
echo
echo "The 'canonical name' value returned by getaddrinfo(gethostname());"
echo "...obtained by running 'hostname --fqdn'"
echo "Fully qualified hostname: $(pad $FQDN_NAME)"
echo
echo "Alias obtained by gethostbyname(gethostname());"
echo "...obtained by running 'hostname --alias'"
echo "Hostname alias: $(pad $ALIAS_NAME)"

BY_IP_ADDR=`hostname --ip-address`
ALL_IP_ADDR=`hostname --all-ip-addresses`
ALL_FQDN_NAMES=`hostname --all-fqdn`

echo
echo "== 'hostname' values obtained by collecting configured network addresses =="
echo
echo "Collect the IP addresses from getaddrinfo(gethostname()), apply getnameinfo(ip) to all those addresses;"
echo "...obtained by running 'hostname --ip-address'"
echo "By IP address: $BY_IP_ADDR"
echo
echo "Call getnameinfo(NI_NUMERICHOST) on all addresses snarfed from active interfaces;"
echo "...obtained by running 'hostname --all-ip-addresses'"
echo "All IP addresses: $ALL_IP_ADDR"
echo
echo "Call getnameinfo(NI_NAMEREQD) on all addresses snarfed from active interfaces (involves lookup in /etc/hosts);"
echo "...obtained by running 'hostname --all-fqdn'"
echo "All fully qualified hostnames: $ALL_FQDN_NAMES"

La sortie sur un Amazon EC2 VM exécutant Fedora 19, après avoir défini manuellement les valeurs du noyau et rempli /etc/hostname, mais sans modification de /etc/hosts pourrait alors ressembler à ceci:

== Kernel values ==

Kernel hostname: 'kyubee'
Kernel domainname: 'homelinux.org'

== According to bash ==

HOSTNAME = 'ip-172-31-24-249.localdomain'

== Hostname config file ==

File '/etc/hostname' contains: 'kyubee.homelinux.org'

== Network config file ==

File '/etc/sysconfig/network' exists but does not contain a line for 'HOSTNAME'

== Nodename ==

The 'nodename' given by 'uname --nodename' is: 'kyubee'

== 'hostname' directly obtained values ==

The result of gethostname();
...obtained by running 'hostname'
Hostname: 'kyubee'

The part before the first '.' of the value returned by gethostname();
...obtained by running 'hostname --short'
Short name: 'kyubee'

The result of getdomainname(); the code of 'hostname' seems to call this the 'NIS domain name';
...on Linux, this is the kernel-configured domainname;
...obtained by running 'domainname'
NIS domain name: 'homelinux.org'

The result of yp_get_default_domain(), which may fail;
...obtained by running 'ĥostname --yp'
YP default domain: 'homelinux.org'

== 'hostname' values obtained via DNS ==

The part after the first '.' of the 'canonical name' value returned by getaddrinfo(gethostname());
...obtained by running 'hostname --domain'
DNS domain name: ''

The 'canonical name' value returned by getaddrinfo(gethostname());
...obtained by running 'hostname --fqdn'
Fully qualified hostname: 'kyubee'

Alias obtained by gethostbyname(gethostname());
...obtained by running 'hostname --alias'
Hostname alias: ''

== 'hostname' values obtained by collecting configured network addresses ==

Collect the IP addresses from getaddrinfo(gethostname()), apply getnameinfo(ip) to all those addresses;
...obtained by running 'hostname --ip-address'
By IP address: fe80::8f6:8eff:fe49:9e21%eth0 172.31.24.249

Call getnameinfo(NI_NUMERICHOST) on all addresses snarfed from active interfaces;
...obtained by running 'hostname --all-ip-addresses'
All IP addresses: 172.31.24.249

Call getnameinfo(NI_NAMEREQD) on all addresses snarfed from active interfaces (involves lookup in /etc/hosts);
...obtained by running 'hostname --all-fqdn'
All fully qualified hostnames: ip-172-31-24-249.eu-west-1.compute.internal

Le moyen résilient d'obtenir le nom d'hôte complet en Perl serait alors:

sub getHostname {

   my $hostname_short = `/bin/hostname --short`;
   if ($? != 0) { print STDERR "Could not execute 'hostname --short' -- exiting\n"; exit 1 }
   chomp $hostname_short;

   my $hostname_long  = `/bin/hostname`;
   if ($? != 0) { print STDERR "Could not execute 'hostname' -- exiting\n"; exit 1 }
   chomp $hostname_long;

   if ($hostname_long =~ /^${hostname_short}\..+$/) {
      # "hostname_long" is a qualified version of "hostname_short"
      return $hostname_long
   }
   else {
      # both hostnames are "short" (and are equal)
      die unless ($hostname_long eq $hostname_short);

      my $domainname = `/bin/domainname`;
      if ($? != 0) { print STDERR "Could not execute 'domainname' -- exiting\n"; exit 1 }
      chomp $domainname;

      if ($domainname eq "(none)") {
         # Change according to taste
         return "${hostname_short}.localdomain"
      }
      else {
         return "${hostname_short}.${domainname}"
      }
   }
}

et en bash ce serait:

function getHostname {

   local hostname_short=`/bin/hostname --short`

   if [ $? -ne 0 ]; then
      echo "Could not execute 'hostname --short' -- exiting" >&2; exit 1
   fi

   local hostname_long=`/bin/hostname`

   if [ $? -ne 0 ]; then
      echo "Could not execute 'hostname' -- exiting" >&2; exit 1
   fi

   if [[ $hostname_long =~ ^"$hostname_short"\..+$ ]]; then
      # "hostname_long" is a qualified version of "hostname_short"
      echo $hostname_long
   else
      # both hostnames are "short" (and are equal)
      if [[ $hostname_long != $hostname_short ]]; then
         echo "Cannot happen: '$hostname_long' <> '$hostname_short' -- exiting" >&2; exit 1
      fi

      local domainname=`/bin/domainname`

      if [ $? -ne 0 ]; then
         echo "Could not execute 'domainname' -- exiting" >&2; exit 1
      fi

      if [[ domainname == '(none)' ]]; then
         # Change according to taste
         echo "${hostname_short}.localdomain"
      else
         echo "${hostname_short}.${domainname}"
      fi
   fi
}

Notes

Remarque 1: HOSTNAME est une variable Shell fournie par bash ("Défini automatiquement sur le nom de l'hôte actuel.") Mais rien n'indique que bash arrive à cette valeur.

Remarque 2: N'oubliez jamais/etc/hostname dans /boot/initrams-FOO.img ...

13
David Tonhofer