[ipset] Add a service subpackage
Mathieu Bridon
bochecha at fedoraproject.org
Fri Aug 30 06:02:34 UTC 2013
commit e4af967234ab2edaf2d3bf27ea8191f76c10f908
Author: Quentin Armitage <quentin at armitage.org.uk>
Date: Fri Aug 30 13:49:08 2013 +0800
Add a service subpackage
This contains a systemd unit, and the logic to be able to save and
reload functionality on shutdown/startup.
This also adds a missing explicit dependency on the ipset-libs
subpackage in the base package. It is needed to cover the case where a
user would update one explicitly (e.g yum update ipset) as they need to
be kept in sync.
ipset.service | 18 +++++
ipset.spec | 62 +++++++++++++++-
ipset.start-stop | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 285 insertions(+), 4 deletions(-)
---
diff --git a/ipset.service b/ipset.service
new file mode 100644
index 0000000..f86c16b
--- /dev/null
+++ b/ipset.service
@@ -0,0 +1,18 @@
+[Unit]
+Description=IP sets for iptables
+Before=iptables.service
+Before=ip6tables.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/libexec/ipset/ipset.start-stop start
+ExecStop=/usr/libexec/ipset/ipset.start-stop stop
+ExecReload=/usr/libexec/ipset/ipset.start-stop reload
+# Save current ipset entries on stop/restart.
+# Value: yes|no, default: no
+# Saves all ipsets to /etc/sysconfig/ipset if ipset gets stopped
+Environment=IPSET_SAVE_ON_STOP=no IPSET_SAVE_ON_RESTART=no
+
+[Install]
+WantedBy=basic.target
diff --git a/ipset.spec b/ipset.spec
index 6dfef48..55a42ff 100644
--- a/ipset.spec
+++ b/ipset.spec
@@ -1,17 +1,33 @@
Name: ipset
Version: 6.19
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: Manage Linux IP sets
License: GPLv2
URL: http://ipset.netfilter.org/
Source0: http://ipset.netfilter.org/%{name}-%{version}.tar.bz2
-
+Source1: %{name}.service
+Source2: %{name}.start-stop
BuildRequires: libmnl-devel
+Requires: %{name}-libs%{?_isa} = %{version}-%{release}
-# This is developped hand in hand with a kernel module
+# This is developed hand in hand with a kernel module
Requires: kernel
+%package service
+Summary: %{name} service for %{name}s
+Requires: %{name} = %{version}-%{release}
+BuildRequires: systemd
+Requires: iptables-services
+Requires(post): systemd
+Requires(preun): systemd
+Requires(postun): systemd
+BuildArch: noarch
+
+%description service
+This package provides the service %{name} that is split
+out of the base package since it is not active by default.
+
%description
IP sets are a framework inside the Linux 2.4.x and 2.6.x kernel, which can be
administered by the ipset utility. Depending on the type, currently an IP set
@@ -65,9 +81,37 @@ make %{?_smp_mflags}
make install DESTDIR=%{buildroot}
find %{buildroot} -name '*.la' -exec rm -f '{}' \;
+# install systemd unit file
+install -d -m 755 %{buildroot}/%{_unitdir}
+install -c -m 644 %{SOURCE1} %{buildroot}/%{_unitdir}
-%post libs -p /sbin/ldconfig
+# install supporting script
+install -d -m 755 %{buildroot}%{_libexecdir}/%{name}
+install -c -m 755 %{SOURCE2} %{buildroot}%{_libexecdir}/%{name}
+
+# Create directory for configuration
+mkdir -p %{buildroot}%{_sysconfdir}/%{name}
+
+%preun
+if [[ $1 -eq 0 && -n $(lsmod | grep "^xt_set ") ]]; then
+ rmmod xt_set 2>/dev/null
+ [[ $? -ne 0 ]] && echo Current iptables configuration requires ipsets && exit 1
+fi
+%post service
+%systemd_post %{name}.service
+
+%preun service
+if [[ $1 -eq 0 && -n $(lsmod | grep "^xt_set ") ]]; then
+ rmmod xt_set 2>/dev/null
+ [[ $? -ne 0 ]] && echo Current iptables configuration requires ipsets && exit 1
+fi
+%systemd_preun %{name}.service
+
+%postun service
+%systemd_postun_with_restart %{name}.service
+
+%post libs -p /sbin/ldconfig
%postun libs -p /sbin/ldconfig
@@ -81,12 +125,22 @@ find %{buildroot} -name '*.la' -exec rm -f '{}' \;
%doc COPYING
%{_libdir}/lib%{name}.so.3*
+%files service
+%{_unitdir}/%{name}.service
+%dir %{_libexecdir}/%{name}
+%attr(0755,root,root) %{_libexecdir}/%{name}/%{name}.start-stop
+%dir %{_sysconfdir}/%{name}
+
%files devel
%{_includedir}/lib%{name}
%{_libdir}/lib%{name}.so
%changelog
+* Tue Aug 27 2013 Quentin Armitage <quentin at armitage.org.uk> 6.19-2
+- Add service pkg - adds save and reload functionality on shutdown/startup
+- Add requires dependency of ipset on matching ipset-libs
+
* Thu Aug 15 2013 Mathieu Bridon <bochecha at fedoraproject.org> - 6.19
- New upstream release.
diff --git a/ipset.start-stop b/ipset.start-stop
new file mode 100644
index 0000000..da21890
--- /dev/null
+++ b/ipset.start-stop
@@ -0,0 +1,209 @@
+#!/bin/bash
+#
+# ipset Start and stop ipset firewall sets
+#
+# config: /etc/ipset/ipset
+#
+
+IPSET=ipset
+IPSET_BIN=/usr/sbin/${IPSET}
+IPSET_DATA=/etc/${IPSET}/${IPSET}
+
+IPTABLES_CONFIG=/etc/sysconfig/iptables-config
+IP6TABLES_CONFIG=${IPTABLES_CONFIG/iptables/ip6tables}
+
+TMP_FIFO=/tmp/${IPSET}.$$
+
+if [[ ! -x ${IPSET_BIN} ]]; then
+ echo "${IPSET_BIN} does not exist."
+ exit 5
+fi
+
+CLEAN_FILES=TMP_FIFO
+trap "rm -f \$CLEAN_FILES" EXIT
+
+# Default ipset configuration:
+[[ -z $IPSET_SAVE_ON_STOP ]] && IPSET_SAVE_ON_STOP=no # Overridden by ip(6)tables IP(6)TABLES_SAVE_ON_STOP
+[[ -z $IPSET_SAVE_ON_RESTART ]] && IPSET_SAVE_ON_RESTART=no # Overridden by ip(6)tables IP(6)TABLES_SAVE_ON_RESTART
+
+# Load iptables configuration(s)
+[[ -f "$IPTABLES_CONFIG" ]] && . "$IPTABLES_CONFIG"
+[[ -f "$IP6TABLES_CONFIG" ]] && . "$IP6TABLES_CONFIG"
+
+# It doesn't make sense to save iptables config and not our config
+[[ ${IPTABLES_SAVE_ON_STOP} = yes || ${IP6TABLES_SAVE_ON_STOP} = yes ]] && IPSET_SAVE_ON_STOP=yes
+[[ ${IPTABLES_SAVE_ON_RESTART} = yes || ${IP6TABLES_SAVE_ON_RESTART} = yes ]] && IPSET_SAVE_ON_RESTART=yes
+
+check_can_unload() {
+ # If the xt_set module is loaded and can't be unloaded, then iptables is
+ # using ipsets, so refuse to stop the service.
+ if [[ -n $(lsmod | grep "^xt_set ") ]]; then
+ rmmod xt_set 2>/dev/null
+ [[ $? -ne 0 ]] && echo Current iptables configuration requires ipsets && return 1
+ fi
+
+ return 0
+}
+
+flush_n_delete() {
+ local ret=0 set
+
+ # Flush sets
+ ${IPSET_BIN} flush
+ let ret+=$?
+
+ # Delete ipset sets. If we don't do them individually, then none
+ # will be deleted unless they all can be.
+ for set in $(${IPSET_BIN} list -name); do
+ ${IPSET_BIN} destroy 2>/dev/null
+ [[ $? -ne 0 ]] && ret=1
+ done
+
+ return $ret
+}
+
+start_clean()
+{
+ mkfifo -m go= "${TMP_FIFO}"
+ [[ $? -ne 0 ]] && return 1
+
+ # Get the lists of sets in current(old) config and new config
+ old_sets="$(${IPSET_BIN} list -name | sort -u)"
+ new_sets="$(grep ^create "${IPSET_DATA}" | cut -d " " -f 2 | sort -u)"
+
+ # List of sets no longer wanted
+ drop_sets="$( printf "%s\n" "${old_sets}" > "${TMP_FIFO}" &
+ printf "%s\n" "${new_sets}" | comm -23 "${TMP_FIFO}" -
+ )"
+
+ # Get rid of sets no longer needed
+ # Unfortunately -! doesn't work for destroy, so we have to do it a command at a time
+ for dset in $drop_sets; do
+ ipset destroy $dset 2>/dev/null
+ # If it won't go - ? in use by iptables, just clear it
+ [[ $? -ne 0 ]] && ipset flush $dset
+ done
+
+ # Now delete the set members no longer required
+ ${IPSET_BIN} save | grep "^add " | sort >${TMP_FIFO} &
+ grep "^add " ${IPSET_DATA} | sort | comm -23 ${TMP_FIFO} - | sed -e "s/^add /del /" \
+ | ${IPSET_BIN} restore -!
+
+ # At last we can add the set members we haven't got
+ ipset restore -! <${IPSET_DATA}
+
+ rm ${TMP_FIFO}
+
+ return 0
+}
+
+start() {
+ # Do not start if there is no config file.
+ [[ ! -f "$IPSET_DATA" ]] && echo "Loaded with no configuration" && return 0
+
+ # We can skip the first bit and do a simple load if
+ # there is no current ipset configuration
+ res=1
+ if [[ -n $(${IPSET_BIN} list -name) ]]; then
+ # The following may fail for some bizarre reason
+ start_clean
+ res=$?
+
+ [[ $res -ne 0 ]] && echo "Some old configuration may remain"
+ fi
+
+ # res -ne 0 => either start_clean failed, or we didn't need to run it
+ if [[ $res -ne 0 ]]; then
+ # This is the easy way to start but would leave any old
+ # entries still configured. Still, better than nothing -
+ # but fine if we had no config
+ ${IPSET_BIN} restore -! <${IPSET_DATA}
+ res=$?
+ fi
+
+ if [[ $res -ne 0 ]]; then
+ return 1
+ fi
+
+ return 0
+}
+
+stop() {
+ # Nothing to stop if ip_set module is not loaded.
+ lsmod | grep -q "^ip_set "
+ [[ $? -ne 0 ]] && return 6
+
+ flush_n_delete
+ [[ $? -ne 0 ]] && echo Warning: Not all sets were flushed/deleted
+
+ return 0
+}
+
+save() {
+ # Do not save if ip_set module is not loaded.
+ lsmod | grep -q "^ip_set "
+ [[ $? -ne 0 ]] && return 6
+
+ [[ -z $(${IPSET_BIN} list -name) ]] && return 0
+
+ ret=0
+ TMP_FILE=$(/bin/mktemp -q /tmp/$IPSET.XXXXXX) \
+ && CLEAN_FILES+=" $TMP_FILE" \
+ && chmod 600 "$TMP_FILE" \
+ && ${IPSET_BIN} save > $TMP_FILE 2>/dev/null \
+ && [[ -s $TMP_FILE ]] \
+ || ret=1
+
+ if [[ $ret -eq 0 ]]; then
+ # No need to do anything if the files are the same
+ if [[ ! -f $IPSET_DATA ]]; then
+ mv $TMP_FILE $IPSET_DATA && chmod 600 $IPSET_DATA || ret=1
+ else
+ diff -q $TMP_FILE $IPSET_DATA >/dev/null
+
+ if [[ $? -ne 0 ]]; then
+ if [[ -f $IPSET_DATA ]]; then
+ cp -f --preserve=timestamps $IPSET_DATA $IPSET_DATA.save \
+ && chmod 600 $IPSET_DATA.save \
+ || ret=1
+ fi
+ if [[ $ret -eq 0 ]]; then
+ cp -f --preserve=timestamps $TMP_FILE $IPSET_DATA \
+ && chmod 600 $IPSET_DATA \
+ || ret=1
+ fi
+ fi
+ fi
+ fi
+
+ rm -f $TMP_FILE
+ return $ret
+}
+
+
+case "$1" in
+ start)
+ start
+ RETVAL=$?
+ ;;
+ stop)
+ check_can_unload || exit 1
+ [[ $IPSET_SAVE_ON_STOP = yes ]] && save
+ stop
+ RETVAL=$?
+ [[ $RETVAL -eq 6 ]] && echo "${IPSET}: not running" && exit 0
+ ;;
+ reload)
+ [[ $IPSET_SAVE_ON_RESTART = yes ]] && save
+ stop
+ RETVAL=$?
+ [[ $RETVAL -eq 6 ]] && echo "${IPSET}: not running" && exit 0
+ start
+ RETVAL=$?
+ ;;
+ *)
+ echo "Usage: $IPSET {start|stop|reload}" >&2
+ exit 1
+esac
+
+exit $RETVAL
More information about the scm-commits
mailing list