I'm reusing shorewall syntax,  +mynetgroup

also fixing iprange and iplist

vmid.fw
-------
IN SSH(ACCEPT) net0 192.168.2.192  # only allow SSH from  192.168.2.192
IN SSH(ACCEPT) net0 10.0.0.1-10.0.0.10 #accept SSH for ip in range 10.0.0.1 to 
10.0.0.10
IN SSH(ACCEPT) net0 10.0.0.1,10.0.0.2,10.0.0.3 #accept ssh for 10.0.0.1 or 
10.0.0.2 or 10.0.0.3
IN SSH(ACCEPT) net0 +mynetgroup   #accept ssh for netgroup mynetgroup

cluster.fw
----------
IN  ACCEPT 10.0.0.1
IN  ACCEPT 10.0.0.1-10.0.0.10
IN  ACCEPT 10.0.0.1,10.0.0.2,10.0.0.3
IN  ACCEPT +mynetgroup

Signed-off-by: Alexandre Derumier <[email protected]>
---
 example/100.fw      |    4 ++++
 example/cluster.fw  |    5 +++--
 src/PVE/Firewall.pm |   62 +++++++++++++++++++++++++++++++++++----------------
 3 files changed, 50 insertions(+), 21 deletions(-)

diff --git a/example/100.fw b/example/100.fw
index 6572fe3..30d1b1b 100644
--- a/example/100.fw
+++ b/example/100.fw
@@ -43,6 +43,10 @@ ips_queues: 0:3
 IN SSH(ACCEPT) net0
 IN SSH(ACCEPT) net0 # a comment
 IN SSH(ACCEPT) net0 192.168.2.192  # only allow SSH from  192.168.2.192
+IN SSH(ACCEPT) net0 10.0.0.1-10.0.0.10 #accept SSH for ip in range 10.0.0.1 to 
10.0.0.10
+IN SSH(ACCEPT) net0 10.0.0.1,10.0.0.2,10.0.0.3 #accept ssh for 10.0.0.1 or 
10.0.0.2 or 10.0.0.3
+IN SSH(ACCEPT) net0 +mynetgroup   #accept ssh for netgroup mynetgroup
+
 |IN SSH(ACCEPT) net0 # disabled rule
 
 # add a security group
diff --git a/example/cluster.fw b/example/cluster.fw
index 97f58cb..8af85f6 100644
--- a/example/cluster.fw
+++ b/example/cluster.fw
@@ -15,8 +15,9 @@ OUT ACCEPT - - icmp - -
 [group group3]
 
 IN  ACCEPT 10.0.0.1 
-IN  ACCEPT 10.0.0.2
-IN  ACCEPT 10.0.0.2 
+IN  ACCEPT 10.0.0.1-10.0.0.10
+IN  ACCEPT 10.0.0.1,10.0.0.2,10.0.0.3
+IN  ACCEPT +mynetgroup 
 
 
 [netgroup mynetgroup]
diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm
index 54235fb..e6809ef 100644
--- a/src/PVE/Firewall.pm
+++ b/src/PVE/Firewall.pm
@@ -602,6 +602,9 @@ sub parse_address_list {
 
     my $nbaor = 0;
     foreach my $aor (split(/,/, $str)) {
+       if($nbaor > 0 && $aor =~ m/-/){
+           die "you can use a range in a list";
+       }
        if (!Net::IP->new($aor)) {
            my $err = Net::IP::Error();
            die "invalid IP address: $err\n";
@@ -609,7 +612,6 @@ sub parse_address_list {
            $nbaor++;
        }
     }
-    return $nbaor;
 }
 
 sub parse_port_name_number_or_range {
@@ -913,7 +915,7 @@ sub ipset_get_chains {
 }
 
 sub ruleset_generate_cmdstr {
-    my ($ruleset, $chain, $rule, $actions, $goto) = @_;
+    my ($ruleset, $chain, $rule, $actions, $goto, $cluster_conf) = @_;
 
     return if defined($rule->{enable}) && !$rule->{enable};
 
@@ -921,18 +923,40 @@ sub ruleset_generate_cmdstr {
 
     my $nbdport = defined($rule->{dport}) ? 
parse_port_name_number_or_range($rule->{dport}) : 0;
     my $nbsport = defined($rule->{sport}) ? 
parse_port_name_number_or_range($rule->{sport}) : 0;
-    my $nbsource = $rule->{source} ? parse_address_list( $rule->{source}) : 0;
-    my $nbdest = $rule->{dest} ? parse_address_list($rule->{dest}) : 0;
 
     my @cmd = ();
 
     push @cmd, "-i $rule->{iface_in}" if $rule->{iface_in};
     push @cmd, "-o $rule->{iface_out}" if $rule->{iface_out};
 
-    push @cmd, "-m iprange --src-range" if $nbsource > 1;
-    push @cmd, "-s $rule->{source}" if $rule->{source};
-    push @cmd, "-m iprange --dst-range" if $nbdest > 1;
-    push @cmd, "-d $rule->{dest}" if $rule->{dest};
+    my $source = $rule->{source};
+    my $dest = $rule->{dest};
+
+    if ($source){
+        if($source =~ m/^(\+)(\S+)$/){
+           die "no such netgroup $2" if !$cluster_conf->{ipset}->{$2};
+           push @cmd, "-m set --match-set $2 src";
+
+        }elsif ($source =~ 
m/^(\d+)\.(\d+).(\d+).(\d+)\-(\d+)\.(\d+).(\d+).(\d+)$/){
+           push @cmd, "-m iprange --src-range $source";
+
+       }else{
+           push @cmd, "-s $source";
+        }
+    }
+
+    if ($dest){
+        if($dest =~ m/^(\+)(\S+)$/){
+           die "no such netgroup $2" if !$cluster_conf->{ipset}->{$2};
+           push @cmd, "-m set --match-set $2 dst";
+
+        }elsif ($dest =~ 
m/^(\d+)\.(\d+).(\d+).(\d+)\-(\d+)\.(\d+).(\d+).(\d+)$/){
+           push @cmd, "-m iprange --dst-range $dest";
+
+       }else{
+           push @cmd, "-s $dest";
+        }
+    }
 
     if ($rule->{proto}) {
        push @cmd, "-p $rule->{proto}";
@@ -1032,7 +1056,7 @@ my $apply_macro = sub {
 };
 
 sub ruleset_generate_rule {
-    my ($ruleset, $chain, $rule, $actions, $goto) = @_;
+    my ($ruleset, $chain, $rule, $actions, $goto, $cluster_conf) = @_;
 
     my $rules;
 
@@ -1043,7 +1067,7 @@ sub ruleset_generate_rule {
     }
 
     foreach my $tmp (@$rules) { 
-       if (my $cmdstr = ruleset_generate_cmdstr($ruleset, $chain, $tmp, 
$actions, $goto)) {
+       if (my $cmdstr = ruleset_generate_cmdstr($ruleset, $chain, $tmp, 
$actions, $goto, $cluster_conf)) {
            ruleset_addrule($ruleset, $chain, $cmdstr);
        }
     }
@@ -1239,10 +1263,10 @@ sub ruleset_generate_vm_rules {
            next if $rule->{type} ne $lc_direction;
            if ($direction eq 'OUT') {
                ruleset_generate_rule($ruleset, $chain, $rule, 
-                                     { ACCEPT => "PVEFW-SET-ACCEPT-MARK", 
REJECT => "PVEFW-reject" });
+                                     { ACCEPT => "PVEFW-SET-ACCEPT-MARK", 
REJECT => "PVEFW-reject" }, undef, $cluster_conf);
            } else {
                my $accept = generate_nfqueue($options);
-               ruleset_generate_rule($ruleset, $chain, $rule, { ACCEPT => 
$accept , REJECT => "PVEFW-reject" });
+               ruleset_generate_rule($ruleset, $chain, $rule, { ACCEPT => 
$accept , REJECT => "PVEFW-reject" }, undef, $cluster_conf);
            }
        }
     }
@@ -1418,7 +1442,7 @@ sub enable_host_firewall {
 
     foreach my $rule (@$rules) {
        next if $rule->{type} ne 'in';
-       ruleset_generate_rule($ruleset, $chain, $rule, { ACCEPT => 
$accept_action, REJECT => "PVEFW-reject" });
+       ruleset_generate_rule($ruleset, $chain, $rule, { ACCEPT => 
$accept_action, REJECT => "PVEFW-reject" }, undef, $cluster_conf);
     }
 
     # implement input policy
@@ -1443,7 +1467,7 @@ sub enable_host_firewall {
 
     foreach my $rule (@$rules) {
        next if $rule->{type} ne 'out';
-       ruleset_generate_rule($ruleset, $chain, $rule, { ACCEPT => 
$accept_action, REJECT => "PVEFW-reject" });
+       ruleset_generate_rule($ruleset, $chain, $rule, { ACCEPT => 
$accept_action, REJECT => "PVEFW-reject" }, undef, $cluster_conf);
     }
 
     # implement output policy
@@ -1467,7 +1491,7 @@ sub generate_group_rules {
 
     foreach my $rule (@$rules) {
        next if $rule->{type} ne 'in';
-       ruleset_generate_rule($ruleset, $chain, $rule, { ACCEPT => 
"PVEFW-SET-ACCEPT-MARK", REJECT => "PVEFW-reject" });
+       ruleset_generate_rule($ruleset, $chain, $rule, { ACCEPT => 
"PVEFW-SET-ACCEPT-MARK", REJECT => "PVEFW-reject" }, undef, $cluster_conf);
     }
 
     $chain = "GROUP-${group}-OUT";
@@ -1480,7 +1504,7 @@ sub generate_group_rules {
        # we use PVEFW-SET-ACCEPT-MARK (Instead of ACCEPT) because we need to
        # check also other tap rules later
        ruleset_generate_rule($ruleset, $chain, $rule, 
-                             { ACCEPT => 'PVEFW-SET-ACCEPT-MARK', REJECT => 
"PVEFW-reject" });
+                             { ACCEPT => 'PVEFW-SET-ACCEPT-MARK', REJECT => 
"PVEFW-reject" }, undef, $cluster_conf);
     }
 }
 
@@ -1555,9 +1579,9 @@ sub parse_fw_rule {
 
     parse_port_name_number_or_range($dport) if defined($dport);
     parse_port_name_number_or_range($sport) if defined($sport);
- 
-    parse_address_list($source) if $source;
-    parse_address_list($dest) if $dest;
+
+    parse_address_list($source) if $source && $source !~ m/^(\+)(\S+)$/;
+    parse_address_list($dest) if $dest && $dest !~ m/^(\+)(\S+)$/;
 
     return {
        type => $type,
-- 
1.7.10.4

_______________________________________________
pve-devel mailing list
[email protected]
http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to