[pve-devel] [PATCH] optimize : accept from physical interfaces on bridges
Alexandre Derumier
aderumier at odiso.com
Tue Apr 22 05:57:15 CEST 2014
They are a lot of chance that a packet is coming/going from/to external network.
Currently, we need to check all tap chains before accept the packet from eth|bond interface.
This can have a big performance impact (mainly for drop|reject, as we don't have an established connection).
So It could be a problem in case of a ddos attack for example.
without optimize
----------------
-A vmbr1-FW -m physdev --physdev-is-in -j vmbr1-OUT
-A vmbr1-OUT -m physdev --physdev-in tapxxxi0 -j tapxxxi0-OUT
-A vmbr1-OUT -m physdev --physdev-in tapxxxi0 -j tapxxxi0-OUT
-A vmbr1-OUT -m physdev --physdev-in tapxxxi0 -j tapxxxi0-OUT
-A vmbr1-OUT -m physdev --physdev-in tapxxxi0 -j tapxxxi0-OUT
-A vmbr1-OUT -m physdev --physdev-in tapxxxi0 -j tapxxxi0-OUT
-A vmbr1-OUT -m physdev --physdev-in tapxxxi0 -j tapxxxi0-OUT
-A vmbr1-FW -m physdev --physdev-is-out -j vmbr1-IN
-A vmbr1-IN -m physdev --physdev-out tapxxxi0 --physdev-is-bridged -j tapxxxi0-IN
-A vmbr1-IN -m physdev --physdev-out tapxxxi0 --physdev-is-bridged -j tapxxxi0-IN
-A vmbr1-IN -m physdev --physdev-out tapxxxi0 --physdev-is-bridged -j tapxxxi0-IN
-A vmbr1-IN -m physdev --physdev-out tapxxxi0 --physdev-is-bridged -j tapxxxi0-IN
-A vmbr1-IN -m physdev --physdev-out tapxxxi0 --physdev-is-bridged -j tapxxxi0-IN
-A vmbr1-IN -m physdev --physdev-out tapxxxi0 --physdev-is-bridged -j tapxxxi0-IN
-A vmbr1-FW -m mark --mark 0x1 -j ACCEPT
-A vmbr1-FW -m physdev --physdev-is-out -j ACCEPT
with optimize
------------
-A vmbr1-FW -m physdev --physdev-is-in -j vmbr1-OUT
-A vmbr1-OUT -m physdev --physdev-in ethX --physdev-is-bridged -g PVEFW-SET-ACCEPT-MARK
-A vmbr1-OUT -m physdev --physdev-in tapxxxi0 -j tapxxxi0-OUT
-A vmbr1-OUT -m physdev --physdev-in tapxxxi0 -j tapxxxi0-OUT
-A vmbr1-OUT -m physdev --physdev-in tapxxxi0 -j tapxxxi0-OUT
-A vmbr1-OUT -m physdev --physdev-in tapxxxi0 -j tapxxxi0-OUT
-A vmbr1-OUT -m physdev --physdev-in tapxxxi0 -j tapxxxi0-OUT
-A vmbr1-OUT -m physdev --physdev-in tapxxxi0 -j tapxxxi0-OUT
-A vmbr1-FW -m physdev --physdev-is-out -j vmbr1-IN
-A vmbr1-IN -m physdev --physdev-out ethX --physdev-is-bridged -j ACCEPT
-A vmbr1-IN -m physdev --physdev-out tapxxxi0 --physdev-is-bridged -j tapxxxi0-IN
-A vmbr1-IN -m physdev --physdev-out tapxxxi0 --physdev-is-bridged -j tapxxxi0-IN
-A vmbr1-IN -m physdev --physdev-out tapxxxi0 --physdev-is-bridged -j tapxxxi0-IN
-A vmbr1-IN -m physdev --physdev-out tapxxxi0 --physdev-is-bridged -j tapxxxi0-IN
-A vmbr1-IN -m physdev --physdev-out tapxxxi0 --physdev-is-bridged -j tapxxxi0-IN
-A vmbr1-IN -m physdev --physdev-out tapxxxi0 --physdev-is-bridged -j tapxxxi0-IN
-A vmbr1-FW -m mark --mark 0x1 -j ACCEPT
-A vmbr1-FW -m physdev --physdev-is-out -j ACCEPT
Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
src/PVE/Firewall.pm | 44 ++++++++++++++++++++++++++++++++++++++------
1 file changed, 38 insertions(+), 6 deletions(-)
diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm
index 7ef38fa..83d7c1c 100644
--- a/src/PVE/Firewall.pm
+++ b/src/PVE/Firewall.pm
@@ -15,7 +15,7 @@ use File::Basename;
use File::Path;
use IO::File;
use Net::IP;
-use PVE::Tools qw(run_command lock_file);
+use PVE::Tools qw(run_command lock_file dir_glob_foreach);
use Encode;
my $hostfw_conf_filename = "/etc/pve/local/host.fw";
@@ -1378,7 +1378,7 @@ sub ruleset_addlog {
}
sub generate_bridge_chains {
- my ($ruleset, $hostfw_conf, $bridge, $routing_table) = @_;
+ my ($ruleset, $hostfw_conf, $bridge, $routing_table, $bridges_config) = @_;
my $options = $hostfw_conf->{options} || {};
@@ -1393,12 +1393,26 @@ sub generate_bridge_chains {
if (!ruleset_chain_exist($ruleset, "$bridge-OUT")) {
ruleset_create_chain($ruleset, "$bridge-OUT");
+
+ if($options->{optimize}){
+ foreach my $interface (@{$bridges_config->{$bridge}}) {
+ ruleset_addrule($ruleset, "$bridge-OUT", "-m physdev --physdev-is-bridged --physdev-in $interface -g PVEFW-SET-ACCEPT-MARK");
+ }
+ }
+
ruleset_addrule($ruleset, "$bridge-FW", "-m physdev --physdev-is-in -j $bridge-OUT");
ruleset_insertrule($ruleset, "PVEFW-INPUT", "-i $bridge -m physdev --physdev-is-in -j $bridge-OUT");
}
if (!ruleset_chain_exist($ruleset, "$bridge-IN")) {
ruleset_create_chain($ruleset, "$bridge-IN");
+
+ if($options->{optimize}){
+ foreach my $interface (@{$bridges_config->{$bridge}}) {
+ ruleset_addrule($ruleset, "$bridge-IN", "-m physdev --physdev-is-bridged --physdev-out $interface -j ACCEPT");
+ }
+ }
+
ruleset_addrule($ruleset, "$bridge-FW", "-m physdev --physdev-is-out -j $bridge-IN");
ruleset_addrule($ruleset, "$bridge-FW", "-m mark --mark 1 -j ACCEPT");
# accept traffic to unmanaged bridge ports
@@ -1636,10 +1650,10 @@ sub generate_tap_rules_direction {
# plug the tap chain to bridge chain
if ($direction eq 'IN') {
- ruleset_insertrule($ruleset, "$bridge-IN",
+ ruleset_addrule($ruleset, "$bridge-IN",
"-m physdev --physdev-is-bridged --physdev-out $iface -j $tapchain");
} else {
- ruleset_insertrule($ruleset, "$bridge-OUT",
+ ruleset_addrule($ruleset, "$bridge-OUT",
"-m physdev --physdev-in $iface -j $tapchain");
}
}
@@ -2188,6 +2202,22 @@ sub read_local_vm_config {
return $vmdata;
};
+sub read_bridges_config {
+
+ my $bridgehash = {};
+
+ dir_glob_foreach('/sys/class/net', 'vmbr(\d+)', sub {
+ my ($bridge) = @_;
+
+ dir_glob_foreach("/sys/class/net/$bridge/brif", '((eth|bond)(\d+)(\.(\d+))?)', sub {
+ my ($interface) = @_;
+ push @{$bridgehash->{$bridge}}, $interface;
+ });
+ });
+
+ return $bridgehash;
+};
+
sub load_vmfw_conf {
my ($vmid) = @_;
@@ -2552,6 +2582,8 @@ sub compile {
my $vmfw_configs = read_vm_firewall_configs($vmdata);
my $routing_table = read_proc_net_route();
+
+ my $bridges_config = read_bridges_config();
my $ipset_ruleset = {};
generate_ipset_chains($ipset_ruleset, $cluster_conf);
@@ -2589,7 +2621,7 @@ sub compile {
$bridge .= "v$net->{tag}" if $net->{tag};
- generate_bridge_chains($ruleset, $hostfw_conf, $bridge, $routing_table);
+ generate_bridge_chains($ruleset, $hostfw_conf, $bridge, $routing_table, $bridges_config);
my $macaddr = $net->{macaddr};
generate_tap_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $iface, $netid, $macaddr,
@@ -2623,7 +2655,7 @@ sub compile {
next; # fixme?
}
- generate_bridge_chains($ruleset, $hostfw_conf, $bridge, $routing_table);
+ generate_bridge_chains($ruleset, $hostfw_conf, $bridge, $routing_table, $bridges_config);
my $macaddr = $d->{mac};
my $iface = $d->{host_ifname};
--
1.7.10.4
More information about the pve-devel
mailing list