DOSC TWiki snapshot as of mid-2005

Top

RedhatIptablesScript


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