Decent iptables script

Good ideas? Share with us!
Ubi
Posts: 1547
Joined: 17 Jul 2007, 09:01

Decent iptables script

Post by Ubi » 16 Nov 2011, 16:20

This issue just pisses me off beyond belief, and I complained about this a long time ago, to no avail.

The B3 has a braindead script that saves the CURRENT firewall rules upon "/etc/init.d/iptables stop". This means that, if you accidently lock yourself out on the B3, and reboot the machine to recover, your mistake is propagated to the reboot and you're locked out forever! In other words, the only way to recover from an iptables typo is to give the bloody thing a hard down!! BRILLIANT!! Whoever thought this script was a good design decision should have his head examined.

In the meantime I can spend an evening recovering from a &#*$^ USB rescue, and as I gave a IPTABLES FLUSH INPUT command, i probably borked my entire iptables settings without a reference. So if anyone can post the default B3 firewall rules that'd be great.

Eek
Posts: 372
Joined: 23 Dec 2007, 03:03
Location: the Netherlands

Re: Decent iptables script

Post by Eek » 17 Nov 2011, 02:54

I hear you!

Code: Select all

*nat
:PREROUTING ACCEPT [13:1903]
:INPUT ACCEPT [6:303]
:OUTPUT ACCEPT [7:842]
:POSTROUTING ACCEPT [7:1800]
-A POSTROUTING -o eth0 -j MASQUERADE 
COMMIT
# Completed on Sat Oct 29 17:26:52 2011
# Generated by iptables-save v1.4.8 on Sat Oct 29 17:26:52 2011
*filter
:INPUT DROP [2:178]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [192:19666]
-A INPUT -p tcp -m tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset 
-A INPUT -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j DROP 
-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A INPUT -i br0 -j ACCEPT 
-A INPUT -i lo -j ACCEPT 
-A INPUT -i eth0 -p icmp -m icmp --icmp-type 11 -j ACCEPT 
-A INPUT -p icmp -m icmp --icmp-type 3/4 -j ACCEPT 
-A FORWARD -i br0 -j ACCEPT 
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A FORWARD -p icmp -m icmp --icmp-type 3/4 -j ACCEPT 
COMMIT
I have the B3 with wifi, thats the br0
cheers
Eek

johannes
Posts: 1470
Joined: 31 Dec 2006, 07:12
Location: Sweden
Contact:

Re: Decent iptables script

Post by johannes » 17 Nov 2011, 02:58

O-oh, a pissed off Ubi is the last thing we want. Default config is here:

Code: Select all

root@b3-demo:/home# cat /usr/share/bubba-configs/firewall.conf
# Generated by iptables-save v1.3.6 on Wed Jul 30 12:58:05 2008
*nat
:PREROUTING ACCEPT [14:1774]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT
# Completed on Wed Jul 30 12:58:05 2008
# Generated by iptables-save v1.3.6 on Wed Jul 30 12:58:05 2008
*filter
:INPUT DROP [12:1678]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [71:15934]
-A INPUT -p tcp -m tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset
-A INPUT -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j DROP
-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth1 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth0 -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A INPUT -i eth0 -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 3/4 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 143 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 993 -j ACCEPT
-A FORWARD -i eth1 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -p icmp -m icmp --icmp-type 3/4 -j ACCEPT
COMMIT
# Completed on Wed Jul 30 12:58:05 2008
root@b3-demo:/home#
I can't comment about the braindead decision since it was not mine, but I'll ask around later today.
/Johannes (Excito co-founder a long time ago, but now I'm just Johannes)

Ubi
Posts: 1547
Joined: 17 Jul 2007, 09:01

Re: Decent iptables script

Post by Ubi » 17 Nov 2011, 03:17

thanks, guys

Ubi
Posts: 1547
Joined: 17 Jul 2007, 09:01

Re: Decent iptables script

Post by Ubi » 17 Nov 2011, 03:32

So would it be possible to tailor the B3 iptables script from the RHEL script, which is GPL and works quite nicely? I guess a complete copy is not working due to the routing required in the B3, but here's the code. I guess the best way to do this is with a serial-connected B3.

Code: Select all

#!/bin/sh
#
# iptables	Start iptables firewall
#
# chkconfig: 2345 08 92
# description:	Starts, stops and saves iptables firewall
#
# config: /etc/sysconfig/iptables
# config: /etc/sysconfig/iptables-config
#
### BEGIN INIT INFO
# Provides: iptables
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop iptables firewall
# Description: Start, stop and save iptables firewall
### END INIT INFO

# Source function library.
. /etc/init.d/functions

IPTABLES=iptables
IPTABLES_DATA=/etc/sysconfig/$IPTABLES
IPTABLES_CONFIG=/etc/sysconfig/${IPTABLES}-config
IPV=${IPTABLES%tables} # ip for ipv4 | ip6 for ipv6
[ "$IPV" = "ip" ] && _IPV="ipv4" || _IPV="ipv6"
PROC_IPTABLES_NAMES=/proc/net/${IPV}_tables_names
VAR_SUBSYS_IPTABLES=/var/lock/subsys/$IPTABLES

# only usable for root
[ $EUID = 0 ] || exit 4

if [ ! -x /sbin/$IPTABLES ]; then
    echo -n $"${IPTABLES}: /sbin/$IPTABLES does not exist."; warning; echo
    exit 5
fi

# Old or new modutils
/sbin/modprobe --version 2>&1 | grep -q module-init-tools \
    && NEW_MODUTILS=1 \
    || NEW_MODUTILS=0

# Default firewall configuration:
IPTABLES_MODULES=""
IPTABLES_MODULES_UNLOAD="yes"
IPTABLES_SAVE_ON_STOP="no"
IPTABLES_SAVE_ON_RESTART="no"
IPTABLES_SAVE_COUNTER="no"
IPTABLES_STATUS_NUMERIC="yes"
IPTABLES_STATUS_VERBOSE="no"
IPTABLES_STATUS_LINENUMBERS="yes"

# Load firewall configuration.
[ -f "$IPTABLES_CONFIG" ] && . "$IPTABLES_CONFIG"

# Netfilter modules
NF_MODULES=($(lsmod | awk "/^${IPV}table_/ {print \$1}") ${IPV}_tables)
NF_MODULES_COMMON=(x_tables nf_nat nf_conntrack) # Used by netfilter v4 and v6

# Get active tables
NF_TABLES=$(cat "$PROC_IPTABLES_NAMES" 2>/dev/null)


rmmod_r() {
    # Unload module with all referring modules.
    # At first all referring modules will be unloaded, then the module itself.
    local mod=$1
    local ret=0
    local ref=

    # Get referring modules.
    # New modutils have another output format.
    [ $NEW_MODUTILS = 1 ] \
	&& ref=$(lsmod | awk "/^${mod}/ { print \$4; }" | tr ',' ' ') \
	|| ref=$(lsmod | grep ^${mod} | cut -d "[" -s -f 2 | cut -d "]" -s -f 1)

    # recursive call for all referring modules
    for i in $ref; do
	rmmod_r $i
	let ret+=$?;
    done

    # Unload module.
    # The extra test is for 2.6: The module might have autocleaned,
    # after all referring modules are unloaded.
    if grep -q "^${mod}" /proc/modules ; then
	modprobe -r $mod > /dev/null 2>&1
	res=$?
	[ $res -eq 0 ] || echo -n " $mod"
	let ret+=$res;
    fi

    return $ret
}

flush_n_delete() {
    # Flush firewall rules and delete chains.
    [ ! -e "$PROC_IPTABLES_NAMES" ] && return 0

    # Check if firewall is configured (has tables)
    [ -z "$NF_TABLES" ] && return 1

    echo -n $"${IPTABLES}: Flushing firewall rules: "
    ret=0
    # For all tables
    for i in $NF_TABLES; do
        # Flush firewall rules.
	$IPTABLES -t $i -F;
	let ret+=$?;

        # Delete firewall chains.
	$IPTABLES -t $i -X;
	let ret+=$?;

	# Set counter to zero.
	$IPTABLES -t $i -Z;
	let ret+=$?;
    done

    [ $ret -eq 0 ] && success || failure
    echo
    return $ret
}

set_policy() {
    # Set policy for configured tables.
    policy=$1

    # Check if iptable module is loaded
    [ ! -e "$PROC_IPTABLES_NAMES" ] && return 0

    # Check if firewall is configured (has tables)
    tables=$(cat "$PROC_IPTABLES_NAMES" 2>/dev/null)
    [ -z "$tables" ] && return 1

    echo -n $"${IPTABLES}: Setting chains to policy $policy: "
    ret=0
    for i in $tables; do
	echo -n "$i "
	case "$i" in
	    raw)
		$IPTABLES -t raw -P PREROUTING $policy \
		    && $IPTABLES -t raw -P OUTPUT $policy \
		    || let ret+=1
		;;
	    filter)
                $IPTABLES -t filter -P INPUT $policy \
		    && $IPTABLES -t filter -P OUTPUT $policy \
		    && $IPTABLES -t filter -P FORWARD $policy \
		    || let ret+=1
		;;
	    nat)
		$IPTABLES -t nat -P PREROUTING $policy \
		    && $IPTABLES -t nat -P POSTROUTING $policy \
		    && $IPTABLES -t nat -P OUTPUT $policy \
		    || let ret+=1
		;;
	    mangle)
	        $IPTABLES -t mangle -P PREROUTING $policy \
		    && $IPTABLES -t mangle -P POSTROUTING $policy \
		    && $IPTABLES -t mangle -P INPUT $policy \
		    && $IPTABLES -t mangle -P OUTPUT $policy \
		    && $IPTABLES -t mangle -P FORWARD $policy \
		    || let ret+=1
		;;
	    *)
	        let ret+=1
		;;
        esac
    done

    [ $ret -eq 0 ] && success || failure
    echo
    return $ret
}

start() {
    # Do not start if there is no config file.
    [ ! -f "$IPTABLES_DATA" ] && return 6

    # check if ipv6 module load is deactivated
    if [ "${_IPV}" = "ipv6" ] \
	&& grep -qIsE "^install[[:space:]]+${_IPV}[[:space:]]+/bin/(true|false)" /etc/modprobe.conf /etc/modprobe.d/* ; then
	echo $"${IPTABLES}: ${_IPV} is disabled."
	return 150
    fi

    echo -n $"${IPTABLES}: Applying firewall rules: "

    OPT=
    [ "x$IPTABLES_SAVE_COUNTER" = "xyes" ] && OPT="-c"

    $IPTABLES-restore $OPT $IPTABLES_DATA
    if [ $? -eq 0 ]; then
	success; echo
    else
	failure; echo; return 1
    fi
    
    # Load additional modules (helpers)
    if [ -n "$IPTABLES_MODULES" ]; then
	echo -n $"${IPTABLES}: Loading additional modules: "
	ret=0
	for mod in $IPTABLES_MODULES; do
	    echo -n "$mod "
	    modprobe $mod > /dev/null 2>&1
	    let ret+=$?;
	done
	[ $ret -eq 0 ] && success || failure
	echo
    fi
    
    touch $VAR_SUBSYS_IPTABLES
    return $ret
}

stop() {
    # Do not stop if iptables module is not loaded.
    [ ! -e "$PROC_IPTABLES_NAMES" ] && return 0

    flush_n_delete
    set_policy ACCEPT
    
    if [ "x$IPTABLES_MODULES_UNLOAD" = "xyes" ]; then
	echo -n $"${IPTABLES}: Unloading modules: "
	ret=0
	for mod in ${NF_MODULES[*]}; do
	    rmmod_r $mod
	    let ret+=$?;
	done
	# try to unload remaining netfilter modules used by ipv4 and ipv6 
	# netfilter
	for mod in ${NF_MODULES_COMMON[*]}; do
	    rmmod_r $mod >/dev/null
	done
	[ $ret -eq 0 ] && success || failure
	echo
    fi
    
    rm -f $VAR_SUBSYS_IPTABLES
    return $ret
}

save() {
    # Check if iptable module is loaded
    [ ! -e "$PROC_IPTABLES_NAMES" ] && return 0

    # Check if firewall is configured (has tables)
    [ -z "$NF_TABLES" ] && return 6

    echo -n $"${IPTABLES}: Saving firewall rules to $IPTABLES_DATA: "

    OPT=
    [ "x$IPTABLES_SAVE_COUNTER" = "xyes" ] && OPT="-c"

    ret=0
    TMP_FILE=$(/bin/mktemp -q /tmp/$IPTABLES.XXXXXX) \
	&& chmod 600 "$TMP_FILE" \
	&& $IPTABLES-save $OPT > $TMP_FILE 2>/dev/null \
	&& size=$(stat -c '%s' $TMP_FILE) && [ $size -gt 0 ] \
	|| ret=1
    if [ $ret -eq 0 ]; then
	if [ -e $IPTABLES_DATA ]; then
	    cp -f $IPTABLES_DATA $IPTABLES_DATA.save \
		&& chmod 600 $IPTABLES_DATA.save \
		|| ret=1
	fi
	if [ $ret -eq 0 ]; then
	    cp -f $TMP_FILE $IPTABLES_DATA \
		&& chmod 600 $IPTABLES_DATA \
	        || ret=1
	fi
    fi
    [ $ret -eq 0 ] && success || failure
    echo
    rm -f $TMP_FILE
    return $ret
}

status() {
    if [ ! -f "$VAR_SUBSYS_IPTABLES" -a -z "$NF_TABLES" ]; then
	echo $"${IPTABLES}: Firewall is not running."
	return 3
    fi

    # Do not print status if lockfile is missing and iptables modules are not 
    # loaded.
    # Check if iptable modules are loaded
    if [ ! -e "$PROC_IPTABLES_NAMES" ]; then
	echo $"${IPTABLES}: Firewall modules are not loaded."
	return 3
    fi

    # Check if firewall is configured (has tables)
    if [ -z "$NF_TABLES" ]; then
	echo $"${IPTABLES}: Firewall is not configured. "
	return 3
    fi

    NUM=
    [ "x$IPTABLES_STATUS_NUMERIC" = "xyes" ] && NUM="-n"
    VERBOSE= 
    [ "x$IPTABLES_STATUS_VERBOSE" = "xyes" ] && VERBOSE="--verbose"
    COUNT=
    [ "x$IPTABLES_STATUS_LINENUMBERS" = "xyes" ] && COUNT="--line-numbers"

    for table in $NF_TABLES; do
	echo $"Table: $table"
	$IPTABLES -t $table --list $NUM $VERBOSE $COUNT && echo
    done

    return 0
}

restart() {
    [ "x$IPTABLES_SAVE_ON_RESTART" = "xyes" ] && save
    stop
    start
}


case "$1" in
    start)
	[ -f "$VAR_SUBSYS_IPTABLES" ] && exit 0
	start
	RETVAL=$?
	;;
    stop)
	[ "x$IPTABLES_SAVE_ON_STOP" = "xyes" ] && save
	stop
	RETVAL=$?
	;;
    restart|force-reload)
	restart
	RETVAL=$?
	;;
    reload)
	# unimplemented
	RETVAL=3
	;;
    condrestart|try-restart)
	[ ! -e "$VAR_SUBSYS_IPTABLES" ] && exit 0
	restart
	RETVAL=$?
	;;
    status)
	status
	RETVAL=$?
	;;
    panic)
	flush_n_delete
	set_policy DROP
	RETVAL=$?
        ;;
    save)
	save
	RETVAL=$?
	;;
    *)
	echo $"Usage: ${IPTABLES} {start|stop|restart|condrestart|status|panic|save}"
	RETVAL=2
	;;
esac

exit $RETVAL

MouettE
Site admin
Posts: 286
Joined: 06 Oct 2011, 19:45

Re: Decent iptables script

Post by MouettE » 17 Nov 2011, 11:37

I think a simpler way is to use iptables-restore in /etc/network/interfaces with the up keyword under eth0 or eth1. Besides that's the method debian guys recommend.

Gordon
Posts: 1390
Joined: 10 Aug 2011, 03:18

Re: Decent iptables script

Post by Gordon » 17 Nov 2011, 12:40

Sorry to say, but *every* firewall script may eventually cause you to be locked out. I must admit though that this one is particularly stupid in that it saves dynamically/user added rules on shutdown.

The trouble with standard firewall settings is that are too general. This was the case with ipfw, with ipchains, and still now with iptables and this will most likely never change. To be able to access anything from the outside, you need to add rules to "INPUT". This does not discriminate between interfaces though, which is what you really want. This is why I requested to implement Shorewall; probably the best firewall script out there (although I would really like them to support the 'controversial' geoip add-on).

Ubi
Posts: 1547
Joined: 17 Jul 2007, 09:01

Re: Decent iptables script

Post by Ubi » 17 Nov 2011, 12:46

isn't shorewall a bit overkill for a relatively simple setup such as the B3?

Gordon
Posts: 1390
Joined: 10 Aug 2011, 03:18

Re: Decent iptables script

Post by Gordon » 17 Nov 2011, 13:48

Depends on your definition of ´simple setup´. It has a ´trusted´ (LAN) and a 'non-trusted' (WAN) interface, so it has all the elements in it that Shorewall is designed for. I know you are an advocate of the Keep-It-Simple policy, but there's also a thing called oversimplifying which is a main cause for error.

Ubi
Posts: 1547
Joined: 17 Jul 2007, 09:01

Re: Decent iptables script

Post by Ubi » 17 Nov 2011, 15:44

fair enough.

I just found the learning curve to be too steep for the benefits it offered. But then I admin mainly simple hosting servers without any routing. I thought benefits of shorewall were only evident in switches and routers. Of course, that is what the B3 is, so for the B3 shorewall may be great indeed.

Gordon
Posts: 1390
Joined: 10 Aug 2011, 03:18

Re: Decent iptables script

Post by Gordon » 17 Nov 2011, 17:40

Thing is that Shorewall will break up the tables by defining directions between what is called zones: where do you come from and where do you want to go? Every rule you create thereafter is based on one of these directions and you never ever get to touch the original INPUT, OUTPUT, FORWARD, PREROUTING, POSTROUTING tables. Once you define the LAN interface as a safe zone you can basically f*ck up the WAN zone without being scared of being locked out when you're connected to the LAN interface.

I'd say it would most likely be possible to adapt the current firewall web interface to manipulate a predefined Shorewall setup. Implementing Shorewall would therefore not have to complicate life for users that never go falukorv, but will make it more flexible for users that want some not-out-of-the-box functionality (like VPN).

Edit: 'falukorv' is what the system prints instead of a word that is also commonly used for something not suited for children. So allow me to rephrase that as "users that never enter system level".
Last edited by Gordon on 18 Nov 2011, 04:36, edited 1 time in total.

RandomUsername
Posts: 904
Joined: 09 Oct 2009, 18:49

Re: Decent iptables script

Post by RandomUsername » 18 Nov 2011, 00:42

OT but; falukorv?

NisseJ
Posts: 40
Joined: 09 Jan 2011, 07:55
Location: Sweden
Contact:

Re: Decent iptables script

Post by NisseJ » 18 Nov 2011, 00:44

RandomUsername wrote:OT but; falukorv?
Better go falukorv than go surströmmig!

Gordon
Posts: 1390
Joined: 10 Aug 2011, 03:18

Re: Decent iptables script

Post by Gordon » 18 Nov 2011, 02:32

RandomUsername wrote:OT but; falukorv?
I have absolutely no idea. A mod joke?

johannes
Posts: 1470
Joined: 31 Dec 2006, 07:12
Location: Sweden
Contact:

Re: Decent iptables script

Post by johannes » 18 Nov 2011, 03:25

Ah, ah spam word censoring thing that went wrong. Gordon ment to write h a r d c o r e.
/Johannes (Excito co-founder a long time ago, but now I'm just Johannes)

Post Reply