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
ipset should be a separate script. Caleb, could you suggest something to begin with?
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?
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.
"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.
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 }
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...
no, init.d scripts should not start/stop others ... use a proper depend() section, or dont use an init.d script
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...
off the top of my head, no idea ... i'd have to experiment to see if they'd get you the behavior you desire
This script really would be a useful thing. I'll try write something myself a bit later.
(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?
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.
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
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.
> I don't know how to do that. Why don't you want to use method from comment 11?
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?
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.
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.
Is there any news on this problem?
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"
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.
xenoterracide: write some patches per your comment #21, and include an init.d like BoneKracker's.
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.
Created attachment 282071 [details] ipset init.d script
Created attachment 282073 [details] ipset confd config
Created attachment 282075 [details, diff] ipset-6.8.ebuild.patch It creates default save directory as well.
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.
(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.
(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.
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.
(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.
Created attachment 282307 [details] ipset.init.d
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.
(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
Created attachment 282459 [details] ipset.initd updated init scipt
Created attachment 282463 [details] ipset.initd Ooops, there was a typo in previous version.
seems sane, but Peter would know much better than i obviously
Thank you guys. Init script was just added to the tree (in 6.9.1-r1).
You forgot to add confd file as well.