ti-enxame.com

Definindo o nome do host: FQDN ou nome abreviado?

Percebi que o método "preferido" de definir o nome do host do sistema é fundamentalmente diferente entre os sistemas Red Hat/CentOS e Debian/Ubuntu.

documentação do CentOS e guia de implantação do RHEL diga o nome do host deve ser o FQDN:

HOSTNAME=<value>, Onde <value> deve ser o nome de domínio totalmente qualificado (FQDN), como hostname.example.com, mas pode ser o nome de host necessário.

O guia de instalação do RHEL é um pouco mais ambíguo:

A instalação solicita que você forneça um nome de host para este computador, como um nome de domínio totalmente qualificado (FQDN) no formato - hostname.domainname ou como um nome abreviado do host no formato hostname.

A referência Debian diz que o nome do host não deve usar o FQDN:

3.5.5 O nome do host

O kernel mantém o nome do host do sistema . O script init no nível de execução S, vinculado a "/etc/init.d/hostname.sh " define o nome do host do sistema no momento da inicialização (usando o nome do host comando) para o nome armazenado em "/etc/hostname " . Este arquivo deve conter apenas o nome do host do sistema, não um nome de domínio totalmente qualificado.

Não vi nenhuma recomendação específica da IBM sobre qual usar, mas alguns softwares parece ter uma preferência.

Minhas perguntas:

  • Em um ambiente heterogêneo, é melhor usar a recomendação do fornecedor ou escolher uma e ser consistente em todos os hosts?
  • Qual software você encontrou que é sensível a saber se o nome do host está definido como o FQDN ou o nome abreviado?
187
Cakemox

Eu escolheria uma abordagem consistente em todo o ambiente. Ambas as soluções funcionam bem e permanecerão compatíveis com a maioria dos aplicativos. Há uma diferença na capacidade de gerenciamento, no entanto.

Eu escolho o nome abreviado como a configuração HOSTNAME e defino o FQDN como a primeira coluna em /etc/hosts para o IP do servidor, seguido pelo nome abreviado.

Eu não encontrei muitos pacotes de software que impõem ou exibem uma preferência entre os dois. Acho que o nome abreviado é mais limpo para alguns aplicativos, especificamente o log. Talvez eu tenha tido azar de ver domínios internos como server.northside.chicago.rizzomanufacturing.com. Quem quer ver isso nos logs ou em um Shell Prompt?

Às vezes, estou envolvido em aquisições ou reestruturações de empresas em que domínios e/ou subdomínios internos mudam. Eu gosto de usar o nome abreviado do host nesses casos porque o registro, kickstarts, impressão, monitoramento de sistemas etc. não precisam de reconfiguração completa para dar conta dos novos nomes de domínio.

Uma configuração típica do servidor RHEL/CentOS para um servidor chamado "rizzo" com domínio interno "ifp.com" seria semelhante a:

/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

-

[[email protected] ~]# 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

Praticamente todo software é sensível à configuração correta do nome do host. Enquanto trabalhava no Digg, uma vez reduzi o site inteiro por 2 horas devido a uma mudança aparentemente inocente em /etc/hosts que afetou a noção de nome do host do sistema. Pise levemente. Dito isto, você pode estar um pouco confuso aqui. Eu não acho que o HOSTNAME= configuração é diretamente equivalente a como as distribuições baseadas no Debian usam /etc/hostname.

O que funciona para mim em um ambiente heterogêneo é:

  1. Defina o nome do host da maneira recomendada pelo fornecedor, usando uma condicional no seu software de gerenciamento de configuração.
  2. Use o comando hostname para definir o nome do host usado pelo kernel, etc.
  3. No /etc/hosts:

    127.0.0.1    localhost
    10.0.0.1     hostname.example.com     hostname
    

Essa configuração ainda não falhou comigo.

39
Paul Lathrop

Você certamente não terá problemas para encontrar referências on-line, o que lhe dirá para fazê-lo definitivamente de uma maneira ou de outra. Parece-me, no entanto, que ter um nome abreviado como nome do host e ter o nome totalmente qualificado em/etc/hosts é certamente muito mais prevalente. Parece a maneira mais sensata, pois os serviços que precisam de um nome totalmente qualificado podem ser adaptados para chamar hostname --fqdn em vez de.

Recentemente, encontrei apenas um pedaço de software que exige rigidamente que um fqdn seja retornado por hostname, que era ganeti. Eles documentam isso aqui . Não vejo motivo para eles não se adaptarem a hostname --fqdn, Contudo.

36
stew

De maneira um tanto tangencial, ao pesquisar essa pergunta, fiquei louco o suficiente para verificar o código fonte de "hostname" e escrever um script para imprimir resultados de investigação (Fedora 19). O que está faltando é uma olhada em "/ etc/hosts", que na minha humilde opinião deve ser mantida fora de tudo isso em primeiro lugar.

#!/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"

A saída em um Amazon EC2 VM executando o Fedora 19, após definir manualmente os valores do kernel e preencher /etc/hostname, mas sem alterações em /etc/hosts pode ser assim:

== 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

A maneira resiliente de obter o nome completo do host no Perl seria:

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}"
      }
   }
}

e no bash seria:

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
}

Notas

Nota 1: HOSTNAME é uma variável do Shell que o bash fornece ("Definido automaticamente como o nome do Host atual."), Mas não há indicação sobre o bash chegar a esse valor.

Nota 2: Nunca esqueça/etc/hostname em /boot/initrams-FOO.img ...

13
David Tonhofer