Revision: 2782
          http://ipcop.svn.sourceforge.net/ipcop/?rev=2782&view=rev
Author:   dotzball
Date:     2009-05-04 20:11:02 +0000 (Mon, 04 May 2009)

Log Message:
-----------
New code for Portforwarding rules (webgui+puzzleFwRules.pl). 

Part 2 (I split this in multiple commits)
 -> iptables rule creation

As I don't have enough spare hardware to test, I can't 100% say 
if portforwarding is working (correctly), from my tests it should do
it... So please test this new feature!

In old portforwarding there where created some MANGLE/MARK 
iptables rules. In setportfw.c there was this comment:
    "Note: if some one remember why the MARK rule ...."
As (in my tests which are not 100% valid!) those rules where not 
needed, but please test this in your environment...

There are some TODOs left:
-> More validation checks when creating rules, change custom 
   addresses, use custom addresses, change custom services,
   change custom services...


Those things I will do later/now but wanted to have the portforwarding 
in SVN so others can test/use it.

Modified Paths:
--------------
    ipcop/trunk/src/scripts/puzzleFwRules.pl

Modified: ipcop/trunk/src/scripts/puzzleFwRules.pl
===================================================================
--- ipcop/trunk/src/scripts/puzzleFwRules.pl    2009-05-04 20:09:16 UTC (rev 
2781)
+++ ipcop/trunk/src/scripts/puzzleFwRules.pl    2009-05-04 20:11:02 UTC (rev 
2782)
@@ -45,7 +45,7 @@
 #      0 - create rules, no print
 #      1 - create rules, print
 #      2 - only print rules
-my $debugLevel = 0;
+my $debugLevel = 1;
 
 #&General::log("BlockOutTraffic: Renew rules");
 # Debug
@@ -64,7 +64,7 @@
 
 # weekday starts on sunday with 0
 
-my @allRuleTypes = ("INPUT", "FORWARD", "EXTERNAL", "DMZHOLES");
+my @allRuleTypes = ("INPUT", "FORWARD", "EXTERNAL", "DMZHOLES", "PORTFW");
 
 my @runRuleTypes          = ();
 my $doUpdateIpcopRules    = 0;
@@ -210,6 +210,12 @@
     # flush External Access rules
     &prepareRule("-F FW_XTACCESS") if ($type eq "EXTERNAL");
     &prepareRule("-F FW_DMZHOLES") if ($type eq "DMZHOLES");
+    if($type eq "PORTFW") {
+         &prepareRule("-t nat -F PORTFW");
+         # TODO: do we need those MANGLE rules?
+         #&prepareRule("-t mangle -F PORTFWMANGLE");
+         &prepareRule("-F PORTFWACCESS");
+    }
 }
 
 my %ruleConfig = ();
@@ -388,6 +394,10 @@
         my @destAdres    = ();
         my $srcPort      = '';
         my @services     = ();
+
+        my $extPfwAdr = '';
+        my @extPfwServices     = ();
+
         my $logPrefix    = '';
         my $ruleAction   = '';
         my $limit        = '';
@@ -537,15 +547,44 @@
             $invDestAdr = "!";
         }
 
+        my $destAdrType = "destination";
+        if($type eq 'PORTFW') {
+
+            # TODO: May check if red interface is active/up
+
+            $destAdrType = "extPfw";
+
+            my @extAdr = (&buildAddressParams($rule->{'PORTFW_EXT_ADR'}, 
"default", "", "extPfw"));
+
+            #  my $extPfwAdr = '';
+            $extPfwAdr = 'N/A';
+            if(defined($extAdr[0])) {
+                # should always be available if we are here, but better check
+                $extPfwAdr = $extAdr[0];
+            }
+            # when red is down we get 'N/A'
+            next if($extPfwAdr =~ /N\/A/);
+
+            # my @extPfwServices = ();
+            if ($rule->{'PORTFW_SERVICE_TYPE'} eq 'custom') {
+                @extPfwServices = 
&buildServiceParamsCustom($rule->{'PORTFW_SERVICE'}, $srcPort);
+            }
+            elsif ($rule->{'PORTFW_SERVICE_TYPE'} eq 'default') {
+                @extPfwServices = 
&buildServiceParamsDefault($rule->{'PORTFW_SERVICE'}, $srcPort);
+            }
+        }
+
         # we only need destination addresses in a FORWARD rule
-        if ($type eq 'FORWARD' || $type eq 'DMZHOLES') {
+        if ($type eq 'FORWARD' || $type eq 'DMZHOLES' || $type eq 'PORTFW') {
 
             # destination address
             if ($rule->{'DST_IP_TYPE'} eq 'defaultDstIP') {
-                @destAdres = (&buildAddressParams($rule->{'DST_IP'}, 
"default", $invDestAdr, "destination"));
+                @destAdres = (&buildAddressParams($rule->{'DST_IP'}, 
"default", $invDestAdr, $destAdrType));
             }
             elsif ($rule->{'DST_IP_TYPE'} eq 'ipDestTxt') {
-                @destAdres = ("-d $invDestAdr $rule->{'DST_IP'}");
+                my $prefix = '';
+                $prefix = '-d' if($destAdrType ne "extPfw");
+                @destAdres = ("$prefix $invDestAdr $rule->{'DST_IP'}");
             }
             elsif ($rule->{'DST_IP_TYPE'} eq 'custDestIP') {
                 unless (defined $custAddresses{$rule->{'DST_IP'}}{'ADDRESS'}) {
@@ -558,7 +597,7 @@
                     &General::log("Error: Custom Address $rule->{'DST_IP'} - 
$Lang::tr{'mac adr not as dest'}");
                     next;
                 }
-                @destAdres = (&buildAddressParams($rule->{'DST_IP'}, "custom", 
$invDestAdr, "destination"));
+                @destAdres = (&buildAddressParams($rule->{'DST_IP'}, "custom", 
$invDestAdr, $destAdrType));
 
             }
             elsif ($rule->{'DST_IP_TYPE'} eq 'groupDestIP') {
@@ -578,7 +617,7 @@
 
                     @destAdres = (
                         @destAdres,
-                        &buildAddressParams($adr->{'ADDRESS_NAME'}, 
$adr->{'ADDRESS_TYP'}, $invDestAdr, "destination")
+                        &buildAddressParams($adr->{'ADDRESS_NAME'}, 
$adr->{'ADDRESS_TYP'}, $invDestAdr, $destAdrType)
                     );
 
                 }
@@ -690,6 +729,9 @@
         elsif ($type eq 'DMZHOLES') {
             $chain = "-A FW_DMZHOLES";
         }
+        elsif ($type eq 'PORTFW') {
+            $chain = "-A PORTFWACCESS";
+        }
         else {    # 'FORWARD'
             $chain = "-A FW_FORWARD";
         }
@@ -707,29 +749,138 @@
             $limit_action = $limit;
         }
 
-        foreach my $tmpOutDev (@outDev) {
-            if ($tmpOutDev ne '') {
-                $tmpOutDev = "-o $invertOutDev $tmpOutDev";
-            }
+        if($type eq 'PORTFW') {
 
-            foreach my $tmpSrcAdr (@srcAdres) {
+#######################################################
+#~  Some rules created from "old" portforwarding /setportfw
+#~      Config:
+#~         Green:                192.168.2.190
+#~         Blue:                   192.168.3.190
+#~         Orange:             192.168.4.190
+
+#~
+#~         src IP:                 2.2.2.2
+#~         IPCop ext IP:     192.168.11.190 (DEFAULT/Red Address)
+#~         ext Port:             123 (tcp)
+#~         internal IP:        1.1.1.1
+#~         internal port:     456 (tcp)
+#~
+#~ /sbin/iptables -t nat -A PORTFW -p tcp -d 192.168.11.190 --dport 123 -j 
DNAT --to 1.1.1.1:456
+#~ /sbin/iptables -t mangle -A PORTFWMANGLE -p tcp -s 
192.168.2.190/255.255.255.0 -d 192.168.11.190 --dport 123 -j MARK --set-mark 1
+#~ /sbin/iptables -t mangle -A PORTFWMANGLE -p tcp -s 
192.168.3.190/255.255.255.0 -d 192.168.11.190 --dport 123 -j MARK --set-mark 21
+#~ /sbin/iptables -t mangle -A PORTFWMANGLE -p tcp -s 
192.168.4.190/255.255.255.0 -d 192.168.11.190 --dport 123 -j MARK --set-mark 31
+#~ /sbin/iptables -A PORTFWACCESS -i eth1 -p tcp -s 2.2.2.2 -d 1.1.1.1 --dport 
456 -j ACCEPT
+
+#~         IPCop ext IP:     192.168.11.190 (DEFAULT/Red Address)
+#~         ext Port:             123 (tcp)
+#~         internal IP:        1.1.1.1
+#~         internal port:     456 (tcp)
+#~
+#~ /sbin/iptables -t nat -A PORTFW -p tcp -d 192.168.11.190 --dport 123 -j 
DNAT --to 1.1.1.1:456
+#~ /sbin/iptables -t mangle -A PORTFWMANGLE -p tcp -s 
192.168.2.190/255.255.255.0 -d 192.168.11.190 --dport 123 -j MARK --set-mark 1
+#~ /sbin/iptables -t mangle -A PORTFWMANGLE -p tcp -s 
192.168.3.190/255.255.255.0 -d 192.168.11.190 --dport 123 -j MARK --set-mark 21
+#~ /sbin/iptables -t mangle -A PORTFWMANGLE -p tcp -s 
192.168.4.190/255.255.255.0 -d 192.168.11.190 --dport 123 -j MARK --set-mark 31
+#~ /sbin/iptables -A PORTFWACCESS -i eth1 -p tcp -s 0.0.0.0/0 -d 1.1.1.1 
--dport 456 -j ACCEPT
+
+
+#~         src IP:                 2.2.2.2 + 3.3.3.3
+#~         IPCop ext IP:     192.168.11.190 (DEFAULT/Red Address)
+#~         ext Port:             123 (tcp)
+#~         internal IP:        1.1.1.1
+#~         internal port:     456 (tcp)
+#~
+#~ /sbin/iptables -t nat -A PORTFW -p tcp -d 192.168.11.190 --dport 123 -j 
DNAT --to 1.1.1.1:456
+#~ /sbin/iptables -t mangle -A PORTFWMANGLE -p tcp -s 
192.168.2.190/255.255.255.0 -d 192.168.11.190 --dport 123 -j MARK --set-mark 1
+#~ /sbin/iptables -t mangle -A PORTFWMANGLE -p tcp -s 
192.168.3.190/255.255.255.0 -d 192.168.11.190 --dport 123 -j MARK --set-mark 21
+#~ /sbin/iptables -t mangle -A PORTFWMANGLE -p tcp -s 
192.168.4.190/255.255.255.0 -d 192.168.11.190 --dport 123 -j MARK --set-mark 31
+#~ /sbin/iptables -A PORTFWACCESS -i eth1 -p tcp -s 2.2.2.2 -d 1.1.1.1 --dport 
456 -j ACCEPT
+#~ /sbin/iptables -A PORTFWACCESS -i eth1 -p tcp -s 3.3.3.3 -d 1.1.1.1 --dport 
456 -j ACCEPT
+
+
+#~         IPCop ext IP:     192.168.11.190 (DEFAULT/Red Address)
+#~         proto:                   GRE
+#~         internal IP:        1.1.1.1
+#~
+#~ /sbin/iptables -t nat -A PORTFW -p gre -d 192.168.11.190 -j DNAT --to 
1.1.1.1
+#~ /sbin/iptables -A PORTFWACCESS -i eth1 -p gre -s 0.0.0.0/0 -d 1.1.1.1 -j 
ACCEPT
+
+            foreach my $tmpOutDev (@outDev) {
                 foreach my $tmpDestAdr (@destAdres) {
+
+                    # remove netmask, iptables don't like the netmask in --to 
<IP>
+                    # as the mask ist /32 there is no problem doing this
+                    $tmpDestAdr =~ s/\/32//;
+                    $tmpDestAdr =~ s/\/255.255.255.255//;
+
+                    foreach my $service (@extPfwServices) {
+
+
+                        # create DNAT rule string
+                        $rulebody = " -t nat -A PORTFW -d $extPfwAdr $service 
-j DNAT --to $tmpDestAdr";
+                        my $destService =  $services[0];
+                        my $destPort = '';
+                        if($service =~ /-p (tcp|udp)/ && $destService =~ 
/--dport\s+(\d+:\d+|\d+)/) {
+                            $destPort = $1;
+                            $destPort =~ s/:/-/;
+                            $rulebody .= ":$destPort ";
+                        }
+                        &prepareRule("$rulebody");
+
+                    }    # foreach $service (@extPfwServices)
+
+                    #######
+                    # TODO: May add some MANGLE rules (like in 1.4) but I 
don't know if this is neccessary
+                    #######
+
                     foreach my $service (@services) {
+                        foreach my $tmpSrcAdr (@srcAdres) {
 
-                        # create rule string
-                        $rulebody = "$chain $inDev $tmpOutDev $tmpSrcAdr 
$tmpDestAdr $service ";
+                            # create rule string
+                            $rulebody = "$chain $inDev $tmpOutDev $tmpSrcAdr 
-d $tmpDestAdr $service ";
 
-                        #print "submit rule\n";
-                        if ($rule->{'LOG_ENABLED'} eq 'on') {
-                            &prepareRule("$rulebody $logPrefix $limit_log");
-                        }
-                        if ($rule->{'RULEACTION'} ne 'logOnly') {
-                            &prepareRule("$rulebody $ruleAction 
$limit_action");
-                        }
+                            #print "submit rule\n";
+                            if ($rule->{'LOG_ENABLED'} eq 'on') {
+                                &prepareRule("$rulebody $logPrefix 
$limit_log");
+                            }
+                            if ($rule->{'RULEACTION'} ne 'logOnly') {
+                                &prepareRule("$rulebody $ruleAction 
$limit_action");
+                            }
+                        }    # foreach $tmpSrcAdr (@srcAdres)
                     }    # foreach $service (@services)
+
                 }    # foreach $tmpDestAdr (@destAdres)
-            }    # foreach $tmpSrcAdr (@srcAdres)
-        }    # foreach my $tmpOutDev (@outDev)
+            }    # foreach my $tmpOutDev (@outDev)
+
+        }
+        else {
+            # no special (== no portfw)
+
+            foreach my $tmpOutDev (@outDev) {
+                if ($tmpOutDev ne '') {
+                    $tmpOutDev = "-o $invertOutDev $tmpOutDev";
+                }
+
+                foreach my $tmpSrcAdr (@srcAdres) {
+                    foreach my $tmpDestAdr (@destAdres) {
+                        foreach my $service (@services) {
+
+
+                            # create rule string
+                            $rulebody = "$chain $inDev $tmpOutDev $tmpSrcAdr 
$tmpDestAdr $service ";
+
+                            #print "submit rule\n";
+                            if ($rule->{'LOG_ENABLED'} eq 'on') {
+                                &prepareRule("$rulebody $logPrefix 
$limit_log");
+                            }
+                            if ($rule->{'RULEACTION'} ne 'logOnly') {
+                                &prepareRule("$rulebody $ruleAction 
$limit_action");
+                            }
+                        }    # foreach $service (@services)
+                    }    # foreach $tmpDestAdr (@destAdres)
+                }    # foreach $tmpSrcAdr (@srcAdres)
+            }    # foreach my $tmpOutDev (@outDev)
+
+        }
     }    # foreach $line (@Rules)
 }
 
@@ -788,7 +939,7 @@
                     foreach my $protoPort (@serviceXYZ) {
                         &prepareRule("-A FW_IPCOP -i 
$FW::interfaces{$inIface}{'IFACE'} $protoPort -j ACCEPT");
                     }
-                }   
+                }
             }
 
             # Allow OpenVPN if enabled on blue, OpenVPN access does not need 
Blue Access entry so it much come first
@@ -830,7 +981,7 @@
                     foreach my $protoPort (@serviceXYZ) {
                         &prepareRule("-A FW_IPCOP -i 
$FW::interfaces{$inIface}{'IFACE'} $protoPort -j ACCEPT");
                     }
-                }   
+                }
             }
 
             # allow OpenVPN if enabled on red
@@ -859,7 +1010,7 @@
             if ($FW::interfaces{$inIface}{'COLOR'} =~ /^ORANGE_COLOR$/) {
                 if ($ipsecSettings{'ENABLED'} eq 'on') {
                     push(@ipcopServices, 'IPCop isakmp', 'IPCop ESP', 'IPCop 
AH');
-                }   
+                }
                 if ($ovpnSettings{'ENABLED_ORANGE_1'} eq 'on') {
                     push(@ipcopServices, 'IPCop OpenVPN');
                 }
@@ -874,7 +1025,7 @@
                 foreach my $protoPort (@serviceXYZ) {
                     &prepareRule("-A FW_IPCOP -i 
$FW::interfaces{$inIface}{'IFACE'} $protoPort -j ACCEPT");
                 }
-            }   
+            }
         }   # if ($ifacePolicies{$inIface}{'POLICY'} =~ /^half-open|open$/)
 
 
@@ -1164,13 +1315,17 @@
 
     my $prefixIP  = "-s";
     my $prefixMAC = '-m mac --mac-source';
-    if ($p_sourceOrDest ne 'source') {
+    if($p_sourceOrDest eq 'extPfw') {
+         $prefixIP = "";
+    }
+    elsif ($p_sourceOrDest ne 'source') {
         $prefixIP = "-d";
 
         # A MAC address can not be a destination address.
         # In case there is a MAC as destination entered we return an empty 
array
     }
 
+
     if ($p_addressType eq 'custom') {
         unless (defined $custAddresses{$p_addressName}{'ADDRESS'}) {
             &General::log("BlockOutTraffic Error: Custom Address 
$p_addressName does not exist");


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Register Now & Save for Velocity, the Web Performance & Operations 
Conference from O'Reilly Media. Velocity features a full day of 
expert-led, hands-on workshops and two days of sessions from industry 
leaders in dedicated Performance & Operations tracks. Use code vel09scf 
and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
_______________________________________________
Ipcop-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ipcop-svn

Reply via email to