[LON-CAPA-cvs] cvs: loncom /configuration Firewall.pm
raeburn
raeburn at source.lon-capa.org
Tue Oct 23 22:08:04 EDT 2018
raeburn Wed Oct 24 02:08:04 2018 EDT
Modified files:
/loncom/configuration Firewall.pm
Log:
- Dynamic management of LON-CAPA port 5663 compatible with firewalld.
-------------- next part --------------
Index: loncom/configuration/Firewall.pm
diff -u loncom/configuration/Firewall.pm:1.14 loncom/configuration/Firewall.pm:1.15
--- loncom/configuration/Firewall.pm:1.14 Mon Mar 17 14:47:46 2014
+++ loncom/configuration/Firewall.pm Wed Oct 24 02:08:04 2018
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Firewall configuration to allow internal LON-CAPA communication between servers
#
-# $Id: Firewall.pm,v 1.14 2014/03/17 14:47:46 bisitz Exp $
+# $Id: Firewall.pm,v 1.15 2018/10/24 02:08:04 raeburn Exp $
#
# The LearningOnline Network with CAPA
#
@@ -37,6 +37,46 @@
use LONCAPA::Configuration;
use LONCAPA;
+sub uses_firewalld {
+ my ($distro) = @_;
+ if ($distro eq '') {
+ $distro = &get_distro();
+ }
+ my ($inuse, $checkfirewalld);
+ if ($distro =~ /^(suse|sles)([\d\.]+)$/) {
+ if (($1 eq 'sles') && ($2 >= 15)) {
+ $checkfirewalld = 1;
+ }
+ } elsif ($distro =~ /^fedora(\d+)$/) {
+ if ($1 >= 18) {
+ $checkfirewalld = 1;
+ }
+ } elsif ($distro =~ /^(?:centos|rhes|scientific)(\d+)/) {
+ if ($1 >= 7) {
+ $checkfirewalld = 1;
+ }
+ }
+ if ($checkfirewalld) {
+ my ($loaded,$active);
+ if (open(PIPE,"systemctl status firewalld |")) {
+ while (<PIPE>) {
+ chomp();
+ if (/^\s*Loaded:\s+(\w+)/) {
+ $loaded = $1;
+ }
+ if (/^\s*Active\s+(\w+)/) {
+ $active = $1;
+ }
+ }
+ close(PIPE);
+ }
+ if (($loaded eq 'loaded') || ($active eq 'active')) {
+ $inuse = 1;
+ }
+ }
+ return $inuse;
+}
+
sub firewall_open_port {
my ($iptables,$fw_chains,$lond_port,$iphost,$ports) = @_;
return 'inactive firewall' if (!&firewall_is_active());
@@ -56,6 +96,7 @@
if (ref($ports) ne 'ARRAY') {
return 'List of ports to open needed.';
}
+ my $firewalld = &uses_firewalld();
foreach my $portnum (@{$ports}) {
my $port = '';
if ($portnum =~ /^(\d+)$/) {
@@ -95,19 +136,36 @@
push(@lond_port_curropen,$ip);
} 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)) {
+ if ($firewalld) {
+ my $cmd = 'firewall-cmd --zone=public --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);
+ }
+ } else {
push (@port_error,$ip);
}
- } elsif ($return_status == 2) {
- push(@{$command_error{$fw_chain}},$ip);
- } elsif ($return_status == 0) {
- push(@lond_port_open,$ip);
- last;
+ } else {
+ 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);
+ }
+ } elsif ($return_status == 2) {
+ push(@{$command_error{$fw_chain}},$ip);
+ } elsif ($return_status == 0) {
+ push(@lond_port_open,$ip);
+ last;
+ }
}
}
}
@@ -147,28 +205,45 @@
} 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);
- my $return_status = $?>>8;
- if ($return_status == 1) {
- push(@port_errors,$fw_chain);
- } elsif ($return_status == 2) {
- $command_errors{$fw_chain} = $firewall_command;
- } elsif ($return_status == 0) {
- push(@opened,$port);
- last;
+ if ($firewalld) {
+ my $cmd = 'firewall-cmd --zone=public --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);
+ }
+ } else {
+ push(@port_errors,$fw_chain);
+ }
+ } else {
+ my $firewall_command =
+ "$iptables -I $fw_chain -p tcp -d 0/0 --dport $port -j ACCEPT";
+ system($firewall_command);
+ my $return_status = $?>>8;
+ if ($return_status == 1) {
+ push(@port_errors,$fw_chain);
+ } elsif ($return_status == 2) {
+ $command_errors{$fw_chain} = $firewall_command;
+ } elsif ($return_status == 0) {
+ push(@opened,$port);
+ last;
+ }
}
- }
- unless (grep(/^\Q$port\E$/, at opened)) {
- if (@port_errors) {
- print "Error opening port for chains: ".
- join(', ', at port_errors).".\n";
- }
- if (keys(%command_errors)) {
- foreach my $fw_chain (sort(keys(%command_errors))) {
- print "Bad command error opening port for chain: $fw_chain. Command was\n".
- " ".$command_errors{$fw_chain}."\n";
+ unless (grep(/^\Q$port\E$/, at opened)) {
+ if (@port_errors) {
+ print "Error opening port for chains: ".
+ join(', ', at port_errors).".\n";
+ }
+ if (keys(%command_errors)) {
+ foreach my $fw_chain (sort(keys(%command_errors))) {
+ print "Bad command error opening port for chain: $fw_chain. Command was\n".
+ " ".$command_errors{$fw_chain}."\n";
+ }
}
}
}
@@ -217,11 +292,20 @@
}
sub firewall_is_active {
+ my $status = 0;
if (-e '/proc/net/ip_tables_names') {
- return 1;
- } else {
- return 0;
+ if (open(PIPE,'cat /proc/net/ip_tables_names |')) {
+ while(<PIPE>) {
+ chomp();
+ if (/^filter$/) {
+ $status = 1;
+ last;
+ }
+ }
+ close(PIPE);
+ }
}
+ return $status;
}
sub firewall_close_port {
@@ -243,6 +327,7 @@
if (ref($ports) ne 'ARRAY') {
return 'List of ports to close needed.';
}
+ my $firewalld = &uses_firewalld();
foreach my $portnum (@{$ports}) {
my $port = '';
if ($portnum =~ /^(\d+)$/) {
@@ -260,7 +345,7 @@
if (open(PIPE, "$iptables -n -L $fw_chain |")) {
while (<PIPE>) {
chomp();
- next unless (/dpt:\Q$port\E\s*$/);
+ 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;
@@ -278,16 +363,32 @@
}
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);
- } elsif ($return_status == 2) {
- push(@command_error,$ip);
- } elsif ($return_status == 0) {
- push(@lond_port_close,$ip);
+ if ($firewalld) {
+ my $cmd = 'firewall-cmd --zone=public --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);
+ }
+ } else {
+ 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);
+ } elsif ($return_status == 2) {
+ push(@command_error,$ip);
+ } elsif ($return_status == 0) {
+ push(@lond_port_close,$ip);
+ }
}
}
}
@@ -315,25 +416,41 @@
if (open(PIPE, "$iptables -n -L $fw_chain |")) {
while (<PIPE>) {
chomp();
- next unless (/dpt:\Q$port\E\s*$/);
+ next unless (/dpt:\Q$port\E/);
$to_close = 1;
}
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";
- } elsif ($return_status == 2) {
- # Bad command
- print "Bad command error closing port. Command was\n".
- " ".$firewall_command."\n";
+ if ($firewalld) {
+ my $cmd = 'firewall-cmd --zone=public --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";
+ }
+ } else {
+ print "Error closing port for chain: $fw_chain.\n";
+ }
} else {
- print "Port closed for chain $fw_chain.\n";
+ 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";
+ } elsif ($return_status == 2) {
+ # Bad command
+ print "Bad command error closing port. Command was\n".
+ " ".$firewall_command."\n";
+ } else {
+ print "Port closed for chain $fw_chain.\n";
+ }
}
}
}
@@ -344,21 +461,38 @@
sub firewall_close_anywhere {
my ($iptables,$fw_chain,$port) = @_;
+ my $firewalld = &uses_firewalld();
if (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/) {
- 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";
+ 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";
+ }
} else {
- print 'Port '.$port.' closed 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 {
+ print 'Port '.$port.' closed for source "anywhere"'."\n";
+ }
}
}
}
@@ -381,12 +515,16 @@
}
sub get_fw_chains {
- my ($iptables) = @_;
- my $distro = &LONCAPA::distro();
+ my ($iptables,$distro) = @_;
+ if ($distro eq '') {
+ $distro = &get_distro();
+ }
my @fw_chains;
my $suse_config = "/etc/sysconfig/SuSEfirewall2";
my $ubuntu_config = "/etc/ufw/ufw.conf";
- if (-e $suse_config) {
+ if (&uses_firewalld($distro)) {
+ push(@fw_chains,'IN_public_allow');
+ } elsif (-e $suse_config) {
push(@fw_chains,'input_ext');
} else {
my @posschains;
@@ -395,8 +533,12 @@
} else {
if ($distro =~ /^(debian|ubuntu|suse|sles)/) {
@posschains = ('INPUT');
- } else {
- @posschains = ('RH-Firewall-1-INPUT','INPUT');
+ } elsif ($distro =~ /^(fedora|rhes|centos|scientific)(\d+)$/) {
+ if ((($1 eq 'fedora') && ($2 > 15)) || (($1 ne 'fedora') && ($2 >= 7))) {
+ @posschains = ('INPUT');
+ } else {
+ @posschains = ('RH-Firewall-1-INPUT','INPUT');
+ }
}
if (!-e '/etc/sysconfig/iptables') {
if (!-e '/var/lib/iptables') {
@@ -404,8 +546,10 @@
print("Unable to find iptables file containing static definitions.\n");
}
}
- if ($distro =~ /^(fedora|rhes|centos|scientific)/) {
- push(@fw_chains,'RH-Firewall-1-INPUT');
+ if ($distro =~ /^(fedora|rhes|centos|scientific)(\d+)$/) {
+ unless ((($1 eq 'fedora') && ($2 > 15)) || (($1 ne 'fedora') && ($2 >= 7))) {
+ push(@fw_chains,'RH-Firewall-1-INPUT');
+ }
}
}
}
@@ -446,6 +590,15 @@
return $iptables;
}
+sub get_distro {
+ my $distro;
+ if (open(PIPE,"/home/httpd/perl/distprobe |")) {
+ $distro = <PIPE>;
+ close(PIPE);
+ }
+ return $distro;
+}
+
1;
__END__
@@ -460,6 +613,7 @@
use lib '/home/httpd/lib/perl/';
use LONCAPA::Firewall;
+ LONCAPA::Firewall::uses_firewalld();
LONCAPA::Firewall::firewall_open_port();
LONCAPA::Firewall::firewall_close_port();
LONCAPA::Firewall::firewall_is_port_open();
@@ -479,6 +633,12 @@
=over 4
+=item LONCAPA::Firewall::uses_firewalld( $distro );
+
+=back
+
+=over 4
+
=item LONCAPA::Firewall::firewall_open_port( $iptables,$fw_chains,$lond_port,$iphost,$port );
=back
@@ -515,7 +675,7 @@
=over 4
-=item LONCAPA::Firewall::get_fw_chains();
+=item LONCAPA::Firewall::get_fw_chains( $iptables,$distro );
=back
@@ -523,6 +683,13 @@
=item LONCAPA::Firewall::get_pathto_iptables();
+=back
+
+=over 4
+
+=item LONCAPA::Firewall::get_distro();
+
+=back
=head1 AUTHORS
More information about the LON-CAPA-cvs
mailing list