[pve-devel] [PATCH 1/2] Added Forward chain management
Flavius Bindea
flav at flav.com
Sat May 9 19:27:13 CEST 2015
---
src/PVE/API2/Firewall/Cluster.pm | 6 +++
src/PVE/API2/Firewall/Host.pm | 2 +
src/PVE/Firewall.pm | 92 +++++++++++++++++++++++++++++++++++---
3 files changed, 93 insertions(+), 7 deletions(-)
diff --git a/src/PVE/API2/Firewall/Cluster.pm b/src/PVE/API2/Firewall/Cluster.pm
index 0f6b98c..9ad3a90 100644
--- a/src/PVE/API2/Firewall/Cluster.pm
+++ b/src/PVE/API2/Firewall/Cluster.pm
@@ -88,6 +88,12 @@ my $option_properties = {
optional => 1,
enum => ['ACCEPT', 'REJECT', 'DROP'],
},
+ policy_forward => {
+ description => "Forward policy.",
+ type => 'string',
+ optional => 1,
+ enum => ['ACCEPT', 'REJECT', 'DROP'],
+ },
};
my $add_option_properties = sub {
diff --git a/src/PVE/API2/Firewall/Host.pm b/src/PVE/API2/Firewall/Host.pm
index 37a63b7..5cdab67 100644
--- a/src/PVE/API2/Firewall/Host.pm
+++ b/src/PVE/API2/Firewall/Host.pm
@@ -59,6 +59,8 @@ my $option_properties = {
description => "Log level for incoming traffic." }),
log_level_out => get_standard_option('pve-fw-loglevel', {
description => "Log level for outgoing traffic." }),
+ log_level_forward => get_standard_option('pve-fw-loglevel', {
+ description => "Log level for forwarded traffic." }),
tcp_flags_log_level => get_standard_option('pve-fw-loglevel', {
description => "Log level for illegal tcp flags filter." }),
smurf_log_level => get_standard_option('pve-fw-loglevel', {
diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm
index 78f9751..79dac20 100644
--- a/src/PVE/Firewall.pm
+++ b/src/PVE/Firewall.pm
@@ -1120,7 +1120,7 @@ my $rule_properties = {
type => {
type => 'string',
optional => 1,
- enum => ['in', 'out', 'group'],
+ enum => ['in', 'out', 'forward', 'group'],
},
action => {
description => "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.",
@@ -1316,7 +1316,7 @@ sub verify_rule {
&$add_error('action', "missing property") if !$action;
if ($type) {
- if ($type eq 'in' || $type eq 'out') {
+ if ($type eq 'in' || $type eq 'out' || $type eq 'forward') {
&$add_error('action', "unknown action '$action'")
if $action && ($action !~ m/^(ACCEPT|DROP|REJECT)$/);
} elsif ($type eq 'group') {
@@ -2174,6 +2174,66 @@ sub enable_host_firewall {
my $policy = $cluster_options->{policy_in} || 'DROP'; # allow nothing by default
ruleset_add_chain_policy($ruleset, $chain, $ipversion, 0, $policy, $loglevel, $accept_action);
+ # host forward firewall
+ $chain = "PVEFW-HOST-FORWARD";
+ ruleset_create_chain($ruleset, $chain);
+
+ $loglevel = get_option_log_level($options, "log_level_forward");
+
+ ruleset_addrule($ruleset, $chain, "-i lo -j ACCEPT");
+
+ ruleset_chain_add_conn_filters($ruleset, $chain, 'ACCEPT');
+ ruleset_chain_add_input_filters($ruleset, $chain, $ipversion, $options, $cluster_conf, $loglevel);
+
+ # we use RETURN because we may want to check other thigs later
+ $accept_action = 'RETURN';
+
+ ruleset_addrule($ruleset, $chain, "-p igmp -j $accept_action"); # important for multicast
+
+ # add host rules first, so that cluster wide rules can be overwritten
+ foreach my $rule (@$rules, @$cluster_rules) {
+ next if !$rule->{enable} || $rule->{errors};
+ next if $rule->{ipversion} && ($rule->{ipversion} != $ipversion);
+
+ # on forward chain we do not take care of interface
+ #$rule->{iface_out} = $rule->{iface} if $rule->{iface};
+ eval {
+ if ($rule->{type} eq 'group') {
+ ruleset_add_group_rule($ruleset, $cluster_conf, $chain, $rule, 'FORWARD', $accept_action, $ipversion);
+ } elsif ($rule->{type} eq 'forward') {
+ ruleset_generate_rule($ruleset, $chain, $ipversion,
+ $rule,
+ { ACCEPT => $accept_action, REJECT => "PVEFW-reject" },
+ undef, $cluster_conf, $hostfw_conf);
+ }
+ };
+ warn $@ if $@;
+ #delete $rule->{iface_out};
+ }
+
+ # allow standard traffic for management ipset (includes cluster network)
+ ruleset_addrule($ruleset, $chain, "$mngmntsrc -p tcp --dport 8006 -j $accept_action"); # PVE API
+ ruleset_addrule($ruleset, $chain, "$mngmntsrc -p tcp --dport 5900:5999 -j $accept_action"); # PVE VNC Console
+ ruleset_addrule($ruleset, $chain, "$mngmntsrc -p tcp --dport 3128 -j $accept_action"); # SPICE Proxy
+ ruleset_addrule($ruleset, $chain, "$mngmntsrc -p tcp --dport 22 -j $accept_action"); # SSH
+
+ # allow standard traffic on cluster network
+ if ($localnet && ($ipversion == $localnet_ver)) {
+ # Flav: TODO verify this 4 rules
+ ruleset_addrule($ruleset, $chain, "-d $localnet -p tcp --dport 8006 -j $accept_action"); # PVE API
+ ruleset_addrule($ruleset, $chain, "-d $localnet -p tcp --dport 22 -j $accept_action"); # SSH
+ ruleset_addrule($ruleset, $chain, "-d $localnet -p tcp --dport 5900:5999 -j $accept_action"); # PVE VNC Console
+ ruleset_addrule($ruleset, $chain, "-d $localnet -p tcp --dport 3128 -j $accept_action"); # SPICE Proxy
+
+ my $corosync_rule = "-p udp --dport 5404:5405 -j $accept_action";
+ ruleset_addrule($ruleset, $chain, "-s $localnet -d $localnet $corosync_rule");
+ ruleset_addrule($ruleset, $chain, "-s $localnet -m addrtype --dst-type MULTICAST $corosync_rule");
+ }
+
+ # implement forward policy
+ $policy = $cluster_options->{policy_forward} || 'ACCEPT'; # allow nothing by default
+ ruleset_add_chain_policy($ruleset, $chain, $ipversion, 0, $policy, $loglevel, $accept_action);
+
# host outbound firewall
$chain = "PVEFW-HOST-OUT";
ruleset_create_chain($ruleset, $chain);
@@ -2226,6 +2286,7 @@ sub enable_host_firewall {
ruleset_addrule($ruleset, "PVEFW-OUTPUT", "-j PVEFW-HOST-OUT");
ruleset_addrule($ruleset, "PVEFW-INPUT", "-j PVEFW-HOST-IN");
+ ruleset_addrule($ruleset, "PVEFW-FORWARD", "-j PVEFW-HOST-FORWARD");
}
sub generate_group_rules {
@@ -2265,6 +2326,21 @@ sub generate_group_rules {
{ ACCEPT => 'PVEFW-SET-ACCEPT-MARK', REJECT => "PVEFW-reject" },
undef, $cluster_conf);
}
+
+ $chain = "GROUP-${group}-FORWARD";
+
+ ruleset_create_chain($ruleset, $chain);
+ ruleset_addrule($ruleset, $chain, "-j MARK --set-mark 0"); # clear mark
+
+ foreach my $rule (@$rules) {
+ next if $rule->{type} ne 'forward';
+ next if $rule->{ipversion} && $rule->{ipversion} ne $ipversion;
+ # we use PVEFW-SET-ACCEPT-MARK (Instead of ACCEPT) because we need to
+ # check also other tap rules later
+ ruleset_generate_rule($ruleset, $chain, $ipversion, $rule,
+ { ACCEPT => 'PVEFW-SET-ACCEPT-MARK', REJECT => "PVEFW-reject" },
+ undef, $cluster_conf);
+ }
}
my $MAX_NETS = 32;
@@ -2295,7 +2371,7 @@ sub parse_fw_rule {
$rule->{type} = lc($1);
$rule->{action} = $2;
- if ($rule->{type} eq 'in' || $rule->{type} eq 'out') {
+ if ($rule->{type} eq 'in' || $rule->{type} eq 'out' || $rule->{type} eq 'forward') {
if ($rule->{action} =~ m/^(\S+)\((ACCEPT|DROP|REJECT)\)$/) {
$rule->{macro} = $1;
$rule->{action} = $2;
@@ -2362,7 +2438,7 @@ sub parse_vmfw_option {
} elsif ($line =~ m/^(log_level_in|log_level_out):\s*(($loglevels)\s*)?$/i) {
$opt = lc($1);
$value = $2 ? lc($3) : '';
- } elsif ($line =~ m/^(policy_(in|out)):\s*(ACCEPT|DROP|REJECT)\s*$/i) {
+ } elsif ($line =~ m/^(policy_(in|out|forward)):\s*(ACCEPT|DROP|REJECT)\s*$/i) {
$opt = lc($1);
$value = uc($3);
} elsif ($line =~ m/^(ips_queues):\s*((\d+)(:(\d+))?)\s*$/i) {
@@ -2385,7 +2461,7 @@ sub parse_hostfw_option {
if ($line =~ m/^(enable|nosmurfs|tcpflags):\s*(0|1)\s*$/i) {
$opt = lc($1);
$value = int($2);
- } elsif ($line =~ m/^(log_level_in|log_level_out|tcp_flags_log_level|smurf_log_level):\s*(($loglevels)\s*)?$/i) {
+ } elsif ($line =~ m/^(log_level_in|log_level_out|log_level_forward|tcp_flags_log_level|smurf_log_level):\s*(($loglevels)\s*)?$/i) {
$opt = lc($1);
$value = $2 ? lc($3) : '';
} elsif ($line =~ m/^(nf_conntrack_max|nf_conntrack_tcp_timeout_established):\s*(\d+)\s*$/i) {
@@ -2406,7 +2482,7 @@ sub parse_clusterfw_option {
if ($line =~ m/^(enable):\s*(0|1)\s*$/i) {
$opt = lc($1);
$value = int($2);
- } elsif ($line =~ m/^(policy_(in|out)):\s*(ACCEPT|DROP|REJECT)\s*$/i) {
+ } elsif ($line =~ m/^(policy_(in|out|forward)):\s*(ACCEPT|DROP|REJECT)\s*$/i) {
$opt = lc($1);
$value = uc($3);
} else {
@@ -2740,7 +2816,9 @@ my $format_rules = sub {
my $raw = '';
foreach my $rule (@$rules) {
- if ($rule->{type} eq 'in' || $rule->{type} eq 'out' || $rule->{type} eq 'group') {
+ if ($rule->{type} eq 'in' || $rule->{type} eq 'out'
+ || $rule->{type} eq 'forward'
+ || $rule->{type} eq 'group') {
$raw .= '|' if defined($rule->{enable}) && !$rule->{enable};
$raw .= uc($rule->{type});
if ($rule->{macro}) {
--
1.7.10.4
More information about the pve-devel
mailing list