};
-use Data::Dumper;
-
my $nodename = PVE::INotify::nodename();
my $pve_fw_lock_filename = "/var/lock/pvefw.lck";
'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' },
+ ],
'Trcrt' => [
{ action => 'PARAM', proto => 'udp', dport => '33434:33524' },
{ action => 'PARAM', proto => 'icmpv6', dport => 'echo-request' },
{ action => 'PARAM', proto => 'tcp', dport => '6881:6999' },
{ action => 'PARAM', proto => 'udp', dport => '6881' },
],
+ 'Ceph' => [
+ "Ceph Storage Cluster traffic (Ceph Monitors, OSD & MDS Deamons)",
+ { action => 'PARAM', proto => 'tcp', dport => '6789' },
+ { action => 'PARAM', proto => 'tcp', dport => '6800:7300' },
+ ],
'CVS' => [
"Concurrent Versions System pserver traffic",
{ action => 'PARAM', proto => 'tcp', dport => '2401' },
my $pve_fw_parsed_macros;
my $pve_fw_macro_descr;
+my $pve_fw_macro_ipversion = {};
my $pve_fw_preferred_macro_names = {};
my $pve_std_chains = {};
'echo-reply' => 1,
'router-solicitation' => 1,
'router-advertisement' => 1,
+ 'neighbor-solicitation' => 1,
'neighbour-solicitation' => 1,
+ 'neighbor-advertisement' => 1,
'neighbour-advertisement' => 1,
'redirect' => 1,
};
$pve_fw_parsed_macros = {};
- foreach my $k (keys %$pve_fw_macros) {
+ my $parse = sub {
+ my ($k, $macro) = @_;
my $lc_name = lc($k);
- my $macro = $pve_fw_macros->{$k};
- if (!ref($macro->[0])) {
- $pve_fw_macro_descr->{$k} = shift @$macro;
+ $pve_fw_macro_ipversion->{$k} = 0;
+ while (!ref($macro->[0])) {
+ my $desc = shift @$macro;
+ if ($desc eq 'ipv4only') {
+ $pve_fw_macro_ipversion->{$k} = 4;
+ } elsif ($desc eq 'ipv6only') {
+ $pve_fw_macro_ipversion->{$k} = 6;
+ } else {
+ $pve_fw_macro_descr->{$k} = $desc;
+ }
}
$pve_fw_preferred_macro_names->{$lc_name} = $k;
$pve_fw_parsed_macros->{$k} = $macro;
+ };
+
+ foreach my $k (keys %$pve_fw_macros) {
+ &$parse($k, $pve_fw_macros->{$k});
+ }
+
+ foreach my $k (keys %$pve_ipv6fw_macros) {
+ next if $pve_fw_parsed_macros->{$k};
+ &$parse($k, $pve_ipv6fw_macros->{$k});
+ $pve_fw_macro_ipversion->{$k} = 6;
}
}
my $testip = Net::IP->new($ip);
- my $routes = PVE::ProcFSTools::read_proc_net_route();
+ my $isv6 = $testip->version == 6;
+ my $routes = $isv6 ? PVE::ProcFSTools::read_proc_net_ipv6_route()
+ : PVE::ProcFSTools::read_proc_net_route();
foreach my $entry (@$routes) {
- my $mask = $ipv4_mask_hash_localnet->{$entry->{mask}};
- next if !defined($mask);
- return if $mask eq '0.0.0.0';
+ my $mask;
+ if ($isv6) {
+ $mask = $entry->{prefix};
+ } else {
+ $mask = $ipv4_mask_hash_localnet->{$entry->{mask}};
+ next if !defined($mask);
+ }
my $cidr = "$entry->{dest}/$mask";
my $testnet = Net::IP->new($cidr);
- if ($testnet->overlaps($testip)) {
+ if ($testnet->overlaps($testip) == $Net::IP::IP_B_IN_A_OVERLAP) {
$__local_network = $cidr;
return;
}
optional => 1,
},
enable => {
- type => 'boolean',
+ type => 'integer',
+ minimum => 0,
optional => 1,
},
sport => {
$macro_rules = $pve_ipv6fw_macros->{$macro_name};
}
+ # skip macros which are specific to another ipversion
+ if ($ipversion && (my $required = $pve_fw_macro_ipversion->{$macro_name})) {
+ return if $ipversion != $required;
+ }
+
my $rules = [];
foreach my $templ (@$macro_rules) {
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, $localnet_ver) = parse_ip_or_cidr(local_network());
+ my $localnet = $cluster_conf->{aliases}->{local_network}->{cidr};
+ my $localnet_ver = $cluster_conf->{aliases}->{local_network}->{ipversion};
# corosync
if ($localnet && ($ipversion == $localnet_ver)) {
my ($opt, $value);
- if ($line =~ m/^(enable):\s*(0|1)\s*$/i) {
+ if ($line =~ m/^(enable):\s*(\d+)\s*$/i) {
$opt = lc($1);
$value = int($2);
+ if (($value > 1) && ((time() - $value) > 60)) {
+ $value = 0
+ }
} elsif ($line =~ m/^(policy_(in|out)):\s*(ACCEPT|DROP|REJECT)\s*$/i) {
$opt = lc($1);
$value = uc($3);
}
#http://backreference.org/2013/03/01/ipv6-address-normalization/
if ($ver == 6) {
- my $ipv6 = inet_pton(AF_INET6, lc($cidr));
- $cidr = inet_ntop(AF_INET6, $ipv6);
+ $cidr = lc(Net::IP::ip_compress_address($cidr, 6));
$cidr =~ s|/128$||;
} else {
$cidr =~ s|/32$||;
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 };