]> git.proxmox.com Git - pve-firewall.git/blobdiff - src/PVE/Firewall.pm
add standard rules after user rules
[pve-firewall.git] / src / PVE / Firewall.pm
index dae867d8fd23fb9d4f6177b20e4bd5eb53ec2df4..82c5c95dbf5f4165d56cb32be0be4434175c3282 100644 (file)
@@ -99,7 +99,7 @@ my $nodename = PVE::INotify::nodename();
 
 my $pve_fw_lock_filename = "/var/lock/pvefw.lck";
 
-my $default_log_level = 'info';
+my $default_log_level = 'nolog'; # avoid logs by default
 
 my $log_level_hash = {
     debug => 7,
@@ -438,8 +438,8 @@ my $pve_fw_macros = {
        { action => 'PARAM', proto => 'icmp', dport => 'echo-request' },
     ],
     'VNC' => [
-       "VNC traffic for VNC display's 0 - 9",
-       { action => 'PARAM', proto => 'tcp', dport => '5900:5909' },
+       "VNC traffic for VNC display's 0 - 99",
+       { action => 'PARAM', proto => 'tcp', dport => '5900:5999' },
     ],
     'VNCL' => [
        "VNC traffic from Vncservers to Vncviewers in listen mode",
@@ -687,6 +687,55 @@ sub get_etc_protocols {
     return $etc_protocols;
 }
 
+my $ipv4_mask_hash_clusternet = {
+    '255.255.0.0' => 16,
+    '255.255.128.0' => 17,
+    '255.255.192.0' => 18,
+    '255.255.224.0' => 19,
+    '255.255.240.0' => 20,
+    '255.255.248.0' => 21,
+    '255.255.252.0' => 22,
+    '255.255.254.0' => 23,
+    '255.255.255.0' => 24,
+    '255.255.255.128' => 25,
+    '255.255.255.192' => 26,
+    '255.255.255.224' => 27,
+    '255.255.255.240' => 28,
+    '255.255.255.248' => 29,
+    '255.255.255.252' => 30,
+};
+
+my $cluster_network;
+
+sub get_cluster_network {
+
+    return $cluster_network if defined($cluster_network);
+
+    eval {
+       my $nodename = PVE::INotify::nodename();
+
+       my $ip = PVE::Cluster::remote_node_ip($nodename);
+
+       my $testip = Net::IP->new($ip);
+   
+       my $routes = PVE::ProcFSTools::read_proc_net_route();
+       foreach my $entry (@$routes) {
+           my $mask = $ipv4_mask_hash_clusternet->{$entry->{mask}};
+           next if !defined($mask);
+           return if $mask eq '0.0.0.0';
+           my $cidr = "$entry->{dest}/$mask";
+           my $testnet = Net::IP->new($cidr);
+           if ($testnet->overlaps($testip)) {
+               $cluster_network = $cidr;
+               return;
+           }
+       }
+    };
+    warn $@ if $@;
+
+    return $cluster_network;
+}
+
 sub parse_address_list {
     my ($str) = @_;
 
@@ -1426,7 +1475,7 @@ sub ruleset_chain_add_input_filters {
 }
 
 sub ruleset_create_vm_chain {
-    my ($ruleset, $chain, $options, $host_options, $macaddr, $direction) = @_;
+    my ($ruleset, $chain, $options, $macaddr, $direction) = @_;
 
     ruleset_create_chain($ruleset, $chain);
     my $accept = generate_nfqueue($options);
@@ -1534,19 +1583,18 @@ sub ruleset_generate_vm_ipsrules {
 }
 
 sub generate_venet_rules_direction {
-    my ($ruleset, $cluster_conf, $hostfw_conf, $vmfw_conf, $vmid, $ip, $direction) = @_;
+    my ($ruleset, $cluster_conf, $vmfw_conf, $vmid, $ip, $direction) = @_;
 
     my $lc_direction = lc($direction);
 
     my $rules = $vmfw_conf->{rules};
 
     my $options = $vmfw_conf->{options};
-    my $hostfw_options = $vmfw_conf->{options};
     my $loglevel = get_option_log_level($options, "log_level_${lc_direction}");
 
     my $chain = "venet0-$vmid-$direction";
 
-    ruleset_create_vm_chain($ruleset, $chain, $options, $hostfw_options, undef, $direction);
+    ruleset_create_vm_chain($ruleset, $chain, $options, undef, $direction);
 
     ruleset_generate_vm_rules($ruleset, $rules, $cluster_conf, $chain, 'venet', $direction);
 
@@ -1577,19 +1625,18 @@ sub generate_venet_rules_direction {
 }
 
 sub generate_tap_rules_direction {
-    my ($ruleset, $cluster_conf, $hostfw_conf, $iface, $netid, $macaddr, $vmfw_conf, $vmid, $direction) = @_;
+    my ($ruleset, $cluster_conf, $iface, $netid, $macaddr, $vmfw_conf, $vmid, $direction) = @_;
 
     my $lc_direction = lc($direction);
 
     my $rules = $vmfw_conf->{rules};
 
     my $options = $vmfw_conf->{options};
-    my $hostfw_options = $hostfw_conf->{options};
     my $loglevel = get_option_log_level($options, "log_level_${lc_direction}");
 
     my $tapchain = "$iface-$direction";
 
-    ruleset_create_vm_chain($ruleset, $tapchain, $options, $hostfw_options, $macaddr, $direction);
+    ruleset_create_vm_chain($ruleset, $tapchain, $options, $macaddr, $direction);
 
     ruleset_generate_vm_rules($ruleset, $rules, $cluster_conf, $tapchain, $netid, $direction, $options);
 
@@ -1637,10 +1684,6 @@ sub enable_host_firewall {
     ruleset_chain_add_conn_filters($ruleset, $chain, 'ACCEPT');
     ruleset_chain_add_input_filters($ruleset, $chain, $options, $cluster_conf, $loglevel);
 
-    ruleset_addrule($ruleset, $chain, "-m addrtype --dst-type MULTICAST -j ACCEPT");
-    ruleset_addrule($ruleset, $chain, "-p udp -m conntrack --ctstate NEW --dport 5404:5405 -j ACCEPT");
-    ruleset_addrule($ruleset, $chain, "-p udp -m udp --dport 9000 -j ACCEPT");  #corosync
-
     # we use RETURN because we need to check also tap rules
     my $accept_action = 'RETURN';
 
@@ -1655,6 +1698,21 @@ sub enable_host_firewall {
        }
        delete $rule->{iface_in};
     }
+   
+    my $clusternet = get_cluster_network();
+
+    # allow standard traffic on cluster network
+    if ($clusternet) {
+       ruleset_addrule($ruleset, $chain, "-s $clusternet -p tcp --dport 8006 -j ACCEPT");  # PVE API
+       ruleset_addrule($ruleset, $chain, "-s $clusternet -p tcp --dport 5900:5999 -j ACCEPT");  # PVE VNC Console 
+       ruleset_addrule($ruleset, $chain, "-s $clusternet -p tcp --dport 3128 -j ACCEPT");  # SPICE Proxy
+       ruleset_addrule($ruleset, $chain, "-s $clusternet -p tcp --dport 22 -j ACCEPT");  # SSH
+       # corosync
+       my $corosync_rule = "-p udp -m conntrack --ctstate NEW --dport 5404:5405 -j ACCEPT"
+       ruleset_addrule($ruleset, $chain, "-s $clusternet -d $clusternet $corosync_rule");
+       ruleset_addrule($ruleset, $chain, "-s $clusternet -m addrtype --dst-type MULTICAST $corosync_rule");
+    }
 
     # implement input policy
     my $policy = $cluster_options->{policy_in} || 'DROP'; # allow nothing by default
@@ -1670,10 +1728,6 @@ sub enable_host_firewall {
 
     ruleset_chain_add_conn_filters($ruleset, $chain, 'ACCEPT');
 
-    ruleset_addrule($ruleset, $chain, "-m addrtype --dst-type MULTICAST -j ACCEPT");
-    ruleset_addrule($ruleset, $chain, "-p udp -m conntrack --ctstate NEW --dport 5404:5405 -j ACCEPT");
-    ruleset_addrule($ruleset, $chain, "-p udp -m udp --dport 9000 -j ACCEPT"); #corosync
-
     # we use RETURN because we may want to check other thigs later
     $accept_action = 'RETURN';
 
@@ -1689,6 +1743,16 @@ sub enable_host_firewall {
        delete $rule->{iface_out};
     }
 
+    # allow standard traffic on cluster network
+    if ($clusternet) {
+       ruleset_addrule($ruleset, $chain, "-d $clusternet -p tcp --dport 8006 -j ACCEPT");  # PVE API
+       ruleset_addrule($ruleset, $chain, "-d $clusternet -p tcp --dport 22 -j ACCEPT");  # SSH
+       my $corosync_rule = "-p udp -m conntrack --ctstate NEW --dport 5404:5405 -j ACCEPT";
+       ruleset_addrule($ruleset, $chain, "-s $clusternet -d $clusternet $corosync_rule");
+       ruleset_addrule($ruleset, $chain, "-s $clusternet -m addrtype --dst-type MULTICAST $corosync_rule");
+    }
+
     # implement output policy
     $policy = $cluster_options->{policy_out} || 'ACCEPT'; # allow everything by default
     ruleset_add_chain_policy($ruleset, $chain, 0, $policy, $loglevel, $accept_action);
@@ -2607,9 +2671,9 @@ sub compile {
            my $iface = "tap${vmid}i$1";
 
            my $macaddr = $net->{macaddr};
-           generate_tap_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $iface, $netid, $macaddr,
+           generate_tap_rules_direction($ruleset, $cluster_conf, $iface, $netid, $macaddr,
                                         $vmfw_conf, $vmid, 'IN');
-           generate_tap_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $iface, $netid, $macaddr,
+           generate_tap_rules_direction($ruleset, $cluster_conf, $iface, $netid, $macaddr,
                                         $vmfw_conf, $vmid, 'OUT');
        }
     }
@@ -2635,8 +2699,8 @@ sub compile {
                push @{$cluster_conf->{ipset}->{venet0}}, $venet0ipset;
            }
 
-           generate_venet_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $vmfw_conf, $vmid, $ip, 'IN');
-           generate_venet_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $vmfw_conf, $vmid, $ip, 'OUT');
+           generate_venet_rules_direction($ruleset, $cluster_conf, $vmfw_conf, $vmid, $ip, 'IN');
+           generate_venet_rules_direction($ruleset, $cluster_conf, $vmfw_conf, $vmid, $ip, 'OUT');
        }
 
        if ($conf->{netif} && $conf->{netif}->{value}) {
@@ -2646,9 +2710,9 @@ sub compile {
 
                my $macaddr = $d->{mac};
                my $iface = $d->{host_ifname};
-               generate_tap_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $iface, $netid, $macaddr,
+               generate_tap_rules_direction($ruleset, $cluster_conf, $iface, $netid, $macaddr,
                                             $vmfw_conf, $vmid, 'IN');
-               generate_tap_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $iface, $netid, $macaddr,
+               generate_tap_rules_direction($ruleset, $cluster_conf, $iface, $netid, $macaddr,
                                             $vmfw_conf, $vmid, 'OUT');
            }
        }
@@ -2930,6 +2994,16 @@ sub remove_pvefw_chains {
     iptables_restore_cmdlist($cmdlist);
 }
 
+sub init {
+    my $cluster_conf = load_clusterfw_conf();
+    my $cluster_options = $cluster_conf->{options};
+    my $enable = $cluster_options->{enable};
+
+    return if !$enable;
+
+    # load required modules here
+}
+
 sub update {
     my ($verbose) = @_;
 
@@ -2958,5 +3032,4 @@ sub update {
     run_locked($code);
 }
 
-
 1;