]> git.proxmox.com Git - pve-firewall.git/blobdiff - src/PVE/Firewall.pm
get_ipset_cmdlist: avoid restore problems due to wrong order
[pve-firewall.git] / src / PVE / Firewall.pm
index 77302a383b0f5777f65e9cf218a15922dd9391ee..4935be854957e974f2ee20d30d1412295c6b5513 100644 (file)
@@ -581,15 +581,17 @@ $pve_std_chains->{6} = {
         # simply DROP BROADCAST/MULTICAST/ANYCAST
         # we can use this to reduce logging
         #{ action => 'DROP', dsttype => 'BROADCAST' }, #no broadcast in ipv6
-        { action => 'DROP', dsttype => 'MULTICAST' },
-        { action => 'DROP', dsttype => 'ANYCAST' },
+       # ipv6 addrtype does not work with kernel 2.6.32
+       #{ action => 'DROP', dsttype => 'MULTICAST' },
+        #{ action => 'DROP', dsttype => 'ANYCAST' },
+        { action => 'DROP', dest => 'ff00::/8' },
         #{ action => 'DROP', dest => '224.0.0.0/4' },
     ],
     'PVEFW-reject' => [
         # same as shorewall 'reject'
         #{ action => 'DROP', dsttype => 'BROADCAST' },
         #{ action => 'DROP', source => '224.0.0.0/4' },
-        { action => 'DROP', proto => 'icmpv6' },
+       { action => 'DROP', proto => 'icmpv6' },
         "-p tcp -j REJECT --reject-with tcp-reset",
         #"-p udp -j REJECT --reject-with icmp-port-unreachable",
         #"-p icmp -j REJECT --reject-with icmp-host-unreachable",
@@ -599,7 +601,7 @@ $pve_std_chains->{6} = {
         # same as shorewall 'Drop', which is equal to DROP,
         # but REJECT/DROP some packages to reduce logging,
         # and ACCEPT critical ICMP types
-        { action => 'PVEFW-reject',  proto => 'tcp', dport => '43' }, # REJECT 'auth'
+       { action => 'PVEFW-reject', proto => 'tcp', dport => '43' }, # REJECT 'auth'
         # we are not interested in BROADCAST/MULTICAST/ANYCAST
         { action => 'PVEFW-DropBroadcast' },
         # ACCEPT critical ICMP types
@@ -610,15 +612,15 @@ $pve_std_chains->{6} = {
         # Drop packets with INVALID state
         "-m conntrack --ctstate INVALID -j DROP",
         # Drop Microsoft SMB noise
-        { action => 'DROP', proto => 'udp', dport => '135,445', nbdport => 2 },
-        { action => 'DROP', proto => 'udp', dport => '137:139'},
-        { action => 'DROP', proto => 'udp', dport => '1024:65535', sport => 137 },
-        { action => 'DROP', proto => 'tcp', dport => '135,139,445', nbdport => 3 },
-        { action => 'DROP', proto => 'udp', dport => 1900 }, # UPnP
+       { action => 'DROP', proto => 'udp', dport => '135,445', nbdport => 2 },
+       { action => 'DROP', proto => 'udp', dport => '137:139'},
+       { action => 'DROP', proto => 'udp', dport => '1024:65535', sport => 137 },
+       { action => 'DROP', proto => 'tcp', dport => '135,139,445', nbdport => 3 },
+       { action => 'DROP', proto => 'udp', dport => 1900 }, # UPnP
         # Drop new/NotSyn traffic so that it doesn't get logged
         "-p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -j DROP",
         # Drop DNS replies
-        { action => 'DROP', proto => 'udp', sport => 53 },
+       { action => 'DROP', proto => 'udp', sport => 53 },
     ],
     'PVEFW-Reject' => [
         # same as shorewall 'Reject', which is equal to Reject,
@@ -654,15 +656,6 @@ $pve_std_chains->{6} = {
         "-p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -g PVEFW-logflags",
         "-p tcp -m tcp --sport 0 --tcp-flags FIN,SYN,RST,ACK SYN -g PVEFW-logflags",
     ],
-    'PVEFW-smurfs' => [
-        #does smurf attack works with ipv6, as broadcast not exist ???
-
-        # same as shorewall smurfs action
-        # Filter packets for smurfs (packets with a broadcast address as the source).
-        #"-s 0.0.0.0/32 -j RETURN",
-        #"-m addrtype --src-type BROADCAST -g PVEFW-smurflog",
-        #"-s 224.0.0.0/4 -g PVEFW-smurflog",
-    ],
 };
 
 # iptables -p icmp -h
@@ -1434,19 +1427,19 @@ my $rule_format = "%-15s %-30s %-30s %-15s %-15s %-15s\n";
 sub iptables_restore_cmdlist {
     my ($cmdlist) = @_;
 
-    run_command("/sbin/iptables-restore -n", input => $cmdlist);
+    run_command("/sbin/iptables-restore -n", input => $cmdlist, errmsg => "iptables_restore_cmdlist");
 }
 
 sub ip6tables_restore_cmdlist {
     my ($cmdlist) = @_;
 
-    run_command("/sbin/ip6tables-restore -n", input => $cmdlist);
+    run_command("/sbin/ip6tables-restore -n", input => $cmdlist, errmsg => "iptables_restore_cmdlist");
 }
 
 sub ipset_restore_cmdlist {
     my ($cmdlist) = @_;
 
-    run_command("/usr/sbin/ipset restore", input => $cmdlist);
+    run_command("/usr/sbin/ipset restore", input => $cmdlist, errmsg => "ipset_restore_cmdlist");
 }
 
 sub iptables_get_chains {
@@ -1823,7 +1816,7 @@ sub ruleset_chain_add_conn_filters {
 }
 
 sub ruleset_chain_add_input_filters {
-    my ($ruleset, $chain, $options, $cluster_conf, $loglevel) = @_;
+    my ($ruleset, $chain, $options, $cluster_conf, $ipversion, $loglevel) = @_;
 
     if ($cluster_conf->{ipset}->{blacklist}){
        if (!ruleset_chain_exist($ruleset, "PVEFW-blacklist")) {
@@ -1836,7 +1829,9 @@ sub ruleset_chain_add_input_filters {
     }
 
     if (!(defined($options->{nosmurfs}) && $options->{nosmurfs} == 0)) {
-       ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate INVALID,NEW -j PVEFW-smurfs");
+       if ($ipversion == 4) {
+           ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate INVALID,NEW -j PVEFW-smurfs");
+       }
     }
 
     if ($options->{tcpflags}) {
@@ -2067,7 +2062,7 @@ sub enable_host_firewall {
     ruleset_addrule($ruleset, $chain, "-i lo -j ACCEPT");
 
     ruleset_chain_add_conn_filters($ruleset, $chain, 'ACCEPT');
-    ruleset_chain_add_input_filters($ruleset, $chain, $options, $cluster_conf, $loglevel);
+    ruleset_chain_add_input_filters($ruleset, $chain, $options, $cluster_conf, $ipversion, $loglevel);
 
     # we use RETURN because we need to check also tap rules
     my $accept_action = 'RETURN';
@@ -3104,7 +3099,7 @@ sub compile_iptables_filter {
     ruleset_addrule($ruleset, "PVEFW-INPUT", "-i venet0 -m set --match-set ${venet0_ipset_chain} src -j PVEFW-VENET-OUT");
 
     ruleset_create_chain($ruleset, "PVEFW-FWBR-IN");
-    ruleset_chain_add_input_filters($ruleset, "PVEFW-FWBR-IN", $hostfw_options, $cluster_conf, $loglevel);
+    ruleset_chain_add_input_filters($ruleset, "PVEFW-FWBR-IN", $hostfw_options, $cluster_conf, $ipversion, $loglevel);
 
     ruleset_addrule($ruleset, "PVEFW-FORWARD", "-m physdev --physdev-is-bridged --physdev-in fwln+ -j PVEFW-FWBR-IN");
 
@@ -3112,7 +3107,7 @@ sub compile_iptables_filter {
     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, $cluster_conf, $loglevel);
+    ruleset_chain_add_input_filters($ruleset, "PVEFW-VENET-IN", $hostfw_options, $cluster_conf, $ipversion, $loglevel);
 
     ruleset_addrule($ruleset, "PVEFW-FORWARD", "-o venet0 -m set --match-set ${venet0_ipset_chain} dst -j PVEFW-VENET-IN");
 
@@ -3337,7 +3332,9 @@ sub get_ipset_cmdlist {
        }
     }
 
-    foreach my $chain (sort keys %$ruleset) {
+    # create -v4 and -v6 chains first
+    foreach my $chain (keys %$ruleset) {
+       next if $chain !~ m/-v[46]$/;
        my $stat = $statushash->{$chain};
        die "internal error" if !$stat;
 
@@ -3348,7 +3345,20 @@ sub get_ipset_cmdlist {
        }
     }
 
-    foreach my $chain (sort keys %$ruleset) {
+    # then create list chains which use above -v4 and -v6 chains
+    foreach my $chain (keys %$ruleset) {
+       next if $chain =~ m/-v[46]$/;
+       my $stat = $statushash->{$chain};
+       die "internal error" if !$stat;
+
+       if ($stat->{action} eq 'create') {
+           foreach my $cmd (@{$ruleset->{$chain}}) {
+               $cmdlist .= "$cmd\n";
+           }
+       }
+    }
+
+    foreach my $chain (keys %$ruleset) {
        my $stat = $statushash->{$chain};
        die "internal error" if !$stat;
 
@@ -3365,8 +3375,19 @@ sub get_ipset_cmdlist {
        }
     }
 
-    foreach my $chain (sort keys %$statushash) {
+    # remove unused list chains first
+    foreach my $chain (keys %$statushash) {
+       next if $statushash->{$chain}->{action} ne 'delete';
+       next if $chain !~ m/-v[46]$/;
+
+       $delete_cmdlist .= "flush $chain\n";
+       $delete_cmdlist .= "destroy $chain\n";
+    }
+
+    # the remove unused -v4 -v6 chains
+    foreach my $chain (keys %$statushash) {
        next if $statushash->{$chain}->{action} ne 'delete';
+       next if $chain =~ m/-v[46]$/;
 
        $delete_cmdlist .= "flush $chain\n";
        $delete_cmdlist .= "destroy $chain\n";