insertRules
changeset 3 5b59ba9c9113
parent 0 26a429d60aae
equal deleted inserted replaced
2:d3b0cd061f26 3:5b59ba9c9113
    17 #use constant FO => { chain => "ipac~fo", parent => "FORWARD", iface =>"--in" };
    17 #use constant FO => { chain => "ipac~fo", parent => "FORWARD", iface =>"--in" };
    18 #use constant I  => { chain => "ipac~i", parent => "OUTPUT", iface => "--in" };
    18 #use constant I  => { chain => "ipac~i", parent => "OUTPUT", iface => "--in" };
    19 #use constant O  => { chain => "ipac~o", parent => "INPUT", iface => "--out" };
    19 #use constant O  => { chain => "ipac~o", parent => "INPUT", iface => "--out" };
    20 
    20 
    21 my %TARGETS = (
    21 my %TARGETS = (
    22     "ipac~fi" => { chain => "ipac~fi", parent => "FORWARD", iface => "--in-interface" },
    22     "ipac~fi" =>
    23     "ipac~fo" => { chain => "ipac~fo", parent => "FORWARD", iface => "--out-interface" },
    23       { chain => "ipac~fi", parent => "FORWARD", iface => "--in-interface" },
    24     "ipac~i" => { chain => "ipac~i", parent => "OUTPUT", iface => "--out-interface" },
    24     "ipac~fo" =>
    25     "ipac~o" => { chain => "ipac~o", parent => "INPUT", iface => "--in-interface" },
    25       { chain => "ipac~fo", parent => "FORWARD", iface => "--out-interface" },
       
    26     "ipac~i" =>
       
    27       { chain => "ipac~i", parent => "OUTPUT", iface => "--out-interface" },
       
    28     "ipac~o" =>
       
    29       { chain => "ipac~o", parent => "INPUT", iface => "--in-interface" },
    26 );
    30 );
    27 
    31 
    28 use constant FILE => $ENV{IPAC_RULES} ? $ENV{IPAC_RULES} : "/etc/ipac-ng/rules.conf";
    32 use constant FILE => $ENV{IPAC_RULES}
       
    33   ? $ENV{IPAC_RULES}
       
    34   : "/etc/ipac-ng/rules.conf";
    29 
    35 
    30 use constant CONFIG => (
    36 use constant CONFIG => (
    31     { CASE => 1 },
    37     { CASE => 1 },
    32     nothing => { ARGS => "!", DEFAULT => 0 },
    38     nothing => { ARGS => "!", DEFAULT => 0 },
    33     verbose => { ARGS => "!", DEFAULT => 0 },
    39     verbose => { ARGS => "!", DEFAULT => 0 },
    34 );
    40 );
    35 
    41 
    36 my $Cf = new AppConfig CONFIG or die;
    42 my $Cf = new AppConfig CONFIG or die;
    37    $Cf->getopt or die;
    43 $Cf->getopt or die;
    38 
    44 
    39 sub checkTarget($);
    45 sub checkTarget($);
    40 sub insertTarget($);
    46 sub insertTarget($);
    41 sub cleanTarget($);
    47 sub cleanTarget($);
    42 sub parseConfig($);
    48 sub parseConfig($);
    43 sub expand($);
    49 sub expand($);
    44 
    50 
    45 MAIN: {
    51 MAIN: {
    46     my @cmds; 
    52     my @cmds;
    47 
    53 
    48     # Check, if our rules exist
    54     # Check, if our rules exist
    49     foreach (keys %TARGETS) {
    55     foreach (keys %TARGETS) {
    50 	checkTarget($TARGETS{$_})
    56         checkTarget($TARGETS{$_})
    51 	    or push @cmds, insertTarget($TARGETS{$_});
    57           or push @cmds, insertTarget($TARGETS{$_});
    52 
    58 
    53 	push @cmds, cleanTarget($TARGETS{$_});
    59         push @cmds, cleanTarget($TARGETS{$_});
    54     }
    60     }
    55     
    61 
    56     
       
    57     my ($iptables, $rules) = parseConfig(FILE);
    62     my ($iptables, $rules) = parseConfig(FILE);
    58     push @cmds, @$iptables;
    63     push @cmds, @$iptables;
    59 
    64 
    60 
       
    61     foreach (@cmds) {
    65     foreach (@cmds) {
    62 	print "@$_\n" if $Cf->verbose or $Cf->nothing;
    66         print "@$_\n" if $Cf->verbose or $Cf->nothing;
    63 	next if $Cf->nothing;
    67         next if $Cf->nothing;
    64 	system @$_ and do {
    68         system @$_ and do {
    65 	    warn "FAILED: @$_\n" if not $Cf->verbose;
    69             warn "FAILED: @$_\n" if not $Cf->verbose;
    66 	};
    70         };
    67     }
    71     }
    68 
    72 
    69     if (!$Cf->nothing) {
    73     if (!$Cf->nothing) {
    70 	open(RUNFILE, $_ = ">/var/run/ipac.rules") or die "Can't open $_: $!\n";
    74         open(RUNFILE, $_ = ">/var/run/ipac.rules") or die "Can't open $_: $!\n";
    71 	print RUNFILE join "\n", @$rules;
    75         print RUNFILE join "\n", @$rules;
    72 	close(RUNFILE);
    76         close(RUNFILE);
    73     }
    77     }
    74 }
    78 }
    75 
    79 
    76 {
    80 {
    77     my $dump;
    81     my $dump;
    78 sub checkTarget($) {
       
    79     my $target = shift;
       
    80 
    82 
    81     if (!$dump) {
    83     sub checkTarget($) {
    82 	open(X, "iptables-save|") or die "Can't open iptables-save: $!\n";
    84         my $target = shift;
    83 	$dump = join "", grep /^:/, <X>;
    85 
    84 	close(X);
    86         if (!$dump) {
       
    87             open(X, "iptables-save|") or die "Can't open iptables-save: $!\n";
       
    88             $dump = join "", grep /^:/, <X>;
       
    89             close(X);
       
    90         }
       
    91 
       
    92         return $dump =~ /^:$target->{chain}/m
       
    93 
    85     }
    94     }
    86 
    95 }
    87     return $dump =~ /^:$target->{chain}/m
       
    88 
       
    89 } }
       
    90 
    96 
    91 sub insertTarget($) {
    97 sub insertTarget($) {
    92     my $target = shift;
    98     my $target = shift;
    93 
    99 
    94     return (
   100     return (
    95 	["iptables", "--new-chain" => $target->{chain}],
   101         ["iptables", "--new-chain" => $target->{chain}],
    96 	["iptables", 
   102         [
    97 	    "--insert" => $target->{parent}, 
   103             "iptables",
    98 	    "--jump" => $target->{chain}]
   104             "--insert" => $target->{parent},
    99 	);
   105             "--jump"   => $target->{chain}
       
   106         ]
       
   107     );
   100 }
   108 }
   101 
   109 
   102 sub cleanTarget($) {
   110 sub cleanTarget($) {
   103     my $target = shift;
   111     my $target = shift;
   104     return ["iptables",
   112     return ["iptables", "--flush" => $target->{chain}];
   105 	"--flush" => $target->{chain}];
       
   106 }
   113 }
   107 
   114 
   108 sub parseConfig($) {
   115 sub parseConfig($) {
   109     my (@iptables, @rules);
   116     my (@iptables, @rules);
   110     my $file = shift;
   117     my $file = shift;
   111     local(@ARGV) = ($file);
   118     local (@ARGV) = ($file);
   112 
   119 
   113     die ME.": Can't open $file: $!\n" if not -r $file;
   120     die ME . ": Can't open $file: $!\n" if not -r $file;
   114 
   121 
   115     @ARGV = ($file);
   122     @ARGV = ($file);
   116 
   123 
   117     # Read the config file and create the iptables statements
   124     # Read the config file and create the iptables statements
   118     while (<>) {
   125     while (<>) {
   119 	s/#.*//;
   126         s/#.*//;
   120 	s/^\s*$//;
   127         s/^\s*$//;
   121 	next unless $_;
   128         next unless $_;
   122 
   129 
   123 	chomp;
   130         chomp;
   124 
   131 
       
   132         my (%src, %dst);
       
   133         (my ($name, $target, $iface, $proto), $src{ip}, $dst{ip}) =
       
   134           split /\s*\|\s*/, $_;
   125 
   135 
   126 	my (%src, %dst);
   136         # $src / $dst
   127 	(my ($name, $target, $iface, $proto), $src{ip}, $dst{ip}) 
   137         foreach (\%src, \%dst) {
   128 		= split /\s*\|\s*/, $_;
   138             @{$_}{qw/ip port/} = split /[:\s]/, $_->{ip};
       
   139         }
   129 
   140 
   130 	# $src / $dst
   141         my @cmd = (
   131 	foreach (\%src, \%dst) {
   142             "iptables",
   132 	    @{$_}{qw/ip port/} = split /[:\s]/, $_->{ip};
   143             "--append"                 => $target,
   133 	}
   144             $TARGETS{$target}->{iface} => $iface,
       
   145             "--src"                    => expand($src{ip}),
       
   146             "--dst"                    => expand($dst{ip}),
       
   147             "--proto"                  => expand($proto),
       
   148             $src{port} ? ("--sport" => $src{port}) : (),
       
   149             $dst{port} ? ("--dport" => $dst{port}) : (),
       
   150         );
   134 
   151 
   135 
   152         push @iptables, \@cmd;
   136 	my @cmd = ("iptables", 
   153         push @rules,    "$target|$name";
   137 	    "--append" => $target, 
       
   138 	    $TARGETS{$target}->{iface} => $iface,
       
   139 	    "--src" => expand($src{ip}),
       
   140 	    "--dst" => expand($dst{ip}),
       
   141 	    "--proto" => expand($proto),
       
   142 	    $src{port} ? ("--sport" => $src{port}) : (),
       
   143 	    $dst{port} ? ("--dport" => $dst{port}) : (),
       
   144 	);
       
   145 
       
   146 	push @iptables, \@cmd;
       
   147 	push @rules, "$target|$name";
       
   148     }
   154     }
   149 
   155 
   150     return \@iptables, \@rules;
   156     return \@iptables, \@rules;
   151 }
   157 }
   152 
   158