第34章 高级网络

34.1. 概述

本章涵盖了许多高级网络主题。

阅读完本章后,您将了解

  • 网关和路由的基础知识。

  • 如何设置USB随身热点。

  • 如何设置IEEE® 802.11和蓝牙®设备。

  • 如何使FreeBSD充当桥接器。

  • 如何设置网络PXE引导。

  • 如何在FreeBSD中启用和利用通用地址冗余协议 (CARP) 的功能。

  • 如何在FreeBSD上配置多个VLAN。

  • 配置蓝牙耳机。

在阅读本章之前,您应该

34.2. 网关和路由

路由是一种机制,允许系统找到到另一个系统的网络路径。路由是一对定义的地址,表示“目标”和“网关”。路由指示在尝试到达指定目标时,通过指定的网关发送数据包。目标有三种类型:单个主机、子网和“默认”。如果没有任何其他路由适用,则使用“默认路由”。网关也有三种类型:单个主机、接口(也称为链路)和以太网硬件(MAC)地址。已知的路由存储在路由表中。

本节提供了路由基础知识的概述。然后演示如何将FreeBSD系统配置为路由器,并提供一些故障排除技巧。

34.2.1. 路由基础知识

要查看FreeBSD系统的路由表,请使用 netstat(1)

% netstat -r
Routing tables

Internet:
Destination      Gateway            Flags     Refs     Use     Netif Expire
default          outside-gw         UGS        37      418       em0
localhost        localhost          UH          0      181       lo0
test0            0:e0:b5:36:cf:4f   UHLW        5    63288       re0     77
10.20.30.255     link#1             UHLW        1     2421
example.com      link#1             UC          0        0
host1            0:e0:a8:37:8:1e    UHLW        3     4601       lo0
host2            0:e0:a8:37:8:1e    UHLW        0        5       lo0 =>
host2.example.com link#1            UC          0        0
224              link#1             UC          0        0

此示例中的条目如下

默认

此表中的第一条路由指定了默认路由。当本地系统需要与远程主机建立连接时,它会检查路由表以确定是否存在已知的路径。如果远程主机与表中的条目匹配,则系统会检查它是否可以使用该条目中指定的接口进行连接。

如果目标与任何条目都不匹配,或者如果所有已知路径都失败,则系统将使用默认路由的条目。对于本地网络上的主机,默认路由中的网关字段设置为与Internet直接连接的系统。阅读此条目时,请验证标志列是否指示网关可用(UG)。

对于本身充当外部世界网关的机器,其默认路由将是互联网服务提供商 (ISP) 处的网关机器。

本地主机

第二条路由是本地主机路由。为本地主机指定的网卡列中的接口是lo0,也称为回环设备。这表示此目标的所有流量都应该是内部的,而不是通过网络发送。

MAC地址

0:e0:开头的地址是MAC地址。FreeBSD将自动识别本地以太网上任何主机(例如,示例中的test0)并通过以太网接口re0为该主机添加一条路由。此类路由具有超时(在过期列中看到),如果主机在特定时间内没有响应,则会使用该超时。发生这种情况时,到该主机的路由将自动删除。这些主机使用路由信息协议 (RIP) 进行识别,该协议根据最短路径确定来计算到本地主机的路由。

子网

FreeBSD将自动为本地子网添加子网路由。在此示例中,10.20.30.255是子网10.20.30的广播地址,example.com是与该子网关联的域名。link#1表示机器中的第一张以太网卡。

本地网络主机和本地子网的路由由名为routed(8)的守护进程自动配置。如果它未运行,则只有管理员静态定义的路由才会存在。

主机

host1行指的是主机及其以太网地址。由于它是发送主机,因此FreeBSD知道使用回环接口(lo0)而不是以太网接口。

两条host2行表示使用ifconfig(8)创建的别名。 lo0接口后面的符号表示除了回环地址之外还设置了一个别名。此类路由仅显示在支持别名的主机上,本地网络上的所有其他主机都将为此类路由显示link#1行。

224

最后一行(目标子网224)处理多播。

每个路由的各种属性都可以在标志列中看到。常见路由表标志总结了一些这些标志及其含义

表1. 常见路由表标志
标志用途

U

路由处于活动状态(启动)。

H

路由目标是单个主机。

G

将此目标的任何内容发送到此网关,网关将从那里确定发送位置。

S

此路由是静态配置的。

C

基于此路由克隆一个新路由,供机器连接。此类路由通常用于本地网络。

W

路由基于本地区域网络 (克隆) 路由自动配置。

L

路由涉及对以太网 (链路) 硬件的引用。

在FreeBSD系统上,可以通过指定默认网关的IP地址在/etc/rc.conf中定义默认路由

defaultrouter="10.20.30.1"

也可以使用route手动添加路由

# route add default 10.20.30.1

请注意,手动添加的路由在重新引导后将不会保留。有关手动操作网络路由表的更多信息,请参阅route(8)

34.2.2. 使用静态路由配置路由器

如果FreeBSD系统是双宿主机,则可以将其配置为网络的默认网关或路由器。双宿主机是指驻留在至少两个不同网络上的主机。通常,每个网络都连接到一个单独的网络接口,尽管可以使用IP别名将多个地址(每个地址位于不同的子网上)绑定到一个物理接口。

为了使系统能够在接口之间转发数据包,必须将FreeBSD配置为路由器。互联网标准和良好的工程实践阻止FreeBSD项目默认启用此功能,但可以通过将此行添加到/etc/rc.conf来配置它在引导时启动

gateway_enable="YES"          # Set to YES if this host will be a gateway

要立即启用路由,请将sysctl(8)变量net.inet.ip.forwarding设置为1。要停止路由,请将此变量重置为0

路由器的路由表需要其他路由,以便它知道如何到达其他网络。路由可以手动添加使用静态路由,也可以使用路由协议自动学习。静态路由适用于小型网络,本节介绍如何为小型网络添加静态路由条目。

对于大型网络,静态路由很快变得无法扩展。FreeBSD附带了标准的BSD路由守护进程routed(8),它提供了路由协议RIP(版本1和2)和IRDP。可以使用net/quagga软件包或端口安装对BGP和OSPF路由协议的支持。

考虑以下网络

static routes

在此方案中,RouterA是充当路由器连接到Internet其余部分的FreeBSD机器。它将默认路由设置为10.0.0.1,这允许它连接外部世界。RouterB已配置为使用192.168.1.1作为其默认网关。

在添加任何静态路由之前,RouterA上的路由表如下所示

% netstat -nr
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif  Expire
default            10.0.0.1           UGS         0    49378    xl0
127.0.0.1          127.0.0.1          UH          0        6    lo0
10.0.0.0/24        link#1             UC          0        0    xl0
192.168.1.0/24     link#2             UC          0        0    xl1

使用当前路由表,RouterA没有到192.168.2.0/24网络的路由。以下命令使用192.168.1.2作为下一跳将内部网络2网络添加到RouterA的路由表中

# route add -net 192.168.2.0/24 192.168.1.2

现在,RouterA可以到达192.168.2.0/24网络上的任何主机。但是,如果FreeBSD系统重新引导,路由信息将不会保留。如果静态路由需要持久化,请将其添加到/etc/rc.conf

# Add Internal Net 2 as a persistent static route
static_routes="internalnet2"
route_internalnet2="-net 192.168.2.0/24 192.168.1.2"

static_routes配置变量是由空格分隔的字符串列表,其中每个字符串引用一个路由名称。变量route_internalnet2包含该路由名称的静态路由。

static_routes中使用多个字符串会创建多个静态路由。以下显示了一个为192.168.0.0/24192.168.1.0/24网络添加静态路由的示例

static_routes="net1 net2"
route_net1="-net 192.168.0.0/24 192.168.0.1"
route_net2="-net 192.168.1.0/24 192.168.1.1"

34.2.3. 故障排除

当一个地址空间被分配给一个网络时,服务提供商会配置他们的路由表,以便该网络的所有流量都会发送到站点的链路上。但是,外部站点如何知道将他们的数据包发送到网络的 ISP 呢?

有一个系统跟踪所有分配的地址空间,并定义它们与互联网主干的连接点,或者说承载跨越全国和世界各地互联网流量的主要干线。每个主干机器都有一份主表集的副本,这些表将特定网络的流量定向到特定的主干运营商,然后沿着服务提供商链向下传递,直到到达特定的网络。

服务提供商的任务是向主干站点通告他们是连接点,因此也是进入站点的路径。这被称为路由传播。

有时,路由传播会出现问题,导致某些站点无法连接。在尝试找出路由中断位置时,最有用命令可能是 traceroute。当 ping 失败时,它很有用。

使用 traceroute 时,请包含要连接到的远程主机的地址。输出将显示尝试路径上的网关主机,最终要么到达目标主机,要么由于缺少连接而终止。有关更多信息,请参阅 traceroute(8)

34.2.4. 多播注意事项

FreeBSD 原生支持多播应用程序和多播路由。多播应用程序不需要任何特殊配置即可在 FreeBSD 上运行。多播路由的支持需要将以下选项编译到自定义内核中

options MROUTING

多播路由守护进程 mrouted 可以使用 net/mrouted 包或端口安装。此守护进程实现 DVMRP 多播路由协议,并通过编辑 /usr/local/etc/mrouted.conf 来配置,以便设置隧道和 DVMRP。安装 mrouted 还会安装 map-mbone 和 mrinfo,以及它们的相关手册页。请参阅这些示例以了解配置。

在许多多播安装中,DVMRP 已在很大程度上被 PIM 协议取代。有关更多信息,请参阅 pim(4)

34.3. 虚拟主机

FreeBSD 的一个常见用途是虚拟站点托管,其中一台服务器对网络显示为多台服务器。这是通过将多个网络地址分配给单个接口来实现的。

给定的网络接口有一个“真实”地址,并且可以有任意数量的“别名”地址。这些别名通常通过在 /etc/rc.conf 中放置别名条目来添加,如本示例所示

# sysrc ifconfig_fxp0_alias0="inet xxx.xxx.xxx.xxx netmask xxx.xxx.xxx.xxx"

别名条目必须以 alias0 开头,使用顺序编号,例如 alias0alias1 等。配置过程将在第一个缺少的编号处停止。

别名网络掩码的计算非常重要。对于给定的接口,必须有一个地址能够正确表示网络的网络掩码。属于此网络的任何其他地址都必须具有全为 1 的网络掩码,表示为 255.255.255.2550xffffffff

例如,考虑 fxp0 接口连接到两个网络的情况:10.1.1.0,网络掩码为 255.255.255.0,以及 202.0.75.16,网络掩码为 255.255.255.240。系统将配置为显示在 10.1.1.110.1.1.5202.0.75.17202.0.75.20 的范围内。给定网络范围内只有第一个地址应该具有真实的网络掩码。所有其他地址(10.1.1.210.1.1.5202.0.75.18202.0.75.20)必须配置为网络掩码 255.255.255.255

以下 /etc/rc.conf 条目将适配器正确配置为此场景

# sysrc ifconfig_fxp0="inet 10.1.1.1 netmask 255.255.255.0"
# sysrc ifconfig_fxp0_alias0="inet 10.1.1.2 netmask 255.255.255.255"
# sysrc ifconfig_fxp0_alias1="inet 10.1.1.3 netmask 255.255.255.255"
# sysrc ifconfig_fxp0_alias2="inet 10.1.1.4 netmask 255.255.255.255"
# sysrc ifconfig_fxp0_alias3="inet 10.1.1.5 netmask 255.255.255.255"
# sysrc ifconfig_fxp0_alias4="inet 202.0.75.17 netmask 255.255.255.240"
# sysrc ifconfig_fxp0_alias5="inet 202.0.75.18 netmask 255.255.255.255"
# sysrc ifconfig_fxp0_alias6="inet 202.0.75.19 netmask 255.255.255.255"
# sysrc ifconfig_fxp0_alias7="inet 202.0.75.20 netmask 255.255.255.255"

更简单的表达方式是使用空格分隔的 IP 地址范围列表。第一个地址将被赋予指示的子网掩码,其他地址将具有 255.255.255.255 的子网掩码。

# sysrc ifconfig_fxp0_aliases="inet 10.1.1.1-5/24 inet 202.0.75.17-20/28"

34.4. 无线高级认证

FreeBSD 支持不同的连接到无线网络的方式。本节介绍如何对无线网络执行高级身份验证。

要连接到无线网络并进行基本身份验证,网络章节中的 连接到无线网络和身份验证 一节介绍了如何操作。

34.4.1. 带 EAP-TLS 的 WPA

使用 WPA 的第二种方式是使用 802.1X 后端认证服务器。在这种情况下,WPA 被称为 WPA Enterprise,以区别于安全性较低的 WPA Personal。WPA Enterprise 中的身份验证基于可扩展身份验证协议 (EAP)。

EAP 本身不带加密方法。相反,EAP 嵌入在一个加密的隧道中。有许多 EAP 身份验证方法,但 EAP-TLS、EAP-TTLS 和 EAP-PEAP 最为常见。

带传输层安全 (EAP-TLS) 的 EAP 是一种得到良好支持的无线身份验证协议,因为它是最早获得 Wi-Fi 联盟 认证的 EAP 方法。EAP-TLS 需要三个证书才能运行:安装在所有机器上的证书颁发机构 (CA) 证书、认证服务器的服务器证书以及每个无线客户端的一个客户端证书。在此 EAP 方法中,认证服务器和无线客户端通过呈现各自的证书相互认证,然后验证这些证书是否由组织的 CA 签署。

与之前一样,配置是通过 /etc/wpa_supplicant.conf 完成的

network={
  ssid="freebsdap" (1)
  proto=RSN  (2)
  key_mgmt=WPA-EAP (3)
  eap=TLS (4)
  identity="loader" (5)
  ca_cert="/etc/certs/cacert.pem" (6)
  client_cert="/etc/certs/clientcert.pem" (7)
  private_key="/etc/certs/clientkey.pem" (8)
  private_key_passwd="freebsdmallclient" (9)
}
1此字段指示网络名称 (SSID)。
2此示例使用 RSN IEEE® 802.11i 协议,也称为 WPA2。
3key_mgmt 行指的是要使用的密钥管理协议。在此示例中,它是使用 EAP 身份验证的 WPA。
4此字段指示连接的 EAP 方法。
5identity 字段包含 EAP 的身份字符串。
6ca_cert 字段指示 CA 证书文件的路径名。此文件用于验证服务器证书。
7client_cert 行给出客户端证书文件的路径名。此证书对于网络上的每个无线客户端都是唯一的。
8private_key 字段是客户端证书私钥文件的路径名。
9private_key_passwd 字段包含私钥的密码。

然后,将以下行添加到 /etc/rc.conf

wlans_ath0="wlan0"
ifconfig_wlan0="WPA DHCP"

下一步是启动接口

# service netif start
Starting wpa_supplicant.
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 7
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 15
DHCPACK from 192.168.0.20
bound to 192.168.0.254 -- renewal in 300 seconds.
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
      ether 00:11:95:d5:43:62
      inet 192.168.0.254 netmask 0xffffff00 broadcast 192.168.0.255
      media: IEEE 802.11 Wireless Ethernet DS/11Mbps mode 11g
      status: associated
      ssid freebsdap channel 1 (2412 Mhz 11g) bssid 00:11:95:c3:0d:ac
      country US ecm authmode WPA2/802.11i privacy ON deftxkey UNDEF
      AES-CCM 3:128-bit txpower 21.5 bmiss 7 scanvalid 450 bgscan
      bgscanintvl 300 bgscanidle 250 roam:rssi 7 roam:rate 5 protmode CTS
      wme burst roaming MANUAL

也可以使用 wpa_supplicant(8)ifconfig(8) 手动启动接口。

34.4.2. 带 EAP-TTLS 的 WPA

对于 EAP-TLS,认证服务器和客户端都需要证书。对于 EAP-TTLS,客户端证书是可选的。此方法类似于 Web 服务器,即使访客没有客户端证书,它也会创建安全的 SSL 隧道。EAP-TTLS 使用加密的 TLS 隧道来安全传输认证数据。

所需的配置可以添加到 /etc/wpa_supplicant.conf

network={
  ssid="freebsdap"
  proto=RSN
  key_mgmt=WPA-EAP
  eap=TTLS (1)
  identity="test" (2)
  password="test" (3)
  ca_cert="/etc/certs/cacert.pem" (4)
  phase2="auth=MD5" (5)
}
1此字段指定连接的 EAP 方法。
2identity 字段包含加密 TLS 隧道内 EAP 身份验证的身份字符串。
3password 字段包含 EAP 身份验证的密码。
4ca_cert 字段指示 CA 证书文件的路径名。此文件用于验证服务器证书。
5此字段指定加密 TLS 隧道中使用的身份验证方法。在此示例中,使用带 MD5-Challenge 的 EAP。“内部身份验证”阶段通常称为“阶段 2”。

接下来,将以下行添加到 /etc/rc.conf

wlans_ath0="wlan0"
ifconfig_wlan0="WPA DHCP"

下一步是启动接口

# service netif start
Starting wpa_supplicant.
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 7
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 15
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 21
DHCPACK from 192.168.0.20
bound to 192.168.0.254 -- renewal in 300 seconds.
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
      ether 00:11:95:d5:43:62
      inet 192.168.0.254 netmask 0xffffff00 broadcast 192.168.0.255
      media: IEEE 802.11 Wireless Ethernet DS/11Mbps mode 11g
      status: associated
      ssid freebsdap channel 1 (2412 Mhz 11g) bssid 00:11:95:c3:0d:ac
      country US ecm authmode WPA2/802.11i privacy ON deftxkey UNDEF
      AES-CCM 3:128-bit txpower 21.5 bmiss 7 scanvalid 450 bgscan
      bgscanintvl 300 bgscanidle 250 roam:rssi 7 roam:rate 5 protmode CTS
      wme burst roaming MANUAL

34.4.3. 带 EAP-PEAP 的 WPA

PEAPv0/EAP-MSCHAPv2 是最常见的 PEAP 方法。在本节中,术语 PEAP 用于指代该方法。

受保护的 EAP (PEAP) 旨在作为 EAP-TTLS 的替代方案,并且是 EAP-TLS 之后使用最广泛的 EAP 标准。在混合操作系统的网络中,PEAP 应该是 EAP-TLS 之后最受支持的标准。

PEAP 类似于 EAP-TTLS,因为它使用服务器端证书通过在客户端和认证服务器之间创建加密的 TLS 隧道来认证客户端,从而保护后续的身份验证信息的交换。PEAP 身份验证与 EAP-TTLS 的区别在于它以明文形式广播用户名,并且只有密码通过加密的 TLS 隧道发送。EAP-TTLS 将使用 TLS 隧道传输用户名和密码。

将以下行添加到 /etc/wpa_supplicant.conf 以配置与 EAP-PEAP 相关的设置

network={
  ssid="freebsdap"
  proto=RSN
  key_mgmt=WPA-EAP
  eap=PEAP (1)
  identity="test" (2)
  password="test" (3)
  ca_cert="/etc/certs/cacert.pem" (4)
  phase1="peaplabel=0" (5)
  phase2="auth=MSCHAPV2" (6)
}
1此字段指定连接的 EAP 方法。
2identity 字段包含加密 TLS 隧道内 EAP 身份验证的身份字符串。
3password 字段包含 EAP 身份验证的密码。
4ca_cert 字段指示 CA 证书文件的路径名。此文件用于验证服务器证书。
5此字段包含身份验证第一阶段(TLS 隧道)的参数。根据使用的认证服务器,为认证指定一个特定的标签。大多数情况下,标签将是“客户端 EAP 加密”,可以通过使用 peaplabel=0 设置。更多信息可以在 wpa_supplicant.conf(5) 中找到。
6此字段指定加密 TLS 隧道中使用的身份验证协议。在 PEAP 的情况下,它是 auth=MSCHAPV2

将以下内容添加到 /etc/rc.conf

wlans_ath0="wlan0"
ifconfig_wlan0="WPA DHCP"

然后,启动接口

# service netif start
Starting wpa_supplicant.
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 7
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 15
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 21
DHCPACK from 192.168.0.20
bound to 192.168.0.254 -- renewal in 300 seconds.
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
      ether 00:11:95:d5:43:62
      inet 192.168.0.254 netmask 0xffffff00 broadcast 192.168.0.255
      media: IEEE 802.11 Wireless Ethernet DS/11Mbps mode 11g
      status: associated
      ssid freebsdap channel 1 (2412 Mhz 11g) bssid 00:11:95:c3:0d:ac
      country US ecm authmode WPA2/802.11i privacy ON deftxkey UNDEF
      AES-CCM 3:128-bit txpower 21.5 bmiss 7 scanvalid 450 bgscan
      bgscanintvl 300 bgscanidle 250 roam:rssi 7 roam:rate 5 protmode CTS
      wme burst roaming MANUAL

34.5. 无线 Ad-hoc 模式

IBSS 模式,也称为 ad-hoc 模式,专为点对点连接而设计。例如,要在机器 AB 之间建立一个 ad-hoc 网络,请选择两个 IP 地址和一个 SSID。

A

# ifconfig wlan0 create wlandev ath0 wlanmode adhoc
# ifconfig wlan0 inet 192.168.0.1 netmask 255.255.255.0 ssid freebsdap
# ifconfig wlan0
  wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	  ether 00:11:95:c3:0d:ac
	  inet 192.168.0.1 netmask 0xffffff00 broadcast 192.168.0.255
	  media: IEEE 802.11 Wireless Ethernet autoselect mode 11g <adhoc>
	  status: running
	  ssid freebsdap channel 2 (2417 Mhz 11g) bssid 02:11:95:c3:0d:ac
	  country US ecm authmode OPEN privacy OFF txpower 21.5 scanvalid 60
	  protmode CTS wme burst

adhoc 参数指示接口正在 IBSS 模式下运行。

B 现在应该能够检测到 A

# ifconfig wlan0 create wlandev ath0 wlanmode adhoc
# ifconfig wlan0 up scan
  SSID/MESH ID    BSSID              CHAN RATE   S:N     INT CAPS
  freebsdap       02:11:95:c3:0d:ac    2   54M -64:-96  100 IS   WME

输出中的 I 确认 A 处于 ad-hoc 模式。现在,使用不同的 IP 地址配置 B

# ifconfig wlan0 inet 192.168.0.2 netmask 255.255.255.0 ssid freebsdap
# ifconfig wlan0
  wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	  ether 00:11:95:d5:43:62
	  inet 192.168.0.2 netmask 0xffffff00 broadcast 192.168.0.255
	  media: IEEE 802.11 Wireless Ethernet autoselect mode 11g <adhoc>
	  status: running
	  ssid freebsdap channel 2 (2417 Mhz 11g) bssid 02:11:95:c3:0d:ac
	  country US ecm authmode OPEN privacy OFF txpower 21.5 scanvalid 60
	  protmode CTS wme burst

AB 现在都已准备好交换信息。

34.5.1. FreeBSD 主机接入点

FreeBSD 可以充当接入点 (AP),从而无需购买硬件 AP 或运行自组织网络。当 FreeBSD 机器充当另一个网络(例如互联网)的网关时,这尤其有用。

34.5.1.1. 基本设置

在将 FreeBSD 机器配置为 AP 之前,必须使用无线网卡以及正在使用的安全协议的相应网络支持来配置内核。有关更多详细信息,请参阅 基本设置

Windows® 驱动程序的 NDIS 驱动程序包装程序目前不支持 AP 操作。只有原生 FreeBSD 无线驱动程序支持 AP 模式。

加载无线网络支持后,检查无线设备是否支持基于主机的接入点模式,也称为 hostap 模式。

# ifconfig wlan0 create wlandev ath0
# ifconfig wlan0 list caps
drivercaps=6f85edc1<STA,FF,TURBOP,IBSS,HOSTAP,AHDEMO,TXPMGT,SHSLOT,SHPREAMBLE,MONITOR,MBSS,WPA1,WPA2,BURST,WME,WDS,BGSCAN,TXFRAG>
cryptocaps=1f<WEP,TKIP,AES,AES_CCM,TKIPMIC>

此输出显示网卡的功能。HOSTAP 字样确认此无线网卡可以充当 AP。还列出了各种支持的密码:WEP、TKIP 和 AES。此信息指示 AP 上可以使用哪些安全协议。

无线设备只能在创建网络伪设备期间置于 hostap 模式,因此必须先销毁先前创建的设备。

# ifconfig wlan0 destroy

然后使用正确的选项重新生成,然后再设置其他参数。

# ifconfig wlan0 create wlandev ath0 wlanmode hostap
# ifconfig wlan0 inet 192.168.0.1 netmask 255.255.255.0 ssid freebsdap mode 11g channel 1

再次使用 ifconfig(8) 查看 wlan0 接口的状态。

# ifconfig wlan0
  wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	  ether 00:11:95:c3:0d:ac
	  inet 192.168.0.1 netmask 0xffffff00 broadcast 192.168.0.255
	  media: IEEE 802.11 Wireless Ethernet autoselect mode 11g <hostap>
	  status: running
	  ssid freebsdap channel 1 (2412 Mhz 11g) bssid 00:11:95:c3:0d:ac
	  country US ecm authmode OPEN privacy OFF txpower 21.5 scanvalid 60
	  protmode CTS wme burst dtimperiod 1 -dfs

hostap 参数指示接口正在基于主机的接入点模式下运行。

可以通过将以下行添加到 /etc/rc.conf 中来自动在启动时完成接口配置。

wlans_ath0="wlan0"
create_args_wlan0="wlanmode hostap"
ifconfig_wlan0="inet 192.168.0.1 netmask 255.255.255.0 ssid freebsdap mode 11g channel 1"

34.5.1.2. 无身份验证或加密的基于主机的接入点

尽管不建议在没有任何身份验证或加密的情况下运行 AP,但这是一种检查 AP 是否正常工作的简单方法。此配置对于调试客户端问题也很重要。

配置 AP 后,从另一台无线机器启动扫描以查找 AP。

# ifconfig wlan0 create wlandev ath0
# ifconfig wlan0 up scan
SSID/MESH ID    BSSID              CHAN RATE   S:N     INT CAPS
freebsdap       00:11:95:c3:0d:ac    1   54M -66:-96  100 ES   WME

客户端机器找到了 AP,并且可以与其关联。

# ifconfig wlan0 inet 192.168.0.2 netmask 255.255.255.0 ssid freebsdap
# ifconfig wlan0
  wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	  ether 00:11:95:d5:43:62
	  inet 192.168.0.2 netmask 0xffffff00 broadcast 192.168.0.255
	  media: IEEE 802.11 Wireless Ethernet OFDM/54Mbps mode 11g
	  status: associated
	  ssid freebsdap channel 1 (2412 Mhz 11g) bssid 00:11:95:c3:0d:ac
	  country US ecm authmode OPEN privacy OFF txpower 21.5 bmiss 7
	  scanvalid 60 bgscan bgscanintvl 300 bgscanidle 250 roam:rssi 7
	  roam:rate 5 protmode CTS wme burst

34.5.1.3. WPA2 基于主机的接入点

本节重点介绍如何使用 WPA2 安全协议设置 FreeBSD 接入点。有关 WPA 以及 WPA 基于无线客户端配置的更多详细信息,请参阅 带 EAP-TLS 的 WPA

hostapd(8) 守护进程用于处理 WPA2 启用 AP 上的客户端身份验证和密钥管理。

以下配置操作在充当 AP 的 FreeBSD 机器上执行。一旦 AP 正常工作,就可以使用 /etc/rc.conf 中的此行在启动时自动启动 hostapd(8)

hostapd_enable="YES"

在尝试配置 hostapd(8) 之前,首先配置 基本设置 中介绍的基本设置。

34.5.1.3.1. WPA2-PSK

WPA2-PSK 适用于无法或不需要使用后端身份验证服务器的小型网络。

配置在 /etc/hostapd.conf 中完成。

interface=wlan0                  (1)
debug=1                          (2)
ctrl_interface=/var/run/hostapd  (3)
ctrl_interface_group=wheel       (4)
ssid=freebsdap                   (5)
wpa=2                            (6)
wpa_passphrase=freebsdmall       (7)
wpa_key_mgmt=WPA-PSK             (8)
wpa_pairwise=CCMP                (9)
1用于接入点的无线接口。
2hostapd(8) 执行期间使用的详细程度。值为 1 表示最低级别。
3hostapd(8) 用于存储与外部程序(如 hostapd_cli(8) 通信的域套接字文件的目录的路径名。本例中使用了默认值。
4允许访问控制接口文件的组。
5无线网络名称或 SSID,它将显示在无线扫描中。
6启用 WPA 并指定将需要哪种 WPA 身份验证协议。值为 2 将 AP 配置为 WPA2,建议使用。仅当需要过时的 WPA 时才设置为 1
7WPA 身份验证的 ASCII 密码。
8要使用的密钥管理协议。此示例设置 WPA-PSK。
9接入点接受的加密算法。在本例中,仅接受 CCMP (AES) 密码。CCMP 是 TKIP 的替代方案,在可能的情况下强烈推荐使用。仅当存在无法使用 CCMP 的站点时才应允许 TKIP。

下一步是启动 hostapd(8)

# service hostapd forcestart
# ifconfig wlan0
wlan0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
	ether 04:f0:21:16:8e:10
	inet6 fe80::6f0:21ff:fe16:8e10%wlan0 prefixlen 64 scopeid 0x9
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet autoselect mode 11na <hostap>
	status: running
	ssid No5ignal channel 36 (5180 MHz 11a ht/40+) bssid 04:f0:21:16:8e:10
	country US ecm authmode WPA2/802.11i privacy MIXED deftxkey 2
	AES-CCM 2:128-bit AES-CCM 3:128-bit txpower 17 mcastrate 6 mgmtrate 6
	scanvalid 60 ampdulimit 64k ampdudensity 8 shortgi wme burst
	dtimperiod 1 -dfs
	groups: wlan

AP 运行后,客户端可以与其关联。有关更多详细信息,请参阅 基本设置。可以使用 ifconfig wlan0 list sta 查看与 AP 关联的站点。

34.6. USB 随身热点

许多手机提供通过 USB 共享其数据连接的选项(通常称为“随身热点”)。此功能使用 RNDIS、CDC 或自定义 Apple® iPhone®/iPad® 协议之一。

  • Android™ 设备通常使用 urndis(4) 驱动程序。

  • Apple® 设备使用 ipheth(4) 驱动程序。

  • 旧版设备通常使用 cdce(4) 驱动程序。

在连接设备之前,将相应的驱动程序加载到内核中。

# kldload if_urndis
# kldload if_cdce
# kldload if_ipheth

连接设备后,ue0 将可以像普通网络设备一样使用。确保设备上启用了“USB 随身热点”选项。

要使此更改永久生效并在启动时将驱动程序加载为模块,请将以下相应行放置在 /boot/loader.conf 中。

if_urndis_load="YES"
if_cdce_load="YES"
if_ipheth_load="YES"

34.7. 蓝牙

蓝牙是一种无线技术,用于创建在 2.4 GHz 无许可频段中运行的个人网络,范围为 10 米。网络通常由便携式设备(如手机、手持设备和笔记本电脑)自组织而成。与 Wi-Fi 无线技术不同,蓝牙提供更高级别的服务配置文件,例如 FTP 式文件服务器、文件推送、语音传输、串行线仿真等。

本节介绍如何在 FreeBSD 系统上使用 USB 蓝牙加密狗。然后描述各种蓝牙协议和实用程序。

34.7.1. 加载蓝牙支持

FreeBSD 中的蓝牙协议栈使用 netgraph(4) 框架实现。ng_ubt(4) 支持各种蓝牙 USB 加密狗。基于 Broadcom BCM2033 的蓝牙设备受 ubtbcmfw(4)ng_ubt(4) 驱动程序支持。3Com 蓝牙 PC 卡 3CRWB60-A 受 ng_bt3c(4) 驱动程序支持。基于串行和 UART 的蓝牙设备受 sio(4)ng_h4(4)hcseriald(8) 支持。

在连接设备之前,确定它使用上述哪个驱动程序,然后加载驱动程序。例如,如果设备使用 ng_ubt(4) 驱动程序。

# kldload ng_ubt

如果蓝牙设备将在系统启动期间连接到系统,则可以通过将驱动程序添加到 /boot/loader.conf 中来配置系统以在启动时加载模块。

ng_ubt_load="YES"

加载驱动程序后,插入 USB 加密狗。如果驱动程序加载成功,控制台和 /var/log/messages 中应显示类似以下内容的输出。

ubt0: vendor 0x0a12 product 0x0001, rev 1.10/5.25, addr 2
ubt0: Interface 0 endpoints: interrupt=0x81, bulk-in=0x82, bulk-out=0x2
ubt0: Interface 1 (alt.config 5) endpoints: isoc-in=0x83, isoc-out=0x3,
      wMaxPacketSize=49, nframes=6, buffer size=294

要启动和停止蓝牙协议栈,请使用其启动脚本。在拔下设备之前停止协议栈是一个好主意。启动蓝牙协议栈可能需要启动 hcsecd(8)。启动协议栈时,输出应类似于以下内容。

# service bluetooth start ubt0
BD_ADDR: 00:02:72:00:d4:1a
Features: 0xff 0xff 0xf 00 00 00 00 00
<3-Slot> <5-Slot> <Encryption> <Slot offset>
<Timing accuracy> <Switch> <Hold mode> <Sniff mode>
<Park mode> <RSSI> <Channel quality> <SCO link>
<HV2 packets> <HV3 packets> <u-law log> <A-law log> <CVSD>
<Paging scheme> <Power control> <Transparent SCO data>
Max. ACL packet size: 192 bytes
Number of ACL packets: 8
Max. SCO packet size: 64 bytes
Number of SCO packets: 8

34.7.2. 查找其他蓝牙设备

主机控制器接口 (HCI) 提供了一种访问蓝牙基带功能的统一方法。在 FreeBSD 中,为每个蓝牙设备创建了一个 netgraph HCI 节点。有关更多详细信息,请参阅 ng_hci(4)

最常见的任务之一是在射频范围内发现蓝牙设备。此操作称为查询。查询和其他与 HCI 相关的操作是使用 hccontrol(8) 完成的。以下示例显示了如何找出哪些蓝牙设备在范围内。设备列表应在几秒钟内显示。请注意,远程设备只有在其设置为可发现模式时才会回答查询。

% hccontrol -n ubt0hci inquiry
Inquiry result, num_responses=1
Inquiry result #0
       BD_ADDR: 00:80:37:29:19:a4
       Page Scan Rep. Mode: 0x1
       Page Scan Period Mode: 00
       Page Scan Mode: 00
       Class: 52:02:04
       Clock offset: 0x78ef
Inquiry complete. Status: No error [00]

BD_ADDR 是蓝牙设备的唯一地址,类似于网卡的 MAC 地址。此地址对于与设备进一步通信是必需的,并且可以为 BD_ADDR 分配一个人类可读的名称。有关已知蓝牙主机的详细信息包含在 /etc/bluetooth/hosts 中。以下示例显示了如何获取分配给远程设备的人类可读名称。

% hccontrol -n ubt0hci remote_name_request 00:80:37:29:19:a4
BD_ADDR: 00:80:37:29:19:a4
Name: Pav's T39

如果对远程蓝牙设备执行查询,它将找到计算机为“your.host.name (ubt0)”。分配给本地设备的名称可以随时更改。

可以在 /etc/bluetooth/hosts 中为远程设备分配别名。有关 /etc/bluetooth/hosts 文件的更多信息可以在 bluetooth.hosts(5) 中找到。

蓝牙系统提供两个蓝牙单元之间的点对点连接,或在多个蓝牙设备之间共享的点对多点连接。以下示例显示了如何创建到远程设备的连接

% hccontrol -n ubt0hci create_connection BT_ADDR

create_connection 接受 BT_ADDR 以及 /etc/bluetooth/hosts 中的主机别名。

以下示例显示了如何获取本地设备的活动基带连接列表

% hccontrol -n ubt0hci read_connection_list
Remote BD_ADDR    Handle Type Mode Role Encrypt Pending Queue State
00:80:37:29:19:a4     41  ACL    0 MAST    NONE       0     0 OPEN

当需要终止基带连接时,连接句柄很有用,尽管通常不需要手动执行此操作。堆栈将自动终止不活动的基带连接。

# hccontrol -n ubt0hci disconnect 41
Connection handle: 41
Reason: Connection terminated by local host [0x16]

键入 hccontrol help 以获取可用 HCI 命令的完整列表。大多数 HCI 命令不需要超级用户权限。

34.7.3. 设备配对

默认情况下,蓝牙通信未经身份验证,任何设备都可以与任何其他设备通信。蓝牙设备(例如手机)可以选择要求身份验证以提供特定服务。蓝牙身份验证通常使用PIN 码完成,PIN 码是一个最多 16 个字符的 ASCII 字符串。用户需要在两个设备上输入相同的 PIN 码。用户输入 PIN 码后,两个设备都将生成一个链路密钥。之后,链路密钥可以存储在设备中或持久存储中。下次,两个设备将使用先前生成的链路密钥。此过程称为配对。请注意,如果任一设备丢失链路密钥,则必须重复配对。

hcsecd(8) 守护程序负责处理蓝牙身份验证请求。默认配置文件为 /etc/bluetooth/hcsecd.conf。以下显示了 PIN 码设置为 1234 的手机的示例部分

device {
        bdaddr  00:80:37:29:19:a4;
        name    "Pav's T39";
        key     nokey;
        pin     "1234";
      }

PIN 码的唯一限制是长度。某些设备(例如蓝牙耳机)可能内置了固定的 PIN 码。-d 开关强制 hcsecd(8) 停留在前台,因此很容易看到发生了什么。将远程设备设置为接收配对并启动到远程设备的蓝牙连接。远程设备应指示配对已接受并请求 PIN 码。输入 hcsecd.conf 中列出的相同 PIN 码。现在,计算机和远程设备已配对。或者,可以在远程设备上启动配对。

可以将以下行添加到 /etc/rc.conf 中以配置 hcsecd(8) 在系统启动时自动启动

hcsecd_enable="YES"

以下是 hcsecd(8) 守护程序输出的示例

hcsecd[16484]: Got Link_Key_Request event from 'ubt0hci', remote bdaddr 0:80:37:29:19:a4
hcsecd[16484]: Found matching entry, remote bdaddr 0:80:37:29:19:a4, name 'Pav's T39', link key doesn't exist
hcsecd[16484]: Sending Link_Key_Negative_Reply to 'ubt0hci' for remote bdaddr 0:80:37:29:19:a4
hcsecd[16484]: Got PIN_Code_Request event from 'ubt0hci', remote bdaddr 0:80:37:29:19:a4
hcsecd[16484]: Found matching entry, remote bdaddr 0:80:37:29:19:a4, name 'Pav's T39', PIN code exists
hcsecd[16484]: Sending PIN_Code_Reply to 'ubt0hci' for remote bdaddr 0:80:37:29:19:a4

34.7.4. 使用 PPP 配置文件进行网络访问

拨号网络 (DUN) 配置文件可用于将手机配置为连接到拨号互联网接入服务器的无线调制解调器。它还可以用于配置计算机以接收来自手机的数据呼叫。

使用 PPP 配置文件进行网络访问可用于为单个蓝牙设备或多个蓝牙设备提供局域网访问。它还可以使用串行电缆仿真上的 PPP 网络提供 PC 到 PC 的连接。

在 FreeBSD 中,这些配置文件使用 ppp(8)rfcomm_pppd(8) 包装器实现,该包装器将蓝牙连接转换为 PPP 可以使用的内容。在可以使用配置文件之前,必须在 /etc/ppp/ppp.conf 中创建一个新的 PPP 标签。有关示例,请参阅 rfcomm_pppd(8)

在此示例中,rfcomm_pppd(8) 用于在 DUNRFCOMM 通道上打开到 00:80:37:29:19:a4BD_ADDR 的远程设备的连接

# rfcomm_pppd -a 00:80:37:29:19:a4 -c -C dun -l rfcomm-dialup

实际通道号将使用 SDP 协议从远程设备获取。可以手动指定 RFCOMM 通道,在这种情况下,rfcomm_pppd(8) 将不会执行 SDP 查询。使用 sdpcontrol(8) 查找远程设备上的 RFCOMM 通道。

为了使用 PPPLAN 服务提供网络访问,必须运行 sdpd(8) 并且必须在 /etc/ppp/ppp.conf 中为局域网客户端创建新条目。有关示例,请参阅 rfcomm_pppd(8)。最后,在有效的 RFCOMM 通道号上启动 RFCOMMPPP 服务器。RFCOMMPPP 服务器将自动向本地 SDP 守护程序注册蓝牙局域网服务。以下示例显示了如何启动 RFCOMMPPP 服务器。

# rfcomm_pppd -s -C 7 -l rfcomm-server

34.7.5. 蓝牙协议

本节概述了各种蓝牙协议、其功能和相关实用程序。

逻辑链路控制和适配协议 (L2CAP) 为上层协议提供面向连接和无连接的数据服务。L2CAP 允许高级协议和应用程序传输和接收长度最长为 64 千字节的 L2CAP 数据包。

L2CAP 基于通道的概念。通道是在基带连接之上的逻辑连接,其中每个通道以多对一的方式绑定到单个协议。多个通道可以绑定到同一个协议,但一个通道不能绑定到多个协议。接收到的每个 L2CAP 数据包都将定向到相应的更高级别的协议。多个通道可以共享同一个基带连接。

在 FreeBSD 中,将为每个蓝牙设备创建一个 netgraph L2CAP 节点。此节点通常连接到下游蓝牙 HCI 节点和上游蓝牙套接字节点。L2CAP 节点的默认名称为“devicel2cap”。有关更多详细信息,请参阅 ng_l2cap(4)

一个有用的命令是 l2ping(8),它可用于 ping 其他设备。某些蓝牙实现可能不会返回发送给它们的所有数据,因此以下示例中的 0 字节 是正常的。

# l2ping -a 00:80:37:29:19:a4
0 bytes from 0:80:37:29:19:a4 seq_no=0 time=48.633 ms result=0
0 bytes from 0:80:37:29:19:a4 seq_no=1 time=37.551 ms result=0
0 bytes from 0:80:37:29:19:a4 seq_no=2 time=28.324 ms result=0
0 bytes from 0:80:37:29:19:a4 seq_no=3 time=46.150 ms result=0

l2control(8) 实用程序用于对 L2CAP 节点执行各种操作。此示例显示了如何获取逻辑连接(通道)列表和本地设备的基带连接列表

% l2control -a 00:02:72:00:d4:1a read_channel_list
L2CAP channels:
Remote BD_ADDR     SCID/ DCID   PSM  IMTU/ OMTU State
00:07:e0:00:0b:ca    66/   64     3   132/  672 OPEN
% l2control -a 00:02:72:00:d4:1a read_connection_list
L2CAP connections:
Remote BD_ADDR    Handle Flags Pending State
00:07:e0:00:0b:ca     41 O           0 OPEN

另一个诊断工具是 btsockstat(1)。它类似于 netstat(1),但用于蓝牙网络相关的数据结构。以下示例显示了与上面 l2control(8) 相同的逻辑连接。

% btsockstat
Active L2CAP sockets
PCB      Recv-Q Send-Q Local address/PSM       Foreign address   CID   State
c2afe900      0      0 00:02:72:00:d4:1a/3     00:07:e0:00:0b:ca 66    OPEN
Active RFCOMM sessions
L2PCB    PCB      Flag MTU   Out-Q DLCs State
c2afe900 c2b53380 1    127   0     Yes  OPEN
Active RFCOMM sockets
PCB      Recv-Q Send-Q Local address     Foreign address   Chan DLCI State
c2e8bc80      0    250 00:02:72:00:d4:1a 00:07:e0:00:0b:ca 3    6    OPEN

34.7.5.2. 射频通信 (RFCOMM)

RFCOMM 协议提供通过 L2CAP 协议模拟串行端口的功能。RFCOMM 是一种简单的传输协议,还提供模拟 RS-232 (EIATIA-232-E) 串行端口的 9 个电路的功能。它支持两个蓝牙设备之间最多 60 个同时连接(RFCOMM 通道)。

就 RFCOMM 而言,完整的通信路径涉及在通信端点上运行的两个应用程序以及它们之间的通信段。RFCOMM 旨在涵盖利用其所在设备的串行端口的应用程序。通信段是来自一个设备到另一个设备的直接连接蓝牙链路。

RFCOMM 仅关注直接连接情况下的设备之间的连接,或网络情况下的设备与调制解调器之间的连接。RFCOMM 可以支持其他配置,例如在一侧通过蓝牙无线技术通信并在另一侧提供有线接口的模块。

在 FreeBSD 中,RFCOMM 在蓝牙套接字层实现。

34.7.5.3. 服务发现协议 (SDP)

服务发现协议 (SDP) 为客户端应用程序提供了一种方法来发现服务器应用程序提供的服务的存在以及这些服务的属性。服务的属性包括提供的服务类型或类别以及利用服务所需的机制或协议信息。

SDP 涉及 SDP 服务器和 SDP 客户端之间的通信。服务器维护一个服务记录列表,这些记录描述与服务器关联的服务的特性。每个服务记录包含有关单个服务的信息。客户端可以通过发出 SDP 请求来检索 SDP 服务器维护的服务记录中的信息。如果客户端或与客户端关联的应用程序决定使用服务,则它必须打开与服务提供程序的单独连接才能利用该服务。SDP 提供了一种发现服务及其属性的机制,但它不提供利用这些服务的机制。

通常,SDP 客户端根据服务的某些所需特性搜索服务。但是,有时希望发现 SDP 服务器的服务记录描述了哪些类型的服务,而无需任何有关服务的先验信息。此查找任何提供的服务的过程称为浏览

蓝牙 SDP 服务器 sdpd(8) 和命令行客户端 sdpcontrol(8) 包含在标准 FreeBSD 安装中。以下示例显示了如何执行 SDP 浏览查询。

% sdpcontrol -a 00:01:03:fc:6e:ec browse
Record Handle: 00000000
Service Class ID List:
        Service Discovery Server (0x1000)
Protocol Descriptor List:
        L2CAP (0x0100)
                Protocol specific parameter #1: u/int/uuid16 1
                Protocol specific parameter #2: u/int/uuid16 1

Record Handle: 0x00000001
Service Class ID List:
        Browse Group Descriptor (0x1001)

Record Handle: 0x00000002
Service Class ID List:
        LAN Access Using PPP (0x1102)
Protocol Descriptor List:
        L2CAP (0x0100)
        RFCOMM (0x0003)
                Protocol specific parameter #1: u/int8/bool 1
Bluetooth Profile Descriptor List:
        LAN Access Using PPP (0x1102) ver. 1.0

请注意,每个服务都有一个属性列表,例如 RFCOMM 通道。根据服务,用户可能需要记下某些属性。某些蓝牙实现不支持服务浏览,并且可能返回空列表。在这种情况下,可以搜索特定服务。以下示例显示了如何搜索 OBEX 对象推送 (OPUSH) 服务

% sdpcontrol -a 00:01:03:fc:6e:ec search OPUSH

在 FreeBSD 上向蓝牙客户端提供服务是通过 sdpd(8) 服务器完成的。可以将以下行添加到 /etc/rc.conf

sdpd_enable="YES"

然后可以使用以下命令启动 sdpd(8) 守护程序

# service sdpd start

想要向远程客户端提供蓝牙服务的本地服务器应用程序将向本地 SDP 守护程序注册该服务。此类应用程序的一个示例是 rfcomm_pppd(8)。启动后,它将向本地 SDP 守护程序注册蓝牙局域网服务。

可以通过通过本地控制通道发出 SDP 浏览查询来获取注册到本地 SDP 服务器的服务列表

# sdpcontrol -l browse

34.7.5.4. OBEX 对象推送 (OPUSH)

对象交换 (OBEX) 是一种广泛使用的协议,用于移动设备之间的简单文件传输。它主要用于红外通信,在笔记本电脑或 PDA 之间用于通用文件传输,以及在手机和其他具有个人信息管理器 (PIM) 应用程序的设备之间发送名片或日历条目。

OBEX 服务器和客户端由 obexapp 实现,可以使用 comms/obexapp 包或端口进行安装。

OBEX 客户端用于从 OBEX 服务器推送和/或拉取对象。例如,名片或约会信息就是一个对象。OBEX 客户端可以通过 SDP 从远程设备获取 RFCOMM 通道号。可以通过指定服务名称而不是 RFCOMM 通道号来实现此操作。支持的服务名称包括:IrMCFTRNOPUSH。也可以将 RFCOMM 通道指定为数字。以下是一个 OBEX 会话的示例,其中从手机中拉取设备信息对象,并将一个新的对象(名片)推送到手机的目录中。

% obexapp -a 00:80:37:29:19:a4 -C IrMC
obex> get telecom/devinfo.txt devinfo-t39.txt
Success, response: OK, Success (0x20)
obex> put new.vcf
Success, response: OK, Success (0x20)
obex> di
Success, response: OK, Success (0x20)

为了提供 OPUSH 服务,必须运行 sdpd(8),并且必须创建一个根文件夹,所有传入的对象都将存储在此文件夹中。根文件夹的默认路径为 /var/spool/obex。最后,在有效的 RFCOMM 通道号上启动 OBEX 服务器。OBEX 服务器将自动向本地 SDP 守护进程注册 OPUSH 服务。以下示例显示了如何启动 OBEX 服务器。

# obexapp -s -C 10

34.7.5.5. 串行端口配置文件 (SPP)

串行端口配置文件 (SPP) 允许蓝牙设备执行串行电缆仿真。此配置文件允许传统应用程序通过虚拟串行端口抽象使用蓝牙作为电缆替代品。

在 FreeBSD 中,rfcomm_sppd(1) 实现 SPP,并且伪终端用作虚拟串行端口抽象。以下示例显示了如何连接到远程设备的串行端口服务。不必指定 RFCOMM 通道,因为 rfcomm_sppd(1) 可以通过 SDP 从远程设备获取它。要覆盖此设置,请在命令行上指定 RFCOMM 通道。

# rfcomm_sppd -a 00:07:E0:00:0B:CA -t
rfcomm_sppd[94692]: Starting on /dev/pts/6...
/dev/pts/6

连接后,伪终端可以用作串行端口。

# cu -l /dev/pts/6

伪终端打印在标准输出上,并且可以由包装脚本读取。

PTS=`rfcomm_sppd -a 00:07:E0:00:0B:CA -t`
cu -l $PTS

34.7.6. 故障排除

默认情况下,当 FreeBSD 接受新连接时,它会尝试执行角色切换并成为主控方。一些不支持角色切换的旧版蓝牙设备将无法连接。由于角色切换是在建立新连接时执行的,因此无法询问远程设备是否支持角色切换。但是,存在一个 HCI 选项可以在本地禁用角色切换。

# hccontrol -n ubt0hci write_node_role_switch 0

要显示蓝牙数据包,请使用第三方包 hcidump,可以使用 comms/hcidump 包或端口进行安装。此实用程序类似于 tcpdump(1),可用于在终端上显示蓝牙数据包的内容并将蓝牙数据包转储到文件中。

34.8. 桥接

有时需要将网络(例如以太网段)划分为网络段,而无需创建 IP 子网并使用路由器将这些段连接在一起。以这种方式连接两个网络的设备称为“桥接器”。

桥接器的工作原理是学习其每个网络接口上的设备的 MAC 地址。它仅在源 MAC 地址和目标 MAC 地址位于不同网络时才转发网络之间的流量。在许多方面,桥接器就像一个端口很少的以太网交换机。配置了多个网络接口的 FreeBSD 系统可以配置为充当桥接器。

桥接在以下情况下很有用:

连接网络

桥接器的基本操作是连接两个或多个网络段。使用基于主机的桥接器而不是网络设备有很多原因,例如布线限制或防火墙。桥接器还可以将以主机模式运行的无线接口连接到有线网络并充当访问点。

过滤/流量整形防火墙

当需要防火墙功能而无需路由或网络地址转换 (NAT) 时,可以使用桥接器。

例如,一家小型公司通过 DSL 或 ISDN 连接到 ISP。ISP 提供了 13 个公共 IP 地址,网络上有 10 台计算机。在这种情况下,由于子网问题,使用基于路由器的防火墙很困难。可以配置基于桥接器的防火墙,而不会出现任何 IP 地址问题。

网络监听

桥接器可以连接两个网络段,以便使用 bpf(4)tcpdump(1) 检查通过它们的所有以太网帧,或者通过在称为跨接端口的其他接口上发送所有帧的副本。

第 2 层 VPN

可以通过将网络桥接到 EtherIP 隧道或基于 tap(4) 的解决方案(如 OpenVPN)来跨 IP 链路连接两个以太网网络。

第 2 层冗余

可以使用多个链路将网络连接在一起,并使用生成树协议 (STP) 阻止冗余路径。

本节介绍如何使用 if_bridge(4) 将 FreeBSD 系统配置为桥接器。还提供了一个 netgraph 桥接驱动程序,并在 ng_bridge(4) 中进行了描述。

可以使用任何挂接到 pfil(9) 框架的防火墙软件包进行数据包过滤。可以使用 altq(4)dummynet(4) 将桥接器用作流量整形器。

34.8.1. 启用桥接器

在 FreeBSD 中,if_bridge(4) 是一个内核模块,当创建桥接接口时,ifconfig(8) 会自动加载它。也可以通过将 device if_bridge 添加到自定义内核配置文件中,将桥接支持编译到自定义内核中。

桥接器是使用接口克隆创建的。要创建桥接接口,请执行以下操作:

# ifconfig bridge create
bridge0
# ifconfig bridge0
bridge0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 96:3d:4b:f1:79:7a
        id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
        root id 00:00:00:00:00:00 priority 0 ifcost 0 port 0

创建桥接接口后,会自动为其分配一个随机生成的以太网地址。maxaddrtimeout 参数控制桥接器在其转发表中保留多少个 MAC 地址,以及在上次看到每个条目后将其删除之前等待多少秒。其他参数控制 STP 的运行方式。

接下来,指定要添加为桥接器成员的网络接口。为了使桥接器转发数据包,所有成员接口和桥接器都需要处于启动状态。

# ifconfig bridge0 addm fxp0 addm fxp1 up
# ifconfig fxp0 up
# ifconfig fxp1 up

桥接器现在可以转发 fxp0fxp1 之间的以太网帧。将以下行添加到 /etc/rc.conf 中,以便在启动时创建桥接器:

cloned_interfaces="bridge0"
ifconfig_bridge0="addm fxp0 addm fxp1 up"
ifconfig_fxp0="up"
ifconfig_fxp1="up"

如果桥接器主机需要 IP 地址,请在桥接器接口上设置它,而不是在成员接口上设置。地址可以静态设置或通过 DHCP 设置。此示例设置了一个静态 IP 地址:

# ifconfig bridge0 inet 192.168.0.1/24

也可以将 IPv6 地址分配给桥接器接口。要使更改永久生效,请将寻址信息添加到 /etc/rc.conf 中。

启用数据包过滤后,桥接数据包将通过桥接器接口上的起始接口入站通过过滤器,并通过相应的接口出站。可以禁用任一阶段。当数据包流的方向很重要时,最好在成员接口而不是桥接器本身设置防火墙。

桥接器有一些可配置的设置,用于传递非 IP 和 IP 数据包,以及使用 ipfw(8) 进行第 2 层防火墙。有关更多信息,请参阅 if_bridge(4)

34.8.2. 启用生成树

为了使以太网网络正常工作,两个设备之间只能存在一条活动路径。STP 协议检测环路并将冗余链路置于阻塞状态。如果其中一条活动链路发生故障,STP 会计算不同的树并启用其中一条阻塞路径以恢复网络中所有点的连接。

快速生成树协议 (RSTP 或 802.1w) 提供了与传统 STP 的向后兼容性。RSTP 提供更快的收敛速度,并与相邻交换机交换信息,以便在不创建环路的情况下快速转换为转发模式。FreeBSD 支持 RSTP 和 STP 作为操作模式,其中 RSTP 为默认模式。

可以使用 ifconfig(8) 在成员接口上启用 STP。对于具有 fxp0fxp1 作为当前接口的桥接器,请使用以下命令启用 STP:

# ifconfig bridge0 stp fxp0 stp fxp1
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether d6:cf:d5:a0:94:6d
        id 00:01:02:4b:d4:50 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
        root id 00:01:02:4b:d4:50 priority 32768 ifcost 0 port 0
        member: fxp0 flags=1c7<LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP>
                port 3 priority 128 path cost 200000 proto rstp
                role designated state forwarding
        member: fxp1 flags=1c7<LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP>
                port 4 priority 128 path cost 200000 proto rstp
                role designated state forwarding

此桥接器的生成树 ID 为 00:01:02:4b:d4:50,优先级为 32768。由于 root id 相同,因此表示这是树的根桥接器。

网络上的另一个桥接器也启用了 STP:

bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 96:3d:4b:f1:79:7a
        id 00:13:d4:9a:06:7a priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
        root id 00:01:02:4b:d4:50 priority 32768 ifcost 400000 port 4
        member: fxp0 flags=1c7<LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP>
                port 4 priority 128 path cost 200000 proto rstp
                role root state forwarding
        member: fxp1 flags=1c7<LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP>
                port 5 priority 128 path cost 200000 proto rstp
                role designated state forwarding

root id 00:01:02:4b:d4:50 priority 32768 ifcost 400000 port 4 显示根桥接器为 00:01:02:4b:d4:50,并且从此桥接器到根桥接器的路径成本为 400000。到根桥接器的路径通过 port 4,即 fxp0

34.8.3. 桥接器接口参数

一些 ifconfig 参数是桥接器接口独有的。本节总结了这些参数的一些常见用法。可用参数的完整列表在 ifconfig(8) 中进行了描述。

private

专用接口不会将任何流量转发到任何其他也指定为专用接口的端口。流量会被无条件阻止,因此不会转发任何以太网帧,包括 ARP 数据包。如果需要选择性地阻止流量,则应使用防火墙。

span

跨接端口会传输桥接器接收到的每个以太网帧的副本。在桥接器上配置的跨接端口数量没有限制,但如果将接口指定为跨接端口,则它也不能用作常规桥接端口。这对于在连接到桥接器跨接端口之一的其他主机上被动侦听桥接网络最有用。例如,要将所有帧的副本发送到名为 fxp4 的接口,请执行以下操作:

# ifconfig bridge0 span fxp4
sticky

如果桥接成员接口被标记为粘滞(sticky),则动态学习的地址条目在转发缓存中被视为静态条目。粘滞条目永远不会从缓存中老化或替换,即使在其他接口上看到该地址也是如此。这提供了静态地址条目的好处,而无需预先填充转发表。在桥接的特定段上学习的客户端无法漫游到其他段。

使用粘滞地址的一个示例是将桥接与 VLAN 结合使用,以便隔离客户网络而无需浪费 IP 地址空间。假设CustomerA位于vlan100上,CustomerB位于vlan101上,并且桥接具有地址192.168.0.1

# ifconfig bridge0 addm vlan100 sticky vlan100 addm vlan101 sticky vlan101
# ifconfig bridge0 inet 192.168.0.1/24

在此示例中,两个客户端都将192.168.0.1视为其默认网关。由于桥接缓存是粘滞的,因此一个主机无法欺骗另一个客户的 MAC 地址以拦截其流量。

可以使用防火墙或如本例所示的专用接口阻止 VLAN 之间的任何通信。

# ifconfig bridge0 private vlan100 private vlan101

客户彼此完全隔离,并且可以分配完整的/24地址范围而无需子网划分。

可以限制接口后面唯一源 MAC 地址的数量。一旦达到限制,具有未知源地址的数据包将被丢弃,直到现有主机缓存条目过期或被删除。

以下示例将vlan100CustomerA的以太网设备最大数量设置为 10。

# ifconfig bridge0 ifmaxaddr vlan100 10

桥接接口还支持监视模式,其中数据包在bpf(4)处理后被丢弃,并且不会进一步处理或转发。这可以用于将两个或多个接口的输入多路复用到单个bpf(4)流中。这对于重建网络监控的流量很有用,网络监控通过两个独立的接口传输 RX/TX 信号。例如,要将来自四个网络接口的输入读取为一个流

# ifconfig bridge0 addm fxp0 addm fxp1 addm fxp2 addm fxp3 monitor up
# tcpdump -i bridge0

34.8.4. SNMP 监控

桥接接口和 STP 参数可以通过bsnmpd(1)进行监控,该程序包含在 FreeBSD 基础系统中。导出的桥接 MIB 符合 IETF 标准,因此任何 SNMP 客户端或监控软件包都可以用于检索数据。

要在桥接上启用监控,请在/etc/snmpd.config中取消此行的注释,方法是删除开头的#符号。

begemotSnmpdModulePath."bridge" = "/usr/lib/snmp_bridge.so"

此文件中可能需要修改其他配置设置,例如社区名称和访问列表。有关更多信息,请参阅bsnmpd(1)snmp_bridge(3)。保存这些编辑后,将以下行添加到/etc/rc.conf

bsnmpd_enable="YES"

然后,启动bsnmpd(1)

# service bsnmpd start

以下示例使用 Net-SNMP 软件(net-mgmt/net-snmp)从客户端系统查询桥接。还可以使用net-mgmt/bsnmptools端口。在运行 Net-SNMP 的 SNMP 客户端中,将以下行添加到$HOME/.snmp/snmp.conf以导入桥接 MIB 定义。

mibdirs +/usr/share/snmp/mibs
mibs +BRIDGE-MIB:RSTP-MIB:BEGEMOT-MIB:BEGEMOT-BRIDGE-MIB

要使用 IETF BRIDGE-MIB(RFC4188)监控单个桥接。

% snmpwalk -v 2c -c public bridge1.example.com mib-2.dot1dBridge
BRIDGE-MIB::dot1dBaseBridgeAddress.0 = STRING: 66:fb:9b:6e:5c:44
BRIDGE-MIB::dot1dBaseNumPorts.0 = INTEGER: 1 ports
BRIDGE-MIB::dot1dStpTimeSinceTopologyChange.0 = Timeticks: (189959) 0:31:39.59 centi-seconds
BRIDGE-MIB::dot1dStpTopChanges.0 = Counter32: 2
BRIDGE-MIB::dot1dStpDesignatedRoot.0 = Hex-STRING: 80 00 00 01 02 4B D4 50
...
BRIDGE-MIB::dot1dStpPortState.3 = INTEGER: forwarding(5)
BRIDGE-MIB::dot1dStpPortEnable.3 = INTEGER: enabled(1)
BRIDGE-MIB::dot1dStpPortPathCost.3 = INTEGER: 200000
BRIDGE-MIB::dot1dStpPortDesignatedRoot.3 = Hex-STRING: 80 00 00 01 02 4B D4 50
BRIDGE-MIB::dot1dStpPortDesignatedCost.3 = INTEGER: 0
BRIDGE-MIB::dot1dStpPortDesignatedBridge.3 = Hex-STRING: 80 00 00 01 02 4B D4 50
BRIDGE-MIB::dot1dStpPortDesignatedPort.3 = Hex-STRING: 03 80
BRIDGE-MIB::dot1dStpPortForwardTransitions.3 = Counter32: 1
RSTP-MIB::dot1dStpVersion.0 = INTEGER: rstp(2)

dot1dStpTopChanges.0值为 2,表示 STP 桥接拓扑已更改两次。拓扑更改意味着网络中的一条或多条链路已更改或发生故障,并且已计算出新的树。dot1dStpTimeSinceTopologyChange.0值将显示何时发生这种情况。

要监控多个桥接接口,可以使用私有的 BEGEMOT-BRIDGE-MIB。

% snmpwalk -v 2c -c public bridge1.example.com
enterprises.fokus.begemot.begemotBridge
BEGEMOT-BRIDGE-MIB::begemotBridgeBaseName."bridge0" = STRING: bridge0
BEGEMOT-BRIDGE-MIB::begemotBridgeBaseName."bridge2" = STRING: bridge2
BEGEMOT-BRIDGE-MIB::begemotBridgeBaseAddress."bridge0" = STRING: e:ce:3b:5a:9e:13
BEGEMOT-BRIDGE-MIB::begemotBridgeBaseAddress."bridge2" = STRING: 12:5e:4d:74:d:fc
BEGEMOT-BRIDGE-MIB::begemotBridgeBaseNumPorts."bridge0" = INTEGER: 1
BEGEMOT-BRIDGE-MIB::begemotBridgeBaseNumPorts."bridge2" = INTEGER: 1
...
BEGEMOT-BRIDGE-MIB::begemotBridgeStpTimeSinceTopologyChange."bridge0" = Timeticks: (116927) 0:19:29.27 centi-seconds
BEGEMOT-BRIDGE-MIB::begemotBridgeStpTimeSinceTopologyChange."bridge2" = Timeticks: (82773) 0:13:47.73 centi-seconds
BEGEMOT-BRIDGE-MIB::begemotBridgeStpTopChanges."bridge0" = Counter32: 1
BEGEMOT-BRIDGE-MIB::begemotBridgeStpTopChanges."bridge2" = Counter32: 1
BEGEMOT-BRIDGE-MIB::begemotBridgeStpDesignatedRoot."bridge0" = Hex-STRING: 80 00 00 40 95 30 5E 31
BEGEMOT-BRIDGE-MIB::begemotBridgeStpDesignatedRoot."bridge2" = Hex-STRING: 80 00 00 50 8B B8 C6 A9

要更改通过mib-2.dot1dBridge子树监视的桥接接口。

% snmpset -v 2c -c private bridge1.example.com
BEGEMOT-BRIDGE-MIB::begemotBridgeDefaultBridgeIf.0 s bridge2

34.9. 链路聚合和故障转移

FreeBSD 提供了lagg(4)接口,该接口可用于将多个网络接口聚合到一个虚拟接口中,以提供故障转移和链路聚合。故障转移允许流量继续流动,只要至少一个聚合的网络接口建立了链路即可。链路聚合在支持 LACP 的交换机上效果最佳,因为此协议双向分配流量,同时响应单个链路的故障。

lagg 接口支持的聚合协议决定了哪些端口用于出站流量以及特定端口是否接受入站流量。以下协议受lagg(4)支持。

故障转移(failover)

此模式仅通过主端口发送和接收流量。如果主端口不可用,则使用下一个活动端口。添加到虚拟接口的第一个接口为主端口,所有后续添加的接口都用作故障转移设备。如果发生到非主端口的故障转移,则原始端口在再次可用时将变为主端口。

负载均衡(loadbalance)

这提供了静态设置,并且不与对等方协商聚合或交换帧以监视链路。如果交换机支持 LACP,则应改用它。

LACP

IEEE® 802.3ad 链路聚合控制协议 (LACP) 将与对等方协商一组可聚合链路,形成一个或多个链路聚合组 (LAG)。每个 LAG 由相同速度的端口组成,设置为全双工操作,并且流量在 LAG 中具有最大总速度的端口之间进行平衡。通常,只有一个 LAG 包含所有端口。在物理连接发生变化的情况下,LACP 将快速收敛到新配置。

LACP 基于散列协议报头信息在活动端口之间平衡出站流量,并从任何活动端口接收入站流量。散列包括以太网源和目标地址,以及(如果可用)VLAN 标记,以及 IPv4 或 IPv6 源和目标地址。

循环(roundrobin)

此模式使用循环调度程序通过所有活动端口分发出站流量,并从任何活动端口接收入站流量。由于此模式违反了以太网帧排序,因此应谨慎使用。

广播(broadcast)

此模式将出站流量发送到 lagg 接口上配置的所有端口,并在任何端口接收帧。

34.9.1. 配置示例

本节演示如何为 LACP 负载均衡配置 Cisco® 交换机和 FreeBSD 系统。然后显示如何以故障转移模式配置两个以太网接口,以及如何在以太网和无线接口之间配置故障转移模式。

示例 1. 使用 Cisco® 交换机的 LACP 聚合

此示例将 FreeBSD 计算机上的两个fxp(4)以太网接口连接到 Cisco® 交换机上的前两个以太网端口,作为单个负载均衡且容错的链路。可以添加更多接口以提高吞吐量和容错能力。将示例中显示的 Cisco® 端口、以太网设备、通道组编号和 IP 地址替换为匹配本地配置的名称。

以太网链路上的帧排序是强制性的,两个站点之间的任何流量始终通过相同的物理链路流动,将最大速度限制为一个接口的速度。传输算法尝试使用尽可能多的信息来区分不同的流量流,并在可用接口之间平衡流量流。

在 Cisco® 交换机上,将FastEthernet0/1FastEthernet0/2接口添加到通道组1

interface FastEthernet0/1
 channel-group 1 mode active
 channel-protocol lacp
!
interface FastEthernet0/2
 channel-group 1 mode active
 channel-protocol lacp

在 FreeBSD 系统上,使用物理接口fxp0fxp1创建lagg(4)接口,并使用10.0.0.3/24的 IP 地址启动接口。

# ifconfig fxp0 up
# ifconfig fxp1 up
# ifconfig lagg0 create
# ifconfig lagg0 up laggproto lacp laggport fxp0 laggport fxp1 10.0.0.3/24

接下来,验证虚拟接口的状态。

# ifconfig lagg0
lagg0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8<VLAN_MTU>
        ether 00:05:5d:71:8d:b8
        inet 10.0.0.3 netmask 0xffffff00 broadcast 10.0.0.255
        media: Ethernet autoselect
        status: active
        laggproto lacp
        laggport: fxp1 flags=1c<ACTIVE,COLLECTING,DISTRIBUTING>
        laggport: fxp0 flags=1c<ACTIVE,COLLECTING,DISTRIBUTING>

标记为ACTIVE的端口是已与远程交换机协商的 LAG 的一部分。流量将通过这些活动端口传输和接收。将-v添加到上述命令以查看 LAG 标识符。

查看 Cisco® 交换机上的端口状态。

switch# show lacp neighbor
Flags:  S - Device is requesting Slow LACPDUs
        F - Device is requesting Fast LACPDUs
        A - Device is in Active mode       P - Device is in Passive mode

Channel group 1 neighbors

Partner's information:

                  LACP port                        Oper    Port     Port
Port      Flags   Priority  Dev ID         Age     Key     Number   State
Fa0/1     SA      32768     0005.5d71.8db8  29s    0x146   0x3      0x3D
Fa0/2     SA      32768     0005.5d71.8db8  29s    0x146   0x4      0x3D

有关更多详细信息,请键入show lacp neighbor detail

要保留跨重新引导的此配置,请在 FreeBSD 系统上的/etc/rc.conf中添加以下条目。

ifconfig_fxp0="up"
ifconfig_fxp1="up"
cloned_interfaces="lagg0"
ifconfig_lagg0="laggproto lacp laggport fxp0 laggport fxp1 10.0.0.3/24"
示例 2. 故障转移模式

如果主接口上的链路丢失,则可以使用故障转移模式切换到辅助接口。要配置故障转移,请确保底层物理接口已启动,然后创建lagg(4)接口。在此示例中,fxp0为主接口,fxp1为辅助接口,虚拟接口分配的 IP 地址为10.0.0.15/24

# ifconfig fxp0 up
# ifconfig fxp1 up
# ifconfig lagg0 create
# ifconfig lagg0 up laggproto failover laggport fxp0 laggport fxp1 10.0.0.15/24

虚拟接口应如下所示。

# ifconfig lagg0
lagg0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8<VLAN_MTU>
        ether 00:05:5d:71:8d:b8
        inet 10.0.0.15 netmask 0xffffff00 broadcast 10.0.0.255
        media: Ethernet autoselect
        status: active
        laggproto failover
        laggport: fxp1 flags=0<>
        laggport: fxp0 flags=5<MASTER,ACTIVE>

流量将在fxp0上传输和接收。如果fxp0上的链路丢失,fxp1将成为活动链路。如果主接口上的链路恢复,它将再次成为活动链路。

要保留跨重新引导的此配置,请在/etc/rc.conf中添加以下条目。

ifconfig_fxp0="up"
ifconfig_fxp1="up"
cloned_interfaces="lagg0"
ifconfig_lagg0="laggproto failover laggport fxp0 laggport fxp1 10.0.0.15/24"
示例 3. 以太网和无线接口之间的故障转移模式

对于笔记本电脑用户,通常希望将无线设备配置为辅助设备,仅在以太网连接不可用时使用。使用lagg(4),可以配置优先使用以太网连接的故障转移,以实现性能和安全性的原因,同时保持能够通过无线连接传输数据。

这是通过将以太网接口的 MAC 地址覆盖为无线接口的 MAC 地址来实现的。

理论上,可以将以太网或无线 MAC 地址更改为匹配另一个地址。但是,一些流行的无线接口缺乏覆盖 MAC 地址的支持。因此,我们建议为此目的覆盖以太网 MAC 地址。

如果无线接口的驱动程序未在GENERIC或自定义内核中加载,并且计算机正在运行 FreeBSD 12.1,请通过在/boot/loader.conf中添加driver_load="YES"并重新引导来加载相应的.ko。另一种更好的方法是在/etc/rc.conf中加载驱动程序,方法是将其添加到kld_list(有关详细信息,请参阅rc.conf(5))并在该文件中重新引导。这是必要的,因为否则在设置lagg(4)接口时,驱动程序尚未加载。

在这个示例中,以太网接口re0为主接口,无线接口wlan0为故障转移接口。wlan0接口是从ath0物理无线接口创建的,并且以太网接口将配置为使用无线接口的MAC地址。首先,启动无线接口(将FR替换为您的两位国家代码),但不要设置IP地址。将wlan0替换为系统无线接口的名称。

# ifconfig wlan0 create wlandev ath0 country FR ssid my_router up

现在您可以确定无线接口的MAC地址。

# ifconfig wlan0
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	ether b8:ee:65:5b:32:59
	groups: wlan
	ssid Bbox-A3BD2403 channel 6 (2437 MHz 11g ht/20) bssid 00:37:b7:56:4b:60
	regdomain ETSI country FR indoor ecm authmode WPA2/802.11i privacy ON
	deftxkey UNDEF AES-CCM 2:128-bit txpower 30 bmiss 7 scanvalid 60
	protmode CTS ampdulimit 64k ampdudensity 8 shortgi -stbctx stbcrx
	-ldpc wme burst roaming MANUAL
	media: IEEE 802.11 Wireless Ethernet MCS mode 11ng
	status: associated
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>

ether行将包含指定接口的MAC地址。现在,将以太网接口的MAC地址更改为匹配的地址。

# ifconfig re0 ether b8:ee:65:5b:32:59

确保re0接口已启动,然后创建lagg(4)接口,其中re0为主接口,wlan0为故障转移接口。

# ifconfig re0 up
# ifconfig lagg0 create
# ifconfig lagg0 up laggproto failover laggport re0 laggport wlan0

虚拟接口应如下所示。

# ifconfig lagg0
lagg0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8<VLAN_MTU>
        ether b8:ee:65:5b:32:59
        laggproto failover lagghash l2,l3,l4
        laggport: re0 flags=5<MASTER,ACTIVE>
        laggport: wlan0 flags=0<>
        groups: lagg
        media: Ethernet autoselect
        status: active

然后,启动DHCP客户端以获取IP地址。

# dhclient lagg0

要保留跨重新引导的此配置,请在/etc/rc.conf中添加以下条目。

ifconfig_re0="ether b8:ee:65:5b:32:59"
wlans_ath0="wlan0"
ifconfig_wlan0="WPA"
create_args_wlan0="country FR"
cloned_interfaces="lagg0"
ifconfig_lagg0="up laggproto failover laggport re0 laggport wlan0 DHCP"

34.10. 使用PXE的无盘操作

英特尔®预启动执行环境(PXE)允许操作系统通过网络启动。例如,FreeBSD系统可以通过网络启动并在没有本地磁盘的情况下运行,使用从NFS服务器挂载的文件系统。PXE支持通常在BIOS中可用。要在机器启动时使用PXE,请在BIOS设置中选择从网络启动选项,或在系统初始化期间按下功能键。

为了提供操作系统通过网络启动所需的文件,PXE设置还需要正确配置的DHCP、TFTP和NFS服务器,其中

  • 初始参数(例如IP地址、可执行引导文件名和位置、服务器名称以及根路径)从DHCP服务器获取。

  • 操作系统加载程序文件使用TFTP启动。

  • 文件系统使用NFS加载。

当计算机PXE启动时,它会通过DHCP接收有关从哪里获取初始引导加载程序文件的信息。主机计算机收到此信息后,它将通过TFTP下载引导加载程序,然后执行引导加载程序。在FreeBSD中,引导加载程序文件为/boot/pxeboot。在/boot/pxeboot执行后,将加载FreeBSD内核,并继续执行FreeBSD的其余启动序列,如FreeBSD启动过程中所述。

对于基于UEFI PXE的启动,实际使用的引导加载程序文件为/boot/loader.efi。请参阅以下部分调试PXE问题,了解如何使用/boot/loader.efi

本节介绍如何在FreeBSD系统上配置这些服务,以便其他系统可以PXE启动到FreeBSD。有关更多信息,请参阅diskless(8)

如前所述,提供这些服务的系统是不安全的。它应该位于网络的受保护区域,并且不受其他主机信任。

34.10.1. 设置PXE环境

本节中显示的步骤配置内置的NFS和TFTP服务器。下一节演示如何安装和配置DHCP服务器。在此示例中,将包含PXE用户使用的文件的目录为/b/tftpboot/FreeBSD/install。此目录必须存在,并且在/etc/inetd.conf/usr/local/etc/dhcpd.conf中都设置相同的目录名称非常重要。

以下命令示例假设使用sh(1) shell。csh(1)tcsh(1)用户需要启动sh(1) shell或将命令调整为csh(1)语法。

  1. 创建将包含要NFS挂载的FreeBSD安装的根目录。

    # export NFSROOTDIR=/b/tftpboot/FreeBSD/install
    # mkdir -p ${NFSROOTDIR}
  2. 通过将以下行添加到/etc/rc.conf来启用NFS服务器。

    nfs_server_enable="YES"
  3. 通过将以下内容添加到/etc/exports来通过NFS导出无盘根目录。

    /b -ro -alldirs -maproot=root
  4. 启动NFS服务器。

    # service nfsd start
  5. 通过将以下行添加到/etc/rc.conf来启用inetd(8)

    inetd_enable="YES"
  6. /etc/inetd.conf中取消以下行的注释,确保它不以#符号开头。

    tftp dgram udp wait root /usr/libexec/tftpd tftpd blocksize 1468 -l -s /b/tftpboot

    指定的tftp块大小(例如1468字节)替换默认大小512字节。某些PXE版本需要TFTP的TCP版本。在这种情况下,取消包含stream tcp的第二个tftp行的注释。

  7. 启动inetd(8)

    # service inetd start
  8. 将基本系统安装到${NFSROOTDIR}中,可以通过解压缩官方档案或重新构建FreeBSD内核和用户空间来完成(有关更详细的说明,请参阅“从源代码更新FreeBSD”,但不要忘记在运行make installkernelmake installworld命令时添加DESTDIR=${NFSROOTDIR})。

  9. 测试TFTP服务器是否正常工作,并且可以下载将通过PXE获取的引导加载程序。

    # tftp localhost
    tftp> get FreeBSD/install/boot/pxeboot
    Received 264951 bytes in 0.1 seconds
  10. 编辑${NFSROOTDIR}/etc/fstab并创建一个条目以通过NFS挂载根文件系统。

    # Device                                         Mountpoint    FSType   Options  Dump Pass
    myhost.example.com:/b/tftpboot/FreeBSD/install       /         nfs      ro        0    0

    myhost.example.com替换为NFS服务器的主机名或IP地址。在此示例中,根文件系统以只读方式挂载,以防止NFS客户端可能删除根文件系统的内容。

  11. 在PXE环境中为PXE启动的客户端机器设置根密码。

    # chroot ${NFSROOTDIR}
    # passwd
  12. 如果需要,通过编辑${NFSROOTDIR}/etc/ssh/sshd_config并启用PermitRootLogin来为PXE启动的客户端机器启用ssh(1)根登录。此选项在sshd_config(5)中进行了说明。

  13. ${NFSROOTDIR}中执行PXE环境所需的任何其他自定义。这些自定义可能包括安装软件包或使用vipw(8)编辑密码文件。

从NFS根卷启动时,/etc/rc检测到NFS启动并运行/etc/rc.initdiskless。在这种情况下,/etc/var需要是内存支持的文件系统,以便这些目录可写,但NFS根目录为只读。

# chroot ${NFSROOTDIR}
# mkdir -p conf/base
# tar -c -v -f conf/base/etc.cpio.gz --format cpio --gzip etc
# tar -c -v -f conf/base/var.cpio.gz --format cpio --gzip var

系统启动时,将创建并挂载/etc/var的内存文件系统,并将cpio.gz文件的内容复制到其中。默认情况下,这些文件系统的最大容量为5兆字节。如果您的档案不适合(通常在安装二进制软件包时/var会出现这种情况),请请求更大的大小,将所需的512字节扇区数(例如,5兆字节为10240个扇区)放在${NFSROOTDIR}/conf/base/etc/md_size${NFSROOTDIR}/conf/base/var/md_size文件中,分别用于/etc/var文件系统。

34.10.2. 配置DHCP服务器

DHCP服务器不必与TFTP和NFS服务器位于同一台机器上,但它需要在网络中可访问。

DHCP不是FreeBSD基本系统的一部分,但可以使用net/isc-dhcp44-server端口或软件包安装。

安装后,编辑配置文件/usr/local/etc/dhcpd.conf。配置next-serverfilenameroot-path设置,如本示例所示。

subnet 192.168.0.0 netmask 255.255.255.0 {
   range 192.168.0.2 192.168.0.3 ;
   option subnet-mask 255.255.255.0 ;
   option routers 192.168.0.1 ;
   option broadcast-address 192.168.0.255 ;
   option domain-name-servers 192.168.35.35, 192.168.35.36 ;
   option domain-name "example.com";

   # IP address of TFTP server
   next-server 192.168.0.1 ;

   # path of boot loader obtained via tftp
   filename "FreeBSD/install/boot/pxeboot" ;

   # pxeboot boot loader will try to NFS mount this directory for root FS
   option root-path "192.168.0.1:/b/tftpboot/FreeBSD/install/" ;

}

next-server指令用于指定TFTP服务器的IP地址。

filename指令定义/boot/pxeboot的路径。使用相对文件名,这意味着/b/tftpboot不包含在路径中。

root-path选项定义NFS根文件系统的路径。

保存编辑后,通过将以下行添加到/etc/rc.conf来在启动时启用DHCP。

dhcpd_enable="YES"

然后启动DHCP服务。

# service isc-dhcpd start

34.10.3. 调试PXE问题

所有服务都配置并启动后,PXE客户端应该能够自动通过网络加载FreeBSD。如果特定客户端无法连接,则在该客户端机器启动时,进入BIOS配置菜单并确认它已设置为从网络启动。

本节介绍一些故障排除技巧,用于隔离配置问题的根源,以防任何客户端都无法PXE启动。

  1. 使用net/wireshark软件包或端口调试PXE启动过程中涉及的网络流量,如下图所示。

    pxe nfs
    图1. 使用NFS根挂载的PXE启动过程
    1. 客户端广播DHCPDISCOVER消息。

    2. DHCP服务器以IP地址、next-server、filename和root-path值进行响应。

    3. 客户端向next-server发送TFTP请求,要求检索filename。

    4. TFTP服务器响应并将filename发送到客户端。

    5. 客户端执行filename(即pxeboot(8)),然后加载内核。内核执行后,将通过NFS挂载由root-path指定的根文件系统。

  2. 在TFTP服务器上,读取/var/log/xferlog以确保从正确的位置检索pxeboot。要测试此示例配置,

    # tftp 192.168.0.1
    tftp> get FreeBSD/install/boot/pxeboot
    Received 264951 bytes in 0.1 seconds

    tftpd(8)tftp(1)中的BUGS部分记录了TFTP的一些限制。

  3. 确保可以通过NFS挂载根文件系统。要测试此示例配置,

    # mount -t nfs 192.168.0.1:/b/tftpboot/FreeBSD/install /mnt
  4. 对于基于UEFI PXE的启动,请将boot/pxeboot文件替换为boot/loader.efi文件。

# chroot ${NFSROOTDIR}
# mv boot/pxeboot boot/pxeboot.original
# cp boot/loader.efi boot/pxeboot

34.11. 公共地址冗余协议 (CARP)

通用地址冗余协议 (CARP) 允许多个主机共享相同的 IP 地址和虚拟主机 ID (VHID),以便为一个或多个服务提供高可用性。这意味着一个或多个主机可能会发生故障,而其他主机将透明地接管,以确保用户不会遇到服务中断。

除了共享的 IP 地址外,每个主机还拥有自己的 IP 地址用于管理和配置。所有共享 IP 地址的机器都具有相同的 VHID。每个虚拟 IP 地址的 VHID 在网络接口的广播域中必须是唯一的。

FreeBSD 内置了使用 CARP 实现高可用性的功能,但配置步骤会根据 FreeBSD 版本略有不同。本节提供了 FreeBSD 10 及之前版本和之后版本的相同示例配置。

此示例配置了三个主机的故障转移支持,所有主机都具有唯一的 IP 地址,但提供相同 Web 内容。它有两个名为 hosta.example.orghostb.example.org 的不同主服务器,以及一个名为 hostc.example.org 的共享备份服务器。

这些机器通过轮循 DNS 配置进行负载均衡。主服务器和备份服务器的配置相同,除了主机名和管理 IP 地址。这些服务器必须具有相同的配置并运行相同的服务。当发生故障转移时,只有当备份服务器可以访问相同的内容时,才能正确响应对共享 IP 地址上服务的请求。备份机器有两个额外的 CARP 接口,每个主内容服务器的 IP 地址各一个。当发生故障时,备份服务器将获取发生故障的主服务器的 IP 地址。

34.11.1. 使用 CARP

通过在 /boot/loader.conf 中添加 carp.ko 内核模块的条目来启用 CARP 的启动时支持。

carp_load="YES"

要在不重启的情况下加载模块,请执行以下操作:

# kldload carp

对于喜欢使用自定义内核的用户,请在自定义内核配置文件中包含以下行,并按照配置 FreeBSD 内核中的说明编译内核。

device	carp

主机名、管理 IP 地址和子网掩码、共享 IP 地址和 VHID 都是通过在 /etc/rc.conf 中添加条目来设置的。此示例适用于 hosta.example.org

hostname="hosta.example.org"
ifconfig_em0="inet 192.168.1.3 netmask 255.255.255.0"
ifconfig_em0_alias0="inet vhid 1 pass testpass alias 192.168.1.50/32"

下一组条目适用于 hostb.example.org。由于它表示第二个主服务器,因此它使用不同的共享 IP 地址和 VHID。但是,使用 pass 指定的密码必须相同,因为 CARP 仅侦听并接受来自具有正确密码的机器的公告。

hostname="hostb.example.org"
ifconfig_em0="inet 192.168.1.4 netmask 255.255.255.0"
ifconfig_em0_alias0="inet vhid 2 pass testpass alias 192.168.1.51/32"

第三台机器 hostc.example.org 配置为处理来自任一主服务器的故障转移。这台机器配置了两个 CARPVHID,一个用于处理每个主服务器的虚拟 IP 地址。CARP 广告偏差 advskew 设置为确保备份主机比主服务器晚些发布公告,因为 advskew 控制存在多个备份服务器时的优先级顺序。

hostname="hostc.example.org"
ifconfig_em0="inet 192.168.1.5 netmask 255.255.255.0"
ifconfig_em0_alias0="inet vhid 1 advskew 100 pass testpass alias 192.168.1.50/32"
ifconfig_em0_alias1="inet vhid 2 advskew 100 pass testpass alias 192.168.1.51/32"

配置了两个 CARPVHID 意味着 hostc.example.org 将会注意到任一主服务器是否不可用。如果主服务器在备份服务器之前未能发布公告,则备份服务器将接管共享 IP 地址,直到主服务器再次可用。

如果原始主服务器再次可用,hostc.example.org 不会自动将其虚拟 IP 地址释放回它。为此,必须启用抢占功能。该功能默认情况下处于禁用状态,它通过 sysctl(8) 变量 net.inet.carp.preempt 进行控制。管理员可以强制备份服务器将 IP 地址返回给主服务器。

# ifconfig em0 vhid 1 state backup

配置完成后,重新启动网络或重新引导每个系统。高可用性现已启用。

CARP 功能可以通过 sysctl(8) 变量进行控制,这些变量在 carp(4) 手册页中进行了说明。其他操作可以通过使用 devd(8) 从 CARP 事件触发。

34.12. VLAN

VLAN 是一种将网络虚拟划分为许多不同子网络的方式,也称为分段。每个分段将拥有自己的广播域,并且与其他 VLAN 隔离。

在 FreeBSD 上,网络卡驱动程序必须支持 VLAN。要查看哪些驱动程序支持 VLAN,请参阅 vlan(4) 手册页。

配置 VLAN 时,必须了解几个信息。首先,哪个网络接口?其次,VLAN 标签是什么?

要使用 em0 的网卡和 5 的 VLAN 标签在运行时配置 VLAN,命令如下所示:

# ifconfig em0.5 create vlan 5 vlandev em0 inet 192.168.20.20/24

看到接口名称包含 NIC 驱动程序名称和 VLAN 标签,它们之间用句点分隔了吗?这是在机器上存在许多 VLAN 时简化 VLAN 配置维护的最佳实践。

定义 VLAN 时,请确保父网络接口也已配置并启用。上述示例的最小配置如下所示:

# ifconfig em0 up

要在启动时配置 VLAN,必须更新 /etc/rc.conf。要复制上述配置,需要添加以下内容:

vlans_em0="5"
ifconfig_em0_5="inet 192.168.20.20/24"

可以通过简单地将标签添加到 vlans_em0 字段并添加另一行来配置该 VLAN 标签的接口上的网络来添加其他 VLAN。

/etc/rc.conf 中定义 VLAN 时,请确保父网络接口也已配置并启用。上述示例的最小配置如下所示:

ifconfig_em0="up"

将符号名称分配给接口非常有用,这样当关联的硬件发生更改时,只需要更新几个配置变量即可。例如,安全摄像头需要通过 em0 上的 VLAN 1 运行。稍后,如果 em0 卡被使用 ixgb(4) 驱动程序的卡替换,则所有对 em0.1 的引用都不需要更改为 ixgb0.1

要配置 em0 NIC 上的 VLAN 5,为接口分配名称 cameras,并为接口分配 192.168.20.20 的 IP 地址和 24 位前缀,请使用以下命令:

# ifconfig em0.5 create vlan 5 vlandev em0 name cameras inet 192.168.20.20/24

对于名为 video 的接口,请使用以下命令:

# ifconfig video.5 create vlan 5 vlandev video name cameras inet 192.168.20.20/24

要在启动时应用更改,请将以下行添加到 /etc/rc.conf 中:

vlans_video="cameras"
create_args_cameras="vlan 5"
ifconfig_cameras="inet 192.168.20.20/24"

最后修改时间:2024 年 9 月 23 日,作者:Fernando Apesteguía