Debian

為什麼即使在配置 sysctl.conf 之後,IPv6 在重新啟動時也會被禁用?

  • October 21, 2020

首先,它讓我大吃一驚,有多少文章在 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

希望這是一個容易的。如果可以的話請幫忙!

我假設您正在使用這三個包來提供正在使用的選項:ifupdownbridge-utilsvlan。兩者後來提供了命令brctl和,都已過時,但更重要的是,它們為ifupdownvconfig提供了 Debian 特定的外掛腳本。雖然仍在這些腳本中使用,但甚至沒有使用(並被現代命令取代)。brctl``vconfig``ip link

問題是由橋實用程序腳本(而不是vlan包中的腳本)br0創建的 VLAN 子介面的父級事實引起的。

bridge -utils的ifupdown外掛腳本阻止網橋埠參與路由:

# ls -l /etc/network/if-pre-up.d/bridge
lrwxrwxrwx. 1 root root 29 Jan 28  2019 bridge -> /lib/bridge-utils/ifupdown.sh

這是一個 Debian 特定的腳本,屬於bridge-utils包。這是相關內容(抱歉,這是一個罕見的包,似乎不在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 子介面本身的父介面,該子介面本身受制於網橋。這是bridge-utils不期望的拓撲。

前面的腳本呼叫/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 的設置中,子介面是在配置中定義的,旨在通過vlan包中的外掛腳本在系統上創建,但由於沒有任何auto br0.5nor ,因此當bridge-utilsauto br0.90時介面不是在系統級別創建的的腳本已檢查,因此它執行塊:創建它們但首先在其父介面上禁用 IPv6。這裡重要的是不要將ifupdown所見的邏輯介面與系統上的真實介面混淆,儘管它們在幾乎所有設置中都具有相同的名稱。# port doesn't yet exist

解決方案

以下三種方法中的任何一種都應該得到預期的結果。我還建議使用第 4 種方法,但與 Docker 等應用程序的集成並不簡單。

  • 通過適應(相當過時的)bridge-utils包的特性來解決這個問題:提前調出配置的子介面,因此它們存在於系統級別。那麼上面的腳本不會在它們的父介面上禁用 IPv6(它不會匹配# port doesn't yet exist)。也不是來自這次創建 VLAN 子介面的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

並確保它發生在和的配置之前br5br90現在就是這種情況)。在此之後,只有這些介面將禁用 IPv6,因為它應該是:br0.5br0.90以及enp175s0f1enp175s0f0hostveth0

雖然這是一個簡單的更改,但如果以“錯誤的順序”使用它並不能防止以後出現問題,其中ifup可能會再次禁用 IPv6,或者某些應該禁用它的介面(埠)不會。唯一保證工作的順序是配置中的一個:ifdown``br0

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
  • 保持網橋僅作為網橋,並使用額外的一對veth介面,一端在網橋上,一端參與路由。這在橋接和路由之間提供了清晰的分離(並且不會受到任何副作用,例如在使用 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 是 debian 的網路介面管理器 ifupdown 的新實現。它了解介面依賴關係,簡化介面配置,擴展 ifquery 以支持介面配置驗證,支持 JSON 等。

它具有內置的網橋和 VLAN 處理功能,不再依賴bridge-utilsvlan包。

像往常一樣,管理網路的切換工具可能會導致連接問題,因此請使用遠端控制台訪問。

保持您的配置原樣應該可以正常工作,但是從ifupdown2interfaces(5)版本中的評論來看:

內置介面

ifupdown 可以理解某些介面的 iface 部分,例如點表示法的物理介面或 vlan 介面(如 eth1.100)。 如果這些介面依賴於其他介面並且不需要任何特定配置(如地址等**),則這些介面不需要介面文件中的條目。**

br0.5您應該從配置中完全刪除定義br0.90(當然在bridge_ports條目中除外)。

這樣的配置將再次使 IPv6 僅在橋接埠上被禁用:br0.5br0.90enp175s0f1enp175s0f0hostveth0我仍然預計使用任意ifdown/ifup命令時可能會出現問題。

這應該是最好的設置,但目前沒有多少應用程序支持在網橋埠上配置 VLAN ID(例如:使用bridge vlan命令)。我不認為 Docker 支持這一點,所以這對 OP 的設置沒有用。

引用自:https://serverfault.com/questions/1038857