]> git.proxmox.com Git - pve-firewall.git/blobdiff - PVE/Firewall.pm
implement stop command using new iptables_get_chains
[pve-firewall.git] / PVE / Firewall.pm
index 65e0050ed603831885c690578e7e1678df9f33d9..8a83dcb862b126fc64893c84bcf3964333adfecb 100644 (file)
@@ -3,6 +3,7 @@ package PVE::Firewall;
 use warnings;
 use strict;
 use Data::Dumper;
+use Digest::SHA;
 use PVE::Tools;
 use PVE::QemuServer;
 use File::Path;
@@ -145,14 +146,87 @@ sub iptables {
     run_command("/sbin/iptables $cmd", outfunc => sub {}, errfunc => sub {});
 }
 
+sub iptables_restore_cmdlist {
+    my ($cmdlist) = @_;
+
+    my $verbose = 1; # fixme: how/when do we set this
+
+    #run_command("echo '$cmdlist' | /sbin/iptables-restore -n");
+    eval { run_command("/sbin/iptables-restore -n ", input => $cmdlist); };
+    if (my $err = $@) {
+       print STDERR $cmdlist if $verbose;
+       die $err;
+    }
+}
+
 sub iptables_restore {
 
     unshift (@ruleset, '*filter');
     push (@ruleset, 'COMMIT');
 
-    my $cmdlist = join("\n", @ruleset);
+    my $cmdlist = join("\n", @ruleset) . "\n";
+
+    iptables_restore_cmdlist($cmdlist);
+}
+
+# experimental code to read existing chains and compute SHA1 checksum
+# for each chain. 
+sub iptables_get_chains {
+
+    my $res = {};
+
+    # check what chains we want to track
+    my $is_pvefw_chain = sub {
+       my $name = shift;
+
+       return 1 if $name =~ m/^BRIDGEFW-(:?IN|OUT)$/;
+       return 1 if $name =~ m/^proxmoxfw-\S+$/;
+       return 1 if $name =~ m/^tap\d+i\d+-(:?IN|OUT)$/;
+       return 1 if $name =~ m/^vmbr\d+-(:?IN|OUT)$/;
+
+       return undef;
+    };
+
+    my $table = '';
 
-    run_command("/sbin/iptables-restore -n", input => $cmdlist, outfunc => sub {});
+    my $dhash = {};
+
+    my $parser = sub {
+       my $line = shift;
+
+       return if $line =~ m/^#/;
+       return if $line =~ m/^\s*$/;
+
+       if ($line =~ m/^\*(\S+)$/) {
+           $table = $1;
+           return;
+       }
+
+       return if $table ne 'filter';
+
+       if ($line =~ m/^:(\S+)\s/) {
+           my $chain = $1;
+           return if !&$is_pvefw_chain($chain);
+           $dhash->{$chain} = Digest::SHA->new('sha1');
+       } elsif ($line =~ m/^-([A-Z]) (\S+)\s/) {
+           my $chain = $2;
+           return if !&$is_pvefw_chain($chain);
+           my $sha = $dhash->{$chain} || die "undefined chain '$chain'";
+           $sha->add_bits("$line\n");
+       } else {
+           # simply ignore the rest
+           return;
+       }
+    };
+
+    run_command("/sbin/iptables-save", outfunc => $parser);
+
+    foreach my $chain (keys %$dhash) {
+       my $sha = $dhash->{$chain};
+       $res->{$chain} = $sha->b64digest;
+    }
+
+    return $res;
 }
 
 sub iptables_addrule {