问题描述
我有一个通过IPv6自动配置发布IPv6地址的网络。为了允许DNS查找并拥有精美的IP地址,我们通过/etc /network /interfaces设置了”static” 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自动配置,因为我无法控制路由器发布的设置。
最佳思路
当然,防止使用自动配置地址的最简单方法是通过执行以下操作来防止内核创建地址:
echo 0 >/proc/sys/net/ipv6/conf/eth0/autoconf
请注意,这不需要您重新配置路由器,以使其停止发出该前缀的广告。
注意在注释中,您谈论的是/etc/gai.conf
,但这不适用。这是glibc的配置文件,而不是内核,它会影响目标地址的选择而不是源地址的选择。
如果您仍然希望拥有自动配置地址,但又不想被使用,请继续阅读…
用于同一网络上主机之间的通信
我找不到一种强迫地址选择优先于静态地址而不是自动配置的好方法。通过查看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。
-
Re-override所需静态地址的标签分配,将其设置回1(即,与其余Internet地址获得的标签相同)。该规则将仅匹配特定的所需地址,因此它将为/128。
这样,本地子网上的所有这些自动配置地址都将获得火星人的标签,该标签与互联网上的其他任何标签都不匹配,因此将不会被使用,而所需源地址的标签将是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
您可以将这两个命令添加为/etc/network/interfaces
中的up
命令,以便每次接口出现时都将执行它们。