# 7.3.有线网络

待加载了正确的驱动程序，就需要配置网络适配器。FreeBSD 使用驱动程序名称后跟一个单元号来命名网络接口适配器。单元号表示适配器在启动时被检测到的顺序，或者稍后发现的顺序。

例如，`em0` 是系统中使用 [em(4)](https://man.freebsd.org/cgi/man.cgi?query=em\&sektion=4\&format=html) 驱动程序的第一个网络接口卡（NIC）。

要显示网络接口配置，输入以下命令：

```sh
% ifconfig
```

输出应类似于以下内容：

```sh
em0: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=481249b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,LRO,WOL_MAGIC,VLAN_HWFILTER,NOMAP>
        ether 00:1f:16:0f:27:5a
        inet6 fe80::21f:16ff:fe0f:275a%em0 prefixlen 64 scopeid 0x1
        inet 192.168.1.19 netmask 0xffffff00 broadcast 192.168.1.255
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active
        nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
        inet 127.0.0.1 netmask 0xff000000
        groups: lo
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
```

在这个例子中，显示了以下设备：

* `em0`：以太网接口。
* `lo0`：回环接口是一种软件回环机制，可以用于性能分析、软件测试/本地通信。更多信息请参考 [lo(4)](https://man.freebsd.org/cgi/man.cgi?query=lo\&sektion=4\&format=html)。

该例子显示 `em0` 已经启动并在运行。

关键指示项是：

1. `UP` 表示接口已配置并准备就绪。
2. 接口具有 IPv4 地址（`inet`），`192.168.1.19`。
3. 接口具有 IPv6 地址（`inet6`），`fe80::21f:16ff:fe0f:275a%em0`。
4. 它有一个有效的子网掩码（`netmask`），其中 `0xffffff00` 等同于 `255.255.255.0`。
5. 它有一个有效的广播地址，`192.168.1.255`。
6. 接口的 MAC 地址（`ether`）是 `00:1f:16:0f:27:5a`。
7. 物理媒体选择处于自动选择模式（`media: Ethernet autoselect (1000baseT <full-duplex>)`）。
8. 链接状态（`status`）为 `active`，表示检测到载波信号。对于 `em0`，当以太网电缆未插入接口时，`status: no carrier` 状态是正常的。

如果 [ifconfig(8)](https://man.freebsd.org/cgi/man.cgi?query=ifconfig\&sektion=8\&format=html) 输出类似于以下内容，则表示接口未配置：

```sh
em0: flags=8822<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=481249b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,LRO,WOL_MAGIC,VLAN_HWFILTER,NOMAP>
        ether 00:1f:16:0f:27:5a
        media: Ethernet autoselect
        status: no carrier
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
```

## 7.3.1. 配置静态 IPv4 地址

本节提供了在 FreeBSD 系统上配置静态 IPv4 地址的指南。

可以通过命令行使用 [ifconfig(8)](https://man.freebsd.org/cgi/man.cgi?query=ifconfig\&sektion=8\&format=html) 来执行网络接口卡配置，但除非将配置添加到 /etc/rc.conf 中，否则在重启后不会保留。

> **注意**
>
> 如果在安装过程中通过 [bsdinstall(8)](https://man.freebsd.org/cgi/man.cgi?query=bsdinstall\&sektion=8\&format=html) 配置了网络，可能已经有了某些网卡（NIC）的条目。在执行 [sysrc(8)](https://man.freebsd.org/cgi/man.cgi?query=sysrc\&sektion=8\&format=html) 之前，请仔细检查 /etc/rc.conf。

可以通过执行以下命令设置 IP 地址：

```sh
# ifconfig em0 inet 192.168.1.150/24
```

要使更改在重启后保持，可以执行以下命令：

```sh
# sysrc ifconfig_em0="inet 192.168.1.150 netmask 255.255.255.0"
```

添加默认路由，执行以下命令：

```sh
# sysrc defaultrouter="192.168.1.1"
```

将 DNS 记录添加到 /etc/resolv.conf：

```ini
nameserver 8.8.8.8
nameserver 8.8.4.4
```

然后通过执行以下命令重启 `netif` 和 `routing` 服务：

```sh
# service netif restart && service routing restart
```

可以使用 [ping(8)](https://man.freebsd.org/cgi/man.cgi?query=ping\&sektion=8\&format=html) 测试连接：

```sh
% ping -c2 www.FreeBSD.org
```

输出应类似于以下内容：

```sh
PING web.geo.FreeBSD.org (147.28.184.45): 56 data bytes
64 bytes from 147.28.184.45: icmp_seq=0 ttl=51 time=55.173 ms
64 bytes from 147.28.184.45: icmp_seq=1 ttl=51 time=53.093 ms

--- web.geo.FreeBSD.org ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 53.093/54.133/55.173/1.040 ms
```

## 7.3.2. 配置动态 IPv4 地址

如果网络中有 DHCP 服务器，配置网络接口使用 DHCP 非常简单。FreeBSD 使用 [dhclient(8)](https://man.freebsd.org/cgi/man.cgi?query=dhclient\&sektion=8\&format=html) 作为 DHCP 客户端。[dhclient(8)](https://man.freebsd.org/cgi/man.cgi?query=dhclient\&sektion=8\&format=html) 会自动提供 IP 地址、子网掩码和默认路由。

要使接口使用 DHCP，执行以下命令：

```sh
# sysrc ifconfig_em0="DHCP"
```

可以通过手动运行以下命令使用 [dhclient(8)](https://man.freebsd.org/cgi/man.cgi?query=dhclient\&sektion=8\&format=html)：

```sh
# dhclient em0
```

输出应类似于以下内容：

```sh
DHCPREQUEST on em0 to 255.255.255.255 port 67
DHCPACK from 192.168.1.1
unknown dhcp option value 0x7d
bound to 192.168.1.19 -- renewal in 43200 seconds.
```

这样可以验证使用 DHCP 进行地址分配是否正常工作。

```sh
# sysrc background_dhclient="YES"
```

然后重启 `netif`，执行以下命令：

```sh
# service netif restart
```

可以使用 [ping(8)](https://man.freebsd.org/cgi/man.cgi?query=ping\&sektion=8\&format=html) 测试连接：

```sh
% ping -c2 www.FreeBSD.org
```

输出应类似于以下内容：

```sh
PING web.geo.FreeBSD.org (147.28.184.45): 56 data bytes
64 bytes from 147.28.184.45: icmp_seq=0 ttl=51 time=55.173 ms
64 bytes from 147.28.184.45: icmp_seq=1 ttl=51 time=53.093 ms

--- web.geo.FreeBSD.org ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 53.093/54.133/55.173/1.040 ms
```

## 7.3.3. IPv6

IPv6 是著名的 IP 协议的新版本，也被称为 IPv4。

与 IPv4 相比，IPv6 提供了许多优势和新特性：

* 其 128 位地址空间允许拥有 340,282,366,920,938,463,463,374,607,431,768,211,456 个地址。这解决了 IPv4 地址短缺和最终耗尽的问题。
* 路由器仅在其路由表中存储网络聚合地址，从而将路由表的平均大小减少到 8192 条目。这解决了与 IPv4 相关的可扩展性问题，IPv4 需要每个分配的地址块在互联网路由器之间交换，导致路由表变得过大，无法进行有效路由。
* 地址自动配置（[RFC4862](http://www.ietf.org/rfc/rfc4862.txt)）。
* 强制使用多播地址。
* 内建 IPsec（IP 安全）。
* 简化的头部结构。
* 支持移动 IP。
* IPv6 到 IPv4 的过渡机制。

FreeBSD 包含 [KAME 项目](http://www.kame.net/) 的 IPv6 参考实现，并附带了使用 IPv6 所需的一切。

本节将重点介绍如何配置和启用 IPv6。

IPv6 地址有三种不同类型：

* **单播（Unicast）**：发送到单播地址的数据包到达属于该地址的接口。
* **任播（Anycast）**：这些地址在语法上与单播地址相同，但它们表示一组接口。发往任播地址的数据包将到达距离最近的接口。
* **多播（Multicast）**：这些地址标识一组接口。发送到多播地址的数据包将到达属于该多播组的所有接口。IPv4 的广播地址（通常是 `xxx.xxx.xxx.255`）在 IPv6 中由多播地址表示。

阅读 IPv6 地址时，规范形式表示为 `xxxx:x`，其中每个 `x` 代表 16 位十六进制值。示例：`FEBC:A574:382B:23C1:AA49:4592:4EFE:9982`。

通常，一个地址会有很长的零子串。可以使用 `::`（双冒号）来替换地址中的一个子串。另外，每个十六进制值最多可以省略三个前导零。例如，`fe80::1` 等同于规范形式 `fe80:0000:0000:0000:0000:0000:0000:0001`。

另一种形式是使用已知的 IPv4 表示法来写最后 32 位。例如，`2002::10.0.0.1` 对应的十六进制规范表示为 `2002:0000:0000:0000:0000:0000:0a00:0001`，这又等同于 `2002::a00:1`。

要查看 FreeBSD 系统的 IPv6 地址，执行以下命令：

```sh
# ifconfig
```

输出应类似于以下内容：

```sh
em0: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=481249b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,LRO,WOL_MAGIC,VLAN_HWFILTER,NOMAP>
        ether 00:1f:16:0f:27:5a
        inet 192.168.1.150 netmask 0xffffff00 broadcast 192.168.1.255
        inet6 fe80::21f:16ff:fe0f:275a%em0 prefixlen 64 scopeid 0x1
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active
        nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
```

在此示例中，`em0` 接口使用 `fe80::21f:16ff:fe0f:275a%em0`，这是一个自动配置的链路本地地址，自动从 MAC 地址生成。

某些 IPv6 地址是保留的。可以查看下表了解保留地址的列表：

| IPv6 地址                    | 描述              | 备注                                  |
| -------------------------- | --------------- | ----------------------------------- |
| `::/128`                   | 未指定             | 相当于 IPv4 中的 `0.0.0.0`。              |
| `::1/128`                  | 回环地址            | 相当于 IPv4 中的 `127.0.0.1`。            |
| `::ffff:0.0.0.0/96`        | IPv4 映射 IPv6 地址 | 低 32 位是 IPv4 地址，用于与 IPv4 主机和路由器的兼容。 |
| `fe80::/10`                | 链路本地单播          | 相当于 IPv4 中的 169.254.0.0/16。         |
| `fc00::/7`                 | 唯一本地地址          | 唯一本地地址用于本地通信，只能在一组协作站点内路由。          |
| `ff00::/8`                 | 多播              |                                     |
| `2000::/3`                 | 全局单播            | 所有全局单播地址都从该地址池中分配。前三位比特是 `001`。     |
| `2001:db8::/32, 3fff::/20` | 文档使用            | 用于文档的 IPv6 地址前缀。                    |

有关 IPv6 地址结构的更多信息，请参阅 [RFC4291](http://www.ietf.org/rfc/rfc4291.txt)。

## 7.3.4. 配置静态 IPv6 地址

要将 FreeBSD 系统配置为 IPv6 客户端并使用静态 IPv6 地址，必须设置 IPv6 地址。

执行以下命令以满足要求：

```sh
# sysrc ifconfig_em0_ipv6="inet6 2001:db8:4672:6565:2026:5043:2d42:5344 prefixlen 64"
```

要指定默认路由器地址，执行以下命令：

```sh
# sysrc ipv6_defaultrouter="2001:db8:4672:6565::1"
```

要配置额外的 IPv6 任播地址，请按照 [rc.conf(5)](https://man.freebsd.org/cgi/man.cgi?query=rc.conf\&sektion=5\&format=html) 中的说明，将任播地址指定为 `_aliasN`，并在后面加上选项 `anycast`：

```sh
# sysrc ifconfig_em0_alias0="inet6 2001:db8:4672:6565::a anycast"
```

请注意，应用程序无法绑定到任播地址；这种情况下需要使用别名地址来代替。

## 7.3.5. 配置动态 IPv6 地址

要使用 [SLAAC](https://docs.freebsd.org/en/books/handbook/glossary/#slaac-glossary) 动态配置接口的 IPv6 地址，请执行以下命令：

```sh
# sysrc ifconfig_em0_ipv6="inet6 accept_rtadv"
# sysrc rtsold_enable="YES"
```

请注意，当启用 IPv6 数据包转发（即 `ipv6_gateway_enable=YES`）时，除非将 [sysctl(8)](https://man.freebsd.org/cgi/man.cgi?query=sysctl\&sektion=8\&format=html) 变量 `net.inet6.ip6.rfc6204w3`设置为 `1`，否则系统不会配置 SLAAC 地址。

## 7.3.6. 路由器通告和主机自动配置

本节演示如何在 IPv6 路由器上设置 `[rtadvd(8)](https://man.freebsd.org/cgi/man.cgi?query=rtadvd&sektion=8&format=html)`，以广播 IPv6 网络前缀和默认路由。

要启用 `[rtadvd(8)](https://man.freebsd.org/cgi/man.cgi?query=rtadvd&sektion=8&format=html)`，执行以下命令：

```sh
# sysrc rtadvd_enable="YES"
```

重要的是要指定进行 IPv6 路由器通告的接口。例如，要告诉 `[rtadvd(8)](https://man.freebsd.org/cgi/man.cgi?query=rtadvd&sektion=8&format=html)` 使用 `em0`：

```sh
# sysrc rtadvd_interfaces="em0"
```

接下来，创建配置文件 `/etc/rtadvd.conf`，如以下示例所示：

```ini
em0:\
	:addrs#1:addr="2001:db8:1f11:246::":prefixlen#64:tc=ether:
```

将 `em0` 替换为要使用的接口，并将 `2001:db8:1f11:246::` 替换为分配的前缀。

对于专用的 `/64` 子网，无需更改其他任何内容。否则，请将 `prefixlen#` 更改为正确的值。

## 7.3.7. IPv6 和 IPv4 地址映射

启用 IPv6 的服务器可能需要启用 IPv4 映射的 IPv6 地址通信。此兼容性选项允许将 IPv4 地址表示为 IPv6 地址。允许 IPv6 应用程序与 IPv4 通信，反之亦然，这可能会带来安全问题。

在大多数情况下，此选项可能不是必需的，仅用于兼容性。此选项能让仅支持 IPv6 的应用程序在双栈环境中与 IPv4 一起工作。这对那些可能不支持仅 IPv6 环境的第三方应用程序最为有用。

要启用此功能，请执行以下命令：

```sh
# sysrc ipv6_ipv4mapping="YES"
```
