optional => 1,
});
-my $security_group_pattern = '[A-Za-z][A-Za-z0-9\-\_]+';
+my $security_group_name_pattern = '[A-Za-z][A-Za-z0-9\-\_]+';
+my $ip_alias_pattern = '[A-Za-z][A-Za-z0-9\-\_]+';
PVE::JSONSchema::register_standard_option('pve-security-group-name', {
description => "Security Group name.",
type => 'string',
- pattern => $security_group_pattern,
+ pattern => $security_group_name_pattern,
minLength => 2,
maxLength => 20,
});
my ($str) = @_;
return if $str =~ m/^(\+)(\S+)$/; # ipset ref
- return if $str =~ m/^${security_group_pattern}$/; # aliases
+ return if $str =~ m/^${ip_alias_pattern}$/;
my $count = 0;
my $iprange = 0;
description => "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.",
type => 'string',
optional => 1,
- pattern => $security_group_pattern,
+ pattern => $security_group_name_pattern,
maxLength => 20,
minLength => 2,
},
raise_param_exc({ type => "security groups not allowed"})
if !$allow_groups;
raise_param_exc({ action => "invalid characters in security group name"})
- if $rule->{action} !~ m/^${security_group_pattern}$/;
+ if $rule->{action} !~ m/^${security_group_name_pattern}$/;
} else {
raise_param_exc({ type => "unknown rule type '$type'"});
}
return 1 if $name =~ m/^venet0-\d+-(:?IN|OUT)$/;
- return 1 if $name =~ m/^vmbr\d+-(:?FW|IN|OUT|IPS)$/;
+ return 1 if $name =~ m/^vmbr\d+(v\d+)?-(:?FW|IN|OUT|IPS)$/;
return 1 if $name =~ m/^GROUP-(:?[^\s\-]+)-(:?IN|OUT)$/;
return undef;
my $dest = $rule->{dest};
if ($source) {
- if ($source =~ m/^(\+)(\S+)$/) {
- die "no such ipset $2" if !$cluster_conf->{ipset}->{$2};
- push @cmd, "-m set --match-set PVEFW-$2 src";
-
- } elsif ($source =~ m/^${security_group_pattern}$/){
- die "no such alias $source" if !$cluster_conf->{aliases}->{$source};
+ if ($source =~ m/^\+/) {
+ if ($source =~ m/^\+(${security_group_name_pattern})$/) {
+ die "no such ipset '$1'\n" if !$cluster_conf->{ipset}->{$1};
+ push @cmd, "-m set --match-set PVEFW-$1 src";
+ } else {
+ 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}";
} elsif ($source =~ m/\-/){
}
if ($dest) {
- if ($dest =~ m/^(\+)(\S+)$/) {
- die "no such ipset $2" if !$cluster_conf->{ipset}->{$2};
- push @cmd, "-m set --match-set PVEFW-$2 dst";
-
- } elsif ($dest =~ m/^${security_group_pattern}$/){
+ if ($dest =~ m/^\+/) {
+ if ($dest =~ m/^\+(${security_group_name_pattern})$/) {
+ die "no such ipset '$1'\n" if !$cluster_conf->{ipset}->{$1};
+ push @cmd, "-m set --match-set PVEFW-$1 dst";
+ } else {
+ 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}";
$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};
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);
+ ruleset_generate_rule($ruleset, $chain, $rule, { ACCEPT => $in_accept , REJECT => "PVEFW-reject" }, undef, $cluster_conf);
}
}
}
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 {
die "wrong number of rule elements\n" if scalar(@data) != 3;
die "groups disabled\n" if !$allow_groups;
- die "invalid characters in group name\n" if $action !~ m/^${security_group_pattern}$/;
+ die "invalid characters in group name\n" if $action !~ m/^${security_group_name_pattern}$/;
} else {
die "unknown rule type '$type'\n";
}
my $nomatch = $1;
my $cidr = $2;
- if($cidr !~ m/^${security_group_pattern}$/) {
+ if($cidr !~ m/^${ip_alias_pattern}$/) {
$cidr =~ s|/32$||;
eval { pve_verify_ipv4_or_cidr($cidr); };
my $nethash = {};
foreach my $entry (@$options) {
my $cidr = $entry->{cidr};
- #check aliases
- if ($cidr =~ m/^${security_group_pattern}$/){
- die "no such alias $cidr" if !$aliases->{$cidr};
- $entry->{cidr} = $aliases->{$cidr};
+ if ($cidr =~ m/^${ip_alias_pattern}$/) {
+ if ($aliases->{$cidr}) {
+ $entry->{cidr} = $aliases->{$cidr};
+ } else {
+ warn "no such alias '$cidr'\n" if !$aliases->{$cidr};
+ }
}
$nethash->{$entry->{cidr}} = $entry;
}
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 {