add aliases feature
authorAlexandre Derumier <aderumier@odiso.com>
Sat, 19 Apr 2014 07:00:03 +0000 (09:00 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Tue, 22 Apr 2014 05:49:09 +0000 (07:49 +0200)
this allow to defined ip et network aliases,

which can be used in vm/group rules and also ipset

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
debian/example/100.fw
debian/example/cluster.fw
src/PVE/Firewall.pm

index b1f65c3..78f300a 100644 (file)
@@ -40,6 +40,7 @@ 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 +myserveralias   #accept ssh for alias myserveralias
 
 |IN SSH(ACCEPT) net0 # disabled rule
 
index e9a57ea..bf5a98f 100644 (file)
@@ -7,6 +7,11 @@ enable: 1
 policy_in: DROP
 policy_out: ACCEPT
 
+[ALIASES]
+
+myserveralias 10.0.0.111
+mynetworkalias 10.0.0.0/24
+
 [RULES]
 
 IN  SSH(ACCEPT) vmbr0
@@ -23,6 +28,7 @@ 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 
+IN  ACCEPT myserveralias
 
 
 [ipset myipset]
@@ -31,4 +37,4 @@ IN  ACCEPT +mynetgroup
 172.16.0.10
 192.168.0.0/24
 ! 10.0.0.0/8  #nomatch - needs kernel 3.7 or newer
-
+mynetworkalias
index 6ec314c..7ef38fa 100644 (file)
@@ -712,6 +712,7 @@ sub parse_address_list {
     my ($str) = @_;
 
     return if $str =~ m/^(\+)(\S+)$/; # ipset ref
+    return if $str =~ m/^${security_group_pattern}$/; # aliases
 
     my $count = 0;
     my $iprange = 0;
@@ -1208,6 +1209,10 @@ sub ruleset_generate_cmdstr {
            die "no such ipset $2" if !$cluster_conf->{ipset}->{$2};
            push @cmd, "-m set --match-set PVEFW-$2 src";
 
+       } elsif ($source =~ m/^${security_group_pattern}$/){
+           die "no such alias $source" if !$cluster_conf->{aliases}->{$source};
+           push @cmd, "-s $cluster_conf->{aliases}->{$source}";
+
         } elsif ($source =~ m/\-/){
            push @cmd, "-m iprange --src-range $source";
 
@@ -1221,6 +1226,10 @@ sub ruleset_generate_cmdstr {
            die "no such ipset $2" if !$cluster_conf->{ipset}->{$2};
            push @cmd, "-m set --match-set PVEFW-$2 dst";
 
+       } elsif ($dest =~ m/^${security_group_pattern}$/){
+           die "no such alias $dest" if !$cluster_conf->{aliases}->{$dest};
+           push @cmd, "-d $cluster_conf->{aliases}->{$dest}";
+
         } elsif ($dest =~ m/^(\d+)\.(\d+).(\d+).(\d+)\-(\d+)\.(\d+).(\d+).(\d+)$/){
            push @cmd, "-m iprange --dst-range $dest";
 
@@ -1897,6 +1906,25 @@ sub parse_clusterfw_option {
     return ($opt, $value);
 }
 
+sub parse_clusterfw_alias {
+    my ($line) = @_;
+
+    my ($opt, $value);
+    if ($line =~ m/^(\S+)\s(\S+)$/) {
+       $opt = lc($1);
+       if($2){
+           $2 =~ s|/32$||;
+           pve_verify_ipv4_or_cidr($2) if $2;
+           $value = $2;
+       }
+    } else {
+       chomp $line;
+       die "can't parse option '$line'\n";
+    }
+
+    return ($opt, $value);
+}
+
 sub parse_vm_fw_rules {
     my ($filename, $fh) = @_;
 
@@ -2020,6 +2048,11 @@ sub parse_cluster_fw_rules {
            next;
        }
 
+       if ($line =~ m/^\[aliases\]$/i) {
+           $section = 'aliases';
+           next;
+       }
+
        if ($line =~ m/^\[group\s+(\S+)\]\s*(?:#\s*(.*?)\s*)?$/i) {
            $section = 'groups';
            $group = lc($1);
@@ -2056,6 +2089,12 @@ sub parse_cluster_fw_rules {
                $res->{options}->{$opt} = $value;
            };
            warn "$prefix: $@" if $@;
+       } elsif ($section eq 'aliases') {
+           eval {
+               my ($opt, $value) = parse_clusterfw_alias($line);
+               $res->{aliases}->{$opt} = $value;
+           };
+           warn "$prefix: $@" if $@;
        } elsif ($section eq 'rules') {
            my $rule;
            eval { $rule = parse_fw_rule($line, 1, 1); };
@@ -2080,12 +2119,14 @@ sub parse_cluster_fw_rules {
            my $nomatch = $1;
            my $cidr = $2;
 
-           $cidr =~ s|/32$||;
+           if($cidr !~ m/^${security_group_pattern}$/) {
+               $cidr =~ s|/32$||;
            
-           eval { pve_verify_ipv4_or_cidr($cidr); };
-           if (my $err = $@) {
-               warn "$prefix: $cidr - $err";
-               next;
+               eval { pve_verify_ipv4_or_cidr($cidr); };
+               if (my $err = $@) {
+                   warn "$prefix: $cidr - $err";
+                   next;
+               }
            }
 
            my $entry = { cidr => $cidr }; 
@@ -2317,12 +2358,12 @@ sub generate_ipset_chains {
     my ($ipset_ruleset, $fw_conf) = @_;
 
     foreach my $ipset (keys %{$fw_conf->{ipset}}) {
-       generate_ipset($ipset_ruleset, "PVEFW-$ipset", $fw_conf->{ipset}->{$ipset});
+       generate_ipset($ipset_ruleset, "PVEFW-$ipset", $fw_conf->{ipset}->{$ipset}, $fw_conf->{aliases});
     }
 }
 
 sub generate_ipset {
-    my ($ipset_ruleset, $name, $options) = @_;
+    my ($ipset_ruleset, $name, $options, $aliases) = @_;
 
     my $hashsize = scalar(@$options);
     if ($hashsize <= 64) {
@@ -2336,6 +2377,12 @@ sub generate_ipset {
     # remove duplicates
     my $nethash = {};
     foreach my $entry (@$options) {
+       my $cidr = $entry->{cidr};
+       #check aliases
+       if ($cidr =~ m/^${security_group_pattern}$/){
+           die "no such alias $cidr" if !$aliases->{$cidr};
+           $entry->{cidr} = $aliases->{$cidr};
+       }
        $nethash->{$entry->{cidr}} = $entry;
     }