在 sysctl 中,这些/proc/sys/net/ipv[46]/conf/
键具有以下子键:all
、default
和每个网络接口的键。例如,在具有单个网络接口 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/
所有相应的设置分别存在于每个键中。例如,如果我想使用该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
我现在的问题是:我需要更改哪些值?我想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
机器现在是否接受 eth0 上的路由器通告?
答案1
我在写问题的同时就找到了答案。无论如何,我决定发布它,因为其他人可能会觉得这很有洞察力,然后我自己回答;我希望这不会让人皱眉:)
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.
他没有介绍accept_ra
,但至少现在很清楚它们是如何工作all
的default
,或者更确切地说,它们如何不像我预期的那样工作。
答案2
我将为这个问题提供一个新的答案,因为许多谷歌搜索结果都指向这里,并且互联网上有很多关于此的过时信息和错误信息。
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.txt或者https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/networking/ip-sysctl.txt?h=linux-4.15.y (在右上角选择您的特定内核版本)。
例如,值rp_filter
将被最大化(如前所述,不是 AND 运算):
The max value from conf/{all,interface}/rp_filter is used
when doing source validation on the {interface}.
arp_filter
, 另一方面,是或运算:
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
但是关于accept_ra
?出色地,内核 4.15 文档没有说明这种情况下的行为,并且实际上不再允许基于每个接口 IIRC。它曾经在内核 2.6(CentOS 6 等)中被允许。
答案3
accept_ra
in的处理程序net/ipv6/addrconf.c
是proc_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
我迟到了大约 4 年,但这是正确的答案:P