mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
security/wazuh-agent - add initial wazuh agent plugin.
features available in this version: o Pluggable ossec.conf sections in /usr/local/opnsense/service/templates/OPNsense/WazuhAgent/ossec_config.d/ o Selectable syslog applications (flushed to it's own log file using a format Wazuh understands) o Suricata (IDPS) log shipping using localfile json parser o Optional Password authentication (as specified in https://documentation.wazuh.com/current/user-manual/agent-enrollment/security-options/using-password-authentication.html) o Active response support, including a custom firewall action (opnsense-fw) o Ignore list for opnsense-fw, using a standard alias which contains networks to skip o Toggle standard modules (wodle_syscollector, rootcheck, syscheck) o Log views and format parsers for local insights. (ossec.log, active-responses.log) o When searching for issues, a debug toggle is available which changes all debug options at once to the requested level
This commit is contained in:
@@ -0,0 +1 @@
|
||||
rm /var/ossec/active-response/bin/opnsense-fw
|
||||
@@ -0,0 +1,5 @@
|
||||
echo -n 'reload filter to register alias: '
|
||||
/usr/local/sbin/configctl filter reload
|
||||
cp /usr/local/opnsense/scripts/wazuh/opnsense-fw /var/ossec/active-response/bin/opnsense-fw
|
||||
chmod 750 /var/ossec/active-response/bin/opnsense-fw
|
||||
chown root:wazuh /var/ossec/active-response/bin/opnsense-fw
|
||||
@@ -0,0 +1,8 @@
|
||||
PLUGIN_NAME= wazuh-agent
|
||||
PLUGIN_VERSION= 1.0.0
|
||||
#PLUGIN_REVISION= 1
|
||||
PLUGIN_COMMENT= Agent for the opensource security platform Wazuh
|
||||
PLUGIN_MAINTAINER= ad@opnsense.org
|
||||
PLUGIN_TIER= 3
|
||||
|
||||
.include "../../Mk/plugins.mk"
|
||||
@@ -0,0 +1,3 @@
|
||||
Wazuh is a free and open source platform used for threat prevention, detection, and response. It is capable of protecting workloads across on-premises, virtualized, containerized, and cloud-based environments.
|
||||
|
||||
Using this plugin you can integrate your OPNsense firewall into the Wazuh solution.
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 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.
|
||||
*/
|
||||
|
||||
|
||||
function wazuhagent_services()
|
||||
{
|
||||
$services = [];
|
||||
if ((new \OPNsense\WazuhAgent\WazuhAgent())->general->enabled == '1') {
|
||||
$service = [
|
||||
'description' => gettext('Wazuh Agent'),
|
||||
'configd' => [
|
||||
'restart' => ['wazuh_agent restart'],
|
||||
'start' => ['wazuh_agent start'],
|
||||
'stop' => ['wazuh_agent stop'],
|
||||
],
|
||||
'name' => 'wazuh-agentd',
|
||||
];
|
||||
$services[] = $service;
|
||||
}
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
function wazuhagent_firewall($fw)
|
||||
{
|
||||
global $config;
|
||||
$defaults = ['block' => ['type' => 'block', 'log' => !isset($config['syslog']['nologdefaultblock'])]];
|
||||
if ((new \OPNsense\WazuhAgent\WazuhAgent())->general->enabled == '1') {
|
||||
//$fw->registerFilterRule();
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
['from' => '<__wazuh_agent_drop>', 'descr' => 'Wazuh agent blocklist', '#ref' => 'ui/wazuhagent/'],
|
||||
$defaults['block']
|
||||
);
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2023 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\WazuhAgent\Api;
|
||||
|
||||
use OPNsense\Base\ApiMutableServiceControllerBase;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
class ServiceController extends ApiMutableServiceControllerBase
|
||||
{
|
||||
protected static $internalServiceClass = '\OPNsense\WazuhAgent\WazuhAgent';
|
||||
protected static $internalServiceEnabled = 'general.enabled';
|
||||
protected static $internalServiceTemplate = 'OPNsense/WazuhAgent';
|
||||
protected static $internalServiceName = 'wazuh_agent';
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2023 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\WazuhAgent\Api;
|
||||
|
||||
use OPNsense\Base\ApiMutableModelControllerBase;
|
||||
|
||||
class SettingsController extends ApiMutableModelControllerBase
|
||||
{
|
||||
protected static $internalModelName = 'agent';
|
||||
protected static $internalModelClass = 'OPNsense\WazuhAgent\WazuhAgent';
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2023 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\WazuhAgent;
|
||||
|
||||
/**
|
||||
* Class IndexController
|
||||
* @package OPNsense\WazuhAgent
|
||||
*/
|
||||
class IndexController extends \OPNsense\Base\IndexController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
// link dialogs
|
||||
$this->view->formSettings = $this->getForm("settings");
|
||||
// choose template
|
||||
$this->view->pick('OPNsense/WazuhAgent/index');
|
||||
}
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
<form>
|
||||
<field>
|
||||
<type>header</type>
|
||||
<label>General Settings</label>
|
||||
</field>
|
||||
<field>
|
||||
<id>agent.general.enabled</id>
|
||||
<label>Enable</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable Wazuh Agent</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>agent.general.server_address</id>
|
||||
<label>Manager hostname</label>
|
||||
<type>text</type>
|
||||
<help>Specifies the IP address or the hostname of the Wazuh manager.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>agent.logcollector.syslog_programs</id>
|
||||
<label>Applications</label>
|
||||
<type>select_multiple</type>
|
||||
<help>Choose which applications to forward to Wazuh.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>agent.logcollector.suricata_eve_log</id>
|
||||
<label>Intrusion detection events</label>
|
||||
<type>checkbox</type>
|
||||
<help>Send events from the intrusion detection engine to Wazuh (Suricata EVE log)</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>agent.logcollector.remote_commands</id>
|
||||
<label>Logcollector remote commands</label>
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>
|
||||
Enable remote commands from the log collector, disabling this will ignore command and full_command log sources
|
||||
and prevents Wazuh manager from running arbitrary commands on this node.
|
||||
</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>agent.general.debug_level</id>
|
||||
<advanced>true</advanced>
|
||||
<label>Debug</label>
|
||||
<type>dropdown</type>
|
||||
<help>
|
||||
Debug level for this agents services.
|
||||
</help>
|
||||
</field>
|
||||
<field>
|
||||
<type>header</type>
|
||||
<label>Active response</label>
|
||||
<collapse>true</collapse>
|
||||
</field>
|
||||
<field>
|
||||
<id>agent.active_response.enabled</id>
|
||||
<label>Enable</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable Active response</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>agent.active_response.fw_alias_ignore</id>
|
||||
<label>Firewall command ignore</label>
|
||||
<type>dropdown</type>
|
||||
<help>
|
||||
Select an alias from which the items should be ignored when dropping ip addresses using the opnsense-fw
|
||||
active-response action.
|
||||
</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>agent.active_response.remote_commands</id>
|
||||
<label>Wazuh remote commands</label>
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>
|
||||
Toggles whether Command Module should accept commands defined in the shared configuration or not.
|
||||
</help>
|
||||
</field>
|
||||
<field>
|
||||
<type>header</type>
|
||||
<label>Authentication</label>
|
||||
<collapse>true</collapse>
|
||||
</field>
|
||||
<field>
|
||||
<id>agent.auth.password</id>
|
||||
<label>Password</label>
|
||||
<type>password</type>
|
||||
<help>Password to use in authd.pass file.</help>
|
||||
</field>
|
||||
<field>
|
||||
<type>header</type>
|
||||
<label>Policy monitoring and anomaly detection</label>
|
||||
<collapse>true</collapse>
|
||||
</field>
|
||||
<field>
|
||||
<id>agent.rootcheck.enabled</id>
|
||||
<label>Enable</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable policy monitoring and anomaly detection</help>
|
||||
</field>
|
||||
<field>
|
||||
<type>header</type>
|
||||
<label>System inventory</label>
|
||||
<collapse>true</collapse>
|
||||
</field>
|
||||
<field>
|
||||
<id>agent.syscollector.enabled</id>
|
||||
<label>Enable</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable syscollector</help>
|
||||
</field>
|
||||
<field>
|
||||
<type>header</type>
|
||||
<label>File integrity monitoring</label>
|
||||
<collapse>true</collapse>
|
||||
</field>
|
||||
<field>
|
||||
<id>agent.syscheck.enabled</id>
|
||||
<label>Enable</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable file integrity monitoring</help>
|
||||
</field>
|
||||
</form>
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"__wazuh_agent_drop": {
|
||||
"enabled": "1",
|
||||
"name": "__wazuh_agent_drop",
|
||||
"type": "external",
|
||||
"description": "Wazuh Agent blocklist (internal)",
|
||||
"content": ""
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<acl>
|
||||
<page-services-wazuh_agent>
|
||||
<name>Services: Wazuh Agent</name>
|
||||
<patterns>
|
||||
<pattern>ui/wazuh_agent/*</pattern>
|
||||
<pattern>api/wazuh_agent/*</pattern>
|
||||
</patterns>
|
||||
</page-services-wazuh_agent>
|
||||
</acl>
|
||||
@@ -0,0 +1,9 @@
|
||||
<menu>
|
||||
<Services>
|
||||
<WazuhAgent VisibleName="Wazuh Agent" cssClass="fa fa-heartbeat fa-fw">
|
||||
<Settings order="10" url="/ui/wazuhagent/"/>
|
||||
<Ossec VisibleName="Logfile / ossec" order="20" url="/ui/diagnostics/log/wazuhagent/ossec" />
|
||||
<ActiveResponses VisibleName="Logfile / active-responses" order="30" url="/ui/diagnostics/log/wazuhagent/activeresponses" />
|
||||
</WazuhAgent>
|
||||
</Services>
|
||||
</menu>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 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\WazuhAgent;
|
||||
|
||||
use Phalcon\Messages\Message;
|
||||
use OPNsense\Base\BaseModel;
|
||||
|
||||
/**
|
||||
* Class WazuhAgent
|
||||
* @package OPNsense\WazuhAgent
|
||||
*/
|
||||
class WazuhAgent extends BaseModel
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<model>
|
||||
<mount>//OPNsense/WazuhAgent</mount>
|
||||
<version>1.0.0</version>
|
||||
<description>
|
||||
Wazuh Agent
|
||||
</description>
|
||||
<items>
|
||||
<general>
|
||||
<enabled type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
<server_address type="HostnameField">
|
||||
<Required>Y</Required>
|
||||
<IpAllowed>Y</IpAllowed>
|
||||
</server_address>
|
||||
<debug_level type="OptionField">
|
||||
<default>0</default>
|
||||
<Required>Y</Required>
|
||||
<OptionValues>
|
||||
<val0 value="0">no debug</val0>
|
||||
<val1 value="1">first level of debug</val1>
|
||||
<val2 value="2">full debugging</val2>
|
||||
</OptionValues>
|
||||
</debug_level>
|
||||
</general>
|
||||
<auth>
|
||||
<password type="TextField">
|
||||
</password>
|
||||
</auth>
|
||||
<logcollector>
|
||||
<remote_commands type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</remote_commands>
|
||||
<syslog_programs type="JsonKeyValueStoreField">
|
||||
<Required>N</Required>
|
||||
<Multiple>Y</Multiple>
|
||||
<default>filterlog,openvpn,unbound,audit,sshd</default>
|
||||
<ConfigdPopulateAct>syslog list applications</ConfigdPopulateAct>
|
||||
<SourceFile>/tmp/syslog_applications.json</SourceFile>
|
||||
<ConfigdPopulateTTL>20</ConfigdPopulateTTL>
|
||||
<SortByValue>Y</SortByValue>
|
||||
<ValidationMessage>Specify valid source applications.</ValidationMessage>
|
||||
</syslog_programs>
|
||||
<suricata_eve_log type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</suricata_eve_log>
|
||||
</logcollector>
|
||||
<rootcheck>
|
||||
<enabled type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
</rootcheck>
|
||||
<syscollector>
|
||||
<enabled type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
</syscollector>
|
||||
<syscheck>
|
||||
<enabled type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
</syscheck>
|
||||
<active_response>
|
||||
<enabled type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
<remote_commands type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</remote_commands>
|
||||
<fw_alias_ignore type="ModelRelationField">
|
||||
<Model>
|
||||
<alias>
|
||||
<source>OPNsense.Firewall.Alias</source>
|
||||
<items>aliases.alias</items>
|
||||
<display>name</display>
|
||||
<filters>
|
||||
<type>/[network|host]/</type>
|
||||
</filters>
|
||||
</alias>
|
||||
</Model>
|
||||
<Required>N</Required>
|
||||
</fw_alias_ignore>
|
||||
</active_response>
|
||||
</items>
|
||||
</model>
|
||||
@@ -0,0 +1,76 @@
|
||||
{#
|
||||
|
||||
OPNsense® is Copyright © 2023 by 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.
|
||||
|
||||
#}
|
||||
|
||||
<script>
|
||||
$( document ).ready(function() {
|
||||
let data_get_map = {'frm_settings':"/api/wazuhagent/settings/get"};
|
||||
mapDataToFormUI(data_get_map).done(function(){
|
||||
formatTokenizersUI();
|
||||
$('.selectpicker').selectpicker('refresh');
|
||||
updateServiceControlUI('wazuhagent');
|
||||
});
|
||||
|
||||
$("#reconfigureAct").SimpleActionButton({
|
||||
onPreAction: function() {
|
||||
const dfObj = new $.Deferred();
|
||||
saveFormToEndpoint("/api/wazuhagent/settings/set", 'frm_settings', function(){
|
||||
dfObj.resolve();
|
||||
});
|
||||
return dfObj;
|
||||
},
|
||||
onAction: function(data, status) {
|
||||
updateServiceControlUI('wazuhagent');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
|
||||
<li class="active"><a data-toggle="tab" href="#settings" id="settings_tab">{{ lang._('Settings') }}</a></li>
|
||||
</ul>
|
||||
<div class="tab-content content-box">
|
||||
<div id="settings" class="tab-pane fade in active">
|
||||
{{ partial("layout_partials/base_form",['fields':formSettings,'id':'frm_settings'])}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="page-content-main">
|
||||
<div class="content-box">
|
||||
<div class="col-md-12">
|
||||
<br/>
|
||||
<button class="btn btn-primary" id="reconfigureAct"
|
||||
data-endpoint='/api/wazuhagent/service/reconfigure'
|
||||
data-label="{{ lang._('Apply') }}"
|
||||
data-service-widget="wazuh_agent"
|
||||
data-error-title="{{ lang._('Error reconfiguring Wazuh Agent') }}"
|
||||
type="button"
|
||||
></button>
|
||||
<br/><br/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,51 @@
|
||||
"""
|
||||
Copyright (c) 2023 Ad Schellevis <ad@opnsense.org>
|
||||
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.
|
||||
"""
|
||||
import re
|
||||
import datetime
|
||||
from . import NewBaseLogFormat
|
||||
ossec_timeformat = r'^(\d{4}/\d{1,2}/\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}).*'
|
||||
|
||||
class OssecLogFormat(NewBaseLogFormat):
|
||||
def __init__(self, filename):
|
||||
super().__init__(filename)
|
||||
self._priority = 100
|
||||
|
||||
def match(self, line):
|
||||
return self._filename.find('wazuhagent') > -1 and re.match(ossec_timeformat, line) is not None
|
||||
|
||||
@property
|
||||
def timestamp(self):
|
||||
tmp = re.match(ossec_timeformat, self._line)
|
||||
grp = tmp.group(1)
|
||||
return datetime.datetime.strptime(grp, "%Y/%m/%d %H:%M:%S").isoformat()
|
||||
|
||||
@property
|
||||
def process_name(self):
|
||||
return self._line[19:].strip().split(':', 1)[0]
|
||||
|
||||
@property
|
||||
def line(self):
|
||||
return self._line[19:].strip().split(':', 1)[-1]
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
#!/usr/local/bin/python3
|
||||
|
||||
"""
|
||||
Copyright (c) 2023 Ad Schellevis <ad@opnsense.org>
|
||||
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.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import ipaddress
|
||||
from select import select
|
||||
from configparser import ConfigParser
|
||||
|
||||
|
||||
def send_log(line):
|
||||
with open('/var/ossec/logs/active-responses.log', 'a') as handle:
|
||||
handle.write(
|
||||
str(datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S')) +
|
||||
" " +
|
||||
os.path.basename(__file__) +
|
||||
": " +
|
||||
line +
|
||||
"\n"
|
||||
)
|
||||
|
||||
|
||||
def read_data(filename):
|
||||
payload = []
|
||||
with open(filename, 'rb') as fin:
|
||||
while True:
|
||||
rlist, _, _ = select([fin], [], [], 0.5)
|
||||
if not rlist:
|
||||
break
|
||||
line = fin.readline()
|
||||
if line == b'':
|
||||
break
|
||||
payload.append(line)
|
||||
|
||||
return b''.join(payload)
|
||||
|
||||
|
||||
def main(params):
|
||||
send_log('Started')
|
||||
skip_alias=''
|
||||
if os.path.isfile('/var/ossec/etc/opnsense-fw.conf'):
|
||||
cnf = ConfigParser()
|
||||
cnf.read('/var/ossec/etc/opnsense-fw.conf')
|
||||
skip_alias = cnf.get('general', 'skip_alias') if cnf.has_option('general', 'skip_alias') else ''
|
||||
else:
|
||||
send_log('Skip configuration')
|
||||
|
||||
event=None
|
||||
try:
|
||||
event=json.loads(read_data(params.input))
|
||||
except ValueError:
|
||||
pass
|
||||
if event is None:
|
||||
send_log('Decoding JSON has failed, invalid input format')
|
||||
return -1
|
||||
else:
|
||||
send_log('Received : %s' % json.dumps(event))
|
||||
|
||||
command=event.get('command', None)
|
||||
srcip=event
|
||||
for token in ['parameters', 'alert', 'data', 'srcip']:
|
||||
if type(srcip) is dict and token in srcip:
|
||||
srcip = srcip[token]
|
||||
else:
|
||||
srcip = None
|
||||
break
|
||||
|
||||
if srcip is None:
|
||||
send_log('srcip not found')
|
||||
return -1
|
||||
|
||||
try:
|
||||
ipaddress.ip_address(srcip)
|
||||
except ValueError:
|
||||
send_log('Unable to process even, invalid srcip (%s)' % srcip)
|
||||
return -1
|
||||
|
||||
if skip_alias != '' and command == 'add':
|
||||
sp = subprocess.run(['/sbin/pfctl', '-t', skip_alias, '-Ttest', srcip], capture_output=True, text=True)
|
||||
if sp.stderr.strip().find("1/1") == 0:
|
||||
send_log('Skip event %s in alias %s' % (srcip, skip_alias))
|
||||
return 0
|
||||
|
||||
if command == 'add':
|
||||
# return rule id for timeout list
|
||||
try:
|
||||
print(json.dumps({
|
||||
"version": 1,
|
||||
"origin": {
|
||||
"name": sys.argv[0],
|
||||
"module":"active-response"
|
||||
},
|
||||
"command": "check_keys",
|
||||
"parameters":{
|
||||
"keys": [event['parameters']['alert']['rule']['id']]
|
||||
}
|
||||
}))
|
||||
sys.stdout.flush()
|
||||
except KeyError:
|
||||
pass
|
||||
# When attached to stdin we're likely running inside the agent, in which case we will read a second event which
|
||||
# may abort the first one.
|
||||
if params.input == '/dev/stdin':
|
||||
timeout_event = None
|
||||
try:
|
||||
timeout_event=json.loads(read_data(params.input))
|
||||
except ValueError:
|
||||
pass
|
||||
if timeout_event:
|
||||
send_log('Received : %s' % json.dumps(timeout_event))
|
||||
if timeout_event.get('command') == 'abort':
|
||||
send_log('Aborted')
|
||||
return 0
|
||||
elif timeout_event.get('command') != 'continue':
|
||||
send_log('Invalid command')
|
||||
return -1
|
||||
# add to table and kill active sessions for this ip as well
|
||||
subprocess.run(['/sbin/pfctl', '-t', '__wazuh_agent_drop', '-T', 'add', srcip], capture_output=True)
|
||||
subprocess.run(['/sbin/pfctl', '-k', srcip], capture_output=True)
|
||||
elif command == 'delete':
|
||||
subprocess.run(['/sbin/pfctl', '-t', '__wazuh_agent_drop', '-T', 'delete', srcip], capture_output=True)
|
||||
|
||||
send_log('Active response executed (%s %s)' % (command, srcip))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-input', help='read message from', default='/dev/stdin')
|
||||
sys.exit(main(parser.parse_args()))
|
||||
@@ -0,0 +1,61 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2023 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.
|
||||
*
|
||||
*/
|
||||
|
||||
require_once('script/load_phalcon.php');
|
||||
$authd_pass = '/var/ossec/etc/authd.pass';
|
||||
|
||||
$mdl = new \OPNsense\WazuhAgent\WazuhAgent();
|
||||
|
||||
/**
|
||||
* Configure authentication when needed
|
||||
*/
|
||||
if (!empty((string)$mdl->auth->password)) {
|
||||
$fhandle = fopen($authd_pass, 'a+');
|
||||
if (flock($fhandle, LOCK_EX)) {
|
||||
chown($authd_pass, 'root');
|
||||
chgrp($authd_pass, 'wazuh');
|
||||
chmod($authd_pass, 0640);
|
||||
fseek($fhandle, 0);
|
||||
ftruncate($fhandle, 0);
|
||||
fwrite($fhandle, (string)$mdl->auth->password);
|
||||
flock($fhandle, LOCK_UN);
|
||||
}
|
||||
} elseif (file_exists($authd_pass)) {
|
||||
unlink($authd_pass);
|
||||
}
|
||||
|
||||
/***
|
||||
* Temporary solution to link log files so we can view at least the last items in the file easily for debug purposes
|
||||
* It looks like ossec is not able to log to syslog directly, which means our log files live outside our normal bounds
|
||||
**/
|
||||
mkdir("/var/log/wazuhagent/ossec/", 0700, true);
|
||||
mkdir("/var/log/wazuhagent/activeresponses/", 0700, true);
|
||||
@symlink("/var/ossec/logs/ossec.log", "/var/log/wazuhagent/ossec/ossec_99991231.log");
|
||||
@symlink( "/var/ossec/logs/active-responses.log", "/var/log/wazuhagent/activeresponses/activeresponses_99991231.log");
|
||||
@@ -0,0 +1,25 @@
|
||||
[start]
|
||||
command:
|
||||
/usr/local/sbin/pluginctl -s syslog-ng restart;
|
||||
/usr/local/etc/rc.d/wazuh-agent onestart
|
||||
type:script
|
||||
message:starting wazuh-agent
|
||||
|
||||
[stop]
|
||||
command:/usr/local/etc/rc.d/wazuh-agent onestop
|
||||
type:script
|
||||
message:stopping wazuh-agent
|
||||
|
||||
[status]
|
||||
command:
|
||||
/usr/local/etc/rc.d/wazuh-agent status > /dev/null 2>&1 && echo "wazuh is running..." || echo "wazuh is not running...";
|
||||
exit 0
|
||||
type:script_output
|
||||
message:get wazuh-agent status
|
||||
|
||||
[restart]
|
||||
command:
|
||||
/usr/local/sbin/pluginctl -s syslog-ng restart;
|
||||
/usr/local/etc/rc.d/wazuh-agent onerestart
|
||||
type:script
|
||||
message:restarting wazuh-agent
|
||||
@@ -0,0 +1,6 @@
|
||||
ossec.conf:/var/ossec/etc/ossec.conf
|
||||
local_internal_options.conf:/var/ossec/etc/local_internal_options.conf
|
||||
rc.conf.d:/etc/rc.conf.d/wazuh_agent
|
||||
syslog-ng-wazuh-agent.conf:/usr/local/etc/syslog-ng.conf.d/syslog-ng-wazuh-agent.conf
|
||||
newsyslog.conf:/etc/newsyslog.conf.d/wazuh-agent.conf
|
||||
opnsense-fw.conf:/var/ossec/etc/opnsense-fw.conf
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user