[pve-devel] [PATCH 1/2] compile ebtables rules

Alexandre DERUMIER aderumier at odiso.com
Tue Jul 15 20:52:13 CEST 2014


>>Please also look in my other mail. It still contains a bug if no layer2 
filter is set. 

I have fixed it in my V3, I finally do it like this

macfilter:
-A tap110i0-OUT -s ! 36:97:15:91:19:3c -j DROP

protocol filter:
-A tap110i0-OUT -p ARP -j ACCEPT
-A tap110i0-OUT -p ... -j ACCEPT
-A tap110i0-OUT -p ... -j ACCEPT
-A tap110i0-OUT -j DROP

in all cases:
-A tap110i0-OUT -j ACCEPT





about your mac address digest patch v3, is it this one ? (don't see any V3 reference in the mailing)
http://pve.proxmox.com/pipermail/pve-devel/2014-July/012173.html 



	

----- Mail original -----

De: "Stefan Priebe" <s.priebe at profihost.ag> 
À: "Alexandre DERUMIER" <aderumier at odiso.com> 
Cc: pve-devel at pve.proxmox.com 
Envoyé: Mardi 15 Juillet 2014 20:45:14 
Objet: Re: [pve-devel] [PATCH 1/2] compile ebtables rules 

Am 15.07.2014 20:43, schrieb Alexandre DERUMIER: 
>>> this one has the old mac patch included. Please use V3. 
> Oh, I have missed your v3 patch in all theses mail, I'll send a new version tomorrow morning. 

Please also look in my other mail. It still contains a bug if no layer2 
filter is set. 

Stefan 


> ----- Mail original ----- 
> 
> De: "Stefan Priebe" <s.priebe at profihost.ag> 
> À: "Alexandre Derumier" <aderumier at odiso.com>, pve-devel at pve.proxmox.com 
> Envoyé: Mardi 15 Juillet 2014 19:48:19 
> Objet: Re: [pve-devel] [PATCH 1/2] compile ebtables rules 
> 
> this one has the old mac patch included. Please use V3. 
> 
> Am 15.07.2014 19:45, schrieb Alexandre Derumier: 
>> -A FORWARD -j PVEFW-FORWARD 
>> -A PVEFW-FORWARD -p IPv4 -j ACCEPT #filter mac in iptables for ipv4, so we can speedup rules with conntrack established 
>> -A PVEFW-FORWARD -p IPv6 -j ACCEPT 
>> -A PVEFW-FORWARD -o fwln+ -j PVEFW-FWBR-OUT 
>> -A PVEFW-FWBR-OUT -i tap110i0 -j tap110i0-OUT 
>> -A tap110i0-OUT -s ! 36:97:15:91:19:3c -j DROP 
>> -A tap110i0-OUT -p ARP -j ACCEPT 
>> -A tap110i0-OUT -j DROP 
>> -A tap110i0-OUT -j ACCEPT 
>> -A PVEFW-FWBR-OUT -i veth130.1 -j veth130.1-OUT 
>> -A veth130.1-OUT -s ! 36:95:a9:ae:f5:ec -j DROP 
>> -A veth130.1-OUT -j ACCEPT 
>> 
>> Signed-off-by: Alexandre Derumier <aderumier at odiso.com> 
>> --- 
>> debian/example/100.fw | 3 ++ 
>> src/PVE/Firewall.pm | 102 ++++++++++++++++++++++++++++++++++++++++++++++++- 
>> src/pve-firewall | 4 +- 
>> 3 files changed, 105 insertions(+), 4 deletions(-) 
>> 
>> diff --git a/debian/example/100.fw b/debian/example/100.fw 
>> index 7a8da48..0388dde 100644 
>> --- a/debian/example/100.fw 
>> +++ b/debian/example/100.fw 
>> @@ -9,6 +9,9 @@ enable: 1 
>> # disable/enable MAC address filter 
>> macfilter: 0 
>> 
>> +# allow only layer2 specific protocols 
>> +layer2filter_protocols: ARP,802_1Q,IPX,NetBEUI,PPP 
>> + 
>> # default policy 
>> policy_in: DROP 
>> policy_out: REJECT 
>> diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm 
>> index abf122b..48d9b8c 100644 
>> --- a/src/PVE/Firewall.pm 
>> +++ b/src/PVE/Firewall.pm 
>> @@ -2245,6 +2245,9 @@ sub parse_vmfw_option { 
>> } elsif ($line =~ m/^(policy_(in|out)):\s*(ACCEPT|DROP|REJECT)\s*$/i) { 
>> $opt = lc($1); 
>> $value = uc($3); 
>> + } elsif ($line =~ m/^(layer2filter_protocols):\s*(((ARP|802_1Q|IPX|NetBEUI|PPP)[,]?)+)\s*$/i) { 
>> + $opt = lc($1); 
>> + $value = $2; 
>> } elsif ($line =~ m/^(ips_queues):\s*((\d+)(:(\d+))?)\s*$/i) { 
>> $opt = lc($1); 
>> $value = $2; 
>> @@ -3000,8 +3003,9 @@ sub compile { 
>> 
>> my ($ruleset, $ipset_ruleset) = compile_iptables_filter($cluster_conf, $hostfw_conf, $vmfw_configs, $vmdata, 4, $verbose); 
>> my ($rulesetv6) = compile_iptables_filter($cluster_conf, $hostfw_conf, $vmfw_configs, $vmdata, 6, $verbose); 
>> + my ($ebtables_ruleset) = compile_ebtables_filter($cluster_conf, $hostfw_conf, $vmfw_configs, $vmdata, $verbose); 
>> 
>> - return ($ruleset, $ipset_ruleset, $rulesetv6); 
>> + return ($ruleset, $ipset_ruleset, $rulesetv6, $ebtables_ruleset); 
>> } 
>> 
>> sub compile_iptables_filter { 
>> @@ -3150,6 +3154,100 @@ sub compile_iptables_filter { 
>> return ($ruleset, $ipset_ruleset); 
>> } 
>> 
>> +sub compile_ebtables_filter { 
>> + my ($cluster_conf, $hostfw_conf, $vmfw_configs, $vmdata, $verbose) = @_; 
>> + 
>> + return ({}, {}) if !$cluster_conf->{options}->{enable}; 
>> + 
>> + my $ruleset = {}; 
>> + 
>> + ruleset_create_chain($ruleset, "PVEFW-FORWARD"); 
>> + 
>> + 
>> + ruleset_create_chain($ruleset, "PVEFW-FWBR-OUT"); 
>> + #for ipv4 and ipv6, check macaddress in iptables, so we use conntrack 'ESTABLISHED', to speedup rules 
>> + ruleset_addrule($ruleset, "PVEFW-FORWARD", "-p IPv4 -j ACCEPT"); 
>> + ruleset_addrule($ruleset, "PVEFW-FORWARD", "-p IPv6 -j ACCEPT"); 
>> + ruleset_addrule($ruleset, "PVEFW-FORWARD", "-o fwln+ -j PVEFW-FWBR-OUT"); 
>> + 
>> + # generate firewall rules for QEMU VMs 
>> + foreach my $vmid (keys %{$vmdata->{qemu}}) { 
>> + eval { 
>> + my $conf = $vmdata->{qemu}->{$vmid}; 
>> + my $vmfw_conf = $vmfw_configs->{$vmid}; 
>> + return if !$vmfw_conf; 
>> + 
>> + foreach my $netid (keys %$conf) { 
>> + next if $netid !~ m/^net(\d+)$/; 
>> + my $net = PVE::QemuServer::parse_net($conf->{$netid}); 
>> + next if !$net->{firewall}; 
>> + my $iface = "tap${vmid}i$1"; 
>> + my $macaddr = $net->{macaddr}; 
>> + 
>> + # ebtables remove preceeding zero so we need todo it too (but only the first) 
>> + $macaddr =~ s/^0//; 
>> + 
>> + generate_tap_layer2filter($ruleset, $iface, $macaddr, $vmfw_conf, $vmid); 
>> + 
>> + } 
>> + }; 
>> + warn $@ if $@; # just to be sure - should not happen 
>> + } 
>> + 
>> + # generate firewall rules for OpenVZ containers 
>> + foreach my $vmid (keys %{$vmdata->{openvz}}) { 
>> + eval { 
>> + my $conf = $vmdata->{openvz}->{$vmid}; 
>> + 
>> + my $vmfw_conf = $vmfw_configs->{$vmid}; 
>> + return if !$vmfw_conf; 
>> + 
>> + if ($conf->{netif} && $conf->{netif}->{value}) { 
>> + my $netif = PVE::OpenVZ::parse_netif($conf->{netif}->{value}); 
>> + foreach my $netid (keys %$netif) { 
>> + my $d = $netif->{$netid}; 
>> + my $bridge = $d->{bridge}; 
>> + next if !$bridge || $bridge !~ m/^vmbr\d+(v(\d+))?f$/; # firewall enabled ? 
>> + my $macaddr = $d->{mac}; 
>> + my $iface = $d->{host_ifname}; 
>> + 
>> + # ebtables remove preceeding zero so we need todo it too (but only the first) 
>> + $macaddr =~ s/^0//; 
>> + 
>> + generate_tap_layer2filter($ruleset, $iface, $macaddr, $vmfw_conf, $vmid); 
>> + } 
>> + } 
>> + }; 
>> + warn $@ if $@; # just to be sure - should not happen 
>> + } 
>> + 
>> + return $ruleset; 
>> +} 
>> + 
>> +sub generate_tap_layer2filter { 
>> + my ($ruleset, $iface, $macaddr, $vmfw_conf, $vmid) = @_; 
>> + my $options = $vmfw_conf->{options}; 
>> + 
>> + my $tapchain = $iface."-OUT"; 
>> + $macaddr = lc($macaddr); 
>> + 
>> + ruleset_create_chain($ruleset, $tapchain); 
>> + 
>> + if (defined($macaddr) && !(defined($options->{macfilter}) && $options->{macfilter} == 0)) { 
>> + ruleset_addrule($ruleset, $tapchain, "-s ! $macaddr -j DROP"); 
>> + } 
>> + 
>> + if (defined($options->{layer2filter_protocols})){ 
>> + foreach my $proto (split(/,/, $options->{layer2filter_protocols})) { 
>> + ruleset_addrule($ruleset, $tapchain, "-p $proto -j ACCEPT"); 
>> + } 
>> + ruleset_addrule($ruleset, $tapchain, "-j DROP"); 
>> + } 
>> + 
>> + ruleset_addrule($ruleset, $tapchain, "-j ACCEPT"); 
>> + ruleset_addrule($ruleset, "PVEFW-FWBR-OUT","-i $iface -j $tapchain"); 
>> +} 
>> + 
>> sub get_ruleset_status { 
>> my ($ruleset, $active_chains, $digest_fn, $verbose) = @_; 
>> 
>> @@ -3475,7 +3573,7 @@ sub update { 
>> 
>> my $hostfw_conf = load_hostfw_conf(); 
>> 
>> - my ($ruleset, $ipset_ruleset, $rulesetv6) = compile($cluster_conf, $hostfw_conf); 
>> + my ($ruleset, $ipset_ruleset, $rulesetv6, $ebtables_ruleset) = compile($cluster_conf, $hostfw_conf); 
>> 
>> apply_ruleset($ruleset, $hostfw_conf, $ipset_ruleset, $rulesetv6); 
>> }; 
>> diff --git a/src/pve-firewall b/src/pve-firewall 
>> index 6e5eb16..8e4c68d 100755 
>> --- a/src/pve-firewall 
>> +++ b/src/pve-firewall 
>> @@ -344,7 +344,7 @@ __PACKAGE__->register_method ({ 
>> 
>> if ($status eq 'running') { 
>> 
>> - my ($ruleset, $ipset_ruleset, $rulesetv6) = PVE::Firewall::compile($cluster_conf, undef, undef, $verbose); 
>> + my ($ruleset, $ipset_ruleset, $rulesetv6, $ebtables_ruleset) = PVE::Firewall::compile($cluster_conf, undef, undef, $verbose); 
>> 
>> $verbose = 0; # do not show iptables details 
>> my (undef, undef, $ipset_changes) = PVE::Firewall::get_ipset_cmdlist($ipset_ruleset, $verbose); 
>> @@ -381,7 +381,7 @@ __PACKAGE__->register_method ({ 
>> my $verbose = 1; 
>> 
>> my $cluster_conf = PVE::Firewall::load_clusterfw_conf(undef, $verbose); 
>> - my ($ruleset, $ipset_ruleset, $rulesetv6) = PVE::Firewall::compile($cluster_conf, undef, undef, $verbose); 
>> + my ($ruleset, $ipset_ruleset, $rulesetv6, $ebtables_ruleset) = PVE::Firewall::compile($cluster_conf, undef, undef, $verbose); 
>> 
>> my (undef, undef, $ipset_changes) = PVE::Firewall::get_ipset_cmdlist($ipset_ruleset, $verbose); 
>> my (undef, $ruleset_changes) = PVE::Firewall::get_ruleset_cmdlist($ruleset, $verbose); 
>> 


More information about the pve-devel mailing list