X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=config%2Fforwardfw%2Frules.pl;h=4461893ae99911854f273c3a973b5e3fc156f753;hb=82e136591e5dbe3366f2a8d3f9129b98603ad620;hp=953aad0bc0c6587d9aa4ceca5db5a6eb5bd17390;hpb=62fc8511664c6646d706aa42927bac53ac6a5b5f;p=people%2Fteissler%2Fipfire-2.x.git diff --git a/config/forwardfw/rules.pl b/config/forwardfw/rules.pl index 953aad0bc..4461893ae 100755 --- a/config/forwardfw/rules.pl +++ b/config/forwardfw/rules.pl @@ -24,8 +24,8 @@ # This script builds firewallrules from the webinterface # ############################################################################### - use strict; +use Time::Local; no warnings 'uninitialized'; # enable only the following on debugging purpose @@ -43,30 +43,58 @@ our %sourcehash=(); our %targethash=(); my @timeframe=(); my %configinputfw=(); +my %configoutgoingfw=(); +my %configdmzfw=(); +my %confignatfw=(); my %aliases=(); my @DPROT=(); +my @p2ps=(); require '/var/ipfire/general-functions.pl'; require "${General::swroot}/lang.pl"; require "${General::swroot}/forward/bin/firewall-lib.pl"; +my $configdmz = "${General::swroot}/forward/dmz"; my $configfwdfw = "${General::swroot}/forward/config"; my $configinput = "${General::swroot}/forward/input"; +my $configoutgoing = "${General::swroot}/forward/outgoing"; +my $confignat = "${General::swroot}/forward/nat"; +my $p2pfile = "${General::swroot}/forward/p2protocols"; my $configgrp = "${General::swroot}/fwhosts/customgroups"; +my $netsettings = "${General::swroot}/ethernet/settings"; my $errormessage=''; +my $orange; +my $green; +my $blue; my ($TYPE,$PROT,$SPROT,$DPROT,$SPORT,$DPORT,$TIME,$TIMEFROM,$TIMETILL,$SRC_TGT); my $CHAIN="FORWARDFW"; - - +my $conexists='off'; +my $command = 'iptables -A'; +my $dnat=''; +my $snat=''; &General::readhash("${General::swroot}/forward/settings", \%fwdfwsettings); +&General::readhash("$netsettings", \%defaultNetworks); +&General::readhasharray($configdmz, \%configdmzfw); &General::readhasharray($configfwdfw, \%configfwdfw); &General::readhasharray($configinput, \%configinputfw); +&General::readhasharray($configoutgoing, \%configoutgoingfw); +&General::readhasharray($confignat, \%confignatfw); &General::readhasharray($configgrp, \%customgrp); &General::get_aliases(\%aliases); +#check if we have an internetconnection +open (CONN,"/var/ipfire/red/iface"); +my $con = ; +close(CONN); +if (-f "/var/ipfire/red/active"){ + $conexists='on'; +} +open (CONN1,"/var/ipfire/red/local-ipaddress"); +my $redip = ; +close(CONN1); ################################ # DEBUG/TEST # ################################ -my $MODE=0; # 0 - normal operation +my $MODE=1; # 0 - normal operation # 1 - print configline and rules to console # ################################ @@ -88,38 +116,80 @@ if($param eq 'flush'){ &preparerules; if($MODE eq '0'){ if ($fwdfwsettings{'POLICY'} eq 'MODE1'){ - system ("/usr/sbin/firewall-forward-policy"); + &p2pblock; + system ("/usr/sbin/firewall-policy"); }elsif($fwdfwsettings{'POLICY'} eq 'MODE2'){ - system ("/usr/sbin/firewall-forward-policy"); - }elsif($fwdfwsettings{'POLICY'} eq 'MODE0' || $fwdfwsettings{'POLICY'} eq 'MODE2'){ - system ("/usr/sbin/firewall-forward-policy"); + $defaultNetworks{'GREEN_NETMASK'}=&General::iporsubtocidr($defaultNetworks{'GREEN_NETMASK'}); + $green="$defaultNetworks{'GREEN_ADDRESS'}/$defaultNetworks{'GREEN_NETMASK'}"; + if ($defaultNetworks{'BLUE_DEV'}){ + $defaultNetworks{'BLUE_NETMASK'}=&General::iporsubtocidr($defaultNetworks{'BLUE_NETMASK'}); + $blue="$defaultNetworks{'BLUE_ADDRESS'}/$defaultNetworks{'BLUE_NETMASK'}"; + #set default rules for BLUE + system ("iptables -A $CHAIN -s $blue -d $green -j RETURN"); + } + if ($defaultNetworks{'ORANGE_DEV'}){ + $defaultNetworks{'ORANGE_NETMASK'}=&General::iporsubtocidr($defaultNetworks{'ORANGE_NETMASK'}); + $orange="$defaultNetworks{'ORANGE_ADDRESS'}/$defaultNetworks{'ORANGE_NETMASK'}"; + #set default rules for DMZ + system ("iptables -A $CHAIN -s $orange -d $green -j RETURN"); + if ($defaultNetworks{'BLUE_DEV'}){ + system ("iptables -A $CHAIN -s $orange -d $blue -j RETURN"); + } + } + &p2pblock; system ("iptables -A $CHAIN -m state --state NEW -j ACCEPT"); + system ("/usr/sbin/firewall-policy"); } } } - sub flush { system ("iptables -F FORWARDFW"); system ("iptables -F INPUTFW"); + system ("iptables -F OUTGOINGFW"); } sub preparerules { + if (! -z "${General::swroot}/forward/dmz"){ + &buildrules(\%configdmzfw); + } if (! -z "${General::swroot}/forward/config"){ &buildrules(\%configfwdfw); } if (! -z "${General::swroot}/forward/input"){ &buildrules(\%configinputfw); } + if (! -z "${General::swroot}/forward/outgoing"){ + &buildrules(\%configoutgoingfw); + } + if (! -z "${General::swroot}/forward/nat"){ + &buildrules(\%confignatfw); + } } sub buildrules { my $hash=shift; - foreach my $key (sort keys %$hash){ + my $STAG; + my $natip; + my $snatport; + my $fireport; + foreach my $key (sort {$a <=> $b} keys %$hash){ + next if ($$hash{$key}[6] eq 'RED' && $conexists eq 'off' ); + if ($$hash{$key}[28] eq 'ON'){ + $command='iptables -t nat -A'; + $natip=&get_nat_ip($$hash{$key}[29]); + if($$hash{$key}[31] eq 'dnat'){ + $$hash{$key}[0]='DNAT'; + $fireport='--dport '.$$hash{$key}[30] if ($$hash{$key}[30]>0); + }else{ + $$hash{$key}[0]='SNAT'; + } + } + $STAG=''; if($$hash{$key}[2] eq 'ON'){ #get source ip's if ($$hash{$key}[3] eq 'cust_grp_src'){ - foreach my $grp (sort keys %customgrp){ + foreach my $grp (sort {$a <=> $b} keys %customgrp){ if($customgrp{$grp}[0] eq $$hash{$key}[4]){ &get_address($customgrp{$grp}[3],$customgrp{$grp}[2],"src"); } @@ -129,13 +199,12 @@ sub buildrules } #get target ip's if ($$hash{$key}[5] eq 'cust_grp_tgt'){ - foreach my $grp (sort keys %customgrp){ + foreach my $grp (sort {$a <=> $b} keys %customgrp){ if($customgrp{$grp}[0] eq $$hash{$key}[6]){ &get_address($customgrp{$grp}[3],$customgrp{$grp}[2],"tgt"); } } }elsif($$hash{$key}[5] eq 'ipfire'){ - if($$hash{$key}[6] eq 'Default IP'){ open(FILE, "/var/ipfire/red/local-ipaddress") or die 'Unable to open config file.'; $targethash{$key}[0]= ; @@ -162,9 +231,12 @@ sub buildrules if ($DPROT eq ''){$DPROT=' ';} @DPROT=split(",",$DPROT); - #get time if defined if($$hash{$key}[18] eq 'ON'){ + my ($time1,$time2,$daylight); + my $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");} if($$hash{$key}[20] ne ''){push (@timeframe,"Tue");} if($$hash{$key}[21] ne ''){push (@timeframe,"Wed");} @@ -173,11 +245,11 @@ sub buildrules if($$hash{$key}[24] ne ''){push (@timeframe,"Sat");} if($$hash{$key}[25] ne ''){push (@timeframe,"Sun");} $TIME=join(",",@timeframe); - $TIMEFROM="--timestart $$hash{$key}[26] "; - $TIMETILL="--timestop $$hash{$key}[27] "; + + $TIMEFROM="--timestart $time1 "; + $TIMETILL="--timestop $time2 "; $TIME="-m time --weekdays $TIME $TIMEFROM $TIMETILL"; } - if ($MODE eq '1'){ print "NR:$key "; foreach my $i (0 .. $#{$$hash{$key}}){ @@ -186,26 +258,42 @@ sub buildrules print "\n"; print"##################################\n"; #print rules to console - foreach my $DPROT (@DPROT){ $DPORT = &get_port($hash,$key,$DPROT); if ($SPROT ne ''){$PROT=$SPROT;}else{$PROT=$DPROT;} $PROT="-p $PROT" if ($PROT ne '' && $PROT ne ' '); foreach my $a (sort keys %sourcehash){ foreach my $b (sort keys %targethash){ - if ($sourcehash{$a}[0] ne $targethash{$b}[0] && $targethash{$b}[0] ne 'none'){ + if ($sourcehash{$a}[0] ne $targethash{$b}[0] && $targethash{$b}[0] ne 'none' || $sourcehash{$a}[0] eq '0.0.0.0/0.0.0.0'){ if($SPROT eq '' || $SPROT eq $DPROT || $DPROT eq ' '){ - if ($$hash{$key}[17] eq 'ON'){ - print "iptables -A $$hash{$key}[1] $PROT -s $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG\n"; + if(substr($sourcehash{$a}[0], 3, 3) ne 'mac' && $sourcehash{$a}[0] ne ''){ $STAG="-s";} + if(substr($DPORT, 2, 4) eq 'icmp'){ + my @icmprule= split(",",substr($DPORT, 12,)); + foreach (@icmprule){ + if ($$hash{$key}[17] eq 'ON'){ + print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] --icmp-type $_ $TIME -j LOG\n"; + } + print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] --icmp-type $_ $TIME -j $$hash{$key}[0]\n"; + } + }elsif($$hash{$key}[28] ne 'ON'){ + if ($$hash{$key}[17] eq 'ON'){ + print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG\n"; + } + print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]\n"; + }elsif($$hash{$key}[28] eq 'ON' && $$hash{$key}[32] eq 'dnat'){ + #if ($$hash{$key}[17] eq 'ON'){ + #print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $targethash{$b}[0] $DPORT $TIME -j LOG\n"; + #} + print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j $$hash{$key}[0] --to $targethash{$b}[0]$DPORT\n"; + }elsif($$hash{$key}[28] eq 'ON' && $$hash{$key}[32] eq 'snat'){ + print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0] --to $natip$fireport\n"; } - print "iptables -A $$hash{$key}[1] $PROT -s $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]\n"; } } } } print"\n"; } - }elsif($MODE eq '0'){ foreach my $DPROT (@DPROT){ $DPORT = &get_port($hash,$key,$DPROT); @@ -213,17 +301,40 @@ sub buildrules $PROT="-p $PROT" if ($PROT ne '' && $PROT ne ' '); foreach my $a (sort keys %sourcehash){ foreach my $b (sort keys %targethash){ - if ($sourcehash{$a}[0] ne $targethash{$b}[0] && $targethash{$b}[0] ne 'none'){ + if ($sourcehash{$a}[0] ne $targethash{$b}[0] && $targethash{$b}[0] ne 'none' || $sourcehash{$a}[0] eq '0.0.0.0/0.0.0.0'){ if($SPROT eq '' || $SPROT eq $DPROT || $DPROT eq ' '){ - if ($$hash{$key}[17] eq 'ON'){ - system ("iptables -A $$hash{$key}[1] $PROT -s $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG"); + if(substr($sourcehash{$a}[0], 3, 3) ne 'mac' && $sourcehash{$a}[0] ne ''){ $STAG="-s";} + if(substr($DPORT, 2, 4) eq 'icmp'){ + my @icmprule= split(",",substr($DPORT, 12,)); + foreach (@icmprule){ + if ($$hash{$key}[17] eq 'ON'){ + system ("$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] -- icmp-type $_ $TIME -j LOG"); + } + system ("$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] --icmp-type $_ $TIME -j $$hash{$key}[0]"); + } + }elsif($$hash{$key}[28] ne 'ON'){ + if ($$hash{$key}[17] eq 'ON'){ + system "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG\n"; + } + system "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]\n"; + }elsif($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'dnat'){ + if ($$hash{$key}[17] eq 'ON'){ + system "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j LOG --log-prefix 'DNAT' \n"; + } + my $fwaccessdport="--dport ".substr($DPORT,1,) if ($DPORT); + my ($ip,$sub) =split("/",$targethash{$b}[0]); + system "iptables -A PORTFWACCESS $PROT $STAG $sourcehash{$a}[0] -d $targethash{$b}[0] $fwaccessdport $TIME \n"; + system "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j $$hash{$key}[0] --to $ip$DPORT\n"; + }elsif($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'snat'){ + if ($$hash{$key}[17] eq 'ON'){ + system "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG --log-prefix 'SNAT '\n"; + } + system "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0] --to $natip$fireport\n"; } - system ("iptables -A $$hash{$key}[1] $PROT -s $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]"); } } } } - print"\n"; } } } @@ -232,6 +343,88 @@ sub buildrules undef $TIME; undef $TIMEFROM; undef $TIMETILL; + undef $fireport; + } +} +sub get_nat_ip +{ + my $val=shift; + my $result; + if($val eq 'RED' || $val eq 'GREEN' || $val eq 'ORANGE' || $val eq 'BLUE'){ + $result=$defaultNetworks{$val.'_ADDRESS'}; + }elsif($val eq 'ALL'){ + $result='-i '.$con; + }elsif($val eq 'Default IP'){ + $result='-d '.$redip; + }else{ + foreach my $al (sort keys %aliases){ + if($val eq $al){ + $result='-d '.$aliases{$al}{'IPT'}; + } + } + } + return $result; +} +sub get_time +{ + my $val=shift; + my $val1=shift; + my $time; + my $minutes; + my $ruletime; + $minutes = &utcmin($val); + $ruletime = $minutes + &time_get_utc($val); + if ($ruletime < 0){$ruletime +=1440;} + if ($ruletime > 1440){$ruletime -=1440;} + $time=sprintf "%02d:%02d", $ruletime / 60, $ruletime % 60; + return $time; +} +sub time_get_utc +{ + # Calculates the UTCtime from a given time + my $val=shift; + my @localtime=localtime(time); + my @gmtime=gmtime(time); + my $diff = ($gmtime[2]*60+$gmtime[1]%60)-($localtime[2]*60+$localtime[1]%60); + return $diff; +} +sub utcmin +{ + my $ruletime=shift; + my ($hrs,$min) = split(":",$ruletime); + my $newtime = $hrs*60+$min; + return $newtime; +} +sub p2pblock +{ + my $P2PSTRING; + my $DO; + open( FILE, "< $p2pfile" ) or die "Unable to read $p2pfile"; + @p2ps = ; + close FILE; + my $CMD = "-m ipp2p"; + foreach my $p2pentry (sort @p2ps) { + my @p2pline = split( /\;/, $p2pentry ); + if ( $fwdfwsettings{'POLICY'} eq 'MODE1' ) { + $DO = "ACCEPT"; + if ("$p2pline[2]" eq "on") { + $P2PSTRING = "$P2PSTRING --$p2pline[1]"; + } + }else { + $DO = "RETURN"; + if ("$p2pline[2]" eq "off") { + $P2PSTRING = "$P2PSTRING --$p2pline[1]"; + } + } + } + if ($MODE eq 1){ + if($P2PSTRING){ + print"/sbin/iptables -A FORWARDFW $CMD $P2PSTRING -j $DO\n"; + } + }else{ + if($P2PSTRING){ + system("/sbin/iptables -A FORWARDFW $CMD $P2PSTRING -j $DO"); + } } } sub get_address @@ -247,9 +440,13 @@ sub get_address } my $key = &General::findhasharraykey($hash); if($base eq 'src_addr' || $base eq 'tgt_addr' ){ - $$hash{$key}[0] = $base2; + if (&General::validmac($base2)){ + $$hash{$key}[0] = "-m mac --mac-source $base2"; + }else{ + $$hash{$key}[0] = $base2; + } }elsif($base eq 'std_net_src' || $base eq 'std_net_tgt' || $base eq 'Standard Network'){ - $$hash{$key}[0]=&fwlib::get_std_net_ip($base2); + $$hash{$key}[0]=&fwlib::get_std_net_ip($base2,$con); }elsif($base eq 'cust_net_src' || $base eq 'cust_net_tgt' || $base eq 'Custom Network'){ $$hash{$key}[0]=&fwlib::get_net_ip($base2); }elsif($base eq 'cust_host_src' || $base eq 'cust_host_tgt' || $base eq 'Custom Host'){ @@ -300,16 +497,35 @@ sub get_port my $prot=shift; if ($$hash{$key}[7] eq 'ON' && $SRC_TGT eq 'SRC'){ if ($$hash{$key}[10] ne ''){ - return "--sport $$hash{$key}[10] "; + $$hash{$key}[10] =~ s/\|/,/g; + if(index($$hash{$key}[10],",") > 0){ + return "-m multiport --sport $$hash{$key}[10] "; + }else{ + if($$hash{$key}[28] ne 'ON' || ($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'snat') ||($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'dnat') ){ + return "--sport $$hash{$key}[10] "; + }else{ + return ":$$hash{$key}[10]"; + } + } }elsif($$hash{$key}[9] ne '' && $$hash{$key}[9] ne 'All ICMP-Types'){ return "--icmp-type $$hash{$key}[9] "; }elsif($$hash{$key}[9] eq 'All ICMP-Types'){ return; } }elsif($$hash{$key}[11] eq 'ON' && $SRC_TGT eq ''){ + if($$hash{$key}[14] eq 'TGT_PORT'){ if ($$hash{$key}[15] ne ''){ - return "--dport $$hash{$key}[15] "; + $$hash{$key}[15] =~ s/\|/,/g; + if(index($$hash{$key}[15],",") > 0){ + return "-m multiport --dport $$hash{$key}[15] "; + }else{ + if($$hash{$key}[28] ne 'ON' || ($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'snat') ){ + return "--dport $$hash{$key}[15] "; + }else{ + return ":$$hash{$key}[15]"; + } + } }elsif($$hash{$key}[13] ne '' && $$hash{$key}[13] ne 'All ICMP-Types'){ return "--icmp-type $$hash{$key}[13] "; }elsif($$hash{$key}[13] ne '' && $$hash{$key}[13] eq 'All ICMP-Types'){