%PDF- %PDF-
Direktori : /backups/router/usr/local/opnsense/mvc/app/controllers/OPNsense/IDS/Api/ |
Current File : //backups/router/usr/local/opnsense/mvc/app/controllers/OPNsense/IDS/Api/ServiceController.php |
<?php /* * Copyright (C) 2015-2017 Deciso B.V. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ namespace OPNsense\IDS\Api; use OPNsense\Base\ApiMutableServiceControllerBase; use OPNsense\Core\Backend; use OPNsense\Core\Config; use OPNsense\Core\SanitizeFilter; use OPNsense\Cron\Cron; use OPNsense\IDS\IDS; /** * Class ServiceController * @package OPNsense\IDS */ class ServiceController extends ApiMutableServiceControllerBase { protected static $internalServiceClass = '\OPNsense\IDS\IDS'; protected static $internalServiceEnabled = 'general.enabled'; protected static $internalServiceTemplate = 'OPNsense/IDS'; protected static $internalServiceName = 'ids'; /** * Reconfigure IDS * @return array result status * @throws \Exception when configd action fails * @throws \OPNsense\Base\ModelException when unable to construct model * @throws \OPNsense\Base\ValidationException when one or more model validations fail */ public function reconfigureAction() { $status = "failed"; if ($this->request->isPost()) { $mdlIDS = new IDS(); $runStatus = $this->statusAction(); // we should always have a cron item configured for IDS, let's create one upon first reconfigure. if ((string)$mdlIDS->general->UpdateCron == "") { $mdlCron = new Cron(); // update cron relation (if this doesn't break consistency) $mdlIDS->general->UpdateCron = $mdlCron->newDailyJob("IDS", "ids update", "ids rule updates", "*", "0"); if (count($mdlCron->performValidation()) == 0) { $mdlCron->serializeToConfig(); // save data to config, do not validate because the current in memory model doesn't know about the // cron item just created. $mdlIDS->serializeToConfig($validateFullModel = false, $disable_validation = true); Config::getInstance()->save(); } } if ($runStatus['status'] == "running" && (string)$mdlIDS->general->enabled == 0) { $this->stopAction(); } $backend = new Backend(); $bckresult = trim($backend->configdRun('template reload OPNsense/IDS')); if ($bckresult == "OK") { if ((string)$mdlIDS->general->enabled == 1) { $bckresult = trim($backend->configdRun("ids install rules")); if ($bckresult == "OK") { if ($runStatus['status'] == 'running') { $status = $this->restartAction()['response']; } else { $status = $this->startAction()['response']; } } else { $status = "error installing ids rules (" . $bckresult . ")"; } } else { $status = "OK"; } } else { $status = "error generating ids template (" . $bckresult . ")"; } } return array("status" => $status); } /** * Download and update rules * @param null|string $wait wait for update to complete (default) or run in background and return message id * @return array result status * @throws \Exception when configd action fails */ public function updateRulesAction($wait = null) { $status = "failed"; if ($this->request->isPost()) { $backend = new Backend(); // we have to trigger a template reload to be sure we have the right download configuration // ideally we should only regenerate the download config, but that's not supported at the moment. // (not sure if it should be supported) $bckresult = trim($backend->configdRun('template reload OPNsense/IDS')); if ($bckresult == "OK") { if ($wait != null) { $detach = true; } else { $detach = false; } $status = $backend->configdRun("ids update", $detach); } else { $status = "template error"; } } return array("status" => $status); } /** * Flush rule configuration to config and reload suricata ruleset (graceful restart) * @return array * @throws \Exception when configd action fails */ public function reloadRulesAction() { $status = "failed"; if ($this->request->isPost()) { $backend = new Backend(); // flush rule configuration $bckresult = trim($backend->configdRun('template reload OPNsense/IDS')); if ($bckresult == "OK") { $status = $backend->configdRun("ids reload"); } else { $status = "template error"; } } return array("status" => $status); } /** * Query suricata alerts * @return array * @throws \Exception when configd action fails */ public function queryAlertsAction() { if ($this->request->isPost()) { // fetch query parameters (limit results to prevent out of memory issues) $itemsPerPage = $this->request->getPost('rowCount', 'int', 9999); $currentPage = $this->request->getPost('current', 'int', 1); if ($this->request->getPost('searchPhrase', 'string', '') != "") { $filterTag = (new SanitizeFilter())->sanitize($this->request->getPost('searchPhrase'), "query"); $searchPhrase = 'alert,alert_action,src_ip,dest_ip/"*' . $filterTag . '*"'; } else { $searchPhrase = ''; } if ($this->request->getPost('fileid', 'string', '') != "") { $fileid = $this->request->getPost('fileid', 'int', -1); } else { $fileid = null; } $backend = new Backend(); $response = $backend->configdpRun("ids query alerts", array($itemsPerPage, ($currentPage - 1) * $itemsPerPage, $searchPhrase, $fileid)); $result = json_decode($response, true); if ($result != null) { $result['rowCount'] = count($result['rows']); $result['total'] = $result['total_rows']; $result['current'] = (int)$currentPage; unset($result['total_rows']); return $result; } } return array(); } /** * Fetch alert detailed info * @param string $alertId alert id, position in log file * @param string $fileid log file id number (empty for standard) * @return array alert info * @throws \Exception when configd action fails */ public function getAlertInfoAction($alertId, $fileid = "") { $backend = new Backend(); $id = (new SanitizeFilter())->sanitize($alertId, "int"); $response = $backend->configdpRun("ids query alerts", array(1, 0, "filepos/" . $id, $fileid)); $result = json_decode($response, true); if ($result != null && count($result['rows']) > 0) { return $result['rows'][0]; } else { return array(); } } /** * List all available logs * @return array list of alert logs * @throws \Exception when configd action fails */ public function getAlertLogsAction() { $backend = new Backend(); $response = $backend->configdRun("ids list alertlogs"); $result = json_decode($response, true); if ($result != null) { $logs = array(); foreach ($result as $log) { $log['modified'] = date('Y/m/d G:i', (int)$log['modified']); $logs[] = $log; } return $logs; } else { return array(); } } /** * Drop alert log * @return array result status * @throws \Exception when configd action fails */ public function dropAlertLogAction() { if ($this->request->isPost()) { $backend = new Backend(); $filename = $this->request->getPost('filename', 'string', null); if ($filename != null) { $filename = basename($filename); $backend->configdpRun("ids drop alertlog", array($filename)); return array("status" => "ok"); } } return array("status" => "failed"); } }