砥砺奋进谱新篇,且看旧貌换新颜。欢迎访问新的 IBM Developer 中文网站! 了解详情

学习 Linux 101:基本网络故障诊断

概述

在本教程中,我们将学习诊断 Linux 客户端系统上的网络问题。学习:

  • 手动配置网络接口,包括使用 iproute2 查看和更改网络接口的配置。
  • 手动配置路由,包括使用 iproute2 查看和更改路由表以及设置默认路由。
  • 调试与网络配置相关的问题。
  • 认识 net-tools 旧命令。

Linux 中的网络

在当今世界,计算机网络让信息共享、研究和商务等都跨越了国界,覆盖了全球。想要考察肯尼亚国家公园?当然可以。希望买一张瑞士火车票?也没问题。给街上或者另一个大洲的人发电子邮件。欣赏外太空的照片。计算机网络让这一切都能够更加轻而易举地实现。但是,当网络出现故障时会发生什么情况呢?

本教程将帮助您围绕 Linux 管理员 (LPIC-1) 考试 101 的 109 主题中的 109.3 目标进行应考准备。该目标的权重为 4。本教程反映了 2018 年 10 月 29 日更新的 5.0 版本的目标。

前提条件

要想最充分地利用本系列教程,您应该掌握 Linux 的基本知识,还应该有一个正常工作的 Linux 系统,您可以在这个系统上练习本教程中介绍的命令。对于本教程,您还需要一个或多个网络连接。有时,不同版本程序的输出格式也有所不同。因此,您的结果可能并不总是与这里显示的清单和数字完全相同。

本教程中的示例来自 Fedora 31 和 Ubuntu 18.04.3 LTS。

网络工具集

对于许多用户来说,当您插入网络电缆或提供 Wifi 网络的某种登录凭证时,网络配置就会自动完成。 在“学习 Linux 101:永久网络配置”教程中,我展示了在需要进行一些手动配置的情况下如何使用图形工具进行基本网络配置。在本教程中,我将展示用于执行这些任务和诊断网络问题的命令行工具。要通过 LPI 认证考试,就需要使用和理解 iproute2 网络命令集。开发这些命令是为了更好地与 2.2 内核集成,而这些命令目前已存在了很长时间。更早的 net-tools 套件仍在使用,因为很多 Linux 老用户很熟悉它们,这种使用习惯早已根深蒂固。虽然从现代的发展来看,它们存在某些不足,但仍能执行很多有用的功能,您或许也因而能够与那些不熟悉新工具的人员协作。早在 2009 年,人们就曾讨论过是要完全删除 net-tools,还是不将其包含在发行版中,但这种讨论仍未有定论。

在一些系统上(如 Fedora),iproute2 工具是通过 iproute (no 2) 包安装的,而在 Ubuntu 上,这个包称为 iproute2。清单 1 显示了如何在 Fedora 上使用 dnf 命令或在 Ubuntu 上使用 apt 命令来检查已安装或可用的包。

清单 1. 检查网络工具包
ian@ianattic5-f31 ~]$ # Fedora 31
[ian@ianattic5-f31 ~]$ dnf list iproute iproute2 net-tools
Last metadata expiration check: 0:24:28 ago on Tue 24 Mar 2020 09:03:02 PM EDT.
Installed Packages
iproute.x86_64                 5.4.0-1.fc31                             @updates
net-tools.x86_64               2.0-0.55.20160912git.fc31                @fedora

ian@attic4-u18:~$ # Ubuntu 18.04 LTS
ian@attic4-u18:~$ apt list iproute iproute2 net-tools
Listing...Done
iproute2/bionic,now 4.15.0-2ubuntu1 amd64 [installed]
net-tools/bionic,now 1.60+git20161116.90da8a0-1ubuntu1 amd64 [installed]

iproute 或 iproute2 包会安装一些二进制文件,您可以使用 dnf、rpm 或 dpkg 工具列出这些二进制文件。清单 2 显示了如何列出 Ubuntu 上已经安装的二进制文件。

清单 2. iproute2 安装的二进制文件
ian@attic4-u18:~$ dpkg -L  iproute2 | grep "bin/"
/bin/ip
/bin/ss
/sbin/bridge
/sbin/devlink
/sbin/rtacct
/sbin/rtmon
/sbin/tc
/sbin/tipc
/usr/bin/lnstat
/usr/bin/nstat
/usr/bin/rdma
/usr/bin/routef
/usr/bin/routel
/usr/sbin/arpd
/usr/sbin/genl
/sbin/ip
/usr/bin/ctstat
/usr/bin/rtstat

本教程重点介绍用于配置接口和路由的 ip 命令。您在本教程中了解的其他工具来自以下包:

  • hostname
  • traceroute 或 inetutils-traceroute
  • iputils、iputils-ping 或 iputils-tracepath
  • nmap-ncat 或 netcat-openbsd

在基于 rpm 和 deb 的系统之间,这些包的名称和内容会有所不同。因此,这只是一个通用指南,告诉您可以在哪里查找这些命令。

ip 命令用法介绍

在开始使用 ip 更改配置之前,我将展示如何查看有关现有网络的信息。

ip 命令的一般格式如下:

ip [ OPTIONS ] OBJECT { COMMAND | help }

如果调用时不含任何选项,您将看到命令的简短帮助,如清单 3 中所示。

清单 3. ip 命令的帮助
ian@ianattic5-f31 ~]$ ip
Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }
       ip [ -force ] -batch filename
where  OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |
                   tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |
                   netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |
                   vrf | sr | nexthop }
       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |
                    -h[uman-readable] | -iec | -j[son] | -p[retty] |
                    -f[amily] { inet | inet6 | mpls | bridge | link } |
                    -4 | -6 | -I | -D | -M | -B | -0 |
                    -l[oops] { maximum-addr-flush-attempts } | -br[ief] |
                    -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |
                    -rc[vbuf] [size] | -n[etns] name | -N[umeric] | -a[ll] |
                    -c[olor]}

否则,您就需要指定要操作的网络对象。这包括链路、地址、路由或邻居等。大多数对象可以采用完整形式,也可以采用缩写形式。 如果您对缩写不太确定,那么通常可以采用最短的、含义明确的形式。

命令是要对该对象执行的操作。命令会因对象类型而有所不同。通常可以添加、删除和显示(或列出)对象,但并不是所有对象都支持这些命令。对象的帮助会告诉您受支持的命令。 例如,使用 ip link 帮助或 ip neigh 帮助可获取链路或邻居的帮助信息。清单 4 显示了邻居的帮助信息,缩写 n 足以表示 neigh。须注意,也可以使用 neighborneighbour

清单 4. ip 邻居对象的帮助
[ian@ianattic5-f31 ~]$ ip n help
Usage: ip neigh { add | del | change | replace }
        { ADDR [ lladdr LLADDR ] [ nud STATE ] | proxy ADDR } [ dev DEV ]
        [ router ] [ extern_learn ] [ protocol PROTO ]

    ip neigh { show | flush } [ proxy ] [ to PREFIX ] [ dev DEV ] [ nud STATE ]
        [ vrf NAME ]

STATE := { permanent | noarp | stale | reachable | none |
           incomplete | delay | probe | failed }

如果为某个对象调用 ip OBJECT,您将获得该类型可用对象的信息摘要。继续以邻居为例,您可能会看到清单 5 中所示的内容。

清单 5. 使用 ip 命令显示邻居
ian@attic4-u18:~$ ip n
192.168.1.38 dev enp2s0 lladdr ac:18:26:6c:48:aa REACHABLE
192.168.1.37 dev enp2s0 lladdr 00:1b:a9:8a:18:91 STALE
192.168.1.1 dev enp2s0 lladdr 1c:f2:9a:c7:50:0d REACHABLE
192.168.1.25 dev enp2s0 lladdr 30:5a:3a:08:da:e4 REACHABLE
2606:a000:1126:c8a8:5a1e:d3c4:ffe:3894 dev enp2s0 lladdr 30:5a:3a:08:da:e4 STALE
fe80::bc87:36ff:fe3f:c4b2 dev enp2s0 lladdr 1c:f2:9a:c7:50:0d router DELAY
fe80::efaa:4539:a6ba:27b9 dev enp2s0 lladdr 30:5a:3a:08:da:e4 STALE

此信息来自邻居发现缓存 (NDC)。如果 30 秒内没有流量,则可访问的位置将过时。

ip 命令的详细手册页

可以使用 manip-neighbour 或 info ip-link 等命令,在手册或信息页面中找到将 ip 命令与各种对象一起使用的更详细帮助。可供阅览的网页包括:

  • ip-address
  • ip-addrlabel
  • ip-l2tp
  • ip-link
  • ip-mad‐dress
  • ip-monitor
  • ip-mroute
  • ip-neighbour
  • ip-netns
  • ip-ntable
  • ip-route
  • ip-rule
  • ip-tcp_metrics
  • ip-token
  • ip-tunnel

须注意,在显示这些展开的手册页时,不支持缩写和替换拼写(如用 neighbor 表示 neighbour),同时也不存在包含这些名称的单独命令。

使用 ip 命令查看接口、地址和路由

为了在接口或链路上传输数据包,您需要一个链路、至少一个与该链路相关联的 IP 地址,以及一个路由表,该路由表告诉您要将数据包传输到特定目的地的链路。这是一个简化的基本网络视图,可用于详细了解 ip 命令。清单 6 显示了来自我的 Ubuntu 系统的一个基本示例。

清单 6. 使用 ip 命令显示链路信息
ian@attic4-u18:~$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen
   1000 link/ether 84:16:f9:04:7a:2a brd ff:ff:ff:ff:ff:ff
3: enp4s0: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel state DOWN mode DEFAULT group default qlen 1000
    link/ether 00:23:54:33:f3:ee brd ff:ff:ff:ff:ff:ff

该系统有一个环回链路 (lo) 和两个以太网链路(enp2s0 和 enp4s0)。本地环回链路和链路 enp2s0 都是开启状态,而链路 enp4s0 则处于关闭状态(未显示为“UP”)。LOWER_UP 状态表示底层介质(如以太网电缆)已连接。

须注意,此信息不显示链路的任何流量统计信息。ip 命令有许多选项,包括用于显示统计数据的 -s(或 -stats-statistics),或者仅显示基本信息的 -br(或 -brief)。您还可以将信息限制为 IPv6(选项 -6)或 IPv4(选项 -4)。这些选项可能并不适用于所有对象。查看手册或信息页面(man ipinfo ip)了解更多信息。清单 7 显示了这些选项的两个示例。

清单 7. 将 ip 命令与各种选项一起使用
ian@attic4-u18:~$ ip -br link show
lo               UNKNOWN        00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
enp2s0           UP             84:16:f9:04:7a:2a <BROADCAST,MULTICAST,UP,LOWER_UP>
enp4s0           DOWN           00:23:54:33:f3:ee <BROADCAST,MULTICAST>
ian@attic4-u18:~$ ip -s link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    RX: bytes  packets  errors  dropped overrun mcast
    12434028   175440   0       0       0       0
    TX: bytes  packets  errors  dropped carrier collsns
    12434028   175440   0       0       0       0
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen
    1000 link/ether 84:16:f9:04:7a:2a brd ff:ff:ff:ff:ff:ff
    RX: bytes  packets  errors  dropped overrun mcast
    181493549  740195   0       0       0       39546
    TX: bytes  packets  errors  dropped carrier collsns
    10908959   121827   0       0       0       0
3: enp4s0: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel state DOWN mode DEFAULT group default qlen 1000
    link/ether 00:23:54:33:f3:ee brd ff:ff:ff:ff:ff:ff
    RX: bytes  packets  errors  dropped overrun mcast
    47979      118      0       0       0       6
    TX: bytes  packets  errors  dropped carrier collsns
    29955049   165003   0       0       0       0

链路信息不会告诉您是否存在与任何链路相关联的 IPv4或 IPv6 地址。

清单 8 显示了如何将 ip 命令与 addr 对象一起使用来查看与链路关联的 IP 地址。须注意,链路 enp4s0 没有任何与之关联的 IP 地址。此链路当前配置为使用动态主机配置协议 (DHCP) 获取地址。

清单 8. 使用 ip addr
iian@attic4-u18:~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 84:16:f9:04:7a:2a brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.24/24 brd 192.168.1.255 scope global dynamic noprefixroute enp2s0
       valid_lft 83404sec preferred_lft 83404sec
    inet6 2606:a000:1126:c8a8:d517:956c:66ed:b709/64 scope global temporary dynamic
       valid_lft 86356sec preferred_lft 27375sec
    inet6 2606:a000:1126:c8a8:f419:b701:db6f:8608/64 scope global temporary deprecated dynamic
       valid_lft 86356sec preferred_lft 0sec
    inet6 2606:a000:1126:c8a8:b1:978b:6813:4705/64 scope global temporary deprecated dynamic
       valid_lft 86356sec preferred_lft 0sec
    inet6 2606:a000:1126:c8a8:a96e:36bd:8f26:5aca/64 scope global temporary deprecated dynamic
       valid_lft 86356sec preferred_lft 0sec
    inet6 2606:a000:1126:c8a8:6da4:fb09:dca6:8ffa/64 scope global temporary deprecated dynamic
       valid_lft 86356sec preferred_lft 0sec
    inet6 2606:a000:1126:c8a8:5d0:831b:2c28:9d40/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 86356sec preferred_lft 86356sec
    inet6 fe80::48bc:4691:9ac0:d027/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: enp4s0: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether 00:23:54:33:f3:ee brd ff:ff:ff:ff:ff:ff

与其他形式的 ip 命令一样,您可以使用选项来更改输出。例如,使用 -br 选项来显示简短输出,使用 -4-6 将输出分别限制为 IPv4 或 IPv6。清单 9 显示了两个示例。

清单 9. 限制 ip addr 输出
ian@attic4-u18:~$ ip -br a
lo               UNKNOWN        127.0.0.1/8 ::1/128
enp2s0           UP             192.168.1.24/24 2606:a000:1126:c8a8:d517:956c:66ed:b709/64
2606:a000:1126:c8a8:f419:b701:db6f:8608/64 2606:a000:1126:c8a8:b1:978b:6813:4705/64
2606:a000:1126:c8a8:a96e:36bd:8f26:5aca/64 2606:a000:1126:c8a8:6da4:fb09:dca6:8ffa/64
2606:a000:1126:c8a8:5d0:831b:2c28:9d40/64 fe80::48bc:4691:9ac0:d027/64
enp4s0           DOWN
ian@attic4-u18:~$ ip -br -4  a
lo               UNKNOWN        127.0.0.1/8
enp2s0           UP             192.168.1.24/24

到目前为止,您已经看到了本地环回链路和以太网链路。您可能还会看到其他几种链路类型,包括 Wifi 链路和网桥链路。清单 10 显示了 Fedora 系统的一个简短的 IPv4 输出,该系统有一个环回地址、一个以太网链路、一个 Wifi 链路和一个网桥链路(以供我的系统上可能存在的虚拟机使用)。

清单 10. 其他链路类型
[ian@ianattic5-f31 ~]$ ip -4 -br a
lo               UNKNOWN        127.0.0.1/8
enp9s0           UP             192.168.1.25/24
virbr0           DOWN           192.168.122.1/24
wlp8s0u2         UP             192.168.3.21/24

另一个您需要获取系统出入流量的对象是路由。将 iproute 对象一起使用可显示路由。如果没有看到任何 v6 信息,可使用 -6 选项再次运行命令,如清单 11 所示。

清单 11. 使用 ip route 显示路由信息
ian@attic4-u18:~$ ip route
default via 192.168.1.1 dev enp2s0 proto dhcp metric 103
169.254.0.0/16 dev enp2s0 scope link metric 1000
192.168.1.0/24 dev enp2s0 proto kernel scope link src 192.168.1.24 metric 103
ian@attic4-u18:~$ ip -6 route
2606:a000:1126:c8a8::/64 dev enp2s0 proto ra metric 103 pref medium
fe80::/64 dev enp2s0 proto kernel metric 103 pref medium
fe80::/64 dev enp2s0 proto kernel metric 256 pref medium
default via fe80::bc87:36ff:fe3f:c4b2 dev enp2s0 proto ra metric 103 pref medium

查看第一行输出,您将看到一个默认的 IPv4 路由,这将用于所有 v4 通信(除非找到更具体的路由)。将通过以太网链路 enp2s0 发送和接收流量。proto 字段表示在通过 DHCP 服务器分配地址时设置该路由。最后,度量值是一种衡量标准,用于给出一条优先于替代路由的路由。度量值越低,该路由的优先级就越高。

您还会看到 IPv4 子网 192.168.1.0/24 的一个条目。这也会使用以太网链路 enp2s0。该路由是由内核在初始化期间添加的,通过此路由发送的流量将具有此主机的源 IP 地址,即 192.168.1.24。

这个例子非常简单,只有一个活动的网络链路。在我的 Fedora 系统中,以太网和 Wifi 链路都处于活动状态,路由信息要稍微复杂一些。清单 12 中显示了 v4 信息。

清单 12. 显示包含多个链路的路由信息
[ian@ianattic5-f31 ~]$ ip route
default via 192.168.1.1 dev ) proto dhcp metric 100
default via 192.168.3.1 dev wlp8s0u2 proto dhcp metric 600
192.168.1.0/24 dev enp9s0 proto kernel scope link src 192.168.1.25 metric 100
192.168.3.0/24 dev wlp8s0u2 proto kernel scope link src 192.168.3.21 metric 600
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
[ian@ianattic5-f31 ~]$ ip -6 route
::1 dev lo proto kernel metric 256 pref medium
2606:a000:1126:c8a8::/64 dev enp9s0 proto ra metric 100 pref medium
fe80::/64 dev enp9s0 proto kernel metric 100 pref medium
fe80::/64 dev wlp8s0u2 proto kernel metric 600 pref medium
default via fe80::bc87:36ff:fe3f:c4b2 dev enp9s0 proto ra metric 100 pref medium

在这种情况下,以太网 (enp9s0) 和 Wifi (wlp8s0u2) 都有默认路由。以太网链路的度量值为 100,而 Wifi 链路的度量值更高,为 600。因此,如果没有任何其他链路覆盖路由决策,则首选以太网链路。Wifi 链路位于访客网络(子网 192.168.3.0/24),这个客户网络对主网络(子网 192.168.3.0/24 )上的资源访问有限。目的地为 192.168.3.0/24 子网的流量将在 Wifi 适配器上发送,其源地址为 192.168.3.21,而 192.168.3.0/24 子网的流量以及不太具体的流量将使用以太网适配器,其源地址为 192.168.1.25。

考虑到上面的路由信息,您可能想知道为什么从 192.168.1.25 到其自身的流量似乎是通过以太网适配器进行路由,而不是在主机内循环的。192.168.3.21 和 Wifi 适配器也有类似的问题。流量如何路由到 127.0.0.1?答案就是内核维护一个本地路由表,用于广播和环回流量的高优先级路由。使用 ip get 命令查看有关特定路由的更多详细信息。如果要检查特定链路上的路由,则针对输出接口添加 oif。清单 13 中有几个说明。

清单 13. 将 ip 与 get 命令一起使用
[ian@ianattic5-f31 ~]$ ip route get 127.0.0.1
local 127.0.0.1 dev lo src 127.0.0.1 uid 1000
    cache <local>
[ian@ianattic5-f31 ~]$ ip route get 192.168.1.25
local 192.168.1.25 dev lo src 192.168.1.25 uid 1000
    cache <local>
[ian@ianattic5-f31 ~]$ ip route get 192.168.3.21
local 192.168.3.21 dev lo src 192.168.3.21 uid 1000
    cache <local>
[ian@ianattic5-f31 ~]$ ip route get 8.8.8.8
8.8.8.8 via 192.168.1.1 dev enp9s0 src 192.168.1.25 uid 1000
    cache
[ian@ianattic5-f31 ~]$ ip route get 192.168.3.29
192.168.3.29 dev wlp8s0u2 src 192.168.3.21 uid 1000
    cache
[ian@ianattic5-f31 ~]$ ip route get 8.8.8.8 oif wlp8s0u2
8.8.8.8 via 192.168.3.1 dev wlp8s0u2 src 192.168.3.21 uid 1000
    cache

这个用于显示链路、地址和路由信息的简短介绍并未涵盖 ip 命令的所有可用选项。您可以参阅我在本文中列出的更详细手册页的列表了解更多信息。

使用 ip 命令激活或停用接口

在开始配置接口之前,知道如何激活或停用接口会十分方便。通常,对已经激活的接口进行更改并不好!清单 14 显示了如何停用一个接口,然后使用 ip 命令重新激活该接口,以将该接口设置为 updown。您需要管理权限才能更改设备(如链路)的状态。

清单 14. 使用 ip 停用和激活接口
[ian@ianattic5-f31 l-lpic1-109-3]$ sudo ip link set enp9s0 down
[ian@ianattic5-f31 l-lpic1-109-3]$ ip -br addr show dev enp9s0
enp9s0           DOWN
[ian@ianattic5-f31 l-lpic1-109-3]$ sudo ip link set enp9s0 up
[ian@ianattic5-f31 l-lpic1-109-3]$ ip -br addr show dev enp9s0
enp9s0           UP             192.168.1.25/24 fe80::efaa:4539:a6ba:27b9/64

保存和恢复接口及路由

知道如何保存并有可能恢复网络和路由的状态也很不错。ip 命令可以使用 save 选项将当前信息保存到二进制文件中。使用 showdump 显示这样一个二进制文件中的内容,并可使用 restore 来恢复。毋庸置疑,恢复操作需要管理员权限。清单 15 显示了如何转储以太网链路的信息和路由信息,以及如何显示保存的二进制文件的内容。

清单 15. 使用 ip 来保存和恢复
[ian@ianattic5-f31 l-lpic1-109-3]$ ip addr save enp9s0 >saved-enp9s0
[ian@ianattic5-f31 l-lpic1-109-3]$ ip addr showdump < saved-enp9s0
if2:
    inet 192.168.1.25/24 brd 192.168.1.255 scope global dynamic noprefixroute enp9s0
       valid_lft 73568sec preferred_lft 73568sec
if2:
    inet6 2606:a000:1126:c8a8:5a1e:d3c4:ffe:3894/64 scope global dynamic noprefixroute
       valid_lft 86382sec preferred_lft 86382sec
if2:
    inet6 fe80::efaa:4539:a6ba:27b9/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
[ian@ianattic5-f31 l-lpic1-109-3]$ ip route save >saved-route
[ian@ianattic5-f31 l-lpic1-109-3]$ ip route showdump < saved-route
default via 192.168.1.1 dev enp9s0 proto dhcp metric 100
default via 192.168.3.1 dev wlp8s0u2 proto dhcp metric 600
192.168.1.0/24 dev enp9s0 proto kernel scope link src 192.168.1.25 metric 100
192.168.3.0/24 dev wlp8s0u2 proto kernel scope link src 192.168.3.21 metric 600
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown

配置网络接口和路由

您可以使用 ip 命令来配置链路、地址或路由。使用 ip 命令所做的更改不能永久保存。因此,您需要在每次引导后进行更改,否则就使用“学习 Linux 101:永久网络配置”教程中讲解的永久性网络配置工具。使用 ip 来试验和检查计划更改是个不错的方法。

ip 命令对物理链路(如以太网或 Wifi 链路)具有有限的配置能力。例如,您可以更改标志(如多播),也可以添加或删除 IP 地址。但是,您可以使用 ip 来配置各种各样的虚拟链路,例如网桥、VLAN 或通道绑定。可以使用 ip link help 查找各种链路类型,并可添加类型以查找适用于特定链路类型的参数。清单 16 显示了 ip link help 的输出末尾部分以及 ip help bond 的输出。

清单 16. 适用于绑定链路的参数
ian@attic4-u18:~$ ip l help
Usage: ip link add [link DEV] [ name ] NAME
                   [ txqueuelen PACKETS ]
                   [ address LLADDR ]
                   [ broadcast LLADDR ]
                   [ mtu MTU ] [index IDX ]
                   [ numtxqueues QUEUE_COUNT ]
                   [ numrxqueues QUEUE_COUNT ]
                   type TYPE [ ARGS ]

...

       ip link help [ TYPE ]

TYPE := { vlan | veth | vcan | vxcan | dummy | ifb | macvlan | macvtap |
          bridge | bond | team | ipoib | ip6tnl | ipip | sit | vxlan |
          gre | gretap | erspan | ip6gre | ip6gretap | ip6erspan |
          vti | nlmon | team_slave | bond_slave | ipvlan | geneve |
          bridge_slave | vrf | macsec }
ian@attic4-u18:~$ ip link help bond
Usage: ... bond [ mode BONDMODE ] [ active_slave SLAVE_DEV ]
                [ clear_active_slave ] [ miimon MIIMON ]
                [ updelay UPDELAY ] [ downdelay DOWNDELAY ]
                [ use_carrier USE_CARRIER ]
                [ arp_interval ARP_INTERVAL ]
                [ arp_validate ARP_VALIDATE ]
                [ arp_all_targets ARP_ALL_TARGETS ]
                [ arp_ip_target [ ARP_IP_TARGET, ...] ]
                [ primary SLAVE_DEV ]
                [ primary_reselect PRIMARY_RESELECT ]
                [ fail_over_mac FAIL_OVER_MAC ]
                [ xmit_hash_policy XMIT_HASH_POLICY ]
                [ resend_igmp RESEND_IGMP ]
                [ num_grat_arp|num_unsol_na NUM_GRAT_ARP|NUM_UNSOL_NA ]
                [ all_slaves_active ALL_SLAVES_ACTIVE ]
                [ min_links MIN_LINKS ]
                [ lp_interval LP_INTERVAL ]
                [ packets_per_slave PACKETS_PER_SLAVE ]
                [ tlb_dynamic_lb TLB_DYNAMIC_LB ]
                [ lacp_rate LACP_RATE ]
                [ ad_select AD_SELECT ]
                [ ad_user_port_key PORTKEY ]
                [ ad_actor_sys_prio SYSPRIO ]
                [ ad_actor_system LLADDR ]


BONDMODE := balance-rr|active-backup|balance-xor|broadcast|802.3ad|balance-tlb|balance-alb
ARP_VALIDATE := none|active|backup|all
ARP_ALL_TARGETS := any|all
PRIMARY_RESELECT := always|better|failure
FAIL_OVER_MAC := none|active|follow
XMIT_HASH_POLICY := layer2|layer2+3|layer3+4|encap2+3|encap3+4
LACP_RATE := slow|fast
AD_SELECT := stable|bandwidth|count

现在,我将展示如何向现有链路中添加 IP 地址,以及如何更新路由表。为了简单起见,我将只讨论 IPv4 地址,但同样的通用技巧也适用于 IPv6。

回想一下,我的 Fedora 系统有一个 Wifi 适配器,其关联的 IP 地址为 192.168.3.21。清单 17 中显示了 IPv4 地址和路由信息。

清单 17. 链路 wlp8s0u2 的 IPv4 地址和路由信息
[[ian@ianattic5-f31 ~]$ ip -4 a show wlp8s0u2
3: wlp8s0u2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc mq state UP group default qlen 1000
    inet 192.168.3.21/24 brd 192.168.3.255 scope global dynamic noprefixroute wlp8s0u2
       valid_lft 53458sec preferred_lft 53458sec
[ian@ianattic5-f31 ~]$ ip -4 r
default via 192.168.1.1 dev enp9s0 proto dhcp metric 100
default via 192.168.3.1 dev wlp8s0u2 proto dhcp metric 600
192.168.1.0/24 dev enp9s0 proto kernel scope link src 192.168.1.25 metric 100
192.168.3.0/24 dev wlp8s0u2 proto kernel scope link src 192.168.3.21 metric 600
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown

假设我想将地址从 192.168.3.21 更改为 192.168.3.30,并将度量值更改为 550。由于不能使用 IP 命令来更改度量值,因此,一种方法就是先添加新地址和新度量值,然后再删除原始地址。

首先,我将添加一个地址,然后查看我完成了哪些部分,如清单 18 所示。须注意,您需要管理权限来添加地址或执行将要完成的其他几项操作。

清单 18. 使用 ip 添加 IP 地址
[ian@ianattic5-f31 ~]$ sudo ip addr add 192.168.3.30/24 dev wlp8s0u2
[ian@ianattic5-f31 ~]$ ip -4 a show wlp8s0u2
3: wlp8s0u2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc mq state UP group default qlen 1000
    inet 192.168.3.21/24 brd 192.168.3.255 scope global dynamic noprefixroute wlp8s0u2
       valid_lft 53338sec preferred_lft 53338sec
    inet 192.168.3.30/24 scope global secondary wlp8s0u2
       valid_lft forever preferred_lft forever

到目前为止一切顺利,但我忘了添加广播地址和度量值。清单 19 显示了如何删除刚才添加的地址,然后再次添加包含广播地址和度量值的地址。须注意,brd 是 broadcast 的适当缩写,+ 告知 ip 从 IP 地址派生广播地址(通过设置或重置接口前缀的主机位)。为此,您可以使用 +-,也可以完全用点分格式拼写出广播地址。

清单 19. 使用 ip 删除地址和添加广播地址
[ian@ianattic5-f31 ~]$ sudo ip addr del 192.168.3.30/24  dev wlp8s0u2
[ian@ianattic5-f31 ~]$ sudo ip addr add 192.168.3.30/24 brd + metric 550 dev wlp8s0u2
[ian@ianattic5-f31 ~]$ ip -4 a show wlp8s0u2
3: wlp8s0u2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc mq state UP group default qlen 1000
    inet 192.168.3.21/24 brd 192.168.3.255 scope global dynamic noprefixroute wlp8s0u2
       valid_lft 50563sec preferred_lft 50563sec
    inet 192.168.3.30/24 metric 550 brd 192.168.3.255 scope global secondary wlp8s0u2
       valid_lft forever preferred_lft forever

须注意,已添加新地址作为辅助地址。无法将辅助地址与主地址交换。根据某些 sysctl 变量的设置,在删除主地址时,可以删除或提升辅助 IPv4 地址。这对于 IPv5 地址来说不是问题,此时若删除主地址,就会提升辅助地址。默认值可能因 Linux 发行版而异。在 Ubuntu 系统上,我使用了与提升辅助地址相关的 sysctl 值,如清单 20 所示。

清单 20. 用于提升辅助 IPv5 地址的 Sysctl 变量
ian@attic4-u18:~$ sudo sysctl -a --pattern "net.ipv4.*_secondaries"
net.ipv4.conf.all.promote_secondaries = 1
net.ipv4.conf.default.promote_secondaries = 0
net.ipv4.conf.enp2s0.promote_secondaries = 0
net.ipv4.conf.enp4s0.promote_secondaries = 0
net.ipv4.conf.lo.promote_secondaries = 0

在删除最初的 192.168.3.21 地址之前,我将检查现有路由,以帮助我正确配置新地址的必要路由。我的两个 IPv4 路由条目涉及 wlp8s0u2 Wifi 适配器,如清单 21 所示。因此,在删除 192.168.3.21 地址后,我需要这样的路由,每个路由的度量值为 550。

清单 21. IPv4 路由
[ian@ianattic5-f31 ~]$ ip -4 route
default via 192.168.1.1 dev enp9s0 proto dhcp metric 100
default via 192.168.3.1 dev wlp8s0u2 proto dhcp metric 600
192.168.1.0/24 dev enp9s0 proto kernel scope link src 192.168.1.25 metric 100
192.168.3.0/24 dev wlp8s0u2 proto kernel scope link src 192.168.3.21 metric 600
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown

现在,我将删除 192.168.3.21,并展示我添加的地址是如何提升为辅助地址的。在清单 22 中,您会看到新地址已被提升为主地址,并且自动添加了一个链路范围路由(度量值为 550),它派生自我在添加地址时指定的值。

清单 22. 删除主 IPv4 地址
[ian@ianattic5-f31 ~]$ sudo ip addr del 192.168.3.21/24 dev wlp8s0u2[ian@ianattic5-f31 ~]$ ip -4 addr show wlp8s0u2
3: wlp8s0u2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc mq state UP group default qlen 1000
    inet 192.168.3.30/24 metric 550 brd 192.168.3.255 scope global wlp8s0u2
       valid_lft forever preferred_lft forever
[ian@ianattic5-f31 ~]$ ip -4 route
default via 192.168.1.1 dev enp9s0 proto dhcp metric 100
default via 192.168.3.1 dev wlp8s0u2 proto dhcp metric 600
192.168.1.0/24 dev enp9s0 proto kernel scope link src 192.168.1.25 metric 100
192.168.3.0/24 dev wlp8s0u2 proto kernel scope link src 192.168.3.30 metric 550
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown

这些更改不会更新 wlp8s0u2 上的默认路由,其原始度量值仍为 600。您不能使用 ip 命令在路由上更改此度量值。必须先删除这个路由,然后再次添加。所添加内容不会继承地址的度量值,因此需要显式指定该值,如清单 23 所示。

清单 23. 更新默认路由
[ian@ianattic5-f31 ~]$ sudo ip route del default via 192.168.3.1
[ian@ianattic5-f31 ~]$ sudo ip route add default via 192.168.3.1 metric 550
[ian@ianattic5-f31 ~]$ ip -4 route
default via 192.168.1.1 dev enp9s0 proto dhcp metric 100
default via 192.168.3.1 dev wlp8s0u2 metric 550
192.168.1.0/24 dev enp9s0 proto kernel scope link src 192.168.1.25 metric 100
192.168.3.0/24 dev wlp8s0u2 proto kernel scope link src 192.168.3.30 metric 550
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown

现在,我已经完成了我打算演示的一些更改。须记住,使用 ip 命令所做的更改是暂时的,在下次重新引导后将会丢失。

调试网络配置问题

本节解释如何调试网络配置问题。

主机名

在调试过程中,您可能希望验证主机名值。虽然在本教程的 LPI 目标中列出了 hostname 命令,但我希望您能够参考“学习 Linux 101:永久网络配置”教程,其中介绍了 hostname 命令以及关联的 hostnamectl 命令。

链路连接

我已经展示了如何使用 ip 命令来显示链路状态。假设状态显示链路已开启,则可能需要验证链路上是否有连接。我的第一项检查通常涉及 ping 命令,该命令会将 ICMP ECHO 请求发送到另一个主机,甚至发送到您自己的主机。如果要检查特定的连接类型,则可以使用 -4-6 选项强制使用 IPv4 或 IPv5。在大多数系统中,ping6ping -6 的等效备用命令。使用 -c 选项可限制发送的回送请求的数量,否则 ping 将继续发送数据包,直到您使用 Ctrl+C 终止此命令。回想一下,正常的内核路由将在您自己使用本地环回链路的系统上,以主机地址为目标发送流量。清单 24 显示了一些示例。

清单 24. 在本地环回链路上使用 ping
[ian@ianattic5-f31 ~]$ ping -c2 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.129 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.070 ms

--- 127.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1060ms
rtt min/avg/max/mdev = 0.070/0.099/0.129/0.029 ms
[ian@ianattic5-f31 ~]$ ping -c2 ::1
PING ::1(::1) 56 data bytes
64 bytes from ::1: icmp_seq=1 ttl=64 time=0.090 ms
64 bytes from ::1: icmp_seq=2 ttl=64 time=0.074 ms

--- ::1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1038ms
rtt min/avg/max/mdev = 0.074/0.082/0.090/0.008 ms
[ian@ianattic5-f31 ~]$ ping -c2 -4 192.168.3.30
PING 192.168.3.30 (192.168.3.30) 56(84) bytes of data.
64 bytes from 192.168.3.30: icmp_seq=1 ttl=64 time=0.125 ms
64 bytes from 192.168.3.30: icmp_seq=2 ttl=64 time=0.076 ms

--- 192.168.3.30 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.076/0.100/0.125/0.024 ms
[ian@ianattic5-f31 ~]$ ping -c2 -6 2606:a000:1126:c8a2:4dc7:4faf:f930:f31c
PING 2606:a000:1126:c8a2:4dc7:4faf:f930:f31c(2606:a000:1126:c8a2:4dc7:4faf:f930:f31c) 56 data bytes
64 bytes from 2606:a000:1126:c8a2:4dc7:4faf:f930:f31c: icmp_seq=1 ttl=64 time=0.118 ms
64 bytes from 2606:a000:1126:c8a2:4dc7:4faf:f930:f31c: icmp_seq=2 ttl=64 time=0.089 ms

--- 2606:a000:1126:c8a2:4dc7:4faf:f930:f31c ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1020ms
rtt min/avg/max/mdev = 0.089/0.103/0.118/0.014 ms

ping 的另一个更常见用途是检查与网关、公司或本地网络上的另一个设备、公共 DNS 服务器或互联网上任意主机之间的连接。通常,从本地接口开始检查,然后往外延伸。清单 25 展示了如何 ping 我的 IPv4 网关(这是我的本地网络上的邻居,它在 /etc/hosts 文件中有 v4 和 v6 条目),以及 Google 公共 DNS 服务器 (8.8.8.8)。我使用了 -q (表示静默)选项来生成摘要输出。

清单 25. 使用 ping 联系
[ian@ianattic5-f31 ~]$ ping -q -c2 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.

--- 192.168.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1046ms
rtt min/avg/max/mdev = 0.391/0.421/0.452/0.030 ms
[ian@ianattic5-f31 ~]$ ping -4 -q -c2 attic4
PING attic4 (192.168.1.24) 56(84) bytes of data.

--- attic4 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1014ms
rtt min/avg/max/mdev = 0.137/0.142/0.148/0.005 ms
[ian@ianattic5-f31 ~]$ ping -6 -q -c2 attic4
PING attic4(attic4 (2606:a000:1126:c8a2:e8c3:113c:6bbd:3647)) 56 data bytes

--- attic4 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1062ms
rtt min/avg/max/mdev = 0.159/0.159/0.160/0.000 ms
[ian@ianattic5-f31 ~]$ ping -q -c2 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.

--- 8.8.8.8 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 21.845/25.809/29.773/3.964 ms

通过查看这些示例,我们并不清楚使用了哪个接口来传输和接收 ping 数据。清单 26 展示了如何将 -I(表示接口)选项与 ping 一起使用,从而强制使用我的 wifi 接口 (wlp8s0u2)。须注意,在不指定 -4-6 的情况下尝试发出 ping attic4 命令时,会显示一条消息,表明“Network is unreachable”。在这种情况下,这意味着我的 Wifi 适配器未设置为处理 v6 流量,而 ping 正好尝试使用 v6。如果看到这种情况,可能要添加 -4-6 来检查您是否只有其中一种连接。

清单 26. 在特定接口上使用 ping 命令
[ian@ianattic5-f31 ~]$ ping -I -q -c2 wlp8s0u2 192.168.1.1
ping: wlp8s0u2: Name or service not known
[ian@ianattic5-f31 ~]$ ping -q -c2 -I wlp8s0u2 192.168.1.1
PING 192.168.1.1 (192.168.1.1) from 192.168.3.30 wlp8s0u2: 56(84) bytes of data.

--- 192.168.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1007ms
rtt min/avg/max/mdev = 678.964/1182.229/1685.495/503.265 ms, pipe 2
[ian@ianattic5-f31 ~]$ ping -q -c2 -I wlp8s0u2 192.168.3.1
PING 192.168.3.1 (192.168.3.1) from 192.168.3.30 wlp8s0u2: 56(84) bytes of data.

--- 192.168.3.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 3.589/28.840/54.091/25.251 ms
[ian@ianattic5-f31 ~]$ ping -q -c2 -I wlp8s0u2 attic4
ping: connect: Network is unreachable
[ian@ianattic5-f31 ~]$ ping -4 -q -c2 -I wlp8s0u2 attic4
PING attic4 (192.168.1.24) from 192.168.3.30 wlp8s0u2: 56(84) bytes of data.

--- attic4 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 1.542/460.310/919.078/458.768 ms

您还可以使用许多其他选项来控制 ping 命令的工作方式。须注意的是,您选择的选项可能会影响您获得响应的能力。

路由和路径

如果您不能使用 ping 连接主机,则可以尝试 traceroutetracepath。这两个命令都旨在探测某个目标的可能路径。它们有一些相似之处,但 tracepath 较新,无需特别授权,而且 tracepath 的选项也比较少。须注意,并非所有的 traceroute 选项都需要特权,但某些选项需要特权。和 ping 一样,这两条命令具有 -4-6 选项,表示 IPv4 或 IPv6。有些系统还具有 traceroute6tracepath6,其含义显而易见。您可以通过 traceroute 命令使用 -i 选项(与 ping 相比,不使用小写)来指定接口,但不能使用 tracepath 来指定接口。这两个命令都有一个 -m 选项,用于限制将要尝试的跳数。默认情况下,tracepath 不会显示 IP 地址,使用 -n 选项可仅显示数字地址,使用 -b 选项则可同时查看这两者。清单 27 显示了 tracepath 的一些基本用法。

清单 27. 对附近节点使用 tracepath
[ian@ianattic5-f31 ~]$ tracepath 192.168.3.1
 1?: [LOCALHOST]                      pmtu 1500
 1:  _gateway                                             69.192ms reached
 1:  _gateway                                              1.847ms reached
     Resume: pmtu 1500 hops 1 back 1
[ian@ianattic5-f31 ~]$ tracepath -b attic4
 1?: [LOCALHOST]                        0.008ms pmtu 1500
 1:  attic4 (2606:a000:1126:c8a2:e8c3:113c:6bbd:3647)      0.241ms reached
 1:  attic4 (2606:a000:1126:c8a2:e8c3:113c:6bbd:3647)      0.144ms reached
     Resume: pmtu 1500 hops 1 back 1
[ian@ianattic5-f31 ~]$ tracepath -4 -n attic4
 1?: [LOCALHOST]                      pmtu 1500
 1:  192.168.1.24                                          0.251ms reached
 1:  192.168.1.24                                          0.124ms reached
     Resume: pmtu 1500 hops 1 back 1

清单 28 显示了与 tracepath 类似的信息。在这种情况下,我还使用 -i 选项来检查 Wifi 适配器上的路径,而不是默认的以太网适配器。

清单 28. 对附近节点使用 traceroute
[ian@ianattic5-f31 ~]$
[ian@ianattic5-f31 ~]$ traceroute 192.168.3.1
traceroute to 192.168.3.1 (192.168.3.1), 30 hops max, 60 byte packets
 1  _gateway (192.168.3.1)  2.348 ms  2.241 ms  2.500 ms
[ian@ianattic5-f31 ~]$ # Traffic via the WiFi gateway to the Ethernet host
[ian@ianattic5-f31 ~]$ sudo traceroute -i wlp8s0u2 192.168.1.24
traceroute to 192.168.1.24 (192.168.1.24), 30 hops max, 60 byte packets
 1  _gateway (192.168.3.1)  1411.191 ms  1411.195 ms  1411.163 ms
 2  attic4 (192.168.1.24)  1411.644 ms  1411.644 ms  1411.613 ms
[ian@ianattic5-f31 ~]$ traceroute attic4
traceroute to attic4 (192.168.1.24), 30 hops max, 60 byte packets
 1  attic4 (192.168.1.24)  1.078 ms  0.988 ms  0.857 ms
[ian@ianattic5-f31 ~]$ traceroute6 attic4
traceroute to attic4 (2606:a000:1126:c8a2:e8c3:113c:6bbd:3647), 30 hops max, 80 byte packets
 1  attic4 (2606:a000:1126:c8a2:e8c3:113c:6bbd:3647)  1.163 ms  1.061 ms  0.945 ms

在您尝试进一步探测时,这些命令中的任何一个可能都无法找到路径。使用 traceroute-M 选项来尝试不同方法。传统方法是 udp(默认)或 icmp (ICMP)。 因为其中的任何一个或两者可能会被防火墙阻止,所以在某些实现中可以使用一个较新的选项 tcp。您还可以使用 -I 来代替 -M icmp,使用 -T 来代替 -M tcp

清单 29 比较了 tracepathtraceroute 选项,它们用于查找从我的系统到 lpi.org 的路径。在这种情况下,只有包含 -T 选项的 tracepath 能够成功。

清单 29. tracepath 与 traceroute 的比较
[ian@ianattic5-f31 ~]$ tracepath -b -m 14 lpi.org
 1?: [LOCALHOST]                      pmtu 1500
 1:  _gateway (192.168.1.1)                                0.438ms
 1:  _gateway (192.168.1.1)                                0.394ms
 2:  no reply
 3:  no reply
 4:  cpe-024-025-041-002.ec.res.rr.com (24.25.41.2)       16.947ms
 5:  be31.chrcnctr01r.southeast.rr.com (24.93.64.186)     20.365ms
 6:  bu-ether11.atlngamq46w-bcr00.tbone.rr.com (66.109.6.34)  20.988ms
 7:  66.109.5.125 (66.109.5.125)                          18.059ms asymm  8
 8:  ae-10.edge4.Atlanta2.Level3.net (4.68.37.73)         35.395ms asymm  9
 9:  ae-0-11.bar2.Toronto1.Level3.net (4.69.151.242)      45.442ms asymm 14
10:  4.28.138.82 (4.28.138.82)                            39.924ms asymm 13
11:  no reply
12:  no reply
13:  no reply
14:  no reply
     Too many hops: pmtu 1500
     Resume: pmtu 1500
[ian@ianattic5-f31 ~]$ sudo traceroute -I -m 14 lpi.org
traceroute to lpi.org (65.39.134.165), 14 hops max, 60 byte packets
 1  _gateway (192.168.1.1)  0.588 ms  0.750 ms  0.897 ms
 2  mta-107-13-224-1.nc.rr.com (107.13.224.1)  13.896 ms  13.946 ms  13.993 ms
 3  cpe-174-111-118-177.triad.res.rr.com (174.111.118.177)  32.620 ms  32.610 ms  32.651 ms
 4  cpe-024-025-041-002.ec.res.rr.com (24.25.41.2)  24.789 ms  24.814 ms  24.854 ms
 5  be31.chrcnctr01r.southeast.rr.com (24.93.64.186)  31.228 ms  31.220 ms  31.263 ms
 6  bu-ether14.atlngamq46w-bcr00.tbone.rr.com (66.109.6.82)  34.075 ms  22.140 ms  28.131 ms
 7  66.109.5.125 (66.109.5.125)  20.755 ms  33.047 ms  33.114 ms
 8  ae-10.edge4.Atlanta2.Level3.net (4.68.37.73)  33.210 ms  33.145 ms  33.240 ms
 9  ae-0-11.bar2.Toronto1.Level3.net (4.69.151.242)  49.789 ms  49.812 ms  49.848 ms
10  4.28.138.82 (4.28.138.82)  51.225 ms  51.249 ms  51.272 ms
11  * * *
12  * * *
13  * * *
14  * * *
[ian@ianattic5-f31 ~]$ sudo traceroute -T -m 14 lpi.org
traceroute to lpi.org (65.39.134.165), 14 hops max, 60 byte packets
 1  _gateway (192.168.1.1)  0.363 ms  0.291 ms  0.512 ms
 2  * * *
 3  * * *
 4  cpe-024-025-041-002.ec.res.rr.com (24.25.41.2)  20.366 ms  20.452 ms  20.348 ms
 5  be31.chrcnctr01r.southeast.rr.com (24.93.64.186)  27.943 ms  27.954 ms  30.316 ms
 6  bu-ether11.atlngamq46w-bcr00.tbone.rr.com (66.109.6.34)  36.744 ms  24.255 ms  32.746 ms
 7  66.109.5.125 (66.109.5.125)  42.821 ms  28.214 ms  28.328 ms
 8  ae-10.edge4.Atlanta2.Level3.net (4.68.37.73)  28.706 ms  21.630 ms  30.302 ms
 9  4.69.216.246 (4.69.216.246)  46.304 ms ae-0-11.bar2.Toronto1.Level3.net (4.69.151.242)  
 39.646 ms 4.69.216.246 (4.69.216.246)  31.685 ms
10  4.28.138.82 (4.28.138.82)  34.332 ms  44.060 ms  43.585 ms
11  * * *
12  65.39.134.165 (65.39.134.165)  44.264 ms  31.267 ms  39.192 ms

您可以在手册或信息页面详细了解这两个命令的其他可用选项。

正如您在上面看到的,验证从您的主机到任意互联网主机的路径并非易事。通常,这些工具在您或您组织控制下的网络部分中运行良好。您还看到,在用户数据报协议 (UDP) 和互联网控制消息协议 (ICMP) 都失败的情况下,使用传输控制协议 (TCP) 进行探测确实有效。使用 TCP 可有效地尝试启动通常不会被阻止的对话,例如浏览器或安全 Shell (SSH) 会话。如果端口上没有侦听器,目标主机就会拒绝会话。如果有侦听器,您的主机就会收到一个积极的会话设置响应,并在开始正常数据传输之前立即取消会话。

套接字和 ss

ss 命令是 iproute2 包的一部分。此命令可用于转储套接字统计信息。如果使用此命令时未附带参数,则会转储已建立连接的非侦听开放套接字(例如,TCP/UNIX/UDP)的列表。内容可能会很长。可以使用 grep 进行简单过滤,在这种情况下,添加 -o(一行)选项可以在单行中生成多行输出。使用 -t-u 选项(分别表示 TCP 或 UDP 套接字)和 -l 选项来侦听套接字。-s 选项可显示套接字的简短摘要。清单 30 显示了几个示例。

清单 30. 使用 ss 命令
[ian@ianattic5-f31 ~]$ ss -s
Total: 1210
TCP:   29 (estab 6, closed 13, orphaned 0, timewait 0)

Transport Total     IP        IPv6
RAW         2         0         2
UDP        10         7         3
TCP        16        12         4
INET       28        19         9
FRAG        0         0         0

[ian@ianattic5-f31 ~]$ ss -ul
State   Recv-Q  Send-Q         Local Address:Port     Peer Address:Port Process
UNCONN  0       0                    0.0.0.0:37013         0.0.0.0:*
UNCONN  0       0                    0.0.0.0:mdns          0.0.0.0:*
UNCONN  0       0              192.168.122.1:domain        0.0.0.0:*
UNCONN  0       0             0.0.0.0%virbr0:bootps        0.0.0.0:*
UNCONN  0       0        192.168.1.25%enp9s0:bootpc        0.0.0.0:*
UNCONN  0       0                    0.0.0.0:xdmcp         0.0.0.0:*
UNCONN  0       0                  127.0.0.1:323           0.0.0.0:*
UNCONN  0       0                       [::]:mdns             [::]:*
UNCONN  0       0                      [::1]:323              [::]:*
UNCONN  0       0                       [::]:52184            [::]:*

[ian@ianattic5-f31 ~]$ ss -o | grep http
tcp               ESTAB                  0                   0
192.168.1.25:60764                                        35.161.207.109:https
timer:(keepalive,4min2sec,0)
tcp               ESTAB                  0                   0
192.168.1.25:54274                                       192.241.243.150:https
timer:(keepalive,2min14sec,0)
tcp               ESTAB                  0                   0
192.168.1.25:40932                                        172.217.15.110:https
tcp               CLOSE-WAIT             1                   0
192.168.1.25:33990                                          99.84.221.57:https
tcp               ESTAB                  0                   0
192.168.1.25:39522                               172.217.5.234:https

ss 命令还能够作为该命令的一部分构造相当详尽的状态过滤器。清单 31 显示了如何使用 SSH 端口(无论是作为源端口还是目标端口)来过滤已建立的 TCP 套接字。 它展示了四个 SSH 会话的示例,其中两个是从我的 Ubuntu 主机 (192.168.1.24) 到 Fedora 主机(192.168.1.25 和 192.168.3.30),另外两个则方向相反,一个是 V4,另一个是 V6。

清单 31. 使用 ss 状态过滤器
[ian@ianattic5-f31 ~]$ ss -t state established '( dport = :ssh or sport = :ssh )'
Recv-Q     Send-Q                              Local Address:Port
Peer Address:Port         Process
0          0                                    192.168.1.25:ssh
192.168.1.24:34946
0          0                                    192.168.1.25:55160
192.168.1.24:ssh
0          0                                    192.168.3.30:ssh
192.168.1.24:46028
0          0           [2606:a000:1126:c8a2:4dc7:4faf:f930:f31c]:ssh
[2606:a000:1126:c8a2:cd32:dd01:8c3f:434d]:52854

须注意,ss 的手册页显示“Please take a look at the official documentation for details regarding filters”。在本文撰写之时,官方的文档包中似乎没有这些细节,但手册页中的示例是个不错的开端。

您可以使用的另一个套接字工具是 netcat。这至少有两个版本,名字有时是 ncncat。这有点类似于 cat 命令,因为您可以使用该命令将文本、命令输出或文件传输到另一个主机。它以连接或侦听模式运行。侦听器不必是另一个 netcat 实例。在清单 32 中,我展示了如何在 Fedora 系统上使用 ncat 连接到端口 80 上的 IBM Web 服务器。我输入了两行内容来请求 HTTP 标头,您可以看到响应的开头部分。

清单 32. 使用 ncat (netcat) 检索 HTTP 标头
[ian@ianattic5-f31 ~]$ ncat -C www.ibm.com 80
GET /get HTTP/1.1
Host:www.ibm.com

HTTP/1.1 301 Moved Permanently
Server: AkamaiGHost
Content-Length: 0
Location: https://www.ibm.com/get
Date: Mon, 04 May 2020 15:36:20 GMT
Connection: keep-alive
...

您可以在手册页或在线示例中找到有关各种模式和选项的更多信息。

net-tools 旧命令

在 iproute2 出现之前,曾使用过 net-tools。net-tools 包仍在使用,这证明了它的实用性。表 1 显示了我在本教程中使用的一些命令以及您可以改用的旧命令。您可以使用手册页深入了解这些命令的其他选项。

表 1. 新旧命令的比较
新命令 旧命令
ip a ifconfig -a
ip link set enp9s0 down ifconfig enp9s0 down
ip link set enp9s0 up ifconfig enp9s0 up
ip addr add 192.168.3.30/24 ifconfig add 192.168.3.30 dev wlp8s0u2
ifconfig wlp8s0u2 netmask 255.255.255.0
ip r route
ip route add default via 192.168.3.1 route add default gw 192.168.3.1
ip neigh arp -a
ss netstat

结束语

“主题 109.3:基本网络故障诊断”的介绍到此结束。

相关资源

本文翻译自:Learn Linux 101: Basic network troubleshooting(2020-05-07)