Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 27087

Summary: iptables init.d script should be 'before net' not 'need net'
Product: Gentoo Linux Reporter: Michael C. Ferguson <michael.christopher.ferguson>
Component: [OLD] Core systemAssignee: Gentoo's Team for Core System packages <base-system>
Status: RESOLVED FIXED    
Severity: major CC: aalmenar, aurelus, chutz+bugs.gentoo.org, dopey, john.robinson+bug.gentoo.org, mholzer, michael.christopher.ferguson
Priority: High    
Version: 2004.0   
Hardware: All   
OS: Linux   
Whiteboard:
Package list:
Runtime testing required: ---
Bug Depends on:    
Bug Blocks: 14761    
Attachments: New iptables initscript
Simple before-net iptables script

Description Michael C. Ferguson 2003-08-21 18:23:35 UTC
The current iptables /etc/init.d script uses 'need net' in its depend() section.
This should be replaced with 'before net', or there is the possibility of a
critical lag time between when the network connection is brought up and when
iptables begins filtering it. During this lag time, services could be compromised.

It is important to note that iptables does not care whether or not an interface
is up (or even if it exists) for a rule to be set. For example:

#iptables -A INPUT -i eth9 -j ACCEPT

The above will work in any configuration that supports iptables, even if you do
not have an eth9. Please commit this ASAP; I know it is a minor issue, but it is
still an issue and has the potential for being a real security problem.


-- mcf
Comment 1 SpanKY gentoo-dev 2003-08-21 18:30:41 UTC
umm and how do you propose resolving hostnames if you dont have net ? 
 
or do you tell users that they have to use ip addresses for all their rules ? 
Comment 2 Michael C. Ferguson 2003-08-21 18:38:30 UTC
Rules can still use names, as long as they are entered after the network (and, presumably, DNS or whatever) is brought up. /sbin/iptables-save saves rules as IP addresses anyway, even if you entered them as names, so I think you are exaggerating the issue.
Comment 3 SpanKY gentoo-dev 2003-08-21 19:12:32 UTC
you're picking over less than 60 seconds of no iptables rules and you're telling me i'm 
exageratting ?  after all, who knows when a box comes up ?  the chances of 'exploiting' 
anything is quite small 
Comment 4 Michael C. Ferguson 2003-08-21 19:41:54 UTC
I
Comment 5 Michael C. Ferguson 2003-08-21 19:41:54 UTC
Im sorry I wrote you were exaggerating  actually, hostname resolution is a non-issue, since it is only used once (during the initial rule creation with /sbin/iptables) and then never again. iptables L will use reverse-lookup to try to give you a readable idea about what your rules do, but the reverse-lookup it does may or may not resolve to the same hostname you originally used in your rule.

If I didn't believe this was a security issue, I would not have posted a bug report. I know of cases where internet-connected Windows machines have been compromised during installation, before they even had a chance to be patched. Although it is improbable that a machine would be compromised during this short time period, it is still possible, and therefore we should attempt to eliminate the possibility.

If you have any *constructive* comments, please post them.


-- mcf
Comment 6 Michael C. Ferguson 2003-09-22 09:56:56 UTC
Created attachment 18131 [details]
New iptables initscript

The new script removes the ENABLE_FORWARDING_IPv4 option (see bug 14761 for
why) and changes the init order slightly to put iptables 'before net'. This
also incorporates changes suggested by Max Kalika in bug 21801 (reload
support).
Comment 7 Nahor 2003-09-22 12:02:48 UTC
It's more a matter of security/simplicity but setting up a firewall after the net could help automatize some stuff (like denying packets that don't belong to your network/IP)

What about having iptables setup to DENY/REJECT everything before setting up the network and doing the real firewall setup only after?
Comment 8 Michael C. Ferguson 2003-09-22 13:09:40 UTC
Nahor -

That idea sounds good also. The question is... where to put it? iptables is 
not installed in the system by default, so maybe we need a test in one of the 
initialization scripts to see if it exists, and to enable it if it is ? I 
admit this is not my area of expertice. I like the idea of having iptables as 
part of the default system, but I'm not sure if this goes with the overall 
minimalist Gentoo architecture. Also, while testing the modified script, I 
noticed that portage will still turn off iptables before turning off the 
network, even though iptables is 
Comment 9 Michael C. Ferguson 2003-09-22 13:09:40 UTC
Nahor -

That idea sounds good also. The question is... where to put it? iptables is 
not installed in the system by default, so maybe we need a test in one of the 
initialization scripts to see if it exists, and to enable it if it is ? I 
admit this is not my area of expertice. I like the idea of having iptables as 
part of the default system, but I'm not sure if this goes with the overall 
minimalist Gentoo architecture. Also, while testing the modified script, I 
noticed that portage will still turn off iptables before turning off the 
network, even though iptables is before net (maybe this is a bug in the 
initscripts ?)  it sounds like your idea might also help that situation, if 
we block everything whenever iptables is stopped.

I would still like to get rid of ENABLE_FORWARDING_IPv4 in the iptables 
initscript, since I think this is misplaced no matter what. Forwarding, static 
routes, and other settings that sit under /proc/sys/net/ipv4/conf/* and 
net.ipv?.conf.* kernel parameters really belong in the net.* scripts, not in 
iptables.
Comment 10 Nahor 2003-09-22 13:36:02 UTC
> where to put it?
Two possibilities:
 - Have an iptables-before and an iptables-after scripts which has the advantage
of being "firewall-idependant" (one can then easily replace iptables with
ipchains)
 - Or put it in the net script.

I'm in favor of the net script. It would not be the first generic script having
some code for a specific package (like halt.sh assume that nut is handling the
UPS) and iptables is quite the default firewall now.


Then, one can:
 - check if the iptables executable is there or not and ignore any error
messages if it's not in the kernel (maybe not ideal if the error is because of a
failures of some sort in the program/kernel).
 - or have yet another variable in the /etc/conf.d/net to specify if the script
should call iptables or not.


As for Gentoo being minimalist, a firewall can be consider mandatory, can't it?
Afterall, a firewall is more important than Python (which has to be install for
portage) :p. Anyway, a variable in /etc/conf.d/net should solve that problem.
Comment 11 John Robinson 2003-10-24 17:08:40 UTC
I was going to post something along these lines here myself, but you guys
have saved me bothering. Still I'd like to add my 2p to the discussion.

I agree that iptables should be up and running before the net starts, and
that it shouldn't be stopped until after net. I agree that the ENABLE_FOWARDING
stuff shouldn't be in iptables, really it should be in net or even in a separate
routing item. People do use Linux boxes as non-filtering routers from time
to time. Worse, some people use iptables as a firewall to protect a non-routing
box, so why the heck would they want IP forwarding enabled?

For my current application - home firewall/router - I do want IP forwarding,
and as we're most likely to have IP at boot time (because that's when the
loopback interface is brought up, at least with the current Gentoo structure),
moving the ENABLE_FORWARDING stuff is no big deal for me right now. So, I've
merged the distribution /etc/init.d/iptables with MCF's version - keeping
the ENABLE_FORWARDING in - but what's currently bugging me is that even though
it says 'before net' it isn't running before net at all. I've run /sbin/depscan.sh
by hand just to try to persuade it to do the right thing, and actually it
does because the contents of /var/init.d/deptree look fine:
depinfo_net() {
    export rc_name="net"
    export rc_ineed=
    export rc_needsme="dhcp exim named netmount sshd"
    export rc_iuse=
    export rc_usesme="rsyncd"
    export rc_ibefore=
    export rc_iafter="iptables"
    export rc_broken=
    export rc_parallel=
}
This sounds like it may be related to MCF's report of things not being done
in the right reverse order at shutdown. However this in itself is not a bug
report for iptables so I'll take it elsewhere :-)
Comment 12 John Robinson 2003-10-24 17:45:59 UTC
I have had A Thought[tm]. New virtual service called firewall. Default configuration,
it's an empty stub except for a note saying, "If you have a network interface,
you ought to have a firewall.". Then net can
  depend() { need firewall }
or whatever. And those of us who like doing things properly can install iptables
or whatever our firewall software of choice is.
Comment 13 Martin Holzer (RETIRED) gentoo-dev 2003-10-26 04:24:03 UTC
when running before net, iptables doesn't resolve domains
Comment 14 John Robinson 2003-10-26 11:05:55 UTC
MH, MCF has covered this above; `/sbin/iptables` resolves names as a service
to the user on the command line, but `/etc/init.d/iptables save` saves the
filter rules as IP numbers so that `/etc/init.d/iptables start` doesn't need
to resolve names, and because of this, it is safe to run the service before
net. It is also useful to do so to make sure your filters are in place as
soon as the interfaces are up.
Comment 15 Nahor 2003-10-26 11:40:21 UTC
That's suppose that the script just reload a previous firewall state. People
using DHCP may want a script that will dynamically update the firewall to
there current IP.

But as I suggested before, a solution is to block everything from the network
(except DHCP if so configured) before bringing up the network and once the
network is up, to finish setting up the network. That way, the firewall scrip
can still access any network data it needs without leaving gaping holes in
the firewall.
Comment 16 John Robinson 2003-10-26 18:58:21 UTC
That's a good point, and it's made me think again: what are we protecting
by using iptables (or whatever)? I mean, if we think iptables (or whatever)
is good enough that it is not itself vulnerable to nasty hackers, can we
suppose that the kernel's IP handling is reasonably solid and unlikely to
be cracked? I ask this as a lead-in to the suggestion that, if we can contrive
that iptables (or whatever firewall configuration) is run immediately after
after the network interfaces are brought up, and before any userland software
binds to them, it might even be safe enough not to load any firewall configuration
at all before bringing up the network interfaces; only the kernel's regular
IP handling code is at risk. At the moment I'm not sure the initscripts'
"after" feature could, even in theory, guarantee such immediate running,
however; what happens if two things both want to be "after" something? Also,
if the interfaces have previously been set to drop almost all traffic, I
can envisage scenarios when something that "need"s net cannot start if the
firewall configuration proper has  not yet been run despite net having been
run.

Perhaps the answer is actually that this really does need to be done within
net, but in a configurable way; for example if conf.d/net says "FIREWALL=iptables"
then net can run a separate script (or two or more e.g. pre-if and post-if)
called iptables. Similarly, there might be configuration for what kind of
routing and forwarding a box does, so we run something else if we've a bunch
of complex routing to do, or just set default route if specified, and then
don't turn on IP forwarding if we don't want it. Already net is a multi-module
service (eth, ppp, vlan etc), let's just add some more modules?

Hope that's of interest. I might have done it myself by now if I hadn't totally
hosed my box. (Dunno how I did it, but I'd been playing with compiler options
so maybe I overdid it with the optimisation.)
Comment 17 Thomas Smith 2003-11-19 15:59:41 UTC
I think Comment 14 is a good idea. However, I think the ability to load multiple scripts is a bit redundant (e.g having a pre-if and post-if). This would simply add to the complexity of the iptables setup and kill unnecassary CPU cycles.

The ability to load the firewall script, though, from /etc/conf.d/net /after/ the interfaces are loaded should resolve this issue since the system is really under no threat until network-aware services are loaded.

Loading the iptables rules after the network interfaces has the added benefit of being able to configure dynamic network devices--such as those using DHCP.
Comment 18 Thomas Smith 2003-11-19 16:13:12 UTC
It may also be of interest (for those of you not watching the mailing list) that
there's a rather lengthly thread regarding this topic. The Subject is:

What is the best way to start iptables on boot time?
Comment 19 Michael C. Ferguson 2003-11-19 16:20:10 UTC
No, the solution is still just to make iptables 'before net'. I haven't seen a
rational reason yet why this wouldn't work (and in fact, this is exactly what
all of my machines are using, via the initscript I attached above). There's no
reason to add more needless complexity to what is really a simple fix.

iptables should be loaded before any other network service, including bringing
up interfaces and using dhcp.



-- mcf
Comment 20 Nahor 2003-11-19 16:48:27 UTC
Michael, please define "rational reason" if you don't see DHCP as being a problem. Or explain how you would handle dynamic IPs. Your attached initscipt didn't enlightened me
Comment 21 Thomas Smith 2003-11-19 16:54:13 UTC
Let me see if I understand you correctly...

You're stating that one should load their iptables script before the network
interfaces. Then, after the interfaces load, you're saying that the iptables
script (or possibly a second script) would be run to gather the requisite IP
data from dynamically configured interfaces. Yes?

I think I understand your perspective. Truth is...it would work. But so would
what I (and some other posters) suggested--I stand by my previous posts.

I don't know, though, that using /etc/conf.d/net is the best solution--it's
simply one of many possibles. Another options would be to load the iptables
script after net.eth* but before any userland programs load. This would
eliminate the need to add modules to conf.d/net.

In either case, I think the load time between net.eth* and iptables (as it
currently stands) is inconsequential. The fact of the matter is that someone
would have to know the exact moment that the system begins to boot to launch a
successful attack on the system--and even then, we're only talking a few seconds
of opportunity. I don't know of anyone who can successfully exploit a system in
that amount of time.
Comment 22 Michael C. Ferguson 2003-11-19 16:58:34 UTC
Hi Nahor,

If you're using DHCP, you should filter on the interface (-i ethX) instead
of on the interface's address (-d ...). This is regardless of whether or not
you're using any initscript, since you may be assigned a new address at any
time, at which point your iptables rules would probably become invalid.

Best regards,



-- mcf
Comment 23 Michael C. Ferguson 2003-11-19 17:10:44 UTC
Hi Thomas,

I'm suggesting that iptables be started (and the saved rules from /var/lib/iptables/rules-save) be loaded 'before net' is started. There is no need to do
any 'post-initialization' of any kind. I wrote a small explanation of the
perceived issues in bug 14761, which might help clarify things. Please let me
know if you have any other questions, and feel free to contact me via e-mail
or IRC (also nickname 'mcf' on FreeNode).

Best regards,



-- mcf
Comment 24 Nahor 2003-11-19 17:31:55 UTC
Usually, when renewing an IP with DHCP, you keep the same one. And in any case,
there is always the possibility to restart the firewall then.

As for filtering on the interface only, I'm not sure it would be enough. For
instance one could forge a network packet to use your MAC address with a bogus
IP. It's probably not a good example but the idea is there. And the same way it
is advised to use TCP Wrapper even if one has a firewall, it is best to filter
on both the interface and the IP.

I give you that your solution is still better than what we have now. But I do
think that the better solution is to block everything (except DHCP if needed),
bringing the network up then setup the firewall. The before-net script is very
simple and secures the machine. The after-net script can then be run any time,
even after the network services (well maybe not completly, some service may
need the network to start (like ntpd which tries to sync the clock first))
Comment 25 Thomas Smith 2003-11-19 19:32:24 UTC
Okay, let me backup a little ;-)...

The "before-net" idea sounds interesting for "simple" setups--say, for example,
for systems with single or multiple NICs and the script justs binds to those
devices.

But what about situations where servers have entire subnets aliased on one
interface? One of my servers has around 200 IPs on a single interface. To take
it one further, not all of those IPs require the same services to be
available--thus, only the necassary ports are opened (on a per-IP basis) and the
rest are blocked. This situation would certainly require filtering by IP and not
by device--thus an "after-net" script would be required.

Given this situation, and Nahor's comments, perhaps a "before-net" and
"after-net" /option/ would be beneficial.

Going back a couple of comments, adding a conf.d/net option may be the right way
to go. People who don't want to use it can leave out the options; those who'd
like to use it can add the option(s).

I personally don't think that a "before-net" option is unnecassary--but that's
just my opinion. The arguments made for it are valid and compelling but loading
iptables immediately after the net.eth* devices will acheive the same effect.

In the spirit of Gentoo, users should have the option to use
before-net/after-net, just before-net, or just after-net--as opposed to being
locked into a single method. For example, one could add to conf.d/net a
BEFORE_NET= and an AFTER_NET= variable pointing to a script that does what they
want. Simple. Flexible. Every body's happy (at least in an ideal world ;-).
Comment 26 Tero Pelander 2003-11-24 04:31:07 UTC
>I think the load time between net.eth* and iptables (as it
currently stands) is inconsequential.

Not so. A real world example:
I'm one of those who needs to switch between administrative net and "work" net from time to time. Both nets have dhcp service for ipv4 and one of them has stateless ipv6. When switching from one net to other using "/etc/init.d/net.eth0 restart" there is about 15 second delay before the dhcpcd decides that it can't contanct the latest dhcp server and looks for a new one. During that time anyone can use global ipv6 connections to my host as the firewall rules are disabled.

>One of my servers has around 200 IPs on a single interface...
>This situation would certainly require filtering by IP and not by device--thus an "after-net" script would be required.

For such a list it is propably fixed ip-numbers. The rules by ip-number can be loaded as well even before you have initialized any of your network interfaces. It's just dynamic numbers (like dhcp) that you should newer trust to be constant.

Doing similar things with dynamic numbers... Well, there are interesting things you can do to shoot your own legs.

To sum it up. The current iptables doesn't contain anything that uses net at service start-up. Changing it from "need net" to "before net" is therefore the correct solution.
Comment 27 Aurelus 2003-11-30 06:54:28 UTC
Created attachment 21506 [details]
Simple before-net iptables script


Hi there,

I think it's a good idea to put iptables before the net services. What I would
suggest is a script such as the changed (stateful) iptables script I attached.

It blocks all TCP and UDP traffic by default, and makes a chain in which rules
can be added to allow certain traffic. These rules could be added by the
services that need a specific "hole" and/or by an after-net iptables script
that loads user-specific settings. (A machine with no external services
wouldn't need the last script.) Such as rule would e.g. be "/sbin/iptables -I
INPUT_ACCEPT -p tcp -m tcp --dport 80 -j ACCEPT".

I'm aware that this script would not yet suit more complex situations. Probably
a FORWARD_ACCEPT chain or so would be needed for example.

With regards,
Aurelus
Comment 28 Daniel Ahlberg (RETIRED) gentoo-dev 2004-01-23 13:56:42 UTC
*** Bug 39112 has been marked as a duplicate of this bug. ***
Comment 29 Georgi Georgiev 2004-01-29 20:09:34 UTC
I'd like to join the discussion in favor of "before net".

My argument:

Since all that these scripts do in start() is to run ip{,6}tables-restore on the data that has been saved by ip{,6}tables-save, this is all pretty static stuff, isn't it? ip{,6}tables-save does not save dynamic configuration if I am not mistaken.

And I really need to do this "before net", because there is a broken router somewhere in school that I want to block. It is broadcasting useless ipv6 data, which assigns a useless ipv6 address to my interface (there is no routing to this address).
Comment 30 Georgi Georgiev 2004-03-09 08:39:54 UTC
It's been a month since my comment, and three months since the comment before that. Progress on this one? I'd really like to see it addressed.
Comment 31 Thomas Smith 2004-03-09 17:42:05 UTC
I finaly got a chance to see for my self that iptables can be loaded without incident "before net". Thus, my previous arguments hold much less weight than I originally thought.

The only remaining issue, as I now see it, is catering to those who use DHCP. I agree with a previous post that everything in /var/lib/iptables/rules-save will remain static.

This being the case, how would one plug DHCP-obtained values into it if iptables is loaded "before net"?

(I suppose, too, that it would be much easier to simply edit /etc/init.d/iptables and change

depend() {
    need logger net
}

to

depend() {
    need logger
    before net
}

for those who don't need DHCP or who prefer to load iptable "before net" rather than inventing a new way to load iptables.)
Comment 32 Georgi Georgiev 2004-03-09 18:06:16 UTC
Re: Comment #29

How exactly do DHCP users benefit from the current setup? The stuff in /var/lib/ip{,6}tables/rules-save *is* static. There is no way around it, unless the dhcp client adjusts stuff in those files, which I haven't checked but highly doubt. If you want to have dynamic information in you iptables rules, you'd need to load a custom script, and the current default /etc/init.d/ip{,6}tables do not mention any custom scripts. Those scripts only read the *static* /var/lib/ip*/rules-save. Neither DHCP users (need net), nor those like me (before net) benefit from the current setup.

Could you give an exact example of a situation where one would actually need the ip{,6}tables init script to be "need net"? Before submitting this example, could you test in your environment and confirm that this is *really* what the person would want?
Comment 33 John Robinson 2004-03-09 18:11:35 UTC
Agreed, the DHCP problem is separate from this. If you use DHCP, you need to keep some things open enough so you can renew your lease(s). So if your filters can work at all, they can work before your IP is assigned. If you use DHCP, you probably ought to be filtering on interface, not IP address, or doing something else otherwise beyond the scope of the iptables package (because you need to hook in to whatever dhcpcd is doing so you can update your filters).

Please can we have this fixed up.
Comment 34 Georgi Georgiev 2004-03-09 18:22:25 UTC
To make myself clearer:

Quote from comment #29:
``The only remaining issue, as I now see it, is catering to those who use DHCP. I agree with a previous post that everything in /var/lib/iptables/rules-save will remain static.

This being the case, how would one plug DHCP-obtained values into it if iptables is loaded "before net"?''

Question: How would one plug DHCP-obtained values into it if iptables is loaded "after net"?

My point: There is no way to do anything about DHCP-obtained values with the current setup. "need net" does not help *anyone*.
Comment 35 John Robinson 2004-03-09 18:36:03 UTC
Precisely.

You can have a /var/lib/iptables/rules-save file produced by iptables-save which works with DHCP, and it'll work just fine "before net". (It just won't refer to your DHCP-allocated variable IP address, but to your network interface, and perhaps the IP range(s) issued by your DHCP server.)

If you want to do funky stuff which takes note of an IP address assigned by DHCP, you have to do something extra, and if you decided then you wanted iptables to "need net" you could make the change yourself. This is very much beyond what most users want.

But the default shipped version should be "before net".
Comment 36 John Robinson 2004-03-09 19:47:04 UTC
In fact it's not all that funky at all; `man dhcpcd` shows that dhcpcd calls a script (/var/lib/dhcpc/dhcpcd.exe, stupid name I know) when it gets an IP, gets a new IP, or loses its IP, and `man pppd` shows pppd does something similar with /etc/ppp/ip-up and /etc/ppp/ip-down. iptables fiddling for variable IPs should be done by those scripts, and iptables fiddling for default and fixed rules should be done by /etc/init.d/iptables "before net".
Comment 37 Andy Wang 2004-04-14 23:30:22 UTC
Any progress on this?  the "before net" idea seems really kludgy to me.  I don't know why.  however, i can't think of a simpler solution.  I really think a better solution overall is add the ability to do immediately after/immediately before which will let the admin decide, but this will result in cluttering the dependency tree more.
Comment 38 Michael C. Ferguson 2004-04-19 20:22:41 UTC
Back into the pool with you. Someone fix this please... it's a no brainer.
If you want, e-mail me and I will call you from work and explain what the issue
is and why it should be fixed. Or just read bug 14761 or below if you have time...

Comment 39 Daniel Ahlberg (RETIRED) gentoo-dev 2004-04-25 09:31:17 UTC
Added to 1.2.9-r1
Comment 40 Andy Wang 2004-08-22 00:18:53 UTC
Either I'm doing something wrong, or something is just wonky. my iptables script now has before net in the depend() section.  However, iptables is still being loaded in alphabetical order with the rest of the initscripts.  Anyone else still seeing this behavior?
Comment 41 John Robinson 2004-08-22 18:37:58 UTC
Yes, I had that problem when I made the change myself (see comment 9) but I think it's an init-system bug, not an iptables bug. I've kludged round this by adding iptables to the boot runlevel.
Comment 42 John Robinson 2004-08-22 21:08:31 UTC
I meant, yes I had that problem, and yes it is still present. I have reported the init problem in bug #31950.
Comment 43 Georgi Georgiev 2005-05-25 17:28:37 UTC
Worth noting that the new baselayout allows us to solve this problem easily:

$ tail -n3 /etc/conf.d/net
depend_eth0() {
        need ip6tables iptables
}