]> git.proxmox.com Git - pve-firewall.git/blobdiff - src/PVE/Firewall.pm
rename link+ to fwln+
[pve-firewall.git] / src / PVE / Firewall.pm
index 8d0e187938db44a9ba9de1dfbf6805345b77fb2c..9098c0ecb8748034edd746701075a5d351eafd85 100644 (file)
@@ -1577,27 +1577,16 @@ sub generate_venet_rules_direction {
     my $accept_action = $direction eq 'OUT' ? "PVEFW-SET-ACCEPT-MARK" : $accept;
     ruleset_add_chain_policy($ruleset, $chain, $vmid, $policy, $loglevel, $accept_action);
 
-    # plug into FORWARD, INPUT and OUTPUT chain
     if ($direction eq 'OUT') {
        ruleset_generate_rule_insert($ruleset, "PVEFW-VENET-OUT", {
            action => $chain,
            source => $ip,
            iface_in => 'venet0'});
-
-       ruleset_generate_rule_insert($ruleset, "PVEFW-INPUT", {
-           action => $chain,
-           source => $ip,
-           iface_in => 'venet0'});
     } else {
        ruleset_generate_rule($ruleset, "PVEFW-VENET-IN", {
            action => $chain,
            dest => $ip,
            iface_out => 'venet0'});
-
-       ruleset_generate_rule($ruleset, "PVEFW-OUTPUT", {
-           action => $chain,
-           dest => $ip,
-           iface_out => 'venet0'});
     }
 }
 
@@ -2186,11 +2175,13 @@ sub read_local_vm_config {
 };
 
 sub load_vmfw_conf {
-    my ($vmid) = @_;
+    my ($vmid, $dir) = @_;
 
     my $vmfw_conf = {};
 
-    my $filename = "/etc/pve/firewall/$vmid.fw";
+    $dir = "/etc/pve/firewall" if !defined($dir);
+
+    my $filename = "$dir/$vmid.fw";
     if (my $fh = IO::File->new($filename, O_RDONLY)) {
        $vmfw_conf = parse_vm_fw_rules($filename, $fh);
     }
@@ -2307,11 +2298,12 @@ sub save_vmfw_conf {
 }
 
 sub read_vm_firewall_configs {
-    my ($vmdata) = @_;
+    my ($vmdata, $dir) = @_;
+
     my $vmfw_configs = {};
 
     foreach my $vmid (keys %{$vmdata->{qemu}}, keys %{$vmdata->{openvz}}) {
-       my $vmfw_conf = load_vmfw_conf($vmid);
+       my $vmfw_conf = load_vmfw_conf($vmid, $dir);
        next if !$vmfw_conf->{options}; # skip if file does not exists
        $vmfw_configs->{$vmid} = $vmfw_conf;
     }
@@ -2455,10 +2447,13 @@ sub read_pvefw_status {
 }
 
 sub load_clusterfw_conf {
+    my ($filename) = @_;
+
+    $filename = $clusterfw_conf_filename if !defined($filename);
 
     my $cluster_conf = {};
-     if (my $fh = IO::File->new($clusterfw_conf_filename, O_RDONLY)) {
-       $cluster_conf = parse_cluster_fw_rules($clusterfw_conf_filename, $fh);
+    if (my $fh = IO::File->new($filename, O_RDONLY)) {
+       $cluster_conf = parse_cluster_fw_rules($filename, $fh);
     }
 
     return $cluster_conf;
@@ -2511,10 +2506,13 @@ sub save_clusterfw_conf {
 }
 
 sub load_hostfw_conf {
+    my ($filename) = @_;
+
+    $filename = $hostfw_conf_filename if !defined($filename);
 
     my $hostfw_conf = {};
-    if (my $fh = IO::File->new($hostfw_conf_filename, O_RDONLY)) {
-       $hostfw_conf = parse_host_fw_rules($hostfw_conf_filename, $fh);
+    if (my $fh = IO::File->new($filename, O_RDONLY)) {
+       $hostfw_conf = parse_host_fw_rules($filename, $fh);
     }
     return $hostfw_conf;
 }
@@ -2538,13 +2536,30 @@ sub save_hostfw_conf {
 }
 
 sub compile {
-    my ($cluster_conf, $hostfw_conf) = @_;
+    my ($cluster_conf, $hostfw_conf, $vmdata) = @_;
+
+    my $vmfw_configs;
+
+    if ($vmdata) { # test mode
+       my $testdir = $vmdata->{testdir} || die "no test directory specified";
+       my $filename = "$testdir/cluster.fw";
+       die "missing test file '$filename'\n" if ! -f $filename;
+       $cluster_conf = load_clusterfw_conf($filename);
+
+       $filename = "$testdir/host.fw";
+       die "missing test file '$filename'\n" if ! -f $filename;
+       $hostfw_conf = load_hostfw_conf($filename);
+
+       $vmfw_configs = read_vm_firewall_configs($vmdata, $testdir);
+    } else { # normal operation
+       $cluster_conf = load_clusterfw_conf() if !$cluster_conf;
 
-    $cluster_conf = load_clusterfw_conf() if !$cluster_conf;
-    $hostfw_conf = load_hostfw_conf() if !$hostfw_conf;
+       $hostfw_conf = load_hostfw_conf() if !$hostfw_conf;
+
+       $vmdata = read_local_vm_config();
+       $vmfw_configs = read_vm_firewall_configs($vmdata);
+    }
 
-    my $vmdata = read_local_vm_config();
-    my $vmfw_configs = read_vm_firewall_configs($vmdata);
 
     my $ipset_ruleset = {};
     generate_ipset_chains($ipset_ruleset, $cluster_conf);
@@ -2561,10 +2576,7 @@ sub compile {
     # fixme: what log level should we use here?
     my $loglevel = get_option_log_level($hostfw_options, "log_level_out");
 
-    my $accept = ruleset_chain_exist($ruleset, "PVEFW-IPS") ? "PVEFW-IPS" : "ACCEPT";
-    ruleset_chain_add_conn_filters($ruleset, "PVEFW-FORWARD", $accept);
-
-    #ruleset_chain_add_conn_filters($ruleset, "PVEFW-FORWARD", $hostfw_options, $accept);
+    ruleset_chain_add_conn_filters($ruleset, "PVEFW-FORWARD", "ACCEPT");
 
     if ($cluster_conf->{ipset}->{blacklist}){
        ruleset_addlog($ruleset, "PVEFW-FORWARD", 0, "DROP: ", $loglevel, "-m set --match-set PVEFW-blacklist src");
@@ -2573,14 +2585,15 @@ sub compile {
 
     ruleset_create_chain($ruleset, "PVEFW-VENET-OUT");
     ruleset_addrule($ruleset, "PVEFW-FORWARD", "-i venet0 -j PVEFW-VENET-OUT");
+    ruleset_addrule($ruleset, "PVEFW-INPUT", "-i venet0 -j PVEFW-VENET-OUT");
 
     ruleset_create_chain($ruleset, "PVEFW-FWBR-IN");
     ruleset_chain_add_input_filters($ruleset, "PVEFW-FWBR-IN", $hostfw_options);
 
-    ruleset_addrule($ruleset, "PVEFW-FORWARD", "-m physdev --physdev-is-bridged --physdev-in link+ -j PVEFW-FWBR-IN");
+    ruleset_addrule($ruleset, "PVEFW-FORWARD", "-m physdev --physdev-is-bridged --physdev-in fwln+ -j PVEFW-FWBR-IN");
 
     ruleset_create_chain($ruleset, "PVEFW-FWBR-OUT");
-    ruleset_addrule($ruleset, "PVEFW-FORWARD", "-m physdev --physdev-is-bridged --physdev-out link+ -j PVEFW-FWBR-OUT");
+    ruleset_addrule($ruleset, "PVEFW-FORWARD", "-m physdev --physdev-is-bridged --physdev-out fwln+ -j PVEFW-FWBR-OUT");
 
     ruleset_create_chain($ruleset, "PVEFW-VENET-IN");
     ruleset_chain_add_input_filters($ruleset, "PVEFW-VENET-IN", $hostfw_options);
@@ -2593,6 +2606,8 @@ sub compile {
 
     enable_host_firewall($ruleset, $hostfw_conf, $cluster_conf) if $hostfw_enable;
 
+    ruleset_addrule($ruleset, "PVEFW-OUTPUT", "-o venet0 -j PVEFW-VENET-IN");
+
     # generate firewall rules for QEMU VMs
     foreach my $vmid (keys %{$vmdata->{qemu}}) {
        my $conf = $vmdata->{qemu}->{$vmid};
@@ -2624,6 +2639,7 @@ sub compile {
 
        if ($conf->{ip_address} && $conf->{ip_address}->{value}) {
            my $ip = $conf->{ip_address}->{value};
+           $ip =~ s/\s/,/g;  
            generate_venet_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $vmfw_conf, $vmid, $ip, 'IN');
            generate_venet_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $vmfw_conf, $vmid, $ip, 'OUT');
        }
@@ -2643,6 +2659,10 @@ sub compile {
        }
     }
 
+    if(ruleset_chain_exist($ruleset, "PVEFW-IPS")){
+       ruleset_insertrule($ruleset, "PVEFW-FORWARD", "-m conntrack --ctstate RELATED,ESTABLISHED -j PVEFW-IPS");
+    }
+
     return ($ruleset, $ipset_ruleset);
 }