首先,我很好奇有多少文章在强制关闭 Linux 服务器上的 IPv6。来吧,大家,赶快行动起来吧!:D
root@hodor:~# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 10 (buster)
Release: 10
Codename: buster
root@hodor:~# uname -a
Linux hodor 4.19.0-8-amd64 #1 SMP Debian 4.19.98-1 (2020-01-26) x86_64 GNU/Linux
我遇到了一个重复出现的问题,在重新启动后,我的一个桥接接口和该桥接的所有子/从属接口都禁用了 IPv6。这导致在主机上设置 ipv6 地址失败等。这是我看到的
net.ipv6.conf.br0.disable_ipv6 = 1
net.ipv6.conf.enp175s0f0.disable_ipv6 = 1
net.ipv6.conf.enp175s0f1.disable_ipv6 = 1
net.ipv6.conf.hostveth0.disable_ipv6 = 1
我在 /etc/sysctl.d/* 中找不到任何相关内容。这是我的 sysctl.conf:
root@hodor:~# grep -v ^\# /etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.br0.disable_ipv6 = 0
net.ipv6.conf.br0/5.disable_ipv6 = 0
net.ipv6.conf.br0/90.disable_ipv6 = 0
net.ipv6.conf.enp175s0f0.disable_ipv6 = 0
net.ipv6.conf.enp175s0f1.disable_ipv6 = 0
net.ipv6.conf.hostveth0.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0
net.ipv6.conf.all.disable_ipv6 = 0
之后sysctl -p
我可以手动设置我的 ipv6 并修复所有其他小细节,但这很糟糕。
也认为也许 grub 是我的罪魁祸首,但我没有看到任何与这个内核参数有关的内容。
root@hodor:~# grep -v ^\# /etc/default/grub
GRUB_DEFAULT=0
GRUB_TIMEOUT=1
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX="console=tty1 console=ttyS0,115200 intel_iommu=on"
GRUB_TERMINAL="console serial"
GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
这是 /etc/network/interfaces(已混淆),并且没有任何内容 /etc/network/interfaces.d/:
source /etc/network/interfaces.d/*
auto lo
auto enp5s0
auto enp6s0
iface lo inet loopback
iface enp5s0 inet manual
iface enp6s0 inet manual
auto enp175s0f0
iface enp175s0f0 inet manual
auto enp175s0f1
iface enp175s0f1 inet manual
auto br0
iface br0 inet static
bridge_ports enp175s0f1 enp175s0f0 hostveth0
bridge_stp off
bridge_maxwait 5
address 172.16.10.35
netmask 255.255.254.0
gateway 172.16.10.1
dns-nameservers 172.16.10.1
hwaddress ether 9e:7d:01:6c:32:1b
pre-up ip link add name hostveth0 type veth peer name dockerveth0
pre-up ip link set hostveth0 up
pre-up ip link set dockerveth0 up
iface br0 inet6 static
address 2600:####:####:###0::face/64
dns-nameservers 2600:####:####:###0::1
gateway 2600:####:####:####0::1
auto virttap0
iface virttap0 inet manual
pre-up modprobe dummy
pre-up ip link add name virttap0 type dummy
post-up ip link set virttap0 arp on multicast on
iface br0.5 inet manual
vlan-raw-device br0
iface br0.90 inet manual
vlan-raw-device br0
auto br5
iface br5 inet manual
bridge_ports br0.5
bridge_stp off
bridge_maxwait 5
auto br90
iface br90 inet manual
bridge_ports br0.90
bridge_stp off
bridge_maxwait 5
希望这很简单。如果可以的话请帮忙!
答案1
我假设您正在使用这三个包来提供正在使用的选项:下拉,桥梁工具,虚拟局域网。后面两个提供了命令brctl
和vconfig
,都已经过时了,但更重要的是它们提供了 Debian 特定的插件脚本来下拉。虽然brctl
在这些脚本中仍然使用,但vconfig
甚至不再使用(并被现代ip link
命令取代)。
问题是由于 是br0
VLAN 子接口的父级,而该子接口是由桥梁工具脚本(不是来自虚拟局域网包裹)。
这桥梁工具的下拉插件脚本阻止桥接端口参与路由:
# ls -l /etc/network/if-pre-up.d/bridge
lrwxrwxrwx. 1 root root 29 Jan 28 2019 bridge -> /lib/bridge-utils/ifupdown.sh
这是一个 Debian 特定的脚本,属于桥梁工具包。以下是相关内容(抱歉,这是一个罕见的包,似乎不在https://salsa.debian.org,因此没有链接):
if [ -f /proc/sys/net/ipv6/conf/$port/disable_ipv6 ] then echo 1 > /proc/sys/net/ipv6/conf/$port/disable_ipv6 fi
这是桥接端口所需的设置。
但在 OP 的设置中,桥接接口旨在接收地址以参与路由,并成为 VLAN 子接口的父接口,而子接口本身又隶属于桥接。这是 OP 所不希望的拓扑桥梁工具。
上述脚本调用/lib/bridge-utils/bridge-utils.sh
包括:
create_vlan_port() { # port doesn't yet exist if [ ! -e "/sys/class/net/$port" ] then local dev="${port%.*}" # port is a vlan and the device exists? if [ "$port" != "$dev" ] && [ -e "/sys/class/net/$dev" ] then if [ -f /proc/sys/net/ipv6/conf/$dev/disable_ipv6 ] then echo 1 > /proc/sys/net/ipv6/conf/$dev/disable_ipv6 fi ip link set "$dev" up ip link add link "$dev" name "$port" type vlan id "${port#*.}" fi fi }
当子接口不存在时(因为使用此脚本根本不需要创建配置),其父接口将被禁用 IPv6(而端口本身将从上一个脚本中禁用它),原因与桥接情况类似:父接口应该只承载 VLAN 标记流量,因此可以防止干扰任何路由,例如通过接收自动 IPv6 地址。这也是通常这是一个理想的设置,但不适用于 OP 的情况,因为 OP 要求同一个接口同时承载标记和未标记的流量。
在 OP 的设置中,子接口在配置中定义,并打算通过来自以下插件脚本在系统上创建:虚拟局域网包,但由于没有任何auto br0.5
,因此auto br0.90
接口不是在系统级别创建的桥梁工具的脚本已检查,因此它执行以下# port doesn't yet exist
块:创建它们,但首先禁用其父接口上的 IPv6。这里重要的是不要混淆如图所示的逻辑接口下拉与系统上的真实界面,尽管它们在几乎所有设置中都有相同的名称。
解决方案
以下三种方法中的任何一种都应该能得到预期的结果。我还建议使用第四种方法,但与 Docker 等应用程序的集成并不简单。
通过适应(相当过时的)的特性来解决这个问题桥梁工具包:提前调出配置的子接口,这样它们就存在于系统级别。然后上面的脚本不会在其父接口上禁用 IPv6(它不会匹配
# port doesn't yet exist
)。来自虚拟局域网这次创建了 VLAN 子接口的包。auto br0.5 iface br0.5 inet manual vlan-raw-device br0 auto br0.90 iface br0.90 inet manual vlan-raw-device br0
并确保它在配置
br5
和之前发生br90
(现在就是这种情况)。此后,只有这些接口将禁用 IPv6,正如应该的那样:br0.5
,br0.90
以及enp175s0f1
,,enp175s0f0
。hostveth0
ifup
虽然这是一个简单的更改,但如果和ifdown
以“错误的顺序”使用,它不会阻止以后出现问题,br0
在这种情况下,IPv6 可能会再次被禁用,或者一些应该禁用的接口(端口)不会被禁用。唯一保证有效的顺序是配置中的顺序:ifdown br90 ifdown br5 ifdown br0.90 # even if they have now disappeared from the system ifdown br0.5 # they are still up for ifupdown's logic ifdown br0 ifup br0 ifup br0.5 ifup br0.90 ifup br5 ifup br90
保持桥梁仅仅是桥梁,并使用额外的一对韦特接口,一端位于桥接器上,一端参与路由。这样可以清晰地区分桥接器和路由器(并且不会产生任何副作用,例如使用 Docker 时,但同时可能需要更改您当前的 Docker 设置):
auto routing0 iface routing0 inet static pre-up ip link add name routing0 address 9e:7d:01:6c:32:1b type veth peer name br0routing0 || : address 172.16.10.35 netmask 255.255.254.0 gateway 172.16.10.1 dns-nameservers 172.16.10.1 iface routing0 inet6 static address 2600:####:####:###0::face/64 dns-nameservers 2600:####:####:###0::1 gateway 2600:####:####:####0::1 auto br0 iface br0 inet manual bridge_ports br0routing0 enp175s0f1 enp175s0f0 hostveth0 bridge_stp off bridge_maxwait 5 pre-up ip link add name hostveth0 type veth peer name dockerveth0 || : pre-up ip link set hostveth0 up pre-up ip link set dockerveth0 up
我不知道硬件地址是新的(在上述配置中假设)还是属于enp175s0f1并且由于某种原因需要它(在这种情况下
routing0
不能使用它,并且为了避免复杂性,不要使用此解决方案)。您可能必须调整br0
其配置中任何不相关服务的配置并使用routing0
。切换到ifupdown2这是一个下拉完全重新实施Cumulus 网络提供运行 Linux 的交换机和路由器:
ifupdown2 是 debian 网络接口管理器 ifupdown 的新实现。它理解接口依赖关系、简化接口配置、扩展 ifquery 以支持接口配置验证、支持 JSON 等。
它具有内置桥接和 VLAN 处理功能,并且不依赖于桥梁工具或者虚拟局域网包裹了。
通常,切换管理网络的工具可能会导致连接问题,因此需要进行远程控制台访问。
保持配置原样应该可以正常工作,但是从此评论来看ifupdown2的版本接口(5):
内置接口
ifupdown 可以理解某些接口(例如物理接口或点表示法的 vlan 接口(例如 eth1.100))的 iface 部分。 如果这些接口依赖于其他接口,则它们不需要在接口文件中输入条目并且不需要任何特定配置,如地址等。
您应该从配置中完全删除
br0.5
和的定义(当然条目除外)。br0.90
bridge_ports
此类配置将再次仅在桥接端口上禁用 IPv6:,
br0.5
以及br0.90
,,enp175s0f1
。enp175s0f0
我hostveth0
仍然预计在使用任意ifdown
/ifup
命令时可能出现问题。仅建议:ifupdown2也可以是配置为使用 VLAN 感知桥接器,将设置变成一桥梁和零VLAN子接口。
这应该是最好的设置,但目前没有多少应用程序支持在桥接端口上配置 VLAN ID(例如:使用
bridge vlan
命令)。我认为 Docker 不支持这个功能,所以这对 OP 的设置来说没用。
答案2
我最终按照上面@AB 的建议得到了这个工作:
“切换到 ifupdown2,这是由 Cumulus Networks 制作的 ifupdown 完全重新实现,它提供运行 Linux 的交换机和路由器:”
从 ifupdown 切换到 ifupdown2 时,我们学到了很多教训:
- 正如 @AB 所警告的,从 ifupdown 升级到 ifupdown2 时立即出现了网络问题。主要问题是我的接口被重命名(交换)。enp175s0f0 变成了 enp175s0f1,反之亦然。大约 45 分钟的 tcpdump 等让我在这里找到了解决方案。
- 自 2020 年 10 月 21 日起,Debian 存储库提供了旧版本的 ifupdown2
# apt-cache madison ifupdown2
ifupdown2 | 1.2.5-1 | http://deb.debian.org/debian buster/main amd64 Packages
ifupdown2 | 1.2.5-1 | http://deb.debian.org/debian buster/main i386 Packages
ifupdown2 | 1.2.5-1 | http://deb.debian.org/debian buster/main Sources
我试用这个版本后感到非常沮丧,仍然无法让 /etc/network/interfaces 中的配置为我的网桥或任何接口分配 IPv6 地址。这里不讨论语法,因为语法在更高版本上有效。请...从这里轻松编译最新的 .deb:Cumulus Github使用此版本 ifupdown2(ver.3) 后,我的 /etc/network/interfaces 配置文件在我的接口上生成了所需的 IPv6 IP。
- 重要的是要注意@AB 关于“内置接口”的警告,当指定现有的接口时,没有对它们进行进一步的配置,例如
auto enp175s0f0
并iface enp175s0f0 inet manual
导致奇怪的问题,特别是我的 KVM 客户机无法自动启动;并且由于其中一个使用 PCI 直通 NIC,这些 NIC 决定从基础设施中提取 IPv4 和 IPv6 地址,这让我更加困惑。 - DNS...我的 /etc/network/interfaces 中的 DNS 条目被完全忽略,我费了很大劲才找到正确的方法使用 ifupdown2 设置 DNS 设置。
- 我尝试过使用 NetworkManager 并最终将其删除,但仍然不允许我使用 /etc/network/interfaces 设置 DNS...
- 我一直都知道,在现代 Linux 系统上,您无法手动编辑 /etc/resolv.conf,因为这些条目最终会被 NetworkManager 或 ifupdown(2) 或其他程序覆盖。Debian 文档中有关此事的内容
- 我了解到 ifupdown2 利用包 resolvconf 来解释 /etc/network/interfaces 中的 dns 设置并将其部署到 /etc/resolv.conf。 仅仅因为您有目录 /etc/resolvconf/ 并不意味着您已经安装了 resolvconf 包!你必须安装它。之后我就可以开始做生意了。
这是我的最终 /etc/network/interfaces(简单得多):
grep -v ^\# /etc/network/interfaces
source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
auto br0
iface br0 inet manual
bridge_ports enp175s0f1 enp175s0f0 hostveth0
bridge_stp off
bridge_maxwait 5
up echo $IFACE is up;
address 172.16.10.35/23
address 2600:####:####:###0::face/64
gateway 172.16.10.1
gateway 2600:####:####:###0::1
dns-nameservers 172.16.10.1 2600:####:####:###0::1
dns-search ####.tld
hwaddress ether 9e:7d:01:6c:32:1b
pre-up ip link add name hostveth0 type veth peer name dockerveth0
pre-up ip link set hostveth0 up
pre-up ip link set dockerveth0 up
auto virttap0
iface virttap0 inet manual
pre-up modprobe dummy
pre-up ip link add name virttap0 type dummy
post-up ip link set virttap0 arp on multicast on
auto br5
iface br5 inet manual
bridge_ports br0.5
bridge_stp off
bridge_maxwait 5
auto br90
iface br90 inet manual
bridge_ports br0.90
bridge_stp off
bridge_maxwait 5