host firewall support
authorAlexandre Derumier <aderumier@odiso.com>
Fri, 7 Feb 2014 15:22:30 +0000 (16:22 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 13 Feb 2014 09:56:53 +0000 (10:56 +0100)
defaults rules:

/etc/pve/local/host.fw

[IN]

ACCEPT - - - tcp 24007 -   #glusterfs
ACCEPT - - - icmp - -
ACCEPT - - - tcp 22 -
ACCEPT - - - tcp 8006 - #pveproxy
ACCEPT - - - tcp 3128 -  #spiceproxy
ACCEPT - - - tcp 6789 -  #ceph mon
ACCEPT - - - tcp 5900:5910 - #vnc consoles
ACCEPT - - - udp 53 -

[OUT]

ACCEPT - - - icmp - -
ACCEPT - - - tcp 24007 - #glusterfs
ACCEPT - - - tcp 6789 - #ceph mon
ACCEPT - - - tcp 22 -
ACCEPT - - - udp 53 -

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
PVE/Firewall.pm
pvefw

index f29d5ec..de25b04 100644 (file)
@@ -347,6 +347,124 @@ sub flush_tap_rules_direction {
     }
 }
 
+sub enablehostfw {
+
+    generate_proxmoxfwinput();
+    generate_proxmoxfwoutput();
+
+    my $filename = "/etc/pve/local/host.fw";
+    my $fh = IO::File->new($filename, O_RDONLY);
+    return if !$fh;
+
+    my $rules = parse_fw_rules($filename, $fh);
+    my $inrules = $rules->{in};
+    my $outrules = $rules->{out};
+
+    #host inbound firewall
+    iptables_addrule(":host-IN - [0:0]");
+    iptables_addrule("-A host-IN -m state --state INVALID -j DROP");
+    iptables_addrule("-A host-IN -m state --state RELATED,ESTABLISHED -j ACCEPT");
+    iptables_addrule("-A host-IN -i lo -j ACCEPT");
+    iptables_addrule("-A host-IN -m addrtype --dst-type MULTICAST -j ACCEPT");
+    iptables_addrule("-A host-IN -p udp -m state --state NEW -m multiport --dports 5404,5405 -j ACCEPT");
+    iptables_addrule("-A host-IN -p udp -m udp --dport 9000 -j ACCEPT"); #corosync
+
+    if (scalar(@$inrules)) {
+        foreach my $rule (@$inrules) {
+            #we use RETURN because we need to check also tap rules
+            $rule->{action} = 'RETURN' if $rule->{action} eq 'ACCEPT';
+            iptables_generate_rule('host-IN', $rule);
+        }
+    }
+
+    iptables_addrule("-A host-IN -j LOG --log-prefix \"kvmhost-IN dropped: \" --log-level 4");
+    iptables_addrule("-A host-IN -j DROP");
+
+    #host outbound firewall
+    iptables_addrule(":host-OUT - [0:0]");
+    iptables_addrule("-A host-OUT -m state --state INVALID -j DROP");
+    iptables_addrule("-A host-OUT -m state --state RELATED,ESTABLISHED -j ACCEPT");
+    iptables_addrule("-A host-OUT -o lo -j ACCEPT");
+    iptables_addrule("-A host-OUT -m addrtype --dst-type MULTICAST -j ACCEPT");
+    iptables_addrule("-A host-OUT -p udp -m state --state NEW -m multiport --dports 5404,5405 -j ACCEPT");
+    iptables_addrule("-A host-OUT -p udp -m udp --dport 9000 -j ACCEPT"); #corosync
+
+    if (scalar(@$outrules)) {
+        foreach my $rule (@$outrules) {
+            #we use RETURN because we need to check also tap rules
+            $rule->{action} = 'RETURN' if $rule->{action} eq 'ACCEPT';
+            iptables_generate_rule('host-OUT', $rule);
+        }
+    }
+
+    iptables_addrule("-A host-OUT -j LOG --log-prefix \"kvmhost-OUT dropped: \" --log-level 4");
+    iptables_addrule("-A host-OUT -j DROP");
+
+    
+    my $rule = "proxmoxfw-INPUT -j host-IN";
+    if(!iptables_rule_exist($rule)){
+       iptables_addrule("-I $rule");
+    }
+
+    $rule = "proxmoxfw-OUTPUT -j host-OUT";
+    if(!iptables_rule_exist($rule)){
+       iptables_addrule("-I $rule");
+    }
+
+    iptables_restore();
+
+
+}
+
+sub disablehostfw {
+
+    my $chain = "host-IN";
+
+    my $rule = "proxmoxfw-INPUT -j $chain";
+    if(iptables_rule_exist($rule)){
+       iptables_addrule("-D $rule");
+    }
+
+    if(iptables_chain_exist($chain)){
+       iptables_addrule("-F $chain");
+       iptables_addrule("-X $chain");
+    }
+
+    $chain = "host-OUT";
+
+    $rule = "proxmoxfw-OUTPUT -j $chain";
+    if(iptables_rule_exist($rule)){
+       iptables_addrule("-D $rule");
+    }
+
+    if(iptables_chain_exist($chain)){
+       iptables_addrule("-F $chain");
+       iptables_addrule("-X $chain");
+    }
+
+    iptables_restore();   
+}
+
+sub generate_proxmoxfwinput {
+
+    if(!iptables_chain_exist("proxmoxfw-INPUT")){
+        iptables_addrule(":proxmoxfw-INPUT - [0:0]");
+        iptables_addrule("-I INPUT -j proxmoxfw-INPUT");
+        iptables_addrule("-A INPUT -j ACCEPT");
+    }
+}
+
+sub generate_proxmoxfwoutput {
+
+    if(!iptables_chain_exist("proxmoxfw-OUTPUT")){
+        iptables_addrule(":proxmoxfw-OUTPUT - [0:0]");
+        iptables_addrule("-I OUTPUT -j proxmoxfw-OUTPUT");
+        iptables_addrule("-A OUTPUT -j ACCEPT");
+    }
+
+}
+
+
 my $generate_input_rule = sub {
     my ($zoneinfo, $rule, $net, $netid) = @_;
 
diff --git a/pvefw b/pvefw
index 9ba1adf..25c4f8a 100755 (executable)
--- a/pvefw
+++ b/pvefw
@@ -89,6 +89,42 @@ __PACKAGE__->register_method({
         return undef;
     }});
 
+__PACKAGE__->register_method({
+    name => 'enablehostfw',
+    path => 'enablehostfw',
+    method => 'POST',
+    parameters => {
+       additionalProperties => 0,
+       properties => {},
+    },
+    returns => { type => 'null' },
+
+    code => sub {
+       my ($param) = @_;
+
+       PVE::Firewall::enablehostfw();
+
+       return undef;
+    }});
+
+__PACKAGE__->register_method({
+    name => 'disablehostfw',
+    path => 'disablehostfw',
+    method => 'POST',
+    parameters => {
+       additionalProperties => 0,
+       properties => {},
+    },
+    returns => { type => 'null' },
+
+    code => sub {
+       my ($param) = @_;
+
+       PVE::Firewall::disablehostfw();
+
+       return undef;
+    }});
+
 __PACKAGE__->register_method ({
     name => 'compile',
     path => 'compile',
@@ -194,6 +230,8 @@ my $cmddef = {
     clear => [ __PACKAGE__, 'clear', []],
     enabletaprules => [ __PACKAGE__, 'enabletaprules', []],
     disabletaprules => [ __PACKAGE__, 'disabletaprules', []],
+    enablehostfw => [ __PACKAGE__, 'enablehostfw', []],
+    disablehostfw => [ __PACKAGE__, 'disablehostfw', []],
 };
 
 my $cmd = shift;