]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blobdiff - config/forwardfw/rules.pl
Forward Firewall: Bugfix: When creating a rule which results in an error, the counter...
[people/teissler/ipfire-2.x.git] / config / forwardfw / rules.pl
index 529943f8170d4ad3e62950eec6c1f065f6759453..3f491f79465906cf08c30426e43f6f65e7206f86 100755 (executable)
@@ -2,7 +2,7 @@
 ###############################################################################
 #                                                                             #
 # IPFire.org - A linux based firewall                                         #
-# Copyright (C) 2012                                                                                                             #
+# Copyright (C) 2013 Alexander Marx <amarx@ipfire.org>                        #
 #                                                                             #
 # This program is free software: you can redistribute it and/or modify        #
 # it under the terms of the GNU General Public License as published by        #
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
 #                                                                             #
 ###############################################################################
-#                                                                                                                                                        #
-# Hi folks! I hope this code is useful for all. I needed something to handle  #
-# my VPN Connections in a comfortable way.                                                               #
-# This script builds firewallrules from the webinterface                      #
-###############################################################################
 
 use strict;
 use Time::Local;
@@ -44,7 +39,6 @@ our %targethash=();
 my @timeframe=();
 my %configinputfw=();
 my %configoutgoingfw=();
-my %configdmzfw=();
 my %confignatfw=();
 my %aliases=();
 my @DPROT=();
@@ -53,11 +47,9 @@ 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";
@@ -73,11 +65,9 @@ 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);
 
@@ -94,7 +84,7 @@ close(CONN1);
 ################################
 #    DEBUG/TEST                #
 ################################
-my $MODE=1;     # 0 - normal operation
+my $MODE=0;     # 0 - normal operation
                                # 1 - print configline and rules to console     
                                # 
 ################################               
@@ -119,26 +109,10 @@ if($param eq 'flush'){
                        &p2pblock;
                        system ("/usr/sbin/firewall-policy"); 
                }elsif($fwdfwsettings{'POLICY'} eq 'MODE2'){
-                       $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 ("iptables -A $CHAIN -m conntrack --ctstate NEW -j ACCEPT");
                        system ("/usr/sbin/firewall-policy");
+                       system ("/etc/sysconfig/firewall.local reload");
                }
        }
 }
@@ -147,15 +121,11 @@ sub flush
        system ("iptables -F FORWARDFW");
        system ("iptables -F INPUTFW");
        system ("iptables -F OUTGOINGFW");
-       system ("iptables -F PORTFWACCESS");
        system ("iptables -t nat -F NAT_DESTINATION");
        system ("iptables -t nat -F NAT_SOURCE");
 }                      
 sub preparerules
 {
-       if (! -z  "${General::swroot}/forward/dmz"){
-               &buildrules(\%configdmzfw);
-       }
        if (! -z  "${General::swroot}/forward/config"){
                &buildrules(\%configfwdfw);
        }
@@ -165,9 +135,6 @@ sub preparerules
        if (! -z  "${General::swroot}/forward/outgoing"){
                &buildrules(\%configoutgoingfw);
        }
-       if (! -z  "${General::swroot}/forward/nat"){
-               &buildrules(\%confignatfw);
-       }
 }
 sub buildrules
 {
@@ -178,8 +145,11 @@ sub buildrules
        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' && $conexists eq 'off' );
+               next if (($$hash{$key}[6] eq 'RED' || $$hash{$key}[6] eq 'RED1') && $conexists eq 'off' );
+               $command="iptables -A";
                if ($$hash{$key}[28] eq 'ON'){
                        $command='iptables -t nat -A';
                        $natip=&get_nat_ip($$hash{$key}[29],$$hash{$key}[31]);
@@ -214,9 +184,21 @@ sub buildrules
                                                &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.';
+                       }elsif($$hash{$key}[5] eq 'ipfire' ){
+                               if($$hash{$key}[6] eq 'GREEN'){
+                                       $targethash{$key}[0]=$defaultNetworks{'GREEN_ADDRESS'};
+                               }
+                               if($$hash{$key}[6] eq 'BLUE'){
+                                       $targethash{$key}[0]=$defaultNetworks{'BLUE_ADDRESS'};
+                               }
+                               if($$hash{$key}[6] eq 'ORANGE'){
+                                       $targethash{$key}[0]=$defaultNetworks{'ORANGE_ADDRESS'};
+                               }
+                               if($$hash{$key}[6] eq 'ALL'){
+                                       $targethash{$key}[0]='0.0.0.0/0';
+                               }
+                               if($$hash{$key}[6] eq 'RED' || $$hash{$key}[6] eq 'RED1'){
+                                       open(FILE, "/var/ipfire/red/local-ipaddress")or die "Couldn't open local-ipaddress";
                                        $targethash{$key}[0]= <FILE>;
                                        close(FILE);
                                }else{
@@ -280,22 +262,23 @@ sub buildrules
                                                                        if(substr($DPORT, 2, 4) eq 'icmp'){
                                                                                my @icmprule= split(",",substr($DPORT, 12,));
                                                                                foreach (@icmprule){
+                                                                                       $icmptype="--icmp-type ";
+                                                                                       if ($_ eq "BLANK") {
+                                                                                                       $icmptype="";
+                                                                                                       $_="";
+                                                                                       }
                                                                                        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] $icmptype $_ $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";
+                                                                                               print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $icmptype $_ $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}[31] eq 'dnat'){
+                                                                               $natchain='NAT_DESTINATION';
                                                                                if ($$hash{$key}[17] eq 'ON'){
-                                                                                       print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $fireport $TIME -j LOG --log-prefix 'DNAT' \n";
+                                                                                       print "$command $natchain $PROT $STAG $sourcehash{$a}[0] $fireport $TIME -j LOG --log-prefix 'DNAT' \n";
                                                                                }
                                                                                my ($ip,$sub) =split("/",$targethash{$b}[0]);
-                                                                               print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j $nat --to $ip$DPORT\n";
+                                                                               print "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j $nat --to $ip$DPORT\n";
                                                                                $DPORT =~ s/\-/:/g;
                                                                                if ($DPORT){
                                                                                        $fwaccessdport="--dport ".substr($DPORT,1,);
@@ -307,9 +290,17 @@ sub buildrules
                                                                                                $fwaccessdport="--dport $$hash{$key}[30]";
                                                                                        }
                                                                                }
-                                                                               print "iptables -A PORTFWACCESS $PROT -i $con $STAG $sourcehash{$a}[0] -d $ip $fwaccessdport $TIME -j $$hash{$key}[0]\n";
+                                                                               print "iptables -A FORWARDFW $PROT -i $con $STAG $sourcehash{$a}[0] -d $ip $fwaccessdport $TIME -j $$hash{$key}[0]\n";
+                                                                               next;
                                                                        }elsif($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'snat'){
-                                                                               print "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $nat --to $natip\n";
+                                                                               $natchain='NAT_SOURCE';
+                                                                               print "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $nat --to $natip\n";
+                                                                       }
+                                                                       if ($$hash{$key}[17] eq 'ON' ){
+                                                                                       print "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG\n";
+                                                                       }
+                                                                       if ($PROT ne '-p ICMP'){
+                                                                               print "iptables -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]\n";
                                                                        }
                                                                }                               
                                                        }
@@ -327,25 +318,28 @@ sub buildrules
                                                        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(substr($sourcehash{$a}[0], 3, 3) ne 'mac' && $sourcehash{$a}[0] ne ''){ $STAG="-s";}
+                                                                       #Process ICMP RULE
                                                                        if(substr($DPORT, 2, 4) eq 'icmp'){
                                                                                my @icmprule= split(",",substr($DPORT, 12,));
                                                                                foreach (@icmprule){
+                                                                                       $icmptype="--icmp-type ";
+                                                                                       if ($_ eq "BLANK") {
+                                                                                                       $icmptype="";
+                                                                                                       $_="";
+                                                                                       }
                                                                                        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] $icmptype $_ $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] $icmptype $_ $TIME -j $$hash{$key}[0]");
                                                                                }
-                                                                               system "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]\n";
+                                                                       #PROCESS DNAT RULE (Portforward)
                                                                        }elsif($$hash{$key}[28] eq 'ON' && $$hash{$key}[31] eq 'dnat'){
+                                                                               $natchain='NAT_DESTINATION';
                                                                                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";
+                                                                                       system "$command $natchain $PROT $STAG $sourcehash{$a}[0] $fireport $TIME -j LOG --log-prefix 'DNAT' \n";
                                                                                }
                                                                                my ($ip,$sub) =split("/",$targethash{$b}[0]);
-                                                                               system "$command $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j $nat --to $ip$DPORT\n";
+                                                                               system "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT $natip $fireport $TIME -j $nat --to $ip$DPORT\n";
                                                                                $DPORT =~ s/\-/:/g;
                                                                                if ($DPORT){
                                                                                        $fwaccessdport="--dport ".substr($DPORT,1,);
@@ -357,12 +351,19 @@ sub buildrules
                                                                                                $fwaccessdport="--dport $$hash{$key}[30]";
                                                                                        }
                                                                                }
-                                                                               system "iptables -A PORTFWACCESS $PROT -i $con $STAG $sourcehash{$a}[0] -d $ip $fwaccessdport $TIME -j $$hash{$key}[0]\n";
+                                                                               system "iptables -A FORWARDFW $PROT -i $con $STAG $sourcehash{$a}[0] -d $ip $fwaccessdport $TIME -j $$hash{$key}[0]\n";
+                                                                               next;
+                                                                       #PROCESS SNAT RULE
                                                                        }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 $nat  --to $natip$fireport\n";
+                                                                               $natchain='NAT_SOURCE';
+                                                                               system "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $nat --to $natip\n";
+                                                                       }
+                                                                       if ($$hash{$key}[17] eq 'ON' && substr($DPORT, 2, 4) ne 'icmp'){
+                                                                               system "$command $natchain $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j LOG\n";
+                                                                       }
+                                                                       #PROCESS EVERY OTHER RULE (If NOT ICMP, else the rule would be applied double)
+                                                                       if ($PROT ne '-p ICMP'){
+                                                                               system "iptables -A $$hash{$key}[1] $PROT $STAG $sourcehash{$a}[0] $SPORT -d $targethash{$b}[0] $DPORT $TIME -j $$hash{$key}[0]\n";
                                                                        }
                                                                }                               
                                                        }
@@ -497,6 +498,30 @@ sub get_address
                $$hash{$key}[0]=&fwlib::get_ovpn_n2n_ip($base2,11);
        }elsif($base eq 'ipsec_net_src' || $base eq 'ipsec_net_tgt' || $base eq 'IpSec Network'){
                $$hash{$key}[0]=&fwlib::get_ipsec_net_ip($base2,11);
+       }elsif($base eq 'ipfire_src' ){
+               if($base2 eq 'GREEN'){
+                       $$hash{$key}[0]=$defaultNetworks{'GREEN_ADDRESS'};
+               }
+               if($base2 eq 'BLUE'){
+                       $$hash{$key}[0]=$defaultNetworks{'BLUE_ADDRESS'};
+               }
+               if($base2 eq 'ORANGE'){
+                       $$hash{$key}[0]=$defaultNetworks{'ORANGE_ADDRESS'};
+               }
+               if($base2 eq 'ALL'){
+                       $$hash{$key}[0]='0.0.0.0/0';
+               }
+               if($base2 eq 'RED' || $base2 eq 'RED1'){
+                       open(FILE, "/var/ipfire/red/local-ipaddress")or die "Couldn't open local-ipaddress";
+                       $$hash{$key}[0]= <FILE>;
+                       close(FILE);
+               }else{
+                       foreach my $alias (sort keys %aliases){
+                               if ($base2 eq $alias){
+                                       $$hash{$key}[0]=$aliases{$alias}{'IPT'};
+                               }
+                       }
+               }
        }
 }
 sub get_prot
@@ -565,7 +590,7 @@ sub get_port
                                                return "--dport $$hash{$key}[15] ";
                                         }else{
                                                 $$hash{$key}[15] =~ s/\:/-/g;
-                                               return ":$$hash{$key}[15]";
+                                                return ":$$hash{$key}[15]";
                                         }
                                }
                        }elsif($$hash{$key}[13] ne '' && $$hash{$key}[13] ne 'All ICMP-Types'){
@@ -575,7 +600,7 @@ sub get_port
                        }
                }elsif($$hash{$key}[14] eq 'cust_srv'){
                        if ($prot ne 'ICMP'){
-                               if($$hash{$key}[31] eq 'dnat'){
+                               if($$hash{$key}[31] eq 'dnat' && $$hash{$key}[28] eq 'ON'){
                                        return ":".&fwlib::get_srv_port($$hash{$key}[15],1,$prot);
                                }else{
                                        return "--dport ".&fwlib::get_srv_port($$hash{$key}[15],1,$prot);