第 5 章 网络设置

# 第 5 章 网络设置

| 提示
关于 Debian 专属的网络手册，请查看 Debian 管理员手册—网络配置。

| 提示
systemd 环境下，可以用 networkd 来配置网络。请参考 systemd-networkd(8)。

## 5.1. 基本网络架构

让我们来回顾一下现代 Debian 操作系统中的基本网络架构。

表 5.1. 网络配置工具一览表

软件包 | 流行度 | 大小 | 类型 | 说明
--- | --- | --- | --- | ---
`network-manager` | V:422, I:469 | 7021 | 配置：：NM | NetworkManager（守卫进程）：自动管理网络
`network-manager-gnome` | V:39, I:156 | 18 | 配置：：NM | NetworkManager（GNOME前端）
`netplan.io` | V:1.4, I:8.6 | 340 | 配置：：NM+networkd | Netplan (生成器): 统一的，声明网络接口到 NetworkManager 和 systemd-networkd 后端
`ifupdown` | V:640, I:972 | 201 | 配置：：ifupdown | 用来启动/关闭网络的标准工具（Debian特有）
`pppoeconf` | V:0.2, I:4.0 | 176 | 配置：：辅助 | 配置助手，以便于使用PPPoE连接
`wpasupplicant` | V:411, I:513 | 3896 | 配置：：辅助 | WPA和WPA2客户端支持（IEEE 802.11i)
`wpagui` | V:0.2, I:1.4 | 779 | 配置：：辅助 | wpa_supplicant Qt 图形界面客户端
`wireless-tools` | V:190, I:260 | 232 | 配置：：辅助 | 操控Linux无线扩展的工具
`iw` | V:38, I:472 | 332 | 配置：：辅助 | 配置 Linux 无线设备的工具
`iproute2` | V:775, I:987 | 4123 | 配置：：iproute2 | iproute2, IPv6和其他高级网络配置：ip(8),tc(8)等等
`iptables` | V:382, I:642 | 2408 | 配置：：Netfilter | 封包过滤和网络地址转换管理工具（Netfilter）
`nftables` | V:254, I:872 | 189 | 配置：：Netfilter | 封包过滤和网络地址转换管理工具（Netfilter） ({ip,ip6,arp,eb}tables 的后续替代者)
`iputils-ping` | V:198, I:998 | 188 | 测试 | 测试能否连接远程主机，通过主机名或IP 地址（iproute2）
`iputils-arping` | V:2, I:18 | 53 | 测试 | 测试能否连接远程主机，通过ARP地址
`iputils-tracepath` | V:2, I:21 | 50 | 测试 | 跟踪访问远程主机的路径
`ethtool` | V:97, I:254 | 1093 | 测试 | 显示或更改以太网设备的设定
`mtr-tiny` | V:4, I:39 | 182 | 测试：：底层 | 追踪连接远程主机的路径（文本界面）
`mtr` | V:4, I:41 | 231 | 测试：：底层 | 追踪连接远程主机的路径（文本界面和GTK界面）
`gnome-nettool` | V:0.5, I:9.1 | 2480 | 测试：：底层 | 获取常见网络信息的工具（GNOME)
`nmap` | V:25, I:186 | 4759 | 测试：：底层 | 网络映射/端口扫描（Nmap，控制台）
`tcpdump` | V:19, I:177 | 1346 | 测试：：底层 | 网络流量分析（Tcpdump，控制台）
`wireshark` | V:4, I:39 | 17068 | 测试：：底层 | 网络流量分析（Wireshark,GTK）
`tshark` | V:2, I:24 | 433 | 测试：：底层 | 网络流量分析(控制台）
`tcptrace` | V:0.2, I:1.7 | 407 | 测试：：底层 | 根据`tcpdump`的输出生成的连接数据统计
`dnsutils` | V:5, I:156 | 23 | 测试：：底层 | BIND 软件包提供的网络客户端程序：nslookup(8),nsupdate(8),dig(8)
`dlint` | V:0.1, I:2.1 | 52 | 测试：：底层 | 利用域名服务器查询来查看 DNS 域信息
`dnstracer` | V:0.1, I:1.1 | 63 | 测试：：底层 | 跟踪 DNS 查询直至源头

### 5.1.1. 主机名解析

主机名解析，目前也是由 NSS (名字服务转换 Name Service Switch) 机制来支持。这个解析的流程如下。

1. "`/etc/nsswitch.conf`" 文件里的 "`hosts: files dns`" 这段规定主机名解析顺序。 (代替 "`/etc/host.conf`" 文件里的"`order`" 这段原有的功能。)

2. `files` 方式首先被调用。如果主机名在 "`/etc/hosts`" 文件里面发现，则返回所有有效地址并退出。 ( "`/etc/host.conf`" 文件包含 "`multi on`".)

3. `dns` 方式被调用。如果主机名通过查询 "`/etc/resolv.conf`" 文件里面写的 互联网域名系统 Domain Name System (DNS) 来找到，则返回所有有效地址并退出。

一个典型的工作站在安装时就会设置主机名，例如"host_name"和设置为空字符串的可选域名。这样，"`/etc/hosts`"看起来像下文所示的这样。

    127.0.0.1 localhost
    127.0.1.1 host_name

    # The following lines are desirable for IPv6 capable hosts
    ::1     localhost ip6-localhost ip6-loopback
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters

每一行由 IP 地址 开始，接下来是相关联的主机名.

在这个例子的第二行 `127.0.1.1` IP 地址也许不会在其它类 Unix 系统发现。Debian Installer 为没有永久 IP 地址的系统创建这个条目，作为某些软件（如 GNOME）的一个变通方法，见文档 bug #719621.

host_name 匹配在"`/etc/hostname`"里定义的主机名。(参见 第 3.8.1 节 “主机名”)。

对于有永久 IP 地址的系统，这个永久 IP 地址应当代替这里的 `127.0.1.1`。

对于有永久 IP 地址和有 域名系统 Domain Name System (DNS)提供完全资格域名 fully qualified domain name (FQDN) 的系统，规范名 host_name.domain_name 应当被用来代替 host_name.

如果 `resolvconf` 软件包没有安装，"`/etc/resolv.conf`" 是一个静态文件。如果安装了，它是一个符号链接。此外，它包含有解析策略的初始化信息。如 DNS 是 IP="`192.168.11.1`",则包含如下。

    nameserver 192.168.11.1

`resolvconf` 软件包使这个 "`/etc/resolv.conf`" 文件成为一个符号链接，并通过钩子脚本自动管理其内容。

对于典型 adhoc 局域网环境下的 PC 工作站，除了基本的 `files` 和 `dns` 方式之外，主机名还能够通过 Multicast DNS (mDNS)进行解析。

- Avahi 提供 Debian 下的组播 DNS 发现框架。

- 它和 Apple Bonjour / Apple Rendezvous 相当.

- `libnss-mdns` 插件包提供 mDNS 的主机名解析，GNU C 库 (glibc)的 GNU 名字服务转换 Name Service Switch (NSS) 功能支持 mDNS。

- "`/etc/nsswitch.conf`" 文件应当有像 "`hosts: files mdns4_minimal [NOTFOUND=return] dns`" 这样的一段(其它配置参见 `/usr/share/doc/libnss-mdns/README.Debian`)。

- 一个使用 ".local" pseudo-top-level domain 后缀的主机名解析，是用 IPv4 地址 "`224.0.0.251`" 或 IPv6 地址 "`FF02::FB`"发送一个组播 UDP 包的 mDNS 查询信息。

| 注意
域名系统 Domain Name System 中的扩展通用顶级域名 expansion of generic Top-Level Domains (gTLD) 还在进行中。在局域网内，选择一个域名时，请提防名字冲突 name collision。

| 注意
使用软件包，比如 `libnss-resolve` 联合 `systemd-resolved`, 或者 `libnss-myhostname`, 或者 `libnss-mymachine`, 并在 "`/etc/nsswitch.conf`" 文件里面的 "`hosts`" 行里相应列出 mymachines 或 myhostname 关键字，这将忽略我们上面讨论的传统网络配置。更多信息参见 nss-resolve(8)、systemd-resolved(8)、nss-myhostname(8)和 nss-mymachines(8)。

### 5.1.2. 网络接口名称

systemd 使用"`enp0s25`" 之类的 "可预测网络接口名称"。

### 5.1.3. 局域网网络地址范围

让我们重新提醒下在 rfc1918 里规定的局域网 local area networks (LANs)IPv4 32 位地址在各类地址的保留范围. 这些地址保证不会与因特网上专有的地址冲突。

| 注意
IP 地址书写中有冒号的是 IPv6 地址，例如，"`::1`" 是 `localhost 本地主机`。

表 5.2. 网络地址范围列表

类别 | 网络地址 | 子网掩码 | 子网掩码/位数 | 子网数
--- | --- | --- | --- | ---
A | 10.x.x.x | 255.0.0.0 | /8 | 1
B | 172.16.x.x — 172.31.x.x | 255.255.0.0 | /16 | 16
C | 192.168.0.x — 192.168.255.x | 255.255.255.0 | /24 | 256

| 注意
如果这些地址分配到一个主机，那么这个主机一定不能够直接访问互联网，必须通过一个作为网关的代理服务或通过 网络地址转换 Network Address Translation (NAT). 消费局域网环境，宽带路由器通常使用 NAT。

### 5.1.4. 网络设备支持

尽管 Debian 系统支持大多数硬件设备，但依旧有一些网络设备需要 DFSG non-free 固件来支持它们。参见 第 9.10.5 节 “硬件驱动和固件”。

## 5.2. 现代的桌面网络配置

对于使用 `systemd` 的现代 Debian 桌面系统，网络接口通常由两个服务进行初始化：`lo` 接口通常在“`networking.service`”处理，而其它接口则由“`NetworkManager.service`”处理。

Debian 可以通过后台守护进程（daemon）管理软件来管理网络连接，例如 NetworkManager (NM)（network-manager 和相关软件包）。

- 它们有自己的 GUI 和命令行程序来作为用户界面。

- 它们有自己的后台守护进程（daemon）作为它们的系统后端。

- 它们使你可以简单地将系统连接到网络。

- 它们使你可以简单地管理有线和无线网络的配置。

- 它们允许你配置网络而不依赖传统的 `ifupdown` 软件包。

| 注意
不要在服务器上使用这些自动网络配置工具。它们主要针对于笔记本电脑上的移动桌面用户。

这些现代的网络配置工具需要进行适当的配置，以避免与传统 `ifupdown` 软件包发生冲突，它的配置文件位于 “`/etc/network/interfaces`”。

### 5.2.1. 图形界面的网络配置工具

Debian 系统 NM 的官方文档位于 “`/usr/share/doc/network-manager/README.Debian`” 。

本质上，如下操作即可完成桌面的网络配置。

1. 通过下列命令使桌面用户 `foo` 归属 “`netdev`” 组（另外，例如 GNOME 和 KDE 这样的现代桌面环境会通过 D-bus 自动完成该操作）。

       $ sudo usermod -a -G netdev foo

2. 使 “`/etc/network/interfaces`” 的配置保持下面那样简洁。

       auto lo
       iface lo inet loopback

3. 通过下列命令重新启动 NM。

       $ sudo systemctl restart NetworkManager

4. 通过图形界面配置网络。

| 注意
只有不列在 “`/etc/network/interfaces`” 中的接口会被 NM 管理，以避免与 `ifupdown` 的冲突。

| 提示
如果你想扩展 NM 的网络配置功能，请寻找适当的插件模块和补充软件包，例如 `network-manager-openconnect`、`network-manager-openvpn-gnome`、`network-manager-pptp-gnome`、`mobile-broadband-provider-info`、`gnome-bluetooth` 等等。

## 5.3. 没有图像界面的现代网络配置

使用 systemd 的系统中，可以在 `/etc/systemd/network/` 里配置网络。参见 systemd-resolved(8)、resolved.conf(5) 和 systemd-networkd(8)。

这个允许在没有图像界面的情况下配置现代网络。

DHCP 客户端的配置可以通过创建 "`/etc/systemd/network/dhcp.network`" 文件来进行设置。例如：

    [Match]
    Name=en*

    [Network]
    DHCP=yes

一个静态网络配置能够通过创建 "`/etc/systemd/network/static.network`" 来设置.比如：

    [Match]
    Name=en*

    [Network]
    Address=192.168.0.15/24
    Gateway=192.168.0.1

## 5.4. 现代云网络配置

云的现代网络配置可以使用 `cloud-init` 和 `netplan.io` 软件包(参见 第 3.8.4 节 “云系统初始化”)。

`netplan.io` 软件包支持把 `systemd-networkd` 和 `NetworkManager` 作为它的网络配置后端，能够使用 YAML 数据声明网络配置。当你改变 YAML:

- 运行 "`netplan generate`" 命令，从 YAML 生成所有必须的后端配置。

- 运行 "`netplan apply`" 命令应用生成的配置到后端。

参见 "Netplan documentation", netplan(5), netplan-generate(8)和 netplan-apply(8)。

也可以参见 "Cloud-init documentation" (特别是围绕 "Configuration sources" 和 "Netplan Passthrough") 了解 `cloud-init` 是怎样能够集成替代的数据源到`netplan.io` 配置。

### 5.4.1. 使用 DHCP 的现代云网络配置

DHCP 客户端的配置可以通过创建一个数据源文件"`/etc/netplan/50-dhcp.yaml`"来进行设置：

    network:
      version: 2
      ethernets:
        all-en:
          match:
            name: "en*"
          dhcp4: true
          dhcp6: true

### 5.4.2. 使用静态 IP 的现代云网络配置

一个静态网络配置能够通过创建一个数据源文件 "`/etc/netplan/50-static.yaml`"来设置：

    network:
      version: 2
      ethernets:
        eth0:
          addresses:
            - 192.168.0.15/24
          routes:
            - to: default
              via: 192.168.0.1

### 5.4.3. 使用 Network Manager 的现代云网络配置

使用 Network Manager 架构的网络客户端配置，可以通过创建一个数据源文件 "`/etc/netplan/00-network-manager.yaml`"来进行设置：

    network:
      version: 2
      renderer: NetworkManager

## 5.5. 底层网络配置

在 Linux 上的底层网络配置，使用 iproute2 程序 (ip(8), …) .

### 5.5.1. Iproute2 命令

Iproute2 命令集提供完整的底层网络配置能力。有个从旧的 net-tools 命令集到新的 iproute2 命令集的转换表。

表 5.3. 从旧的 `net-tools` 命令集到新的 `iproute2` 命令集转换表

旧的 net-tools | 新的 iproute2 | 操作
--- | --- | ---
ifconfig(8) | `ip addr` | 一个设备上的协议（IP 或 IPv6）地址
route(8) | `ip route` | 路由表条目
arp(8) | `ip neigh` | ARP 或 NDISC 缓存条目
`ipmaddr` | `ip maddr` | 多播地址
`iptunnel` | `ip tunnel` | IP 隧道
nameif(8) | ifrename(8) | 基于 MAC 地址的网络接口名
mii-tool(8) | ethtool(8) | 以太网设备设置

参见 ip(8) 和 Linux 高级路由和流量控制（Linux Advanced Routing & Traffic Control）.

### 5.5.2. 安全的底层网络操作

你可以按下面的方式安全的使用底层网络命令，这些命令不会改变网络配置。

表 5.4. 底层网络命令列表

命令 | 说明
--- | ---
`ip addr show` | 显示活动的网络接口连接和地址状态
`route -n` | 用数字地址显示全部路由表
`ip route show` | 用数字地址显示全部路由表
`arp` | 显示当前 ARP 缓存表的内容
`ip neigh` | 显示当前 ARP 缓存表的内容
`plog` | 显示 ppp 后台守护进程（daemon）日志
`ping yahoo.com` | 检查到 "`yahoo.com`" 的因特网连接
`whois yahoo.com` | 在域名数据库里面检查谁注册了 "`yahoo.com`"
`traceroute yahoo.com` | 跟踪到 "`yahoo.com`" 的因特网连接
`tracepath yahoo.com` | 跟踪到 "`yahoo.com`" 的因特网连接
`mtr yahoo.com` | 跟踪到 "`yahoo.com`" 的因特网连接（重复的）
`dig [@dns-server.com] example.com [{a|mx|any}]` | 查询由 "`dns-server.com`" 提供服务的 "`example.com`" 域名的 DNS 记录： "`a`", "`mx`" 或 "`any`" 记录
`iptables -L -n` | 查看包过滤
`ss -a` | 找出所有打开的端口
`ss -l` | 找出监听端口
`ss -l -t -n` | 找出 TCP 监听端口（数字的）
`dlint example.com` | 查询 "`example.com`" 的 DNS zone 信息

| 提示
部分底层网络配置工具放在 "`/usr/sbin/`" 目录。你可以像 "`/usr/sbin/ifconfig`" 这样使用完整命令路径，或把 "`/usr/sbin`" 加到 "`~/.bashrc`" 文件列出的 "`$PATH`" 环境变量里 。

## 5.6. 网络优化

通用的网络优化超出了本文的范围。我提及消费等级连接相关的主题。

表 5.5. 网络优化工具列表

软件包 | 流行度 | 大小 | 说明
--- | --- | --- | ---
`iftop` | V:6, I:88 | 93 | 显示一个网络接口上的带宽使用信息
`iperf` | V:2, I:34 | 431 | 互联网协议带宽测量工具
`ifstat` | V:0.6, I:5.5 | 52 | 接口统计监控
`bmon` | V:2, I:20 | 141 | 便携式带宽监视器和网速估计工具
`ethstatus` | V:0.2, I:2.6 | 41 | 快速测量网络设备吞吐的脚本
`bing` | V:0.07, I:0.50 | 80 | 实验性的随机带宽测试器
`bwm-ng` | V:1.0, I:9.6 | 95 | 小巧简单的控制台带宽监测器
`ethstats` | V:0.05, I:0.39 | 21 | 基于控制台的以太网统计监视器
`ipfm` | V:0.04, I:0.11 | 78 | 带宽分析工具

### 5.6.1. 找出最佳 MTU

网络管理器通常会自动设置最佳 最大传输单元 (MTU) 。

在一些场景中，在用 ping(8) 加上"`-M do`"选项发送各种大小的 ICMP 报文数据包进行实验后，你希望可以手动设置 MTU。MTU 是最大可完成没有 IP 分片的数据包大小加上 28 字节（IPv4）或 48 字节（IPv6）。下面的列子，发现 IPv4 连接的 MTU 是 1460，IPv6 连接的 MTU 是 1500。

    $ ping -4 -c 1 -s $((1500-28)) -M do www.debian.org
    PING  (149.20.4.15) 1472(1500) bytes of data.
    ping: local error: message too long, mtu=1460

    ---  ping statistics ---
    1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

    $ ping -4 -c 1 -s $((1460-28)) -M do www.debian.org
    PING  (130.89.148.77) 1432(1460) bytes of data.
    1440 bytes from klecker-misc.debian.org (130.89.148.77): icmp_seq=1 ttl=50 time=325 ms

    ---  ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 325.318/325.318/325.318/0.000 ms
    $ ping -6 -c 1 -s $((1500-48)) -M do www.debian.org
    PING www.debian.org(mirror-csail.debian.org (2603:400a:ffff:bb8::801f:3e)) 1452 data bytes
    1460 bytes from mirror-csail.debian.org (2603:400a:ffff:bb8::801f:3e): icmp_seq=1 ttl=47 time=191 ms

    --- www.debian.org ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 191.332/191.332/191.332/0.000 ms

这个过程是 路径 MTU (PMTU) 发现 (RFC1191) ， tracepath(8) 命令能够自动完成这个。

表 5.6. 最佳 MTU 值的基本指引方法

网络环境 | MTU | 基本原理
--- | --- | ---
拨号连接(IP: PPP) | 576 | 标准的
以太网连接 (IP: DHCP 或固定) | 1500 | 默认标准值

除了这些基本的指引方法外，你还应当知道下面的信息。

- 使用任何隧道方式(VPN 等.)的最佳 MTU 需要进一步减去它们上面的头部。

- MTU 值不应当超过通过实验验证的 PMTU 值。

- 当遇到其它限制的时候，较大的 MTU 值通常比较好。

最大分片大小 (MSS) 是另外一种衡量包大小的方法。MSS 和 MTU 的关系如下.

- 对于 IPv4， MSS = MTU - 40

- 对于 IPv6，MSS = MTU - 60

| 注意
基于 iptables(8) (参见 第 5.7 节 “Netfilter 网络过滤框架”) 的优化，能够通过 MSS 来压缩包大小，路由器会用到 MMS 。参见 iptables(8)中的"TCPMSS" .

### 5.6.2. WAN TCP 优化

现代大带宽和高延时的 WAN，TCP 吞吐量能够通过调整 TCP 缓冲大小的参数，在"TCP 调整"里，来最大化。到目前为止，当前 Debian 默认设置能够很好的服务好我的 1G bps 光纤到户 LAN 连接。

## 5.7. Netfilter 网络过滤框架

Netfilter 使用 Linux 内核 模块 (参见 第 3.10 节 “内核模块初始化”) 提供 状态防火墙 和 网络地址转换 (NAT) 框架。

表 5.7. 防火墙工具列表

软件包 | 流行度 | 大小 | 说明
--- | --- | --- | ---
`nftables` | V:254, I:872 | 189 | 封包过滤和网络地址转换管理工具（Netfilter） ({ip,ip6,arp,eb}tables 的后续替代者)
`iptables` | V:382, I:642 | 2408 | netfilter 管理工具(iptables(8) 用于 IPv4, ip6tables(8) 用于 IPv6)
`arptables` | V:0.1, I:1.8 | 102 | netfilter 管理工具(arptables(8) 用于 ARP)
`ebtables` | V:14, I:24 | 276 | netfilter 管理工具 (ebtables(8) 用于以太网桥)
`iptstate` | V:0.2, I:1.7 | 121 | 持续性监控 netfilter 状态 (和 top(1) 相似)
`ufw` | V:82, I:109 | 862 | Uncomplicated Firewall (UFW) 是一个管理 netfilter 防火墙的程序
`gufw` | V:6, I:11 | 3682 | Uncomplicated Firewall (UFW) 的图像用户界面
`firewalld` | V:14, I:22 | 2581 | firewalld 是一个动态管理防火墙的程序，支持网络区域
`firewall-config` | V:0.7, I:3.3 | 1096 | firewalld 图像用户界面
`shorewall-init` | V:0.18, I:0.40 | 88 | Shoreline 防火墙 初始化
`shorewall` | V:2.2, I:5.0 | 3090 | Shoreline 防火墙, netfilter 配置文件生成器
`shorewall-lite` | V:0.02, I:0.06 | 71 | Shoreline 防火墙, netfilter 配置文件生成器 (精简版)
`shorewall6` | V:0.7, I:1.3 | 1334 | Shoreline 防火墙, netfilter 配置文件生成器(IPv6 版本)
`shorewall6-lite` | V:0.01, I:0.02 | 71 | Shoreline 防火墙, netfilter 配置文件生成器 (IPv6,精简版)

See The netfilter.org "nftables" project for the newer user space nft(8) command in the `nftables` package. (Linux kernel >= 3.13)

See The netfilter.org "iptables" project for the older user space iptables(8) and similar commands in the `iptables` and similar packages. (Linux kernel >= 2.4.x)

You can manually configure netfilter interactively from shell, save its state with "`nft list ruleset > file`" or iptables-save(8), and restore it via init script with "`nft -f file`" or iptables-restore(8) upon system reboot.

像 shorewall 这样的配置帮助脚本能够使这个过程变得更简单。

参见 Netfilter 文档 上的文档(或在 "`/usr/share/doc/iptables/html/`" 里面的文档)。

- Linux Networking-concepts HOWTO

- Linux 2.4 Packet Filtering HOWTO

- Linux 2.4 NAT HOWTO

- nftables HOWTO

第 4 章 认证和访问控制 |  | 第 6 章 网络应用