Red Hat Bugzilla – Bug 295611
iptables setup broken with non-modular kernels
Last modified: 2007-11-30 17:12:16 EST
Description of problem:
The new init.d/iptables script is totally confused by a kernel with the iptables
support compiled in (or by an early loading of the modules).
The reason? The "start" case will decide that iptables has already been set up,
and doesn't bother doing it again.
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. Compile a kernel with the necessary filtering modules compiled in, or
load the modules by hand in single-user mode
2. Go into multi-user mode, which runs "/etc/rc.d/rc5.d/S26iptables start"
3. Notice how no iptables has been set up!
Empty iptables - with the associated security issues
Properly set up firewall
This worked before, including in Fedora 7
In Fedora7, the iptables "start)" case looks like this:
but in Fedora8-test2 it now looks like this:
[ $running -eq 0 ] && exit 0
and the "$running" has been set by the return value of "status", which will be a
success if there is already a table listed in PROC_IPTABLES_NAMES due to the
modules being compiled in.
I realize that this only happens when people compile their own kernels, but it's
still a major security hole. When iptables starts, it should fill in the
firewall, not decide to do nothing.
You can "fix" it by running "S26iptables restart", which will avoid the buggy
test for "the firewall already exists".
BTW, I think Fedora 7 was a *lot* safer in starting iptables *before* it started
networking. The move from S08 -> S26 seems to be a recipe for security disasters.
The init-script is S08 again. There was a wrong requirement to local_fs in the
Thanks, the S08->S26 switch was fixed in iptables-1.3.8-3.fc8,
but the basic problem with the lack of actual setup still remains.
You should be able to reproduce this even on a modular kernel by
just setting IPTABLES_MODULES_UNLOAD to "no" instead of "yes",
and then doing
because now the "start" will incorrectly think that the firewall is
already set up, so it will not set the firewall up!
NOTE! This is *different* from
which will work fine, because "restart" will do an unconditional start,
it's just plain "start" that is broken, because it has a totally wrong
check for whether the firewall is actually up and running or not!
I'll attach a suggested patch to this bugzilla entry (I only did it for
the iptables script, but ip6tables has the same bug).
Created attachment 203201 [details]
Suggested fix to /etc/init.d/iptables script
Here's a patch that looks sane, and I verified that it fixes
the problem for me.
Created attachment 204061 [details]
Init script patch
please have a look at the attached patch and test if it is working for you.
This makes it work for me, but I wonder why you selected the much more
complex and broken patch that still seems to think that "modules loaded"
has something to do with whether the firewall rules have been set up or
But the fact that you then add special tests for "if it's compiled in,
don't bother with the idiotic tests" at least makes it *work*. But why
do those incorrect tests in the first place? What does "modules loaded"
have to do with anything, really?
But yes, my particular bug is fixed.
The ip6tables script needs the same loving attention.
The "idiotic tests" are needed to be able to start and stop the firewall if it
was not configured with the init script. "iptables -L" loads the netfilter
modules and is often used to check if there is a firewall active.
The expected behaviour of "service iptables stop" is to stop the firewall, even
if only "iptables -L" was used. "service iptables start" should start the
firewall, even if there was a "iptables -L" call before. Your patch did not work
BTW: The ip6tables script is generated out of the iptables script.
Fixed in rawhide in package iptables-1.3.8-4 or newer.
If so, the real problem is that you're trying to re-use the same test
for two *totally* different things.
You seem to think that both "stop" and "start" should use the same
"running" test, but then you say that they have two totally different
behaviors. No wonder the script is broken.
So on "start" you should *only* check whether it was already running,
i.e. whether the lockfile exists. It does not matter whether the firewall
was active or not.
But you're also saying that "stop" should do something even if it was
*not* running. See? You're trying to use the same "$running" for both
cases, and all the trouble seems to come from that basic mistake. So
why do it?
So I'll attach an even simpler patch that actually matches what you seem
to say that the behaviour should be.
Created attachment 204311 [details]
An even simpler patch that seems to match what the bahaviour should be..
So why not something like this instead?
This just says:
- start (and "try-restart") should *only* happen when the lock-file doesn't
exist (ie it isn't already running). It has nothing to do with whether
modules are loaded or not, or indeed anything else.
- stop should stop the firewall and unload the modules if they are there,
and that in turn has nothing to do with whether the lock-file exists or
In other words, you cannot - and must not - try to use the same logic (just
reversed) for the two cases, since the two simply aren't mirror images!
Trying to use the same (reversed) test is what caused problems, and is what
made "compiled in" vs "modular" appear to be different. But they aren't
really different at all, what is different is that "start" and "stop" are
simply not mirror events according to you!
I don't really care, since your patch did work for me, but it seems much too
complex and fragile.
Btw, the older Fedora scripts worked fine, and they were even simpler, since
"start" just always did a restart, and "stop" just did a stop - with no
conditionals at all. I'm not sure why that was so bad either, and was changed
in the first place?
Fixed in rawhide in package iptables-1.3.8-4.1 or newer.
Thanks for the simple solution :-)