# 练习 24：接口配置，`ifconfig`，`netstat`，`iproute2`，`ss`，`route`

> 原文：[Exercise 24. Networking: interface configuration, ifconfig, netstat, iproute2, ss, route](https://archive.fo/JzBji)

> 译者：[飞龙](https://github.com/wizardforcel)

> 协议：[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)

> 自豪地采用[谷歌翻译](https://translate.google.cn/)

这个练习对于你来说是一个很大的信息量，如果你不熟悉网络，这就是一个伤害。如果你感到非常失落，请立即跳到“这样做”的部分，并完成它。为了正确理解这部分，你至少应该非常熟悉网络的以下基本概念：

+   [通信协议](http://en.wikipedia.org/wiki/Communications_protocol) - 通信协议，就是数字消息格式和规则的系统，用于在计算系统或在电子通讯中交换那些消息。
+   [以太网](http://en.wikipedia.org/wiki/Ethernet) - 用于局域网（LAN）的计算机网络技术族。
+   [MAC 地址](http://en.wikipedia.org/wiki/MAC_address) - 分配给物理网段上通信的网络接口的唯一标识符。例如：` 08:00:27:d4:45:68`。
+   [TCP/IP](http://en.wikipedia.org/wiki/Internet_protocol_suite) - 互联网协议套件是一组通信协议，用于互联网和类似网络，通常是广域网最流行的协议栈。它通常被称为 TCP/IP，由于其最重要的协议：传输控制协议（TCP）和互联网协议（IP）
+   [IP](http://en.wikipedia.org/wiki/Internet_Protocol) - 互联网协议（IP）是主要通信协议，用于跨互联网络中继转发数据报（也称为网络封包）。
+   [IP 地址](http://en.wikipedia.org/wiki/IP_address) - 互联网协议地址。示例：`10.0.2.15`
+   [端口](http://en.wikipedia.org/wiki/Port_(computer_networking)) - 应用特定或流程特定的软件结构，在计算机的主机操作系统中用作通信端点。示例：`22`
+   [网络套接字](http://en.wikipedia.org/wiki/Network_socket) - 跨计算机网络的，进程间通信流的端点。今天，大多数计算机之间的通信基于互联网协议；因此大多数网络套接字都是互联网套接字。
+   本地套接字地址 - 本地 IP 地址和端口号，例如：`10.0.2.15:22`。
+   远程套接字地址 - 远程 IP 地址和端口号，仅适用于已建立的 TCP 套接字。示例：`10.0.2.2:52173`。
+   [套接字对](http://en.wikipedia.org/wiki/Network_socket%23Socket_pairs) - 沟通本地和远程套接字，只有 TCP 协议。示例：`(10.0.2.15:22, 10.0.2.2:52173)`。
+   [子网掩码](http://en.wikipedia.org/wiki/Subnetwork) - 逻辑可见的 IP 网络细分。示例：`/24`或另一个记号`255.255.255.0`。
+   [路由](http://en.wikipedia.org/wiki/Routing) - 在网络中选择路径，来发送网络流量的过程。
+   [默认网关](http://en.wikipedia.org/wiki/Default_gateway) - 在计算机网络中，网关是一个 TCP/IP 网络上的节点（路由器），作为另一个网络的接入点。默认网关是计算机网络上的节点，当 IP 地址与路由表中的任何其他路由不匹配时，网络软件使用它。示例：`10.0.2.2`。
+   [广播地址](http://en.wikipedia.org/wiki/Broadcast_address) - 逻辑地址，其中连接到多重访问的网络的设备能接收数据报。发给广播地址的消息，通常会由所有附加到网络的主机接收，而不是特定主机。示例：`10.0.2.255`。
+   [ICMP](http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol) - 互联网消息控制协议，示例用法：`ping 10.0.2.2`。
+   [TCP](http://en.wikipedia.org/wiki/Transmission_Control_Protocol) - 传输控制协议。在数据交换之前建立连接，因此设计上可靠。示例：SSH, HTTP。
+   [UDP](http://en.wikipedia.org/wiki/User_Datagram_Protocol) - 用户数据报协议。传输数据而不建立连接，因此设计上不可靠。示例：DNS。

如果你对某些概念不熟悉，不用担心。

+   阅读相应的维基百科文章，直到你至少充分理解（但是深入钻研当然更好）。
+   观看 <http://www.visualland.net.cn/> 的视频：
    +   展开站点左侧的 IP 地址树节点，并通过它来以你的方式实现。
    +   展开 TCP 树节点并执行相同操作。
+   阅读 [Linux 网络概念介绍](http://www.iptables.org/documentation/HOWTO//networking-concepts-HOWTO-3.html%23ss3.1)。这本指南很好，因为它甚至承认 互联网是为情欲而生的。

让我们继续。这是 Linux 网络相关的命令列表：

+   `ifconfig` - 配置和查看网络接口的状态。
+   `netstat` - 打印网络连接，路由表，接口统计信息，伪装连接和组播成员资格。
+   `ip` - 显示/操做路由，设备，策略和隧道。
+   `ss` - 调查套接字的另一个实用程序。

现在让我们来看看每个命令可以告诉我们什么信息。我们将从`ifconfig`开始。

```
user1@vm1:~$ sudo ifconfig
 
eth0      Link encap:Ethernet  HWaddr 08:00:27:d4:45:68               # (1), (2), (3)
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0   # (4), (5), (6), (7)
          inet6 addr: fe80::a00:27ff:fed4:4568/64 Scope:Link          # (8), (9), (10)
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1          # (11), (12), (13), (14), (15), (16)
          RX packets:35033 errors:0 dropped:0 overruns:0 frame:0      # (17), (18), (19), (20), (21), (22)
          TX packets:28590 errors:0 dropped:0 overruns:0 carrier:0    # (23), (24), (25), (26), (27), (28)
          collisions:0 txqueuelen:1000                                # (29), (30)
          RX bytes:6360747 (6.0 MiB)  TX bytes:21721365 (20.7 MiB)   # (31), (32)
 
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:560 (560.0 B)  TX bytes:560 (560.0 B)
```

我们可以看到`vm1`中有两个网络接口，`eth0`和`lo`。`lo`是一个回送 接口，用于连接同一台机器上的客户端-服务器程序。

让我们看看我们在`eth0`上有哪些信息，它是一个 VirtualBox 的伪网络接口：

| 字段 | 描述 | 字段 | 描述 |
| --- | --- | --- | --- |
| (1) Link | 物理选项 | (17) RX | 接收（缩写） |
| (2) encap | 封装类型 | (18) packets | 封包总数 |
| (3) Hwaddr | MAC 地址 | (19) errors | 错误的数据包总数 |
| (4) inet | 地址族（IPv4） | (20) dropped | 丢弃的封包（低系统内存？） |
| (5) addr | IPv4 地址 | (21) overruns | 比处理速度快的封包 |
| (6) Bcast | 广播地址 | (22) frame | 接收的无效的帧 |
| (7) Mask | 网络掩码 | (23) TX | 传输（缩写） |
| (8) inet6 | 地址族（IPv6） | (24) packets | 封包总数 |
| (9) addr | IPv6 地址 | (25) errors | 错误的数据包总数 |
| (10) Scope | 地址范围（主机，链路，全局） | (26) dropped | 丢弃的封包（低系统内存？） |
| (11) UP | 接口功能正常 | (27) overruns | 比处理速度快的封包（我不确定） |
| (12) BROADCAST | 它可以一次性向所有主机发送流量 | (28) carrier | 链路载波丢失 |
| (13) RUNNING | 它准备好接受数据（我不确定） | (29) collisions | 发生了包装碰撞 |
| (14) MULTICAST | 它可以发送和接收组播封包 | (30) txqueuelen | 传出数据包的转发队列长度 |
| (15) MTU | 其最大传输单位 | (31) RX bytes | 收到的字节总数 |
| (16) Metric | 路由开销（在 Linux 中未使用） | (32) TX bytes | 发送的字节总数 |

这确实很多。但是同样，现在的重要字段是：

+   (5) `addr` - IPv4地址。
+   (6) `Bcast` - 广播地址。
+   (7) `Mask ` - 网络掩码。
+   (11) `UP` - 接口正常工作。
+   (13) `RUNNING` - 准备好接受数据。
+   (19) `errors` 和 (25) `errors` - 如果在这里有不为零的东西，我们就有问题了。

现在让我们看看`netstat`能给我们看的东西。

```
user1@vm1:~$ sudo netstat -ap
Active Internet connections (servers and established)
#(1)  (2)    (3)    (4)                     (5)                     (6)         (7)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 *:sunrpc                *:*                     LISTEN      580/portmap
tcp        0      0 *:ssh                   *:*                     LISTEN      900/sshd
tcp        0      0 localhost:smtp          *:*                     LISTEN      1111/exim4
tcp        0      0 *:36286                 *:*                     LISTEN      610/rpc.statd
tcp        0      0 10.0.2.15:ssh           10.0.2.2:52191          ESTABLISHED 12023/sshd: user1 [
tcp        0      0 10.0.2.15:ssh           10.0.2.2:48663          ESTABLISHED 11792/sshd: user1 [
tcp6       0      0 [::]:ssh                [::]:*                  LISTEN      900/sshd
tcp6       0      0 ip6-localhost:smtp      [::]:*                  LISTEN      1111/exim4
udp        0      0 *:bootpc                *:*                                 843/dhclient
udp        0      0 *:sunrpc                *:*                                 580/portmap
udp        0      0 *:52104                 *:*                                 610/rpc.statd
udp        0      0 *:786                   *:*                                 610/rpc.statd
#(8)  (9)    (10)        (11)       (12)          (13)     (14)                (15)
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node   PID/Program name    Path
unix  2      [ ACC ]     STREAM     LISTENING     3452     786/acpid           /var/run/acpid.socket
unix  6      [ ]         DGRAM                    3407     751/rsyslogd        /dev/log
unix  2      [ ]         DGRAM                    1940     214/udevd           @/org/kernel/udev/udevd
unix  2      [ ]         DGRAM                    88528    30939/sudo
unix  3      [ ]         STREAM     CONNECTED     68565    12023/sshd: user1 [
unix  3      [ ]         STREAM     CONNECTED     68564    12026/1
unix  2      [ ]         DGRAM                    68563    12023/sshd: user1 [
unix  3      [ ]         STREAM     CONNECTED     66682    11792/sshd: user1 [
unix  3      [ ]         STREAM     CONNECTED     66681    11794/0
unix  2      [ ]         DGRAM                    66680    11792/sshd: user1 [
unix  2      [ ]         DGRAM                    3465     843/dhclient
unix  2      [ ]         DGRAM                    3448     786/acpid
unix  3      [ ]         DGRAM                    1945     214/udevd
unix  3      [ ]         DGRAM                    1944     214/udevd
```

我使用两个参数来修改`netstat`输出。`-a`参数告诉`netstat`来显示所有的连接，包括建立的，例如你当前正在打字的`ssh`会话，以及监听的，例如等待新的连接的`sshd`守护进程。`-p`告诉`netstat`来显示哪个程序拥有每个连接。

| 活动互联网连接（服务器和已建立） | |
| --- | --- |
| 字段 | 描述 |
| (1) Proto | 套接字使用的协议（tcp，udp，raw） |
| (2) Recv-Q | 连接到此套接字的用户程序的未复制的字节数 |
| (3) Send-Q | 远程主机未确认的字节数 |
| (4) Local Address | 套接字的本端的地址和端口号。 |
| (5) Foreign Address | 套接字远端的地址和端口号。 |
| (6) State | `ESTABLISHED`, `SYN_SENT`, `SYN_RECV`, `FIN_WAIT1`, `FIN_WAIT2`, `TIME_WAIT`, `CLOSE`, `CLOSE_WAIT`, `LAST_ACK`, `LISTEN`, `CLOSING`, `UNKNOWN` |
| (7) PID | 拥有套接字的进程的进程 ID（PID）和进程名称的斜杠对。 |
| 活动 UNIX 域套接字（服务器和已建立） |
| 字段 | 描述 |
| (8) Proto | 套接字使用的协议（通常为 unix）。 |
| (9) RefCnt | 引用计数（即附加到此套接字的进程）。 |
| (10) Flags | 显示的标志是`SO_ACCEPTON`（显示为`ACC`），`SO_WAITDATA`（`W`）或`SO_NOSPACE`（`N`）。 |
| (11) Type | `SOCK_DGRAM`, `SOCK_STREAM`, `SOCK_RAW`, `SOCK_RDM`, `SOCK_SEQPACKET`, `SOCK_PACKET`, `UNKNOWN`. |
| (12) State | `FREE`, `LISTENING`, `CONNECTING`, `CONNECTED`, `DISCONNECTING`, `(empty)`, `UNKNOWN`. |
| (13) I-Node | 套接字文件的索引节点。 |
| (14) PID | 打开套接字的进程的进程 ID（PID）和进程名称。 |
| (15) Path | 这是连接到套接字的对应进程的路径名。 |

并非所有字段都是重要的。通常你只需要查看活动的互联网连接（服务器和已建立） 部分，并使用以下字段：

（1）`Proto` - 套接字使用的协议（tcp，udp，raw）。
（4）`Local Address` - 套接字本端的地址和端口号。
（5）`Foreign Address` - 套接字远端的地址和端口号，仅用于套接字对。
（6）`State` - 现在你只应该知道两个状态：`LISTEN`和`ESTABLISHED`。前者意味着你可以连接到这个套接字，第后者的意思是这个套接字已经连接了，在这种情况下，`netstat`显示你的套接字对。

`ip`是一个类似于`ifconfig`的，具有扩展功能的程序。它来自`iproute2`套件，用于在某一天替换`ifconfig`。示例输出：

```
user1@vm1:~$ sudo ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
#        (1)        (2)      (3) (4)       (5)      (6)              (8)      (9)
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:d4:45:68 brd ff:ff:ff:ff:ff:ff      # (9),  (10), (11)
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0      # (12), (13), (14)
    inet6 fe80::a00:27ff:fed4:4568/64 scope link            # (15), (16)
       valid_lft forever preferred_lft forever              # (17), (18), (19)
```

同样，我们来看看我们在`eth0`上有什么信息：

| 字段 | 描述 |
| --- | --- |
| (1) BROADCAST | 它可以一次性向所有主机发送流量 |
| (2) MULTICAST | 它可以发送和接收组播数据包 |
| (3) UP | 它是生效的，逻辑状态 |
| (4) LOWER_UP | 驱动器信号 L1 已开启（自 Linux 2.6.17 起） |
| (5) MTU | 最大传输单位 |
| (6) qdisc | 排队规则，基本上是流量调度策略 |
| (8) State | 物理状态（载体感觉？） |
| (9) qlen | 传出数据包的转发队列长度 |
| (10) link | 物理选项 |
| (11) ether | 封装类型，MAC 地址 |
| (12) brd | 数据链路层（物理）广播地址 |
| (13) inet | IPv4 地址族地址 |
| (14) brd | IPv4 广播 |
| (15) scope | IPv4地址范围（主机，链路，全局） |
| (16) inet6 | IPv6 地址族地址 |
| (17) scope | IPv6地址范围（主机，链路，全局） |
| (18) valid_lft | IPv6 源地址选择策略 |
| (19) preffered_lft | IPv6 源地址选择策略 |

你已经知道哪些参数很重要（与`ifconfig`相同）。

`ss`基本上是具有扩展功能的当代`netstat`。这是它的示例输出，其解释为留作练习：

```
user1@vm1:~$ sudo ss -ap | cut -c1-200
State      Recv-Q Send-Q    Local Address:Port      Peer Address:Port
LISTEN     0      128                   *:sunrpc               *:*        users:(("portmap",580,5))
LISTEN     0      128                  :::ssh                 :::*        users:(("sshd",900,4))
LISTEN     0      128                   *:ssh                  *:*        users:(("sshd",900,3))
LISTEN     0      20                  ::1:smtp                :::*        users:(("exim4",1111,4))
LISTEN     0      20            127.0.0.1:smtp                 *:*        users:(("exim4",1111,3))
LISTEN     0      128                   *:36286                *:*        users:(("rpc.statd",610,7))
ESTAB      0      0             10.0.2.15:ssh           10.0.2.2:52191    users:(("sshd",12023,3),("sshd",12026,3))
ESTAB      0      0             10.0.2.15:ssh           10.0.2.2:48663    users:(("sshd",11792,3),("sshd",11794,3))
```

这用于处理接口，连接和接口地址。但是网络路由呢？你也可以使用几个命令获取它们的信息：

```
user1@vm1:~$ sudo route -n
Kernel IP routing table
# (1)           (2)             (3)             (4)   (5)    (6)    (7) (8)
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.2.0        *               255.255.255.0   U     0      0        0 eth0
default         10.0.2.2        0.0.0.0         UG    0      0        0 eth0
user1@vm1:~$ sudo netstat -nr
Kernel IP routing table #                                           (9)
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
10.0.2.0        0.0.0.0         255.255.255.0   U         0 0          0 eth0
0.0.0.0         10.0.2.2        0.0.0.0         UG        0 0          0 eth0
user1@vm1:~$ sudo ip route show
# (10)      (11)      (12)          (13)        (14)
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15
#(15)                (16)
default via 10.0.2.2 dev eth0
```

让我们再一次看看字段：

| 字段 | 描述 |
| --- | --- |
| (1) Destination | 目标网络或目标主机。 |
| (2) Gateway | 网关地址或`*`，如果没有设置的话。 |
| (3) Genmask | 目标网络的掩码；`255.255.255.255`为主机目标，`0.0.0.0`为默认路由。 |
| (4) Flags | Up, Host, Gateway, Reinstate, Dynamically installed, Modified, Addrconf, Cache entry, ! reject. |
| (5) Metric | 目标的“距离”（通常以跳数计算）。最近的内核不使用它，但路由守护进程可能需要它。 |
| (6) Ref | 这个路由的引用次数（在 Linux 内核中未使用）。 |
| (7) Use | 路由查询次数。 |
| (8) Iface | 用于这个路由的，发送封包的接口 |
| (9) irtt | 初始 RTT（往返时间）。内核使用它来猜测最佳的 TCP 协议参数，而无需等待（可能很慢）的答案。 |
| (10) Net/Mask | 目标网络或目标主机。 |
| (11) dev | 用于这个路由的，发送封包的接口 |
| (12) proto | `man ip /RTPROTO`: redirect, kernel, boot, static, ra |
| (13) scope | `man ip /SCOPE_WALUE`: global, site, link, host |
| (14) src | 发送到路由前缀覆盖的目标时，优先选择的源地址。 |
| (15) default | 默认网关地址 |
| (15) dev | 用于这个路由的，发送封包的接口 |

目前的重要字段：

+   （1）`Destination` - 目标网络或目标主机。
+   （2）`Gateway` - 网关地址或`*`，如果没有设置的话。默认值意味着，如果没有明确指定的目标地址的网关，则将通过该网关发送数据包。
+   （3）`Genmask` - 目标网络的网络掩码；`255.255.255.255`为主机目标，`0.0.0.0`为默认路由。
+   （8）`Iface` - 用于这个路由的，发送封包的接口。


`netstat`和`route`的哪个字段对应于`ip route show ·的哪个字段 ，再次留作一个练习。这真是太多了！深吸一口气，让我们转到实践。

现在你将学习如何创建伪接口，为其分配地址并更改其状态。

## 这样做

```
 1: sudo aptitude install uml-utilities
 2: sudo tunctl -t tap0 -u user1
 3: ls -al /sys/devices/virtual/net/tap0
 4: sudo ifconfig tap0 10.1.1.1 netmask 255.255.255.0
 5: sudo ifconfig
 6: sudo route
 7: ping 10.1.1.1 -c 2
 8: sudo ifconfig tap0 down
 9: ping 10.1.1.1 -c 2
10: sudo ifconfig tap0 up
11: sudo ip a a 10.2.2.2/24 brd + dev tap0
12: sudo ifconfig
13: sudo route
14: ip a s
15: ip r s
16: ping 10.2.2.2 -c 2
17: sudo ip link set dev tap0 down
18: ip a s
19: ip r s
20: ping 10.2.2.2 -c 2
21: sudo tunctl -d tap0
22: ip a s
23: ls -al /sys/devices/virtual/net/tap0
```

## 你会看到什么

```
user1@vm1:~$ sudo aptitude install uml-utilities
The following NEW packages will be installed:
  libfuse2{a} uml-utilities
0 packages upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/205 kB of archives. After unpacking 737 kB will be used.
Do you want to continue? [Y/n/?]
Selecting previously deselected package libfuse2.
(Reading database ... 39616 files and directories currently installed.)
Unpacking libfuse2 (from .../libfuse2_2.8.4-1.1_amd64.deb) ...
Selecting previously deselected package uml-utilities.
Unpacking uml-utilities (from .../uml-utilities_20070815-1.1_amd64.deb) ...
Processing triggers for man-db ...
Setting up libfuse2 (2.8.4-1.1) ...
Setting up uml-utilities (20070815-1.1) ...
Starting User-mode networking switch: uml_switch.
user1@vm1:~$ sudo tunctl -t tap0 -u user1
Set 'tap0' persistent and owned by uid 1000
user1@vm1:~$ ls -al /sys/devices/virtual/net/tap0
total 0
drwxr-xr-x 4 root root    0 Jul 11 05:33 .
drwxr-xr-x 4 root root    0 Jul 11 05:33 ..
-r--r--r-- 1 root root 4096 Jul 11 05:33 address
-r--r--r-- 1 root root 4096 Jul 11 05:33 addr_len
-r--r--r-- 1 root root 4096 Jul 11 05:33 broadcast
-r--r--r-- 1 root root 4096 Jul 11 05:33 carrier
-r--r--r-- 1 root root 4096 Jul 11 05:33 dev_id
-r--r--r-- 1 root root 4096 Jul 11 05:33 dormant
-r--r--r-- 1 root root 4096 Jul 11 05:33 duplex
-r--r--r-- 1 root root 4096 Jul 11 05:33 features
-rw-r--r-- 1 root root 4096 Jul 11 05:33 flags
-r--r--r-- 1 root root 4096 Jul 11 05:33 group
-rw-r--r-- 1 root root 4096 Jul 11 05:33 ifalias
-r--r--r-- 1 root root 4096 Jul 11 05:33 ifindex
-r--r--r-- 1 root root 4096 Jul 11 05:33 iflink
-r--r--r-- 1 root root 4096 Jul 11 05:33 link_mode
-rw-r--r-- 1 root root 4096 Jul 11 05:33 mtu
-r--r--r-- 1 root root 4096 Jul 11 05:33 operstate
-r--r--r-- 1 root root 4096 Jul 11 05:33 owner
drwxr-xr-x 2 root root    0 Jul 11 05:33 power
-r--r--r-- 1 root root 4096 Jul 11 05:33 speed
drwxr-xr-x 2 root root    0 Jul 11 05:33 statistics
lrwxrwxrwx 1 root root    0 Jul 11 05:33 subsystem -> ../../../../class/net
-r--r--r-- 1 root root 4096 Jul 11 05:33 tun_flags
-rw-r--r-- 1 root root 4096 Jul 11 05:33 tx_queue_len
-r--r--r-- 1 root root 4096 Jul 11 05:33 type
-rw-r--r-- 1 root root 4096 Jul 11 05:33 uevent
user1@vm1:~$ sudo ifconfig tap0 10.1.1.1 netmask 255.255.255.0
user1@vm1:~$ sudo ifconfig
eth0      Link encap:Ethernet  HWaddr 08:00:27:d4:45:68
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fed4:4568/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:64040 errors:0 dropped:0 overruns:0 frame:0
          TX packets:44578 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:19663646 (18.7 MiB)  TX bytes:25043918 (23.8 MiB)
 
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:76 errors:0 dropped:0 overruns:0 frame:0
          TX packets:76 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:6272 (6.1 KiB)  TX bytes:6272 (6.1 KiB)
 
tap0      Link encap:Ethernet  HWaddr ee:d8:2e:f6:bc:f1
          inet addr:10.1.1.1  Bcast:10.1.1.255  Mask:255.255.255.0
          inet6 addr: fe80::ecd8:2eff:fef6:bcf1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:1 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
 
user1@vm1:~$ sudo route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.2.0        *               255.255.255.0   U     0      0        0 eth0
10.1.1.0        *               255.255.255.0   U     0      0        0 tap0
default         10.0.2.2        0.0.0.0         UG    0      0        0 eth0
user1@vm1:~$ ping 10.1.1.1 -c 2
PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_req=1 ttl=64 time=0.070 ms
64 bytes from 10.1.1.1: icmp_req=2 ttl=64 time=0.027 ms
 
--- 10.1.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.027/0.048/0.070/0.022 ms
user1@vm1:~$ sudo ifconfig tap0 down
user1@vm1:~$ ping 10.1.1.1 -c 2
PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_req=1 ttl=64 time=0.030 ms
64 bytes from 10.1.1.1: icmp_req=2 ttl=64 time=0.024 ms
 
--- 10.1.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.024/0.027/0.030/0.003 ms
user1@vm1:~$ sudo ifconfig tap0 up
user1@vm1:~$ sudo ip a a 10.2.2.2/24 brd + dev tap0
user1@vm1:~$ sudo ifconfig
eth0      Link encap:Ethernet  HWaddr 08:00:27:d4:45:68
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fed4:4568/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:64088 errors:0 dropped:0 overruns:0 frame:0
          TX packets:44609 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:19667480 (18.7 MiB)  TX bytes:25049771 (23.8 MiB)
 
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:84 errors:0 dropped:0 overruns:0 frame:0
          TX packets:84 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:6944 (6.7 KiB)  TX bytes:6944 (6.7 KiB)
 
tap0      Link encap:Ethernet  HWaddr ee:d8:2e:f6:bc:f1
          inet addr:10.1.1.1  Bcast:10.1.1.255  Mask:255.255.255.0
          inet6 addr: fe80::ecd8:2eff:fef6:bcf1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:9 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
user1@vm1:~$ sudo route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.2.2.0        *               255.255.255.0   U     0      0        0 tap0
10.0.2.0        *               255.255.255.0   U     0      0        0 eth0
10.1.1.0        *               255.255.255.0   U     0      0        0 tap0
default         10.0.2.2        0.0.0.0         UG    0      0        0 eth0
user1@vm1:~$ ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:d4:45:68 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
    inet6 fe80::a00:27ff:fed4:4568/64 scope link
       valid_lft forever preferred_lft forever
12: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 500
    link/ether ee:d8:2e:f6:bc:f1 brd ff:ff:ff:ff:ff:ff
    inet 10.1.1.1/24 brd 10.1.1.255 scope global tap0
    inet 10.2.2.2/24 brd 10.2.2.255 scope global tap0
    inet6 fe80::ecd8:2eff:fef6:bcf1/64 scope link
       valid_lft forever preferred_lft forever
user1@vm1:~$ ip r s
10.2.2.0/24 dev tap0  proto kernel  scope link  src 10.2.2.2
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15
10.1.1.0/24 dev tap0  proto kernel  scope link  src 10.1.1.1
default via 10.0.2.2 dev eth0
user1@vm1:~$ ping 10.2.2.2 -c 2
PING 10.2.2.2 (10.2.2.2) 56(84) bytes of data.
64 bytes from 10.2.2.2: icmp_req=1 ttl=64 time=0.081 ms
64 bytes from 10.2.2.2: icmp_req=2 ttl=64 time=0.025 ms
 
--- 10.2.2.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.025/0.053/0.081/0.028 ms
user1@vm1:~$ sudo ip link set dev tap0 down
user1@vm1:~$ ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:d4:45:68 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
    inet6 fe80::a00:27ff:fed4:4568/64 scope link
       valid_lft forever preferred_lft forever
12: tap0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN qlen 500
    link/ether ee:d8:2e:f6:bc:f1 brd ff:ff:ff:ff:ff:ff
    inet 10.1.1.1/24 brd 10.1.1.255 scope global tap0
    inet 10.2.2.2/24 brd 10.2.2.255 scope global tap0
user1@vm1:~$ ip r s
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15
default via 10.0.2.2 dev eth0
user1@vm1:~$ ping 10.2.2.2 -c 2
PING 10.2.2.2 (10.2.2.2) 56(84) bytes of data.
64 bytes from 10.2.2.2: icmp_req=1 ttl=64 time=0.037 ms
64 bytes from 10.2.2.2: icmp_req=2 ttl=64 time=0.024 ms
 
--- 10.2.2.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.024/0.030/0.037/0.008 ms
user1@vm1:~$ sudo tunctl -d tap0
Set 'tap0' nonpersistent
user1@vm1:~$ ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:d4:45:68 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
    inet6 fe80::a00:27ff:fed4:4568/64 scope link
       valid_lft forever preferred_lft forever
user1@vm1:~$ ls -al /sys/devices/virtual/net/tap0
ls: cannot access /sys/devices/virtual/net/tap0: No such file or directory
user1@vm1:~$
```

## 解释

1.  安装使用伪（虚拟）接口的软件包。
1.  创建伪接口`tap0`。
1.  打印为此接口创建的，虚拟目录的内容，其中包含其设置和统计信息。
1.  将 IP 地址`10.1.1.1/24`添加到`tap0`。
1.  打印当前接口状态。
1.  打印当前路由表条目。请注意，Linux 自动为`tap0`添加新路由。
1.  通过向其发送 ICMP 回显请求数据包来测试`tap0`。
1.  将`tap0`设为`DOWN`状态（停用）。
1.  通过再次发送 ICMP 回显请求数据包来测试`tap0`。会有额外的附加题来解释为什么这个仍然可以工作，尽管已经停用了。
1.  将`tap0`设为`UP`状态（启用）。
1.  向`tap0`添加额外的IP地址`10.2.2.2/24`。`ip aa`是`ip addr add`的缩写版本。这个`+`的含义，你会在附加题中自己发现它。
1.  打印当前接口状态。注意`ifconfig`无法列出使用`ip`工具添加的新 IP 地址。为什么？留作附加题。
1.  打印当前路由表。请注意，Linux 自动为`tap0`添加了一条路由。
1.  使用`ip`工具打印当前接口状态。你可以在这里看到新添加的地址。
1.  使用`ip`工具打印我们的路由表。
1.  通过向其发送 ICMP 回显请求报文，来测试`net tap0`的 IP 地址。
1.  将`tap0`设为`DOWN`状态。
1.  打印当前接口状态。
1.  打印当前路由表条目。请注意，`tap0`路由将自动删除。
1.  通过向其发送 ICMP 回显请求报文，来测试`net tap0`的 IP 地址。这个有用，为什么？
1.  删除伪接口`tap0`。
1.  打印当前接口状态。`tap0`不存在
1.  告诉我们，`tap0`虚拟目录现在也没有了。

## 附加题

+   熟悉`man ifconfig`，`man ip`，`man netstat`，`man ss`。
+   当`tap0`处于关闭状态时，为什么`ping`有用？
+   `brd +`的意思是什么？
+   为什么`ifconfig`无法列出使用`ip`添加的新地址？
