From 6178953be5c93975c069314cfe3b20cd2d684746 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 1 Mar 2014 19:54:14 +0100 Subject: [PATCH] firewall: rules.pl: Cleanup rule generation. Various perl coding errors that have been suppressed by "no warnings uninitialized" have been fixed and lots of helper variables have been introduced to make it much more clearer what the code is actually doing. --- config/firewall/rules.pl | 112 +++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 41 deletions(-) diff --git a/config/firewall/rules.pl b/config/firewall/rules.pl index 6b22ea378a..523f6e3422 100755 --- a/config/firewall/rules.pl +++ b/config/firewall/rules.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w ############################################################################### # # # IPFire.org - A linux based firewall # @@ -21,7 +21,6 @@ use strict; use Time::Local; -no warnings 'uninitialized'; require '/var/ipfire/general-functions.pl'; require "${General::swroot}/lang.pl"; @@ -32,6 +31,11 @@ my $DEBUG = 0; my $IPTABLES = "iptables --wait"; +# iptables chains +my $CHAIN = "FORWARDFW"; +my $CHAIN_NAT_SOURCE = "NAT_SOURCE"; +my $CHAIN_NAT_DESTINATION = "NAT_DESTINATION"; + my %fwdfwsettings=(); my %defaultNetworks=(); my %configfwdfw=(); @@ -59,8 +63,7 @@ my $errormessage = ''; my $orange = ''; my $green = ''; my $blue = ''; -my ($TYPE,$PROT,$SPROT,$DPROT,$SPORT,$DPORT,$TIME,$TIMEFROM,$TIMETILL,$SRC_TGT); -my $CHAIN = "FORWARDFW"; +my ($TYPE,$PROT,$SPROT,$DPROT,$SPORT,$DPORT,$SRC_TGT); my $conexists = 'off'; my $dnat =''; my $snat =''; @@ -114,6 +117,12 @@ sub run { } } +sub print_error { + my $message = shift; + + print STDERR "$message\n"; +} + sub flush { run("$IPTABLES -F FORWARDFW"); run("$IPTABLES -F INPUTFW"); @@ -137,29 +146,55 @@ sub preparerules { sub buildrules { my $hash=shift; my $STAG; - my $natip; my $snatport; my $fireport; - my $nat; my $fwaccessdport; my $natchain; my $icmptype; foreach my $key (sort {$a <=> $b} keys %$hash){ next if (($$hash{$key}[6] eq 'RED' || $$hash{$key}[6] eq 'RED1') && $conexists eq 'off' ); - if ($$hash{$key}[28] eq 'ON'){ - $natip=&get_nat_ip($$hash{$key}[29],$$hash{$key}[31]); - if($$hash{$key}[31] eq 'dnat'){ - $nat='DNAT'; - if ($$hash{$key}[30] =~ /\|/){ + + my $TIME = ""; + my $TIMEFROM; + my $TIMETILL; + my $natip = ""; + + # Check if logging should be enabled. + my $LOG = 0; + if ($$hash{$key}[17] eq 'ON') { + $LOG = 1; + } + + my $NAT = 0; + my $NAT_MODE; + + # Check if NAT is enabled and initialize variables, that we use for that. + if ($$hash{$key}[28] eq 'ON') { + $NAT = 1; + + # Destination NAT + if ($$hash{$key}[31] eq 'dnat') { + $NAT_MODE = "DNAT"; + + if ($$hash{$key}[30] =~ /\|/) { $$hash{$key}[30]=~ tr/|/,/; $fireport='-m multiport --dport '.$$hash{$key}[30]; - }else{ + } else { $fireport='--dport '.$$hash{$key}[30] if ($$hash{$key}[30]>0); } - }else{ - $nat='SNAT'; + + # Source NAT + } elsif ($$hash{$key}[31] eq 'snat') { + $NAT_MODE = "SNAT"; + + } else { + print_error("Invalid NAT mode: $$hash{$key}[31]"); + next; } + + $natip = &get_nat_ip($$hash{$key}[29], $NAT_MODE); } + $STAG=''; if($$hash{$key}[2] eq 'ON'){ #get source ip's @@ -220,7 +255,7 @@ sub buildrules { #get time if defined if($$hash{$key}[18] eq 'ON'){ my ($time1,$time2,$daylight); - my $daylight=$$hash{$key}[28]; + $daylight=$$hash{$key}[28]; $time1=&get_time($$hash{$key}[26],$daylight); $time2=&get_time($$hash{$key}[27],$daylight); if($$hash{$key}[19] ne ''){push (@timeframe,"Mon");} @@ -245,7 +280,7 @@ sub buildrules { } foreach my $a (sort keys %sourcehash){ foreach my $b (sort keys %targethash){ - if(! $sourcehash{$a}[0] || ! $targethash{$b}[0] || ($natip eq '-d ' && $$hash{$key}[28] eq 'ON') || (!$natip && $$hash{$key}[28] eq 'ON')){ + if(! $sourcehash{$a}[0] || ! $targethash{$b}[0] || ($natip eq '-d ' && $NAT) || (!$natip && $NAT)){ #Skip rules when no RED IP is set (DHCP,DSL) next; } @@ -263,24 +298,23 @@ sub buildrules { $icmptype=""; $_=""; } - if ($$hash{$key}[17] eq 'ON'){ + if ($LOG) { run("$IPTABLES -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $icmptype $_ $TIME -j LOG"); } - run("$IPTABLES -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $icmptype $_ $TIME -j $$hash{$key}[0]"); + run("$IPTABLES -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $icmptype $_ $TIME -j $$hash{$key}[0]"); } #PROCESS DNAT RULE (Portforward) - }elsif($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'dnat'){ - $natchain='NAT_DESTINATION'; - if ($$hash{$key}[17] eq 'ON'){ - run("$IPTABLES -t nat -A $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j LOG --log-prefix 'DNAT'"); + } elsif ($NAT && $NAT_MODE eq "DNAT") { + if ($LOG) { + run("$IPTABLES -t nat -A $CHAIN_NAT_DESTINATION $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j LOG --log-prefix 'DNAT'"); } my ($ip,$sub) =split("/",$targethash{$b}[0]); #Process NAT with servicegroup used - if ($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'dnat' && $$hash{$key}[14] eq 'cust_srvgrp'){ - run("$IPTABLES -t nat -A $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j $nat --to-destination $ip $DPORT"); + if ($$hash{$key}[14] eq 'cust_srvgrp') { + run("$IPTABLES -t nat -A $CHAIN_NAT_DESTINATION $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j DNAT --to-destination $ip $DPORT"); $fwaccessdport=$DPORT; - }else{ - run("$IPTABLES -t nat -A $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j $nat --to-destination $ip$DPORT"); + } else { + run("$IPTABLES -t nat -A $CHAIN_NAT_DESTINATION $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j DNAT --to-destination $ip$DPORT"); $DPORT =~ s/\-/:/g; if ($DPORT){ $fwaccessdport="--dport ".substr($DPORT,1,); @@ -296,23 +330,22 @@ sub buildrules { run("$IPTABLES -A FORWARDFW $PROT $STAG $sourcehash{$a}[0] -d $ip $fwaccessdport $TIME -j $$hash{$key}[0]"); next; #PROCESS SNAT RULE - }elsif($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'snat'){ - $natchain='NAT_SOURCE'; - if ($$hash{$key}[17] eq 'ON' ){ - run("$IPTABLES -t nat -A $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG --log-prefix 'SNAT'"); + } elsif ($NAT && $NAT_MODE eq "SNAT") { + if ($LOG) { + run("$IPTABLES -t nat -A $CHAIN_NAT_SOURCE $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG --log-prefix 'SNAT'"); } - run("$IPTABLES -t nat -A $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $nat --to-source $natip"); + run("$IPTABLES -t nat -A $CHAIN_NAT_SOURCE $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j SNAT --to-source $natip"); } #PROCESS EVERY OTHER RULE (If NOT ICMP, else the rule would be applied double) if ($PROT ne '-p ICMP'){ - if ($$hash{$key}[17] eq 'ON' && $$hash{$key}[28] ne 'ON'){ + if ($LOG && !$NAT) { run("$IPTABLES -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG"); } run("$IPTABLES -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]"); } #PROCESS Prot ICMP and type = All ICMP-Types if ($PROT eq '-p ICMP' && $$hash{$key}[9] eq 'All ICMP-Types'){ - if ($$hash{$key}[17] eq 'ON' && $$hash{$key}[28] ne 'ON'){ + if ($LOG && !$NAT) { run("$IPTABLES -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG"); } run("$IPTABLES -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]"); @@ -325,9 +358,6 @@ sub buildrules { } %sourcehash=(); %targethash=(); - undef $TIME; - undef $TIMEFROM; - undef $TIMETILL; undef $fireport; } } @@ -340,15 +370,15 @@ sub get_nat_ip { $result=$defaultNetworks{$val.'_ADDRESS'}; }elsif($val eq 'ALL'){ $result='-i '.$con; - }elsif($val eq 'Default IP' && $type eq 'dnat'){ + }elsif($val eq 'Default IP' && $type eq "DNAT"){ $result='-d '.$redip; - }elsif($val eq 'Default IP' && $type eq 'snat'){ + }elsif($val eq 'Default IP' && $type eq "SNAT"){ $result=$redip; }else{ foreach my $al (sort keys %aliases){ - if($val eq $al && $type eq 'dnat'){ + if($val eq $al && $type eq "DNAT"){ $result='-d '.$aliases{$al}{'IPT'}; - }elsif($val eq $al && $type eq 'snat'){ + }elsif($val eq $al && $type eq "SNAT"){ $result=$aliases{$al}{'IPT'}; } } @@ -387,7 +417,7 @@ sub utcmin { } sub p2pblock { - my $P2PSTRING; + my $P2PSTRING = ""; my $DO; open( FILE, "< $p2pfile" ) or die "Unable to read $p2pfile"; @p2ps = ; -- 2.39.5