我有一个通过 IPv6 自动配置发布 IPv6 地址的网络。为了允许 DNS 查找并拥有理想的 IP 地址,我们通过 /etc/network/interfaces 设置“静态”IPv6 地址:
auto eth0
iface eth0 inet dhcp
iface eth0 inet6 static
address a:b:c:d:e::f
netmask 64
每当我们通过 IPv6 连接时,Linux 都会使用 IPv6 自动配置地址:
a:b:c:d:21d:60ff:fe4a:479
而不是静态 IPv6 地址:
a:b:c:d:e::f
另一端的服务器只能看到自动配置地址。
有没有办法强制 Linux(Debian/Ubuntu)使用静态地址发送数据包?这对于反向 DNS 和防火墙设置尤其有用。
我不想禁用 IPv6 自动配置,因为我无法控制路由器通告的设置。
答案1
当然,防止使用 autoconf 地址的最简单方法是通过执行以下操作来阻止内核创建它们:
echo 0 >/proc/sys/net/ipv6/conf/eth0/autoconf
请注意,这并不要求您重新配置路由器,以便它停止发出前缀的广告。
笔记在评论中,您谈到了/etc/gai.conf
,但这并不适用。这是 glibc 的配置文件,而不是内核的配置文件,它影响目标地址选择,而不是源地址选择。
如果您仍希望保留 autoconf 地址但不想使用它们,请继续阅读...
用于同一网络上的主机之间的通信
我找不到一个好方法来强制地址选择优先选择静态地址而不是 autoconf 地址。通过查看RFC 3484他们都没有真正起到帮助。
您可以尝试更改所连接子网的路由表中的 /64 路由,以使其具有“src”属性,但是当子网中的任何地址添加到接口时,内核会自动生成该路由,而我事后无法对其进行编辑。
用于与互联网其他主机的通信
有多种方法可以影响出站连接的地址选择。最明显的方法是使用src
路由上的属性。例如:
ip route add ::/0 via <gateway> src <desired-source-IP-address>
但您的默认路由可能来自路由器通告消息,并由内核自动插入。在这种情况下,您无法为路由提供“src”属性。因此,这里有另一种方法,基于配置地址标签。
默认情况下,在Linux中,内核的地址标签表如下所示:
prefix ::1/128 label 0
prefix ::/96 label 3
prefix ::ffff:0.0.0.0/96 label 4
prefix 2001::/32 label 6
prefix 2001:10::/28 label 7
prefix 2002::/16 label 2
prefix fc00::/7 label 5
prefix ::/0 label 1
这个想法是,当启动一个带有标签的目标地址的数据包时x
,内核会优先使用具有相同标签的源地址x
。例如,如果你将一个数据包发送到一个带有 6to4 地址的主机(即 2002::/16 中的地址),该地址的标签为 2,并且内核将优先为传出的数据包选择一个 6to4 源地址(如果有可用的话)。
常规 IPv6 目标获得标签 1(::/0,匹配所有内容)。以下是您要执行的操作:
- 覆盖本地子网的标签分配,以便本地子网上的地址获得“martian”标签(其他任何地址都未使用的标签)。此规则将匹配整个子网,因此它将是 /64。
- 重新覆盖所需静态地址的标签分配,将其重新设置为 1(即,与其余 Internet 地址获得的标签相同)。此规则将仅匹配特定的所需地址,因此它将是 /128。
这样,本地子网上的所有 autoconf 地址都将获得一个火星标签,该标签与互联网上任何其他标签都不匹配,因此它们将不会被优先考虑,而所需源地址的标签将为 1,因此它将与目标地址匹配并被选中。
如果您的前缀是 2001:db8::/64 并且您选择的静态地址是 2001:db8::aaaa/128,那么:
ip addrlabel add prefix 2001:db8::/64 label 99
ip addrlabel add prefix 2001:db8::aaaa/128 label 1
您可以将这两个命令添加为up
命令,/etc/network/interfaces
以便每次界面出现时都会执行它们。