Blame SOURCES/ipset.start-stop

f5104d
#!/bin/bash
f5104d
#
f5104d
# ipset      Start and stop ipset firewall sets
f5104d
#
f5104d
# config: /etc/ipset/ipset
f5104d
#
f5104d
f5104d
IPSET=ipset
f5104d
IPSET_BIN=/usr/sbin/${IPSET}
f5104d
IPSET_DATA=/etc/sysconfig/${IPSET}
f5104d
IPSET_CONFIG=/etc/sysconfig/ipset-config
f5104d
f5104d
TMP_FIFO=/tmp/${IPSET}.$$
f5104d
f5104d
if [[ ! -x ${IPSET_BIN} ]]; then
f5104d
	echo "${IPSET_BIN} does not exist."
f5104d
	exit 5
f5104d
fi
f5104d
f5104d
CLEAN_FILES=TMP_FIFO
f5104d
trap "rm -f \$CLEAN_FILES" EXIT
f5104d
f5104d
# Load ipset configuration
f5104d
[[ -f "$IPSET_CONFIG" ]] && . "$IPSET_CONFIG"
f5104d
f5104d
# Default ipset configuration:
f5104d
[[ -z $IPSET_SAVE_ON_STOP ]] && IPSET_SAVE_ON_STOP=no
f5104d
f5104d
check_can_unload() {
f5104d
    # If the xt_set module is loaded and can't be unloaded, then iptables is
f5104d
    # using ipsets, so refuse to stop the service.
f5104d
    if [[ -n $(lsmod | grep "^xt_set ") ]]; then
f5104d
	rmmod xt_set 2>/dev/null
f5104d
	[[ $? -ne 0 ]] && echo Current iptables configuration requires ipsets && return 1
f5104d
    fi
f5104d
f5104d
    return 0
f5104d
}
f5104d
f5104d
flush_n_delete() {
f5104d
    local ret=0 set
f5104d
f5104d
    # Flush sets
f5104d
    ${IPSET_BIN} flush
f5104d
    let ret+=$?
f5104d
f5104d
    # Delete ipset sets. If we don't do them individually, then none
f5104d
    # will be deleted unless they all can be.
f5104d
    for set in $(${IPSET_BIN} list -name); do
f5104d
	    ${IPSET_BIN} destroy 2>/dev/null
f5104d
	    [[ $? -ne 0 ]] && ret=1
f5104d
    done
f5104d
f5104d
    return $ret
f5104d
}
f5104d
f5104d
start_clean()
f5104d
{
f5104d
    mkfifo -m go= "${TMP_FIFO}"
f5104d
    [[ $? -ne 0 ]] && return 1
f5104d
f5104d
    # Get the lists of sets in current(old) config and new config
f5104d
    old_sets="$(${IPSET_BIN} list -name | sort -u)"
f5104d
    new_sets="$(grep ^create "${IPSET_DATA}" | cut -d " " -f 2 | sort -u)"
f5104d
f5104d
    # List of sets no longer wanted
f5104d
    drop_sets="$( printf "%s\n" "${old_sets}" > "${TMP_FIFO}"  &
f5104d
		  printf "%s\n" "${new_sets}" | comm -23 "${TMP_FIFO}" -
f5104d
		)"
f5104d
f5104d
    # Get rid of sets no longer needed
f5104d
    # Unfortunately -! doesn't work for destroy, so we have to do it a command at a time
f5104d
    for dset in $drop_sets; do
f5104d
	ipset destroy $dset 2>/dev/null
f5104d
	# If it won't go - ? in use by iptables, just clear it
f5104d
	[[ $? -ne 0 ]] && ipset flush $dset
f5104d
    done
f5104d
f5104d
    # Now delete the set members no longer required
f5104d
    ${IPSET_BIN} save | grep "^add " | sort >${TMP_FIFO} &
f5104d
      grep "^add " ${IPSET_DATA} | sort | comm -23 ${TMP_FIFO} - | sed -e "s/^add /del /" \
f5104d
      | ${IPSET_BIN} restore -!
f5104d
f5104d
    # At last we can add the set members we haven't got
f5104d
    ipset restore -! <${IPSET_DATA}
f5104d
f5104d
    rm ${TMP_FIFO}
f5104d
f5104d
    return 0
f5104d
}
f5104d
f5104d
start() {
f5104d
    # Do not start if there is no config file.
f5104d
    [[ ! -f "$IPSET_DATA" ]] && echo "Loaded with no configuration" && return 0
f5104d
f5104d
    # We can skip the first bit and do a simple load if
f5104d
    # there is no current ipset configuration
f5104d
    res=1
f5104d
    if [[ -n $(${IPSET_BIN} list -name) ]]; then
f5104d
	# The following may fail for some bizarre reason
f5104d
	start_clean
f5104d
	res=$?
f5104d
f5104d
	[[ $res -ne 0 ]] && echo "Some old configuration may remain"
f5104d
    fi
f5104d
f5104d
    # res -ne 0 => either start_clean failed, or we didn't need to run it
f5104d
    if [[ $res -ne 0 ]]; then
f5104d
	# This is the easy way to start but would leave any old
f5104d
	# entries still configured. Still, better than nothing -
f5104d
	# but fine if we had no config
f5104d
	${IPSET_BIN} restore -! <${IPSET_DATA}
f5104d
	res=$?
f5104d
    fi
f5104d
f5104d
    if [[ $res -ne 0 ]]; then
f5104d
	return 1
f5104d
    fi
f5104d
f5104d
    return 0
f5104d
}
f5104d
f5104d
stop() {
f5104d
    # Nothing to stop if ip_set module is not loaded.
f5104d
    lsmod | grep -q "^ip_set "
f5104d
    [[ $? -ne 0 ]] && return 6
f5104d
f5104d
    flush_n_delete
f5104d
    [[ $? -ne 0 ]] && echo Warning: Not all sets were flushed/deleted
f5104d
f5104d
    return 0
f5104d
}
f5104d
f5104d
save() {
f5104d
    # Do not save if ip_set module is not loaded.
f5104d
    lsmod | grep -q "^ip_set "
f5104d
    [[ $? -ne 0 ]] && return 6
f5104d
afce33
    if [[ -z $(${IPSET_BIN} list -name) ]]; then
afce33
	if [[ -f $IPSET_DATA ]]; then
afce33
	    mv $IPSET_DATA $IPSET_DATA.save && chmod 600 $IPSET_DATA.save \
afce33
		    || return 1
afce33
	fi
afce33
	return 0
afce33
    fi
f5104d
f5104d
    ret=0
f5104d
    TMP_FILE=$(/bin/mktemp -q /tmp/$IPSET.XXXXXX) \
f5104d
	&& CLEAN_FILES+=" $TMP_FILE" \
f5104d
	&& chmod 600 "$TMP_FILE" \
f5104d
	&& ${IPSET_BIN} save > $TMP_FILE 2>/dev/null \
f5104d
	&& [[ -s $TMP_FILE ]] \
f5104d
	|| ret=1
f5104d
f5104d
    if [[ $ret -eq 0 ]]; then
f5104d
	# No need to do anything if the files are the same
f5104d
	if [[ ! -f $IPSET_DATA ]]; then
f5104d
	    mv $TMP_FILE $IPSET_DATA && chmod 600 $IPSET_DATA || ret=1
f5104d
	else
f5104d
	    diff -q $TMP_FILE $IPSET_DATA >/dev/null
f5104d
	
f5104d
	    if [[ $? -ne 0 ]]; then
f5104d
		if [[ -f $IPSET_DATA ]]; then
f5104d
		    cp -f --preserve=timestamps $IPSET_DATA $IPSET_DATA.save \
f5104d
			&& chmod 600 $IPSET_DATA.save \
f5104d
			|| ret=1
f5104d
		fi
f5104d
		if [[ $ret -eq 0 ]]; then
f5104d
		    cp -f --preserve=timestamps $TMP_FILE $IPSET_DATA \
f5104d
			&& chmod 600 $IPSET_DATA \
f5104d
			|| ret=1
f5104d
		fi
f5104d
	    fi
f5104d
	fi
f5104d
    fi
f5104d
f5104d
    rm -f $TMP_FILE
f5104d
    return $ret
f5104d
}
f5104d
f5104d
f5104d
case "$1" in
f5104d
    start)
f5104d
	start
f5104d
	RETVAL=$?
f5104d
	;;
f5104d
    stop)
f5104d
	check_can_unload || exit 1
f5104d
	[[ $IPSET_SAVE_ON_STOP = yes ]] && save
f5104d
	stop
f5104d
	RETVAL=$?
f5104d
	[[ $RETVAL -eq 6 ]] && echo "${IPSET}: not running" && exit 0
f5104d
	;;
f5104d
    reload)
f5104d
	stop
f5104d
	RETVAL=$?
f5104d
	[[ $RETVAL -eq 6 ]] && echo "${IPSET}: not running" && exit 0
f5104d
	start
f5104d
	RETVAL=$?
f5104d
	;;
f5104d
    save)
f5104d
        save
f5104d
        RETVAL=$?
f5104d
        ;;
f5104d
    *)
f5104d
	echo "Usage: $IPSET {start|stop|reload}" >&2
f5104d
	exit 1
f5104d
esac
f5104d
f5104d
exit $RETVAL