我的/etc/network/interfaces:
auto eth0
iface eth0 inet static
address 192.168.3.75
netmask 255.255.255.0
gateway 192.168.3.0
情况 1:
Linux 启动后我设置了一个 IP 别名:ifconfig eth0:0 192.168.3.111
现在报告两个ifconfig
IP192.168.3.75
地址eth0
192.168.3.111
eth0:0
当我将主 IP 更改为另一个网络时:ifconfig eth0 192.168.1.111
别名eth0:0
是丢失的!
情况 2:
Linux 启动后我设置了一个 IP 别名:ifconfig eth0:0 192.168.4.111
现在报告两个ifconfig
IP192.168.3.75
地址eth0
192.168.4.111
eth0:0
当我将主 IP 更改为另一个网络时:ifconfig eth0 192.168.1.111
别名eth0:0
停留!
我该如何正确更改主 IP,以免丢失所有别名?
答案1
解决方案很简单:停止使用史前的ifconfig
。它已被弃用,并且使用已弃用的 ioctl API。您遇到的是内核的兼容层,它试图推断ifconfig
和route
不提供的信息。
ip
从包装中使用。无论如何,iproute2
这就是现代人所做的(看看我在说什么)。ifupdown
ifup -v eth0
ip
并且 rtnetlink 具有向接口添加多个 IP 地址的本机功能,而无需使用诸如不是接口也不是别名的接口别名之类的过时的黑客技术。
哦,顺便说一句:现代ifupdown
应该能够支持这一点:
auto eth0
iface eth0 inet static
address 192.168.3.75
netmask 255.255.255.0
gateway 192.168.3.0
iface eth0 inet static
address 192.168.3.111
netmask 255.255.255.0
并且它应该能正确执行。请进行测试以ifup -v eth0
确保无误。
为什么兼容层会这样破坏?这很简单。考虑一下用户期望系统运行时做什么ifconfig eth0 192.0.2.42
:
- 用户是否要将 192.0.2.42 IP 地址添加到可用地址列表中?
- 用户是否要重置接口的现有地址以使其仅具有 192.0.2.42 地址?
有时,用户想要第一个选项。有时,他们想要第二个选项(例如,当完全更改配置时)。但是 SIOCSIFADDR ioctl 没有定义语义。
使用 rtnetlink 不会出现歧义:您可以管理不同类型的地址列表(IPv4、IPv6……),并使用 RTM_NEWADDR 添加地址,使用 RTM_DELADDR 删除现有地址(如果您指定一个)或接口的所有地址。
是ip
rtnetlink API 的薄包装器:
- 用于
ip addr add 192.168.3.111/24 dev eth0
添加地址。 - 用于
ip addr del 192.168.3.111/24 dev eth0
删除地址。如果地址不存在,操作将失败。 - 用于
ip -4 addr flush dev eth0
删除所有 ipv4 地址。
您可以用同样的方式管理 IPv6 地址。考虑到在一个接口上拥有多个 IPv6 地址只是正常行为,这非常方便。