version 1.35, 2015/01/02 13:34:08
|
version 1.54, 2019/05/26 22:23:25
|
Line 26
|
Line 26
|
use strict; |
use strict; |
use File::Copy; |
use File::Copy; |
use Term::ReadKey; |
use Term::ReadKey; |
|
use Socket; |
|
use Sys::Hostname::FQDN(); |
use DBI; |
use DBI; |
|
use Cwd(); |
|
use File::Basename(); |
|
use lib File::Basename::dirname(Cwd::abs_path($0)); |
use LCLocalization::localize; |
use LCLocalization::localize; |
|
|
# ========================================================= The language handle |
# ========================================================= The language handle |
Line 159 sub get_user_selection {
|
Line 164 sub get_user_selection {
|
} |
} |
|
|
sub get_distro { |
sub get_distro { |
my ($distro,$gotprereqs,$updatecmd,$packagecmd,$installnow); |
my ($distro,$gotprereqs,$updatecmd,$packagecmd,$installnow,$unknown); |
$packagecmd = '/bin/rpm -q LONCAPA-prerequisites '; |
$packagecmd = '/bin/rpm -q LONCAPA-prerequisites '; |
if (-e '/etc/redhat-release') { |
if (-e '/etc/redhat-release') { |
open(IN,'</etc/redhat-release'); |
open(IN,'</etc/redhat-release'); |
Line 191 sub get_distro {
|
Line 196 sub get_distro {
|
$distro = 'rhes'.$1; |
$distro = 'rhes'.$1; |
$updatecmd = 'yum install LONCAPA-prerequisites'; |
$updatecmd = 'yum install LONCAPA-prerequisites'; |
$installnow = 'yum -y install LONCAPA-prerequisites'; |
$installnow = 'yum -y install LONCAPA-prerequisites'; |
|
} elsif ($versionstring =~ /Red Hat Enterprise Linux release (\d+)/) { |
|
$distro = 'rhes'.$1; |
|
$updatecmd = 'dnf install LONCAPA-prerequisites'; |
|
$installnow = 'dnf -y install LONCAPA-prerequisites'; |
} elsif ($versionstring =~ /CentOS(?:| Linux) release (\d+)/) { |
} elsif ($versionstring =~ /CentOS(?:| Linux) release (\d+)/) { |
$distro = 'centos'.$1; |
$distro = 'centos'.$1; |
$updatecmd = 'yum install LONCAPA-prerequisites'; |
$updatecmd = 'yum install LONCAPA-prerequisites'; |
Line 204 sub get_distro {
|
Line 213 sub get_distro {
|
} else { |
} else { |
print &mt('Unable to interpret [_1] to determine system type.', |
print &mt('Unable to interpret [_1] to determine system type.', |
'/etc/redhat-release')."\n"; |
'/etc/redhat-release')."\n"; |
|
$unknown = 1; |
} |
} |
} elsif (-e '/etc/SuSE-release') { |
} elsif (-e '/etc/SuSE-release') { |
open(IN,'</etc/SuSE-release'); |
open(IN,'</etc/SuSE-release'); |
Line 230 sub get_distro {
|
Line 240 sub get_distro {
|
} else { |
} else { |
print &mt('Unable to interpret [_1] to determine system type.', |
print &mt('Unable to interpret [_1] to determine system type.', |
'/etc/SuSE-release')."\n"; |
'/etc/SuSE-release')."\n"; |
|
$unknown = 1; |
} |
} |
} elsif (-e '/etc/issue') { |
} elsif (-e '/etc/issue') { |
open(IN,'</etc/issue'); |
open(IN,'</etc/issue'); |
my $versionstring=<IN>; |
my $versionstring=<IN>; |
chomp($versionstring); |
chomp($versionstring); |
close(IN); |
close(IN); |
$packagecmd = '/usr/bin/dpkg -l loncapa-prerequisites '; |
|
$updatecmd = 'apt-get install loncapa-prerequisites'; |
|
if ($versionstring =~ /^Ubuntu (\d+)\.\d+/i) { |
if ($versionstring =~ /^Ubuntu (\d+)\.\d+/i) { |
$distro = 'ubuntu'.$1; |
$distro = 'ubuntu'.$1; |
$updatecmd = 'sudo apt-get install loncapa-prerequisites'; |
$updatecmd = 'sudo apt-get install loncapa-prerequisites'; |
} elsif ($versionstring =~ /^Debian\s+GNU\/Linux\s+(\d+)\.\d+/i) { |
} elsif ($versionstring =~ /^Debian\s+GNU\/Linux\s+(\d+)\.\d+/i) { |
$distro = 'debian'.$1; |
$distro = 'debian'.$1; |
|
$updatecmd = 'apt-get install loncapa-prerequisites'; |
} elsif (-e '/etc/debian_version') { |
} elsif (-e '/etc/debian_version') { |
open(IN,'</etc/debian_version'); |
open(IN,'</etc/debian_version'); |
my $version=<IN>; |
my $version=<IN>; |
Line 250 sub get_distro {
|
Line 260 sub get_distro {
|
close(IN); |
close(IN); |
if ($version =~ /^(\d+)\.\d+\.?\d*/) { |
if ($version =~ /^(\d+)\.\d+\.?\d*/) { |
$distro='debian'.$1; |
$distro='debian'.$1; |
|
$updatecmd = 'apt-get install loncapa-prerequisites'; |
} else { |
} else { |
print &mt('Unable to interpret [_1] to determine system type.', |
print &mt('Unable to interpret [_1] to determine system type.', |
'/etc/debian_version')."\n"; |
'/etc/debian_version')."\n"; |
|
$unknown = 1; |
} |
} |
} else { |
} |
print &mt('Unable to interpret [_1] to determine system type.', |
if ($distro ne '') { |
'/etc/issue')."\n"; |
$packagecmd = '/usr/bin/dpkg -l loncapa-prerequisites '; |
} |
} |
} elsif (-e '/etc/debian_version') { |
} elsif (-e '/etc/debian_version') { |
open(IN,'</etc/debian_version'); |
open(IN,'</etc/debian_version'); |
Line 270 sub get_distro {
|
Line 282 sub get_distro {
|
} else { |
} else { |
print &mt('Unable to interpret [_1] to determine system type.', |
print &mt('Unable to interpret [_1] to determine system type.', |
'/etc/debian_version')."\n"; |
'/etc/debian_version')."\n"; |
|
$unknown = 1; |
|
} |
|
} |
|
if (($distro eq '') && (!$unknown)) { |
|
if (-e '/etc/os-release') { |
|
if (open(IN,'<','/etc/os-release')) { |
|
my ($id,$version); |
|
while(<IN>) { |
|
chomp(); |
|
if (/^ID="(\w+)"/) { |
|
$id=$1; |
|
} elsif (/^VERSION_ID="([\d\.]+)"/) { |
|
$version=$1; |
|
} |
|
} |
|
close(IN); |
|
if ($id eq 'sles') { |
|
my ($major,$minor) = split(/\./,$version); |
|
if ($major =~ /^\d+$/) { |
|
$distro = $id.$major; |
|
$updatecmd = 'zypper install LONCAPA-prerequisites'; |
|
} |
|
} |
|
} |
|
if ($distro eq '') { |
|
print &mt('Unable to interpret [_1] to determine system type.', |
|
'/etc/os-release')."\n"; |
|
$unknown = 1; |
|
} |
|
} else { |
|
print &mt('Unknown installation: expecting a debian, ubuntu, suse, sles, redhat, fedora or scientific linux system.')."\n"; |
} |
} |
} else { |
|
print &mt('Unknown installation: expecting a debian, ubuntu, suse, sles, redhat, fedora or scientific linux system.')."\n"; |
|
} |
} |
return ($distro,$packagecmd,$updatecmd,$installnow); |
return ($distro,$packagecmd,$updatecmd,$installnow); |
} |
} |
|
|
|
# |
|
# get_hostname() prompts the user to provide the server's hostname. |
|
# |
|
# If invalid input is provided, the routine is called recursively |
|
# until, a valid hostname is provided. |
|
# |
|
|
|
sub get_hostname { |
|
my $hostname; |
|
print &mt('Enter the hostname of this server, e.g., loncapa.somewhere.edu'."\n"); |
|
my $choice = <STDIN>; |
|
chomp($choice); |
|
$choice =~ s/(^\s+|\s+$)//g; |
|
if ($choice eq '') { |
|
print &mt("Hostname you entered was either blank or contanied only white space.\n"); |
|
} elsif ($choice =~ /^[\w\.\-]+$/) { |
|
$hostname = $choice; |
|
} else { |
|
print &mt("Hostname you entered was invalid -- a hostname may only contain letters, numbers, - and .\n"); |
|
} |
|
while ($hostname eq '') { |
|
$hostname = &get_hostname(); |
|
} |
|
print "\n"; |
|
return $hostname; |
|
} |
|
|
|
# |
|
# get_hostname() prompts the user to provide the server's IPv4 IP address |
|
# |
|
# If invalid input is provided, the routine is called recursively |
|
# until, a valid IPv4 address is provided. |
|
# |
|
|
|
sub get_hostip { |
|
my $hostip; |
|
print &mt('Enter the IP address of this server, e.g., 192.168.10.24'."\n"); |
|
my $choice = <STDIN>; |
|
chomp($choice); |
|
$choice =~ s/(^\s+|\s+$)//g; |
|
my $badformat = 1; |
|
if ($choice eq '') { |
|
print &mt("IP address you entered was either blank or contained only white space.\n"); |
|
} else { |
|
if ($choice =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/) { |
|
if (($1<=255) && ($2<=255) && ($3<=255) && ($4<=255)) { |
|
$badformat = 0; |
|
} |
|
} |
|
if ($badformat) { |
|
print &mt('Host IP you entered was invalid -- a host IP has the format d.d.d.d where each d is an integer between 0 and 255')."\n"; |
|
} else { |
|
$hostip = $choice; |
|
} |
|
} |
|
while ($hostip eq '') { |
|
$hostip = &get_hostip(); |
|
} |
|
print "\n"; |
|
return $hostip; |
|
} |
|
|
sub check_prerequisites { |
sub check_prerequisites { |
my ($packagecmd,$distro) = @_; |
my ($packagecmd,$distro) = @_; |
my $gotprereqs; |
my $gotprereqs; |
Line 314 sub check_locale {
|
Line 417 sub check_locale {
|
print &mt('Failed to open: [_1], default locale not checked.', |
print &mt('Failed to open: [_1], default locale not checked.', |
'/etc/default/locale'); |
'/etc/default/locale'); |
} |
} |
} elsif ($distro =~ /^(suse|sles)/) { |
} elsif ($distro =~ /^(suse|sles)(\d+)/) { |
if (!open($fh,"</etc/sysconfig/language")) { |
if (($1 eq 'sles') && ($2 >= 15)) { |
print &mt('Failed to open: [_1], default locale not checked.', |
if (!open($fh,"</etc/locale.conf")) { |
'/etc/sysconfig/language'); |
print &mt('Failed to open: [_1], default locale not checked.', |
|
'/etc/locale.conf'); |
|
} |
|
} else { |
|
if (!open($fh,"</etc/sysconfig/language")) { |
|
print &mt('Failed to open: [_1], default locale not checked.', |
|
'/etc/sysconfig/language'); |
|
} |
|
$langvar = 'RC_LANG'; |
} |
} |
$langvar = 'RC_LANG'; |
|
} elsif ($distro =~ /^fedora(\d+)/) { |
} elsif ($distro =~ /^fedora(\d+)/) { |
if ($1 >= 18) { |
if ($1 >= 18) { |
if (!open($fh,"</etc/locale.conf")) { |
if (!open($fh,"</etc/locale.conf")) { |
Line 360 sub check_locale {
|
Line 470 sub check_locale {
|
'sudo update-locale LANG=en_US.UTF-8'; |
'sudo update-locale LANG=en_US.UTF-8'; |
} elsif ($distro =~ /^(suse|sles)/) { |
} elsif ($distro =~ /^(suse|sles)/) { |
$command = 'yast language'; |
$command = 'yast language'; |
} else { |
} elsif (-e '/usr/bin/system-config-language') { |
$command = 'system-config-language'; |
$command = 'system-config-language'; |
|
} elsif (-e '/usr/bin/localectl') { |
|
$command = 'localectl set-locale en_US.UTF-8'; |
|
} else { |
|
$command = 'No standard command found'; |
} |
} |
} |
} |
last; |
last; |
Line 386 sub check_required {
|
Line 500 sub check_required {
|
return ($distro,$gotprereqs,$localecmd); |
return ($distro,$gotprereqs,$localecmd); |
} |
} |
my ($mysqlon,$mysqlsetup,$mysqlrestart,$dbh,$has_pass,$has_lcdb,%recommended, |
my ($mysqlon,$mysqlsetup,$mysqlrestart,$dbh,$has_pass,$has_lcdb,%recommended, |
$downloadstatus,$filetouse,$production,$testing,$apachefw,$tostop,$uses_systemctl); |
$downloadstatus,$filetouse,$production,$testing,$apachefw,$tostop, |
|
$uses_systemctl,$hostname,$hostip); |
my $wwwuid = &uid_of_www(); |
my $wwwuid = &uid_of_www(); |
my $wwwgid = getgrnam('www'); |
my $wwwgid = getgrnam('www'); |
if (($wwwuid eq '') || ($wwwgid eq '')) { |
if (($wwwuid eq '') || ($wwwgid eq '')) { |
Line 395 sub check_required {
|
Line 510 sub check_required {
|
unless( -e "/usr/local/sbin/pwauth") { |
unless( -e "/usr/local/sbin/pwauth") { |
$recommended{'pwauth'} = 1; |
$recommended{'pwauth'} = 1; |
} |
} |
|
$hostname = Sys::Hostname::FQDN::fqdn(); |
|
if ($hostname eq '') { |
|
$hostname =&get_hostname(); |
|
} else { |
|
print &mt("Hostname detected: $hostname. Is that correct? ~[Y/n~]"); |
|
if (!&get_user_selection(1)) { |
|
$hostname =&get_hostname(); |
|
} |
|
} |
|
$hostip = Socket::inet_ntoa(scalar(gethostbyname($hostname)) || 'localhost'); |
|
if ($hostip eq '') { |
|
$hostip=&get_hostip(); |
|
} else { |
|
print &mt("Host IP address detected: $hostip. Is that correct? ~[Y/n~]"); |
|
if (!&get_user_selection(1)) { |
|
$hostip=&get_hostip(); |
|
} |
|
} |
|
print_and_log("\n".&mt('Hostname is [_1] and IP address is [_2]',$hostname,$hostip)."\n"); |
$mysqlon = &check_mysql_running($distro); |
$mysqlon = &check_mysql_running($distro); |
if ($mysqlon) { |
if ($mysqlon) { |
my $mysql_has_wwwuser = &check_mysql_wwwuser(); |
my $mysql_has_wwwuser = &check_mysql_wwwuser(); |
Line 423 sub check_required {
|
Line 557 sub check_required {
|
} |
} |
} |
} |
} |
} |
|
my ($sslhostsfilesref,$has_std,$has_int,$rewritenum,$nochgstd,$nochgint); |
($recommended{'firewall'},$apachefw) = &chkfirewall($distro); |
($recommended{'firewall'},$apachefw) = &chkfirewall($distro); |
($recommended{'runlevels'},$tostop,$uses_systemctl) = &chkconfig($distro,$instdir); |
($recommended{'runlevels'},$tostop,$uses_systemctl) = &chkconfig($distro,$instdir); |
$recommended{'apache'} = &chkapache($distro,$instdir); |
$recommended{'apache'} = &chkapache($distro,$instdir); |
|
($recommended{'apachessl'},$sslhostsfilesref,$has_std,$has_int,$rewritenum, |
|
$nochgstd,$nochgint) = &chkapachessl($distro,$instdir,$hostname,$hostip); |
$recommended{'stopsrvcs'} = &chksrvcs($distro,$tostop); |
$recommended{'stopsrvcs'} = &chksrvcs($distro,$tostop); |
($recommended{'download'},$downloadstatus,$filetouse,$production,$testing) |
($recommended{'download'},$downloadstatus,$filetouse,$production,$testing) |
= &need_download(); |
= &need_download(); |
return ($distro,$gotprereqs,$localecmd,$packagecmd,$updatecmd,$installnow, |
return ($distro,$gotprereqs,$localecmd,$packagecmd,$updatecmd,$installnow, |
$mysqlrestart,\%recommended,$dbh,$has_pass,$has_lcdb,$downloadstatus, |
$mysqlrestart,\%recommended,$dbh,$has_pass,$has_lcdb,$downloadstatus, |
$filetouse,$production,$testing,$apachefw,$uses_systemctl); |
$filetouse,$production,$testing,$apachefw,$uses_systemctl,$hostname, |
|
$hostip,$sslhostsfilesref,$has_std,$has_int,$rewritenum,$nochgstd, |
|
$nochgint); |
} |
} |
|
|
sub check_mysql_running { |
sub check_mysql_running { |
Line 454 sub check_mysql_running {
|
Line 593 sub check_mysql_running {
|
$proc_owner = 'mysql'; |
$proc_owner = 'mysql'; |
$use_systemctl = 1; |
$use_systemctl = 1; |
} |
} |
|
if ($1 >= 19) { |
|
$mysqldaemon ='mariadb'; |
|
} |
} elsif ($distro =~ /^(?:centos|rhes|scientific)(\d+)/) { |
} elsif ($distro =~ /^(?:centos|rhes|scientific)(\d+)/) { |
if ($1 >= 7) { |
if ($1 >= 7) { |
$mysqldaemon ='mariadb'; |
$mysqldaemon ='mariadb'; |
Line 464 sub check_mysql_running {
|
Line 606 sub check_mysql_running {
|
} elsif ($distro =~ /^sles(\d+)/) { |
} elsif ($distro =~ /^sles(\d+)/) { |
if ($1 >= 12) { |
if ($1 >= 12) { |
$use_systemctl = 1; |
$use_systemctl = 1; |
|
$proc_owner = 'mysql'; |
|
$process = 'mysqld'; |
|
} |
|
if ($1 >= 15) { |
|
$mysqldaemon ='mariadb'; |
} |
} |
} elsif ($distro =~ /^suse(\d+)/) { |
} elsif ($distro =~ /^suse(\d+)/) { |
if ($1 >= 13) { |
if ($1 >= 13) { |
Line 548 sub chkconfig {
|
Line 695 sub chkconfig {
|
$uses_systemctl{'ntp'} = 1; |
$uses_systemctl{'ntp'} = 1; |
$uses_systemctl{'cups'} = 1; |
$uses_systemctl{'cups'} = 1; |
$uses_systemctl{'memcached'} = 1; |
$uses_systemctl{'memcached'} = 1; |
$daemon{'ntp'} = 'ntpd'; |
if (($name eq 'sles') && ($num >= 15)) { |
|
$daemon{'ntp'} = 'chronyd'; |
|
$daemon{'mysql'} = 'mariadb'; |
|
} else { |
|
$daemon{'ntp'} = 'ntpd'; |
|
} |
} |
} |
} |
} |
} |
} |
Line 556 sub chkconfig {
|
Line 708 sub chkconfig {
|
my $version = $1; |
my $version = $1; |
@runlevels = qw/2 3 4 5/; |
@runlevels = qw/2 3 4 5/; |
@norunlevels = qw/0 1 6/; |
@norunlevels = qw/0 1 6/; |
$checker_bin = '/usr/sbin/sysv-rc-conf'; |
if (($distro =~ /^ubuntu/) && ($version <= 16)) { |
|
$checker_bin = '/usr/sbin/sysv-rc-conf'; |
|
} else { |
|
$uses_systemctl{'ntp'} = 1; |
|
$uses_systemctl{'mysql'} = 1; |
|
$uses_systemctl{'apache'} = 1; |
|
$uses_systemctl{'memcached'} = 1; |
|
$uses_systemctl{'cups'} = 1; |
|
} |
$daemon{'mysql'} = 'mysql'; |
$daemon{'mysql'} = 'mysql'; |
$daemon{'apache'} = 'apache2'; |
$daemon{'apache'} = 'apache2'; |
$daemon{'ntp'} = 'ntp'; |
$daemon{'ntp'} = 'ntp'; |
Line 574 sub chkconfig {
|
Line 734 sub chkconfig {
|
$uses_systemctl{'memcached'} = 1; |
$uses_systemctl{'memcached'} = 1; |
$uses_systemctl{'cups'} = 1; |
$uses_systemctl{'cups'} = 1; |
} |
} |
|
if ($version >= 19) { |
|
$daemon{'mysql'} = 'mariadb'; |
|
} |
} elsif ($distro =~ /^(?:centos|rhes|scientific)(\d+)/) { |
} elsif ($distro =~ /^(?:centos|rhes|scientific)(\d+)/) { |
my $version = $1; |
my $version = $1; |
if ($version >= 7) { |
if ($version >= 7) { |
Line 584 sub chkconfig {
|
Line 747 sub chkconfig {
|
$uses_systemctl{'cups'} = 1; |
$uses_systemctl{'cups'} = 1; |
$daemon{'mysql'} = 'mariadb'; |
$daemon{'mysql'} = 'mariadb'; |
} |
} |
|
if ($version >= 8) { |
|
$daemon{'ntp'} = 'chronyd'; |
|
} |
} |
} |
my $nocheck; |
my $nocheck; |
if (! -x $checker_bin) { |
if (! -x $checker_bin) { |
Line 667 sub chkconfig {
|
Line 833 sub chkconfig {
|
} else { |
} else { |
$major = $version; |
$major = $version; |
} |
} |
if ($major > 10) { |
if (($major > 10) && ($major <= 13)) { |
if (&check_SuSEfirewall2_setup($instdir)) { |
if (&check_SuSEfirewall2_setup($instdir)) { |
$needfix{'insserv'} = 1; |
$needfix{'insserv'} = 1; |
} |
} |
Line 676 sub chkconfig {
|
Line 842 sub chkconfig {
|
return (\%needfix,\%tostop,\%uses_systemctl); |
return (\%needfix,\%tostop,\%uses_systemctl); |
} |
} |
|
|
|
sub uses_firewalld { |
|
my ($distro) = @_; |
|
my ($inuse,$checkfirewalld,$zone); |
|
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; |
|
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); |
|
} |
|
|
sub chkfirewall { |
sub chkfirewall { |
my ($distro) = @_; |
my ($distro) = @_; |
my $configfirewall = 1; |
my $configfirewall = 1; |
Line 684 sub chkfirewall {
|
Line 896 sub chkfirewall {
|
https => 443, |
https => 443, |
); |
); |
my %activefw; |
my %activefw; |
if (&firewall_is_active()) { |
my ($firewalld,$zone) = &uses_firewalld($distro); |
my $iptables = &get_pathto_iptables(); |
if ($firewalld) { |
if ($iptables eq '') { |
my %current; |
print &mt('Firewall not checked as path to iptables not determined.')."\n"; |
if (open(PIPE,'firewall-cmd --permanent --zone='.$zone.' --list-services |')) { |
} else { |
my $svc = <PIPE>; |
my @fwchains = &get_fw_chains($iptables,$distro); |
close(PIPE); |
if (@fwchains) { |
chomp($svc); |
foreach my $service ('http','https') { |
map { $current{$_} = 1; } (split(/\s+/,$svc)); |
foreach my $fwchain (@fwchains) { |
} |
if (&firewall_is_port_open($iptables,$fwchain,$ports{$service})) { |
if ($current{'http'} && $current{'https'}) { |
$activefw{$service} = 1; |
$configfirewall = 0; |
last; |
} |
|
} else { |
|
if (&firewall_is_active()) { |
|
my $iptables = &get_pathto_iptables(); |
|
if ($iptables eq '') { |
|
print &mt('Firewall not checked as path to iptables not determined.')."\n"; |
|
} else { |
|
my @fwchains = &get_fw_chains($iptables,$distro); |
|
if (@fwchains) { |
|
foreach my $service ('http','https') { |
|
foreach my $fwchain (@fwchains) { |
|
if (&firewall_is_port_open($iptables,$fwchain,$ports{$service})) { |
|
$activefw{$service} = 1; |
|
last; |
|
} |
} |
} |
} |
} |
|
if ($activefw{'http'}) { |
|
$configfirewall = 0; |
|
} |
|
} else { |
|
print &mt('Firewall not checked as iptables Chains not identified.')."\n"; |
} |
} |
if ($activefw{'http'}) { |
|
$configfirewall = 0; |
|
} |
|
} else { |
|
print &mt('Firewall not checked as iptables Chains not identified.')."\n"; |
|
} |
} |
|
} else { |
|
print &mt('Firewall not enabled.')."\n"; |
} |
} |
} else { |
|
print &mt('Firewall not enabled.')."\n"; |
|
} |
} |
return ($configfirewall,\%activefw); |
return ($configfirewall,\%activefw); |
} |
} |
Line 766 sub chkapache {
|
Line 992 sub chkapache {
|
} |
} |
} |
} |
} |
} |
} elsif ($distro =~ /^(?:suse|sles)([\d\.]+)$/) { |
} elsif ($distro =~ /^(suse|sles)([\d\.]+)$/) { |
|
my ($name,$version) = ($1,$2); |
my $apache = 'apache'; |
my $apache = 'apache'; |
if ($1 >= 10) { |
my $conf_file = "$instdir/sles-suse/default-server.conf"; |
|
if ($version >= 10) { |
$apache = 'apache2'; |
$apache = 'apache2'; |
} |
} |
if (!-e "$instdir/sles-suse/default-server.conf") { |
if (($name eq 'sles') && ($version >= 12)) { |
|
$conf_file = "$instdir/sles-suse/apache2.4/default-server.conf"; |
|
} |
|
if (!-e "$conf_file") { |
$fixapache = 0; |
$fixapache = 0; |
print &mt('Warning: No LON-CAPA Apache configuration file found for installation check.')."\n"; |
print &mt('Warning: No LON-CAPA Apache configuration file found for installation check.')."\n"; |
} elsif ((-e "/etc/$apache/default-server.conf") && (-e "$instdir/sles-suse/default-server.conf")) { |
} elsif (-e "/etc/$apache/default-server.conf") { |
if (open(PIPE, "diff --brief $instdir/sles-suse/default-server.conf /etc/$apache/default-server.conf |")) { |
if (open(PIPE, "diff --brief $conf_file /etc/$apache/default-server.conf |")) { |
my $diffres = <PIPE>; |
my $diffres = <PIPE>; |
close(PIPE); |
close(PIPE); |
chomp($diffres); |
chomp($diffres); |
Line 830 sub chkapache {
|
Line 1061 sub chkapache {
|
return $fixapache; |
return $fixapache; |
} |
} |
|
|
|
# |
|
# chkapachessl() determines whether a server's Apache SSL configuration |
|
# needs updating to support LON-CAPA. |
|
# |
|
# LON-CAPA uses VirtualHosts for port 443, and requires that they are |
|
# defined in one Apache configuration file containing two VirtualHost |
|
# blocks, in order: |
|
# |
|
# (1) a block with no ServerName, or with ServerName set to the |
|
# server's hostname. This block should contain: |
|
# |
|
# <IfModule mod_rewrite.c> |
|
# LON-CAPA rewrite rules defined in sslrewrite.conf |
|
# </IfModule> |
|
# |
|
# (2) a block with ServerName set to internal-$hostname |
|
# (where $hostname is server's hostname). |
|
# This block should contain the config and rewrite rules |
|
# found in loncapassl.conf. |
|
# |
|
# chkapachessl() retrieves the names of .conf files in |
|
# the directory appropriate for the particular Linux distro, |
|
# and then checks to see which .conf file is the best candidate as |
|
# the single file containing VirtualHosts definitions and |
|
# <IfModule mod_rewrite.c> </IfModule> rewrite blocks. |
|
# |
|
# The best candidate is the one containing a block: |
|
# <VirtualHost ????? :443> |
|
# (where ????? might be _default_ or * or an IP address) |
|
# <IfModule mod_rewrite.c> |
|
# </IfModule> |
|
# </VirtualHost> |
|
# with the fewest differences between the contents of the |
|
# IfModule block and the expected contents (from sslrewrite.conf) |
|
# |
|
# If there are no files with rewrite blocks, then a candidate file |
|
# is chosen from the .conf files containing VirtualHosts definitions. |
|
# |
|
# If the user includes "Configure SSL for Apache web server" as |
|
# one of the actions to take to prepare the server for LON-CAPA |
|
# installation, then the output from &chkapachessl() will be |
|
# used to determined which file will contain VirtualHost configs. |
|
# |
|
# If there are no files containing VirtualHosts definitions, then |
|
# <VirtualHost *:443> </VirtualHost> blocks will be appended to |
|
# the standard Apache SSL config for the particular distro: |
|
# ssl.conf for RHEL/CentOS/Scientific/Fedora, vhost-ssl.conf |
|
# for SuSE/SLES, and default-ssl.conf for Ubuntu. |
|
# |
|
# Once a file is selected, the contents of sslrewrite.conf and |
|
# loncapassl.conf are compared with appropriate blocks in the file |
|
# and the user will be prompted to agree to insertion of missing |
|
# lines and/or deletion of surplus lines. |
|
# |
|
|
|
sub chkapachessl { |
|
my ($distro,$instdir,$hostname,$hostip) = @_; |
|
my $fixapachessl = 1; |
|
my $sslintconf = "$instdir/loncapassl.conf"; |
|
my $sslrewriteconf = "$instdir/sslrewrite.conf"; |
|
my (%sslfiles,%rewrites,%vhostonly,$has_std,$has_int,$rewritenum,$nochgint,$nochgstd); |
|
$nochgstd = 0; |
|
$nochgint = 0; |
|
if (!-e $sslintconf) { |
|
$fixapachessl = 0; |
|
print &mt('Warning: LON-CAPA SSL Apache configuration file [_1] needed for installation check.',$sslintconf)."\n"; |
|
} elsif (!-e $sslrewriteconf) { |
|
$fixapachessl = 0; |
|
print &mt('Warning: LON-CAPA SSL Apache configuration file [_1] needed for installation check is missing.',$sslrewriteconf)."\n"; |
|
} else { |
|
my $ssldir; |
|
if ($distro =~ /^(debian|ubuntu)(\d+)$/) { |
|
$ssldir = '/etc/apache2/sites-available'; |
|
} elsif ($distro =~ /(suse|sles)/) { |
|
$ssldir = '/etc/apache2/vhosts.d'; |
|
} else { |
|
$ssldir = '/etc/httpd/conf.d'; |
|
} |
|
my @rewritessl = (); |
|
if (open(my $fh,'<',$sslrewriteconf)) { |
|
my $skipnext = 0; |
|
while (<$fh>) { |
|
chomp(); |
|
s/(^\s+|\s+$)//g; |
|
next if ($_ eq ''); |
|
next if ($_ eq '<IfModule mod_rewrite.c>'); |
|
next if ($_ eq '</IfModule>'); |
|
if ($_ eq 'RewriteCond %{REMOTE_ADDR} {[[[[HostIP]]]]}') { |
|
if (($hostip ne '') && ($hostip ne '127.0.0.1')) { |
|
push(@rewritessl,'RewriteCond %{REMOTE_ADDR} '.$hostip); |
|
next; |
|
} else { |
|
$skipnext = 1; |
|
} |
|
} elsif (($_ eq 'RewriteRule (.*) - [L]') && ($skipnext)) { |
|
$skipnext = 0; |
|
next; |
|
} |
|
push(@rewritessl,$_); |
|
} |
|
} |
|
my @intssl = (); |
|
if (open(my $fh,'<',$sslintconf)) { |
|
while(<$fh>) { |
|
chomp(); |
|
s/(^\s+|\s+$)//g; |
|
next if ($_ eq ''); |
|
if ($_ eq 'ServerName internal-{[[[[Hostname]]]]}') { |
|
if ($hostname ne '') { |
|
push(@intssl,'ServerName internal-'.$hostname); |
|
next; |
|
} |
|
} |
|
next if ($_ eq '<VirtualHost *:443>'); |
|
next if ($_ eq '</VirtualHost>'); |
|
push(@intssl,$_); |
|
} |
|
} |
|
if (-d $ssldir) { |
|
my @actualint = (); |
|
if (opendir(my $dir,$ssldir)) { |
|
my @sslconf_files; |
|
foreach my $file (grep(!/^\.+/,readdir($dir))) { |
|
next if (($distro =~ /(suse|sles)/) && ($file =~ /\.template$/)); |
|
next if ($file =~ /\.rpmnew$/); |
|
if (open(my $fh,'<',"$ssldir/$file")) { |
|
while (<$fh>) { |
|
if (/^\s*<VirtualHost\s+[^:]*\:443>\s*$/) { |
|
push(@sslconf_files,$file); |
|
last; |
|
} |
|
} |
|
close($fh); |
|
} |
|
} |
|
closedir($dir); |
|
if (@sslconf_files) { |
|
foreach my $file (@sslconf_files) { |
|
if (open(my $fh,'<',"$ssldir/$file")) { |
|
my ($virtualhost,$rewrite,$num) = (0,0,0); |
|
my ($currname,$has_rewrite); |
|
while (<$fh>) { |
|
chomp(); |
|
next if (/^\s*$/); |
|
if ($virtualhost) { |
|
if (/^\s*<\/VirtualHost>/) { |
|
if ($currname !~ /^\Qinternal-$hostname\E/) { |
|
if ($has_rewrite) { |
|
delete($vhostonly{$file}); |
|
} else { |
|
$vhostonly{$file} = 1; |
|
} |
|
} |
|
$sslfiles{$currname}{$file} = 1; |
|
$virtualhost = 0; |
|
$currname = ''; |
|
$has_rewrite = ''; |
|
next; |
|
} elsif (/^\s*ServerName\s+([^\s]+)\s*$/) { |
|
$currname = $1; |
|
} |
|
if ($currname =~ /^\Qinternal-$hostname\E/) { |
|
s/(^\s+|\s+$)//g; |
|
push(@actualint,$_); |
|
$has_int = $file; |
|
} else { |
|
if ($rewrite) { |
|
if (/^\s*<\/IfModule>/) { |
|
$rewrite = 0; |
|
$num ++; |
|
} else { |
|
s/(^\s+|\s+$)//g; |
|
push(@{$rewrites{$file}[$num]},$_); |
|
} |
|
} elsif (/^\s*<IfModule\s+mod_rewrite\.c>/) { |
|
$rewrite = 1; |
|
$has_rewrite = 1; |
|
if ($currname eq '') { |
|
$currname = $hostname; |
|
} |
|
$rewrites{$file}[$num] = []; |
|
} |
|
} |
|
} elsif (/^\s*<VirtualHost\s+[^:]*\:443>\s*$/) { |
|
$virtualhost = 1; |
|
} |
|
} |
|
close($fh); |
|
} |
|
} |
|
} |
|
if (keys(%rewrites)) { |
|
my $mindiffsall; |
|
foreach my $file (sort(keys(%rewrites))) { |
|
if (ref($rewrites{$file}) eq 'ARRAY') { |
|
my $mindiffs; |
|
for (my $i=0; $i<@{$rewrites{$file}}; $i++) { |
|
if (ref($rewrites{$file}[$i]) eq 'ARRAY') { |
|
my @diffs = &compare_arrays($rewrites{$file}[$i],\@rewritessl); |
|
if (@diffs == 0) { |
|
$fixapachessl = 0; |
|
$mindiffs = 0; |
|
$rewritenum = 1+$i; |
|
last; |
|
} else { |
|
if ($mindiffs eq '') { |
|
$mindiffs = scalar(@diffs); |
|
$rewritenum = 1+$i; |
|
} elsif (scalar(@diffs) <= $mindiffs) { |
|
$mindiffs = scalar(@diffs); |
|
$rewritenum = 1+$i; |
|
} |
|
} |
|
} |
|
} |
|
if ($mindiffsall eq '') { |
|
$mindiffsall = $mindiffs; |
|
$has_std = $file; |
|
} elsif ($mindiffs <= $mindiffsall) { |
|
$mindiffsall = $mindiffs; |
|
$has_std = $file; |
|
} |
|
if ($mindiffsall == 0) { |
|
$nochgstd = 1; |
|
} |
|
} |
|
} |
|
} elsif (keys(%vhostonly) > 0) { |
|
if (($has_int ne '') && (exists($vhostonly{$has_int}))) { |
|
$has_std = $has_int; |
|
} |
|
} |
|
if (@actualint) { |
|
my @diffs = &compare_arrays(\@actualint,\@intssl); |
|
if (@diffs) { |
|
$fixapachessl = 1; |
|
} else { |
|
$nochgint = 1; |
|
} |
|
} else { |
|
$fixapachessl = 1; |
|
} |
|
} |
|
} |
|
unless ($fixapachessl) { |
|
if ($distro =~ /^(debian|ubuntu)(\d+)$/) { |
|
my $enabled_dir = '/etc/apache2/sites-enabled'; |
|
if (keys(%sslfiles)) { |
|
foreach my $key (sort(keys(%sslfiles))) { |
|
if (ref($sslfiles{$key}) eq 'HASH') { |
|
foreach my $file (sort(keys(%{$sslfiles{$key}}))) { |
|
unless ((-l "$enabled_dir/$file") && |
|
(readlink("$enabled_dir/$file") eq "$ssldir/$file")) { |
|
print_and_log(&mt("Warning, use: 'sudo a2ensite $file' to activate LON-CAPA SSL Apache config\n")); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
return ($fixapachessl,\%sslfiles,$has_std,$has_int,$rewritenum,$nochgstd,$nochgint); |
|
} |
|
|
|
# |
|
# compare_arrays() expects two refs to arrays as args. |
|
# |
|
# The contents of the two arrays are compared, and if they |
|
# are different, and array of the differences is returned. |
|
# |
|
|
|
sub compare_arrays { |
|
my ($arrayref1,$arrayref2) = @_; |
|
my (@difference,%count); |
|
@difference = (); |
|
%count = (); |
|
if ((ref($arrayref1) eq 'ARRAY') && (ref($arrayref2) eq 'ARRAY')) { |
|
foreach my $element (@{$arrayref1}, @{$arrayref2}) { $count{$element}++; } |
|
foreach my $element (keys(%count)) { |
|
if ($count{$element} == 1) { |
|
push(@difference,$element); |
|
} |
|
} |
|
} |
|
return @difference; |
|
} |
|
|
sub chksrvcs { |
sub chksrvcs { |
my ($distro,$tostop) = @_; |
my ($distro,$tostop) = @_; |
my %stopsrvcs; |
my %stopsrvcs; |
Line 1060 sub get_pathto_iptables {
|
Line 1579 sub get_pathto_iptables {
|
|
|
sub firewall_is_active { |
sub firewall_is_active { |
if (-e '/proc/net/ip_tables_names') { |
if (-e '/proc/net/ip_tables_names') { |
return 1; |
if (open(PIPE,'cat /proc/net/ip_tables_names |grep filter |')) { |
} else { |
my $status = <PIPE>; |
return 0; |
close(PIPE); |
|
chomp($status); |
|
if ($status eq 'filter') { |
|
return 1; |
|
} |
|
} |
} |
} |
|
return 0; |
} |
} |
|
|
sub get_fw_chains { |
sub get_fw_chains { |
Line 1079 sub get_fw_chains {
|
Line 1604 sub get_fw_chains {
|
@posschains = ('ufw-user-input','INPUT'); |
@posschains = ('ufw-user-input','INPUT'); |
} elsif ($distro =~ /^debian5/) { |
} elsif ($distro =~ /^debian5/) { |
@posschains = ('INPUT'); |
@posschains = ('INPUT'); |
|
} elsif ($distro =~ /^(suse|sles)(\d+)/) { |
|
@posschains = ('IN_public'); |
} else { |
} else { |
@posschains = ('RH-Firewall-1-INPUT','INPUT'); |
@posschains = ('RH-Firewall-1-INPUT','INPUT'); |
if (!-e '/etc/sysconfig/iptables') { |
if (!-e '/etc/sysconfig/iptables') { |
Line 1221 print "
|
Line 1748 print "
|
".&mt('3.')." ".&mt('Set-up the MySQL database.')." |
".&mt('3.')." ".&mt('Set-up the MySQL database.')." |
".&mt('4.')." ".&mt('Set-up MySQL permissions.')." |
".&mt('4.')." ".&mt('Set-up MySQL permissions.')." |
".&mt('5.')." ".&mt('Configure Apache web server.')." |
".&mt('5.')." ".&mt('Configure Apache web server.')." |
".&mt('6.')." ".&mt('Configure start-up of services.')." |
".&mt('6.')." ".&mt('Configure SSL for Apache web server.')." |
".&mt('7.')." ".&mt('Check firewall settings.')." |
".&mt('7.')." ".&mt('Configure start-up of services.')." |
".&mt('8.')." ".&mt('Stop services not used by LON-CAPA,')." |
".&mt('8.')." ".&mt('Check firewall settings.')." |
|
".&mt('9.')." ".&mt('Stop services not used by LON-CAPA,')." |
".&mt('i.e., services for a print server: [_1] daemon.',"'cups'")." |
".&mt('i.e., services for a print server: [_1] daemon.',"'cups'")." |
".&mt('9.')." ".&mt('Download LON-CAPA source code in readiness for installation.')." |
".&mt('10.')." ".&mt('Download LON-CAPA source code in readiness for installation.')." |
|
|
".&mt('Typically, you will run this script only once, when you first install LON-CAPA.')." |
".&mt('Typically, you will run this script only once, when you first install LON-CAPA.')." |
|
|
Line 1255 chomp($instdir);
|
Line 1783 chomp($instdir);
|
|
|
my %callsub; |
my %callsub; |
my @actions = ('wwwuser','pwauth','mysql','mysqlperms','apache', |
my @actions = ('wwwuser','pwauth','mysql','mysqlperms','apache', |
'runlevels','firewall','stopsrvcs','download'); |
'apachessl','runlevels','firewall','stopsrvcs','download'); |
my %prompts = &texthash( |
my %prompts = &texthash( |
wwwuser => "Create the 'www' user?", |
wwwuser => "Create the 'www' user?", |
pwauth => 'Install the package LON-CAPA uses to authenticate users?', |
pwauth => 'Install the package LON-CAPA uses to authenticate users?', |
mysql => 'Set-up the MySQL database?', |
mysql => 'Set-up the MySQL database?', |
mysqlperms => 'Set-up MySQL permissions?', |
mysqlperms => 'Set-up MySQL permissions?', |
apache => 'Configure Apache web server?', |
apache => 'Configure Apache web server?', |
|
apachessl => 'Configure SSL for Apache web server?', |
runlevels => 'Set overrides for start-up order of services?', |
runlevels => 'Set overrides for start-up order of services?', |
firewall => 'Configure firewall settings for Apache', |
firewall => 'Configure firewall settings for Apache', |
stopsrvcs => 'Stop extra services not required on a LON-CAPA server?', |
stopsrvcs => 'Stop extra services not required on a LON-CAPA server?', |
download => 'Download LON-CAPA source code in readiness for installation?', |
download => 'Download LON-CAPA source code in readiness for installation?', |
); |
); |
|
|
print "\n".&mt('Checking system status ...')."\n"; |
print "\n".&mt('Checking system status ...')."\n\n"; |
|
|
my $dsn = "DBI:mysql:database=mysql"; |
my $dsn = "DBI:mysql:database=mysql"; |
my ($distro,$gotprereqs,$localecmd,$packagecmd,$updatecmd,$installnow,$mysqlrestart, |
my ($distro,$gotprereqs,$localecmd,$packagecmd,$updatecmd,$installnow,$mysqlrestart, |
$recommended,$dbh,$has_pass,$has_lcdb,$downloadstatus,$filetouse,$production, |
$recommended,$dbh,$has_pass,$has_lcdb,$downloadstatus,$filetouse,$production, |
$testing,$apachefw,$uses_systemctl) = &check_required($instdir,$dsn); |
$testing,$apachefw,$uses_systemctl,$hostname,$hostip,$sslhostsfiles,$has_std, |
|
$has_int,$rewritenum,$nochgstd,$nochgint) = &check_required($instdir,$dsn); |
if ($distro eq '') { |
if ($distro eq '') { |
print "\n".&mt('Linux distribution could not be verified as a supported distribution.')."\n". |
print "\n".&mt('Linux distribution could not be verified as a supported distribution.')."\n". |
&mt('The following are supported: [_1].', |
&mt('The following are supported: [_1].', |
Line 1301 if (!$gotprereqs) {
|
Line 1831 if (!$gotprereqs) {
|
&mt('The following command can be used to install the package (and dependencies):')."\n\n". |
&mt('The following command can be used to install the package (and dependencies):')."\n\n". |
$updatecmd."\n\n"; |
$updatecmd."\n\n"; |
if ($installnow eq '') { |
if ($installnow eq '') { |
print &mt('Stopping execution.')."\n"; |
|
exit; |
exit; |
} else { |
} else { |
print &mt('Run command? ~[Y/n~]'); |
print &mt('Run command? ~[Y/n~]'); |
Line 1441 if ($dbh) {
|
Line 1970 if ($dbh) {
|
|
|
if ($callsub{'apache'}) { |
if ($callsub{'apache'}) { |
if ($distro =~ /^(suse|sles)/) { |
if ($distro =~ /^(suse|sles)/) { |
©_apache2_suseconf($instdir); |
©_apache2_suseconf($instdir,$hostname,$distro); |
} elsif ($distro =~ /^(debian|ubuntu)/) { |
} elsif ($distro =~ /^(debian|ubuntu)/) { |
©_apache2_debconf($instdir,$distro); |
©_apache2_debconf($instdir,$distro,$hostname); |
} else { |
} else { |
©_httpd_conf($instdir,$distro); |
©_httpd_conf($instdir,$distro,$hostname); |
} |
} |
} else { |
} else { |
print_and_log(&mt('Skipping configuration of Apache web server.')."\n"); |
print_and_log(&mt('Skipping configuration of Apache web server.')."\n"); |
} |
} |
|
|
|
if ($callsub{'apachessl'}) { |
|
my $targetdir = '/etc/httpd/conf.d'; |
|
if ($distro =~ /^(suse|sles)/) { |
|
$targetdir = '/etc/apache2/vhosts.d'; |
|
} elsif ($distro =~ /^(debian|ubuntu)/) { |
|
$targetdir = '/etc/apache2/sites-available'; |
|
} |
|
my ($new_rewrite,$new_int) = |
|
©_apache_sslconf_files($distro,$hostname,$hostip,$instdir,$targetdir,$sslhostsfiles, |
|
$has_std,$has_int,$rewritenum,$nochgstd,$nochgint); |
|
if ($distro =~ /^(debian|ubuntu)/) { |
|
my $apache2_sites_enabled_dir = '/etc/apache2/sites-enabled'; |
|
if (-d $apache2_sites_enabled_dir) { |
|
if ($has_std ne '') { |
|
unless ((-l "$apache2_sites_enabled_dir/$has_std") && (readlink(("$apache2_sites_enabled_dir/$has_std") eq "$targetdir/$has_std"))) { |
|
my $made_symlink = eval { symlink("$targetdir/$has_std","$apache2_sites_enabled_dir/$has_std"); 1}; |
|
if ($made_symlink) { |
|
print_and_log(&mt('Enabling "[_1]" Apache SSL configuration.',$has_std)."\n"); |
|
} |
|
} |
|
} |
|
if (($has_int ne '') && ($has_int ne $has_std)) { |
|
unless ((-l "$apache2_sites_enabled_dir/$has_int") && (readlink("$apache2_sites_enabled_dir/$has_int") eq "$targetdir/$has_int")) { |
|
my $made_symlink = eval { symlink("$targetdir/$has_int","$apache2_sites_enabled_dir/$has_int"); 1 }; |
|
if ($made_symlink) { |
|
print_and_log(&mt('Enabling "[_1]" Apache SSL configuration.',$has_int)."\n"); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
print_and_log("\n"); |
|
} else { |
|
print_and_log(&mt('Skipping configuration of SSL for Apache web server.')."\n"); |
|
} |
|
|
if ($callsub{'runlevels'}) { |
if ($callsub{'runlevels'}) { |
my $count = 0; |
my $count = 0; |
if (ref($recommended) eq 'HASH') { |
if (ref($recommended) eq 'HASH') { |
Line 1469 if ($callsub{'runlevels'}) {
|
Line 2034 if ($callsub{'runlevels'}) {
|
} |
} |
} |
} |
} |
} |
if ($distro =~ /^(suse|sles)/) { |
if ($distro =~ /^(suse|sles)(\d+)/) { |
&update_SuSEfirewall2_setup($instdir); |
unless(($1 eq 'sles') && ($2 >= 15)) { |
|
&update_SuSEfirewall2_setup($instdir); |
|
} |
} |
} |
} else { |
} else { |
&print_and_log(&mt('Skipping setting override for start-up order of services.')."\n"); |
&print_and_log(&mt('Skipping setting override for start-up order of services.')."\n"); |
} |
} |
|
|
if ($callsub{'firewall'}) { |
if ($callsub{'firewall'}) { |
if ($distro =~ /^(suse|sles)/) { |
my ($firewalld,$zone) = &uses_firewalld($distro); |
|
if ($firewalld) { |
|
my (%current,%added); |
|
if (open(PIPE,"firewall-cmd --permanent --zone=$zone --list-services |")) { |
|
my $svc = <PIPE>; |
|
close(PIPE); |
|
chomp($svc); |
|
map { $current{$_} = 1; } (split(/\s+/,$svc)); |
|
} |
|
foreach my $service ('http','https') { |
|
unless ($current{$service}) { |
|
if (open(PIPE,"firewall-cmd --permanent --zone=$zone --add-service=$service |")) { |
|
my $result = <PIPE>; |
|
if ($result =~ /^success/) { |
|
$added{$service} = 1; |
|
} |
|
} |
|
} |
|
} |
|
if (keys(%added) > 0) { |
|
print &mt('Firewall configured to allow access for: [_1].', |
|
join(', ',sort(keys(%added))))."\n"; |
|
} |
|
if ($current{'http'} || $current{'https'}) { |
|
print &mt('Firewall already configured to allow access for:[_1].', |
|
(($current{'http'})? ' http':'').(($current{'https'})? ' https':''))."\n"; |
|
} |
|
unless ($current{'ssh'}) { |
|
print &mt('If you would the like to allow access to ssh from outside, use the command[_1].', |
|
"firewall-cmd --permanent --zone=$zone --add-service=ssh")."\n"; |
|
} |
|
} elsif ($distro =~ /^(suse|sles)/) { |
print &mt('Use [_1] to configure the firewall to allow access for [_2].', |
print &mt('Use [_1] to configure the firewall to allow access for [_2].', |
'yast -- Security and Users -> Firewall -> Interfaces', |
'yast -- Security and Users -> Firewall -> Interfaces', |
'ssh, http, https')."\n"; |
'ssh, http, https')."\n"; |
} elsif ($distro =~ /^(debian|ubuntu)(\d+)/) { |
} elsif ($distro =~ /^(debian|ubuntu)(\d+)/) { |
if (($1 eq 'ubuntu') || ($2 > 5)) { |
if (($1 eq 'ubuntu') || ($2 > 5)) { |
print &mt('Use [_1] to configure the firewall to allow access for [_2].', |
print &mt('Use [_1] to configure the firewall to allow access for [_2].', |
Line 1502 if ($callsub{'firewall'}) {
|
Line 2100 if ($callsub{'firewall'}) {
|
'system-config-firewall-tui -- Customize', |
'system-config-firewall-tui -- Customize', |
'ssh, http')."\n"; |
'ssh, http')."\n"; |
} else { |
} else { |
print &mt('Use [_1] to configure the firewall to allow access for [_2].', |
my $version; |
'setup -- Firewall configuration -> Customize', |
if ($distro =~ /^(redhat|centos)(\d+)$/) { |
'ssh, http, https')."\n"; |
$version = $1; |
|
} |
|
if ($version > 5) { |
|
print &mt('Use [_1] to configure the firewall to allow access for [_2].', |
|
'system-config-firewall-tui -- Customize', |
|
'ssh, http')."\n"; |
|
} else { |
|
print &mt('Use [_1] to configure the firewall to allow access for [_2].', |
|
'setup -- Firewall configuration -> Customize', |
|
'ssh, http, https')."\n"; |
|
} |
} |
} |
} else { |
} else { |
&print_and_log(&mt('Skipping Firewall configuration.')."\n"); |
&print_and_log(&mt('Skipping Firewall configuration.')."\n"); |
} |
} |
|
|
if ($callsub{'stopsrvcs'}) { |
if ($callsub{'stopsrvcs'}) { |
&kill_extra_services($distro,$recommended->{'stopsrvcs'}); |
&kill_extra_services($distro,$recommended->{'stopsrvcs'},$uses_systemctl); |
} else { |
} else { |
&print_and_log(&mt('Skipping stopping unnecessary service ([_1] daemons).',"'cups','memcached'")."\n"); |
&print_and_log(&mt('Skipping stopping unnecessary service ([_1] daemons).',"'cups','memcached'")."\n"); |
} |
} |
Line 1698 END
|
Line 2306 END
|
} |
} |
|
|
sub kill_extra_services { |
sub kill_extra_services { |
my ($distro,$stopsrvcs) = @_; |
my ($distro,$stopsrvcs,$uses_systemctl) = @_; |
if (ref($stopsrvcs) eq 'HASH') { |
if (ref($stopsrvcs) eq 'HASH') { |
my @stopping = sort(keys(%{$stopsrvcs})); |
my @stopping = sort(keys(%{$stopsrvcs})); |
if (@stopping) { |
if (@stopping) { |
Line 1729 sub kill_extra_services {
|
Line 2337 sub kill_extra_services {
|
} |
} |
} |
} |
&print_and_log(&mt('Removing [_1] from startup.',$service)."\n"); |
&print_and_log(&mt('Removing [_1] from startup.',$service)."\n"); |
if ($distro =~ /^(debian|ubuntu)/) { |
if ($distro =~ /^(?:debian|ubuntu)(\d+)/) { |
&print_and_log(`update-rc.d -f $daemon remove`); |
my $version = $1; |
|
if (($distro =~ /^ubuntu/) && ($version > 16)) { |
|
if (ref($uses_systemctl) eq 'HASH') { |
|
if ($uses_systemctl->{$service}) { |
|
if (`systemctl is-enabled $service`) { |
|
&print_and_log(`systemctl disable $service`); |
|
} |
|
} |
|
} |
|
} else { |
|
&print_and_log(`update-rc.d -f $daemon remove`); |
|
} |
} else { |
} else { |
if (ref($uses_systemctl) eq 'HASH') { |
if (ref($uses_systemctl) eq 'HASH') { |
if ($uses_systemctl->{$service}) { |
if ($uses_systemctl->{$service}) { |
Line 1780 CREATE TABLE IF NOT EXISTS metadata (tit
|
Line 2399 CREATE TABLE IF NOT EXISTS metadata (tit
|
|
|
sub setup_mysql_permissions { |
sub setup_mysql_permissions { |
my ($dbh,$has_pass,@mysql_lc_commands) = @_; |
my ($dbh,$has_pass,@mysql_lc_commands) = @_; |
my $mysqlversion = &get_mysql_version(); |
my ($mysqlversion,$mysqlsubver,$mysqlname) = &get_mysql_version(); |
my @mysql_commands = ("INSERT user (Host, User, Password) VALUES('localhost','www',password('localhostkey'));"); |
my ($usesauth,$is_mariadb,$hasauthcol,@mysql_commands); |
|
if ($mysqlname =~ /^MariaDB/i) { |
|
$is_mariadb = 1; |
|
if ($mysqlversion >= 10.2) { |
|
$usesauth = 1; |
|
} elsif ($mysqlversion >= 5.5) { |
|
$hasauthcol = 1; |
|
} |
|
} else { |
|
if (($mysqlversion > 5.7) || (($mysqlversion == 5.7) && ($mysqlsubver > 5))) { |
|
$usesauth = 1; |
|
} elsif (($mysqlversion >= 5.6) || (($mysqlversion == 5.5) && ($mysqlsubver >= 7))) { |
|
$hasauthcol = 1; |
|
} |
|
} |
|
if ($usesauth) { |
|
@mysql_commands = ("INSERT user (Host, User, ssl_cipher, x509_issuer, x509_subject, authentication_string) VALUES('localhost','www','','','','')"); |
|
if ($is_mariadb) { |
|
push(@mysql_commands,"ALTER USER 'www'\@'localhost' IDENTIFIED BY 'localhostkey'"); |
|
} else { |
|
push(@mysql_commands,"ALTER USER 'www'\@'localhost' IDENTIFIED WITH mysql_native_password BY 'localhostkey'"); |
|
} |
|
} elsif ($hasauthcol) { |
|
@mysql_commands = ("INSERT user (Host, User, Password, ssl_cipher, x509_issuer, x509_subject, authentication_string) VALUES('localhost','www',password('localhostkey'),'','','','');"); |
|
} else { |
|
@mysql_commands = ("INSERT user (Host, User, Password, ssl_cipher, x509_issuer, x509_subject) VALUES('localhost','www',password('localhostkey'),'','','');"); |
|
} |
if ($mysqlversion < 4) { |
if ($mysqlversion < 4) { |
push (@mysql_commands," |
push (@mysql_commands," |
INSERT db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Grant_priv,References_priv,Index_priv,Alter_priv) VALUES('localhost','loncapa','www','Y','Y','Y','Y','Y','Y','N','Y','Y','Y')"); |
INSERT db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Grant_priv,References_priv,Index_priv,Alter_priv) VALUES('localhost','loncapa','www','Y','Y','Y','Y','Y','Y','N','Y','Y','Y')"); |
Line 1831 INSERT db (Host,Db,User,Select_priv,Inse
|
Line 2476 INSERT db (Host,Db,User,Select_priv,Inse
|
} |
} |
} |
} |
if ($got_passwd) { |
if ($got_passwd) { |
my (@newpass_cmds) = &new_mysql_rootpasswd($newmysqlpass); |
my (@newpass_cmds) = &new_mysql_rootpasswd($newmysqlpass,$usesauth,$is_mariadb); |
push(@mysql_commands,@newpass_cmds); |
push(@mysql_commands,@newpass_cmds); |
} else { |
} else { |
print_and_log(&mt('Failed to get MySQL root password from user input.')."\n"); |
print_and_log(&mt('Failed to get MySQL root password from user input.')."\n"); |
Line 1840 INSERT db (Host,Db,User,Select_priv,Inse
|
Line 2485 INSERT db (Host,Db,User,Select_priv,Inse
|
if (@mysql_commands) { |
if (@mysql_commands) { |
foreach my $cmd (@mysql_commands) { |
foreach my $cmd (@mysql_commands) { |
$dbh->do($cmd) || print $dbh->errstr."\n"; |
$dbh->do($cmd) || print $dbh->errstr."\n"; |
|
|
} |
} |
} |
} |
if (@mysql_lc_commands) { |
if (@mysql_lc_commands) { |
Line 1862 INSERT db (Host,Db,User,Select_priv,Inse
|
Line 2506 INSERT db (Host,Db,User,Select_priv,Inse
|
} |
} |
|
|
sub new_mysql_rootpasswd { |
sub new_mysql_rootpasswd { |
my ($currmysqlpass) = @_; |
my ($currmysqlpass,$usesauth,$is_mariadb) = @_; |
return ("SET PASSWORD FOR 'root'\@'localhost'=PASSWORD('$currmysqlpass')", |
if ($usesauth) { |
"FLUSH PRIVILEGES;"); |
if ($is_mariadb) { |
|
return ("ALTER USER 'root'\@'localhost' IDENTIFIED BY '$currmysqlpass'", |
|
"FLUSH PRIVILEGES;"); |
|
} else { |
|
return ("ALTER USER 'root'\@'localhost' IDENTIFIED WITH mysql_native_password BY '$currmysqlpass'", |
|
"FLUSH PRIVILEGES;"); |
|
} |
|
} else { |
|
return ("SET PASSWORD FOR 'root'\@'localhost'=PASSWORD('$currmysqlpass')", |
|
"FLUSH PRIVILEGES;"); |
|
} |
} |
} |
|
|
sub get_mysql_version { |
sub get_mysql_version { |
my $version; |
my ($version,$subversion,$name); |
if (open(PIPE," mysql -V |")) { |
if (open(PIPE," mysql -V |")) { |
my $info = <PIPE>; |
my $info = <PIPE>; |
chomp($info); |
chomp($info); |
close(PIPE); |
close(PIPE); |
($version) = ($info =~ /(\d+\.\d+)\.\d+[\-\w]*,/); |
($version,$subversion,$name) = ($info =~ /(\d+\.\d+)\.(\d+)\-?(\w*),/); |
} else { |
} else { |
print &mt('Could not determine which version of MySQL is installed.'). |
print &mt('Could not determine which version of MySQL is installed.'). |
"\n"; |
"\n"; |
} |
} |
return $version; |
return ($version,$subversion,$name); |
} |
} |
|
|
########################################################### |
########################################################### |
Line 1889 sub get_mysql_version {
|
Line 2543 sub get_mysql_version {
|
########################################################### |
########################################################### |
|
|
sub copy_httpd_conf { |
sub copy_httpd_conf { |
my ($instdir,$distro) = @_; |
my ($instdir,$distro,$hostname) = @_; |
my $configfile = 'httpd.conf'; |
my $configfile = 'httpd.conf'; |
if ($distro =~ /^(?:centos|rhes|scientific)(\d+)$/) { |
if ($distro =~ /^(?:centos|rhes|scientific)(\d+)$/) { |
if ($1 >= 7) { |
if ($1 >= 7) { |
Line 1912 sub copy_httpd_conf {
|
Line 2566 sub copy_httpd_conf {
|
print_and_log("\n"); |
print_and_log("\n"); |
} |
} |
|
|
|
############################################### |
|
## |
|
## Copy loncapassl.conf and sslrewrite.conf |
|
## |
|
############################################### |
|
|
|
# |
|
# The Apache SSL configuration used by LON-CAPA is contained in |
|
# two files: sslrewrite.conf and loncapassl.conf. |
|
# |
|
# Starting with LON-CAPA 2.12, name-based virtual hosts are used |
|
# with port 443. The default virtual host (i.e., the one listed |
|
# first) is for the server's standard hostname, and that is the one |
|
# which will respond to client browser requests for https:// pages. |
|
# |
|
# Accordingly, a system administrator will need to edit the config |
|
# config file to include paths to a signed SSL certificate (public), |
|
# chain (public) and key (private) pem files. The certificate should |
|
# have been signed by a recognized certificate authority ((e.g., |
|
# InCommon or Let's Encrypt). |
|
# |
|
# The sslrewrite.conf file contains the rewrite configuration for |
|
# the default virtual host. The rewrite rules defined are used to |
|
# allow internal HEAD requests to /cgi-bin/mimetex.cgi to be served |
|
# http://, in order to support vertical alignment of mimetex images |
|
# (one of the options for rendering Math content); (b) allow requests |
|
# for certain URLs (external resource, and syllabus, if external URL |
|
# used) to be served http:// to accommodate the use of iframes which |
|
# would otherwise result in browser blocking of mixed active content. |
|
# |
|
# The loncapassl.conf file contains the configuration for the |
|
# "internal" virtual host, which will respond to requests for https:// |
|
# pages from other LON-CAPA servers in the network to which the node |
|
# belongs. The ServerName is internal-<hostname> where <hostname> |
|
# is the server's hostname. There is no need to create a DNS entry |
|
# for internal-<hostname>, as LON-CAPA 2.12 automatically performs |
|
# the required hostname to IP mapping. |
|
# |
|
# Requests to /raw on the "internal" virtual host require a valid |
|
# SSL client certificate, signed by the certificate authority |
|
# for the LON-CAPA network to which the node belongs. |
|
# |
|
# The configuration file to which the contents of sslrewrite.conf |
|
# and loncapassl.conf will be written will have either been identified |
|
# when &chkapachessl() was run, or if no files were found with |
|
# existing rewrite blocks, then a candidate file will be chosen |
|
# from the .conf files containing VirtualHosts definitions. |
|
# If there is more than one suitable candidate file, the system |
|
# administrator will be prompted to select from the available files. |
|
# |
|
# If there are no files containing VirtualHosts definitions, then |
|
# <VirtualHost *:443> </VirtualHost> blocks will be appended to |
|
# the standard Apache SSL config for the particular distro: |
|
# ssl.conf for RHEL/CentOS/Scientific/Fedora, vhost-ssl.conf |
|
# for SuSE/SLES, and default-ssl.conf for Ubuntu. |
|
# |
|
# Once a file is selected, the contents of sslrewrite.conf and |
|
# loncapassl.conf are compared with appropriate blocks in the file |
|
# and the user will be prompted to agree to insertion of missing lines |
|
# and/or deletion of surplus lines. |
|
# |
|
|
|
sub copy_apache_sslconf_files { |
|
my ($distro,$hostname,$hostip,$instdir,$targetdir,$targetfilesref, |
|
$has_std,$has_int,$rewritenum,$nochgstd,$nochgint) = @_; |
|
my ($new_std,$new_int); |
|
my (@internal,@standard,%int_by_linenum,%int_by_linetext, |
|
%rule_by_linenum,%rule_by_linetext,%foundint); |
|
if (-e "$instdir/loncapassl.conf") { |
|
if (open(my $fh,'<',"$instdir/loncapassl.conf")) { |
|
my $num = 1; |
|
while (<$fh>) { |
|
chomp(); |
|
if (/^ServerName/) { |
|
s/(\Qinternal-{[[[[Hostname]]]]}\E)/internal-$hostname/; |
|
} |
|
push(@internal,$_); |
|
$int_by_linenum{$num} = $_; |
|
s/(^\s+|\s+$)//g; |
|
push(@{$int_by_linetext{$_}},$num); |
|
$num ++; |
|
} |
|
close($fh); |
|
} |
|
} |
|
if (-e "$instdir/sslrewrite.conf") { |
|
if (open(my $fh,'<',"$instdir/sslrewrite.conf")) { |
|
my $num = 1; |
|
while (<$fh>) { |
|
chomp(); |
|
if (/\Q{[[[[HostIP]]]]}\E/) { |
|
s/(\QRewriteCond %{REMOTE_ADDR} {[[[[HostIP]]]]}\E)/RewriteCond %{REMOTE_ADDR} $hostip/; |
|
} |
|
push(@standard,$_); |
|
$rule_by_linenum{$num} = $_; |
|
s/(^\s+|\s+$)//g; |
|
push(@{$rule_by_linetext{$_}},$num); |
|
$num ++; |
|
} |
|
close($fh); |
|
} |
|
} |
|
if (!$nochgstd) { |
|
if ($has_std eq '') { |
|
my $file; |
|
if ($has_int ne '') { |
|
if (open(my $fh,'<',"$targetdir/$has_int")) { |
|
my @saved = <$fh>; |
|
close($fh); |
|
if (open(my $fhout, '>',"$targetdir/$has_int")) { |
|
print $fhout "<VirtualHost *:443>\n". |
|
"ServerName $hostname\n". |
|
join("\n",@standard)."\n". |
|
"</VirtualHost>\n\n". |
|
join('',@saved); |
|
close($fhout); |
|
$new_int = $has_int; |
|
} |
|
} |
|
} |
|
} else { |
|
if ($rewritenum eq '') { |
|
&append_to_vhost($targetdir,$has_std,$hostname,\%rule_by_linenum,'std'); |
|
$new_std = $has_std; |
|
} else { |
|
$new_std = &modify_ssl_config($targetdir,$has_std,$hostname,$rewritenum, |
|
\%rule_by_linetext,\%rule_by_linenum,'std'); |
|
} |
|
} |
|
} |
|
if (!$nochgint) { |
|
if ($has_int eq '') { |
|
if ($has_std ne '') { |
|
if (open(my $fhout,'>>',"$targetdir/$has_std")) { |
|
print $fhout "\n".join("\n",@internal)."\n"; |
|
close($fhout); |
|
$new_int = $has_std; |
|
} |
|
} |
|
} else { |
|
$new_int = &modify_ssl_config($targetdir,$has_int,$hostname,$rewritenum,\%int_by_linetext,\%int_by_linenum,'int'); |
|
} |
|
} |
|
if (($has_std eq '') && ($has_int eq '')) { |
|
my ($file,$numfiles) = &get_sslconf_filename($distro,$targetdir,$targetfilesref); |
|
if ($numfiles == 0) { |
|
if (open(my $fhout, '>>', "$targetdir/$file")) { |
|
print $fhout "<VirtualHost *:443>\n". |
|
"ServerName $hostname\n". |
|
join("\n",@standard)."\n". |
|
"</VirtualHost>\n\n". |
|
join("\n",@internal)."\n"; |
|
close($fhout); |
|
$new_std = $file; |
|
$new_int = $file; |
|
} |
|
} elsif ($numfiles == 1) { |
|
&append_to_vhost($targetdir,$file,$hostname,\%rule_by_linenum,'std'); |
|
if (open(my $fhout, '>>', "$targetdir/$file")) { |
|
print $fhout "\n".join("\n",@internal)."\n"; |
|
close($fhout); |
|
$new_std = $file; |
|
$new_int = $file; |
|
} |
|
} elsif ($numfiles == -1) { |
|
print_and_log(&mt('Failed to copy contents of [_1] or [_2] to a file in [_3]', |
|
"'loncapassl.conf'","'sslrewrite.conf'","'$targetdir'")."\n"); |
|
} |
|
} |
|
if ($nochgstd) { |
|
print_and_log(&mt('No change required to file: [_1] in [_2], (no difference between [_3] and rewrite block.)', |
|
"'$has_std'","'$targetdir'","'sslrewrite.conf'")); |
|
} |
|
if ($nochgint) { |
|
print_and_log(&mt('No change required to file: [_1] in [_2], (no difference between [_3] and virtualhost block.)', |
|
"'$has_int'","'$targetdir'","'loncapassl.conf'")); |
|
} |
|
if ($new_int) { |
|
print_and_log(&mt('Successfully copied contents of [_1] to [_2].',"'loncapassl.conf'","'$targetdir/$new_int'")."\n"); |
|
chmod(0444,"$targetdir/loncapassl.conf"); |
|
} |
|
if ($new_std) { |
|
print_and_log(&mt('Successfully copied contents of [_1] to [_2].',"'sslrewrite.conf'","'$targetdir/$new_std'")."\n"); |
|
chmod(0444,"$targetdir/loncapassl.conf"); |
|
} |
|
return ($new_int,$new_std); |
|
} |
|
|
|
# |
|
# append_to_vhost() is called to add rewrite rules (in a |
|
# <IfModule +mod_rewrite.c> </IfModule> block), provided |
|
# in the sslrewrite.conf configuration file, to an Apache |
|
# SSL configuration file within a VirtualHost for port 443 |
|
# (for server's public-facing hostname). |
|
# |
|
sub append_to_vhost { |
|
my ($targetdir,$filename,$hostname,$by_linenum,$type) = @_; |
|
return unless (ref($by_linenum) eq 'HASH'); |
|
my ($startvhost,$endvhost); |
|
if (-e "$targetdir/$filename") { |
|
my (@lines,$currname,$virtualhost,$hasname); |
|
if (open(my $fh,'<',"$targetdir/$filename")) { |
|
my $currline = 0; |
|
while (<$fh>) { |
|
$currline ++; |
|
push(@lines,$_); |
|
chomp(); |
|
s/(^\s+|\s+$)//g; |
|
if (/^<VirtualHost\s+[^:]*\:443>/) { |
|
$virtualhost = 1; |
|
unless ($endvhost) { |
|
$startvhost = $currline; |
|
} |
|
} |
|
if ($virtualhost) { |
|
if (/^ServerName\s+([^\s]+)\s*$/) { |
|
$currname = $1; |
|
unless ($endvhost) { |
|
if ((($currname eq '') || ($currname eq $hostname)) && ($type eq 'std')) { |
|
$hasname = 1; |
|
} |
|
} |
|
} |
|
if (/^<\/VirtualHost>/) { |
|
$virtualhost = 0; |
|
unless ($endvhost) { |
|
if (((($currname eq '') || ($currname eq $hostname)) && ($type eq 'std')) || |
|
(($currname eq 'internal-'.$hostname) && ($type eq 'int'))) { |
|
$endvhost = $currline; |
|
} else { |
|
undef($startvhost); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
close($fh); |
|
} |
|
if ($endvhost) { |
|
if (open(my $fout,'>',"$targetdir/$filename")) { |
|
for (my $i=0; $i<@lines; $i++) { |
|
if ($i == $startvhost) { |
|
unless (($hasname) && ($type eq 'std')) { |
|
print $fout "ServerName $hostname\n"; |
|
} |
|
} |
|
if ($i == $endvhost-1) { |
|
foreach my $item (sort { $a <=> $b } keys(%{$by_linenum})) { |
|
print $fout $by_linenum->{$item}."\n"; |
|
} |
|
} |
|
print $fout $lines[$i]; |
|
} |
|
close($fout); |
|
} |
|
} |
|
} |
|
return $endvhost; |
|
} |
|
|
|
# |
|
# get_sslconf_filename() is called when the Apache SSL configuration |
|
# option has been selected and there are no files containing |
|
# VirtualHost definitions containing rewrite blocks, |
|
# |
|
# In this case get_sslconf_filename() is used to chose from the |
|
# available .conf files containing VirtualHosts definitions. If |
|
# there is ambiguity about which file to use, &apacheconf_choice() |
|
# will be called to prompt the user to choose one of the possible |
|
# files. |
|
# |
|
|
|
sub get_sslconf_filename { |
|
my ($distro,$targetdir,$targetfilesref) = @_; |
|
my ($configfile,$numfiles,@possfiles); |
|
if (ref($targetfilesref) eq 'HASH') { |
|
if (keys(%{$targetfilesref}) > 0) { |
|
foreach my $name (sort(keys(%{$targetfilesref}))) { |
|
if (ref($targetfilesref->{$name}) eq 'HASH') { |
|
foreach my $file (sort(keys(%{$targetfilesref->{$name}}))) { |
|
next if ($file eq ''); |
|
next if (!-e "$targetdir/$file"); |
|
unless (grep(/^\Q$file\E$/,@possfiles)) { |
|
push(@possfiles,$file); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if (@possfiles == 0) { |
|
$configfile = 'ssl.conf'; |
|
if ($distro =~ /^(suse|sles)/) { |
|
$configfile = 'vhost-ssl.conf'; |
|
} elsif ($distro =~ /^(debian|ubuntu)/) { |
|
$configfile = 'default-ssl.conf'; |
|
} |
|
$numfiles = 0; |
|
print &mt('No configuration files in [_1] contain a <VirtualHost *:443> </VirtualHost> block which can be used to house Apache rewrite rules from https to http.',$targetdir)."\n\n". |
|
&mt('Accordingly, the contents of sslrewrite.conf will be included in a <VirtualHost *:443> </VirtualHost> block which will be added to a file named: [_1].',$configfile)."\n\n"; |
|
} elsif (@possfiles == 1) { |
|
$configfile = $possfiles[0]; |
|
$numfiles = 1; |
|
print &mt('A single configuration file in [_1] contains a <VirtualHost *:443> </VirtualHost> block.',$targetdir)."\n". |
|
&mt('The contents of sslrewrite.conf will be added to this block.')."\n\n"; |
|
} else { |
|
print &mt('More than one Apache config file contains a <VirtualHost *:443> </VirtualHost> block.')."\n\n".&mt('The possible files are:')."\n"; |
|
my $counter = 1; |
|
my $max = scalar(@possfiles); |
|
foreach my $file (@possfiles) { |
|
print "$counter. $file\n"; |
|
$counter ++; |
|
} |
|
print "\n".&mt('Enter a number between 1 and [_1] to indicate which file should be modified to include the contents of sslrewrite.conf.',$max)."\n"; |
|
my $choice = &apacheconf_choice($max); |
|
if (($choice =~ /^\d+$/) && ($choice >= 1) && ($choice <= $max)) { |
|
$configfile = $possfiles[$choice-1]; |
|
$numfiles = 1; |
|
} else { |
|
$numfiles = -1; |
|
} |
|
} |
|
} |
|
return ($configfile,$numfiles); |
|
} |
|
|
|
# |
|
# &apacheconf_choice() prompts a user to choose an integer between 1 and the |
|
# maximum number of available of possible Apache SSL config files found |
|
# at the distros standard location for Apache config files containing |
|
# VirtualHost definitions. |
|
# |
|
# This routine is called recursively until the user enters a valid integer. |
|
# |
|
|
|
sub apacheconf_choice { |
|
my ($max) = @_; |
|
my $choice = <STDIN>; |
|
chomp($choice); |
|
$choice =~ s/(^\s+|\s+$)//g; |
|
my $configfile; |
|
if (($choice =~ /^\d+$/) && ($choice >= 1) && ($choice <= $max)) { |
|
$configfile = $choice; |
|
} |
|
while ($configfile eq '') { |
|
print &mt('Invalid choice. Please enter a number between 1 and [_1].',$max)."\n"; |
|
$configfile = &apacheconf_choice($max); |
|
} |
|
print "\n"; |
|
return $configfile; |
|
} |
|
|
|
# |
|
# &modify_ssl_config() is called to modify the contents of an Apache SSL config |
|
# file so that it has two <VirtualHost *:443> </VirtualHost> blocks containing |
|
# (a) the default VirtualHost with the <IfModule mod_rewrite.c> </IfModule> block |
|
# provided in sslrewrites.conf, and (b) an "internal" VirtualHost with the |
|
# content provided in loncapassl.conf. |
|
# |
|
# This routine will prompted you to agree to insertion of lines present in the |
|
# shipped conf file, but missing from the local config file, and also for |
|
# deletion of lines present in the local config file, but not required in |
|
# the shipped conf file. |
|
# |
|
|
|
sub modify_ssl_config { |
|
my ($targetdir,$filename,$hostname,$rewritenum,$by_linetext,$by_linenum,$type) = @_; |
|
return unless ((ref($by_linetext) eq 'HASH') && (ref($by_linenum) eq 'HASH')); |
|
if (-e "$targetdir/$filename") { |
|
my (@lines,$virtualhost,$currname,$rewrite); |
|
if (open(my $fh,'<',"$targetdir/$filename")) { |
|
my %found; |
|
my %possible; |
|
my $currline = 0; |
|
my $rewritecount = 0; |
|
while (<$fh>) { |
|
$currline ++; |
|
push(@lines,$_); |
|
chomp(); |
|
s/(^\s+|\s+$)//g; |
|
if (/^\s*<VirtualHost\s+[^:]*\:443>\s*$/) { |
|
$virtualhost = 1; |
|
} |
|
if ($virtualhost) { |
|
if ((exists($by_linetext->{$_})) && (ref($by_linetext->{$_}) eq 'ARRAY') && |
|
(@{$by_linetext->{$_}} > 0)) { |
|
$possible{$currline} = shift(@{$by_linetext->{$_}}); |
|
} |
|
if (/^\s*<\/VirtualHost>/) { |
|
if ((($currname eq 'internal-'.$hostname) && ($type eq 'int')) || |
|
((($currname eq $hostname) || ($currname eq '')) && ($type eq 'std') && |
|
($rewritecount == $rewritenum))) { |
|
%found = (%found,%possible); |
|
} else { |
|
foreach my $line (sort {$b <=> $a } keys(%possible)) { |
|
my $num = $possible{$line}; |
|
if (ref($by_linetext->{$by_linenum->{$num}}) eq 'ARRAY') { |
|
unshift(@{$by_linetext->{$by_linenum->{$num}}},$num); |
|
} |
|
} |
|
} |
|
undef(%possible); |
|
$virtualhost = 0; |
|
$currname = ''; |
|
} elsif (/^\s*ServerName\s+([^\s]+)\s*$/) { |
|
$currname = $1; |
|
} elsif (/^\s*<IfModule\s+mod_rewrite\.c>/) { |
|
$rewrite = 1; |
|
} elsif (/^\s*<\/IfModule>/) { |
|
$rewritecount ++; |
|
$rewrite = 0; |
|
} |
|
} |
|
} |
|
close($fh); |
|
if (open(my $fout,'>',"$targetdir/$filename")) { |
|
my $currline = 0; |
|
my ($lastfound,$done); |
|
my $numfound = 0; |
|
foreach my $line (@lines) { |
|
$currline ++; |
|
if ($done) { |
|
print $fout $line; |
|
} elsif ($lastfound) { |
|
if ($found{$currline}) { |
|
for (my $i=$lastfound+1; $i<$found{$currline}; $i++) { |
|
print &mt('The following line is missing from the current <VirtualHost *:443> </VirtualHost> block:')."\n". |
|
$by_linenum->{$i}."\n". |
|
&mt('Add this line? ~[Y/n~]'); |
|
if (&get_user_selection(1)) { |
|
print $fout $by_linenum->{$i}."\n"; |
|
} |
|
} |
|
$numfound ++; |
|
$lastfound = $found{$currline}; |
|
print $fout $line; |
|
if ($numfound == scalar(keys(%found))) { |
|
$done = 1; |
|
for (my $i=$found{$currline}+1; $i<=scalar(keys(%{$by_linenum})); $i++) { |
|
print &mt('The following line is missing from the current <VirtualHost *:443> </VirtualHost> block:')."\n". |
|
$by_linenum->{$i}."\n". |
|
&mt('Add this line? ~[Y/n~]'); |
|
if (&get_user_selection(1)) { |
|
print $fout $by_linenum->{$i}."\n"; |
|
} |
|
} |
|
} |
|
} else { |
|
print &mt('The following line found within a <VirtualHost *:443> </VirtualHost> block does not match that expected by LON-CAPA:')."\n". |
|
$line. |
|
&mt('Delete this line? ~[Y/n~]'); |
|
if (!&get_user_selection(1)) { |
|
print $fout $line; |
|
} |
|
} |
|
} elsif ($found{$currline}) { |
|
$numfound ++; |
|
$lastfound = $found{$currline}; |
|
for (my $i=1; $i<$found{$currline}; $i++) { |
|
print &mt('The following line is missing from the current <VirtualHost *:443> </VirtualHost> block:')."\n". |
|
$by_linenum->{$i}."\n". |
|
&mt('Add this line? ~[Y/n~]'); |
|
if (&get_user_selection(1)) { |
|
print $fout $by_linenum->{$i}."\n"; |
|
} |
|
} |
|
print $fout $line; |
|
} else { |
|
print $fout $line; |
|
} |
|
} |
|
close($fout); |
|
} |
|
} |
|
} |
|
return $filename; |
|
} |
|
|
######################################################### |
######################################################### |
## |
## |
## Ubuntu/Debian -- copy our loncapa configuration file to |
## Ubuntu/Debian -- copy our loncapa configuration file to |
Line 1920 sub copy_httpd_conf {
|
Line 3051 sub copy_httpd_conf {
|
######################################################### |
######################################################### |
|
|
sub copy_apache2_debconf { |
sub copy_apache2_debconf { |
my ($instdir,$distro) = @_; |
my ($instdir,$distro,$hostname) = @_; |
my $apache2_mods_enabled_dir = '/etc/apache2/mods-enabled'; |
my $apache2_mods_enabled_dir = '/etc/apache2/mods-enabled'; |
my $apache2_mods_available_dir = '/etc/apache2/mods-available'; |
my $apache2_mods_available_dir = '/etc/apache2/mods-available'; |
foreach my $module ('headers.load','expires.load') { |
foreach my $module ('headers.load','expires.load') { |
Line 1982 sub copy_apache2_debconf {
|
Line 3113 sub copy_apache2_debconf {
|
########################################################### |
########################################################### |
|
|
sub copy_apache2_suseconf { |
sub copy_apache2_suseconf { |
my ($instdir) = @_; |
my ($instdir,$hostname,$distro) = @_; |
|
my ($name,$version) = ($distro =~ /^(suse|sles)([\d\.]+)$/); |
|
my $conf_file = "$instdir/sles-suse/default-server.conf"; |
|
if (($name eq 'sles') && ($version >= 12)) { |
|
$conf_file = "$instdir/sles-suse/apache2.4/default-server.conf"; |
|
} |
print_and_log(&mt('Copying the LON-CAPA [_1] to [_2].', |
print_and_log(&mt('Copying the LON-CAPA [_1] to [_2].', |
"'default-server.conf'", |
"'default-server.conf'", |
"'/etc/apache2/default-server.conf'")."\n"); |
"'/etc/apache2/default-server.conf'")."\n"); |
if (!-e "/etc/apache2/default-server.conf.original") { |
if (!-e "/etc/apache2/default-server.conf.original") { |
copy "/etc/apache2/default-server.conf","/etc/apache2/default-server.conf.original"; |
copy "/etc/apache2/default-server.conf","/etc/apache2/default-server.conf.original"; |
} |
} |
copy "$instdir/sles-suse/default-server.conf","/etc/apache2/default-server.conf"; |
copy $conf_file,"/etc/apache2/default-server.conf"; |
chmod(0444,"/etc/apache2/default-server.conf"); |
chmod(0444,"/etc/apache2/default-server.conf"); |
# Make symlink for conf directory (included in loncapa_apache.conf) |
# Make symlink for conf directory (included in loncapa_apache.conf) |
my $can_symlink = (eval { symlink('/etc/apache2','/srv/www/conf'); }, $@ eq ''); |
my $can_symlink = (eval { symlink('/etc/apache2','/srv/www/conf'); }, $@ eq ''); |
Line 2000 sub copy_apache2_suseconf {
|
Line 3136 sub copy_apache2_suseconf {
|
&print_and_log(&mt('Symlink creation failed for [_1] to [_2]. You will need to perform this action from the command line.',"'/srv/www/conf'","'/etc/apache2'")."\n"); |
&print_and_log(&mt('Symlink creation failed for [_1] to [_2]. You will need to perform this action from the command line.',"'/srv/www/conf'","'/etc/apache2'")."\n"); |
} |
} |
©_apache2_conf_files($instdir); |
©_apache2_conf_files($instdir); |
©_sysconfig_apache2_file($instdir); |
©_sysconfig_apache2_file($instdir,$name,$version); |
print_and_log("\n"); |
print_and_log("\n"); |
} |
} |
|
|
Line 2026 sub copy_apache2_conf_files {
|
Line 3162 sub copy_apache2_conf_files {
|
## |
## |
############################################### |
############################################### |
sub copy_sysconfig_apache2_file { |
sub copy_sysconfig_apache2_file { |
my ($instdir) = @_; |
my ($instdir,$name,$version) = @_; |
print_and_log(&mt('Copying the LON-CAPA [_1] to [_2].',"'sysconfig/apache2'","'/etc/sysconfig/apache2'")."\n"); |
print_and_log(&mt('Copying the LON-CAPA [_1] to [_2].',"'sysconfig/apache2'","'/etc/sysconfig/apache2'")."\n"); |
if (!-e "/etc/sysconfig/apache2.original") { |
if (!-e "/etc/sysconfig/apache2.original") { |
copy "/etc/sysconfig/apache2","/etc/sysconfig/apache2.original"; |
copy "/etc/sysconfig/apache2","/etc/sysconfig/apache2.original"; |
} |
} |
copy "$instdir/sles-suse/sysconfig_apache2","/etc/sysconfig/apache2"; |
my $sysconf_file = "$instdir/sles-suse/sysconfig_apache2"; |
|
if (($name eq 'sles') && ($version >= 12)) { |
|
$sysconf_file = "$instdir/sles-suse/apache2.4/sysconfig_apache2"; |
|
} |
|
copy "$sysconf_file","/etc/sysconfig/apache2"; |
chmod(0444,"/etc/sysconfig/apache2"); |
chmod(0444,"/etc/sysconfig/apache2"); |
} |
} |
|
|