[pve-devel] [PATCH 6/6] add support for security groups

Alexandre Derumier aderumier at odiso.com
Fri Feb 7 16:22:32 CET 2014


pvefw disablegroup -securitygroup <string> [OPTIONS]
pvefw enablegroup -securitygroup <string> [OPTIONS]

(pool permissions is not yet implemented)

/etc/pve/firewall/groups.fw

[IN:group1]

ACCEPT - - - tcp 22 -
ACCEPT - - - icmp - -

[OUT:group1]

ACCEPT - - - tcp 80 -
ACCEPT - - - icmp - -

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 PVE/Firewall.pm |   84 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 pvefw           |   47 +++++++++++++++++++++++++++++++
 2 files changed, 129 insertions(+), 2 deletions(-)

diff --git a/PVE/Firewall.pm b/PVE/Firewall.pm
index 5396bcd..ff5cadf 100644
--- a/PVE/Firewall.pm
+++ b/PVE/Firewall.pm
@@ -463,6 +463,80 @@ sub generate_proxmoxfwoutput {
 
 }
 
+sub enable_group_rules {
+    my ($group) = @_;
+    
+    generate_group_rules($group);
+    iptables_restore();
+}
+
+sub generate_group_rules {
+    my ($group) = @_;
+
+    my $filename = "/etc/pve/firewall/groups.fw";
+    my $fh = IO::File->new($filename, O_RDONLY);
+    return if !$fh;
+
+    my $rules = parse_fw_rules($filename, $fh, $group);
+    my $inrules = $rules->{in};
+    my $outrules = $rules->{out};
+
+    my $chain = "GROUP-".$group."-IN";
+
+    iptables_addrule(":$chain - [0:0]");
+
+    if (scalar(@$inrules)) {
+        foreach my $rule (@$inrules) {
+            iptables_generate_rule($chain, $rule);
+        }
+    }
+
+    $chain = "GROUP-".$group."-OUT";
+
+    iptables_addrule(":$chain - [0:0]");
+
+    if(!iptables_chain_exist("BRIDGEFW-OUT")){
+	iptables_addrule(":BRIDGEFW-OUT - [0:0]");
+    }
+
+    if(!iptables_chain_exist("BRIDGEFW-IN")){
+	iptables_addrule(":BRIDGEFW-IN - [0:0]");
+    }
+
+    if (scalar(@$outrules)) {
+        foreach my $rule (@$outrules) {
+            #we go the BRIDGEFW-IN because we need to check also other tap rules 
+            #(and group rules can be set on any bridge, so we can't go to VMBRXX-IN)
+            $rule->{action} = 'BRIDGEFW-IN' if $rule->{action} eq 'ACCEPT';
+            iptables_generate_rule($chain, $rule);
+        }
+    }
+
+}
+
+sub disable_group_rules {
+    my ($group) = @_;
+
+    my $chain = "GROUP-".$group."-IN";
+
+    if(iptables_chain_exist($chain)){
+	iptables_addrule("-F $chain");
+	iptables_addrule("-X $chain");
+    }
+
+    $chain = "GROUP-".$group."-OUT";
+
+    if(iptables_chain_exist($chain)){
+	iptables_addrule("-F $chain");
+	iptables_addrule("-X $chain");
+    }
+
+    #iptables_restore will die if security group is linked in a tap chain
+    #maybe can we improve that, parsing each vm config, or parsing iptables -S
+    #to see if the security group is linked or not
+    iptables_restore();
+}
+
 
 my $generate_input_rule = sub {
     my ($zoneinfo, $rule, $net, $netid) = @_;
@@ -777,9 +851,11 @@ my $compile_shorewall = sub {
 
 
 sub parse_fw_rules {
-    my ($filename, $fh) = @_;
+    my ($filename, $fh, $group) = @_;
 
     my $section;
+    my $securitygroup;
+    my $securitygroupexist;
 
     my $res = { in => [], out => [] };
 
@@ -790,11 +866,14 @@ sub parse_fw_rules {
 	next if $line =~ m/^#/;
 	next if $line =~ m/^\s*$/;
 
-	if ($line =~ m/^\[(in|out)\]\s*$/i) {
+	if ($line =~ m/^\[(in|out)(:(\S+))?\]\s*$/i) {
 	    $section = lc($1);
+	    $securitygroup = lc($3) if $3;
+	    $securitygroupexist = 1 if $securitygroup &&  $securitygroup eq $group;
 	    next;
 	}
 	next if !$section;
+	next if $group && $securitygroup ne $group;
 
 	my ($action, $iface, $source, $dest, $proto, $dport, $sport) =
 	    split(/\s+/, $line);
@@ -873,6 +952,7 @@ sub parse_fw_rules {
 	push @{$res->{$section}}, $rule;
     }
 
+    die "security group $group don't exist" if $group && !$securitygroupexist;
     return $res;
 }
 
diff --git a/pvefw b/pvefw
index 2d4d450..70a2bee 100755
--- a/pvefw
+++ b/pvefw
@@ -101,6 +101,51 @@ __PACKAGE__->register_method({
     }});
 
 __PACKAGE__->register_method({
+    name => 'enablegroup',
+    path => 'enablegroup',
+    method => 'POST',
+    parameters => {
+        additionalProperties => 0,
+        properties => {
+            securitygroup => {
+                type => 'string',
+            },
+        },
+    },
+    returns => { type => 'null' },
+    code => sub {
+        my ($param) = @_;
+
+	my $group = $param->{securitygroup};
+	PVE::Firewall::enable_group_rules($group);
+
+        return undef;
+    }});
+
+__PACKAGE__->register_method({
+    name => 'disablegroup',
+    path => 'disablegroup',
+    method => 'POST',
+    parameters => {
+        additionalProperties => 0,
+        properties => {
+            securitygroup => {
+                type => 'string',
+            },
+
+        },
+    },
+    returns => { type => 'null' },
+    code => sub {
+        my ($param) = @_;
+
+	my $group = $param->{securitygroup};
+	PVE::Firewall::disable_group_rules($group);
+
+        return undef;
+    }});
+
+__PACKAGE__->register_method({
     name => 'enablehostfw',
     path => 'enablehostfw',
     method => 'POST',
@@ -243,6 +288,8 @@ my $cmddef = {
     disablevmfw => [ __PACKAGE__, 'disablevmfw', []],
     enablehostfw => [ __PACKAGE__, 'enablehostfw', []],
     disablehostfw => [ __PACKAGE__, 'disablehostfw', []],
+    enablegroup => [ __PACKAGE__, 'enablegroup', []],
+    disablegroup => [ __PACKAGE__, 'disablegroup', []],
 };
 
 my $cmd = shift;
-- 
1.7.10.4




More information about the pve-devel mailing list