]> git.proxmox.com Git - pve-firewall.git/blobdiff - pvefw
fix iptables-restore - correctly add newline after COMMIT
[pve-firewall.git] / pvefw
diff --git a/pvefw b/pvefw
index 1a0631b4bf9870b42d6e96de6a11bbd7d6d7b4a0..e33518de64c13db1e7463a8382505bd47a8afab6 100755 (executable)
--- a/pvefw
+++ b/pvefw
@@ -3,15 +3,11 @@
 use strict;
 use lib qw(.);
 use PVE::Firewall;
-use File::Path;
-use IO::File;
-use Data::Dumper;
 
 use PVE::SafeSyslog;
 use PVE::Cluster;
 use PVE::INotify;
 use PVE::RPCEnvironment;
-use PVE::QemuServer;
 
 use PVE::JSONSchema qw(get_standard_option);
 
@@ -33,124 +29,143 @@ $rpcenv->init_request();
 $rpcenv->set_language($ENV{LANG});
 $rpcenv->set_user('root@pam');
 
+__PACKAGE__->register_method({
+    name => 'enablevmfw',
+    path => 'enablevmfw',
+    method => 'POST',
+    parameters => {
+        additionalProperties => 0,
+        properties => {
+            vmid => get_standard_option('pve-vmid'),
+            netid => {
+                type => 'string',
+               optional => 1
+            },
+        },
+    },
+    returns => { type => 'null' },
+    code => sub {
+        my ($param) = @_;
 
-sub parse_fw_rules {
-    my ($filename, $fh) = @_;
+        # test if VM exists
+        my $vmid = $param->{vmid};
+        my $netid = $param->{netid};
 
-    my $section;
+       my $code = sub {
+           my $conf = PVE::QemuServer::load_config($vmid);
 
-    my $res = { in => [], out => [] };
+           foreach my $opt (keys %$conf) {
+               next if $opt !~ m/^net(\d+)$/;
+               my $net = PVE::QemuServer::parse_net($conf->{$opt});
+               next if !$net;
+               next if $netid && $opt != $netid;
+               PVE::Firewall::generate_tap_rules($net, $opt, $vmid);
+           }
+       };
 
-    my $macros = PVE::Firewall::get_shorewall_macros();
+       PVE::Firewall::run_locked($code);
+        
+       return undef;
+    }});
 
-    while (defined(my $line = <$fh>)) {
-       next if $line =~ m/^#/;
-       next if $line =~ m/^\s*$/;
+__PACKAGE__->register_method({
+    name => 'disablevmfw',
+    path => 'disablevmfw',
+    method => 'POST',
+    parameters => {
+        additionalProperties => 0,
+        properties => {
+            vmid => get_standard_option('pve-vmid'),
+            netid => {
+                type => 'string',
+               optional => 1
+            },
+
+        },
+    },
+    returns => { type => 'null' },
+    code => sub {
+        my ($param) = @_;
 
-       if ($line =~ m/^\[(in|out)\]\s*$/i) {
-           $section = lc($1);
-           next;
-       }
-       next if !$section;
+        # test if VM exists
+        my $vmid = $param->{vmid};
+        my $netid = $param->{netid};
 
-       my ($action, $iface, $source, $dest, $proto, $dport, $sport) =
-           split(/\s+/, $line);
 
-       if (!($action && $iface && $source && $dest)) {
-           warn "skip incomplete line\n";
-           next;
-       }
+       my $code = sub {
+           my $conf = PVE::QemuServer::load_config($vmid);
 
-       my $service;
-       if ($action =~ m/^(ACCEPT|DROP|REJECT)$/) {
-           # OK
-       } elsif ($action =~ m/^(\S+)\((ACCEPT|DROP|REJECT)\)$/) {
-           ($service, $action) = ($1, $2);
-           if (!$macros->{$service}) {
-               warn "unknown service '$service'\n";
-               next;
+           foreach my $opt (keys %$conf) {
+               next if $opt !~ m/^net(\d+)$/;
+               my $net = PVE::QemuServer::parse_net($conf->{$opt});
+               next if !$net;
+               next if $netid && $opt != $netid;
+               PVE::Firewall::flush_tap_rules($net, $opt, $vmid);
            }
-       } else {
-           warn "unknown action '$action'\n";
-           next;
-       }
-
-       if ($iface !~ m/^(all|net0|net1|net2|net3|net4|net5)$/) {
-           warn "unknown interface '$iface'\n";
-           next;
-       }
-
-       if ($proto && $proto !~ m/^(icmp|tcp|udp)$/) {
-           warn "unknown protokol '$proto'\n";
-           next;
-       }
-
-       if ($source !~ m/^(any)$/) {
-           warn "unknown source '$source'\n";
-           next;
-       }
-
-       if ($dest !~ m/^(any)$/) {
-           warn "unknown destination '$dest'\n";
-           next;
-       }
-
-       my $rule = {
-           action => $action,
-           service => $service,
-           iface => $iface,
-           source => $source,
-           dest => $dest,
-           proto => $proto,
-           dport => $dport,
-           sport => $sport,
        };
 
-       push @{$res->{$section}}, $rule;
-    }
-
-    return $res;
-}
+       PVE::Firewall::run_locked($code);
 
-sub read_local_vm_config {
-
-    my $openvz = {};
+        return undef;
+    }});
 
-    my $qemu = {};
+__PACKAGE__->register_method({
+    name => 'enablegroup',
+    path => 'enablegroup',
+    method => 'POST',
+    parameters => {
+        additionalProperties => 0,
+        properties => {
+            securitygroup => {
+                type => 'string',
+            },
+        },
+    },
+    returns => { type => 'null' },
+    code => sub {
+        my ($param) = @_;
 
-    my $list = PVE::QemuServer::config_list();
+       my $code = sub {
+           my $group = $param->{securitygroup};
+           PVE::Firewall::enable_group_rules($group);
+       };
 
-    foreach my $vmid (keys %$list) {
-       my $cfspath = PVE::QemuServer::cfs_config_path($vmid);
-       if (my $conf = PVE::Cluster::cfs_read_file($cfspath)) {
-           $qemu->{$vmid} = $conf;
-       }
-    }
+       PVE::Firewall::run_locked($code);
+       
+        return undef;
+    }});
 
-    my $vmdata = { openvz => $openvz, qemu => $qemu };
+__PACKAGE__->register_method({
+    name => 'disablegroup',
+    path => 'disablegroup',
+    method => 'POST',
+    parameters => {
+        additionalProperties => 0,
+        properties => {
+            securitygroup => {
+                type => 'string',
+            },
 
-    return $vmdata;
-};
+        },
+    },
+    returns => { type => 'null' },
+    code => sub {
+        my ($param) = @_;
 
-sub read_vm_firewall_rules {
-    my ($vmdata) = @_;
-    my $rules = {};
-    foreach my $vmid (keys %{$vmdata->{qemu}}, keys %{$vmdata->{openvz}}) {
-       my $filename = "/etc/pve/firewall/$vmid.fw";
-       my $fh = IO::File->new($filename, O_RDONLY);
-       next if !$fh;
+       my $code = sub {
+           my $group = $param->{securitygroup};
+           PVE::Firewall::disable_group_rules($group);
+       };
 
-       $rules->{$vmid} = parse_fw_rules($filename, $fh);
-    }
+       PVE::Firewall::run_locked($code);
 
-    return $rules;
-}
+        return undef;
+    }});
 
-__PACKAGE__->register_method ({
-    name => 'compile',
-    path => 'compile',
+__PACKAGE__->register_method({
+    name => 'enablehostfw',
+    path => 'enablehostfw',
     method => 'POST',
-    description => "Compile firewall rules.",
     parameters => {
        additionalProperties => 0,
        properties => {},
@@ -160,27 +175,42 @@ __PACKAGE__->register_method ({
     code => sub {
        my ($param) = @_;
 
-       my $vmdata = read_local_vm_config();
-       my $rules = read_vm_firewall_rules($vmdata);
+       my $code = sub {
+           PVE::Firewall::enablehostfw();
+       };
 
-       # print Dumper($vmdata);
+       PVE::Firewall::run_locked($code);
 
-       my $swdir = '/etc/shorewall';
-       mkdir $swdir;
+       return undef;
+    }});
 
-       PVE::Firewall::compile($swdir, $vmdata, $rules);
+__PACKAGE__->register_method({
+    name => 'disablehostfw',
+    path => 'disablehostfw',
+    method => 'POST',
+    parameters => {
+       additionalProperties => 0,
+       properties => {},
+    },
+    returns => { type => 'null' },
+
+    code => sub {
+       my ($param) = @_;
+
+       my $code = sub {
+           PVE::Firewall::disablehostfw();
+       };
 
-       PVE::Tools::run_command(['shorewall', 'compile']);
+       PVE::Firewall::run_locked($code);
 
        return undef;
-
     }});
 
 __PACKAGE__->register_method ({
-    name => 'start',
-    path => 'start',
+    name => 'compile',
+    path => 'compile',
     method => 'POST',
-    description => "Start firewall.",
+    description => "Compile firewall rules.",
     parameters => {
        additionalProperties => 0,
        properties => {},
@@ -190,16 +220,20 @@ __PACKAGE__->register_method ({
     code => sub {
        my ($param) = @_;
 
-       PVE::Tools::run_command(['shorewall', 'start']);
+       my $code = sub {
+           PVE::Firewall::compile();
+       };
+
+       PVE::Firewall::run_locked($code);
 
        return undef;
     }});
 
 __PACKAGE__->register_method ({
-    name => 'stop',
-    path => 'stop',
+    name => 'start',
+    path => 'start',
     method => 'POST',
-    description => "Stop firewall.",
+    description => "Start (or restart if already active) firewall.",
     parameters => {
        additionalProperties => 0,
        properties => {},
@@ -209,16 +243,20 @@ __PACKAGE__->register_method ({
     code => sub {
        my ($param) = @_;
 
-       PVE::Tools::run_command(['shorewall', 'stop']);
+       my $code = sub {
+           PVE::Firewall::compile_and_start();
+       };
+
+       PVE::Firewall::run_locked($code);
 
        return undef;
     }});
 
 __PACKAGE__->register_method ({
-    name => 'clear',
-    path => 'clear',
+    name => 'stop',
+    path => 'stop',
     method => 'POST',
-    description => "Clear will remove all rules installed by this script. The host is then unprotected.",
+    description => "Stop firewall. This will remove all rules installed by this script. The host is then unprotected.",
     parameters => {
        additionalProperties => 0,
        properties => {},
@@ -228,7 +266,11 @@ __PACKAGE__->register_method ({
     code => sub {
        my ($param) = @_;
 
-       PVE::Tools::run_command(['shorewall', 'clear']);
+       my $code = sub {
+           die "implement me";
+       };
+
+       PVE::Firewall::run_locked($code);
 
        return undef;
     }});
@@ -238,8 +280,14 @@ my $nodename = PVE::INotify::nodename();
 my $cmddef = {
     compile => [ __PACKAGE__, 'compile', []],
     start => [ __PACKAGE__, 'start', []],
+    restart => [ __PACKAGE__, 'restart', []],
     stop => [ __PACKAGE__, 'stop', []],
-    clear => [ __PACKAGE__, 'clear', []],
+    enablevmfw => [ __PACKAGE__, 'enablevmfw', []],
+    disablevmfw => [ __PACKAGE__, 'disablevmfw', []],
+    enablehostfw => [ __PACKAGE__, 'enablehostfw', []],
+    disablehostfw => [ __PACKAGE__, 'disablehostfw', []],
+    enablegroup => [ __PACKAGE__, 'enablegroup', []],
+    disablegroup => [ __PACKAGE__, 'disablegroup', []],
 };
 
 my $cmd = shift;