DOSC TWiki snapshot as of mid-2005
I didn't like, or really understand :), the default redhat iptables script, so I started my own in perl. I have a feeling perl was wild overkill, but whatever. This understands a very simple configuration file; here is mine:
#####################BEGIN################## iptables "/sbin/iptables" tcp_public "22,113" udp_public "" tcp_dartmouth "913" udp_dartmouth "" tcp_reject_public "1080" udp_reject_public "" tcp_reject_dartmouth "445" udp_reject_dartmouth "" dartmouth "129.170.0.0/16" ntp_conf "/etc/ntp.conf" open_ntp true ################END####################The location for this is /etc/sysconfig/iptablesnew. This example allows connections to 22 and 113 tcp from anywhere, to 913 tcp from 129.170.0.0./16 only, and sends tcp rsts on 1080 from everywhere, and 445 from 129.170.0.0/16 only. It also makes appropriate rules for
server xxxxx
lines in /etc/ntp.conf. The code is super super alpha and maybe doesn't even work; it's more for people to comment on/add to at this point.
Hint: set iptables to "/bin/echo" to test it.
Ok, the attachment mechanism baffles me so I'm going to post this thing directly:
########################BEGIN######################### #!/usr/bin/perl use strict; use warnings; sub true () {1}; sub false () {undef}; %ENV=(); usage() unless @ARGV == 1; our $config_file = "/etc/sysconfig/iptablesnew"; our %config; for (qw/iptables tcp_public udp_public tcp_dartmouth udp_dartmouth tcp_reject_public tcp_reject_dartmouth udp_reject_public udp_reject_dartmouth dartmouth ntp_conf open_ntp/) { no strict 'refs'; *$_ = \$config{$_}; } our $iptables; our $tcp_public; our $udp_public; our $tcp_dartmouth; our $udp_dartmouth; our $tcp_reject_public; our $tcp_reject_dartmouth; our $udp_reject_public; our $udp_reject_dartmouth; our $dartmouth; our $ntp_conf; our $open_ntp; our %funcs = ( start => \&start, stop => \&stop, restart => \&restart, #save => \&save ); our $command = shift; #($command) = $command =~ /(.*)/; usage() unless exists $funcs{$command}; load(); exit $funcs{$command}->(); no strict 'vars'; sub start { flush(); print "Starting iptables: "; my @lines = ( "$iptables -N ALF", "$iptables -N ALF-TCP", "$iptables -N ALF-UDP", "$iptables -N ALF-ICMP", "$iptables -N ALF-OTHER", "$iptables -A INPUT -j ALF", "$iptables -A ALF -m state --state ESTABLISHED,RELATED -j ACCEPT", "$iptables -A ALF -i lo -j ACCEPT", "$iptables -A ALF -p tcp -j ALF-TCP", "$iptables -A ALF -p udp -j ALF-UDP", "$iptables -A ALF -p icmp -j ALF-ICMP", "$iptables -A ALF -j ALF-OTHER", ); my $alf_tcp = "-A ALF-TCP -p tcp --syn"; push @lines, "$iptables $alf_tcp -m multiport --dports $tcp_public -j ACCEPT" if $tcp_public; push @lines, "$iptables $alf_tcp -s $dartmouth -m multiport --dports $tcp_dartmouth -j ACCEPT" if $tcp_dartmouth; push @lines, "$iptables $alf_tcp -m multiport --dports $tcp_reject_public -j REJECT --reject-with tcp-reset" if $tcp_reject_public; push @lines, "$iptables $alf_tcp -s $dartmouth -m multiport --dports $tcp_reject_dartmouth -j REJECT --reject-with tcp-reset" if $tcp_reject_public; push @lines, "$iptables $alf_tcp -j DROP"; my $alf_udp = "-A ALF-UDP -p udp"; push @lines, "$iptables $alf_udp -m multiport --dports $udp_public -j ACCEPT" if $udp_public; push @lines, "$iptables $alf_udp -s $dartmouth -m multiport --dports $udp_dartmouth -j ACCEPT" if $udp_dartmouth; if ($open_ntp) { for my $server (parse_ntp()) { push @lines, "$iptables $alf_udp -s $server --sport ntp --dport ntp -j ACCEPT"; } } push @lines, "$iptables $alf_udp -m multiport --dports $udp_reject_public -j REJECT" if $udp_reject_public; push @lines, "$iptables $alf_udp -s $dartmouth -m multiport --dports $udp_reject_dartmouth -j REJECT" if $udp_reject_dartmouth; push @lines, "$iptables $alf_udp -j DROP"; push @lines, ( "$iptables -A ALF-ICMP -j DROP", "$iptables -A ALF-OTHER -j DROP", ); lockme(); my $ret = 0; for (@lines) { system $_; $ret += $? >> 8; } if ($ret == 0) { success(); return 0; } else { failure(); return 1; } } sub parse_ntp { open(IN, '<', $ntp_conf) or return; my @ret; while (<IN>) { push @ret, $1 if (/^\s*?server\s+?(\S+)/); } close IN; return @ret; } sub flush { open (IN, '<', "/proc/net/ip_tables_names") or warn "Can't open /proc/net/ip_tables_names: $!\n", return 1; my @tables = <IN>; close IN; print "Flushing rulesets: "; my $ret = 0; for (@tables) { chomp; system $iptables, '-t', $_, '-F'; $ret = $? >> 8; last unless $ret == 0; system $iptables, '-t', $_, '-X'; $ret = $? >> 8; last unless $ret == 0; } $ret == 0 ? success() : failure(); return $ret; } sub stop { unlock(); flush() == 0 ? 0 : 1; } sub restart { if (stop() == 0) { return start(); } else { return 1; } } sub success { system("source /etc/init.d/functions; success"); print "\n"; } sub failure { system("source /etc/init.d/functions; failure"); print "\n"; } sub lockme { open(OUT, '>>', "/var/lock/subsys/iptables"); close OUT; } sub unlock { unlink "/var/lock/subsys/iptables"; } sub usage { warn "Usage: $0 {start|stop|restart}\n"; exit 1; } sub load { print "Reading iptables configuration: "; open(IN, '<', $config_file) or failure(), die "$0: Can't open $config_file for reading: $!\n"; while (<IN>) { chomp; next if /^\s*$/; next if /^\s*#/; my ($k, $v) = split ' ', $_, 2; next unless defined $k && defined $v; $config{$k} = eval $v; failure(), die "$0: Reading $config_file: $@\n" if $@; } close IN; success(); } ############################END######################AlexFerguson - 21 Mar 2003