--- loncom/init.d/loncontrol 2009/06/07 23:20:38 1.36 +++ loncom/init.d/loncontrol 2009/06/10 23:51:46 1.37 @@ -1,6 +1,6 @@ #!/usr/bin/perl # -# $Id: loncontrol,v 1.36 2009/06/07 23:20:38 raeburn Exp $ +# $Id: loncontrol,v 1.37 2009/06/10 23:51:46 raeburn Exp $ # # The LearningOnline Network with CAPA # @@ -50,6 +50,7 @@ use strict; use lib '/home/httpd/lib/perl/'; use LONCAPA::Configuration; +use LONCAPA::Firewall; use Apache::lonnet; my $command=$ARGV[0]; $command=~s/[^a-z]//g; @@ -57,234 +58,6 @@ my $command=$ARGV[0]; $command=~s/[^a-z] $ENV{'PATH'}="/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin"; $ENV{'BASH_ENV'}=""; -{ # Firewall variable scoping - # Firewall code is based on the code in FC2 /etc/init.d/ntpd - my $fw_chain = 'RH-Firewall-1-INPUT'; - my $iptables = '/sbin/iptables'; - if (! -e $iptables) { - $iptables = '/usr/sbin/iptables'; - if (!-e $iptables) { - print("Unable to find iptables command\n"); - } - } - my $suse_config = "/etc/sysconfig/SuSEfirewall2"; - if (-e $suse_config) { - $fw_chain = 'input_ext'; - } else { - if (!-e '/etc/sysconfig/iptables') { - print("Unable to find iptables file containing static definitions\n"); - } - } - my $lond_port = &get_lond_port(); - if (!$lond_port) { - print("Unable to determine lond port number from LON-CAPA configuration.\n"); - } - -sub firewall_open_port { - return 'inactive firewall' if (! &firewall_is_active); - return 'port number unknown' if !$lond_port; - my @opened; - 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); - } - } - } - 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; - if ($return_status == 1) { - # Error - print "Error opening port.\n"; - } elsif ($return_status == 2) { - # Bad command - print "Bad command error opening port. Command was\n". - " ".$firewall_command."\n"; - } elsif ($return_status == 0) { - push(@opened,$port); - } - } - } - foreach my $port ($lond_port) { - if (!grep(/^\Q$port\E$/,@opened)) { - return 'Required port not open: '.$port."\n"; - } - } - return 'ok'; -} - -sub firewall_is_port_open { - my ($port) = @_; - # 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 ($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 { - if (`$iptables -L -n 2>/dev/null | grep "tcp dpt:$port"`) { - return 1; - } else { - return 0; - } - } -} - -sub firewall_is_active { - if (-e '/proc/net/ip_tables_names') { - return 1; - } else { - return 0; - } -} - -sub firewall_close_port { - return 'inactive firewall' if (! &firewall_is_active); - return 'port number unknown' if !$lond_port; - 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"; - 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 () { - 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 { - 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; -} - -sub get_lond_port { - my $perlvarref=&LONCAPA::Configuration::read_conf(); - my $lond_port; - if (ref($perlvarref) eq 'HASH') { - if (defined($perlvarref->{'londPort'})) { - $lond_port = $perlvarref->{'londPort'}; - } - } - return $lond_port; -} - -sub firewall_close_anywhere { - my ($port) = @_; - open(PIPE, "$iptables --line-numbers -n -L $fw_chain |"); - while () { - 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 { my ($daemon,$killallname)=@_; my $pidfile="/home/httpd/perl/logs/$daemon.pid"; @@ -344,65 +117,71 @@ if ($command eq "restart") { print 'Starting LON-CAPA client and daemon processes (please be patient)'. "\n"; system("su www -c '/home/httpd/perl/loncron --justcheckdaemons'"); -} elsif ($command eq "stop") { - print 'Stopping LON-CAPA'."\n"; - foreach my $daemon ('lonsql','lond','lonc','lonmemcached','lonmaxima','lonr') { - my $killallname=$daemon; - if ($daemon eq 'lonc') { $killallname='loncnew'; } - &stop_daemon($daemon,$killallname); - } - my $firewall_result = &firewall_close_port(); - if ($firewall_result) { - print "$firewall_result\n"; - } - &clean_sockets(); -} elsif ($command eq "start") { - my $firewall_result = &firewall_open_port(); - if (($firewall_result eq 'ok') || ($firewall_result eq 'inactive firewall')) { - if ($firewall_result eq 'inactive firewall') { - print "WARNING: iptables firewall is currently inactive\n"; - } - print 'Starting LON-CAPA'."\n"; - print 'Starting LON-CAPA client and daemon processes (please be patient)'. - "\n"; - system("su www -c '/home/httpd/perl/loncron --justcheckdaemons'"); - } else { - print "Not starting LON-CAPA\n"; - if ($firewall_result eq 'port number unknown') { - print "Could not check for status of LON-CAPA port in running firewall - port number unknown. \n"; - } elsif ($firewall_result) { +} elsif (($command eq "stop") || ($command eq 'start') || ($command eq 'status')) { + my $iptables = &LONCAPA::Firewall::get_pathto_iptables(); + my $fw_chain = &LONCAPA::Firewall::get_fw_chain(); + my $lond_port = &LONCAPA::Firewall::get_lond_port(); + my %iphost = &Apache::lonnet::get_iphost(); + if ($command eq 'stop') { + print 'Stopping LON-CAPA'."\n"; + foreach my $daemon ('lonsql','lond','lonc','lonmemcached','lonmaxima','lonr') { + my $killallname=$daemon; + if ($daemon eq 'lonc') { $killallname='loncnew'; } + &stop_daemon($daemon,$killallname); + } + my $firewall_result = + &LONCAPA::Firewall::firewall_close_port($iptables,$fw_chain,$lond_port,[$lond_port]); + if ($firewall_result) { print "$firewall_result\n"; } - } -} elsif ($command eq "reload") { - print 'Reload LON-CAPA config files'."\n"; - system("su www -c '/home/httpd/perl/loncron --justreload'"); -} elsif ($command eq "status") { - my $lond_port = &get_lond_port(); - my $response=`/bin/cat /home/httpd/perl/logs/*.pid 2>&1`; - if ($response=~/No such file or directory/) { - print 'LON-CAPA is not running.'."\n"; - } else { - print 'LON-CAPA is running.'."\n"; - system("su www -c '/home/httpd/perl/loncron --justcheckconnections'"); - } - if (! &firewall_is_active) { - print 'The iptables firewall is not active'."\n"; - } - my $lond_port = &get_lond_port(); - if ($lond_port) { - if (&firewall_is_port_open($lond_port)) { - print "The LON-CAPA port ($lond_port) is open in firewall.\n"; - } elsif (&firewall_is_active) { - print "The LON-CAPA port ($lond_port) is NOT open in running firewall!\n"; + &clean_sockets(); + } elsif ($command eq "start") { + my $firewall_result = + &LONCAPA::Firewall::firewall_open_port($iptables,$fw_chain,$lond_port,\%iphost,[$lond_port]); + if (($firewall_result eq 'ok') || ($firewall_result eq 'inactive firewall')) { + if ($firewall_result eq 'inactive firewall') { + print "WARNING: iptables firewall is currently inactive\n"; + } + print 'Starting LON-CAPA'."\n"; + print 'Starting LON-CAPA client and daemon processes (please be patient)'. + "\n"; + system("su www -c '/home/httpd/perl/loncron --justcheckdaemons'"); + } else { + print "Not starting LON-CAPA\n"; + if ($firewall_result eq 'port number unknown') { + print "Could not check for status of LON-CAPA port in running firewall - port number unknown. \n"; + } elsif ($firewall_result) { + print "$firewall_result\n"; + } } - } else { - if (&firewall_is_active) { - print "Could not check for status of LON-CAPA port in running firewall - port number unknown.\n"; + } elsif ($command eq "status") { + my $response=`/bin/cat /home/httpd/perl/logs/*.pid 2>&1`; + if ($response=~/No such file or directory/) { + print 'LON-CAPA is not running.'."\n"; + } else { + print 'LON-CAPA is running.'."\n"; + system("su www -c '/home/httpd/perl/loncron --justcheckconnections'"); + } + if (! &LONCAPA::Firewall::firewall_is_active()) { + print 'The iptables firewall is not active'."\n"; + } + if ($lond_port) { + if (&LONCAPA::Firewall::firewall_is_port_open($iptables,$fw_chain,$lond_port,$lond_port,\%iphost)) { + print "The LON-CAPA port ($lond_port) is open in firewall.\n"; + } elsif (&LONCAPA::Firewall::firewall_is_active) { + print "The LON-CAPA port ($lond_port) is NOT open in running firewall!\n"; + } } else { - print "LON-CAPA port number is unknown, and firewall is not running.\n"; + if (&LONCAPA::Firewall::firewall_is_active()) { + print "Could not check for status of LON-CAPA port in running firewall - port number unknown.\n"; + } else { + print "LON-CAPA port number is unknown, and firewall is not running.\n"; + } } } +} elsif ($command eq "reload") { + print 'Reload LON-CAPA config files'."\n"; + system("su www -c '/home/httpd/perl/loncron --justreload'"); } else { - print "You need to specify one of restart|stop|start|status on the command line.\n"; + print "You need to specify one of reload|restart|stop|start|status on the command line.\n"; }