From: Alexandre Derumier <aderumier@odiso.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH V2 pve-firewall] add cluster ebtables_dst_macfilter option.
Date: Fri, 10 Sep 2021 17:34:29 +0200 [thread overview]
Message-ID: <20210910153430.4045276-1-aderumier@odiso.com> (raw)
This new option allow filtering of destination macs for ingress traffic.
This is a protection from bad/hosting networks (like hetzner) flooding
traffic with non-hosted mac.
To be fast, one rule, this use the "--among-dst mac,mac,mac,mac," syntax.
broadcast mac ff:ff:ff:ff:ff:ff is always allowed
currently, ebtables-restore segfault if too many are defined
https://www.spinics.net/lists/netfilter/msg55995.html
So, I'm using "--among-dst-file", loading macs from an external file.
Note that "ebtables-save" still show the syntax with "--among-dst mac,mac,mac,"
(with a comma at the end), so I compile the full mac list with --among-dst to
compare, and if update is needed, I'm writing the dst file in
/var/lib/pve-firewall/chain-macfilter, and replace among-dst syntax by among-dst-file
Changelog v2:
- as we use one rule for performance, add all vms/ct macaddress when vm firewall is enabled.
(even if vm macfilter option is disabled).
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
src/PVE/Firewall.pm | 40 ++++++++++++++++++++++++++++++++++++----
1 file changed, 36 insertions(+), 4 deletions(-)
diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm
index edc5336..8277ee0 100644
--- a/src/PVE/Firewall.pm
+++ b/src/PVE/Firewall.pm
@@ -1221,6 +1221,11 @@ our $cluster_option_properties = {
default => 1,
optional => 1,
},
+ ebtables_dst_macfilter => {
+ description => "Filtering VM/CT destination mac for ingress traffic.",
+ type => 'boolean',
+ optional => 1,
+ },
policy_in => {
description => "Input policy.",
type => 'string',
@@ -2867,7 +2872,7 @@ sub parse_clusterfw_option {
if (($value > 1) && ((time() - $value) > 60)) {
$value = 0
}
- } elsif ($line =~ m/^(ebtables):\s*(0|1)\s*$/i) {
+ } elsif ($line =~ m/^(ebtables|ebtables_dst_macfilter):\s*(0|1)\s*$/i) {
$opt = lc($1);
$value = int($2);
} elsif ($line =~ m/^(policy_(in|out)):\s*(ACCEPT|DROP|REJECT)\s*$/i) {
@@ -3948,11 +3953,19 @@ sub compile_ebtables_filter {
ruleset_create_chain($ruleset, "PVEFW-FORWARD");
ruleset_create_chain($ruleset, "PVEFW-FWBR-OUT");
+
+ if ($cluster_conf->{options}->{ebtables_dst_macfilter}) {
+ #filtering destination mac for ipv4/ipv6
+ ruleset_create_chain($ruleset, "PVEFW-FWBR-IN");
+ ruleset_addrule($ruleset, 'PVEFW-FORWARD', '-i fwln+', '-j PVEFW-FWBR-IN');
+ }
+
#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');
+ my $maclist = [];
# generate firewall rules for QEMU VMs
foreach my $vmid (sort keys %{$vmdata->{qemu}}) {
eval {
@@ -3975,7 +3988,7 @@ sub compile_ebtables_filter {
push(@$arpfilter, $ip);
}
}
- generate_tap_layer2filter($ruleset, $iface, $macaddr, $vmfw_conf, $vmid, $arpfilter);
+ generate_tap_layer2filter($ruleset, $iface, $macaddr, $vmfw_conf, $vmid, $arpfilter, $maclist);
}
};
warn $@ if $@; # just to be sure - should not happen
@@ -4012,17 +4025,23 @@ sub compile_ebtables_filter {
push @$arpfilter, $ip;
}
}
- generate_tap_layer2filter($ruleset, $iface, $macaddr, $vmfw_conf, $vmid, $arpfilter);
+ generate_tap_layer2filter($ruleset, $iface, $macaddr, $vmfw_conf, $vmid, $arpfilter, $maclist);
}
};
warn $@ if $@; # just to be sure - should not happen
}
+ if ($cluster_conf->{options}->{'ebtables_dst_macfilter'} && @$maclist > 0) {
+ push @$maclist, 'ff:ff:ff:ff:ff:ff'; #allow broadcast mac
+ my $maclist_str = join ',',sort(@$maclist);
+ ruleset_addrule($ruleset, 'PVEFW-FWBR-IN', "--among-dst ! $maclist_str,", '-j DROP');
+ }
+
return $ruleset;
}
sub generate_tap_layer2filter {
- my ($ruleset, $iface, $macaddr, $vmfw_conf, $vmid, $arpfilter) = @_;
+ my ($ruleset, $iface, $macaddr, $vmfw_conf, $vmid, $arpfilter, $maclist) = @_;
my $options = $vmfw_conf->{options};
my $tapchain = $iface."-OUT";
@@ -4037,6 +4056,10 @@ sub generate_tap_layer2filter {
ruleset_addrule($ruleset, $tapchain, "-s ! $macaddr", '-j DROP');
}
+ if (defined($macaddr)) {
+ push @$maclist, $macaddr;
+ }
+
if (@$arpfilter){
my $arpchain = $tapchain."-ARP";
ruleset_addrule($ruleset, $tapchain, "-p ARP", "-j $arpchain");
@@ -4225,6 +4248,15 @@ sub get_ebtables_cmdlist {
next if ! $pve_include;
$pve_include = 0;
}
+
+ if ($cmd =~ m/^-A (\S+) --among-dst ! (\S+) -j DROP/) {
+ my $chain = $1;
+ my $maclist_raw = $2."\n";
+ my $filename = "$pve_fw_status_dir/ebtables_macfilter-$chain";
+ PVE::Tools::file_set_contents($filename, $maclist_raw);
+ $cmd = "-A $1 --among-dst-file ! $filename -j DROP";
+ }
+
$cmdlist .= "$cmd\n";
}
}
--
2.30.2
next reply other threads:[~2021-09-10 15:35 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-10 15:34 Alexandre Derumier [this message]
2022-03-18 13:26 ` Wolfgang Bumiller
2022-03-18 18:59 ` DERUMIER, Alexandre
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210910153430.4045276-1-aderumier@odiso.com \
--to=aderumier@odiso.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.