diff --git a/server/mods-available/web_module.inc.php b/server/mods-available/web_module.inc.php index 12ad81ef9cd38db186728d0517e8a73422f03904..6019100ed76a01f59db4f82de24afd595798f117 100644 --- a/server/mods-available/web_module.inc.php +++ b/server/mods-available/web_module.inc.php @@ -54,6 +54,9 @@ class web_module { 'web_backup_insert', 'web_backup_update', 'web_backup_delete', + 'server_php_insert', + 'server_php_update', + 'server_php_delete', 'aps_instance_insert', 'aps_instance_update', 'aps_instance_delete', @@ -112,6 +115,7 @@ class web_module { $app->modules->registerTableHook('web_folder', 'web_module', 'process'); $app->modules->registerTableHook('web_folder_user', 'web_module', 'process'); $app->modules->registerTableHook('web_backup', 'web_module', 'process'); + $app->modules->registerTableHook('server_php', 'web_module', 'process'); $app->modules->registerTableHook('aps_instances', 'web_module', 'process'); $app->modules->registerTableHook('aps_instances_settings', 'web_module', 'process'); $app->modules->registerTableHook('aps_packages', 'web_module', 'process'); @@ -167,6 +171,11 @@ class web_module { if($action == 'u') $app->plugins->raiseEvent('web_backup_update', $data); if($action == 'd') $app->plugins->raiseEvent('web_backup_delete', $data); break; + case 'server_php': + if($action == 'i') $app->plugins->raiseEvent('server_php_insert', $data); + if($action == 'u') $app->plugins->raiseEvent('server_php_update', $data); + if($action == 'd') $app->plugins->raiseEvent('server_php_delete', $data); + break; case 'aps_instances': if($action == 'i') $app->plugins->raiseEvent('aps_instance_insert', $data); if($action == 'u') $app->plugins->raiseEvent('aps_instance_update', $data); diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php index 19f650d4b3bf05f76bc235dfb99ee00248c2d8f2..b0f87c192bfd68960a5d72b281c06fc8d87ffa44 100644 --- a/server/plugins-available/apache2_plugin.inc.php +++ b/server/plugins-available/apache2_plugin.inc.php @@ -1178,7 +1178,7 @@ class apache2_plugin { $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); } - //* Write the custom php.ini file, if custom_php_ini fieled is not empty + //* Write the custom php.ini file, if custom_php_ini field is not empty $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user']; if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $custom_php_ini_dir .= '_' . $web_folder; if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf'); diff --git a/server/plugins-available/webserver_plugin.inc.php b/server/plugins-available/webserver_plugin.inc.php index 0873826bde4de220e63b8533f965a7f08e511efd..7d307233d8ed6ef8bbd65323eb1f5d2276158760 100644 --- a/server/plugins-available/webserver_plugin.inc.php +++ b/server/plugins-available/webserver_plugin.inc.php @@ -37,8 +37,6 @@ class webserver_plugin { * This function is called during ispconfig installation to determine * if a symlink shall be created for this plugin. */ - - public function onInstall() { global $conf; @@ -56,7 +54,11 @@ class webserver_plugin { global $app; $app->plugins->registerAction('server_plugins_loaded', $this->plugin_name, 'check_phpini_changes'); + $app->plugins->registerEvent('server_update', $this->plugin_name, 'server_update'); + + $app->plugins->registerEvent('server_php_insert', $this->plugin_name, 'server_php_update'); + $app->plugins->registerEvent('server_php_update', $this->plugin_name, 'server_php_update'); } /** @@ -92,10 +94,6 @@ class webserver_plugin { 'mode' => 'mod', 'php_version' => 0); // default; - $check_files[] = array('file' => $web_config['php_ini_path_cgi'], - 'mode' => '', // all but 'mod' and 'fast-cgi' - 'php_version' => 0); // default; - if($fastcgi_config["fastcgi_phpini_path"] && $fastcgi_config["fastcgi_phpini_path"] != $web_config['php_ini_path_cgi']) { $check_files[] = array('file' => $fastcgi_config["fastcgi_phpini_path"], 'mode' => 'fast-cgi', @@ -106,6 +104,16 @@ class webserver_plugin { 'php_version' => 0); // default; } + $check_files[] = array('file' => $web_config['php_fpm_ini_path'], + 'mode' => 'php-fpm', + 'php_version' => 0); // default; + + if(!array_search($web_config['php_ini_path_cgi'], array_column($check_files, 'file'))) { + $check_files[] = array('file' => $web_config['php_ini_path_cgi'], + 'mode' => '', // all but 'mod' and 'fast-cgi' + 'php_version' => 0); // default; + } + //** read additional php versions of this server $php_versions = $app->db->queryAllRecords('SELECT server_php_id, php_fastcgi_ini_dir, php_fpm_ini_dir FROM server_php WHERE server_id = ?', $conf['server_id']); @@ -114,7 +122,8 @@ class webserver_plugin { $check_files[] = array('file' => $php['php_fastcgi_ini_dir'] . '/php.ini', 'mode' => 'fast-cgi', 'php_version' => $php['server_php_id']); - } elseif($php['php_fpm_ini_dir'] && $php['php_fpm_ini_dir'] . '/php.ini' != $web_config['php_ini_path_cgi']) { + } + if($php['php_fpm_ini_dir'] && $php['php_fpm_ini_dir'] . '/php.ini' != $web_config['php_fpm_ini_path']) { $check_files[] = array('file' => $php['php_fpm_ini_dir'] . '/php.ini', 'mode' => 'php-fpm', 'php_version' => $php['server_php_id']); @@ -134,6 +143,13 @@ class webserver_plugin { } if(!is_array($php_ini_md5)) $php_ini_md5 = array(); + // verify needed php file settings if that hasn't been done since 15 minutes + $now = time(); + $verify_php_ini=false; + if(!isset($php_ini_md5['last_verify_php_ini']) || ($now - intval($php_ini_md5['last_verify_php_ini']) > 15*60)) { + $verify_php_ini=true; + } + $processed = array(); foreach($check_files as $file) { $file_path = $file['file']; @@ -145,6 +161,11 @@ class webserver_plugin { if(in_array($ident, $processed) == true) continue; $processed[] = $ident; + //** check that needed php.ini settings/changes are made + if($verify_php_ini) { + $this->verify_php_ini($file); + } + //** check if md5sum of file changed $file_md5 = md5_file($file_path); if(array_key_exists($file_path, $php_ini_md5) == false || $php_ini_md5[$file_path] != $file_md5) { @@ -158,13 +179,62 @@ class webserver_plugin { $new_php_ini_md5[$file_path] = $file_md5; } + $new_php_ini_md5['last_verify_php_ini'] = time(); + //** write new md5 sums if something changed - if($php_ini_changed == true) $app->system->file_put_contents(SCRIPT_PATH . '/temp/php.ini.md5sum', base64_encode(serialize($new_php_ini_md5))); + if($php_ini_changed == true || $verify_php_ini == true) $app->system->file_put_contents(SCRIPT_PATH . '/temp/php.ini.md5sum', base64_encode(serialize($new_php_ini_md5))); unset($new_php_ini_md5); unset($php_ini_md5); unset($processed); } + /** + * The method runs each php.ini file through verify_php_ini() + */ + function server_php_update($event_name, $data) { + global $app, $conf; + + if(isset($data['new']['php_fastcgi_ini_dir'])) { + $php_ini = $data['new']['php_fastcgi_ini_dir'] . '/php.ini'; + if(file_exists($php_ini)) { + $this->verify_php_ini(array('file' => $php_ini, + 'mode' => 'fast-cgi', + 'php_version' => $data['new']['server_php_id']) + ); + } else { + $app->log("Cannot verify php.ini, file not found: $php_ini", LOGLEVEL_WARN); + } + } + if(isset($data['new']['php_fpm_ini_dir'])) { + $php_ini = $data['new']['php_fpm_ini_dir'] . '/php.ini'; + if(file_exists($php_ini)) { + $this->verify_php_ini(array('file' => $php_ini, + 'mode' => 'php-fpm', + 'php_version' => $data['new']['server_php_id']) + ); + } else { + $app->log("Cannot verify php.ini, file not found: $php_ini", LOGLEVEL_WARN); + } + } + } + + /** + * The method checks/sets needed php.ini settings + */ + public function verify_php_ini($file) { + global $app; + + if(isset($file['file']) && is_file($file['file'])) { + $php_ini = $file['file']; + // ensure opcache.validate_root = 1 + $app->system->exec_safe('grep ^opcache.validate_root ?', $php_ini); + if($app->system->last_exec_retcode() != 0) { + $app->log('verify_php_ini(): php.ini '.$php_ini.' is missing validate_root', LOGLEVEL_DEBUG); + $sed_script='s/; *opcache\.validate_root *= *.+$/opcache.validate_root = 1/g'; + $app->system->exec_safe('sed -E -i ? ?', $sed_script, $php_ini); + } + } + } /* * Checks for changes to jailkit settings in server config and schedules affected jails to be updated. @@ -245,7 +315,32 @@ class webserver_plugin { } } } + + $check_files = array(); + if ($old['php_ini_path_apache'] != $new['php_ini_path_apache']) { + $check_files[] = array('file' => $new['php_ini_path_apache'], + 'mode' => 'mod', + 'php_version' => 0); + } + + if ($old['fastcgi_phpini_path'] != $new['fastcgi_phpini_path']) { + $check_files[] = array('file' => $new['fastcgi_phpini_path'], + 'mode' => 'fast-cgi', + 'php_version' => 0); + } + if ($old['php_ini_path_cgi'] != $new['php_ini_path_cgi']) { + $check_files[] = array('file' => $new['php_ini_path_cgi'], + 'mode' => 'fast-cgi', + 'php_version' => 0); + } + if ($old['php_fpm_ini_path'] != $new['php_fpm_ini_path']) { + $check_files[] = array('file' => $web_config['php_fpm_ini_path'], + 'mode' => 'php-fpm', + 'php_version' => 0); + } + foreach ($check_files as $file) { + $this->verify_php_ini($file); + } } } -?>