网络桥接

出自 ArchWiki

网络桥接是一种虚拟网络设备,用于在两个或多个网段之间转发数据包。桥接的行为类似于虚拟网络交换机,并且透明地工作。网络中的其他机器不需要知道它的存在。物理网络设备(例如 eth1)和虚拟网络设备(例如 tap0)可以连接到它。

创建桥接

有很多方法可以创建网络桥接。本节概述了使用至少一个以太网接口设置桥接所需的步骤。这对于诸如 QEMU 的桥接模式、设置基于软件的接入点等很有用。

警告: 如果您要在远程服务器上创建桥接,并且计划将主网络接口添加到桥接,请确保首先在桥接上添加主网络接口的 IP 地址,设置桥接,并设置备份默认路由,将接口添加到桥接之前。否则,服务器将失去网络连接,您将无法通过 SSH 连接回服务器。

使用 iproute2

本节介绍如何使用 iproute2 软件包中的 ip 工具管理网络桥接,base 元软件包 需要该软件包。

创建一个新的桥接并将其状态更改为 up

# ip link add name bridge_name type bridge
# ip link set dev bridge_name up

要将接口(例如 eth1)添加到桥接中,其状态必须为 up

# ip link set eth1 up

将接口添加到桥接是通过将其 master 设置为 bridge_name 来完成的

# ip link set eth1 master bridge_name

要显示现有桥接和关联的接口,请使用 bridge 实用程序(也是 iproute2 的一部分)。有关详细信息,请参见 bridge(8)

# bridge link

这是从桥接中删除接口的方法

# ip link set eth1 nomaster

该接口仍将处于 up 状态,因此您可能还想将其关闭

# ip link set eth1 down

要删除桥接,请发出以下命令

# ip link delete bridge_name type bridge

这将自动从桥接中删除所有接口。但是,从属接口仍将处于 up 状态,因此您可能还想在之后将其关闭。

添加主网络接口

如果您在远程服务器上执行此操作,并且计划将主网络接口(例如 eth0)添加到桥接,请首先记下当前的网络状态

$ ip address show eth0
$ ip route show dev eth0

对于此示例,这是相关信息

  • 附加到 eth0 的 IP 地址: 10.2.3.4/8
  • 默认网关: 10.0.0.1
  • 桥接名称: br0

桥接的初始设置

# ip link add name br0 type bridge
# ip link set dev br0 up
# ip address add 10.2.3.4/8 dev br0
# ip route append default via 10.0.0.1 dev br0

然后,快速连续执行这些命令。建议将它们放在脚本文件中并执行脚本

# ip link set eth0 master br0
# ip address del 10.2.3.4/8 dev eth0

说明

  • 一旦将 eth0 添加到桥接,它将不再用于路由。br0 将取代它的位置,因此它需要一个 IP 并附加默认路由。
  • 在将接口添加到 br0 之前,我们无法删除 eth0 上的 IP 地址,否则将失去网络连接。
  • 但是,我们需要快速删除 eth0 上的 ip 地址,否则在短时间后将失去网络连接。
  • Linux 不允许在同一路由表上存在两个默认路由。简单的解决方法是仅附加新的默认路由。
  • 删除 eth0 的 IP 地址后,附加到它的默认路由将自动删除。

使用 bridge-utils

本节介绍如何使用来自 bridge-utils 软件包的旧版 brctl 工具管理网络桥接。有关选项的完整列表,请参见 brctl(8)

注意: brctl 的使用已弃用,并被认为是过时的。有关详细信息,请参见 brctl(8) § NOTES 中的“注释”部分。

创建一个新的桥接

# brctl addbr bridge_name

将设备添加到桥接,例如 eth1

注意: 将接口添加到桥接将导致该接口丢失其现有的 IP 地址。如果您是通过要添加到桥接的接口远程连接的,则将失去连接。可以通过脚本在系统启动时创建桥接来解决此问题。
# brctl addif bridge_name eth1

显示当前的桥接以及它们连接到的接口

$ brctl show

启动桥接设备

# ip link set dev bridge_name up

删除桥接,您需要先将其设置为 down

# ip link set dev bridge_name down
# brctl delbr bridge_name
注意: 要启用 bridge-netfilter 功能,您需要手动加载 br_netfilter 模块
# modprobe br_netfilter

您还可以在启动时加载模块

添加主网络接口

首先,记下当前的网络状态

$ ip address show eth0
$ ip route show dev eth0

对于此示例,这是相关信息

  • 附加到 eth0 的 IP 地址: 10.2.3.4/8
  • 默认网关: 10.0.0.1
  • 桥接名称: br0

桥接的初始设置

# brctl addbr br0
# ip address add 10.2.3.4/8 dev br0
# ip link set dev br0 up

然后,快速连续执行这些命令。建议将它们放在脚本文件中并执行脚本

# brctl addif br0 eth0
# ip address del 10.2.3.4/8 dev eth0

使用 netctl

参见 使用 netctl 的桥接

使用 systemd-networkd

参见 systemd-networkd#桥接接口

使用 NetworkManager

GNOME 的网络设置可以创建桥接,但目前不会自动连接到它们或从属/连接的接口。打开网络设置,添加类型为桥接的新接口,添加新的桥接连接,然后选择要连接到桥接的设备的 MAC 地址。

KDEplasma-nm 可以创建桥接。为了查看、创建和修改桥接接口,请打开“连接”窗口,可以通过右键单击系统托盘中的“网络”小程序并选择配置网络连接...,或者从系统设置 > 连接中打开。单击模块左下角的配置按钮,并启用“显示虚拟连接”。需要重启会话才能使用启用的功能。

nm-connection-editor 可以像 GNOME 的网络设置一样创建桥接。页面显示了带有屏幕截图的这些步骤。

来自 networkmanagernmcli 可以创建桥接。例如,要创建禁用 STP 的桥接 br0(以避免桥接在网络上广播),请运行

$ nmcli connection add type bridge ifname br0 stp no

使您的以太网接口(本例中为 enp30s0,有关查找名称的说明,请参见 网络配置#网络接口)成为桥接的从属

$ nmcli connection add type bridge-slave ifname enp30s0 master br0

关闭现有连接(您可以使用 nmcli connection show --active 获取连接名称)

$ nmcli connection down Connection

启动新的桥接

$ nmcli connection up bridge-br0
$ nmcli connection up bridge-slave-enp30s0

如果 NetworkManager 为您添加到桥接的设备的默认接口自动连接,您可能希望通过单击“网络设置”中其旁边的齿轮,并取消选中身份下的自动连接或使用以下命令来禁用该功能

$ nmcli connection modify Connection connection.autoconnect no

分配 IP 地址

本文或章节需要扩充。

原因: 本节需要连接到 QEMU#使用 QEMU 的 Tap 网络 中描述的链接层部分。目前,请参阅此处给出的说明。(在 Talk:Network bridge 中讨论)

当桥接完全设置好后,可以为其分配 IP 地址

使用 iproute2

# ip address add dev bridge_name 192.168.66.66/24

使用 NetworkManager

为其提供所需的地址

# nmcli connection modify Connection ipv4.addresses desired_IP

设置 DNS 服务器(这也将避免在应用更改后无法加载任何页面)

# nmcli connection modify Connection ipv4.dns DNS_server

将 IP 地址设置为静态

# nmcli connection modify Connection ipv4.method manual

应用更改

# nmcli connection up Connection

技巧与窍门

桥接上的无线接口

要将无线接口添加到桥接,您首先必须将无线接口分配给接入点,或者使用 hostapd 启动接入点。否则,无线接口将不会添加到桥接。

另请参见 Debian:BridgeNetworkConnections#使用无线网卡桥接

加速发往桥接自身的流量

在某些情况下,桥接不仅充当桥接盒,还与其他主机通信。到达桥接端口并发送到桥接盒自身的数据包默认情况下将使用逻辑桥接端口作为输入设备进入 iptables INPUT 链。这些数据包将被网络代码排队两次,第一次是在它们被网络设备接收之后排队。第二次是在桥接代码检查了目标 MAC 地址并确定它是本地目标数据包,因此决定将帧传递到更高的协议栈之后。[1]

让本地目标数据包仅排队一次的方法是在 broute 表的 BROUTING 链中对它们进行路由。假设 br0 具有 IP 地址,并且 br0 的桥接端口没有 IP 地址。使用以下规则应使所有本地定向流量仅排队一次

# ebtables -t broute -A BROUTING -d $MAC_OF_BR0 -p ipv4 -j redirect --redirect-target DROP

来自桥接的回复将通过 br0 设备发送出去(假设您的路由表正确并且将所有流量通过 br0 发送),因此一切都保持整洁地工作,而不会因数据包排队两次而导致性能损失。

之所以需要 redirect 目标,是因为桥接端口的 MAC 地址不一定等于桥接设备的 MAC 地址。发送到桥接盒的数据包的目标 MAC 地址将等于桥接 br0 的 MAC 地址,因此必须将该目标地址更改为桥接端口的 MAC 地址。

故障排除

桥接配置后无网络连接

本文或章节需要语言、Wiki 语法或样式改进。请参阅 Help:Style 以供参考。

原因: 此问题在 #使用 bridge-utils 中作为注释指出。应在所有其他部分中明确说明,并且应将运行 DHCP 客户端添加到 #分配 IP 地址。(在 Talk:Network bridge 中讨论)

从添加到桥接的接口(例如 eth1)中删除所有 IP 地址和路由,并为桥接配置这些参数可能会有所帮助。

首先,请确保没有为 eth1 运行 dhcpcd 实例,否则删除的地址可能会被重新分配。

eth1 接口删除地址和路由

# ip addr del address dev eth1
# ip route del address dev eth1

现在必须设置先前配置的桥接的 IP 地址和路由。这通常通过为此接口启动 DHCP 客户端来完成。否则,请查阅 网络配置 以进行手动配置。

桥接配置后托管服务器无网络连接

本文或章节需要语言、Wiki 语法或样式改进。请参阅 Help:Style 以供参考。

原因: “托管服务器”不是一个普遍明显的术语。(在 Talk:Network bridge 中讨论)

由于桥接的 MAC 地址不一定等于服务器通常使用的网卡的 MAC 地址,因此服务器提供商可能会丢弃从桥接传出的流量,从而导致在桥接(例如服务器以太网接口)时失去连接。因此,可能需要将桥接配置为克隆以太网接口的 mac 地址以用于托管服务器。

连接到常用连接后无法连接到桥接连接

在 Network Manager 小程序中,如果您有常用的以太网/无线连接(不是桥接从属连接),并且如果您首先连接到它,然后尝试连接到桥接连接(无论是否先断开与常用连接的连接),则您无法连接到它。由于某种原因,即使启用了自动连接复选框,桥接从属连接(未在网络小程序中列出)也未激活。

解决方法是通过终端手动激活它

nmcli connection up br1\ slave\ 1

然后您的桥接连接立即工作。

本文或章节需要扩充。

原因: 是否有关于此的错误报告?(在 Talk:Network bridge 中讨论)

桥接似乎在网络的一侧无法工作

参见 QEMU#内部网络

参见