[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