X-Git-Url: https://git.proxmox.com/?p=pve-firewall.git;a=blobdiff_plain;f=src%2FPVE%2FFirewall.pm;h=44068249992b7a78b9b6acbb31ce3d1a0ea575f9;hp=8594c9e0e47cb583bea125dd02df385a0b5af052;hb=e7b3571121372860f43ab905757c1b7e78bad19d;hpb=e5d76bdebeda050970593357bfb172a606632e64 diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm index 8594c9e..4406824 100644 --- a/src/PVE/Firewall.pm +++ b/src/PVE/Firewall.pm @@ -635,6 +635,25 @@ sub parse_port_name_number_or_range { return ($nbports); } +# helper function for API +sub cleanup_fw_rule { + my ($rule, $digest, $pos) = @_; + + my $r = {}; + + foreach my $k (keys %$rule) { + next if $k eq 'nbdport'; + next if $k eq 'nbsport'; + my $v = $rule->{$k}; + next if !defined($v); + $r->{$k} = $v; + $r->{digest} = $digest; + $r->{pos} = $pos; + } + + return $r; +} + my $bridge_firewall_enabled = 0; sub enable_bridge_firewall { @@ -1154,7 +1173,7 @@ sub generate_group_rules { die "no such security group '$group'\n" if !$groups_conf->{$group}; - my $rules = $groups_conf->{$group}->{rules}; + my $rules = $groups_conf->{rules}->{$group}; my $chain = "GROUP-${group}-IN"; @@ -1381,7 +1400,11 @@ sub parse_vm_fw_rules { my $section; + my $digest = Digest::SHA->new('sha1'); + while (defined(my $line = <$fh>)) { + $digest->add($line); + next if $line =~ m/^#/; next if $line =~ m/^\s*$/; @@ -1419,6 +1442,8 @@ sub parse_vm_fw_rules { push @{$res->{$section}}, @$rules; } + $res->{digest} = $digest->b64digest; + return $res; } @@ -1429,7 +1454,11 @@ sub parse_host_fw_rules { my $section; + my $digest = Digest::SHA->new('sha1'); + while (defined(my $line = <$fh>)) { + $digest->add($line); + next if $line =~ m/^#/; next if $line =~ m/^\s*$/; @@ -1467,6 +1496,8 @@ sub parse_host_fw_rules { push @{$res->{$section}}, @$rules; } + $res->{digest} = $digest->b64digest; + return $res; } @@ -1476,9 +1507,13 @@ sub parse_group_fw_rules { my $section; my $group; - my $res = { rules => [] }; + my $res = { rules => {} }; + + my $digest = Digest::SHA->new('sha1'); while (defined(my $line = <$fh>)) { + $digest->add($line); + next if $line =~ m/^#/; next if $line =~ m/^\s*$/; @@ -1502,9 +1537,11 @@ sub parse_group_fw_rules { next; } - push @{$res->{$group}->{$section}}, @$rules; + push @{$res->{$section}->{$group}}, @$rules; } + $res->{digest} = $digest->b64digest; + return $res; } @@ -1556,16 +1593,27 @@ sub read_local_vm_config { return $vmdata; }; +sub load_vmfw_conf { + my ($vmid) = @_; + + my $vmfw_conf = {}; + + my $filename = "/etc/pve/firewall/$vmid.fw"; + if (my $fh = IO::File->new($filename, O_RDONLY)) { + $vmfw_conf = parse_vm_fw_rules($filename, $fh); + } + + return $vmfw_conf; +} + sub read_vm_firewall_configs { my ($vmdata) = @_; my $vmfw_configs = {}; 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; - - $vmfw_configs->{$vmid} = parse_vm_fw_rules($filename, $fh); + my $vmfw_conf = load_vmfw_conf($vmid); + next if !$vmfw_conf->{options}; # skip if file does not exists + $vmfw_configs->{$vmid} = $vmfw_conf; } return $vmfw_configs; @@ -1681,6 +1729,16 @@ sub load_security_groups { return $groups_conf; } +sub load_hostfw_conf { + + my $hostfw_conf = {}; + my $filename = "/etc/pve/local/host.fw"; + if (my $fh = IO::File->new($filename, O_RDONLY)) { + $hostfw_conf = parse_host_fw_rules($filename, $fh); + } + return $hostfw_conf; +} + sub compile { my $vmdata = read_local_vm_config(); my $vmfw_configs = read_vm_firewall_configs($vmdata); @@ -1696,14 +1754,8 @@ sub compile { ruleset_create_chain($ruleset, "PVEFW-FORWARD"); - my $hostfw_options = {}; - my $hostfw_conf = {}; - - $filename = "/etc/pve/local/host.fw"; - if (my $fh = IO::File->new($filename, O_RDONLY)) { - $hostfw_conf = parse_host_fw_rules($filename, $fh); - $hostfw_options = $hostfw_conf->{options}; - } + my $hostfw_conf = load_hostfw_conf(); + my $hostfw_options = $hostfw_conf->{options} || {}; generate_std_chains($ruleset, $hostfw_options);