Патч для поддержки ipset в /etc/init.d/iptables:
1) save после iptables-save сохраняет "ipset -S" в /etc/sysconfig/ipset
2) start перед iptables-restore читает "ipset -R" из /etc/sysconfig/ipset
3) при [cond]{reload|restart} делается stop.
Зачем нужен stop?
1) iptables-restore будет ругаться на правила "... -m set --match-set name ...", если имя не создано через "ipset -N name ..."
2) ipset -R будет ругаться, если сет с таким именем уже определён, или если строка с добавлением в сет встретилась до строки создания этого сета.
3) удалить перед ipset -R существующие сеты с помощью ipset -X нельзя, пока на них ссылаются правила iptables
4) единственный выход - перед iptables-restore вызывать ipset -R, перед ним вызывать ipset -X, а перед ним удалять правила iptables. То есть делать stop.
Кто-нибудь может предложить менее корявое решение?
Если патч не вызовет замечаний, отправлю мантейнеру iptables,
т.к. без него использовать ipset в скомпилированных правилах IMHO проблематично.
--- /etc/init.d/iptables.orig 2009-09-23 02:01:37 +0400
+++ /etc/init.d/iptables 2010-04-18 05:27:11 +0400
@@ -29,10 +29,42 @@
IPV="${IPTABLES%tables}" # ip for ipv4 | ip6 for ipv6
IPTABLES_TABLES_NAMES="/proc/net/${IPV}_tables_names"
+IPSET_BINARY=/sbin/ipset
+IPSET_DATA="/etc/sysconfig/ipset"
+
# Source config
SourceIfNotEmpty "$IPTABLES_CONFIG"
RETVAL=0
+load_ipset()
+{
+ test -x "$IPSET_BINARY" || return
+ test -e "$IPSET_DATA" || return
+ action $"Loading ipset rules:"\
+ $IPSET_BINARY -qR < $IPSET_DATA
+}
+
+save_ipset()
+{
+ test -x "$IPSET_BINARY" || return
+ test -e "$IPSET_DATA" && mv "$IPSET_DATA" "${IPSET_DATA}.save"
+
+ local msg="Saving ipset rules to $IPSET_DATA"
+ printf '%s: ' "$msg"
+ $IPSET_BINARY -S > "$IPSET_DATA" && success "$msg" || failure "$msg"
+ echo
+}
+
+flush_ipset()
+{
+ test -x "$IPSET_BINARY" || return
+ local msg="Removing ipsets"
+ printf '%s: ' "$msg"
+ $IPSET_BINARY -qX &&
+ { success "$msg"; echo; return 0; } ||
+ { failure "$msg"; echo; return 1; }
+}
+
load_modules()
{
[ -s "$IPTABLES_MODULES" ] || return 0
@@ -73,6 +105,8 @@
load_modules
+ load_ipset
+
action $"Applying $IPTABLES firewall rules:" \
$IPTABLES_RESTORE $IPTABLES_RESTORE_ARGS <"$tmp"
RETVAL=$?
@@ -173,6 +207,10 @@
success "Zeroing packet and byte counters" ||
failure "Zeroing packet and byte counters"
echo
+ [ "$RETVAL" -eq 0 ] || return $RETVAL
+
+ flush_ipset || RETVAL=1
+
return $RETVAL
}
@@ -227,6 +265,7 @@
[ -z "$tmp" ] || rm -f "$tmp"
fi
echo
+ save_ipset
else
printf %s $"$IPTABLES firewall is not started"
passed "$IPTABLES save"
@@ -290,10 +329,11 @@
;;
restart|reload)
is_yes "$IPTABLES_SAVE_ON_RESTART" && save
+ stop
start
;;
condrestart)
- [ -e "$LOCKFILE" ] && start
+ [ -e "$LOCKFILE" ] && { stop; start; }
;;
condstop)
[ -e "$LOCKFILE" ] && stop