Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 181045 - net-firewall/ipset needs an init script
Summary: net-firewall/ipset needs an init script
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: New packages (show other bugs)
Hardware: All Linux
: High enhancement with 1 vote (vote)
Assignee: Robin Johnson
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-06-06 04:43 UTC by Caleb Cushing
Modified: 2011-11-10 21:03 UTC (History)
10 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
/etc/init.d/ipset (ipset.sh,959 bytes, text/plain)
2008-04-11 09:01 UTC, Caleb Cushing
Details
/etc/conf.d/ipset (ipset.conf,271 bytes, text/plain)
2008-04-11 09:03 UTC, Caleb Cushing
Details
ipset init.d script (ipset.initd,1.10 KB, text/plain)
2011-08-04 16:19 UTC, Andrew Savchenko
Details
ipset confd config (ipset.confd,191 bytes, text/plain)
2011-08-04 16:20 UTC, Andrew Savchenko
Details
ipset-6.8.ebuild.patch (ipset-6.8.ebuild.patch,401 bytes, patch)
2011-08-04 16:20 UTC, Andrew Savchenko
Details | Diff
ipset.init.d (ipset.initd,1.00 KB, text/plain)
2011-08-06 13:47 UTC, Andrew Savchenko
Details
ipset.initd (ipset.initd,1.03 KB, text/plain)
2011-08-07 17:51 UTC, Andrew Savchenko
Details
ipset.initd (ipset.initd,1.03 KB, text/plain)
2011-08-07 18:08 UTC, Andrew Savchenko
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Caleb Cushing 2007-06-06 04:43:25 UTC
here's the problem. ipset like iptables doesn't remember it's 'sets' on reboot. so what I would like is either one of 2 things ipset's own init script which would allow me to do a stop, start, save, etc... or have that some how be integrated into the iptables init script.

Reproducible: Always
Comment 1 Peter Volkov (RETIRED) gentoo-dev 2007-10-28 08:22:29 UTC
ipset should be a separate script. Caleb, could you suggest something to begin with?
Comment 2 Peter Volkov (RETIRED) gentoo-dev 2007-10-28 11:16:43 UTC
The very simple ipset init script is posted here:
http://overlays.gentoo.org/dev/pva/browser/net-firewall/ipset

Now I see the problem which occurs if ipset is a separate script. 

The problem is that if we do not remove iptables rules which contain references on ipset sets ("-m set ...") then flush for ipset will not work with the error:

"ipset v2.2.9a: Set is in use, operation not permitted"

So to stop ipset you have to stop iptables first and to start iptables you have to start ipset first.

UberLord, seems that what I need is like "need" dependency but on revers which resides in ipset. before does not work as it does not stop iptables when I stop ipset. Is it safe to do something like this in ipset init script:

service_started iptables && /etc/init.d/iptables stop

Or really may be it's better to extend iptables script and handle everything there?

robbat2, what do you think on this?
Comment 3 Robin Johnson archtester Gentoo Infrastructure gentoo-dev Security 2007-10-29 00:59:04 UTC
Your sentence there is a bit confusing, but this it what you mean.

start order:
- ipset
- iptables

stop order:
- iptables
- ipset

Thus putting 'before iptables' into the ipset init.d and 'use ipset' into the iptables init.d should work fine.

pva: Are you interested in maintaining the ipset package? I don't use it in production anymore, so if you do, you're welcome to it.
Comment 4 Peter Volkov (RETIRED) gentoo-dev 2007-10-29 05:25:35 UTC
"before" does not work because if you start both ipset and iptables and after that try to stop ipset, iptables remain started and in result error:

camobap ~ # /etc/init.d/ipset start
 * Loading ipset state ...                                                                             [ ok ]
camobap ~ # /etc/init.d/iptables start
 * Loading iptables state and starting firewall ...                                                    [ ok ]
camobap ~ # /etc/init.d/ipset stop
 * Saving ipsets state ...                                                                             [ ok ]
 * Stopping ipset (cleaning all ipsets) ...
ipset v2.2.9a: Set is in use, operation not permitted                                                  [ !! ]
camobap ~ # grep before /etc/init.d/ipset
        before iptables net
camobap ~ #

Robin, I'll have few time in near future, but I'll add myself in metadata.xml as I have to use ipset now.
Comment 5 Robin Johnson archtester Gentoo Infrastructure gentoo-dev Security 2007-10-29 05:38:58 UTC
ah, I see it.
we basically need a way that the ipset init script injects 'need ipset' into the iptable init.d. One I can think of is adding this to the iptables script:

depend() {
 [ -e /etc/init.d/ipset ] && need ipset
}
Comment 6 Peter Volkov (RETIRED) gentoo-dev 2007-11-13 08:48:55 UTC
vapier, could you take a look here. I was thinking on way to integrate ipset into iptables. But reading you comment #6 in bug 198907 make me think this such solution could be not accepted. So to avoid useless work, please, comment here.

The reason for integration ipset in iptables is that I do not know how to handle dependencies. Without flushing "-m set" rules from iptables (IOW without iptables stop) ipset could not be stopped. Currently I'm using the following solution:

service_started iptables && /etc/init.d/iptables stop

but i do not know if this is safe to run start/stop services from other services?

OTOH integration of ipset is relatively simple and simple check that ipset binary exists is enough...
Comment 7 SpanKY gentoo-dev 2007-11-14 07:25:47 UTC
no, init.d scripts should not start/stop others ... use a proper depend() section, or dont use an init.d script
Comment 8 Peter Volkov (RETIRED) gentoo-dev 2007-11-14 12:41:57 UTC
vapier, well, any suggestion, what depend to use? The only depend which works and I know about is to add "need ipset" in iptables script. But iptables can work even without ipset...
Comment 9 SpanKY gentoo-dev 2007-11-14 17:02:02 UTC
off the top of my head, no idea ... i'd have to experiment to see if they'd get you the behavior you desire
Comment 10 Konstantin 2008-03-14 23:36:53 UTC
This script really would be a useful thing. I'll try write something myself a bit later.
Comment 11 Kandalincev Alexandre 2008-03-27 16:27:30 UTC
(In reply to comment #4)
> "before" does not work because if you start both ipset and iptables and after
> that try to stop ipset, iptables remain started and in result error:

I think its a normal behavior since ipset in use. I prefer to leave this rather than automaticaly stop iptables then ipset in use.

Also, you can do somethink like this in /etc/init.d/ipset:

stop() {
  ipset_stop() || ( /etc/init.d/iptables stop && ipset_stop() )
}

What do think about it?
Comment 12 Caleb Cushing 2008-04-11 09:01:14 UTC
Created attachment 149373 [details]
/etc/init.d/ipset

test ipset init script. let me know if features problems are encountered.

you will have to mkdir /var/lib/ipset/ if that's where you want to store the saves.

let me know if anything is missing/needed broken or just cruft I forgot to remove. posting /etc/conf.d/ipset in a min.
Comment 13 Caleb Cushing 2008-04-11 09:03:45 UTC
Created attachment 149374 [details]
/etc/conf.d/ipset

here's the the conf.

here's my git for it too... although it's part of a larger bug repo... right now. (larger meaning I may put any bugs I try to fix there, right now it's pretty small).

http://github.com/xenoterracide/bugs/tree/master/gentoo
Comment 14 Caleb Cushing 2008-04-11 09:05:42 UTC
almost forgot. ipset needs to bring iptables down if it goes down. just because iptables may be using ipset rules. although I think we could test for that though.

I don't know how to do that.
Comment 15 Kandalincev Alexandre 2008-04-13 10:17:43 UTC
> I don't know how to do that.
Why don't you want to use method from comment 11?
Comment 16 Caleb Cushing 2008-04-13 19:55:05 UTC
Sorry I forgot you had posted that Kandalincev, after re-reading the bug... (which I hadn't done before posting) see comment #7.

It would be nice to know what the maintainer's think of this?
Comment 17 Caleb Cushing 2008-04-13 19:59:58 UTC
I would say putting a test in the iptables script for ipset would work. except as far as I can tell there isn't a good way to test for SET rules. Just because you have ipset installed doesn't mean you are using it. Personally I think it could be added as is. I just wanted something that would save/stop/restart. We can always patch it later... it doesn't have to be perfect to get committed just working/stable.
Comment 18 Marcel Hamer 2008-12-19 23:37:29 UTC
Hereby I would like to reopen this discussion as I do not think it is solved with the given scripts. The strange dependency problem still remains and ipset is not really workable without nice initialisation in the init scripts.
 
Would it not be far more simpler to edit the iptables init script. For instance test for file existence of the config file and rules file for ipset. If both exist, the ipset rules are loaded and stored by default?

This would solve the strange circular dependency problem and would be rather simple to implement?

If someone has a better idea for fixing the dependencies I am very interested.
Comment 19 Oleg Gawriloff 2009-02-09 14:33:53 UTC
Is there any news on this problem?
Comment 20 Boney McCracker 2009-02-26 05:50:22 UTC
Here's what I've been using (for over a year).  IPset ebuild doesn't have to be completely idiot-proof.  I think it's safe to assume that, if someone is using ipsets, they can probably figure out how to integrate it into their firewall scripts or initscripts as necessary.

--------------------------------------------------------------
depend() {
        before iptables
        use logger
}

start() {
        ebegin "Loading Saved IP Sets from '${IPSETS_SAVE}'"
        /sbin/ipset -R < "${IPSETS_SAVE}"
        eend $?
}

stop() {
        if [ "${SAVE_ON_STOP}" = "yes" ] ; then
                save || return 1
        fi
        ebegin "Voiding Kernel IP Sets"
        /sbin/ipset -X
        eend $?
}

save() {
        ebegin "Saving IP Sets to '${IPSETS_SAVE}'"
        touch "${IPSETS_SAVE}"
        chmod 0600 "${IPSETS_SAVE}"
        /sbin/ipset -S > "${IPSETS_SAVE}"
        eend $?
}
----------------------------------------------------------------

with this is conf.d:
----------------------------------------------------------------
# Location in which ipsets initscript will save ipsets on service shutdown
IPSETS_SAVE="/var/lib/iptables/ipsets-save"

# Save state on stopping iptables
SAVE_ON_STOP="yes"
Comment 21 Caleb Cushing 2009-02-26 06:15:33 UTC
what if we added an IPTABLES_MODULES to /etc/conf.d/iptables it could act kinda like APACHE_MODULES you list any additional modules things you need.

so for ipset you might have IPTABLES_MODULES="ipset" and that would make sure that the ipset script needs to be loaded by iptables. if it's not set then it's not loaded unless the admin explicitly loads it.
Comment 22 Robin Johnson archtester Gentoo Infrastructure gentoo-dev Security 2009-05-14 23:05:11 UTC
xenoterracide: write some patches per your comment #21, and include an init.d like BoneKracker's.
Comment 23 Andrew Savchenko gentoo-dev 2011-08-04 16:19:05 UTC
Since kernel 2.6.39 ipset is included, no patching/external modules are needed and this problem arise anew.

Without ipset init script iptables init script become useless as well, because iptables rules must be loaded manually (from some hand-made scripts) after ipset rules were submitted from the same scripts.

As of now I use modified script, based on work above, but it utilizes new ipset syntax and adds some additional checks. This init script can't be stopped while iptables/ip6tables are running.
Comment 24 Andrew Savchenko gentoo-dev 2011-08-04 16:19:52 UTC
Created attachment 282071 [details]
ipset init.d script
Comment 25 Andrew Savchenko gentoo-dev 2011-08-04 16:20:06 UTC
Created attachment 282073 [details]
ipset confd config
Comment 26 Andrew Savchenko gentoo-dev 2011-08-04 16:20:44 UTC
Created attachment 282075 [details, diff]
ipset-6.8.ebuild.patch

It creates default save directory as well.
Comment 27 SpanKY gentoo-dev 2011-08-06 10:48:23 UTC
Comment on attachment 282071 [details]
ipset init.d script

don't hardcode the path to `ipset`.  this should probably be converted to POSIX rather than using bashisms.  brace style also needs fixing:
foo()
{
    ...
}

the iptables service checking is dubious at best.  it completely ignores people who run iptables by hand.  i'd say just punt it.
Comment 28 Andrew Savchenko gentoo-dev 2011-08-06 11:12:25 UTC
(In reply to comment #27)
> don't hardcode the path to `ipset`.

Why not? It is hardcoded by installation anyway. Well, maybe eprefix support, but most of init.d script hardcode bins anyway.

> this should probably be converted to POSIX
> rather than using bashisms.

What's wrong with bashisms? Bash is supported by runscript anyway.

У  brace style also needs fixing:
> foo()
> {
>     ...
> }

What's wrong with 
func() {
...
}
?

I doubt this is an official policy requirement. Looks like your personal preference.

 
> the iptables service checking is dubious at best.  it completely ignores people
> who run iptables by hand.  i'd say just punt it.

The statement above is completely ridiculous. If people run iptables by hand, this is absolutely natural that they MUST run ipset by hand as well. ipset is not a stand-alone service, but support program for iptables and nothing more and they must be used in the same way.
Comment 29 SpanKY gentoo-dev 2011-08-06 11:27:33 UTC
(In reply to comment #28)

i dont care what other init.d scripts do.  they're all wrong.

openrc was designed to not require bash.  adding init.d scripts which do means we'll get another bug with users complaining about it.  your use of bash-specific commands is hardly warranted when there are trivial direct POSIX equivalents.

there is no init.d style requirement, but reality is that is how most init.d scripts and ebuilds are written.  deviating it for no good reason is unacceptable.

what is opinion though is your view on the iptables service ridiculousness.  people do all sorts of fun things by hand, and my single example is not the only one.  there are plenty of other ways to integrate iptables without using the specific init.d scripts.  come up with something reasonable.
Comment 30 Peter Volkov (RETIRED) gentoo-dev 2011-08-06 11:41:59 UTC
Andrew, as an ipset maintainer I completely agree with all Make said here and I never submit non posix init scripts to the tree. And if you know some of them, please, open bugs so maintainers could fix them. BTW, I've kept silence because you proposed nothing new to this bug. Similar solutions were mentioned above and it's told explicitly why they will no go to the tree.

(In reply to comment #29)
> what is opinion though is your view on the iptables service ridiculousness. 
> people do all sorts of fun things by hand, and my single example is not the
> only one.  there are plenty of other ways to integrate iptables without using
> the specific init.d scripts.  come up with something reasonable.

Just got an idea. If anybody could come up with command to check if iptables still uses ipset - that could be used in init script.

Another good solution is iptables modules mentioned in comment #21 but somebody has to do all the legwork.
Comment 31 Andrew Savchenko gentoo-dev 2011-08-06 13:46:30 UTC
(In reply to comment #29)
> there is no init.d style requirement, but reality is that is how most init.d
> scripts and ebuilds are written.  deviating it for no good reason is
> unacceptable.

Well, ok... but just look at the iptables init script :)
 
> what is opinion though is your view on the iptables service ridiculousness. 
> people do all sorts of fun things by hand, and my single example is not the
> only one.  there are plenty of other ways to integrate iptables without using
> the specific init.d scripts.  come up with something reasonable.

I agree that people may use funny ways to use iptables in their systems, but if they use iptables in non-standard ways it will be only natural to use ipset in the same non-standard ways (e.g. in scripts, daemons or puffy-fluffy gui user interfaces for the firewall). A case where iptables is used without an init script invoke, but ipset requires an init script looks very impractical for me.

(In reply to comment #30)
> Andrew, as an ipset maintainer I completely agree with all Make said here and I
> never submit non posix init scripts to the tree.

OK, I reverted those double square brackets, but single brackets are much slower because this is an external program call.

> Just got an idea. If anybody could come up with command to check if iptables
> still uses ipset - that could be used in init script.

If this is the only problem, it can easily be fixed: just parse an ipset list output and count a number of references. See init.d script below.

But if some iptables rule that uses ipset will be dynamically inserted later, it may malfunction. That's why I checked for iptables service in the first place, because it is the only way to ensure that nothing will be broken later.
Comment 32 Andrew Savchenko gentoo-dev 2011-08-06 13:47:06 UTC
Created attachment 282307 [details]
ipset.init.d
Comment 33 SpanKY gentoo-dev 2011-08-06 23:58:49 UTC
Comment on attachment 282307 [details]
ipset.init.d

- please quote ${IPSET_SAVE} in checkconfig
- ebegin in start seems to have a spurious ' in its message
- you have to use "=" and not "==" in [...] tests
- the gawk in stop is probably more complicated that necessary ... does ipset output negative values ?  otherwise, you can simply do:
if ! ipset list | gawk '($1 == "References:" && $2 > 0) { exit 0; } END { exit 1 }' ; then

also, is `ipset` output localized ?  if so, you'll want to use `LC_ALL=C ipset list ...` or the gawk could fail to match the output.
Comment 34 Andrew Savchenko gentoo-dev 2011-08-07 17:50:23 UTC
(In reply to comment #33)
> - please quote ${IPSET_SAVE} in checkconfig
> - ebegin in start seems to have a spurious ' in its message
> - you have to use "=" and not "==" in [...] tests

Done.

> - the gawk in stop is probably more complicated that necessary ... does ipset
> output negative values ?

I don't think so.

> otherwise, you can simply do:
> if ! ipset list | gawk '($1 == "References:" && $2 > 0) { exit 0; } END { exit
> 1 }' ; then

Well, if you run for simplicity, gawk code may be even more simple.

> also, is `ipset` output localized ?

no, it isn't
Comment 35 Andrew Savchenko gentoo-dev 2011-08-07 17:51:13 UTC
Created attachment 282459 [details]
ipset.initd

updated init scipt
Comment 36 Andrew Savchenko gentoo-dev 2011-08-07 18:08:21 UTC
Created attachment 282463 [details]
ipset.initd

Ooops, there was a typo in previous version.
Comment 37 SpanKY gentoo-dev 2011-08-07 22:06:54 UTC
seems sane, but Peter would know much better than i obviously
Comment 38 Peter Volkov (RETIRED) gentoo-dev 2011-10-02 13:07:54 UTC
Thank you guys. Init script was just added to the tree (in 6.9.1-r1).
Comment 39 Andrew Savchenko gentoo-dev 2011-11-10 21:03:37 UTC
You forgot to add confd file as well.