[pve-devel] [PATCH firewall 1/4] added the 'ipfilter' option
Wolfgang Bumiller
w.bumiller at proxmox.com
Wed Mar 2 12:59:14 CET 2016
This effectively acts like adding an emtpy 'ipfilter-netX'
ipset for every firewall-enabled interface.
---
src/PVE/API2/Firewall/VM.pm | 9 +++++++++
src/PVE/Firewall.pm | 42 ++++++++++++++++++++++++++++++++++--------
2 files changed, 43 insertions(+), 8 deletions(-)
diff --git a/src/PVE/API2/Firewall/VM.pm b/src/PVE/API2/Firewall/VM.pm
index aad973b..192737a 100644
--- a/src/PVE/API2/Firewall/VM.pm
+++ b/src/PVE/API2/Firewall/VM.pm
@@ -38,6 +38,15 @@ my $option_properties = {
type => 'boolean',
optional => 1,
},
+ ipfilter => {
+ description => "Enable default IP filters. " .
+ "This is equivalent to adding an empty ipfilter-net<id> ipset " .
+ "for every interface. Such ipsets implicitly contain sane default " .
+ "restrictions such as restricting IPv6 link local addresses to " .
+ "the one derived from the interface's MAC address.",
+ type => 'boolean',
+ optional => 1,
+ },
policy_in => {
description => "Input policy.",
type => 'string',
diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm
index 1479d3b..73ae6f7 100644
--- a/src/PVE/Firewall.pm
+++ b/src/PVE/Firewall.pm
@@ -2073,7 +2073,7 @@ sub generate_tap_rules_direction {
my $ipfilter_name = compute_ipfilter_ipset_name($netid);
my $ipfilter_ipset = compute_ipset_chain_name($vmid, $ipfilter_name, $ipversion)
- if $vmfw_conf->{ipset}->{$ipfilter_name};
+ if $options->{ipfilter} || $vmfw_conf->{ipset}->{$ipfilter_name};
# create chain with mac and ip filter
ruleset_create_vm_chain($ruleset, $tapchain, $ipversion, $options, $macaddr, $ipfilter_ipset, $direction);
@@ -2360,7 +2360,7 @@ sub parse_vmfw_option {
my $loglevels = "emerg|alert|crit|err|warning|notice|info|debug|nolog";
- if ($line =~ m/^(enable|dhcp|ndp|radv|macfilter|ips):\s*(0|1)\s*$/i) {
+ if ($line =~ m/^(enable|dhcp|ndp|radv|macfilter|ipfilter|ips):\s*(0|1)\s*$/i) {
$opt = lc($1);
$value = int($2);
} elsif ($line =~ m/^(log_level_in|log_level_out):\s*(($loglevels)\s*)?$/i) {
@@ -2972,11 +2972,11 @@ sub generate_std_chains {
}
sub generate_ipset_chains {
- my ($ipset_ruleset, $clusterfw_conf, $fw_conf, $device_ips) = @_; #fixme
+ my ($ipset_ruleset, $clusterfw_conf, $fw_conf, $device_ips, $ipsets) = @_;
- foreach my $ipset (keys %{$fw_conf->{ipset}}) {
+ foreach my $ipset (keys %{$ipsets}) {
- my $options = $fw_conf->{ipset}->{$ipset};
+ my $options = $ipsets->{$ipset};
if ($device_ips && $ipset =~ /^ipfilter-(net\d+)$/) {
if (my $ips = $device_ips->{$1}) {
@@ -3314,12 +3314,24 @@ sub compile_ipsets {
my $vmfw_conf = $vmfw_configs->{$vmid};
return if !$vmfw_conf;
+ # When the 'ipfilter' option is enabled every device for which there
+ # is no 'ipfilter-netX' ipset defiend gets an implicit empty default
+ # ipset.
+ # The reason is that ipfilter ipsets are always filled with standard
+ # IPv6 link-local filters.
+ my $ipsets = $vmfw_conf->{ipset};
+ my $implicit_sets = {};
+
my $device_ips = {};
foreach my $netid (keys %$conf) {
next if $netid !~ m/^net(\d+)$/;
my $net = PVE::QemuServer::parse_net($conf->{$netid});
next if !$net->{firewall};
+ if ($vmfw_conf->{options}->{ipfilter} && !$ipsets->{"ipfilter-$netid"}) {
+ $implicit_sets->{"ipfilter-$netid"} = [];
+ }
+
my $macaddr = $net->{macaddr};
my $linklocal = mac_to_linklocal($macaddr);
$device_ips->{$netid} = [
@@ -3328,7 +3340,8 @@ sub compile_ipsets {
];
}
- generate_ipset_chains($ipset_ruleset, $cluster_conf, $vmfw_conf, $device_ips);
+ generate_ipset_chains($ipset_ruleset, $cluster_conf, $vmfw_conf, $device_ips, $ipsets);
+ generate_ipset_chains($ipset_ruleset, $cluster_conf, $vmfw_conf, $device_ips, $implicit_sets);
};
warn $@ if $@; # just to be sure - should not happen
}
@@ -3340,12 +3353,24 @@ sub compile_ipsets {
my $vmfw_conf = $vmfw_configs->{$vmid};
return if !$vmfw_conf;
+ # When the 'ipfilter' option is enabled every device for which there
+ # is no 'ipfilter-netX' ipset defiend gets an implicit empty default
+ # ipset.
+ # The reason is that ipfilter ipsets are always filled with standard
+ # IPv6 link-local filters.
+ my $ipsets = $vmfw_conf->{ipset};
+ my $implicit_sets = {};
+
my $device_ips = {};
foreach my $netid (keys %$conf) {
next if $netid !~ m/^net(\d+)$/;
my $net = PVE::LXC::parse_lxc_network($conf->{$netid});
next if !$net->{firewall};
+ if ($vmfw_conf->{options}->{ipfilter} && !$ipsets->{"ipfilter-$netid"}) {
+ $implicit_sets->{"ipfilter-$netid"} = [];
+ }
+
my $macaddr = $net->{hwaddr};
my $linklocal = mac_to_linklocal($macaddr);
$device_ips->{$netid} = [
@@ -3354,12 +3379,13 @@ sub compile_ipsets {
];
}
- generate_ipset_chains($ipset_ruleset, $cluster_conf, $vmfw_conf, $device_ips);
+ generate_ipset_chains($ipset_ruleset, $cluster_conf, $vmfw_conf, $device_ips, $ipsets);
+ generate_ipset_chains($ipset_ruleset, $cluster_conf, $vmfw_conf, $device_ips, $implicit_sets);
};
warn $@ if $@; # just to be sure - should not happen
}
- generate_ipset_chains($ipset_ruleset, undef, $cluster_conf, undef);
+ generate_ipset_chains($ipset_ruleset, undef, $cluster_conf, undef, $cluster_conf->{ipset});
return $ipset_ruleset;
}
--
2.1.4
More information about the pve-devel
mailing list