5.7. IP 的接口配置

第 4 章 所述设置硬件后,您必须让内核网络软件知道这些设备。需要使用几个命令来配置网络接口并初始化路由表。这些任务通常在每次启动系统时从网络初始化脚本中执行。此过程的基本工具称为 ifconfig(其中“if”代表接口)和 route

ifconfig 用于使接口可供内核网络层访问。这包括分配 IP 地址和其他参数,以及激活接口,也称为“启动”接口。在此处“激活”意味着内核将通过接口发送和接收 IP 数据报。调用它的最简单方法是使用:
ifconfig interface ip-address

此命令将以下内容分配给ip-address (IP地址)interface(接口)并激活它。所有其他参数都设置为默认值。例如,默认网络掩码源自 IP 地址的网络类,例如 B 类地址的 255.255.0.0ifconfig第 5.8 节中详细描述。”

route 允许您从内核路由表中添加或删除路由。可以这样调用它:
route [add|del] [-net|-host] target [if]

参数add (添加)del (删除)确定是添加还是删除到target(目标)的路由。参数-net (网络)-host (主机)告诉 route 命令目标是网络还是主机(如果您未指定,则假定为主机)。参数if同样是可选的,允许您指定路由应定向到哪个网络接口 — 如果您不提供此信息,Linux 内核会做出合理的猜测。此主题将在后续章节中详细解释。

5.7.1. 环回接口

要激活的第一个接口是环回接口
# ifconfig lo 127.0.0.1

有时,您会看到使用虚拟主机名 localhost 而不是 IP 地址。ifconfig 将在hosts文件中查找该名称,其中一个条目应将其声明为 127.0.0.1 的主机名
# Sample /etc/hosts entry for localhost
localhost     127.0.0.1

要查看接口的配置,您可以调用 ifconfig,仅将接口名称作为参数传递
$ ifconfig lo
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:3924  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          Collisions:0 

您可以看到,环回接口已被分配 255.0.0.0 的网络掩码,因为 127.0.0.1 是 A 类地址。

现在,您几乎可以开始使用您的迷你网络了。仍然缺少的是路由表中的一个条目,该条目告诉 IP 它可以使用此接口作为到达目标 127.0.0.1 的路由。这可以通过以下方式完成:
# route add 127.0.0.1

同样,您可以使用 localhost 而不是 IP 地址,前提是您已将其输入到您的/etc/hosts.

接下来,您应该检查一切是否正常工作,例如使用 pingping 是网络的声纳设备。[1]该命令用于验证给定的地址是否实际可达,并测量将数据报发送到该地址并返回所发生的延迟。此过程所需的时间通常称为“往返时间”

# ping localhost
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=0.4 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=255 time=0.4 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=255 time=0.4 ms
^C
--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.4/0.4/0.4 ms
#

当您像此处所示调用 ping 时,它将继续永久发送数据包,除非用户中断它。^C标记了我们按下 Ctrl-C 的位置。

前面的示例表明,针对 127.0.0.1 的数据包已正确传递,并且几乎立即将回复返回给 ping。这表明您已成功设置了您的第一个网络接口。

如果您从 ping 获得的输出与前面示例中显示的输出不相似,那么您就遇到麻烦了。检查任何错误,如果它们表明某些文件没有正确安装。检查您使用的 ifconfigroute 二进制文件是否与您运行的内核版本兼容,最重要的是,内核已启用网络编译(您可以从/proc/net目录的存在来判断)。如果您收到一条错误消息,指出“网络不可达”,那么您可能弄错了 route 命令。确保使用您给 ifconfig 的相同地址。

前面描述的步骤足以在独立的宿主机上使用网络应用程序。在将前面提到的行添加到您的网络初始化脚本并确保它将在启动时执行后,您可以重新启动您的机器并尝试各种应用程序。例如,telnet localhost 应该建立到您的主机的 telnet 连接,从而为您提供login (登录)提示符。

但是,环回接口不仅可以用作网络书籍中的示例,或者在开发期间用作试验台,而且实际上在正常运行期间被某些应用程序使用。[2]因此,无论您的机器是否连接到网络,您都必须始终配置它。

5.7.2. 以太网接口

配置以太网接口与配置环回接口几乎相同;当您使用子网划分时,它只需要更多参数。

在虚拟酿酒厂中,我们将最初的 B 类网络子网划分到 C 类子网络中。要使接口识别这一点,ifconfig 命令如下所示:
# ifconfig eth0 vstout netmask 255.255.255.0

此命令分配eth0接口的 IP 地址为 vstout (172.16.1.2)。如果我们省略了网络掩码,ifconfig 会从 IP 网络类中推断出网络掩码,这将导致不正确的网络掩码 255.255.0.0。现在快速检查显示
# ifconfig eth0
eth0      Link encap 10Mps Ethernet HWaddr  00:00:C0:90:B3:42
          inet addr 172.16.1.2 Bcast 172.16.1.255 Mask 255.255.255.0
          UP BROADCAST RUNNING  MTU 1500  Metric 1
          RX packets 0 errors 0 dropped 0 overrun 0
          TX packets 0 errors 0 dropped 0 overrun 0

您可以看到 ifconfig 自动将广播地址(Bcast 字段)设置为常用值,即主机的网络号,并将所有主机位设置为 1。此外,最大传输单元(内核将为此接口生成IP数据报的最大大小)已设置为以太网数据包的最大大小:1,500 字节。默认值通常是您将使用的值,但如果需要,所有这些值都可以使用将在 第 5.8 节中描述的特殊选项覆盖。”

与环回接口一样,您现在必须安装一个路由条目,告知内核可以通过eth0到达的网络。对于虚拟酿酒厂,您可以像下面这样调用 route
# route add -net 172.16.1.0

起初这看起来有点像魔法,因为并不清楚 route 如何检测要通过哪个接口进行路由。但是,这个技巧相当简单:内核检查到目前为止已配置的所有接口,并将目标地址(在本例中为 172.16.1.0)与接口地址的网络部分进行比较(即,接口地址与网络掩码的按位与)。唯一匹配的接口是eth0.

现在,这个–net选项是做什么用的?这是因为 route 可以处理到网络和到单个主机的路由(就像您之前看到的 localhost 一样)。当给定点分十进制表示法的地址时,route 会尝试通过查看主机部分位来猜测它是网络还是主机名。如果地址的主机部分为零,则 route 假定它表示网络;否则,route 将其作为主机地址。因此,route 会认为 172.16.1.0 是主机地址而不是网络号,因为它不知道我们使用子网划分。我们必须明确告诉 route 它表示一个网络,因此我们给它–net标志。

当然,route 命令输入起来有点乏味,而且容易出现拼写错误。一种更方便的方法是使用我们在/etc/networks中定义的网络名称。这种方法使命令更具可读性;甚至可以省略–net标志,因为 route 知道 172.16.1.0 表示一个网络
# route add brew-net

现在您已经完成了基本配置步骤,我们希望确保您的以太网接口确实运行良好。从您的以太网中选择一个主机,例如 vlager,然后键入
# ping vlager
PING vlager: 64 byte packets
64 bytes from 172.16.1.1: icmp_seq=0. time=11. ms
64 bytes from 172.16.1.1: icmp_seq=1. time=7. ms
64 bytes from 172.16.1.1: icmp_seq=2. time=12. ms
64 bytes from 172.16.1.1: icmp_seq=3. time=3. ms
^C
----vstout.vbrew.com PING Statistics----
4 packets transmitted, 4 packets received, 0
round-trip (ms)  min/avg/max = 3/8/12

如果您没有看到类似的输出,那么有些东西坏了。如果您遇到不寻常的数据包丢失率,这暗示着一个硬件问题,例如不良或丢失的终端器。如果您根本没有收到任何回复,您应该使用 第 5.9 节中稍后描述的 netstat 检查接口配置。ifconfig 显示的数据包统计信息应告诉您是否已在此接口上发送任何数据包。如果您也可以访问远程主机,您也应该转到该机器并检查接口统计信息。这样,您可以准确地确定数据包在哪里被丢弃。此外,您应该使用 route 显示路由信息,以查看两个主机是否都具有正确的路由条目。当不带任何参数调用 route 时,它会打印出完整的内核路由表 (–n只是让它以点分十进制形式打印地址,而不是使用主机名)
# route -n
Kernel routing table
Destination  Gateway  Genmask         Flags Metric Ref Use    Iface
127.0.0.1    *        255.255.255.255 UH    1      0      112 lo
172.16.1.0   *        255.255.255.0   U     1      0       10 eth0

这些字段的详细含义将在 第 5.9 节中解释。 Flags 列包含为每个接口设置的标志列表。 U 始终为活动接口设置,H 表示目标地址表示主机。如果为您打算作为网络路由的路由设置了 H 标志,则必须使用–net选项重新发布 route 命令。要检查您输入的路由是否被使用,请检查倒数第二列中的 Use 字段是否在两次调用 ping 之间增加。

5.7.3. 通过网关路由

在上一节中,我们仅介绍了在单个以太网上设置主机的情况。但是,人们经常会遇到通过网关相互连接的网络。这些网关可以简单地链接两个或多个以太网,但也提供到外部世界的链接,例如互联网。为了使用网关,您必须向网络层提供额外的路由信息。

虚拟酿酒厂和虚拟葡萄酒厂的以太网通过这样的网关连接,即主机 vlager。假设 vlager 已经配置好,我们只需向 vstout 的路由表中添加另一个条目,告诉内核可以通过 vlager 到达葡萄酒厂网络上的所有主机。route 的相应命令如下所示;gw 关键字告诉它下一个参数表示一个网关

# route add wine-net gw vlager

当然,任何在Winery网络上你希望与之通信的主机,必须要有通往Brewery网络的路由条目。否则,你只能从Brewery网络向Winery网络发送数据,但是Winery网络上的主机将无法回复。

这个例子只描述了一个在两个隔离的以太网之间切换数据包的网关。现在假设 vlager 也有一个到互联网的连接(例如,通过一个额外的SLIP连接)。那么我们希望发往除了Brewery之外任何目标网络的数据报,都被交给 vlager 处理。这个操作可以通过将 vlager 设置为 vstout 的默认网关来实现。
# route add default gw vlager

网络名 default0.0.0.0 的简写,它表示默认路由。默认路由匹配所有目标地址,并且在没有更精确的匹配路由时被使用。你不需要将这个名字添加到/etc/networks因为它是内置在 route 命令中的。

如果你在使用ping命令测试一个或多个网关后面的主机时,发现丢包率很高,这可能暗示网络非常拥塞。丢包并非主要由于技术缺陷,而是由于转发主机上的临时负载过重,导致它们延迟甚至丢弃传入的数据报。

5.7.4 配置网关

配置一台机器在两个以太网之间切换数据包非常简单。假设我们回到 vlager,它配备了两块以太网卡,每块卡都连接到两个网络中的一个。你只需要分别配置这两个接口,给它们各自的IP地址和匹配的路由,就完成了。

将这两个接口的信息添加到hosts文件通常很有用,如下例所示,这样我们就可以方便地使用它们的名字了
172.16.1.1      vlager.vbrew.com    vlager vlager-if1
172.16.2.1      vlager-if2

设置这两个接口的命令序列如下:
# ifconfig eth0 vlager-if1
# route add brew-net
# ifconfig eth1 vlager-if2
# route add wine-net

如果这个序列不起作用,请确保你的内核编译时启用了IP转发。一个好的方法是确保/proc/net/snmp的第二行的第一个数字设置为1.

5.7.5 PLIP接口

用于连接两台机器的PLIP链路与以太网略有不同。PLIP链路是被称为点对点链路的一个例子,这意味着链路的每一端都只有一台主机。像以太网这样的网络被称为广播网络。点对点链路的配置是不同的,因为与广播网络不同,点对点链路不支持它们自己的网络。

PLIP提供了计算机之间非常廉价和可移植的连接。作为一个例子,我们将考虑Virtual Brewery公司员工的笔记本电脑,它通过PLIP连接到 vlager。笔记本电脑本身被称为 vlite,并且只有一个并行端口。在启动时,这个端口将被注册为plip1。要激活该链接,您必须使用以下命令配置plip1接口:[3]
# ifconfig plip1 vlite pointopoint vlager
# route add default gw vlager

第一个命令配置接口,告诉内核这是一个点对点链路,远程端点的地址是 vlager。第二个命令安装默认路由,使用 vlager 作为网关。在 vlager 上,需要类似的 ifconfig 命令来激活链接(不需要调用 route 命令)。
# ifconfig plip1 vlager pointopoint vlite

请注意,vlager 上的plip1接口不需要单独的IP地址,但也可以被赋予地址 172.16.1.1。点对点网络不直接支持网络,因此接口不需要任何受支持的网络上的地址。内核使用路由表中的接口信息来避免任何可能的混淆。[4]

现在我们已经配置了从笔记本电脑到Brewery网络的路由;仍然缺少的是一种从Brewery的任何主机路由到 vlite 的方法。一种特别麻烦的方法是将一个特定的路由添加到每个主机的路由表中,将 vlager 命名为通往 vlite 的网关。
# route add vlite gw vlager

动态路由为临时路由提供了一个更好的选择。你可以使用 gated,一个路由守护进程,你必须在网络中的每个主机上安装它,以便动态地分发路由信息。然而,最简单的选择是使用代理ARP(地址解析协议)。使用代理ARP,vlager 将通过发送自己的以太网地址来响应任何对 vlite 的ARP查询。所有发往 vlite 的数据包最终都会到达 vlager,然后由它将它们转发到笔记本电脑。我们将在第5.10节中再次讨论代理ARP。

当前net-tools版本包含一个名为 plipconfig 的工具,允许您设置某些PLIP定时参数。用于打印机端口的IRQ可以使用 ifconfig 命令设置。

5.7.6 SLIP和PPP接口

虽然SLIP和PPP链路只是像PLIP连接这样的简单的点对点链路,但关于它们还有更多要说的。通常,建立SLIP连接需要通过你的调制解调器拨号连接到一个远程站点,并将串行线路设置为SLIP模式。PPP以类似的方式使用。我们在第7章第8章中详细讨论SLIP和PPP。

5.7.7 Dummy接口

Dummy接口有点特殊,但仍然非常有用。它的主要优点是对于独立的机器和唯一的IP网络连接是拨号链路的机器。事实上,后者大部分时间也是独立的机器。

独立机器的困境是它们只有一个激活的网络设备,即环回设备,通常分配的地址是 127.0.0.1。然而,在某些情况下,你必须将数据发送到本地主机的“官方”IP地址。例如,考虑笔记本电脑 vlite,在本例中,它与网络断开了连接。vlite 上的一个应用程序现在可能想要将数据发送到同一主机上的另一个应用程序。在/etc/hosts中查找 vlite 得到IP地址 172.16.1.65,因此应用程序尝试发送到这个地址。由于环回接口是当前机器上唯一激活的接口,内核不知道 172.16.1.65 实际上指向它自己!因此,内核丢弃数据报并向应用程序返回一个错误。

这就是dummy设备介入的地方。它通过简单地作为环回接口的另一个自我来解决这个困境。对于 vlite 的情况,你只需给它地址 172.16.1.65,并添加一个指向它的主机路由。然后,每个发往 172.16.1.65 的数据报都会在本地传递。正确的调用是:[5]
# ifconfig dummy vlite
# route add vlite

5.7.8 IP别名

新的内核支持一个可以完全取代dummy接口并提供其他有用功能的特性。IP别名 允许你在一个物理设备上配置多个IP地址。在最简单的情况下,你可以通过将主机地址配置为环回接口上的别名来复制dummy接口的功能,并完全避免使用dummy接口。在更复杂的用法中,你可以配置你的主机看起来像许多不同的主机,每个主机都有自己的IP地址。这种配置有时被称为“虚拟主机”,尽管从技术上讲,它也被用于各种其他技术。[6]

要为接口配置别名,你必须首先确保你的内核已编译支持IP别名(检查你是否有一个/proc/net/ip_alias文件;如果没有,你将不得不重新编译你的内核)。配置IP别名实际上与配置真实的网卡设备相同;你使用一个特殊的名称来表明你想要一个别名。例如:
# ifconfig lo:0 172.16.1.1
这个命令将为环回接口创建一个别名,地址为172.16.1.1。IP别名通过附加n到实际的网络设备来引用,其中 “n” 是一个整数。在我们的例子中,我们正在创建别名的网络设备是lo,并且我们正在为它创建一个编号为零的别名。这样,一个物理设备就可以支持多个别名。

每个别名都可以被视为一个单独的设备,就内核IP软件而言,它将是这样;然而,它将与其他接口共享其硬件。

注释

[1]

有人还记得Pink Floyd的 "Echoes "吗?

[2]

例如,所有基于RPC的应用程序都在启动时使用环回接口向 portmapper 守护进程注册自己。这些应用程序包括NIS和NFS。

[3]

请注意pointopoint不是一个错字。它确实是这样拼写的。

[4]

作为一种预防措施,你应该只在你完全设置好以太网的路由表条目之后再配置PLIP或SLIP链路。对于一些较旧的内核,你的网络路由可能最终指向点对点链路。

[5]

dummy设备被称为dummy0如果你把它作为模块加载而不是选择它作为内置内核选项。这是因为你可以加载多个模块并拥有多个dummy设备。

[6]

更准确地说,使用IP别名被称为网络层虚拟主机。在WWW和SMTP领域,更常见的是使用应用层虚拟主机,其中每个虚拟主机都使用相同的IP地址,但每个应用层请求都传递一个不同的主机名。像FTP这样的服务无法以这种方式运行,它们需要网络层虚拟主机。