maxLength => 20,
});
+PVE::JSONSchema::register_standard_option('pve-fw-alias', {
+ description => "Alias name.",
+ type => 'string',
+ pattern => '[A-Za-z][A-Za-z0-9\-\_]+',
+ minLength => 2,
+ maxLength => 20,
+});
+
PVE::JSONSchema::register_standard_option('pve-fw-loglevel' => {
description => "Log level.",
type => 'string',
die "invalid security group name '$source'\n";
}
} elsif ($source =~ m/^${ip_alias_pattern}$/){
- die "no such alias $source\n" if !$cluster_conf->{aliases}->{$source};
- push @cmd, "-s $cluster_conf->{aliases}->{$source}";
-
+ my $alias = lc($source);
+ my $e = $cluster_conf->{aliases}->{$alias};
+ die "no such alias $source\n" if !$e;
+ push @cmd, "-s $e->{cidr}";
} elsif ($source =~ m/\-/){
push @cmd, "-m iprange --src-range $source";
die "invalid security group name '$dest'\n";
}
} elsif ($dest =~ m/^${ip_alias_pattern}$/){
- die "no such alias $dest" if !$cluster_conf->{aliases}->{$dest};
- push @cmd, "-d $cluster_conf->{aliases}->{$dest}";
-
+ my $alias = lc($source);
+ my $e = $cluster_conf->{aliases}->{$alias};
+ die "no such alias $dest" if !$e;
+ push @cmd, "-d $e->{cidr}";
} elsif ($dest =~ m/^(\d+)\.(\d+).(\d+).(\d+)\-(\d+)\.(\d+).(\d+).(\d+)$/){
push @cmd, "-m iprange --dst-range $dest";
$rules = [ $rule ];
}
+ # update all or nothing
+
+ my @cmds = ();
foreach my $tmp (@$rules) {
if (my $cmdstr = ruleset_generate_cmdstr($ruleset, $chain, $tmp, $actions, $goto, $cluster_conf)) {
- ruleset_addrule($ruleset, $chain, $cmdstr);
+ push @cmds, $cmdstr;
}
}
+
+ foreach my $cmdstr (@cmds) {
+ ruleset_addrule($ruleset, $chain, $cmdstr);
+ }
}
sub ruleset_generate_rule_insert {
my $lc_direction = lc($direction);
+ my $in_accept = generate_nfqueue($options);
+
foreach my $rule (@$rules) {
next if $rule->{iface} && $rule->{iface} ne $netid;
next if !$rule->{enable};
} else {
next if $rule->{type} ne $lc_direction;
- if ($direction eq 'OUT') {
- ruleset_generate_rule($ruleset, $chain, $rule,
- { ACCEPT => "PVEFW-SET-ACCEPT-MARK", REJECT => "PVEFW-reject" }, undef, $cluster_conf);
- } else {
- my $accept = generate_nfqueue($options);
- ruleset_generate_rule($ruleset, $chain, $rule, { ACCEPT => $accept , REJECT => "PVEFW-reject" }, undef, $cluster_conf);
- }
+ eval {
+ if ($direction eq 'OUT') {
+ ruleset_generate_rule($ruleset, $chain, $rule,
+ { ACCEPT => "PVEFW-SET-ACCEPT-MARK", REJECT => "PVEFW-reject" },
+ undef, $cluster_conf);
+ } else {
+ ruleset_generate_rule($ruleset, $chain, $rule,
+ { ACCEPT => $in_accept , REJECT => "PVEFW-reject" },
+ undef, $cluster_conf);
+ }
+ };
+ warn $@ if $@;
}
}
}
sub generate_nfqueue {
my ($options) = @_;
- my $action = "";
- if($options->{ips}){
- $action = "NFQUEUE";
- if($options->{ips_queues} && $options->{ips_queues} =~ m/^(\d+)(:(\d+))?$/) {
- if(defined($3) && defined($1)) {
+ if ($options->{ips}) {
+ my $action = "NFQUEUE";
+ if ($options->{ips_queues} && $options->{ips_queues} =~ m/^(\d+)(:(\d+))?$/) {
+ if (defined($3) && defined($1)) {
$action .= " --queue-balance $1:$3";
- }elsif (defined($1)) {
+ } elsif (defined($1)) {
$action .= " --queue-num $1";
}
}
$action .= " --queue-bypass" if $feature_ipset_nomatch; #need kernel 3.10
- }else{
- $action = "ACCEPT";
+ return $action;
+ } else {
+ return "ACCEPT";
}
-
- return $action;
}
sub ruleset_generate_vm_ipsrules {
sub parse_clusterfw_alias {
my ($line) = @_;
- my ($opt, $value);
+ # we can add single line comments to the end of the line
+ my $comment = decode('utf8', $1) if $line =~ s/\s*#\s*(.*?)\s*$//;
+
if ($line =~ m/^(\S+)\s(\S+)$/) {
- $opt = lc($1);
- if($2){
- $2 =~ s|/32$||;
- pve_verify_ipv4_or_cidr($2) if $2;
- $value = $2;
- }
- } else {
- chomp $line;
- die "can't parse option '$line'\n";
+ my ($name, $cidr) = ($1, $2);
+ $cidr =~ s|/32$||;
+ pve_verify_ipv4_or_cidr($cidr);
+ my $data = {
+ name => $name,
+ cidr => $cidr,
+ };
+ $data->{comment} = $comment if $comment;
+ return $data;
}
- return ($opt, $value);
+ return undef;
}
sub parse_vm_fw_rules {
my $res = {
rules => [],
options => {},
+ aliases => {},
groups => {},
group_comments => {},
ipset => {} ,
warn "$prefix: $@" if $@;
} elsif ($section eq 'aliases') {
eval {
- my ($opt, $value) = parse_clusterfw_alias($line);
- $res->{aliases}->{$opt} = $value;
+ my $data = parse_clusterfw_alias($line);
+ $res->{aliases}->{lc($data->{name})} = $data;
};
warn "$prefix: $@" if $@;
} elsif ($section eq 'rules') {
return $raw;
};
+my $format_aliases = sub {
+ my ($aliases) = @_;
+
+ my $raw = '';
+
+ $raw .= "[ALIASES]\n\n";
+ foreach my $k (keys %$aliases) {
+ my $e = $aliases->{$k};
+ $raw .= "$e->{name} $e->{cidr}";
+ $raw .= " # " . encode('utf8', $e->{comment})
+ if $e->{comment} && $e->{comment} !~ m/^\s*$/;
+ $raw .= "\n";
+ }
+ $raw .= "\n";
+
+ return $raw;
+};
+
my $format_ipset = sub {
my ($options) = @_;
my $nethash = {};
foreach my $entry (@$options) {
my $cidr = $entry->{cidr};
- if ($cidr =~ m/^${ip_alias_pattern}$/){
- die "no such alias $cidr" if !$aliases->{$cidr};
- $entry->{cidr} = $aliases->{$cidr};
+ if ($cidr =~ m/^${ip_alias_pattern}$/) {
+ my $alias = lc($cidr);
+ if ($aliases->{$alias}) {
+ $entry->{cidr} = $aliases->{$alias}->{cidr};
+ $nethash->{$entry->{cidr}} = $entry;
+ } else {
+ warn "no such alias '$cidr'\n" if !$aliases->{$alias};
+ }
+ } else {
+ $nethash->{$entry->{cidr}} = $entry;
}
- $nethash->{$entry->{cidr}} = $entry;
}
foreach my $cidr (sort keys %$nethash) {
my $options = $cluster_conf->{options};
$raw .= &$format_options($options) if scalar(keys %$options);
+ my $aliases = $cluster_conf->{aliases};
+ $raw .= &$format_aliases($aliases) if scalar(keys %$aliases);
+
foreach my $ipset (sort keys %{$cluster_conf->{ipset}}) {
if (my $comment = $cluster_conf->{ipset_comments}->{$ipset}) {
my $utf8comment = encode('utf8', $comment);
enable_bridge_firewall();
- update_nf_conntrack_max($hostfw_conf);
-
- update_nf_conntrack_tcp_timeout_established($hostfw_conf);
-
my ($ipset_create_cmdlist, $ipset_delete_cmdlist, $ipset_changes) =
get_ipset_cmdlist($ipset_ruleset, undef, $verbose);
}
die "unable to apply firewall changes\n" if $errors;
+
+ update_nf_conntrack_max($hostfw_conf);
+
+ update_nf_conntrack_tcp_timeout_established($hostfw_conf);
+
}
sub update_nf_conntrack_max {