implement workaround for inbound rules with source IP
authorDietmar Maurer <dietmar@proxmox.com>
Tue, 14 Aug 2012 10:28:37 +0000 (12:28 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Tue, 14 Aug 2012 10:28:37 +0000 (12:28 +0200)
PVE/Firewall.pm
README

index 3f0adf0..f1eba0e 100644 (file)
@@ -41,25 +41,36 @@ my $generate_input_rule = sub {
     my $action = $rule->{service} ? 
        "$rule->{service}($rule->{action})" : $rule->{action};
 
-    my $source;
+    my $sources = [];
 
-    if ($zoneinfo->{$zone}->{type} eq 'bport') {
+    if (!$rule->{source}) {
+       push @$sources, 'all'; 
+    } elsif ($zoneinfo->{$zone}->{type} eq 'bport') {
        my $bridge_zone = $zoneinfo->{$zone}->{bridge_zone} || die "internal error";
-       my $bridge_ext_zone = $zoneinfo->{$bridge_zone}->{bridge_ext_zone} || die "internal error";
-       my $zoneref = $zoneinfo->{$bridge_ext_zone}->{zoneref} || die "internal error";
-       if (!$rule->{source}) {
-           # $source = "${zoneref}";
-           $source = 'all';
-       } else {
-           # 'all' does not work
-           $source = "${zoneref}:$rule->{source}";
+       my $zoneref = $zoneinfo->{$bridge_zone}->{zoneref} || die "internal error";
+
+       # using 'all' does not work, so we create one rule for
+       # each related zone on the same bridge
+       push @$sources, "${zoneref}:$rule->{source}";
+       foreach my $z (keys %$zoneinfo) {
+           next if $z eq $zone;
+           next if !$zoneinfo->{$z}->{bridge_zone};
+           next if $zoneinfo->{$z}->{bridge_zone} ne $bridge_zone;
+           $zoneref = $zoneinfo->{$z}->{zoneref} || die "internal error";
+           push @$sources, "${zoneref}:$rule->{source}";
        }
     } else {
-       $source = "all:$rule->{source}";
+       push @$sources, "all:$rule->{source}";
+    }
+
+    my $out = '';
+
+    foreach my $source (@$sources) {
+       $out .= sprintf($rule_format, $action, $source, $dest, $rule->{proto} || '-', 
+                       $rule->{dport} || '-', $rule->{sport} || '-');
     }
 
-    return sprintf($rule_format, $action, $source, $dest, $rule->{proto} || '-', 
-                  $rule->{dport} || '-', $rule->{sport} || '-');
+    return $out;
 };
 
 my $generate_output_rule = sub {
@@ -421,7 +432,7 @@ sub read_local_vm_config {
     my $list = PVE::QemuServer::config_list();
 
     foreach my $vmid (keys %$list) {
-       # next if $vmid ne '100';
+       #next if !($vmid eq '100' || $vmid eq '102');
        my $cfspath = PVE::QemuServer::cfs_config_path($vmid);
        if (my $conf = PVE::Cluster::cfs_read_file($cfspath)) {
            $qemu->{$vmid} = $conf;
diff --git a/README b/README
index e6f447a..c1c2518 100644 (file)
--- a/README
+++ b/README
@@ -123,7 +123,7 @@ Outbound rules looks like:
  SSH(ACCEPT)     $ZVMBR0VM100:tap100i0          all
 
 
-Unresolved problems
+Problems
 ===================
 
 Inbound rules with source IP does not work, because shorewall
@@ -131,9 +131,12 @@ does not allow rules like:
 
  SSH(ACCEPT)     all:IP_ADDRESS       $ZVMBR0VM100:tap100i0
 
-As workaroud, we can create such rule for each BP zone:
+As workaroud, we create one rule for each BP zone on the same
+bridge:
 
- SSH(ACCEPT)     $ZVMBR0EXT:IP_ADDRESS       $ZVMBR0VM100:tap100i0
+ SSH(ACCEPT)     $ZVMBR0:IP_ADDRESS       $ZVMBR0VM100:tap100i0
+ SSH(ACCEPT)     $ZVMBR0VM777:IP_ADDRESS  $ZVMBR0VM100:tap100i0
+ SSH(ACCEPT)     $ZVMBR0EXT:IP_ADDRESS    $ZVMBR0VM100:tap100i0