X-Git-Url: https://git.proxmox.com/?p=pve-firewall.git;a=blobdiff_plain;f=src%2FPVE%2FFirewall.pm;h=ea2abe27660de47c66f41dfc57b7e697c26a1db6;hp=fd83ba32438ae3787f61a7884eb83a7fb1ee4dc9;hb=dd009ced9c1831b58701c2a6924dbfef021a4930;hpb=b4deedab3b7a041c0a7b5bd0bd2ac6644e041464 diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm index fd83ba3..ea2abe2 100644 --- a/src/PVE/Firewall.pm +++ b/src/PVE/Firewall.pm @@ -98,9 +98,8 @@ use Data::Dumper; my $nodename = PVE::INotify::nodename(); my $pve_fw_lock_filename = "/var/lock/pvefw.lck"; -my $pve_fw_status_filename = "/var/lib/pve-firewall/pvefw.status"; -my $default_log_level = 'info'; +my $default_log_level = 'nolog'; # avoid logs by default my $log_level_hash = { debug => 7, @@ -158,9 +157,8 @@ my $pve_fw_macros = { { action => 'PARAM', proto => 'tcp', dport => '6277' }, ], 'DHCPfwd' => [ - "Forwarded DHCP traffic (bidirectional)", + "Forwarded DHCP traffic", { action => 'PARAM', proto => 'udp', dport => '67:68', sport => '67:68' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => 'udp', dport => '67:68', sport => '67:68' }, ], 'DNS' => [ "Domain Name System traffic (upd and tcp)", @@ -187,9 +185,8 @@ my $pve_fw_macros = { { action => 'PARAM', proto => 'udp', dport => '1080' }, ], 'GRE' => [ - "Generic Routing Encapsulation tunneling protocol (bidirectional)", + "Generic Routing Encapsulation tunneling protocol", { action => 'PARAM', proto => '47' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => '47' }, ], 'Git' => [ "Git distributed revision control traffic", @@ -224,32 +221,24 @@ my $pve_fw_macros = { { action => 'PARAM', proto => 'tcp', dport => '993' }, ], 'IPIP' => [ - "IPIP capsulation traffic (bidirectional)", + "IPIP capsulation traffic", { action => 'PARAM', proto => '94' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => '94' }, ], 'IPsec' => [ - "IPsec traffic (bidirectional)", + "IPsec traffic", { action => 'PARAM', proto => 'udp', dport => '500', sport => '500' }, { action => 'PARAM', proto => '50' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => 'udp', dport => '500', sport => '500' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => '50' }, ], 'IPsecah' => [ - "IPsec authentication (AH) traffic (bidirectional)", + "IPsec authentication (AH) traffic", { action => 'PARAM', proto => 'udp', dport => '500', sport => '500' }, { action => 'PARAM', proto => '51' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => 'udp', dport => '500', sport => '500' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => '51' }, ], 'IPsecnat' => [ - "IPsec traffic and Nat-Traversal (bidirectional)", + "IPsec traffic and Nat-Traversal", { action => 'PARAM', proto => 'udp', dport => '500' }, { action => 'PARAM', proto => 'udp', dport => '4500' }, { action => 'PARAM', proto => '50' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => 'udp', dport => '500' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => 'udp', dport => '4500' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => '50' }, ], 'IRC' => [ "Internet Relay Chat traffic", @@ -262,7 +251,6 @@ my $pve_fw_macros = { 'L2TP' => [ "Layer 2 Tunneling Protocol traffic", { action => 'PARAM', proto => 'udp', dport => '1701' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => 'udp', dport => '1701' }, ], 'LDAP' => [ "Lightweight Directory Access Protocol traffic", @@ -306,11 +294,6 @@ my $pve_fw_macros = { "Network Time Protocol (ntpd)", { action => 'PARAM', proto => 'udp', dport => '123' }, ], - 'NTPbi' => [ - "Bi-directional NTP (for NTP peers)", - { action => 'PARAM', proto => 'udp', dport => '123' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => 'udp', dport => '123' }, - ], 'OSPF' => [ "OSPF multicast traffic", { action => 'PARAM', proto => '89' }, @@ -335,7 +318,6 @@ my $pve_fw_macros = { 'PPtP' => [ "Point-to-Point Tunneling Protocol", { action => 'PARAM', proto => '47' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => '47' }, { action => 'PARAM', proto => 'tcp', dport => '1723' }, ], 'Ping' => [ @@ -354,10 +336,9 @@ my $pve_fw_macros = { "Microsoft Remote Desktop Protocol traffic", { action => 'PARAM', proto => 'tcp', dport => '3389' }, ], - 'RIPbi' => [ + 'RIP' => [ "Routing Information Protocol (bidirectional)", { action => 'PARAM', proto => 'udp', dport => '520' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => 'udp', dport => '520' }, ], 'RNDC' => [ "BIND remote management protocol", @@ -386,17 +367,6 @@ my $pve_fw_macros = { { action => 'PARAM', proto => 'udp', dport => '1024:65535', sport => '137' }, { action => 'PARAM', proto => 'tcp', dport => '135,139,445' }, ], - 'SMBBI' => [ - "Microsoft SMB traffic (bidirectional)", - { action => 'PARAM', proto => 'udp', dport => '135,445' }, - { action => 'PARAM', proto => 'udp', dport => '137:139' }, - { action => 'PARAM', proto => 'udp', dport => '1024:65535', sport => '137' }, - { action => 'PARAM', proto => 'tcp', dport => '135,139,445' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => 'udp', dport => '135,445' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => 'udp', dport => '137:139' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => 'udp', dport => '1024:65535', sport => '137' }, - { action => 'PARAM', source => 'DEST', dest => 'SOURCE', proto => 'tcp', dport => '135,139,445' }, - ], 'SMBswat' => [ "Samba Web Administration Tool", { action => 'PARAM', proto => 'tcp', dport => '901' }, @@ -468,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", @@ -717,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) = @_; @@ -1001,7 +1020,10 @@ sub verify_rule { raise_param_exc({ type => "unknown rule type '$type'"}); } - # fixme: verify $rule->{iface}? + if ($rule->{iface}) { + eval { PVE::JSONSchema::pve_verify_iface($rule->{iface}); }; + raise_param_exc({ iface => $@ }) if $@; + } if ($rule->{macro}) { my $preferred_name = $pve_fw_preferred_macro_names->{lc($rule->{macro})}; @@ -1453,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); @@ -1561,21 +1583,18 @@ sub ruleset_generate_vm_ipsrules { } sub generate_venet_rules_direction { - my ($ruleset, $cluster_conf, $hostfw_conf, $vmfw_conf, $vmid, $ip, $direction) = @_; - - parse_address_list($ip); # make sure we have a valid $ip list + 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); @@ -1606,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); @@ -1666,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'; @@ -1684,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_action"); # PVE API + ruleset_addrule($ruleset, $chain, "-s $clusternet -p tcp --dport 5900:5999 -j $accept_action"); # PVE VNC Console + ruleset_addrule($ruleset, $chain, "-s $clusternet -p tcp --dport 3128 -j $accept_action"); # SPICE Proxy + ruleset_addrule($ruleset, $chain, "-s $clusternet -p tcp --dport 22 -j $accept_action"); # SSH + + # corosync + my $corosync_rule = "-p udp -m conntrack --ctstate NEW --dport 5404:5405 -j $accept_action" + 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 @@ -1699,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'; @@ -1718,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_action"); # PVE API + ruleset_addrule($ruleset, $chain, "-d $clusternet -p tcp --dport 22 -j $accept_action"); # SSH + + my $corosync_rule = "-p udp -m conntrack --ctstate NEW --dport 5404:5405 -j $accept_action"; + 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); @@ -1767,9 +1802,11 @@ for (my $i = 0; $i < $MAX_NETS; $i++) { } sub parse_fw_rule { - my ($line, $need_iface, $allow_groups) = @_; + my ($line, $allow_iface, $allow_groups) = @_; + + my ($type, $action, $macro, $iface, $source, $dest, $proto, $dport, $sport); - my ($type, $action, $iface, $source, $dest, $proto, $dport, $sport); + chomp $line; # we can add single line comments to the end of the rule my $comment = decode('utf8', $1) if $line =~ s/#\s*(.*?)\s*$//; @@ -1779,22 +1816,11 @@ sub parse_fw_rule { $enable = 0 if $line =~ s/^\|//; - my @data = split(/\s+/, $line); - my $expected_elements = $need_iface ? 8 : 7; - - die "wrong number of rule elements\n" if scalar(@data) > $expected_elements; - - if ($need_iface) { - ($type, $action, $iface, $source, $dest, $proto, $dport, $sport) = @data - } else { - ($type, $action, $source, $dest, $proto, $dport, $sport) = @data; - } - - die "incomplete rule\n" if ! ($type && $action); - - my $macro; - - $type = lc($type); + $line =~ s/^(\S+)\s+(\S+)\s*// || + die "unable to parse rule: $line\n"; + + $type = lc($1); + $action = $2; if ($type eq 'in' || $type eq 'out') { if ($action =~ m/^(ACCEPT|DROP|REJECT)$/) { @@ -1808,32 +1834,52 @@ sub parse_fw_rule { die "unknown action '$action'\n"; } } elsif ($type eq 'group') { - die "wrong number of rule elements\n" if scalar(@data) > 3; die "groups disabled\n" if !$allow_groups; - die "invalid characters in group name\n" if $action !~ m/^${security_group_name_pattern}$/; } else { die "unknown rule type '$type'\n"; } - if ($need_iface) { - $iface = undef if $iface && $iface eq '-'; - } - - $proto = undef if $proto && $proto eq '-'; - pve_fw_verify_protocol_spec($proto) if $proto; + while (length($line)) { + if ($line =~ s/^-i (\S+)\s*//) { + die "parameter -i not allowed\n" if !$allow_iface; + $iface = $1; + PVE::JSONSchema::pve_verify_iface($iface); + next; + } - $source = undef if $source && $source eq '-'; - $dest = undef if $dest && $dest eq '-'; + last if $type eq 'group'; - $dport = undef if $dport && $dport eq '-'; - $sport = undef if $sport && $sport eq '-'; + if ($line =~ s/^-p (\S+)\s*//) { + $proto = $1; + pve_fw_verify_protocol_spec($proto); + next; + } + if ($line =~ s/^-dport (\S+)\s*//) { + $dport = $1; + parse_port_name_number_or_range($dport); + next; + } + if ($line =~ s/^-sport (\S+)\s*//) { + $sport = $1; + parse_port_name_number_or_range($sport); + next; + } + if ($line =~ s/^-source (\S+)\s*//) { + $source = $1; + parse_address_list($source); + next; + } + if ($line =~ s/^-dest (\S+)\s*//) { + $dest = $1; + parse_address_list($dest); + next; + } - parse_port_name_number_or_range($dport) if defined($dport); - parse_port_name_number_or_range($sport) if defined($sport); + last; + } - parse_address_list($source) if $source; - parse_address_list($dest) if $dest; + die "unable to parse rule parameters: $line\n" if length($line); return { type => $type, @@ -2221,7 +2267,7 @@ sub load_vmfw_conf { } my $format_rules = sub { - my ($rules, $need_iface) = @_; + my ($rules, $allow_iface) = @_; my $raw = ''; @@ -2234,14 +2280,16 @@ my $format_rules = sub { } else { $raw .= " " . $rule->{action}; } - $raw .= " " . ($rule->{iface} || '-') if $need_iface; + if ($allow_iface && $rule->{iface}) { + $raw .= " -i $rule->{iface}"; + } if ($rule->{type} ne 'group') { - $raw .= " " . ($rule->{source} || '-'); - $raw .= " " . ($rule->{dest} || '-'); - $raw .= " " . ($rule->{proto} || '-'); - $raw .= " " . ($rule->{dport} || '-'); - $raw .= " " . ($rule->{sport} || '-'); + $raw .= " -source $rule->{source}" if $rule->{source}; + $raw .= " -dest $rule->{dest}" if $rule->{dest}; + $raw .= " -p $rule->{proto}" if $rule->{proto}; + $raw .= " -dport $rule->{dport}" if $rule->{dport}; + $raw .= " -sport $rule->{sport}" if $rule->{sport}; } $raw .= " # " . encode('utf8', $rule->{comment}) @@ -2453,30 +2501,6 @@ sub round_powerof2 { return ++$int; } -sub save_pvefw_status { - my ($status) = @_; - - die "unknown status '$status' - internal error" - if $status !~ m/^(stopped|active)$/; - - mkdir dirname($pve_fw_status_filename); - PVE::Tools::file_set_contents($pve_fw_status_filename, $status); -} - -sub read_pvefw_status { - - my $status = 'unknown'; - - return 'stopped' if ! -f $pve_fw_status_filename; - - eval { - $status = PVE::Tools::file_get_contents($pve_fw_status_filename); - }; - warn $@ if $@; - - return $status; -} - sub load_clusterfw_conf { my ($filename) = @_; @@ -2592,8 +2616,7 @@ sub compile { } - my $ipset_ruleset = {}; - generate_ipset_chains($ipset_ruleset, $cluster_conf); + $cluster_conf->{ipset}->{venet0} = []; my $ruleset = {}; @@ -2610,8 +2633,8 @@ sub compile { ruleset_chain_add_conn_filters($ruleset, "PVEFW-FORWARD", "ACCEPT"); ruleset_create_chain($ruleset, "PVEFW-VENET-OUT"); - ruleset_addrule($ruleset, "PVEFW-FORWARD", "-i venet0 -j PVEFW-VENET-OUT"); - ruleset_addrule($ruleset, "PVEFW-INPUT", "-i venet0 -j PVEFW-VENET-OUT"); + ruleset_addrule($ruleset, "PVEFW-FORWARD", "-i venet0 -m set --match-set PVEFW-venet0 src -j PVEFW-VENET-OUT"); + ruleset_addrule($ruleset, "PVEFW-INPUT", "-i venet0 -m set --match-set PVEFW-venet0 src -j PVEFW-VENET-OUT"); ruleset_create_chain($ruleset, "PVEFW-FWBR-IN"); ruleset_chain_add_input_filters($ruleset, "PVEFW-FWBR-IN", $hostfw_options, $cluster_conf, $loglevel); @@ -2624,7 +2647,7 @@ sub compile { ruleset_create_chain($ruleset, "PVEFW-VENET-IN"); ruleset_chain_add_input_filters($ruleset, "PVEFW-VENET-IN", $hostfw_options, $cluster_conf, $loglevel); - ruleset_addrule($ruleset, "PVEFW-FORWARD", "-o venet0 -j PVEFW-VENET-IN"); + ruleset_addrule($ruleset, "PVEFW-FORWARD", "-o venet0 -m set --match-set PVEFW-venet0 dst -j PVEFW-VENET-IN"); generate_std_chains($ruleset, $hostfw_options); @@ -2632,7 +2655,7 @@ sub compile { enable_host_firewall($ruleset, $hostfw_conf, $cluster_conf) if $hostfw_enable; - ruleset_addrule($ruleset, "PVEFW-OUTPUT", "-o venet0 -j PVEFW-VENET-IN"); + ruleset_addrule($ruleset, "PVEFW-OUTPUT", "-o venet0 -m set --match-set PVEFW-venet0 dst -j PVEFW-VENET-IN"); # generate firewall rules for QEMU VMs foreach my $vmid (keys %{$vmdata->{qemu}}) { @@ -2648,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'); } } @@ -2666,8 +2689,18 @@ sub compile { if ($conf->{ip_address} && $conf->{ip_address}->{value}) { my $ip = $conf->{ip_address}->{value}; $ip =~ s/\s+/,/g; - 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'); + parse_address_list($ip); # make sure we have a valid $ip list + + my @ips = split(',', $ip); + + foreach my $singleip (@ips) { + my $venet0ipset = {}; + $venet0ipset->{cidr} = $singleip; + push @{$cluster_conf->{ipset}->{venet0}}, $venet0ipset; + } + + 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}) { @@ -2677,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'); } } @@ -2689,6 +2722,9 @@ sub compile { ruleset_insertrule($ruleset, "PVEFW-FORWARD", "-m conntrack --ctstate RELATED,ESTABLISHED -j PVEFW-IPS"); } + my $ipset_ruleset = {}; + generate_ipset_chains($ipset_ruleset, $cluster_conf); + return ($ruleset, $ipset_ruleset); } @@ -2958,8 +2994,18 @@ 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 ($start, $verbose) = @_; + my ($verbose) = @_; my $code = sub { @@ -2968,9 +3014,7 @@ sub update { my $enable = $cluster_options->{enable}; - my $status = read_pvefw_status(); - - die "Firewall is disabled - cannot start\n" if !$enable && $start; + die "Firewall is disabled - cannot start\n" if !$enable; if (!$enable) { PVE::Firewall::remove_pvefw_chains(); @@ -2982,18 +3026,10 @@ sub update { my ($ruleset, $ipset_ruleset) = compile($cluster_conf, $hostfw_conf); - if ($start || $status eq 'active') { - - save_pvefw_status('active') if ($status ne 'active'); - - apply_ruleset($ruleset, $hostfw_conf, $ipset_ruleset, $verbose); - } else { - print "Firewall not active (status = $status)\n" if $verbose; - } + apply_ruleset($ruleset, $hostfw_conf, $ipset_ruleset, $verbose); }; run_locked($code); } - 1;