use IO::File;
use Net::IP;
use PVE::Tools qw(run_command lock_file);
+use Encode;
# dynamically include PVE::QemuServer and PVE::OpenVZ
# to avoid dependency problems
sub ruleset_generate_cmdstr {
my ($ruleset, $chain, $rule, $actions, $goto) = @_;
- return if $rule->{disable};
+ return if !$rule->{enable};
my @cmd = ();
}
if (!(defined($options->{dhcp}) && $options->{dhcp} == 0)) {
- ruleset_addrule($ruleset, $chain, "-p udp -m udp --dport 67:68 -j ACCEPT");
+ if ($direction eq 'OUT') {
+ ruleset_addrule($ruleset, $chain, "-p udp -m udp --sport 68 --dport 67 -j PVEFW-SET-ACCEPT-MARK");
+ } else {
+ ruleset_addrule($ruleset, $chain, "-p udp -m udp --sport 67 --dport 68 -j ACCEPT");
+ }
}
if ($options->{tcpflags}) {
foreach my $rule (@$rules) {
next if $rule->{iface} && $rule->{iface} ne $netid;
- next if $rule->{disable};
+ next if !$rule->{enable};
if ($rule->{type} eq 'group') {
my $group_chain = "GROUP-$rule->{action}-$direction";
if(!ruleset_chain_exist($ruleset, $group_chain)){
my $loglevel = get_option_log_level($options, "log_level_in");
+ if (!(defined($options->{nosmurfs}) && $options->{nosmurfs} == 0)) {
+ ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate INVALID,NEW -j PVEFW-smurfs");
+ }
+
+ if ($options->{tcpflags}) {
+ ruleset_addrule($ruleset, $chain, "-p tcp -j PVEFW-tcpflags");
+ }
+
ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate INVALID -j DROP");
ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT");
ruleset_addrule($ruleset, $chain, "-i lo -j ACCEPT");
sub generate_group_rules {
my ($ruleset, $groups_conf, $group) = @_;
-
- die "no such security group '$group'\n" if !$groups_conf->{$group};
+ die "no such security group '$group'\n" if !$groups_conf->{rules}->{$group};
my $rules = $groups_conf->{rules}->{$group};
my ($type, $action, $iface, $source, $dest, $proto, $dport, $sport);
# we can add single line comments to the end of the rule
- my $comment = $1 if $line =~ s/#\s*(.*?)\s*$//;
+ my $comment = decode('utf8', $1) if $line =~ s/#\s*(.*?)\s*$//;
# we can disable a rule when prefixed with '|'
- my $disable = 1 if $line =~ s/^\|//;
+ my $enable = 1;
+
+ $enable = 0 if $line =~ s/^\|//;
my @data = split(/\s+/, $line);
my $expected_elements = $need_iface ? 8 : 7;
my $param = {
type => $type,
- disable => $disable,
+ enable => $enable,
comment => $comment,
action => $action,
iface => $iface,
my $section;
+ my $digest = Digest::SHA->new('sha1');
+
while (defined(my $line = <$fh>)) {
+ $digest->add($line);
+
next if $line =~ m/^#/;
next if $line =~ m/^\s*$/;
push @{$res->{$section}}, @$rules;
}
+ $res->{digest} = $digest->b64digest;
+
return $res;
}
return $vmdata;
};
+sub load_vmfw_conf {
+ my ($vmid) = @_;
+
+ my $vmfw_conf = {};
+
+ my $filename = "/etc/pve/firewall/$vmid.fw";
+ if (my $fh = IO::File->new($filename, O_RDONLY)) {
+ $vmfw_conf = parse_vm_fw_rules($filename, $fh);
+ }
+
+ return $vmfw_conf;
+}
+
sub read_vm_firewall_configs {
my ($vmdata) = @_;
my $vmfw_configs = {};
foreach my $vmid (keys %{$vmdata->{qemu}}, keys %{$vmdata->{openvz}}) {
- my $filename = "/etc/pve/firewall/$vmid.fw";
- my $fh = IO::File->new($filename, O_RDONLY);
- next if !$fh;
-
- $vmfw_configs->{$vmid} = parse_vm_fw_rules($filename, $fh);
+ my $vmfw_conf = load_vmfw_conf($vmid);
+ next if !$vmfw_conf->{options}; # skip if file does not exists
+ $vmfw_configs->{$vmid} = $vmfw_conf;
}
return $vmfw_configs;
}
}
- # fixme: this is an optimization? if so, we should also drop INVALID packages?
- ruleset_insertrule($ruleset, "PVEFW-FORWARD", "-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT");
-
# fixme: what log level should we use here?
my $loglevel = get_option_log_level($hostfw_options, "log_level_out");