Thanks to Joel Newkirk, here is the longwinded
response he sent me:
Heavily snipped and re-commented script: IPTABLES=/sbin/iptables LSMOD=/sbin/lsmod DEPMOD=/sbin/depmod INSMOD=/sbin/insmod GREP=/bin/grep AWK=/bin/awk SED=/bin/sed IFCONFIG=/sbin/ifconfig EXTIF="eth0" INTIF="eth1" EXTIP="xxx.xxx.xxx.xxx" INTNET="192.168.1.0/24" INTIP="192.168.1.1/24" # This is redundant, since they are both the same number in actual usage. # It is likely that the intention for INTIP is to hold the IP of $INTIF # interface on this machine, which should not have "/24" at the end. UNIVERSE="0.0.0.0/0" # for what it is worth, this could be "0/0" and would work, but if you # leave it out of rules entirely then this is the default anyway. $DEPMOD -a if [ -z "` $LSMOD | $GREP ip_tables | $AWK {'print $1'} `" ]; then $INSMOD ip_tables fi if [ -z "` $LSMOD | $GREP ip_conntrack | $AWK {'print $1'} `" ]; then $INSMOD ip_conntrack fi if [ -z "` $LSMOD | $GREP ip_conntrack_ftp | $AWK {'print $1'} `" ]; then $INSMOD ip_conntrack_ftp fi if [ -z "` $LSMOD | $GREP ip_conntrack_irc | $AWK {'print $1'} `" ]; then $INSMOD ip_conntrack_irc fi if [ -z "` $LSMOD | $GREP iptable_nat | $AWK {'print $1'} `" ]; then $INSMOD iptable_nat fi if [ -z "` $LSMOD | $GREP ip_nat_ftp | $AWK {'print $1'} `" ]; then $INSMOD ip_nat_ftp fi # You would probably find it faster, and much simpler to read, if you # just use "INSMOD=/sbin/modprobe" and then $INSMOD each # module without the if-fi construct. modprobe checks if the module # is loaded, and if not will load it with insmod, and does it silently. echo "1" > /proc/sys/net/ipv4/ip_forward # barring catastrophe it is not really an issue, but you shouldn't enable # forwarding until AFTER your rules are in place, or at least until after # you have set the DROP policy for FORWARD. $IPTABLES -P INPUT DROP $IPTABLES -F INPUT $IPTABLES -P OUTPUT DROP $IPTABLES -F OUTPUT $IPTABLES -P FORWARD DROP $IPTABLES -F FORWARD $IPTABLES -F -t nat if [ -n "`$IPTABLES -L | $GREP drop-and-log-it`" ]; then $IPTABLES -F drop-and-log-it fi # again, you could dispense with the if-fi construct here. The worst # that will happen is that you see "no chain/target/match by that name" # either on the console or in the logfile. Having it the way it is is a # more 'proper' approach if the script is re-entrant, but in such a case # the "-N drop-and-log-it" below will give you a warning instead if the # "-F drop-and-log-it"... :^) $IPTABLES -X $IPTABLES -Z $IPTABLES -N drop-and-log-it $IPTABLES -A drop-and-log-it -j LOG --log-level info $IPTABLES -A drop-and-log-it -j DROP $IPTABLES -A INPUT -i lo -s $UNIVERSE -d $UNIVERSE -j ACCEPT $IPTABLES -A INPUT -i $INTIF -s $INTNET -d $UNIVERSE -j ACCEPT ### OK, anything in from the LAN is accepted, regardless of what it is. # Kind of loose, but if you are in control of all the machines it's safe # enough. $IPTABLES -A INPUT -i $EXTIF -s $INTNET -d $UNIVERSE -j drop-and-log-it # This is unlikely ever to match, because in the unlikely event that you # DO get a packet from the internet that is addressed back to the # internet, it will end up in the FORWARD chain, since it isn't bound for # this box's IP... $IPTABLES -A INPUT -i $EXTIF -p ICMP -s $UNIVERSE -d $EXTIP -j ACCEPT $IPTABLES -A INPUT -i $EXTIF -s $UNIVERSE -d $EXTIP -m state --state \ ESTABLISHED,RELATED -j ACCEPT ### This rule, together with the ip_conntrack_ftp module you loaded ### above, will allow both passive and active FTP connections through, ### once they are allowed to initiate, IE with the port 20 connection. $IPTABLES -A INPUT -i $INTIF -p tcp --sport 68 --dport 67 -j ACCEPT $IPTABLES -A INPUT -i $INTIF -p udp --sport 68 --dport 67 -j ACCEPT $IPTABLES -A INPUT -i $EXTIF -p tcp --sport 21 -m state --state NEW,ESTABLISHED -j ACCEPT ### Ahhh. You accept "new" connections with SOURCEport 21. ### However, incoming FTP connections will have DESTport 21. $IPTABLES -A OUTPUT -o $EXTIF -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT # This is redundant, since you allow ANY connection out from the local # box below. However, if you ever tighten up the rules to only ACCEPT # specific traffic, simply match "--dport 21" and skip state match. # 1) Active ftp. $IPTABLES -A INPUT -i $EXTIF -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -o $EXTIF -p tcp --dport 20 -m state --state NEW,ESTABLISHED -j ACCEPT # 2) Passive ftp. $IPTABLES -A INPUT -i $EXTIF -p tcp --sport 1024:65535 --dport 1024:65535 \ -m state --state ESTABLISHED -j ACCEPT $IPTABLES -A OUTPUT -o $EXTIF -p tcp --sport 1024:65535 --dport 1024:65535 \ -m state --state ESTABLISHED,RELATED -j ACCEPT ### These (and the two for active, above) are also redundant. You allow ### anything at all outbound anyway, and already have ESTABLISHED ### and RELATED state accepted for inbound. $IPTABLES -A INPUT -s $UNIVERSE -d $UNIVERSE -j drop-and-log-it $IPTABLES -A OUTPUT -o lo -s $UNIVERSE -d $UNIVERSE -j ACCEPT $IPTABLES -A OUTPUT -o $INTIF -s $EXTIP -d $INTNET -j ACCEPT $IPTABLES -A OUTPUT -o $INTIF -s $INTIP -d $INTNET -j ACCEPT $IPTABLES -A OUTPUT -o $EXTIF -s $UNIVERSE -d $INTNET -j drop-and-log-it $IPTABLES -A OUTPUT -o $EXTIF -s $EXTIP -d $UNIVERSE -j ACCEPT $IPTABLES -A OUTPUT -o $INTIF -p tcp -s $INTIP --sport 67 \ -d 255.255.255.255 --dport 68 -j ACCEPT $IPTABLES -A OUTPUT -o $INTIF -p udp -s $INTIP --sport 67 \ -d 255.255.255.255 --dport 68 -j ACCEPT $IPTABLES -A OUTPUT -s $UNIVERSE -d $UNIVERSE -j drop-and-log-it # This rule should be 'safe', since you have the "-s $EXTIP" accept above # However to be precise you'd be better off with: # $IPTABLES -A OUTPUT -s ! $EXTIP -d $UNIVERSE -j drop-and-log-it # which says "any source IP that is NOT $EXTIP" $IPTABLES -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED,RELATED \ -j ACCEPT $IPTABLES -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT $IPTABLES -A FORWARD -j drop-and-log-it $IPTABLES -t nat -A POSTROUTING -o $EXTIF -j SNAT --to $EXTIP # just as an aside, if you're not aware, you need to use # "iptables -t nat -L" to list this rule. the iptables command only # deals with one table at a time, and the default is "-t filter". |