3a00e5
#!/bin/bash
3a00e5
#
3a00e5
# iptables	Start iptables firewall
3a00e5
#
3a00e5
# chkconfig: 2345 08 92
3a00e5
# description:	Starts, stops and saves iptables firewall
3a00e5
#
3a00e5
# config: /etc/sysconfig/iptables
3a00e5
# config: /etc/sysconfig/iptables-config
3a00e5
#
3a00e5
### BEGIN INIT INFO
3a00e5
# Provides: iptables
3a00e5
# Required-Start:
3a00e5
# Required-Stop:
3a00e5
# Default-Start: 2 3 4 5
3a00e5
# Default-Stop: 0 1 6
3a00e5
# Short-Description: start and stop iptables firewall
3a00e5
# Description: Start, stop and save iptables firewall
3a00e5
### END INIT INFO
3a00e5
3a00e5
# compat for removed initscripts dependency
3a00e5
3a00e5
success() {
3a00e5
	echo -n "[  OK  ]"
3a00e5
	return 0
3a00e5
}
3a00e5
3a00e5
warning() {
3a00e5
	echo -n "[WARNING]"
3a00e5
	return 1
3a00e5
}
3a00e5
3a00e5
failure() {
3a00e5
	echo -n "[FAILED]"
3a00e5
	return 1
3a00e5
}
3a00e5
3a00e5
IPTABLES=iptables
3a00e5
IPTABLES_DATA=/etc/sysconfig/$IPTABLES
3a00e5
IPTABLES_FALLBACK_DATA=${IPTABLES_DATA}.fallback
3a00e5
IPTABLES_CONFIG=/etc/sysconfig/${IPTABLES}-config
3a00e5
IPV=${IPTABLES%tables} # ip for ipv4 | ip6 for ipv6
3a00e5
[ "$IPV" = "ip" ] && _IPV="ipv4" || _IPV="ipv6"
3a00e5
PROC_IPTABLES_NAMES=/proc/net/${IPV}_tables_names
3a00e5
VAR_SUBSYS_IPTABLES=/var/lock/subsys/$IPTABLES
3a00e5
3a00e5
# only usable for root
3a00e5
if [ $EUID != 0 ]; then
3a00e5
    echo -n $"${IPTABLES}: Only usable by root."; warning; echo
3a00e5
    exit 4
3a00e5
fi
3a00e5
3a00e5
if [ ! -x /sbin/$IPTABLES ]; then
3a00e5
    echo -n $"${IPTABLES}: /sbin/$IPTABLES does not exist."; warning; echo
3a00e5
    exit 5
3a00e5
fi
3a00e5
3a00e5
# Default firewall configuration:
3a00e5
IPTABLES_MODULES=""
3a00e5
IPTABLES_SAVE_ON_STOP="no"
3a00e5
IPTABLES_SAVE_ON_RESTART="no"
3a00e5
IPTABLES_SAVE_COUNTER="no"
3a00e5
IPTABLES_STATUS_NUMERIC="yes"
3a00e5
IPTABLES_STATUS_VERBOSE="no"
3a00e5
IPTABLES_STATUS_LINENUMBERS="yes"
3a00e5
IPTABLES_SYSCTL_LOAD_LIST=""
3a00e5
IPTABLES_RESTORE_WAIT=600
3a00e5
IPTABLES_RESTORE_WAIT_INTERVAL=1000000
3a00e5
3a00e5
# Load firewall configuration.
3a00e5
[ -f "$IPTABLES_CONFIG" ] && . "$IPTABLES_CONFIG"
3a00e5
3a00e5
is_iptables_nft() {
3a00e5
	iptables --version | grep -q '(nf_tables)'
3a00e5
}
3a00e5
3a00e5
netfilter_active() {
3a00e5
	is_iptables_nft && return 0
3a00e5
	[ -e "$PROC_IPTABLES_NAMES" ]
3a00e5
}
3a00e5
3a00e5
netfilter_tables() {
3a00e5
	netfilter_active || return 1
3a00e5
	is_iptables_nft && {
3a00e5
		# explicitly omit security table from this list as
3a00e5
		# it should be reserved for SELinux use
3a00e5
		echo "raw mangle filter nat"
3a00e5
		return 0
3a00e5
	}
3a00e5
	cat "$PROC_IPTABLES_NAMES" 2>/dev/null
3a00e5
}
3a00e5
3a00e5
# Get active tables
3a00e5
NF_TABLES=$(netfilter_tables)
3a00e5
3a00e5
3a00e5
flush_n_delete() {
3a00e5
    # Flush firewall rules and delete chains.
3a00e5
    netfilter_active || return 0
3a00e5
3a00e5
    # Check if firewall is configured (has tables)
3a00e5
    [ -z "$NF_TABLES" ] && return 1
3a00e5
3a00e5
    echo -n $"${IPTABLES}: Flushing firewall rules: "
3a00e5
    ret=0
3a00e5
    # For all tables
3a00e5
    for i in $NF_TABLES; do
3a00e5
        # Flush firewall rules.
3a00e5
	$IPTABLES -t $i -F;
3a00e5
	let ret+=$?;
3a00e5
3a00e5
        # Delete firewall chains.
3a00e5
	$IPTABLES -t $i -X;
3a00e5
	let ret+=$?;
3a00e5
3a00e5
	# Set counter to zero.
3a00e5
	$IPTABLES -t $i -Z;
3a00e5
	let ret+=$?;
3a00e5
    done
3a00e5
3a00e5
    [ $ret -eq 0 ] && success || failure
3a00e5
    echo
3a00e5
    return $ret
3a00e5
}
3a00e5
3a00e5
set_policy() {
3a00e5
    # Set policy for configured tables.
3a00e5
    policy=$1
3a00e5
3a00e5
    # Check if iptable module is loaded
3a00e5
    netfilter_active || return 0
3a00e5
3a00e5
    # Check if firewall is configured (has tables)
3a00e5
    tables=$(netfilter_tables)
3a00e5
    [ -z "$tables" ] && return 1
3a00e5
3a00e5
    echo -n $"${IPTABLES}: Setting chains to policy $policy: "
3a00e5
    ret=0
3a00e5
    for i in $tables; do
3a00e5
	echo -n "$i "
3a00e5
	case "$i" in
3a00e5
	    raw)
3a00e5
		$IPTABLES -t raw -P PREROUTING $policy \
3a00e5
		    && $IPTABLES -t raw -P OUTPUT $policy \
3a00e5
		    || let ret+=1
3a00e5
		;;
3a00e5
	    filter)
3a00e5
                $IPTABLES -t filter -P INPUT $policy \
3a00e5
		    && $IPTABLES -t filter -P OUTPUT $policy \
3a00e5
		    && $IPTABLES -t filter -P FORWARD $policy \
3a00e5
		    || let ret+=1
3a00e5
		;;
3a00e5
	    nat)
3a00e5
		$IPTABLES -t nat -P PREROUTING $policy \
3a00e5
		    && $IPTABLES -t nat -P POSTROUTING $policy \
3a00e5
		    && $IPTABLES -t nat -P OUTPUT $policy \
3a00e5
		    || let ret+=1
3a00e5
		;;
3a00e5
	    mangle)
3a00e5
	        $IPTABLES -t mangle -P PREROUTING $policy \
3a00e5
		    && $IPTABLES -t mangle -P POSTROUTING $policy \
3a00e5
		    && $IPTABLES -t mangle -P INPUT $policy \
3a00e5
		    && $IPTABLES -t mangle -P OUTPUT $policy \
3a00e5
		    && $IPTABLES -t mangle -P FORWARD $policy \
3a00e5
		    || let ret+=1
3a00e5
		;;
3a00e5
	    *)
3a00e5
	        let ret+=1
3a00e5
		;;
3a00e5
        esac
3a00e5
    done
3a00e5
3a00e5
    [ $ret -eq 0 ] && success || failure
3a00e5
    echo
3a00e5
    return $ret
3a00e5
}
3a00e5
3a00e5
load_sysctl() {
3a00e5
    # load matched sysctl values
3a00e5
    if [ -n "$IPTABLES_SYSCTL_LOAD_LIST" ]; then
3a00e5
        echo -n $"Loading sysctl settings: "
3a00e5
        ret=0
3a00e5
        for item in $IPTABLES_SYSCTL_LOAD_LIST; do
3a00e5
            fgrep -hs $item /etc/sysctl.d/*.conf | sysctl -p - >/dev/null
3a00e5
            let ret+=$?;
3a00e5
        done
3a00e5
        [ $ret -eq 0 ] && success || failure
3a00e5
        echo
3a00e5
    fi
3a00e5
    return $ret
3a00e5
}
3a00e5
3a00e5
start() {
3a00e5
    # Do not start if there is no config file.
3a00e5
    if [ ! -f "$IPTABLES_DATA" ]; then
3a00e5
	echo -n $"${IPTABLES}: No config file."; warning; echo
3a00e5
	return 6
3a00e5
    fi
3a00e5
3a00e5
    # check if ipv6 module load is deactivated
3a00e5
    if [ "${_IPV}" = "ipv6" ] \
3a00e5
	&& grep -qIsE "^install[[:space:]]+${_IPV}[[:space:]]+/bin/(true|false)" /etc/modprobe.conf /etc/modprobe.d/* ; then
3a00e5
	echo $"${IPTABLES}: ${_IPV} is disabled."
3a00e5
	return 150
3a00e5
    fi
3a00e5
3a00e5
    echo -n $"${IPTABLES}: Applying firewall rules: "
3a00e5
3a00e5
    OPT=
3a00e5
    [ "x$IPTABLES_SAVE_COUNTER" = "xyes" ] && OPT="-c"
3a00e5
    if [ $IPTABLES_RESTORE_WAIT -ne 0 ]; then
3a00e5
       OPT="${OPT} --wait ${IPTABLES_RESTORE_WAIT}"
3a00e5
       if [ $IPTABLES_RESTORE_WAIT_INTERVAL -lt 1000000 ]; then
3a00e5
           OPT="${OPT} --wait-interval ${IPTABLES_RESTORE_WAIT_INTERVAL}"
3a00e5
       fi
3a00e5
    fi
3a00e5
3a00e5
    $IPTABLES-restore $OPT $IPTABLES_DATA
3a00e5
    if [ $? -eq 0 ]; then
3a00e5
	success; echo
3a00e5
    else
3a00e5
	failure; echo;
3a00e5
	if [ -f "$IPTABLES_FALLBACK_DATA" ]; then
3a00e5
	    echo -n $"${IPTABLES}: Applying firewall fallback rules: "
3a00e5
	    $IPTABLES-restore $OPT $IPTABLES_FALLBACK_DATA
3a00e5
	    if [ $? -eq 0 ]; then
3a00e5
		success; echo
3a00e5
	    else
3a00e5
		failure; echo; return 1
3a00e5
	    fi
3a00e5
	else
3a00e5
	    return 1
3a00e5
	fi
3a00e5
    fi
3a00e5
 
3a00e5
    # Load additional modules (helpers)
3a00e5
    if [ -n "$IPTABLES_MODULES" ]; then
3a00e5
	echo -n $"${IPTABLES}: Loading additional modules: "
3a00e5
	ret=0
3a00e5
	for mod in $IPTABLES_MODULES; do
3a00e5
	    echo -n "$mod "
3a00e5
	    modprobe $mod > /dev/null 2>&1
3a00e5
	    let ret+=$?;
3a00e5
	done
3a00e5
	[ $ret -eq 0 ] && success || failure
3a00e5
	echo
3a00e5
    fi
3a00e5
 
3a00e5
    # Load sysctl settings
3a00e5
    load_sysctl
3a00e5
3a00e5
    touch $VAR_SUBSYS_IPTABLES
3a00e5
    return $ret
3a00e5
}
3a00e5
3a00e5
stop() {
3a00e5
    # Do not stop if iptables module is not loaded.
3a00e5
    netfilter_active || return 0
3a00e5
3a00e5
    # Set default chain policy to ACCEPT, in order to not break shutdown
3a00e5
    # on systems where the default policy is DROP and root device is
3a00e5
    # network-based (i.e.: iSCSI, NFS)
3a00e5
    set_policy ACCEPT
3a00e5
    # And then, flush the rules and delete chains
3a00e5
    flush_n_delete
3a00e5
3a00e5
    rm -f $VAR_SUBSYS_IPTABLES
3a00e5
    return $ret
3a00e5
}
3a00e5
3a00e5
save() {
3a00e5
    # Check if iptable module is loaded
3a00e5
    if ! netfilter_active; then
3a00e5
	echo -n $"${IPTABLES}: Nothing to save."; warning; echo
3a00e5
	return 0
3a00e5
    fi
3a00e5
3a00e5
    # Check if firewall is configured (has tables)
3a00e5
    if [ -z "$NF_TABLES" ]; then
3a00e5
	echo -n $"${IPTABLES}: Nothing to save."; warning; echo
3a00e5
	return 6
3a00e5
    fi
3a00e5
3a00e5
    echo -n $"${IPTABLES}: Saving firewall rules to $IPTABLES_DATA: "
3a00e5
3a00e5
    OPT=
3a00e5
    [ "x$IPTABLES_SAVE_COUNTER" = "xyes" ] && OPT="-c"
3a00e5
3a00e5
    ret=0
3a00e5
    TMP_FILE=$(/bin/mktemp -q $IPTABLES_DATA.XXXXXX) \
3a00e5
	&& chmod 600 "$TMP_FILE" \
3a00e5
	&& $IPTABLES-save $OPT > $TMP_FILE 2>/dev/null \
3a00e5
	&& size=$(stat -c '%s' $TMP_FILE) && [ $size -gt 0 ] \
3a00e5
	|| ret=1
3a00e5
    if [ $ret -eq 0 ]; then
3a00e5
	if [ -e $IPTABLES_DATA ]; then
3a00e5
	    cp -f $IPTABLES_DATA $IPTABLES_DATA.save \
3a00e5
		&& chmod 600 $IPTABLES_DATA.save \
3a00e5
		&& restorecon $IPTABLES_DATA.save \
3a00e5
		|| ret=1
3a00e5
	fi
3a00e5
	if [ $ret -eq 0 ]; then
3a00e5
	    mv -f $TMP_FILE $IPTABLES_DATA \
3a00e5
		&& chmod 600 $IPTABLES_DATA \
3a00e5
		&& restorecon $IPTABLES_DATA \
3a00e5
	        || ret=1
3a00e5
	fi
3a00e5
    fi
3a00e5
    rm -f $TMP_FILE
3a00e5
    [ $ret -eq 0 ] && success || failure
3a00e5
    echo
3a00e5
    return $ret
3a00e5
}
3a00e5
3a00e5
status() {
3a00e5
    if [ ! -f "$VAR_SUBSYS_IPTABLES" ]; then
3a00e5
	echo $"${IPTABLES}: Firewall is not running."
3a00e5
	return 3
3a00e5
    fi
3a00e5
3a00e5
    # Do not print status if lockfile is missing and iptables modules are not 
3a00e5
    # loaded.
3a00e5
    # Check if iptable modules are loaded
3a00e5
    if ! netfilter_active; then
3a00e5
	echo $"${IPTABLES}: Firewall modules are not loaded."
3a00e5
	return 3
3a00e5
    fi
3a00e5
3a00e5
    # Check if firewall is configured (has tables)
3a00e5
    if [ -z "$NF_TABLES" ]; then
3a00e5
	echo $"${IPTABLES}: Firewall is not configured. "
3a00e5
	return 3
3a00e5
    fi
3a00e5
3a00e5
    NUM=
3a00e5
    [ "x$IPTABLES_STATUS_NUMERIC" = "xyes" ] && NUM="-n"
3a00e5
    VERBOSE=
3a00e5
    [ "x$IPTABLES_STATUS_VERBOSE" = "xyes" ] && VERBOSE="--verbose"
3a00e5
    COUNT=
3a00e5
    [ "x$IPTABLES_STATUS_LINENUMBERS" = "xyes" ] && COUNT="--line-numbers"
3a00e5
3a00e5
    for table in $NF_TABLES; do
3a00e5
	echo $"Table: $table"
3a00e5
	$IPTABLES -t $table --list $NUM $VERBOSE $COUNT && echo
3a00e5
    done
3a00e5
3a00e5
    return 0
3a00e5
}
3a00e5
3a00e5
reload() {
3a00e5
    # Do not reload if there is no config file.
3a00e5
    if [ ! -f "$IPTABLES_DATA" ]; then
3a00e5
	echo -n $"${IPTABLES}: No config file."; warning; echo
3a00e5
	return 6
3a00e5
    fi
3a00e5
3a00e5
    # check if ipv6 module load is deactivated
3a00e5
    if [ "${_IPV}" = "ipv6" ] \
3a00e5
	&& grep -qIsE "^install[[:space:]]+${_IPV}[[:space:]]+/bin/(true|false)" /etc/modprobe.conf /etc/modprobe.d/* ; then
3a00e5
	echo $"${IPTABLES}: ${_IPV} is disabled."
3a00e5
	return 150
3a00e5
    fi
3a00e5
3a00e5
    echo -n $"${IPTABLES}: Trying to reload firewall rules: "
3a00e5
3a00e5
    OPT=
3a00e5
    [ "x$IPTABLES_SAVE_COUNTER" = "xyes" ] && OPT="-c"
3a00e5
    if [ $IPTABLES_RESTORE_WAIT -ne 0 ]; then
3a00e5
       OPT="${OPT} --wait ${IPTABLES_RESTORE_WAIT}"
3a00e5
       if [ $IPTABLES_RESTORE_WAIT_INTERVAL -lt 1000000 ]; then
3a00e5
           OPT="${OPT} --wait-interval ${IPTABLES_RESTORE_WAIT_INTERVAL}"
3a00e5
       fi
3a00e5
    fi
3a00e5
3a00e5
    $IPTABLES-restore $OPT $IPTABLES_DATA
3a00e5
    if [ $? -eq 0 ]; then
3a00e5
	success; echo
3a00e5
    else
3a00e5
	failure; echo; echo "Firewall rules are not changed."; return 1
3a00e5
    fi
3a00e5
3a00e5
    # Load additional modules (helpers)
3a00e5
    if [ -n "$IPTABLES_MODULES" ]; then
3a00e5
	echo -n $"${IPTABLES}: Loading additional modules: "
3a00e5
	ret=0
3a00e5
	for mod in $IPTABLES_MODULES; do
3a00e5
	    echo -n "$mod "
3a00e5
	    modprobe $mod > /dev/null 2>&1
3a00e5
	    let ret+=$?;
3a00e5
	done
3a00e5
	[ $ret -eq 0 ] && success || failure
3a00e5
	echo
3a00e5
    fi
3a00e5
3a00e5
    # Load sysctl settings
3a00e5
    load_sysctl
3a00e5
3a00e5
    return $ret
3a00e5
}
3a00e5
3a00e5
restart() {
3a00e5
    [ "x$IPTABLES_SAVE_ON_RESTART" = "xyes" ] && save
3a00e5
    stop
3a00e5
    start
3a00e5
}
3a00e5
3a00e5
3a00e5
case "$1" in
3a00e5
    start)
3a00e5
	[ -f "$VAR_SUBSYS_IPTABLES" ] && exit 0
3a00e5
	start
3a00e5
	RETVAL=$?
3a00e5
	;;
3a00e5
    stop)
3a00e5
	[ "x$IPTABLES_SAVE_ON_STOP" = "xyes" ] && save
3a00e5
	stop
3a00e5
	RETVAL=$?
3a00e5
	;;
3a00e5
    restart|force-reload)
3a00e5
	restart
3a00e5
	RETVAL=$?
3a00e5
	;;
3a00e5
    reload)
3a00e5
	[ -e "$VAR_SUBSYS_IPTABLES" ] && reload
3a00e5
	RETVAL=$?
3a00e5
	;;      
3a00e5
    condrestart|try-restart)
3a00e5
	[ ! -e "$VAR_SUBSYS_IPTABLES" ] && exit 0
3a00e5
	restart
3a00e5
	RETVAL=$?
3a00e5
	;;
3a00e5
    status)
3a00e5
	status
3a00e5
	RETVAL=$?
3a00e5
	;;
3a00e5
    panic)
3a00e5
	set_policy DROP
3a00e5
	RETVAL=$?
3a00e5
        ;;
3a00e5
    save)
3a00e5
	save
3a00e5
	RETVAL=$?
3a00e5
	;;
3a00e5
    *)
3a00e5
	echo $"Usage: ${IPTABLES} {start|stop|reload|restart|condrestart|status|panic|save}"
3a00e5
	RETVAL=2
3a00e5
	;;
3a00e5
esac
3a00e5
3a00e5
exit $RETVAL