Debian 的 /etc/hosts

Debian 的 /etc/hosts

我试图获取一个连接 PostgreSQL 数据库以在服务器上工作的 perl 脚本。这个脚本神秘地失败了。然后我意识到这localhost不在/etc/hosts文件中。

该机器(当前运行 Debian lenny)的文件目前看起来像

127.0.0.1       machinename.domain   machinename
xxx.xx.x.xxx    machinename.domain   machinename

xxx.xx.x.xxx是IP 地址。我当前的家用计算机的文件是稍旧的安装(当前运行 Debian freeze)是

127.0.0.1       machinename          localhost
127.0.1.1       machinename.domain   machinename

我的家用计算机位于路由器后面,不直接暴露于互联网。无论如何,我使用 DSL 并且没有静态 IP 地址。

/etc对我的机器进行版本控制(使用 etckeeper)已经有一段时间了,我发现对于这台服务器,一些策划者(可能是我自己)于 2009 年 12 月 17 日进行了以下更改。

-127.0.0.1      localhost
+127.0.0.1      machinename.domain  machinename

我之前就想知道为什么这个文件是这样设置的,但答案并不明显。一些问题:

  1. 为什么127.0.1.1?这可能是 Debian 特有的一段历史。我在网上搜索了一下,发现了一些关于 Gnome 的模糊说法,但几乎没有任何实质内容。

  2. 该文件是从 Debian 中的哪里设置的模板?

  3. 目前是否认为该文件的正确/最佳形式?

  4. 行中名称的顺序重要吗?我希望不是。

更一般地说,如何解释为什么这两条线的结构如此?

现在,我想我会将服务器更改/etc/hosts

127.0.0.1       machinename.domain  machinename localhost
xxx.xx.x.xxx    machinename.domain  machinename

评论?

答案1

概括

你应该一直拥有

127.0.0.1    localhost.localdomain localhost

就您而言,由于您没有永久 IP 地址,因此您也可以拥有

127.0.1.1    machinename.domain machinename

这条线似乎对于某些应用程序(如 GNOME)是必需的,但实际上可能会导致其他应用程序出现问题!

提出了解析系统主机名的新方案


实际上,您的计算机有两个主机名。

localhost.localdomain是用于在同一台计算机上运行的两个支持 TCP/IP 的进程之间进行私有通信的名称。

machinename.domain是用于您的机器和连接到您的机器的机器之间通信的名称。

您总是想要localhost.localdomain指向127.0.0.1::1如果您使用的是 IPv6)。这样,同一台计算机上的两个 TCP/IP 进程之间的所有通信都将使用lo(环回)接口,这通常是防火墙(例如 )所允许的iptables,并且无需担心您的网络是否可用或 DNS 是否正常工作。

某些应用程序(例如 GNOME 1)尝试使用计算机的公共名称来表示所有内容,即使是在与同一台计算机通信时也是如此。这样 GNOME 的一个部分就可以与 GNOME 的另一部分进行通信,即使它运行在网络上的另一台机器上。 (GNOME 中的 N 最初代表“网络”。)

理想情况下,您的计算机名称可以通过 DNS 或其他一些共享数据库获知,其他计算机也可以使用这些数据库来确定您计算机的地址,以便其他计算机上的应用程序可以与您的计算机进行通信。

但是,如果您的计算机名称不在 DNS 中,或者 DNS 无法正常工作,像 GNOME 这样的程序仍然需要一种与自身对话的方式。

/etc/hosts为了使这项工作有效,有多种修改方法。

最常见的曾经是

127.0.0.1    localhost.localdomain localhost
w.x.y.z      machinename.domain machinename

其中w.x.y.z是您的主网络接口的地址,例如eth0

如果您的系统使用静态 IP 地址并且始终处于连接状态,则该方法可以正常工作2

如果您的系统有动态 IP 地址,则会使用各种脚本进行编辑/etc/hosts,以包含基于 DHCP 服务器返回的条目。

但是,如果您的系统没有永久的网络连接,您就无法添加这样的条目,因为您没有一个可靠的地址。

于是人们开始做类似的事情

127.0.0.1    localhost.localdomain localhost machinename.domain machinename

或者

127.0.0.1    machinename.domain machinename localhost.localdomain localhost

这样,使用 TCP/IP 的进程仍然可以与同一台计算机上的其他进程通信,即使它们使用计算机名称查找 IP 地址也是如此。

但它破坏了其他应用程序。

例如,dnsdomainname

我还记得有一个问题,即只有同一台计算机上的人才能连接到服务器,因为服务器只侦听3 环回设备上的连接。

该程序将获取机器的名称,然后查找名称的地址,并使用找到的第一个地址,并绑定到该网络接口。如果您的计算机名称解析为127.0.0.14 个地址,则意味着您认为正在运行的服务machinename.domain(因此可用于整个网络)实际上仅可用于同一计算机上运行的其他进程。

正如安迪指出的那样,名称的顺序并不重要。试图查找主机名的东西127.0.0.1会得到第一个名称作为主机的规范/官方/主要名称,但因为它会向前和向后解析,所以我不认为这会导致任何问题,除非有一些/etc/hosts需要一种格式或另一种格式的自动化编辑工具。

但我认为您应该首先拥有一个完全合格的域名(即包含域名的名称),正如我在/etc/hosts 的格式

还有另一种类似的格式,使用两行而不是一行,例如

127.0.0.1    localhost.localdomain localhost
127.0.1.1    machinename.domain machinename

这是一个巧妙的技巧,因为lo的地址确实是127.0.0.1/8,这意味着网络中的任何地址127都是环回设备。

我假设使用这种格式,以便需要更改条目的工具machinename.domain可以在不接触条目的情况下完成此操作127.0.0.1 localhost...

但请注意,它仍然会导致machinename.domain映射到lo,因此它仍然会导致我提到的问题。

我还刚刚在虚拟机中启动 Fedora 15 并登录到 Gnome 桌面,但我看不到任何 TCP/IP 连接。他们似乎都在使用 UNIX 套接字。因此,也许127.0.1.1不再需要该条目。


脚注

  1. 过去就是这样。在我的 Fedora 15 测试机上,它似乎使用 UNIX 套接字而不是 TCP/IP。
  2. 网络启动之前的系统引导期间除外。
  3. 真正的“束缚”而不是“倾听”。
  4. 或任何 127.xxx 地址。

答案2

在我的系统上,我有以下内容/var/lib/dpkg/info/netbase.postinst

create_hosts_file() {
  if [ -e /etc/hosts ]; then return 0; fi

  cat > /etc/hosts <<-EOF
        127.0.0.1       localhost
        ::1             localhost ip6-localhost ip6-loopback
        fe00::0         ip6-localnet
        ff00::0         ip6-mcastprefix
        ff02::1         ip6-allnodes
        ff02::2         ip6-allrouters

EOF

我的netbase版本是4.45。

我希望反向查找 IP 地址时会返回该行的第一个名称,否则我怀疑顺序是否重要。

答案3

我之前就想知道为什么这个文件是这样设置的,但答案并不明显。

从文本文件中添加或删除一行非常容易编写脚本。

编辑文本文件中的一行以添加或删除组件要困难得多。

因此,编写一个运行“hostname -s”和“hostname -f”的脚本非常容易,从 /etc/hosts 中删除 127.0.1.1 并添加一个包含主机名结果的新脚本。

但是编写一个脚本来从包含 127.0.0.1 的行中删除任何主机名(不干扰操作员手动添加的条目),然后将当前主机名添加到 localhost 条目要困难得多。

相关内容