X-Git-Url: https://git.proxmox.com/?p=pve-firewall.git;a=blobdiff_plain;f=src%2FPVE%2FFirewall.pm;h=6ac303831a62f630d437ef0e0508decd2b72f5ac;hp=59052da397a3090c2fe2206e519b729739d0cee6;hb=33efd363ab32d3f8f6a9c49e481cb62a8da40b5d;hpb=b409c8a83465c2d7e9550359ab5f4004744b1055 diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm index 59052da..6ac3038 100644 --- a/src/PVE/Firewall.pm +++ b/src/PVE/Firewall.pm @@ -2114,7 +2114,7 @@ sub ruleset_add_chain_policy { } elsif ($policy eq 'REJECT') { ruleset_addrule($ruleset, $chain, "", "-j PVEFW-Reject"); - ruleset_addrule($ruleset, $chain, "", "-g PVEFW-reject", $loglevel, "policy $policy:", $vmid); + ruleset_addrule($ruleset, $chain, "", "-g PVEFW-reject", $loglevel, "policy $policy: ", $vmid); } else { # should not happen die "internal error: unknown policy '$policy'"; @@ -3687,6 +3687,7 @@ sub compile_ebtables_filter { my $conf = $vmdata->{qemu}->{$vmid}; my $vmfw_conf = $vmfw_configs->{$vmid}; return if !$vmfw_conf; + my $ipsets = $vmfw_conf->{ipset}; foreach my $netid (sort keys %$conf) { next if $netid !~ m/^net(\d+)$/; @@ -3694,9 +3695,15 @@ sub compile_ebtables_filter { next if !$net->{firewall}; my $iface = "tap${vmid}i$1"; my $macaddr = $net->{macaddr}; - - generate_tap_layer2filter($ruleset, $iface, $macaddr, $vmfw_conf, $vmid); - + my $arpfilter = []; + if (defined(my $ipset = $ipsets->{"ipfilter-$netid"})) { + foreach my $ipaddr (@$ipset) { + my($ip, $version) = parse_ip_or_cidr($ipaddr->{cidr}); + next if !$ip || ($version && $version != 4); + push(@$arpfilter, $ip); + } + } + generate_tap_layer2filter($ruleset, $iface, $macaddr, $vmfw_conf, $vmid, $arpfilter); } }; warn $@ if $@; # just to be sure - should not happen @@ -3709,6 +3716,7 @@ sub compile_ebtables_filter { my $vmfw_conf = $vmfw_configs->{$vmid}; return if !$vmfw_conf || !$vmfw_conf->{options}->{enable}; + my $ipsets = $vmfw_conf->{ipset}; foreach my $netid (sort keys %$conf) { next if $netid !~ m/^net(\d+)$/; @@ -3716,7 +3724,16 @@ sub compile_ebtables_filter { next if !$net->{firewall}; my $iface = "veth${vmid}i$1"; my $macaddr = $net->{hwaddr}; - generate_tap_layer2filter($ruleset, $iface, $macaddr, $vmfw_conf, $vmid); + my $arpfilter = []; + if (defined(my $ipset = $ipsets->{"ipfilter-$netid"})) { + foreach my $ipaddr (@$ipset) { + my($ip, $version) = parse_ip_or_cidr($ipaddr->{cidr}); + next if !$ip || ($version && $version != 4); + push(@$arpfilter, $ip); + } + } + push(@$arpfilter, $net->{ip}) if $net->{ip} && $vmfw_conf->{options}->{ipfilter}; + generate_tap_layer2filter($ruleset, $iface, $macaddr, $vmfw_conf, $vmid, $arpfilter); } }; warn $@ if $@; # just to be sure - should not happen @@ -3726,7 +3743,7 @@ sub compile_ebtables_filter { } sub generate_tap_layer2filter { - my ($ruleset, $iface, $macaddr, $vmfw_conf, $vmid) = @_; + my ($ruleset, $iface, $macaddr, $vmfw_conf, $vmid, $arpfilter) = @_; my $options = $vmfw_conf->{options}; my $tapchain = $iface."-OUT"; @@ -3741,15 +3758,30 @@ sub generate_tap_layer2filter { ruleset_addrule($ruleset, $tapchain, "-s ! $macaddr", '-j DROP'); } + if (@$arpfilter){ + my $arpchain = $tapchain."-ARP"; + ruleset_addrule($ruleset, $tapchain, "-p ARP", "-j $arpchain"); + ruleset_create_chain($ruleset, $arpchain); + + foreach my $ip (@{$arpfilter}) { + ruleset_addrule($ruleset, $arpchain, "-p ARP --arp-ip-src $ip", '-j RETURN'); + } + ruleset_addrule($ruleset, $arpchain, '', '-j DROP'); + } + if (defined($options->{layer2_protocols})){ + my $protochain = $tapchain."-PROTO"; + ruleset_addrule($ruleset, $tapchain, '', "-j $protochain"); + ruleset_create_chain($ruleset, $protochain); + foreach my $proto (split(/,/, $options->{layer2_protocols})) { - ruleset_addrule($ruleset, $tapchain, "-p $proto", '-j ACCEPT'); + ruleset_addrule($ruleset, $protochain, "-p $proto", '-j RETURN'); } - ruleset_addrule($ruleset, $tapchain, '', "-j DROP"); - } else { - ruleset_addrule($ruleset, $tapchain, '', '-j ACCEPT'); + ruleset_addrule($ruleset, $protochain, '', '-j DROP'); } + ruleset_addrule($ruleset, $tapchain, '', '-j ACCEPT'); + ruleset_addrule($ruleset, 'PVEFW-FWBR-OUT', "-i $iface", "-j $tapchain"); }