题 设置主机名:FQDN还是短名称?


我注意到设置系统主机名的“首选”方法在Red Hat / CentOS和Debian / Ubuntu系统之间根本不同。

CentOS文档 和 RHEL部署指南 说主机名 应该是FQDN

HOSTNAME=<value>,哪里 <value> 应该是完全合格的域名   名称(FQDN),如 hostname.example.com,但可以是任何东西   主机名是必要的。

RHEL安装指南 稍微有点模棱两可:

安装程序会提示您为此计算机提供主机名,或者作为    完全合格的域名 (FQDN)格式 hostname.domainname   或作为格式的短主机名 主机名

Debian参考 主持人说 不应该使用FQDN

3.5.5。主机名

内核维护系统 主机名。运行级别中的init脚本   S符号链接到“脚本/etc/init.d/hostname.sh“设置系统   启动时的主机名(使用 主机名 命令)到存储的名称   在“在/ etc /主机名“。这个文件应该包含 只要 系统主机名,   不是完全合格的域名。

我没有看到IBM提出的任何具体建议,但是 一些软件 似乎有偏好。

我的问题:

  • 在异构环境中,最好是使用供应商建议,还是选择一个并在所有主机上保持一致?
  • 您遇到的哪个软件对主机名是设置为FQDN还是短名称很敏感?

164
2017-11-17 13:07






答案:


我会在整个环境中选择一致的方法。两种解决方案均可正常工作,并可与大多数应用程但是,可管理性存在差异。

我使用短名称作为HOSTNAME设置,并将FQDN设置为第一列 /etc/hosts 对于服务器的IP,后跟短名称。

我没有遇到过许多强制执行或显示两者之间偏好的软件包。我发现短名称对某些应用程序更清晰,特别是日志记录。也许我看到像内部域名一样不走运 server.northside.chicago.rizzomanufacturing.com。谁想在日志中看到这个或者 shell提示

有时,我参与公司收购或重组,内部域和/或子域名发生变化。我喜欢在这些情况下使用短主机名,因为日志记录,kickstart,打印,系统监控等不需要完全重新配置来考虑新域名。

具有内部域“ifp.com”的名为“rizzo”的服务器的典型RHEL / CentOS服务器设置如下所示:

/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'

96
2017-11-17 13:20



和你一样,我更喜欢短名称,但我最近发现一些Oracle应用程序需要输出 hostname 成为FQDN。只是拥有它 /etc/hosts 不够好。这与我的一致性有些混乱。 - James O'Gorman
在这个例子中主机名的大小写的差异肯定不是最佳实践参考: tools.ietf.org/search/rfc1178 - teknopaul
不能 /etc/sysconfig/network 包含如下行: NETWORKING=yes, NETWORKING_IPV6=no, HOSTNAME=example.com, NISDOMAIN=example ? - Jasmine Lognnes
@JasmineLognnes对,我已经纠正了。我希望ewwhite不介意。 - kubanczyk
这不仅仅是偏好。看到 hostname(1) 在任何Linux机器上。


几乎所有软件都对正确设置主机名很敏感。当我在Digg工作时,由于做出了看似无辜的变化,我曾将整个网站关闭了2个小时 /etc/hosts这影响了系统的主机名概念。轻轻踩踏。那就是说,你可能会有些困惑。我不认为 HOSTNAME= 设置直接等同于基于Debian的发行版的使用方式 /etc/hostname

在异构环境中对我有用的是:

  1. 使用配置管理软件中的条件,以供应商推荐的方式设置主机名。
  2. 使用 hostname 命令设置内核使用的主机名等。
  3. /etc/hosts

    127.0.0.1    localhost
    10.0.0.1     hostname.example.com     hostname
    

这个配置还没有让我失望。


36
2017-11-21 18:48



这几乎就是我在工作中使用的设置。只要域名位于环境中相关机器的DNA搜索路径(/etc/resolv.conf)中,短名称就可以了。 - gWaldo
你是否特别推荐本地网络IP而不是公共IP? - code_monk


你肯定会在网上找到参考资料,这会告诉你一定要这样或那样做。然而,在我看来,使用短名称作为主机名,并在/ etc / hosts中具有完全限定名称肯定更为普遍。这似乎是更明智的方式,因为需要完全限定名称的服务可以适应呼叫 hostname --fqdn 代替。

我最近只遇到过一个软件,它严格要求返回fqdn hostname,这是ganeti。他们记录了这一点 这里。我看不出他们无法适应的任何理由 hostname --fqdn但是。


29
2017-12-15 14:45



奖金提供一个例子!谢谢。 - Cakemox
“我认为他们无法适应任何理由 hostname --fqdn“在”为什么是一个完全限定的主机名“下的第一段中回答 - 它需要猜测,并且需要一个有效的解析器。询问内核是最安全和最可靠的选择。 - womble♦
@womble - 只要/ etc / hosts文件有一个机器的条目(10.0.0.1 hostname.example.com hostname)和/etc/nsswitch.conf指定DNS之前的本地解析(hosts: files dns)然后有一个工作的解析器由本地hosts文件完成。因此,使用FQDN而不是主机名的参数很少有用。另外,另一个严格要求的软件示例 hostname 返回FQDN是Zimbra邮件服务器包。 - crashmaxed
@crashmaxed:这是几个额外的要求,任何一个在给定环境中可能无法实现或者被错误搞砸了。在内核数据结构中使用FQDN要简单得多。 - womble♦


在研究这个问题的同时,我已经疯狂到足以检查“主机名”的源代码并编写一个脚本来打印调查结果(Fedora 19)。缺少的是看看“/ etc / hosts”,在我看来,首先应该保留所有这些内容。

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

运行Fedora 19的Amazon EC2 VM上的输出,手动设置内核值并填充后 /etc/hostname,但没有变化 /etc/hosts 可能就像这样:

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

在perl中获取完全限定主机名的弹性方法是:

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

在bash中它将是:

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
}

笔记 

注1:HOSTNAME是bash提供的shell变量(“自动设置为当前主机的名称。”)但是没有关于bash到达该值的指示。

注2:永远不要忘记/boot/initrams-FOO.img中的/ etc / hostname ...


10
2017-10-03 11:39



对不起,如果这应该是显而易见的,但这与设置主机名有什么关系? - Chris S
基本上是我在研究在Fedora 19 EC2实例上设置主机名时所做的注释。至于结果:1)在/ etc / hostname中设置FQHN 2)不要触摸/ etc / hosts 3)你可以将'kernel hostname'设置为FQHN或非限定主机名,如果取消设置,则取值为/ etc / hostname 4)你可以将'kernel domainname'设置为domainname,这比'(none)'更好。 - David Tonhofer


/ etc / hosts选项运行良好。

但是你想确保所有正确的文件都更新了 建立 工具


-4
2017-11-25 11:56



我的发行版没有“设置”工具;你使用哪个发行版有一个? - nickgrim
任何基于redhat的操作系统都有设置工具rhel / centos / fedora whar OS你用的是什么? - Riaan
由于该问题涉及基于RHEL和基于Debian的发行版之间的差异,我们必须假设提问者使用两者。在基于Debian的发行版上没有“设置”工具。 - Martijn Heemels


嗯...在linux主机中,如果你想改变HOSTNAME和FQDN,你应该解决3个步骤(例如,新的主机是 rizzo.ifp.com):

步骤1 在NETWORK属性配置中更改HOST值:

sudo vi /etc/sysconfig/network

更改或添加字符串:

HOSTNAME=rizzo.ifp.com

第2步 编辑主机配置

sudo vim /etc/hosts
#IPv4
127.0.0.1       localhost localhost.localdomain localhost4 localhost4.localdomain4
[External IP]   rizzo rizzo.ifp.com

第3步 重新启动主机 做得好,只需检查新配置

[rizzo@rizzo]# hostname -f
rizzo.ifp.com

-4
2017-12-22 10:56





订单不对。它一定要是:

1.2.3.4 full.example.com full

所以这个例子可能是这样的:

[External IP] rizzo.example.com rizzo 

-4
2018-04-05 07:23



这个问题已经有了真正优质的答案。这不会添加任何新内容。 - Esa Jokinen