/proc/sys/net/ipv[46]/conf/ 中的“all”、“default”和“eth*”有什么区别?

Mar*_*ich 40 linux proc ipv6 sysctl

在的sysctl,所述/proc/sys/net/ipv[46]/conf/键具有以下子项:alldefault,和每个网络接口的密钥。例如,在具有单个网络接口 eth0 的机器上,它将如下所示:

iserv ~ # ll /proc/sys/net/ipv[46]/conf/
/proc/sys/net/ipv4/conf/:
insgesamt 0
dr-xr-xr-x 0 root root 0 12. Sep 23:30 all/
dr-xr-xr-x 0 root root 0 12. Sep 23:30 default/
dr-xr-xr-x 0 root root 0 12. Sep 23:30 eth0/
dr-xr-xr-x 0 root root 0 12. Sep 23:30 lo/

/proc/sys/net/ipv6/conf/:
insgesamt 0
dr-xr-xr-x 0 root root 0 12. Sep 23:30 all/
dr-xr-xr-x 0 root root 0 12. Sep 23:30 default/
dr-xr-xr-x 0 root root 0 12. Sep 23:30 eth0/
dr-xr-xr-x 0 root root 0 12. Sep 23:30 lo/
Run Code Online (Sandbox Code Playgroud)

所有相应的设置分别存在于每个键中。例如,如果我想使用该accept_ra值禁用 IPv6 路由器广告,则该值存在四次:

iserv ~ # sysctl -a 2>/dev/null | grep "accept_ra "
net.ipv6.conf.all.accept_ra = 1
net.ipv6.conf.default.accept_ra = 1
net.ipv6.conf.lo.accept_ra = 1
net.ipv6.conf.eth0.accept_ra = 1
Run Code Online (Sandbox Code Playgroud)

我现在的问题是:我需要更改这些值中的哪些?我想all(更改所有现有接口)和default(更改以后可能出现的所有新接口),但是更改这些仍然会使 lo 和 eth0 的值保持为 1:

iserv ~ # sysctl -w net.ipv6.conf.all.accept_ra=0
net.ipv6.conf.all.accept_ra = 0
iserv ~ # sysctl -w net.ipv6.conf.default.accept_ra=0
net.ipv6.conf.default.accept_ra = 0
iserv ~ # sysctl -a 2>/dev/null | grep "accept_ra "  
net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.default.accept_ra = 0
net.ipv6.conf.lo.accept_ra = 1
net.ipv6.conf.eth0.accept_ra = 1
Run Code Online (Sandbox Code Playgroud)

机器现在会接受 eth0 上的路由器广告,还是不会?

Mar*_*ich 40

我在写问题的同时找到了答案。无论如何我决定发布它,因为其他人可能会觉得这很有见地,然后自己回答;我希望这不会让人皱眉:)

linux-kernel 邮件列表上的用户 Philipp Matthias Hahn 至少部分地发现了这一点

As far as I researched for IPv4 some time ago, the "default" value gets
copied to newly created interfaces only once.
"all" on the other hand allways gets applied in addition to the current
setting, but it depends on the exact setting, if its ORed, ANDed, or
whatevered:
    log_martians         OR
    accept_redirects     AND
    forwarding           ?
    mc_forwarding        AND
    medium_id
    proxy_arp            OR
    shared_media         OR
    secure_redirects     OR
    send_redirects       OR
    bootp_relay          AND
    accept_source_route  AND
    rp_filter            AND
    arp_filter           OR
    arp_announce         MAX
    arp_ignore           MAX
    arp_accept
    app_solicit
    disable_policy
    disable_xfrm
    tag
(see include/linux/inetdevice.h:83 for IN_DEV_{AND,OR,MAX}CONF)

Putting a new value in "all" doesn't change the value you read from
"$interface", but it only gets computed and used internally.
Run Code Online (Sandbox Code Playgroud)

他没有涵盖accept_ra但至少现在很清楚如何alldefault工作,或者更确切地说,他们如何不像我预期的那样工作。

  • 和 IPv6 的东西?例如,我正在寻找 `use_tempaddr` 参数... (3认同)
  • rp_filter 逻辑在 9 年前改变了。以前它是ANDed,然后更改为MAX。请参阅“在 {interface} 上进行源验证时使用来自 conf/{all,interface}/rp_filter 的最大值。” 在 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/networking/ip-sysctl.txt?h=v4.9#n1090 和 https:// /github.com/torvalds/linux/commit/27fed4175acf81ddd91d9a4ee2fd298981f60295(通过https://unix.stackexchange.com/a/427455/18568) (3认同)

Ste*_*ski 8

我将为这个问题提供一个新的答案,因为许多谷歌搜索结果都指向这里,并且互联网上有很多关于此的过时信息和错误信息。

net.ipv{4,6}.conf.default.*

@Martin von Wittich 关于行为的正确性default——它仅适用于新接口。对于主机接口,该default设置仅在创建新设备时应用,并且主机接口传统上仅在引导时创建。因此,如果您只是更改参数,则在主机重新启动之前,default该值不会应用到主机接口。

容器、Kubernetes 和 CNI的行为有所不同。新的容器接口一直在创建。因此,如果您只是更改default参数,它将应用于新容器创建的新接口,但不适用于现有容器接口和主机接口。这可能会非常令人困惑!

net.ipv{4,6}.conf.all.*net.ipv{4,6}.conf.<net device>.*

正如 @gaia 和 @odivlad 所指出的, ,的行为net.ipv{4,6}.conf.all.*根据要更改的参数而有所不同。真正的答案在内核的文档中,并且随着时间的推移而发生变化(与 一样rp_filter,它是多宿主系统的流行参数)。马丁上面的答案是正确的,但现在已经过时了。

此功能的行为记录在内核文档中,您可以在https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txthttps://git.kernel.org/pub找到该文档/scm/linux/kernel/git/stable/linux.git/tree/Documentation/networking/ip-sysctl.txt?h=linux-4.15.y (在右上角选择您的特定内核版本)。

例如, 的值rp_filter将被 MAXed(而不是前面所述的 ANDed):

The max value from conf/{all,interface}/rp_filter is used
when doing source validation on the {interface}.
Run Code Online (Sandbox Code Playgroud)

arp_filter另一方面,是 OR 运算

arp_filter for the interface will be enabled if at least one of
conf/{all,interface}/arp_filter is set to TRUE,
it will be disabled otherwise
Run Code Online (Sandbox Code Playgroud)

但是关于accept_ra?好吧,内核 4.15 文档没有说明这种情况下的行为,并且实际上不再允许在每个接口的基础上再这样做 IIRC。它曾经在内核 2.6(CentOS 6 等)中被允许。

  • 感谢您提供更新!我已将此作为已接受的答案,以提高可见性。 (2认同)

sup*_*ami 6

accept_rain的处理程序net/ipv6/addrconf.cproc_dointvec。因此,通用接口代码之前已经生成了一个all特定于接口的条目数组,使用sysctl或 procfs写入这些条目只是将您指定的值放入数组中。

我们关心如何使用这些值

您将从ipv6_accept_ra()函数的调用者中看到include/net/ipv6.h,每个调用者都使用特定的接口来调用该函数。

因此net.ipv6.conf.all.accept_ra,据我所知,除了存储 procfs 条目之外,内核中没有任何地方可以使用。

如果你想accept_ra用一个命令改变每个界面,你可以这样做:

for TUNABLE in $(sysctl -aN --pattern "accept_ra$")
do
    sysctl -w "$TUNABLE=0"
done
Run Code Online (Sandbox Code Playgroud)

我迟到了大约 4 年,但这是正确的答案:P