From dba740a9c766f1584f06b87747069740fb333fcd Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Mon, 19 May 2014 07:53:00 +0200 Subject: [PATCH] change rule format: use named parameters --- debian/example/100.fw | 34 +++++++----- debian/example/cluster.fw | 18 +++---- debian/example/host.fw | 4 +- src/PVE/Firewall.pm | 100 +++++++++++++++++++++--------------- test/test-basic1/100.fw | 4 +- test/test-basic1/200.fw | 4 +- test/test-basic1/host.fw | 8 +-- test/test-group1/100.fw | 10 ++-- test/test-group1/200.fw | 8 +-- test/test-group1/cluster.fw | 12 ++--- test/test-ipset1/host.fw | 4 +- 11 files changed, 114 insertions(+), 92 deletions(-) diff --git a/debian/example/100.fw b/debian/example/100.fw index 5ccdcae..dffd144 100644 --- a/debian/example/100.fw +++ b/debian/example/100.fw @@ -32,23 +32,29 @@ ips_queues: 0:3 [RULES] -#TYPE ACTION IFACE SOURCE DEST PROTO D-PORT S-PORT - -IN SSH(ACCEPT) net0 -IN SSH(ACCEPT) net0 # a comment -IN SSH(ACCEPT) net0 192.168.2.192 # only allow SSH from 192.168.2.192 -IN SSH(ACCEPT) net0 10.0.0.1-10.0.0.10 #accept SSH for ip in range 10.0.0.1 to 10.0.0.10 -IN SSH(ACCEPT) net0 10.0.0.1,10.0.0.2,10.0.0.3 #accept ssh for 10.0.0.1 or 10.0.0.2 or 10.0.0.3 -IN SSH(ACCEPT) net0 +mynetgroup #accept ssh for netgroup mynetgroup -IN SSH(ACCEPT) net0 myserveralias #accept ssh for alias myserveralias - -|IN SSH(ACCEPT) net0 # disabled rule +#TYPE ACTION [OPTIONS] +# -i +# -source +# -dest +# -p +# -dport +# -sport + +IN SSH(ACCEPT) -i net0 +IN SSH(ACCEPT) -i net0 # a comment +IN SSH(ACCEPT) -i net0 -source 192.168.2.192 # only allow SSH from 192.168.2.192 +IN SSH(ACCEPT) -i net0 -source 10.0.0.1-10.0.0.10 #accept SSH for ip in range 10.0.0.1 to 10.0.0.10 +IN SSH(ACCEPT) -i net0 -source 10.0.0.1,10.0.0.2,10.0.0.3 #accept ssh for 10.0.0.1 or 10.0.0.2 or 10.0.0.3 +IN SSH(ACCEPT) -i net0 -source +mynetgroup #accept ssh for netgroup mynetgroup +IN SSH(ACCEPT) -i net0 -source myserveralias #accept ssh for alias myserveralias + +|IN SSH(ACCEPT) -i net0 # disabled rule # add a security group -GROUP group1 net0 +GROUP group1 -i net0 -OUT DNS(ACCEPT) net0 -OUT Ping(ACCEPT) net0 +OUT DNS(ACCEPT) -i net0 +OUT Ping(ACCEPT) -i net0 OUT SSH(ACCEPT) diff --git a/debian/example/cluster.fw b/debian/example/cluster.fw index 1708c98..daa9ef5 100644 --- a/debian/example/cluster.fw +++ b/debian/example/cluster.fw @@ -14,21 +14,21 @@ mynetworkalias 10.0.0.0/24 [RULES] -IN SSH(ACCEPT) vmbr0 +IN SSH(ACCEPT) -i vmbr0 [group group1] -IN ACCEPT - - tcp 22 - -OUT ACCEPT - - tcp 80 - -OUT ACCEPT - - icmp - - +IN ACCEPT -p tcp -dport 22 +OUT ACCEPT -p tcp -dport 80 +OUT ACCEPT -p icmp [group group3] -IN ACCEPT 10.0.0.1 -IN ACCEPT 10.0.0.1-10.0.0.10 -IN ACCEPT 10.0.0.1,10.0.0.2,10.0.0.3 -IN ACCEPT +mynetgroup -IN ACCEPT myserveralias +IN ACCEPT -source 10.0.0.1 +IN ACCEPT -source 10.0.0.1-10.0.0.10 +IN ACCEPT -source 10.0.0.1,10.0.0.2,10.0.0.3 +IN ACCEPT -source +mynetgroup +IN ACCEPT -source myserveralias [ipset myipset] diff --git a/debian/example/host.fw b/debian/example/host.fw index 96eacc6..4e51c83 100644 --- a/debian/example/host.fw +++ b/debian/example/host.fw @@ -22,5 +22,5 @@ tcpflags: 1 [RULES] -IN SSH(ACCEPT) - -OUT SSH(ACCEPT) - +IN SSH(ACCEPT) +OUT SSH(ACCEPT) diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm index be5354c..be9cc5a 100644 --- a/src/PVE/Firewall.pm +++ b/src/PVE/Firewall.pm @@ -1000,7 +1000,10 @@ sub verify_rule { raise_param_exc({ type => "unknown rule type '$type'"}); } - # fixme: verify $rule->{iface}? + if ($rule->{iface}) { + eval { PVE::JSONSchema::pve_verify_iface($rule->{iface}); }; + raise_param_exc({ iface => $@ }) if $@; + } if ($rule->{macro}) { my $preferred_name = $pve_fw_preferred_macro_names->{lc($rule->{macro})}; @@ -1764,9 +1767,11 @@ for (my $i = 0; $i < $MAX_NETS; $i++) { } sub parse_fw_rule { - my ($line, $need_iface, $allow_groups) = @_; + my ($line, $allow_iface, $allow_groups) = @_; - my ($type, $action, $iface, $source, $dest, $proto, $dport, $sport); + my ($type, $action, $macro, $iface, $source, $dest, $proto, $dport, $sport); + + chomp $line; # we can add single line comments to the end of the rule my $comment = decode('utf8', $1) if $line =~ s/#\s*(.*?)\s*$//; @@ -1776,22 +1781,11 @@ sub parse_fw_rule { $enable = 0 if $line =~ s/^\|//; - my @data = split(/\s+/, $line); - my $expected_elements = $need_iface ? 8 : 7; - - die "wrong number of rule elements\n" if scalar(@data) > $expected_elements; - - if ($need_iface) { - ($type, $action, $iface, $source, $dest, $proto, $dport, $sport) = @data - } else { - ($type, $action, $source, $dest, $proto, $dport, $sport) = @data; - } - - die "incomplete rule\n" if ! ($type && $action); - - my $macro; - - $type = lc($type); + $line =~ s/^(\S+)\s+(\S+)\s*// || + die "unable to parse rule: $line\n"; + + $type = lc($1); + $action = $2; if ($type eq 'in' || $type eq 'out') { if ($action =~ m/^(ACCEPT|DROP|REJECT)$/) { @@ -1805,32 +1799,52 @@ sub parse_fw_rule { die "unknown action '$action'\n"; } } elsif ($type eq 'group') { - 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_name_pattern}$/; } else { die "unknown rule type '$type'\n"; } - if ($need_iface) { - $iface = undef if $iface && $iface eq '-'; - } - - $proto = undef if $proto && $proto eq '-'; - pve_fw_verify_protocol_spec($proto) if $proto; + while (length($line)) { + if ($line =~ s/^-i (\S+)\s*//) { + die "parameter -i not allowed\n" if !$allow_iface; + $iface = $1; + PVE::JSONSchema::pve_verify_iface($iface); + next; + } - $source = undef if $source && $source eq '-'; - $dest = undef if $dest && $dest eq '-'; + last if $type eq 'group'; - $dport = undef if $dport && $dport eq '-'; - $sport = undef if $sport && $sport eq '-'; + if ($line =~ s/^-p (\S+)\s*//) { + $proto = $1; + pve_fw_verify_protocol_spec($proto); + next; + } + if ($line =~ s/^-dport (\S+)\s*//) { + $dport = $1; + parse_port_name_number_or_range($dport); + next; + } + if ($line =~ s/^-sport (\S+)\s*//) { + $sport = $1; + parse_port_name_number_or_range($sport); + next; + } + if ($line =~ s/^-source (\S+)\s*//) { + $source = $1; + parse_address_list($source); + next; + } + if ($line =~ s/^-dest (\S+)\s*//) { + $dest = $1; + parse_address_list($dest); + next; + } - parse_port_name_number_or_range($dport) if defined($dport); - parse_port_name_number_or_range($sport) if defined($sport); + last; + } - parse_address_list($source) if $source; - parse_address_list($dest) if $dest; + die "unable to parse rule parameters: $line\n" if length($line); return { type => $type, @@ -2218,7 +2232,7 @@ sub load_vmfw_conf { } my $format_rules = sub { - my ($rules, $need_iface) = @_; + my ($rules, $allow_iface) = @_; my $raw = ''; @@ -2231,14 +2245,16 @@ my $format_rules = sub { } else { $raw .= " " . $rule->{action}; } - $raw .= " " . ($rule->{iface} || '-') if $need_iface; + if ($allow_iface && $rule->{iface}) { + $raw .= " -i $rule->{iface}"; + } if ($rule->{type} ne 'group') { - $raw .= " " . ($rule->{source} || '-'); - $raw .= " " . ($rule->{dest} || '-'); - $raw .= " " . ($rule->{proto} || '-'); - $raw .= " " . ($rule->{dport} || '-'); - $raw .= " " . ($rule->{sport} || '-'); + $raw .= " -source $rule->{source}" if $rule->{source}; + $raw .= " -dest $rule->{dest}" if $rule->{dest}; + $raw .= " -p $rule->{proto}" if $rule->{proto}; + $raw .= " -dport $rule->{dport}" if $rule->{dport}; + $raw .= " -sport $rule->{sport}" if $rule->{sport}; } $raw .= " # " . encode('utf8', $rule->{comment}) diff --git a/test/test-basic1/100.fw b/test/test-basic1/100.fw index efd738a..c9d675e 100644 --- a/test/test-basic1/100.fw +++ b/test/test-basic1/100.fw @@ -4,5 +4,5 @@ enable: 1 [RULES] -IN ACCEPT - - - tcp 443 -OUT REJECT - - - tcp 81 +IN ACCEPT -p tcp -dport 443 +OUT REJECT -p tcp -dport 81 diff --git a/test/test-basic1/200.fw b/test/test-basic1/200.fw index 46189b2..86186fd 100644 --- a/test/test-basic1/200.fw +++ b/test/test-basic1/200.fw @@ -4,5 +4,5 @@ enable: 1 [RULES] -IN ACCEPT - - - tcp 22 -OUT REJECT - - - tcp 81 +IN ACCEPT -p tcp -dport 22 +OUT REJECT -p tcp -dport 81 diff --git a/test/test-basic1/host.fw b/test/test-basic1/host.fw index 1021ee0..3431f03 100644 --- a/test/test-basic1/host.fw +++ b/test/test-basic1/host.fw @@ -4,7 +4,7 @@ enable: 1 [RULES] -OUT REJECT - - - tcp 81 -IN ACCEPT - - - tcp 22 -IN REJECT vmbr0 - - tcp 100 -IN REJECT vmbr1 - - tcp 101 +OUT REJECT -p tcp -dport 81 +IN ACCEPT -p tcp -dport 22 +IN REJECT -i vmbr0 -p tcp -dport 100 +IN REJECT -i vmbr1 -p tcp -dport 101 diff --git a/test/test-group1/100.fw b/test/test-group1/100.fw index 7b2581a..7ab0e23 100644 --- a/test/test-group1/100.fw +++ b/test/test-group1/100.fw @@ -1,8 +1,8 @@ [RULES] -IN ACCEPT - 192.168.2.1 - tcp 22 -IN ACCEPT - 192.168.2.1 - tcp 80 -IN ACCEPT - 127.0.0.1 - tcp 80 +IN ACCEPT -source 192.168.2.1 -p tcp -dport 22 +IN ACCEPT -source 192.168.2.1 -p tcp -dport 80 +IN ACCEPT -source 127.0.0.1 -p tcp -dport 80 -IN ACCEPT net0 192.168.5.0/24 - tcp 22 -GROUP group2 net0 \ No newline at end of file +IN ACCEPT -i net0 -source 192.168.5.0/24 -p tcp -dport 22 +GROUP group2 -i net0 \ No newline at end of file diff --git a/test/test-group1/200.fw b/test/test-group1/200.fw index b83456a..6653c44 100644 --- a/test/test-group1/200.fw +++ b/test/test-group1/200.fw @@ -1,7 +1,7 @@ [RULES] -IN ACCEPT - 192.168.2.1 - tcp 22 -IN ACCEPT - 192.168.2.1 - tcp 80 -IN ACCEPT - 127.0.0.1 - tcp 80 +IN ACCEPT -source 192.168.2.1 -p tcp -dport 22 +IN ACCEPT -source 192.168.2.1 -p tcp -dport 80 +IN ACCEPT -source 127.0.0.1 -p tcp -dport 80 -GROUP group3 venet \ No newline at end of file +GROUP group3 -i venet \ No newline at end of file diff --git a/test/test-group1/cluster.fw b/test/test-group1/cluster.fw index 0b24d0e..005681d 100644 --- a/test/test-group1/cluster.fw +++ b/test/test-group1/cluster.fw @@ -4,15 +4,15 @@ enable: 1 [GROUP group1] -IN ACCEPT 192.168.2.0/24 - tcp 22 -IN REJECT 192.168.2.0/24 - tcp 80 -OUT REJECT 192.168.2.0/24 - tcp 80 -OUT REJECT - - tcp 443 +IN ACCEPT -source 192.168.2.0/24 -p tcp -dport 22 +IN REJECT -source 192.168.2.0/24 -p tcp -dport 80 +OUT REJECT -source 192.168.2.0/24 -p tcp -dport 80 +OUT REJECT -p tcp -dport 443 [GROUP group2] -IN ACCEPT 192.168.3.0/24 - tcp 22 +IN ACCEPT -source 192.168.3.0/24 -p tcp -dport 22 [GROUP group3] -IN ACCEPT 192.168.6.0/24 - tcp 22 +IN ACCEPT -source 192.168.6.0/24 -p tcp -dport 22 diff --git a/test/test-ipset1/host.fw b/test/test-ipset1/host.fw index 4d7200e..d983967 100644 --- a/test/test-ipset1/host.fw +++ b/test/test-ipset1/host.fw @@ -2,7 +2,7 @@ [RULES] -IN REJECT - +myipset +dmzhosts tcp 22 +IN REJECT -source +myipset -dest +dmzhosts -p tcp -dport 22 -IN ACCEPT - +myipset - tcp 22 +IN ACCEPT -source +myipset -p tcp -dport 22 -- 2.39.2