emerg => 0,
};
+# we need to overwrite some macros for ipv6
+my $pve_ipv6fw_macros = {
+ 'Ping' => [
+ { action => 'PARAM', proto => 'icmpv6', dport => 'echo-request' },
+ ],
+ 'NeighborDiscovery' => [
+ "IPv6 neighbor solicitation, neighbor and router advertisement",
+ { action => 'PARAM', proto => 'icmpv6', dport => 'router-advertisement' },
+ { action => 'PARAM', proto => 'icmpv6', dport => 'neighbor-solicitation' },
+ { action => 'PARAM', proto => 'icmpv6', dport => 'neighbor-advertisement' },
+ ],
+ 'DHCPv6' => [
+ { action => 'PARAM', proto => 'udp', dport => '546:547', sport => '546:547' },
+ ],
+ 'Trcrt' => [
+ { action => 'PARAM', proto => 'udp', dport => '33434:33524' },
+ { action => 'PARAM', proto => 'icmpv6', dport => 'echo-request' },
+ ],
+ };
+
# imported/converted from: /usr/share/shorewall/macro.*
my $pve_fw_macros = {
'Amanda' => [
'echo-reply' => 1,
'router-solicitation' => 1,
'router-advertisement' => 1,
+ 'neighbor-solicitation' => 1,
'neighbour-solicitation' => 1,
+ 'neighbor-advertisement' => 1,
'neighbour-advertisement' => 1,
'redirect' => 1,
};
}
my $apply_macro = sub {
- my ($macro_name, $param, $verify) = @_;
+ my ($macro_name, $param, $verify, $ipversion) = @_;
my $macro_rules = $pve_fw_parsed_macros->{$macro_name};
die "unknown macro '$macro_name'\n" if !$macro_rules; # should not happen
+ if ($ipversion && ($ipversion == 6) && $pve_ipv6fw_macros->{$macro_name}) {
+ $macro_rules = $pve_ipv6fw_macros->{$macro_name};
+ }
+
my $rules = [];
foreach my $templ (@$macro_rules) {
&$check_ipset_or_alias_property('dest', $ipversion);
}
+ $rule->{ipversion} = $ipversion if $ipversion;
+
if ($rule->{macro} && !$error_count) {
- eval { &$apply_macro($rule->{macro}, $rule, 1); };
+ eval { &$apply_macro($rule->{macro}, $rule, 1, $ipversion); };
if (my $err = $@) {
if (ref($err) eq "PVE::Exception" && $err->{errors}) {
my $eh = $err->{errors};
}
$rule->{errors} = $errors if $error_count;
- $rule->{ipversion} = $ipversion if $ipversion;
return $rule;
}
if ($rule->{dport}) {
if ($rule->{proto} && $rule->{proto} eq 'icmp') {
# Note: we use dport to store --icmp-type
- die "unknown icmp-type '$rule->{dport}'\n" if !defined($icmp_type_names->{$rule->{dport}});
+ die "unknown icmp-type '$rule->{dport}'\n"
+ if $rule->{dport} !~ /^\d+$/ && !defined($icmp_type_names->{$rule->{dport}});
push @cmd, "-m icmp --icmp-type $rule->{dport}";
} elsif ($rule->{proto} && $rule->{proto} eq 'icmpv6') {
# Note: we use dport to store --icmpv6-type
- die "unknown icmpv6-type '$rule->{dport}'\n" if !defined($icmpv6_type_names->{$rule->{dport}});
+ die "unknown icmpv6-type '$rule->{dport}'\n"
+ if $rule->{dport} !~ /^\d+$/ && !defined($icmpv6_type_names->{$rule->{dport}});
push @cmd, "-m icmpv6 --icmpv6-type $rule->{dport}";
} else {
if ($nbdport > 1) {
my $rules;
if ($rule->{macro}) {
- $rules = &$apply_macro($rule->{macro}, $rule);
+ $rules = &$apply_macro($rule->{macro}, $rule, 0, $ipversion);
} else {
$rules = [ $rule ];
}
# 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);
$rule->{iface_in} = $rule->{iface} if $rule->{iface};
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
- my $localnet = local_network();
+ my $localnet = $cluster_conf->{aliases}->{local_network}->{cidr};
+ my $localnet_ver = $cluster_conf->{aliases}->{local_network}->{ipversion};
# corosync
- if ($localnet) {
+ if ($localnet && ($ipversion == $localnet_ver)) {
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");
# 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);
$rule->{iface_out} = $rule->{iface} if $rule->{iface};
eval {
}
# allow standard traffic on cluster network
- if ($localnet) {
+ if ($localnet && ($ipversion == $localnet_ver)) {
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
if ($cluster_conf->{aliases}->{local_network}) {
$localnet = $cluster_conf->{aliases}->{local_network}->{cidr};
} else {
- $localnet = local_network() || '127.0.0.0/8';
- $cluster_conf->{aliases}->{local_network} = { cidr => $localnet };
+ my $localnet_ver;
+ ($localnet, $localnet_ver) = parse_ip_or_cidr(local_network() || '127.0.0.0/8');
+
+ $cluster_conf->{aliases}->{local_network} = {
+ name => 'local_network', cidr => $localnet, ipversion => $localnet_ver };
}
push @{$cluster_conf->{ipset}->{management}}, { cidr => $localnet };
my $ipset_ruleset = {};
- # currently pveproxy don't works with ipv6, so let's generate host fw ipv4 only for the moment
- if ($hostfw_enable && ($ipversion == 4)) {
+ if ($hostfw_enable) {
eval { enable_host_firewall($ruleset, $hostfw_conf, $cluster_conf, $ipversion); };
warn $@ if $@; # just to be sure - should not happen
}