Newer
Older
<?php
/**
* Description of class
*
* @author croydon
*/
class ISPConfigDebianOS extends ISPConfigBaseOS {
public function getPackageVersion($package) {
$cmd = 'dpkg --list ' . $package . ' 2>&1';
$result = $this->exec($cmd);
$version = false;
$matches = array();
if(preg_match_all('/^ii\s+\S+\s+(\S+)(?:\s|$)/m', $result, $matches, PREG_SET_ORDER)) {
for($i = 0; $i < count($matches); $i++) {
$tmp_version = $matches[$i][1];
if(!$version || ISPProtectFunctions::version_compare($version, $tmp_version, '<')) {
$version = $tmp_version;
}
}
}
public function getPackageAlias($package) {
switch($package) {
case 'libssl':
$package = 'libssl[0-9]*';
break;
case 'kernel':
$package = 'linux-image-[0-9]*';
break;
}
public function getUpdateCommand($mode = 'update') {
if($mode == 'prepare') {
$cmd = 'DEBIAN_FRONTEND="noninteractive" apt-get update -qq -y';
} elseif($mode == 'update') {
// for updating all updateable packages
$cmd = 'DEBIAN_FRONTEND="noninteractive" apt-get dist-upgrade -o Dpkg::Options::="--force-overwrite" -qq -y';
} elseif($mode == 'install' || $mode == 'partly_update') {
// for installing / updating specific packages
$cmd = 'DEBIAN_FRONTEND="noninteractive" apt-get install -o Dpkg::Options::="--force-overwrite" -qq -y';
$cmd .= ' <PACKAGES>';
}
$cmd = 'while fuser /var/lib/dpkg/lock >/dev/null 2>&1 || fuser /var/lib/apt/lists/lock >/dev/null 2>&1 ; do sleep 2; done; ' . $cmd . ' 2>&1';
public function getUpdatePackageRegex() {
$regex = '^\w+\s+(?P<package>\S+)\s+(?:\[(?P<oldversion>\S+)\]\s*)?(?:\((?P<newversion>\S+))?(?:\s|$)';
public function getInstallPackageRegex($mode = '') {
if($mode == 'oldversion') {
$regex = '(?P<package>\S+)\s+(?:(?P<oldversion>\d\S+)\s+)?\(.*\.deb';
} elseif($mode == 'newversion') {
$regex = '(?:^|\s+)(?P<package>\S+)\s+\((?P<newversion>\d\S*)\)\s+';
} else {
$regex = ''; // not on debian!
}
public function getRestartServiceCommand($service, $command = 'restart') {
if($command != 'start' && $command != 'stop' && $command != 'status') {
$command = 'restart';
}
switch($service) {
case 'apache':
$service = 'apache2';
break;
case 'pureftpd':
$service = 'pure-ftpd-mysql';
break;
}
return 'service ' . escapeshellarg($service) . ' ' . $command . ' 2>&1';
}
protected function updateMySQLConfig($mysql_root_pw) {
ISPConfigLog::info('Writing MySQL config files.', true);
$this->replaceContents('/etc/mysql/debian.cnf', array('/^password\s*=.*$/m' => 'password = ' . $mysql_root_pw));
$this->replaceContents('/etc/mysql/mariadb.conf.d/50-server.cnf', array('/^bind-address/m' => '#bind-address', '/^sql-mode\s*=.*?$/m' => 'sql-mode = "NO_ENGINE_SUBSTITUTION"'), true, 'mysqld');
protected function getPackagesToInstall($section) {
if($section === 'mail') {
$packages = array(
'dnsutils',
'resolvconf',
'clamav',
'clamav-daemon',
'arj',
'nomarch',
'lzop',
'cabextract',
'apt-listchanges',
'libnet-ldap-perl',
'libauthen-sasl-perl',
'daemon',
'libio-string-perl',
'libio-socket-ssl-perl',
'libnet-ident-perl',
'libnet-dns-perl',
if(ISPConfig::wantsUnbound()) {
$packages[] = 'unbound';
} else {
$packages[] = 'bind9';
}
Marius Burkard
committed
}
if(ISPConfig::shallInstall('mail')) {
$packages[] = 'spamassassin';
if(ISPConfig::wantsAmavis()) {
$packages[] = 'amavisd-new';
} else {
$packages[] = 'rspamd';
$packages[] = 'redis-server';
}
$packages[] = 'postgrey';
}
} elseif($section === 'base') {
$packages = array(
'php-pear',
'php-memcache',
'php-imagick',
'php-gettext',
'mcrypt',
'imagemagick',
'libruby',
'memcached',
'php-apcu'
);
protected function getApacheModulesToDisable() {
Thom
committed
'mpm_prefork',
'php8.0'
return $modules;
}
$modules = array('suexec', 'rewrite', 'ssl', 'actions', 'include', 'dav_fs', 'dav', 'auth_digest', 'cgi', 'headers', 'proxy_fcgi', 'alias', 'http2', 'mpm_event');
ISPConfigLog::info('Setting default system php version.', true);
$cmd = 'update-alternatives --set php /usr/bin/php7.0';
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
if(ISPConfig::shallInstall('web')) {
Thom Pol
committed
// When --use-php-system is used, there is no alternative for php-fpm.sock.
if(ISPConfig::wantsPHP() === 'system') {
$cmd = 'update-alternatives --set php-cgi /usr/bin/php-cgi7.0';
} else {
$cmd = 'update-alternatives --set php-cgi /usr/bin/php-cgi7.0 ; update-alternatives --set php-fpm.sock /run/php/php7.0-fpm.sock';
}
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
}
}
protected function installPHPMyAdmin($mysql_root_pw) {
if(!ISPConfig::shallInstall('web') || !ISPConfig::shallInstall('pma')) {
return;
}
$cmd = 'APP_PASS="' . ISPConfigFunctions::generatePassword(15) . '"' . "\n";
$cmd .= 'ROOT_PASS="' . $mysql_root_pw . '"' . "\n";
$cmd .= 'APP_DB_PASS="' . ISPConfigFunctions::generatePassword(15) . '"' . "\n";
$cmd .= 'echo "phpmyadmin phpmyadmin/dbconfig-install boolean true" | debconf-set-selections 2>&1' . "\n";
$cmd .= 'echo "phpmyadmin phpmyadmin/app-password-confirm password $APP_PASS" | debconf-set-selections 2>&1' . "\n";
$cmd .= 'echo "phpmyadmin phpmyadmin/mysql/admin-user string root" | debconf-set-selections 2>&1' . "\n";
$cmd .= 'echo "phpmyadmin phpmyadmin/mysql/admin-pass password $ROOT_PASS" | debconf-set-selections 2>&1' . "\n";
$cmd .= 'echo "phpmyadmin phpmyadmin/mysql/app-pass password $APP_DB_PASS" | debconf-set-selections 2>&1' . "\n";
$cmd .= 'echo "phpmyadmin phpmyadmin/reconfigure-webserver multiselect apache2" | debconf-set-selections 2>&1' . "\n";
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
$this->installPackages('phpmyadmin');
protected function fixDbconfigCommon() {
ISPConfigLog::info('Fixing dbconfig-common if neccessary');
$replacements = array(
'/_dbc_nodb="yes" dbc_mysql_exec/' => '_dbc_nodb="yes"; dbc_mysql_exec'
);
$this->replaceContents('/usr/share/dbconfig-common/internal/mysql', $replacements, false);
}
protected function setPHPTimezone() {
if(!is_file('/etc/timezone')) {
return;
}
$tz = trim(file_get_contents('/etc/timezone'));
if(!in_array($tz, timezone_identifiers_list())) {
return;
}
// set in all php inis
$ini_files = array(
'/etc/php/5.6/cgi/php.ini',
'/etc/php/5.6/cli/php.ini',
'/etc/php/5.6/fpm/php.ini',
'/etc/php/5.6/apache2/php.ini',
'/etc/php/7.0/cgi/php.ini',
'/etc/php/7.0/cli/php.ini',
'/etc/php/7.0/fpm/php.ini',
'/etc/php/7.0/apache2/php.ini',
'/etc/php/7.1/cgi/php.ini',
'/etc/php/7.1/cli/php.ini',
'/etc/php/7.1/fpm/php.ini',
'/etc/php/7.1/apache2/php.ini',
'/etc/php/7.2/cgi/php.ini',
'/etc/php/7.2/cli/php.ini',
'/etc/php/7.2/fpm/php.ini',
'/etc/php/7.2/apache2/php.ini',
'/etc/php/7.3/cgi/php.ini',
'/etc/php/7.3/cli/php.ini',
'/etc/php/7.3/fpm/php.ini',
'/etc/php/7.3/apache2/php.ini',
'/etc/php/7.4/cgi/php.ini',
'/etc/php/7.4/cli/php.ini',
'/etc/php/7.4/fpm/php.ini',
'/etc/php/7.4/apache2/php.ini',
'/etc/php/8.0/cgi/php.ini',
'/etc/php/8.0/cli/php.ini',
'/etc/php/8.0/fpm/php.ini',
'/etc/php/8.0/apache2/php.ini'
$replace = array(
'/^;?\s*date\.timezone\s+=.*$/' => 'date.timezone = ' . $tz
);
foreach($ini_files as $ini) {
if(is_file($ini)) {
$this->replaceContents($ini, $replace);
}
}
}
protected function configureApt() {
// enable contrib and non-free
ISPConfigLog::info('Enabling contrib and non-free repositories.', true);
$replacements = array(
'/^(deb.*\s+main)\s*$/' => '$1 contrib non-free'
);
$this->replaceContents('/etc/apt/sources.list', $replacements);
}
protected function addSuryRepo() {
ISPConfigLog::info('Activating sury php repository.', true);
$cmd = 'wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg >/dev/null 2>&1 ; echo "deb https://packages.sury.org/php/ $(lsb_release -c -s) main" > /etc/apt/sources.list.d/php.list';
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
ISPConfigLog::info('Activating GoAccess repository.', true);
$cmd = 'echo "deb https://deb.goaccess.io/ $(lsb_release -cs) main" | sudo tee -a /etc/apt/sources.list.d/goaccess.list >/dev/null 2>&1 ; wget -O - https://deb.goaccess.io/gnugpg.key 2>&1 | sudo apt-key --keyring /etc/apt/trusted.gpg.d/goaccess.gpg add - 2>&1';
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
}
protected function installUnattendedUpgrades() {
ISPConfigLog::info('Installing UnattendedUpgrades', true);
$packages = array(
'unattended-upgrades',
'apt-listchanges'
);
$this->installPackages($packages);
// Enable UnattendUpgrades to run every day
$unattendedupgrades = 'APT::Periodic::Update-Package-Lists "1";' . "\n" . 'APT::Periodic::Unattended-Upgrade "1";';
file_put_contents('/etc/apt/apt.conf.d/20auto-upgrades', $unattendedupgrades);
// Enable extra options if set in the arguments
$unattendedupgrades_options = ISPConfig::getUnattendedUpgradesOptions();
if (!empty($unattendedupgrades_options)) {
if (in_array("autoclean", $unattendedupgrades_options)) {
$unattendedupgrades = "\n" . 'APT::Periodic::AutocleanInterval "7";' . "\n" . 'Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";' . "\n" . 'Unattended-Upgrade::Remove-Unused-Dependencies "true";';
file_put_contents('/etc/apt/apt.conf.d/20auto-upgrades', $unattendedupgrades, FILE_APPEND | LOCK_EX);
}
if (in_array("reboot", $unattendedupgrades_options)) {
$unattendedupgrades = "\n" . 'Unattended-Upgrade::Automatic-Reboot "true";' . "\n" . 'Unattended-Upgrade::Automatic-Reboot-Time "03:30";';
file_put_contents('/etc/apt/apt.conf.d/20auto-upgrades', $unattendedupgrades, FILE_APPEND | LOCK_EX);
}
}
protected function shallCompileJailkit() {
return true;
}
protected function getFail2BanJail() {
$jk_jail = '[pure-ftpd]
enabled = true
port = ftp
filter = pure-ftpd
logpath = /var/log/syslog
maxretry = 3
[dovecot]
enabled = true
filter = dovecot
logpath = /var/log/mail.log
maxretry = 5
[postfix-sasl]
enabled = true
port = smtp
filter = postfix-sasl
logpath = /var/log/mail.log
maxretry = 3';
return $jk_jail;
}
protected function installMailman($host_name) {
if(!ISPConfig::shallInstall('mail') || !ISPConfig::shallInstall('mailman')) {
return;
}
ISPConfigLog::info('Installing Mailman', true);
$cmd = 'echo "mailman mailman/site_languages multiselect de (German), en (English)" | debconf-set-selections 2>&1' . "\n";
if(isset($_GET['lang']) && $_GET['lang'] === 'de') {
$cmd .= 'echo "mailman mailman/default_server_language select de (German)" | debconf-set-selections 2>&1';
} else {
$cmd .= 'echo "mailman mailman/default_server_language select en (English)" | debconf-set-selections 2>&1';
}
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
}
$package = 'mailman';
$this->installPackages($package);
$listpw = '';
if(!is_dir('/var/lib/mailman/lists/mailman')) {
$listpw = ISPConfigFunctions::generatePassword(12);
$cmd = 'newlist -q -e ' . escapeshellarg($host_name) . ' mailman ' . escapeshellarg('root@' . $host_name) . ' ' . escapeshellarg($listpw);
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
}
$add_content = '## mailman mailing list
mailman: "|/var/lib/mailman/mail/mailman post mailman"
mailman-admin: "|/var/lib/mailman/mail/mailman admin mailman"
mailman-bounces: "|/var/lib/mailman/mail/mailman bounces mailman"
mailman-confirm: "|/var/lib/mailman/mail/mailman confirm mailman"
mailman-join: "|/var/lib/mailman/mail/mailman join mailman"
mailman-leave: "|/var/lib/mailman/mail/mailman leave mailman"
mailman-owner: "|/var/lib/mailman/mail/mailman owner mailman"
mailman-request: "|/var/lib/mailman/mail/mailman request mailman"
mailman-subscribe: "|/var/lib/mailman/mail/mailman subscribe mailman"
mailman-unsubscribe: "|/var/lib/mailman/mail/mailman unsubscribe mailman"';
$fp = fopen('/etc/aliases', 'r+');
if(!$fp) {
throw new ISPConfigOSException('Opening /etc/aliases failed.');
}
$found = false;
while(!feof($fp)) {
$line = trim(fgets($fp));
if($line === '## mailman mailing list') {
$found = true;
break;
}
}
if($found === false) {
fseek($fp, SEEK_END);
fwrite($fp, "\n\n" . $add_content);
}
$cmd = 'newaliases';
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
}
if(ISPConfig::$WEBSERVER === ISPC_WEBSERVER_APACHE) {
if(!is_link('/etc/apache2/conf-enabled/mailman.conf') && !is_file('/etc/apache2/conf-enabled/mailman.conf')) {
symlink('/etc/mailman/apache.conf', '/etc/apache2/conf-enabled/mailman.conf');
}
$this->restartService('postfix');
$this->restartService('mailman');
if(ISPConfig::$WEBSERVER === ISPC_WEBSERVER_APACHE) {
$this->restartService('apache2');
}
protected function installPackages($packages) {
if(is_string($packages)) {
$packages = array($packages);
}
ISPConfigLog::info('Installing packages ' . implode(', ', $packages), true);
$result = parent::installPackages($packages);
if($result !== false) {
ISPConfigLog::info('Installed packages ' . implode(', ', $packages), true);
} else {
throw new ISPConfigOSException('Installing packages failed.');
}
$log_filename = 'setup-' . strftime('%Y%m%d%H%M%S', time()) . '.log';
ISPConfigLog::setLogFile($log_filename);
if(is_file('/usr/local/ispconfig/server/lib/config.inc.php')) {
ISPConfigLog::error('The server already has ISPConfig installed. Aborting.', true);
return false;
}
if(ISPConfig::wantsUnbound() && ISPConfig::shallInstall('dns')) {
ISPConfigLog::error('You can only use --use-unbound together with --no-dns as ISPConfig requires Bind when dns is enabled.');
return false;
}
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
ISPConfigLog::info('Checking hostname.', true);
$host_name = false;
$cmd = 'hostname -f 2>&1';
$check = $this->exec($cmd);
if($check === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
} else {
$host_name = $check;
}/* elseif(trim($check) !== $host_name) {
ISPConfigLog::warn('Hostname mismatch: ' . $check . ' != ' . $host_name);
}*/
$cmd = 'hostname 2>&1';
$check = $this->exec($cmd);
if($check === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
}/* elseif(trim($check) !== $short_hostname) {
ISPConfigLog::warn('Short hostname mismatch: ' . $check . ' != ' . $short_hostname);
}*/
if($host_name == '') {
ISPConfigLog::error('Could not read the host name of your server. Please check it is correctly set.', true);
throw new ISPConfigOSException('Invalid host name or host name not found.');
} elseif(substr_count($host_name, '.') < 2) {
ISPConfigLog::error('The host name ' . $host_name . ' of your server is no fully qualified domain name (xyz.domain.com). Please check it is correctly set.', true);
throw new ISPConfigOSException('Host name is no FQDN.');
}
$this->configureApt();
$this->updatePackageList();
ISPConfigLog::info('Updating packages', true);
$cmd = $this->getUpdateCommand('update');
$result = $this->exec($cmd);
if($result !== false) {
ISPConfigLog::info('Updated packages', true);
} else {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
}
try {
$this->beforePackageInstall();
} catch (Exception $ex) {
throw $ex;
$packages = array(
'ssh',
'openssh-server',
'nano',
'vim-nox',
'lsb-release',
'apt-transport-https',
'ca-certificates',
'wget',
'git'
);
if(ISPConfig::shallInstall('ntp')) {
$packages[] = 'ntp';
}
$this->installPackages($packages);
if(ISPConfig::shallInstall('mail') && !ISPConfig::wantsAmavis()) {
ISPConfigLog::info('Activating rspamd repository.', true);
$cmd = 'wget -O - "https://rspamd.com/apt-stable/gpg.key" 2>/dev/null | apt-key add - 2>/dev/null ; echo "deb http://rspamd.com/apt-stable/ $(lsb_release -c -s) main" > /etc/apt/sources.list.d/rspamd.list';
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
}
if(ISPConfig::wantsPHP() !== 'system') {
$this->addSuryRepo();
}
if(ISPConfig::shallInstall('web')) {
$this->addGoAccessRepo();
}
ISPConfigLog::info('Updating packages (after enabling 3rd party repos).', true);
$cmd = $this->getUpdateCommand('update');
$result = $this->exec($cmd);
if($result !== false) {
ISPConfigLog::info('Updated packages', true);
} else {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
/*$hostname_changed = false;
ISPConfigLog::info('Setting hostname to ' . $host_name, true);
$dotpos = strpos($host_name, '.');
if($dotpos !== false) {
$short_hostname = substr($host_name, 0, $dotpos);
} else {
$short_hostname = '';
}
$hosts_entry = $this->ip_address . "\t" . $host_name . ($short_hostname ? ' ' . $short_hostname : '');
$use_hosts_file = '/etc/cloud/templates/hosts.tmpl';
} else {
$use_hosts_file = '/etc/hosts';
}
if(preg_match('/^\s*' . preg_quote($this->ip_address, '/') . ' (.*?)$/m', $content, $matches)) {
ISPConfigLog::info('Hostname is currently set to ' . $matches[1]);
$content = str_replace($matches[0], $hosts_entry, $content);
if($matches[0] != $hosts_entry) {
$hostname_changed = true;
}
} else {
ISPConfigLog::info('Hostname not found in hosts file.');
$content .= "\n" . $hosts_entry;
$hostname_changed = true;
}
$content = trim(file_get_contents('/etc/hostname'));
if($content != $short_hostname) {
ISPConfigLog::info('/etc/hostname is currently set to ' . $content, true);
$hostname_changed = true;
file_put_contents('/etc/hostname', $short_hostname);
ISPConfigLog::info('Hostname saved.', true);
if($hostname_changed) {
ISPConfigLog::info('Rebooting server.', true);
$ok = $this->exec('shutdown -r now >/dev/null 2>&1', array(0, 255));
if($ok === false) {
throw new ISPConfigOSException('Command for server reboot failed.');
}
$ok = $this->waitForReboot(30, 1200);
if(!$ok) {
throw new ISPConfigOSException('Timeout waiting for server to come up.');
ISPConfigLog::info('Server online again.', true);
}*/
$cmd = 'readlink /bin/sh 2>&1';
$check = trim($this->exec($cmd));
if($check === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
} elseif($check !== 'bash') {
//debconf-show dash
ISPConfigLog::info('Default shell is currently ' . $check . '.', true);
ISPConfigLog::info('Setting bash as default shell.', true);
$cmd = 'echo "dash dash/sh boolean false" | debconf-set-selections && DEBIAN_FRONTEND=noninteractive dpkg-reconfigure dash 2>&1';
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
}
$cmd = 'readlink /bin/sh 2>&1';
$check = trim($this->exec($cmd));
ISPConfigLog::info('Default shell is now ' . $check . '.', true);
}
$cmd = 'echo "postfix postfix/mailname string ' . $host_name . '" | debconf-set-selections 2>&1' . "\n";
$cmd .= 'echo "postfix postfix/main_mailer_type select Internet Site" | debconf-set-selections 2>&1';
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
'postfix',
'postfix-mysql',
'postfix-doc',
'mariadb-client',
'mariadb-server',
'openssl',
'getmail4',
'rkhunter',
'binutils',
'sudo'
);
$this->installPackages($packages);
if(ISPConfig::shallInstall('mail')) {
$packages = array(
'dovecot-imapd',
'dovecot-pop3d',
'dovecot-mysql',
'dovecot-sieve',
'dovecot-managesieved',
'dovecot-lmtpd'
);
$this->installPackages($packages);
} else {
$cmd = 'postconf -e "inet_interfaces = loopback-only"';
$result = $this->exec($cmd);
if($result === false) {
ISPConfigLog::warn('Command ' . $cmd . ' failed.', true);
}
ISPConfigLog::info('Generating mySQL password.', true);
// generate random password
$mysql_root_pw = ISPConfigFunctions::generatePassword(20);
$escaped_pw = preg_replace('/[\'\\\\]/', '\\$1', $mysql_root_pw);
$queries = array(
'DELETE FROM mysql.user WHERE User=\'\';',
'DELETE FROM mysql.user WHERE User=\'root\' AND Host NOT IN (\'localhost\', \'127.0.0.1\', \'::1\');',
'DROP DATABASE IF EXISTS test;',
'DELETE FROM mysql.db WHERE Db=\'test\' OR Db=\'test\\_%\';',
'UPDATE mysql.user SET Password=PASSWORD(\'' . $escaped_pw . '\') WHERE User=\'root\';',
'UPDATE mysql.user SET plugin = \'mysql_native_password\' WHERE User=\'root\';',
'FLUSH PRIVILEGES;'
);
foreach($queries as $query) {
$cmd = 'mysql --defaults-file=/etc/mysql/debian.cnf -e ' . escapeshellarg($query) . ' 2>&1';
$result = $this->exec($cmd);
if($result === false) {
ISPConfigLog::warn('Query ' . $query . ' failed.', true);
if(ISPConfig::shallInstall('mail')) {
ISPConfigLog::info('Configuring postfix.', true);
$entries = array(
array(
'first_line' => '/^submission\s+inet/',
'last_line' => '/^[a-z]/',
'skip_last_line' => true,
'search' => '/^\s+-o/'
),
array(
'first_line' => '/^smtps\s+inet/',
'last_line' => '/^[a-z]/',
'skip_last_line' => true,
'search' => '/^\s+-o/'
)
);
$this->commentLines('/etc/postfix/master.cf', $entries);
$entries = array(
array(
'first_line' => '/^#?submission\s+inet/',
'last_line' => null,
'search' => null,
'add_lines' => array(
' -o syslog_name=postfix/submission',
' -o smtpd_tls_security_level=encrypt',
' -o smtpd_sasl_auth_enable=yes',
' -o smtpd_client_restrictions=permit_sasl_authenticated,reject'
)
),
array(
'first_line' => '/^#?smtps\s+inet/',
'last_line' => null,
'search' => null,
'add_lines' => array(
' -o syslog_name=postfix/smtps',
' -o smtpd_tls_wrappermode=yes',
' -o smtpd_sasl_auth_enable=yes',
' -o smtpd_client_restrictions=permit_sasl_authenticated,reject'
)
);
$this->uncommentLines('/etc/postfix/master.cf', $entries);
}
ISPConfigLog::info('Restarting postfix', true);
$replacements = array(
'/^mysql\s+soft\s+nofile\s+.*/' => 'mysql soft nofile 65535',
'/^mysql\s+hard\s+nofile\s+.*/' => 'mysql hard nofile 65535'
);
$this->replaceContents('/etc/security/limits.conf', $replacements, true);
if(!is_dir('/etc/systemd/system/mysql.service.d/')) {
mkdir('/etc/systemd/system/mysql.service.d/', 0777, true);
$replacements = array(
'/^\s*LimitNOFILE\s*=.*?$/m' => 'LimitNOFILE=infinity'
);
$this->replaceContents('/etc/systemd/system/mysql.service.d/limits.conf', $replacements, true, 'Service');
$this->exec('systemctl daemon-reload 2>&1');
$this->restartService('mysql');
$this->installPackages($packages);
if(ISPConfig::shallInstall('mail') && !ISPConfig::wantsAmavis()) {
ISPConfigLog::info('Stopping Rspamd.', true);
$this->stopService('rspamd');
if(ISPConfig::wantsUnbound()) {
ISPConfigLog::info('(Re)starting unbound.', true);
$this->restartService('unbound');
} else {
ISPConfigLog::info('(Re)starting Bind.', true);
$this->restartService('bind9');
}
ISPConfigLog::info('Disabling spamassassin daemon.', true);
$this->stopService('spamassassin');
$this->exec('systemctl disable spamassassin 2>&1');
//$cmd = 'sudo -u unbound unbound-anchor -a /var/lib/unbound/root.key';
/*$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
}
$this->restartService('unbound');
*/
Marius Burkard
committed
if(!is_dir('/etc/resolvconf/resolv.conf.d')) {
mkdir('/etc/resolvconf/resolv.conf.d', 0755);
}
$this->addLines('/etc/resolvconf/resolv.conf.d/head', 'nameserver 127.0.0.1', false);
$cmd = 'resolvconf -u 2>&1';
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
}
ISPConfigLog::info('Checking local dns resolver.', true);
$cmd = 'nslookup denic.de | grep Server';
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
} elseif(strpos($result, '127.0.0.1') === false) {
ISPConfigLog::warn('Unexpected resolver response: ' . $result, true);
}
if(ISPConfig::shallInstall('web')) {
$this->stopService('apache2');
$this->stopService('nginx');
if(ISPConfig::$WEBSERVER === ISPC_WEBSERVER_APACHE) {
$packages = array(
'apache2',
'apache2-doc',
'apache2-utils',
'libapache2-mod-fcgid',
'apache2-suexec-pristine',
'libapache2-mod-python',
'libapache2-mod-passenger'
);
} elseif(ISPConfig::$WEBSERVER === ISPC_WEBSERVER_NGINX) {
$packages = array(
'nginx-full',
'fcgiwrap'
);
}
$this->installPackages($packages);
if(ISPConfig::$WEBSERVER === ISPC_WEBSERVER_NGINX) {
$this->stopService('apache2');
$cmd = 'systemctl disable apache2';
$this->exec($cmd); // ignore if this fails
$this->startService('nginx');
}
$packages = $this->getPackagesToInstall('base');
if(ISPConfig::wantsPHP() === 'system') {
$php_versions = array($this->getSystemPHPVersion());
} else {
//ISPConfig::run() validations prevent sending here null values
$php_versions = ISPConfig::wantsPHP();
$php_modules = array(
'common',
'gd',
'mysql',
'imap',
'cli',
'mcrypt',
'curl',
'intl',
'pspell',
'recode',
'sqlite3',
'tidy',
'xmlrpc',
'xsl',
'zip',
'mbstring',
'soap',
'opcache'
);
if(ISPConfig::shallInstall('web')) {
$php_modules[] = 'cgi';
$php_modules[] = 'fpm';
}
foreach($php_versions as $curver) {
$packages[] = 'php' . $curver;
reset($php_modules);
foreach($php_modules as $curmod) {
if(version_compare($curver, '7.2', '>=') && in_array($curmod, array('mcrypt'), true)) {
continue;
} elseif(version_compare($curver, '7.4', '>=') && in_array($curmod, array('mcrypt', 'recode'), true)) {
continue;
} elseif(version_compare($curver, '8.0', '>=') && in_array($curmod, array('mcrypt', 'recode', 'json', 'xmlrpc'), true)) {
$packages[] = 'php' . $curver . '-' . $curmod;
}
}
$this->installPackages($packages);
if(ISPConfig::shallInstall('web') && ISPConfig::$WEBSERVER === ISPC_WEBSERVER_APACHE) {
// Disable conflicting modules so mpm_event can be used with http2
ISPConfigLog::info('Disabling conflicting apache modules.', true);
$modules = $this->getApacheModulesToDisable();
$cmd = 'a2dismod ' . implode(' ', $modules) . ' 2>&1';
$result = $this->exec($cmd);
if($result === false) {
Thom
committed
// throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
ISPConfigLog::info('Enabling apache modules.', true);
$modules = $this->getApacheModulesToEnable();
$cmd = 'a2enmod ' . implode(' ', $modules) . ' 2>&1';
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
}
ISPConfigLog::info('Enabling default PHP-FPM config.', true);
$conf = 'php' . $this->getSystemPHPVersion() . '-fpm';
$cmd = 'a2enconf ' . $conf . ' 2>&1';
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
}
$this->restartService('apache2');
$this->setPHPTimezone();
$this->setDefaultPHP();
foreach($php_versions as $curver) {
$this->restartService('php' . $curver . '-fpm');
if(ISPConfig::shallInstall('web') && ISPConfig::$WEBSERVER === ISPC_WEBSERVER_APACHE) {
ISPConfigLog::info('HTTPoxy config.', true);
$httpoxy = '<IfModule mod_headers.c>' . "\n" . ' RequestHeader unset Proxy early' . "\n" . '</IfModule>';
file_put_contents('/etc/apache2/conf-available/httpoxy.conf', $httpoxy);
$cmd = 'a2enconf httpoxy 2>&1';
$result = $this->exec($cmd);
if($result === false) {
throw new ISPConfigOSException('Command ' . $cmd . ' failed.');
}
$this->restartService('apache2');
if (ISPConfig::wantsCertbot()) {
ISPConfigLog::info('Installing Certbot (Let\'s Encrypt).', true);
ISPConfigLog::info('Installing acme.sh (Let\'s Encrypt).', true);
$cmd = 'cd /tmp ; wget -O - https://get.acme.sh 2>/dev/null | sh 2>/dev/null';
$result = $this->exec($cmd);
if($result === false) {
ISPConfigLog::warn('Installation of acme.sh (Let\'s Encrypt) failed.', true);
} else {
ISPConfigLog::info('acme.sh (Let\'s Encrypt) installed.', true);
}
$mailman_password = '';
if(ISPConfig::shallInstall('mailman')) {
$mailman_password = $this->installMailman($host_name);
$packages = array(
'quota',
'quotatool',
'haveged',
'libclass-dbi-mysql-perl',
'libtimedate-perl',
'build-essential',
'autoconf',
'automake',
'libtool',
'flex',
'bison',
'debhelper',
'binutils'
$this->installPackages($packages);
if(ISPConfig::shallInstall('quota')) {