[LON-CAPA-cvs] cvs: loncom /init.d loncontrol
raeburn
raeburn@source.lon-capa.org
Sun, 07 Jun 2009 23:20:38 -0000
This is a MIME encoded message
--raeburn1244416838
Content-Type: text/plain
raeburn Sun Jun 7 23:20:38 2009 EDT
Modified files:
/loncom/init.d loncontrol
Log:
- open/close firewall for port 5663 for SuSE as well as Fedora/RHEL/CentOS/Scientific Linux.
- restrict inbound traffic on port 5663 to IP addresses identified for hosts in LON-CAPA cluster to which server belongs.
- loncontrol start and loncontrol stop will eliminate firewall rule which allows inbound traffic on port 5663 from anywhere.
- reports number of IP addresses for which lond port was opened or closed
- more verbose message when expected chain is missing from current iptables listing.
--raeburn1244416838
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20090607232038.txt"
Index: loncom/init.d/loncontrol
diff -u loncom/init.d/loncontrol:1.35 loncom/init.d/loncontrol:1.36
--- loncom/init.d/loncontrol:1.35 Wed Apr 22 14:58:59 2009
+++ loncom/init.d/loncontrol Sun Jun 7 23:20:38 2009
@@ -1,6 +1,6 @@
#!/usr/bin/perl
#
-# $Id: loncontrol,v 1.35 2009/04/22 14:58:59 raeburn Exp $
+# $Id: loncontrol,v 1.36 2009/06/07 23:20:38 raeburn Exp $
#
# The LearningOnline Network with CAPA
#
@@ -50,6 +50,7 @@
use strict;
use lib '/home/httpd/lib/perl/';
use LONCAPA::Configuration;
+use Apache::lonnet;
my $command=$ARGV[0]; $command=~s/[^a-z]//g;
@@ -67,7 +68,9 @@
}
}
my $suse_config = "/etc/sysconfig/SuSEfirewall2";
- if (!-e $suse_config) {
+ if (-e $suse_config) {
+ $fw_chain = 'input_ext';
+ } else {
if (!-e '/etc/sysconfig/iptables') {
print("Unable to find iptables file containing static definitions\n");
}
@@ -81,35 +84,49 @@
return 'inactive firewall' if (! &firewall_is_active);
return 'port number unknown' if !$lond_port;
my @opened;
- my $suse_config = "/etc/sysconfig/SuSEfirewall2";
- if (-e $suse_config) {
- if (open(my $fh,"<$suse_config")) {
- while(<$fh>) {
- chomp();
- if (/^FW_SERVICES_EXT_TCP="([^"]+)"\s*$/) {
- my $portstr = $1;
- my @suseports = split(/\s+/,$portstr);
- foreach my $port ($lond_port) {
- if (grep/^\Q$port\E$/,@suseports) {
- push(@opened,$port);
- }
+ if (! `$iptables -L -n 2>/dev/null | grep $fw_chain | wc -l`) {
+ return 'Expected chain "'.$fw_chain.'" missing from iptables'."\n";
+ }
+ # iptables is running with expected chain
+ #
+ # For lond port, restrict the servers allowed to attempt to communicate
+ # to include only source IPs in the LON-CAPA cluster.
+ foreach my $port ($lond_port) {
+ print "Opening firewall access on port $port.\n";
+ my $result;
+ if ($port eq $lond_port) {
+ my (@port_error,@command_error,@lond_port_open);
+ my %iphost = &Apache::lonnet::get_iphost();
+ if (keys(%iphost) > 0) {
+ &firewall_close_anywhere($port);
+ foreach my $ip (keys(%iphost)) {
+ 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) {
+ push (@port_error,$ip);
+ } elsif ($return_status == 2) {
+ push(@command_error,$ip);
+ } elsif ($return_status == 0) {
+ push(@lond_port_open,$ip);
}
}
}
- }
- } else {
- if (! `$iptables -L -n 2>/dev/null | grep $fw_chain | wc -l`) {
- return 'chain error';
- }
- # iptables is running with our chain
- #
- # We could restrict the servers allowed to attempt to communicate
- # here, but the logistics of updating the /home/httpd/lonTabs/host.tab
- # file are likely to be a problem
- foreach my $port ($lond_port) {
- print "Opening firewall access on port $port.\n";
- my $result;
- my $firewall_command =
+ if (@lond_port_open) {
+ push(@opened,$port);
+ print "Port $port opened for ".scalar(@lond_port_open)." IP addresses\n";
+ }
+ if (@port_error) {
+ print "Error opening port $port for following IP addresses: ".join(', ',@port_error)."\n";
+ }
+ if (@command_error) {
+ print "Bad command error opening port for following IP addresses: ".
+ join(', ',@command_error)."\n".
+ 'Command was: "'."$iptables -I $fw_chain -p tcp -s ".'$ip'." -d 0/0 --dport $port -j ACCEPT".'", where $ip is IP address'."\n";
+ }
+ } else {
+ my $firewall_command =
"$iptables -I $fw_chain -p tcp -d 0/0 --dport $port -j ACCEPT";
system($firewall_command);
my $return_status = $?>>8;
@@ -135,14 +152,23 @@
sub firewall_is_port_open {
my ($port) = @_;
- # returns 1 if the firewall port is open, 0 if not.
+ # 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 (`$iptables -L -n 2>/dev/null | grep "tcp dpt:$port"`) {
- return 1;
+ if ($port eq $lond_port) {
+ my %iphost = &Apache::lonnet::get_iphost();
+ foreach my $ip (keys(%iphost)) {
+ my $count = `$iptables -L -n 2>/dev/null | grep "tcp dpt:$port" | wc -l`;
+ return $count;
+ }
} else {
- return 0;
+ if (`$iptables -L -n 2>/dev/null | grep "tcp dpt:$port"`) {
+ return 1;
+ } else {
+ return 0;
+ }
}
}
@@ -157,23 +183,67 @@
sub firewall_close_port {
return 'inactive firewall' if (! &firewall_is_active);
return 'port number unknown' if !$lond_port;
- my $suse_config = "/etc/sysconfig/SuSEfirewall2";
- return if (-e $suse_config);
+ if (! `$iptables -L -n 2>/dev/null | grep $fw_chain | wc -l`) {
+ return 'Expected chain "'.$fw_chain.'" missing from iptables'."\n";
+ }
foreach my $port ($lond_port) {
print "Closing firewall access on port $port\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.\n";
- } elsif ($return_status == 2) {
- # Bad command
- print "Bad command error closing port. Command was\n".
- " ".$firewall_command."\n";
+ if ($port eq $lond_port) {
+ my (@port_error,@command_error,@lond_port_close);
+ my %iphost = &Apache::lonnet::get_iphost();
+ my %toclose;
+ if (keys(%iphost) > 0) {
+ open(PIPE, "$iptables -n -L $fw_chain |");
+ while (<PIPE>) {
+ chomp();
+ next unless (/dpt:\Q$port\E\s*$/);
+ if (/^ACCEPT\s+tcp\s+\-{2}\s+([\S]+)\s+/) {
+ $toclose{$1} = $port;
+ }
+ }
+ close(PIPE);
+ }
+ foreach my $ip (keys(%iphost)) {
+ next unless (exists($toclose{$ip}));
+ 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 (@lond_port_close) {
+ print "Port $port closed for ".scalar(@lond_port_close)." IP addresses\n";
+ }
+ if (@port_error) {
+ print "Error closing port $port for following IP addresses: ".join(', ',@port_error)."\n";
+ }
+ if (@command_error) {
+ print "Bad command error opening port for following IP addresses: ".
+ join(', ',@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";
+ }
+ &firewall_close_anywhere($port);
} else {
- print "Port closed.\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.\n";
+ } elsif ($return_status == 2) {
+ # Bad command
+ print "Bad command error closing port. Command was\n".
+ " ".$firewall_command."\n";
+ } else {
+ print "Port closed.\n";
+ }
}
}
return;
@@ -190,6 +260,29 @@
return $lond_port;
}
+sub firewall_close_anywhere {
+ my ($port) = @_;
+ 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";
+ } else {
+ print 'Port '.$port.' closed for source "anywhere"'."\n";
+ }
+ }
+ }
+ close(PIPE);
+}
+
} # End firewall variable scope
sub stop_daemon {
--raeburn1244416838--