$distname, 'version' => $distver, 'id' => $distid, 'confid' => $distconfid, 'baseid' => $distbaseid); } // this function remains in the tools class, because it is used by cron AND rescue public function monitorServices() { global $app; global $conf; /** the id of the server as int */ $server_id = intval($conf['server_id']); /** get the "active" Services of the server from the DB */ $services = $app->db->queryOneRecord('SELECT * FROM server WHERE server_id = ?', $server_id); /* * If the DB is down, we have to set the db to "yes". * If we don't do this, then the monitor will NOT monitor, that the db is down and so the * rescue-module can not try to rescue the db */ if ($services == null) { $services['db_server'] = 1; } /* The type of the Monitor-data */ $type = 'services'; /** the State of the monitoring */ /* ok, if ALL active services are running, * error, if not * There is no other state! */ $state = 'ok'; /* Monitor Webserver */ $data['webserver'] = -1; // unknown - not needed if ($services['web_server'] == 1) { if ($this->_checkTcp('localhost', 80)) { $data['webserver'] = 1; } else { $data['webserver'] = 0; $state = 'error'; // because service is down } } /* Monitor FTP-Server */ $data['ftpserver'] = -1; // unknown - not needed if ($services['file_server'] == 1) { if ($this->_checkFtp('localhost', 21)) { $data['ftpserver'] = 1; } else { $data['ftpserver'] = 0; $state = 'error'; // because service is down } } /* Monitor SMTP-Server */ $data['smtpserver'] = -1; // unknown - not needed if ($services['mail_server'] == 1) { if ($this->_checkTcp('localhost', 25)) { $data['smtpserver'] = 1; } else { $data['smtpserver'] = 0; $state = 'error'; // because service is down } } /* Monitor POP3-Server */ $data['pop3server'] = -1; // unknown - not needed if ($services['mail_server'] == 1) { if ($this->_checkTcp('localhost', 110)) { $data['pop3server'] = 1; } else { $data['pop3server'] = 0; $state = 'error'; // because service is down } } /* Monitor IMAP-Server */ $data['imapserver'] = -1; // unknown - not needed if ($services['mail_server'] == 1) { if ($this->_checkTcp('localhost', 143)) { $data['imapserver'] = 1; } else { $data['imapserver'] = 0; $state = 'error'; // because service is down } } /* Monitor BIND-Server */ $data['bindserver'] = -1; // unknown - not needed if ($services['dns_server'] == 1) { if ($this->_checkUdp('localhost', 53)) { $data['bindserver'] = 1; } else { $data['bindserver'] = 0; $state = 'error'; // because service is down } } /* Monitor MySQL Server */ $data['mysqlserver'] = -1; // unknown - not needed if ($services['db_server'] == 1) { if ($this->_checkTcp('localhost', 3306)) { $data['mysqlserver'] = 1; } else { $data['mysqlserver'] = 0; $state = 'error'; // because service is down } } /* $data['mongodbserver'] = -1; if ($this->_checkTcp('localhost', 27017)) { $data['mongodbserver'] = 1; } else { $data['mongodbserver'] = 0; */ //$state = 'error'; // because service is down /* TODO!!! check if this is a mongodbserver at all, otherwise it will always throw an error state!!! */ // } /* * Return the Result */ $res['server_id'] = $server_id; $res['type'] = $type; $res['data'] = $data; $res['state'] = $state; return $res; } public function _getLogData($log) { global $conf; $dist = ''; $logfile = ''; if (@is_file('/etc/debian_version')) { $dist = 'debian'; } elseif (@is_file('/etc/redhat-release')) { $dist = 'redhat'; } elseif (@is_file('/etc/SuSE-release')) { $dist = 'suse'; } elseif (@is_file('/etc/gentoo-release')) { $dist = 'gentoo'; } switch ($log) { case 'log_mail': if ($dist == 'debian') { $logfile = '/var/log/mail.log'; } elseif ($dist == 'redhat') { $logfile = '/var/log/maillog'; } elseif ($dist == 'suse') { $logfile = '/var/log/mail.info'; } elseif ($dist == 'gentoo') { $logfile = '/var/log/maillog'; } break; case 'log_mail_warn': if ($dist == 'debian') { $logfile = '/var/log/mail.warn'; } elseif ($dist == 'redhat') { $logfile = '/var/log/maillog'; } elseif ($dist == 'suse') { $logfile = '/var/log/mail.warn'; } elseif ($dist == 'gentoo') { $logfile = '/var/log/maillog'; } break; case 'log_mail_err': if ($dist == 'debian') { $logfile = '/var/log/mail.err'; } elseif ($dist == 'redhat') { $logfile = '/var/log/maillog'; } elseif ($dist == 'suse') { $logfile = '/var/log/mail.err'; } elseif ($dist == 'gentoo') { $logfile = '/var/log/maillog'; } break; case 'log_messages': if ($dist == 'debian') { $logfile = '/var/log/syslog'; } elseif ($dist == 'redhat') { $logfile = '/var/log/messages'; } elseif ($dist == 'suse') { $logfile = '/var/log/messages'; } elseif ($dist == 'gentoo') { $logfile = '/var/log/messages'; } break; case 'log_ispc_cron': if ($dist == 'debian') { $logfile = $conf['ispconfig_log_dir'] . '/cron.log'; } elseif ($dist == 'redhat') { $logfile = $conf['ispconfig_log_dir'] . '/cron.log'; } elseif ($dist == 'suse') { $logfile = $conf['ispconfig_log_dir'] . '/cron.log'; } elseif ($dist == 'gentoo') { $logfile = '/var/log/cron'; } break; case 'log_freshclam': if ($dist == 'debian') { $logfile = '/var/log/clamav/freshclam.log'; } elseif ($dist == 'redhat') { $logfile = (is_file('/var/log/clamav/freshclam.log') ? '/var/log/clamav/freshclam.log' : '/var/log/freshclam.log'); } elseif ($dist == 'suse') { $logfile = '/var/log/freshclam.log'; } elseif ($dist == 'gentoo') { $logfile = '/var/log/clamav/freshclam.log'; } break; case 'log_clamav': if ($dist == 'debian') { $logfile = '/var/log/clamav/clamav.log'; } elseif ($dist == 'redhat') { $logfile = (is_file('/var/log/clamav/clamd.log') ? '/var/log/clamav/clamd.log' : '/var/log/maillog'); } elseif ($dist == 'suse') { $logfile = '/var/log/clamd.log'; } elseif ($dist == 'gentoo') { $logfile = '/var/log/clamav/clamd.log'; } break; case 'log_fail2ban': if ($dist == 'debian') { $logfile = '/var/log/fail2ban.log'; } elseif ($dist == 'redhat') { $logfile = '/var/log/fail2ban.log'; } elseif ($dist == 'suse') { $logfile = '/var/log/fail2ban.log'; } elseif ($dist == 'gentoo') { $logfile = '/var/log/fail2ban.log'; } break; case 'log_mongodb': $logfile = '/var/log/mongodb/mongodb.log'; break; case 'log_ispconfig': if ($dist == 'debian') { $logfile = $conf['ispconfig_log_dir'] . '/ispconfig.log'; } elseif ($dist == 'redhat') { $logfile = $conf['ispconfig_log_dir'] . '/ispconfig.log'; } elseif ($dist == 'suse') { $logfile = $conf['ispconfig_log_dir'] . '/ispconfig.log'; } elseif ($dist == 'gentoo') { $logfile = $conf['ispconfig_log_dir'] . '/ispconfig.log'; } break; default: $logfile = ''; break; } // Getting the logfile content if ($logfile != '') { $logfile = escapeshellcmd($logfile); if (stristr($logfile, ';') or substr($logfile, 0, 9) != '/var/log/' or stristr($logfile, '..')) { $log = 'Logfile path error.'; } else { $log = ''; if (is_readable($logfile)) { $fd = popen('tail -n 100 ' . $logfile, 'r'); if ($fd) { while (!feof($fd)) { $log .= fgets($fd, 4096); $n++; if ($n > 1000) break; } fclose($fd); } } else { $log = 'Unable to read ' . $logfile; } } } return $log; } private function _checkTcp($host, $port) { /* Try to open a connection */ $fp = @fsockopen($host, $port, $errno, $errstr, 2); if ($fp) { /* * We got a connection, this means, everything is O.K. * But maybe we are able to do more deep testing? */ if ($port == 80) { /* * Port 80 means, testing APACHE * So we can do a deepter test and try to get data over this connection. * (if apache hangs, we get a connection but a timeout by trying to GET the data!) */ // fwrite($fp, "GET / HTTP/1.0\r\n\r\n"); $out = "GET / HTTP/1.1\r\n"; $out .= "Host: localhost\r\n"; $out .= "User-Agent: Mozilla/5.0 (ISPConfig monitor)\r\n"; $out .= "Accept: application/xml,application/xhtml+xml,text/html\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); stream_set_timeout($fp, 5); // Timeout after 5 seconds $res = fread($fp, 10); // try to get 10 bytes (enough to test!) $info = stream_get_meta_data($fp); if ($info['timed_out']) { return false; // Apache was not able to send data over this connection } } /* The connection is no longer needed */ fclose($fp); /* We are able to establish a connection */ return true; } else { /* We are NOT able to establish a connection */ return false; } } private function _checkUdp($host, $port) { $fp = @fsockopen('udp://' . $host, $port, $errno, $errstr, 2); if ($fp) { fclose($fp); return true; } else { return false; } } private function _checkFtp($host, $port) { $conn_id = @ftp_connect($host, $port); if ($conn_id) { @ftp_close($conn_id); return true; } else { return false; } } /** * Set the state to the given level (or higher, but not lesser). * * If the actual state is critical and you call the method with ok, * then the state is critical. * * * If the actual state is critical and you call the method with error, * then the state is error. */ public function _setState($oldState, $newState) { /* * Calculate the weight of the old state */ switch ($oldState) { case 'no_state': $oldInt = 0; break; case 'ok': $oldInt = 1; break; case 'unknown': $oldInt = 2; break; case 'info': $oldInt = 3; break; case 'warning': $oldInt = 4; break; case 'critical': $oldInt = 5; break; case 'error': $oldInt = 6; break; } /* * Calculate the weight of the new state */ switch ($newState) { case 'no_state': $newInt = 0; break; case 'ok': $newInt = 1; break; case 'unknown': $newInt = 2; break; case 'info': $newInt = 3; break; case 'warning': $newInt = 4; break; case 'critical': $newInt = 5; break; case 'error': $newInt = 6; break; } /* * Set to the higher level */ if ($newInt > $oldInt) { return $newState; } else { return $oldState; } } /** * Deletes Records older than 4 minutes. * The monitor writes new data every 5 minutes or longer (4 hour, 1 day). * So if i delete all Date older than 4 minutes i can be sure, that all old data * are deleted... */ public function delOldRecords($type, $serverId) { global $app; // $now = time(); // $old = $now - (4 * 60); // 4 minutes $old = 240; //seconds /* * ATTENTION if i do NOT pay attention of the server id, i delete all data (of the type) * of ALL servers. This means, if i have a multiserver-environment and a server has a * time not synced with the others (for example, all server has 11:00 and ONE server has * 10:45) then the actual data of this server (with the time-stamp 10:45) get lost * even though it is the NEWEST data of this server. To avoid this i HAVE to include * the server-id! */ $sql = 'DELETE FROM `monitor_data` WHERE `type` = ? AND `created` < UNIX_TIMESTAMP() - ? AND `server_id` = ?'; $app->dbmaster->query($sql, $type, $old, $serverId); } public function send_notification_email($template, $placeholders, $recipients) { global $conf; if(!is_array($recipients) || count($recipients) < 1) return false; if(!is_array($placeholders)) $placeholders = array(); if(file_exists($conf['rootpath'].'/conf-custom/mail/' . $template . '_'.$conf['language'].'.txt')) { $lines = file($conf['rootpath'].'/conf-custom/mail/' . $template . '_'.$conf['language'].'.txt'); } elseif(file_exists($conf['rootpath'].'/conf-custom/mail/' . $template . '_en.txt')) { $lines = file($conf['rootpath'].'/conf-custom/mail/' . $template . '_en.txt'); } elseif(file_exists($conf['rootpath'].'/conf/mail/' . $template . '_'.$conf['language'].'.txt')) { $lines = file($conf['rootpath'].'/conf/mail/' . $template . '_'.$conf['language'].'.txt'); } else { $lines = file($conf['rootpath'].'/conf/mail/' . $template . '_en.txt'); } //* get mail headers, subject and body $mailHeaders = ''; $mailBody = ''; $mailSubject = ''; $inHeader = true; for($l = 0; $l < count($lines); $l++) { if(trim($lines[$l]) == '') { $inHeader = false; continue; } if($inHeader == true) { $parts = explode(':', $lines[$l], 2); if(strtolower($parts[0]) == 'subject') { $mailSubject = trim($parts[1]); continue; } unset($parts); $mailHeaders .= trim($lines[$l]) . "\n"; } else { $mailBody .= trim($lines[$l]) . "\n"; } } $mailBody = trim($mailBody); //* Replace placeholders $mailHeaders = strtr($mailHeaders, $placeholders); $mailSubject = strtr($mailSubject, $placeholders); $mailBody = strtr($mailBody, $placeholders); for($r = 0; $r < count($recipients); $r++) { mail($recipients[$r], $mailSubject, $mailBody, $mailHeaders); } unset($mailSubject); unset($mailHeaders); unset($mailBody); unset($lines); return true; } } ?>