X-Git-Url: https://git.proxmox.com/?p=pve-firewall.git;a=blobdiff_plain;f=src%2FPVE%2FFirewall.pm;h=ef74ca2fae597a882ea30e778c49cee8cfc5ff77;hp=d4e24694e3094b93bf93f7894ab5010dc838f081;hb=15c800003e921cfd627ef0b6213b9ff09fe3d8c8;hpb=95e3594912d19cd55a5bab9fc2351d688749bdd2 diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm index d4e2469..ef74ca2 100644 --- a/src/PVE/Firewall.pm +++ b/src/PVE/Firewall.pm @@ -52,6 +52,14 @@ my $max_alias_name_length = 64; my $max_ipset_name_length = 64; my $max_group_name_length = 18; +my $PROTOCOLS_WITH_PORTS = { + udp => 1, 17 => 1, + udplite => 1, 136 => 1, + tcp => 1, 6 => 1, + dccp => 1, 33 => 1, + sctp => 1, 132 => 1, +}; + PVE::JSONSchema::register_format('IPorCIDR', \&pve_verify_ip_or_cidr); sub pve_verify_ip_or_cidr { my ($cidr, $noerr) = @_; @@ -903,13 +911,17 @@ sub local_network { my $mask; if ($isv6) { $mask = $entry->{prefix}; + next if !$mask; # skip the default route... } else { $mask = $PVE::Network::ipv4_mask_hash_localnet->{$entry->{mask}}; next if !defined($mask); } my $cidr = "$entry->{dest}/$mask"; my $testnet = Net::IP->new($cidr); - if ($testnet->overlaps($testip) == $Net::IP::IP_B_IN_A_OVERLAP) { + my $overlap = $testnet->overlaps($testip); + if ($overlap == $Net::IP::IP_B_IN_A_OVERLAP || + $overlap == $Net::IP::IP_IDENTICAL) + { $__local_network = $cidr; return; } @@ -1502,15 +1514,22 @@ sub verify_rule { if ($rule->{dport}) { eval { parse_port_name_number_or_range($rule->{dport}, 1); }; &$add_error('dport', $@) if $@; + my $proto = $rule->{proto}; &$add_error('proto', "missing property - 'dport' requires this property") - if !$rule->{proto}; + if !$proto; + &$add_error('dport', "protocol '$proto' does not support ports") + if !$PROTOCOLS_WITH_PORTS->{$proto} && + $proto ne 'icmp' && $proto ne 'icmpv6'; # special cases } if ($rule->{sport}) { eval { parse_port_name_number_or_range($rule->{sport}, 0); }; &$add_error('sport', $@) if $@; + my $proto = $rule->{proto}; &$add_error('proto', "missing property - 'sport' requires this property") - if !$rule->{proto}; + if !$proto; + &$add_error('sport', "protocol '$proto' does not support ports") + if !$PROTOCOLS_WITH_PORTS->{$proto}; } if ($rule->{source}) { @@ -1854,6 +1873,8 @@ sub ruleset_generate_cmdstr { die "unknown icmpv6-type '$rule->{dport}'\n" if $rule->{dport} !~ /^\d+$/ && !defined($icmpv6_type_names->{$rule->{dport}}); push @cmd, "-m icmpv6 --icmpv6-type $rule->{dport}"; + } elsif (!$PROTOCOLS_WITH_PORTS->{$proto}) { + die "protocol $proto does not have ports\n"; } else { if ($nbdport > 1) { if ($multiport == 2) { @@ -1868,6 +1889,8 @@ sub ruleset_generate_cmdstr { } if ($rule->{sport}) { + die "protocol $proto does not have ports\n" + if !$PROTOCOLS_WITH_PORTS->{$proto}; if ($nbsport > 1) { push @cmd, "--sports $rule->{sport}" if $multiport != 2; } else {