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

Stefan Priebe s.priebe at profihost.ag
Tue Jul 15 20:55:48 CEST 2014


Am 15.07.2014 20:52, schrieb Alexandre DERUMIER:
>>> 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

OK will check V3 tomorrow.

> 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

This one:
http://pve.proxmox.com/pipermail/pve-devel/2014-July/012178.html

Stefan

> ----- 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