Red Hat Bugzilla – Bug 1054178
initscripts' /usr/lib/sysctl.d/00-system.conf is pointless
Last modified: 2014-07-23 14:31:22 EDT
Description of problem:
I use bridged networking so I wanted to make sure that forwarding is enabled and packets take a shortcut around iptables:
$ cat /etc/sysctl.d/ip-forward.conf
net.ipv4.conf.all.forwarding = 1
net.ipv6.conf.all.forwarding = 1
net.bridge.bridge-nf-call-arptables = 0
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
but after boot, all bridge-nf-call-*tables variables are set to "1". I suspected weird rules of *sysctl.d/*conf files merging (why bother at all with /etc/sysctl.d when the file in there may be overriden by file in /usr!?) but that wasn't the case either - /usr/lib/sysctl.d/00-system.conf also set these variables to "0".
when I run explicitly "SYSTEMD_LOG_LEVEL=debug SYSTEMD_LOG_LEVEL=debug /usr/lib/systemd/systemd-sysctl" as suggested in bug 924433 comment 3, the variables are set exactly as expected:
# SYSTEMD_LOG_LEVEL=debug /usr/lib/systemd/systemd-sysctl
Setting 'net/bridge/bridge-nf-call-ip6tables' to '0'
Setting 'net/bridge/bridge-nf-call-iptables' to '0'
Setting 'net/bridge/bridge-nf-call-arptables' to '0'
Setting 'kernel/sysrq' to '16'
Setting 'kernel/core_uses_pid' to '1'
Setting 'net/ipv4/conf/default/rp_filter' to '1'
Setting 'net/ipv4/conf/default/accept_source_route' to '0'
Setting 'fs/protected_hardlinks' to '1'
Setting 'fs/protected_symlinks' to '1'
Setting 'net/ipv4/conf/all/forwarding' to '1'
Setting 'net/ipv6/conf/all/forwarding' to '1'
Setting 'fs/aio-max-nr' to '1048576'
so my conclusion is that both system-provided /usr/lib/sysctl.d/00-system.conf and my own /etc/sysctl.d/ip-forward.conf files are silently ignored.
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. place some sysctl setting to /etc/sysctl.d/myfile.conf, make sure it gets applied when you invoke: SYSTEMD_LOG_LEVEL=debug /usr/lib/systemd/systemd-sysctl
sysctl configuration is ignored
sysctl configuration should be applied
Most probably, when sysctl is run at boot, bridge module hasn't been loaded yet and those settings are ignored. At my machine, the bridge module is loaded when NetworkManager does its thing, so much later.
> /usr/lib/sysctl.d/00-system.conf also set these variables to "0".
That is pointless. This file is misleading, since those settings are usually no-ops because of timing issues.
See Bug 634736 for more frustrated discussion of this topic (not sure why it's still assigned to bridge-utils, I actually assumed that the bridge-utils people would send it somewhere else if it was out of their jurisdiction, which it does seem to be).
The problem is most easily evident to users of libvirt "virtual networks" as these networks use transient host bridges that are created when libvirtd starts, which is later than the network/NetworkManager service, as well as being later than when sysctl -p is run (but of course sysctl -p only updates the settings in /etc/sysctl.conf anyway).
I can see 3 possible solutions to this problem, and none of them are acceptable to everybody:
1) build the bridge module into the kernel rather than being loadable
(this would cause problems for anybody who built their own kernel and found that the bridge tunables were no longer being set)
2) change the default config to always load the bridge module, and do so at an early enough time in the boot that the settings from the sysctl.conf files would be applied.
(this is bound to upset people who don't use any bridge devices and are ultra sensitive about memory usage)
3) "do something" to automatically rescan the sysctl.conf files whenever a module is loaded, and pick up any settings related to that module. systemd supposedly does this for tunables related to a specific network interface, so it would make sense for them to do it for the bridge module as well; I don't know if the necessary "anchor" for a hook exists though. Did the systemd people consider this option before re-assigning the bug to initscripts?
Probably the best option is to write an udev rule:
I've hit the same very issue in CentOS7! I'd be glad to see it fixed. ;-)
There is nice workaround in bug 634736#c12 . Don't forget to rebuild initramfs with # dracut --force after you put the file into the modules.d
I don't think it's correct to say the sysctl defaults are 'useless'. The private comment on this bug notes, which I don't think is private, that everything except the bridge module which has tunables is built into Fedora/RHEL kernels, so other things don't suffer from this problem.
Given that, this is effectively a dupe of #634736, and I think the sensible fixes are either to implement a mechanism to load sysctl configs whenever a module is loaded (as suggested by Edgar in https://bugzilla.redhat.com/show_bug.cgi?id=634736#c7 ), do something even smarter in the kernel (as suggested by Edgar in https://bugzilla.redhat.com/show_bug.cgi?id=634736#c9 ), or just build bridge in instead of building it as a module (and look out for similar situations in future, with a policy that anything that has tunables gets built in).
*** This bug has been marked as a duplicate of bug 634736 ***