X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;ds=sidebyside;f=src%2FPVE%2FFirewall.pm;h=ac89966308cd3979ae5db90e778bde44d1d0ddaf;hb=7dd132596c318b4cce431494adec86b5a3110e16;hp=01de542d3305e8dc397ad15110eab2d5775bd0b3;hpb=6b8ca015bec1fec9476c3b5236379d8507a7d5fd;p=pve-firewall.git diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm index 01de542..ac89966 100644 --- a/src/PVE/Firewall.pm +++ b/src/PVE/Firewall.pm @@ -56,6 +56,14 @@ PVE::JSONSchema::register_standard_option('ipset-name', { 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', @@ -1214,9 +1222,10 @@ sub ruleset_generate_cmdstr { 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"; @@ -1234,9 +1243,10 @@ sub ruleset_generate_cmdstr { 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"; @@ -1525,12 +1535,18 @@ sub ruleset_generate_vm_rules { } 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 { - ruleset_generate_rule($ruleset, $chain, $rule, { ACCEPT => $in_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 $@; } } } @@ -1936,20 +1952,22 @@ sub parse_clusterfw_option { 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 { @@ -2057,6 +2075,7 @@ sub parse_cluster_fw_rules { my $res = { rules => [], options => {}, + aliases => {}, groups => {}, group_comments => {}, ipset => {} , @@ -2118,8 +2137,8 @@ sub parse_cluster_fw_rules { 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') { @@ -2293,6 +2312,24 @@ my $format_options = sub { 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) = @_; @@ -2422,13 +2459,16 @@ sub generate_ipset { foreach my $entry (@$options) { my $cidr = $entry->{cidr}; if ($cidr =~ m/^${ip_alias_pattern}$/) { - if ($aliases->{$cidr}) { - $entry->{cidr} = $aliases->{$cidr}; + 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->{$cidr}; + warn "no such alias '$cidr'\n" if !$aliases->{$alias}; } + } else { + $nethash->{$entry->{cidr}} = $entry; } - $nethash->{$entry->{cidr}} = $entry; } foreach my $cidr (sort keys %$nethash) { @@ -2525,6 +2565,9 @@ sub save_clusterfw_conf { 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);