[LON-CAPA-cvs] cvs: loncom / lciptables /configuration Firewall.pm /init.d loncontrol

raeburn raeburn at source.lon-capa.org
Sat Jun 8 22:35:45 EDT 2019


raeburn		Sun Jun  9 02:35:45 2019 EDT

  Modified files:              
    /loncom	lciptables 
    /loncom/init.d	loncontrol 
    /loncom/configuration	Firewall.pm 
  Log:
  - Dynamic management of LON-CAPA port 5663 compatible with firewalld
    - &get_default_zone(() provides default zone
    - Revert changes in rev. 1.17 to &uses_firewalld() -- now returns
      1 if firewalld in use, but not the default zone.
    - Additional arg, value = 1 if firewalld in use  is passed to 
      &firewall_open_port(), &firewall_close_port(),
      &firewall_is_port_open(), &firewall_close_anywhere()
  
  
-------------- next part --------------
Index: loncom/lciptables
diff -u loncom/lciptables:1.8 loncom/lciptables:1.9
--- loncom/lciptables:1.8	Wed Oct 24 15:11:19 2018
+++ loncom/lciptables	Sun Jun  9 02:35:37 2019
@@ -2,7 +2,7 @@
 #
 # The Learning Online Network with CAPA
 #
-# $Id: lciptables,v 1.8 2018/10/24 15:11:19 raeburn Exp $
+# $Id: lciptables,v 1.9 2019/06/09 02:35:37 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -109,7 +109,7 @@
     &Exit(3);
 }
 
-my $firewalld = &LONCAPA::Firewall::uses_firewalld();
+my ($firewalld) = &LONCAPA::Firewall::uses_firewalld();
 
 &EnableRoot();
 my @fw_chains = &LONCAPA::Firewall::get_fw_chains();
@@ -117,9 +117,9 @@
     $<=0;
 }
 $opened =
-    &LONCAPA::Firewall::firewall_close_port($iptables,\@fw_chains,$lond_port,\%iphost,[$lond_port]);
+    &LONCAPA::Firewall::firewall_close_port($iptables,\@fw_chains,$lond_port,\%iphost,[$lond_port],$firewalld);
 $closed =
-    &LONCAPA::Firewall::firewall_open_port($iptables,\@fw_chains,$lond_port,\%iphost,[$lond_port]);
+    &LONCAPA::Firewall::firewall_open_port($iptables,\@fw_chains,$lond_port,\%iphost,[$lond_port],$firewalld);
 if ($firewalld) {
     $<=$wwwid;
 }
Index: loncom/init.d/loncontrol
diff -u loncom/init.d/loncontrol:1.45 loncom/init.d/loncontrol:1.46
--- loncom/init.d/loncontrol:1.45	Tue Aug  7 17:12:17 2018
+++ loncom/init.d/loncontrol	Sun Jun  9 02:35:41 2019
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 #
-# $Id: loncontrol,v 1.45 2018/08/07 17:12:17 raeburn Exp $
+# $Id: loncontrol,v 1.46 2019/06/09 02:35:41 raeburn Exp $
 #
 # The LearningOnline Network with CAPA
 #
@@ -131,6 +131,7 @@
     my $iptables = &LONCAPA::Firewall::get_pathto_iptables();
     my @fw_chains = &LONCAPA::Firewall::get_fw_chains($iptables);
     my $lond_port = &LONCAPA::Firewall::get_lond_port();
+    my $firewalld = &LONCAPA::Firewall::uses_firewalld();
     my %iphost;
     if ($command eq 'restart') {
         print 'Restarting LON-CAPA'."\n";
@@ -143,13 +144,15 @@
         %iphost = &Apache::lonnet::get_iphost('',1);
         my $firewall_result =
             &LONCAPA::Firewall::firewall_close_port($iptables,\@fw_chains,
-                                             $lond_port,\%iphost,[$lond_port]);
+                                             $lond_port,\%iphost,[$lond_port],
+                                             $firewalld);
         if ($firewall_result) {
             print "$firewall_result\n";
         }
         $firewall_result =
             &LONCAPA::Firewall::firewall_open_port($iptables,\@fw_chains,
-                                            $lond_port, \%iphost,[$lond_port]);
+                                            $lond_port,\%iphost,[$lond_port],
+                                            $firewalld);
         if (($firewall_result eq 'ok') || ($firewall_result eq 'inactive firewall')) {
             if ($firewall_result eq 'inactive firewall') {
                 print "WARNING: iptables firewall is currently inactive\n";
@@ -168,7 +171,9 @@
 	    &stop_daemon($daemon,$killallname);
         }
         my $firewall_result = 
-            &LONCAPA::Firewall::firewall_close_port($iptables,\@fw_chains,$lond_port,\%iphost,[$lond_port]);
+            &LONCAPA::Firewall::firewall_close_port($iptables,\@fw_chains,
+                                                    $lond_port,\%iphost,[$lond_port],
+                                                    $firewalld);
         if ($firewall_result) {
             print "$firewall_result\n";
         }
@@ -176,7 +181,9 @@
     } elsif ($command eq "start") {
         %iphost = &Apache::lonnet::get_iphost('',1);
         my $firewall_result = 
-            &LONCAPA::Firewall::firewall_open_port($iptables,\@fw_chains,$lond_port,\%iphost,[$lond_port]);
+            &LONCAPA::Firewall::firewall_open_port($iptables,\@fw_chains,
+                                                   $lond_port,\%iphost,[$lond_port],
+                                                   $firewalld);
         if (($firewall_result eq 'ok') || ($firewall_result eq 'inactive firewall')) {
             if ($firewall_result eq 'inactive firewall') {
                 print "WARNING: iptables firewall is currently inactive\n";
@@ -208,12 +215,12 @@
         if ($lond_port) {
             my $londopen;
             foreach my $fw_chain (@fw_chains) { 
-                my $numopen = &LONCAPA::Firewall::firewall_is_port_open($iptables,$fw_chain,$lond_port,$lond_port,\%iphost);
+                my $numopen = &LONCAPA::Firewall::firewall_is_port_open($iptables,$fw_chain,$lond_port,$lond_port,\%iphost,$firewalld);
                 $londopen += $numopen; 
             }
             if ($londopen) {
                 print "The LON-CAPA port ($lond_port) is open in firewall.\n";
-            } elsif (&LONCAPA::Firewall::firewall_is_active) {
+            } elsif (&LONCAPA::Firewall::firewall_is_active()) {
                 print "The LON-CAPA port ($lond_port) is NOT open in running firewall!\n";
             }
         } else {
Index: loncom/configuration/Firewall.pm
diff -u loncom/configuration/Firewall.pm:1.17 loncom/configuration/Firewall.pm:1.18
--- loncom/configuration/Firewall.pm:1.17	Tue May  7 21:18:24 2019
+++ loncom/configuration/Firewall.pm	Sun Jun  9 02:35:45 2019
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Firewall configuration to allow internal LON-CAPA communication between servers   
 #
-# $Id: Firewall.pm,v 1.17 2019/05/07 21:18:24 raeburn Exp $
+# $Id: Firewall.pm,v 1.18 2019/06/09 02:35:45 raeburn Exp $
 #
 # The LearningOnline Network with CAPA
 #
@@ -42,7 +42,7 @@
     if ($distro eq '') {
         $distro = &get_distro();
     }
-    my ($inuse,$checkfirewalld,$zone);
+    my ($inuse,$checkfirewalld);
     if ($distro =~ /^(suse|sles)([\d\.]+)$/) {
         if (($1 eq 'sles') && ($2 >= 15)) {
             $checkfirewalld = 1;
@@ -72,40 +72,36 @@
         }
         if (($loaded eq 'loaded') || ($active eq 'active')) {
             $inuse = 1;
-            my $cmd = 'firewall-cmd --get-default-zone';
-            if (open(PIPE,"$cmd |")) {
-                my $result = <PIPE>;
-                chomp($result);
-                close(PIPE);
-                if ($result =~ /^\w+$/) {
-                    $zone = $result;
-                }
-            }
         }
     }
-    return ($inuse,$zone);
+    return $inuse;
 }
 
 sub firewall_open_port {
-    my ($iptables,$fw_chains,$lond_port,$iphost,$ports) = @_;
+    my ($iptables,$fw_chains,$lond_port,$iphost,$ports,$firewalld) = @_;
     return 'inactive firewall' if (!&firewall_is_active());
     return 'port number unknown' if !$lond_port;
     return 'invalid firewall chain' unless (ref($fw_chains) eq 'ARRAY');
-    my (@opened, at chains, at badchains, at okchains);
-    foreach my $chain (@{$fw_chains}) {
-        if ($chain =~ /^([\w\-]+)$/) {
-            push(@okchains,$1);
-        } else {
-            push(@badchains,$chain);
+    my (@opened, at okchains,$zone);
+    if ($firewalld) {
+        $zone = &get_default_zone();
+        return 'invalid zone' if ($zone eq '');
+    } else {
+        my @badchains;
+        foreach my $chain (@{$fw_chains}) {
+            if ($chain =~ /^([\w\-]+)$/) {
+                push(@okchains,$1);
+            } else {
+                push(@badchains,$chain);
+            }
+        }
+        if (!@okchains) {
+            return 'None of the chain names has the expected format.'."\n";
         }
-    }
-    if (!@okchains) {
-        return 'None of the chain names has the expected format.'."\n";
     }
     if (ref($ports) ne 'ARRAY') {
         return 'List of ports to open needed.';
     }
-    my ($firewalld,$zone) = &uses_firewalld();
     foreach my $portnum (@{$ports}) {
         my $port = '';
         if ($portnum =~ /^(\d+)$/) {
@@ -124,9 +120,17 @@
             if (ref($iphost) eq 'HASH') {
                 if (keys(%{$iphost}) > 0) {
                     my %curropen;
-                    foreach my $fw_chain (@okchains) {
-                        &firewall_close_anywhere($iptables,$fw_chain,$port);
-                        my $current = &firewall_is_port_open($iptables,$fw_chain,$port,$lond_port,$iphost,\%curropen);
+                    if ($firewalld) {
+                        &firewall_close_anywhere($iptables,$zone,$port,$firewalld);
+                        my $current = &firewall_is_port_open($iptables,$zone,$port,
+                                                             $lond_port,$iphost,\%curropen,
+                                                             $firewalld);
+                    } else {
+                        foreach my $fw_chain (@okchains) {
+                            &firewall_close_anywhere($iptables,$fw_chain,$port);
+                            my $current = &firewall_is_port_open($iptables,$fw_chain,$port,
+                                                                 $lond_port,$iphost,\%curropen);
+                        }
                     }
                     foreach my $key (keys(%{$iphost})) {
                         my $ip = '';
@@ -144,30 +148,27 @@
                         if ($curropen{$ip}) {
                             push(@lond_port_curropen,$ip);
                         } else {
-                            foreach my $fw_chain (@okchains) {
-                                if ($firewalld) {
-                                    my $cmd = 'firewall-cmd --zone='.$zone.' --add-rich-rule \'rule family="ipv4" source address="'.$ip.'/32" port port="'.$port.'" protocol="tcp" accept\'';
-                                    if (open(PIPE,"$cmd |")) {
-                                        my $result = <PIPE>;
-                                        chomp($result);
-                                        close(PIPE);
-                                        if ($result eq 'success') {
-                                            push(@lond_port_open,$ip);
-                                            last;
-                                        } else {
-                                            push (@port_error,$ip);
-                                        }
+                            if ($firewalld) {
+                                my $cmd = 'firewall-cmd --zone='.$zone.' --add-rich-rule \'rule family="ipv4" source address="'.$ip.'/32" port port="'.$port.'" protocol="tcp" accept\'';
+                                if (open(PIPE,"$cmd |")) {
+                                    my $result = <PIPE>;
+                                    chomp($result);
+                                    close(PIPE);
+                                    if ($result eq 'success') {
+                                        push(@lond_port_open,$ip);
                                     } else {
-                                        push (@port_error,$ip);
+                                        push(@port_error,$ip);
                                     }
-                                } else {
+				}	 
+                            } else {
+                                foreach my $fw_chain (@okchains) {
                                     my $firewall_command =
                                         "$iptables -I $fw_chain -p tcp -s $ip -d 0/0 --dport $port -j ACCEPT";
                                     system($firewall_command);
                                     my $return_status = $?>>8;
                                     if ($return_status == 1) {
                                         unless(grep(/^\Q$ip\E$/, at port_error)) {
-                                            push (@port_error,$ip);
+                                            push(@port_error,$ip);
                                         }
                                     } elsif ($return_status == 2) {
                                         push(@{$command_error{$fw_chain}},$ip);
@@ -212,24 +213,27 @@
                 }
             }
         } else {
-            my (@port_errors,%command_errors);
-            foreach my $fw_chain (@okchains) {
-                if ($firewalld) {
-                    my $cmd = 'firewall-cmd --zone='.$zone.' --add-rich-rule \'rule family="ipv4" port port="'.$port.'" protocol="tcp" accept\'';
-                    if (open(PIPE,"$cmd |")) {
-                        my $result = <PIPE>;
-                        chomp($result);
-                        close(PIPE);
-                        if ($result eq 'success') {
-                            push(@opened,$port);
-                            last;
-                        } else {
-                            push(@port_errors,$fw_chain);
-                        }
+            if ($firewalld) {
+                my ($port_error);
+                my $cmd = 'firewall-cmd --zone='.$zone.' --add-rich-rule \'rule family="ipv4" port port="'.$port.'" protocol="tcp" accept\'';
+                if (open(PIPE,"$cmd |")) {
+                    my $result = <PIPE>;
+                    chomp($result);
+                    close(PIPE);
+                    if ($result eq 'success') {
+                        push(@opened,$port);
                     } else {
-                        push(@port_errors,$fw_chain);
+                        $port_error = $port;
                     }
                 } else {
+                    $port_error = $port;
+                }
+                if ($port_error) {
+                    print "Error opening port: $port\n";
+                }
+            } else {
+                my (@port_errors,%command_errors);
+                foreach my $fw_chain (@okchains) {
                     my $firewall_command =
                         "$iptables -I $fw_chain -p tcp -d 0/0 --dport $port -j ACCEPT";
                     system($firewall_command);
@@ -267,14 +271,48 @@
 }
 
 sub firewall_is_port_open {
-    my ($iptables,$fw_chain,$port,$lond_port,$iphost,$curropen) = @_;
+    my ($iptables,$fw_chain,$port,$lond_port,$iphost,$curropen,$firewalld) = @_;
     # for lond port returns number of source IPs for which firewall port is open
     # for other ports returns 1 if the firewall port is open, 0 if not.
-    #
-    # check if firewall is active or installed
-    return if (! &firewall_is_active());
+    # if firewalld is in use, checks for rich rules only.
     my $count = 0;
+    return $count if (! &firewall_is_active());
+    if ($firewalld) {
+        my $zone = &get_default_zone();
+        return $count if ($zone eq ''); 
+        if ($port eq $lond_port) {
+            if (open(PIPE,"firewall-cmd --zone=$zone --list-rich-rules |")) {
+                while(<PIPE>) {
+                    chomp();
+                    if (/\Qrule family="ipv4" source address="\E([\d.]+)\Q\/32" port port="$port" protocol="tcp" accept\E/) {
+                        my $ip = $1;
+                        if ($iphost->{$ip}) {
+                            $count ++;
+                            if (ref($curropen) eq 'HASH') {
+                                $curropen->{$ip} ++;
+                            }
+                        }
+                    }
+                }
+                close(PIPE);
+            }
+        } else {
+            if (open(PIPE,"firewall-cmd --zone=$zone --list-rich-rules |")) {
+                while(<PIPE>) {
+                    if (/\Qrule family="ipv4" port port="$port" protocol="tcp" accept\E/) {
+                        $count ++;
+                        last;
+                    }
+                }
+                close(PIPE);
+            }
+        }
+	return $count; 
+    }
+    return $count unless ($fw_chain !~ /^[\w-]+$/);
     if (open(PIPE,"$iptables -L $fw_chain -n |")) {
+        # check if firewall is active or installed
+        return if (! &firewall_is_active());
         while(<PIPE>) {
             if ($port eq $lond_port) {
                 if (ref($iphost) eq 'HASH') {
@@ -288,11 +326,9 @@
                         }
                     }
                 }
-            } else {
-                if (/tcp dpt\:\Q$port\E/) {
-                    $count ++;
-                    last;
-                }
+            } elsif (/tcp dpt\:\Q$port\E/) {
+                $count ++;
+                last;
             }
         }
         close(PIPE);
@@ -314,29 +350,37 @@
             close(PIPE);
         }
     }
+    unless ($status) {
+        $status = &uses_firewalld();
+    }
     return $status;
 }
 
 sub firewall_close_port {
-    my ($iptables,$fw_chains,$lond_port,$iphost,$ports) = @_;
+    my ($iptables,$fw_chains,$lond_port,$iphost,$ports,$firewalld) = @_;
     return 'inactive firewall' if (!&firewall_is_active());
     return 'port number unknown' if !$lond_port;
     return 'invalid firewall chain' unless (ref($fw_chains) eq 'ARRAY');
-    my (@opened, at chains, at badchains, at okchains);
-    foreach my $chain (@{$fw_chains}) {
-        if ($chain =~ /^([\w\-]+)$/) {
-            push(@okchains,$1);
-        } else {
-            push(@badchains,$chain);
+    my (@okchains,$zone);
+    if ($firewalld) {
+        $zone = &get_default_zone();
+        return 'no default zone' if ($zone eq '');
+    } else {
+        my @badchains;
+        foreach my $chain (@{$fw_chains}) {
+            if ($chain =~ /^([\w\-]+)$/) {
+                push(@okchains,$1);
+            } else {
+                push(@badchains,$chain);
+            }
+        }
+        if (!@okchains) {
+            return 'None of the chain names has the expected format.'."\n";
         }
-    }
-    if (!@okchains) {
-        return 'None of the chain names has the expected format.'."\n";
     }
     if (ref($ports) ne 'ARRAY') {
         return 'List of ports to close needed.';
     }
-    my ($firewalld,$zone) = &uses_firewalld();
     foreach my $portnum (@{$ports}) {
         my $port = '';
         if ($portnum =~ /^(\d+)$/) {
@@ -348,19 +392,17 @@
         print "Closing firewall access on port $port.\n";
         if (($port ne '') && ($port eq $lond_port)) {
             my $output;
-            foreach my $fw_chain (@okchains) {
-                my (@port_error, at command_error, at lond_port_close);
-                my %to_close;
-                if (open(PIPE, "$iptables -n -L $fw_chain |")) {
-                    while (<PIPE>) {
-                        chomp();
-                        next unless (/dpt:\Q$port\E/);
-                        if (/^ACCEPT\s+tcp\s+\-{2}\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+/) {
+            if ($firewalld) {
+                my (%to_close, at port_error, at lond_port_close);
+                my $cmd = 'firewall-cmd --list-rich-rules';
+                if (open(PIPE,"$cmd |")) {
+                    while(<PIPE>) {
+                        if (/\Qrule family="ipv4" source address="\E([\d.]+)\Q\/32" port port="$port" protocol="tcp" accept\E/) {
                             my $ip = $1;
                             my $keepopen = 0;
                             if (ref($iphost) eq 'HASH') {
                                 if (exists($iphost->{$ip})) {
-                                    $keepopen = 1; 
+                                    $keepopen = 1;
                                 }
                             }
                             unless ($keepopen) {
@@ -371,28 +413,58 @@
                     close(PIPE);
                 }
                 if (keys(%to_close) > 0) {
-                    foreach my $ip (keys(%to_close)) {
-                        if ($firewalld) {
-                            my $cmd = 'firewall-cmd --zone='.$zone.' --remove-rich-rule \'rule family="ipv4" source address="'.$ip.'/32" port port="'.$port.'" protocol="tcp" accept\'';
-                            if (open(PIPE,"$cmd |")) {
-                                my $result = <PIPE>;
-                                chomp($result);
-                                close(PIPE);
-                                if ($result eq 'success') {
-                                    push(@lond_port_close,$ip);
-                                } else {
-                                    push(@port_error,$ip);
-                                }
+                    foreach my $ip (sort(keys(%to_close))) {
+                        my $cmd = 'firewall-cmd --zone='.$zone.' --remove-rich-rule \'rule family="ipv4" source address="'.$ip.'/32" port port="'.$port.'" protocol="tcp" accept\'';
+                        if (open(PIPE,"$cmd |")) {
+                            my $result = <PIPE>;
+                            chomp($result);
+                            close(PIPE);
+                            if ($result eq 'success') {
+                                push(@lond_port_close,$ip);
                             } else {
                                 push(@port_error,$ip);
                             }
                         } else {
+                            push(@port_error,$ip);
+                        }
+                    }
+                }
+                if (@lond_port_close) {
+                    $output .= "Port closed for ".scalar(@lond_port_close)." IP addresses.\n";
+                }
+                if (@port_error) {
+                    $output .= "Error closing port for following IP addresses: ".join(', ', at port_error)."\n";
+                }
+            } else {
+                foreach my $fw_chain (@okchains) {
+                    my (%to_close, at port_error, at command_error, at lond_port_close);
+                    if (open(PIPE, "$iptables -n -L $fw_chain |")) {
+                        while (<PIPE>) {
+                            chomp();
+                            next unless (/dpt:\Q$port\E/);
+                            if (/^ACCEPT\s+tcp\s+\-{2}\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+/) {
+                                my $ip = $1;
+                                my $keepopen = 0;
+                                if (ref($iphost) eq 'HASH') {
+                                    if (exists($iphost->{$ip})) {
+                                        $keepopen = 1; 
+                                    }
+                                }
+                                unless ($keepopen) {
+                                    $to_close{$ip} = $port;
+                                }
+                            }
+                        }
+                        close(PIPE);
+                    }
+                    if (keys(%to_close) > 0) {
+                        foreach my $ip (keys(%to_close)) {
                             my $firewall_command =
                                 "$iptables -D $fw_chain -p tcp -s $ip -d 0/0 --dport $port -j ACCEPT";
                             system($firewall_command);
                             my $return_status = $?>>8;
                             if ($return_status == 1) {
-                                push (@port_error,$ip);
+                                push(@port_error,$ip);
                             } elsif ($return_status == 2) {
                                 push(@command_error,$ip);
                             } elsif ($return_status == 0) {
@@ -400,17 +472,17 @@
                             }
                         }
                     }
-                }
-                if (@lond_port_close) {
-                    $output .= "Port closed for ".scalar(@lond_port_close)." IP addresses.\n";
-                }
-                if (@port_error) {
-                    $output .= "Error closing port for following IP addresses: ".join(', ', at port_error)."\n";
-                }
-                if (@command_error) {
-                    $output .= "Bad command error opening port for following IP addresses: ".
-                          join(', ', at command_error)."\n".
-                          'Command was: "'."$iptables -D $fw_chain -p tcp -s ".'$ip'." -d 0/0 --dport $port -j ACCEPT".'", where $ip is IP address'."\n";
+                    if (@lond_port_close) {
+                        $output .= "Port closed for ".scalar(@lond_port_close)." IP addresses.\n";
+                    }
+                    if (@port_error) {
+                        $output .= "Error closing port for following IP addresses: ".join(', ', at port_error)."\n";
+                    }
+                    if (@command_error) {
+                        $output .= "Bad command error opening port for following IP addresses: ".
+                              join(', ', at command_error)."\n".
+                              'Command was: "'."$iptables -D $fw_chain -p tcp -s ".'$ip'." -d 0/0 --dport $port -j ACCEPT".'", where $ip is IP address'."\n";
+                    }
                 }
             }
             if ($output) {
@@ -419,40 +491,52 @@
                 print "No IP addresses required discontinuation of access.\n";
             }
         } else {
-            foreach my $fw_chain (@okchains) {
-                my (@port_error, at command_error, at lond_port_close);
+            if ($firewalld) {
                 my $to_close;
-                if (open(PIPE, "$iptables -n -L $fw_chain |")) {
-                    while (<PIPE>) {
-                        chomp();
-                        next unless (/dpt:\Q$port\E/);
+                if (open(PIPE,"firewall-cmd --list-rich-rules |")) {
+                    while(<PIPE>) {
+                        next unless (/\Qrule family="ipv4" port port="$port" protocol="tcp" accept\E/);
                         $to_close = 1;
+                        last;
                     }
                     close(PIPE);
                 }
                 if ($to_close) {
-                    if ($firewalld) {
-                        my $cmd = 'firewall-cmd --zone='.$zone.' --remove-rich-rule \'rule family="ipv4" port port="'.$port.'" protocol="tcp" accept\'';
-                        if (open(PIPE,"$cmd|")) {
-                            my $result = <PIPE>;
-                            chomp($result);
-                            close(PIPE);
-                            if ($result eq 'success') {
-                                print "Port closed for chain $fw_chain.\n";
-                            } else {
-                                print "Error closing port for chain: $fw_chain.\n";
-                            }
+                    my $cmd = 'firewall-cmd --zone='.$zone.' --remove-rich-rule \'rule family="ipv4" port port="'.$port.'" protocol="tcp" accept\'';
+                    if (open(PIPE,"$cmd|")) {
+                        my $result = <PIPE>;
+                        chomp($result);
+                        close(PIPE);
+                        if ($result eq 'success') {
+                            print "Port: $port closed in zone: $zone.\n";
                         } else {
-                            print "Error closing port for chain: $fw_chain.\n";
+                            print "Error closing port: $port in zone: $zone.\n";
                         }
                     } else {
+                        print "Error closing port: $port in zone: $zone.\n";
+                    }
+                }
+            } else {
+                foreach my $fw_chain (@okchains) {
+                    my (@port_error, at command_error, at lond_port_close);
+                    my $to_close;
+                    if (open(PIPE, "$iptables -n -L $fw_chain |")) {
+                        while (<PIPE>) {
+                            chomp();
+                            next unless (/dpt:\Q$port\E/);
+                            $to_close = 1;
+                            last;
+                        }
+                        close(PIPE);
+                    }
+                    if ($to_close) {
                         my $firewall_command =
                             "$iptables -D $fw_chain -p tcp -d 0/0 --dport $port -j ACCEPT";
                         system($firewall_command);
                         my $return_status = $?>>8;
                         if ($return_status == 1) {
                             # Error
-                            print "Error closing port for chain: $fw_chain.\n";
+                            print "Error closing port: $port for chain: $fw_chain.\n";
                         } elsif ($return_status == 2) {
                             # Bad command
                             print "Bad command error closing port.  Command was\n".
@@ -469,39 +553,61 @@
 }
 
 sub firewall_close_anywhere {
-    my ($iptables,$fw_chain,$port) = @_;
-    my ($firewalld,$zone) = &uses_firewalld();
-    if (open(PIPE, "$iptables --line-numbers -n -L $fw_chain |")) {
+    my ($iptables,$fw_chain,$port,$firewalld) = @_;
+    my $zone; 
+    if ($firewalld) {
+        $zone = &get_default_zone();
+        if ($zone eq '') {
+            print 'no default zone';
+	    return;
+        }
+    } else {
+        unless ($fw_chain =~ /^([\w\-]+)$/) {
+            print 'invalid chain';
+	    return;
+        }
+    }
+    if ($firewalld) { 
+        my $to_close;
+        my $cmd = 'firewall-cmd --list-ports';
+        if (open(PIPE,"$cmd |")) {
+            my $currports = <PIPE>;
+            close(PIPE);
+            chomp($currports);
+            if (grep(/^\Q$port\E\/tcp/,split(/\s+/,$currports))) {
+                $to_close = 1;
+            }
+        }
+        if ($to_close) {
+            my $cmd = 'firewall-cmd --zone='.$zone.' --remove-port='.$port.'/tcp';
+            if (open(PIPE,"$cmd |")) {
+                my $result = <PIPE>;
+                chomp($result);
+                close(PIPE);
+                if ($result eq 'success') {
+                    print 'Port '.$port.' closed for source "anywhere"'."\n";
+                } else {
+                    print 'Error closing port '.$port.' for source "anywhere".'."\n";
+                }
+            } else {
+                print 'Error closing port '.$port.' for source "anywhere".'."\n";
+            }
+        }    
+    } elsif (open(PIPE, "$iptables --line-numbers -n -L $fw_chain |")) {
         while (<PIPE>) {
             next unless (/dpt:\Q$port\E/);
             chomp();
             if (/^(\d+)\s+ACCEPT\s+tcp\s+\-{2}\s+0\.0\.0\.0\/0\s+0\.0\.0\.0\/0/) {
-                if ($firewalld) {
-                    my $cmd = 'firewall-cmd --remove-port='.$port.'/tcp';
-                    if (open(PIPE,"$cmd |")) {
-                        my $result = <PIPE>;
-                        chomp($result);
-                        close(PIPE);
-                        if ($result eq 'success') {
-                            print 'Port '.$port.' closed for source "anywhere"'."\n";
-                        } else {
-                            print 'Error closing port '.$port.' for source "anywhere".'."\n";
-                        }
-                    } else {
-                        print 'Error closing port '.$port.' for source "anywhere".'."\n";
-                    }
+                my $firewall_command = "$iptables -D $fw_chain $1";
+                system($firewall_command);
+                my $return_status = $?>>8;
+                if ($return_status == 1) {
+                    print 'Error closing port '.$port.' for source "anywhere".'."\n";
+                } elsif ($return_status == 2) {
+                    print 'Bad command error closing port '.$port.' for source "anywhere".  Command was'."\n".
+                          ' '.$firewall_command."\n";
                 } else {
-                    my $firewall_command = "$iptables -D $fw_chain $1";
-                    system($firewall_command);
-                    my $return_status = $?>>8;
-                    if ($return_status == 1) {
-                        print 'Error closing port '.$port.' for source "anywhere".'."\n";
-                    } elsif ($return_status == 2) {
-                        print 'Bad command error closing port '.$port.' for source "anywhere".  Command was'."\n".
-                              ' '.$firewall_command."\n";
-                    } else {
-                        print 'Port '.$port.' closed for source "anywhere"'."\n";
-                    }
+                    print 'Port '.$port.' closed for source "anywhere"'."\n";
                 }
             }
         }
@@ -531,13 +637,20 @@
     my @fw_chains;
     my $suse_config = "/etc/sysconfig/SuSEfirewall2";
     my $ubuntu_config = "/etc/ufw/ufw.conf";
-    my ($firewalld,$zone) = &uses_firewalld($distro);
+    my $firewalld = &uses_firewalld($distro);
     if ($firewalld) {
-        if ($zone ne '') {
-            push(@fw_chains,'IN_'.$zone.'_allow');
+        my ($dist,$version) = ($distro =~ /^([\D]+)(\d+)$/);
+        if ((($dist eq 'rhes') || ($dist eq 'centos')) &&
+             ($version >= 8)) {
+            push(@fw_chains,'INPUT');
         } else {
-            push(@fw_chains,'IN_public_allow');
-        }
+            my $zone = &get_default_zone();
+	    if ($zone ne '') {
+                push(@fw_chains,'IN_'.$zone.'_allow');
+            } else {
+                push(@fw_chains,'IN_public_allow');
+            }
+        }  
     } elsif (-e $suse_config) {
         push(@fw_chains,'input_ext');
     } else {
@@ -592,6 +705,18 @@
     return @fw_chains;
 }
 
+sub get_default_zone {
+    my $cmd = 'firewall-cmd --get-default-zone';
+    my $zone;
+    if (open(PIPE,"$cmd |")) {
+        my $result = <PIPE>;
+        chomp($result);
+        close(PIPE);
+        ($zone) = ($result =~ /^(\w+)$/);
+    }
+    return $zone;
+}
+
 sub get_pathto_iptables {
     my $iptables;
     if (-e '/sbin/iptables') {
@@ -653,19 +778,19 @@
 
 =over 4
 
-=item LONCAPA::Firewall::firewall_open_port( $iptables,$fw_chains,$lond_port,$iphost,$port );
+=item LONCAPA::Firewall::firewall_open_port( $iptables,$fw_chains,$lond_port,$iphost,$ports,$firewalld );
 
 =back
 
 =over 4
 
-=item LONCAPA::Firewall::firewall_close_port( $iptables,$fw_chains,$lond_port,$iphost,$ports );
+=item LONCAPA::Firewall::firewall_close_port( $iptables,$fw_chains,$lond_port,$iphost,$ports,$firewalld );
 
 =back
 
 =over 4
 
-=item LONCAPA::Firewall::firewall_is_port_open( $iptables,$fw_chain,$port,$lond_port,$iphost,$curropen );
+=item LONCAPA::Firewall::firewall_is_port_open( $iptables,$fw_chain,$port,$lond_port,$iphost,$curropen,$firewalld );
 
 =back
 
@@ -677,7 +802,7 @@
 
 =over 4
 
-=item LONCAPA::Firewall::firewall_close_anywhere( $iptables,$fw_chain,$port );
+=item LONCAPA::Firewall::firewall_close_anywhere( $iptables,$fw_chain,$port,$firewalld );
 
 =back
 


More information about the LON-CAPA-cvs mailing list