security/crowdsec 1.0.8 (#3959)

This commit is contained in:
mmetc
2024-05-03 10:20:28 +02:00
committed by GitHub
parent 15ddd7ba9e
commit da53031f7f
16 changed files with 73 additions and 172 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
PLUGIN_NAME= crowdsec
PLUGIN_VERSION= 1.0.7
PLUGIN_VERSION= 1.0.8
PLUGIN_DEPENDS= crowdsec
PLUGIN_COMMENT= Lightweight and collaborative security engine
PLUGIN_MAINTAINER= marco@crowdsec.net
+8
View File
@@ -8,6 +8,14 @@ WWW: https://crowdsec.net/
Plugin Changelog
================
1.0.8
* Enable use_wal, remove warning
* Randomize cron execution over 5 minutes
* Refactor javascript
* Fix initial service start with no pending hub updates (1.6.1)
* Add input validation for `rules_tag` to prevent invalid `pf` syntax.
1.0.7
* Add option `retry_initial_connect` to bouncer configuration for more robust startup. The option was introduced in Crowdsec 1.5.4.
@@ -6,4 +6,4 @@
SHELL=/bin/sh
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
#minute hour mday month wday who command
0 1 * * * root (sleep $(jot -r 1 1 60); /usr/local/opnsense/scripts/OPNsense/CrowdSec/hub-upgrade.sh)
0 1 * * * root (sleep $(jot -r 1 1 300); /usr/local/opnsense/scripts/OPNsense/CrowdSec/hub-upgrade.sh)
@@ -1,33 +0,0 @@
<?php
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: © 2021 CrowdSec <info@crowdsec.net>
namespace OPNsense\CrowdSec\Api;
use OPNsense\Base\ApiControllerBase;
use OPNsense\CrowdSec\CrowdSec;
use OPNsense\Core\Backend;
/**
* @package OPNsense\CrowdSec
*/
class CollectionsController extends ApiControllerBase
{
/**
* retrieve list of collections
* @return array of collections
* @throws \OPNsense\Base\ModelException
* @throws \ReflectionException
*/
public function getAction()
{
$backend = new Backend();
$bckresult = json_decode(trim($backend->configdRun("crowdsec collections-list")), true);
if ($bckresult !== null) {
// only return valid json type responses
return $bckresult;
}
return array("message" => "unable to list collections");
}
}
@@ -12,22 +12,22 @@ use OPNsense\Core\Backend;
/**
* @package OPNsense\CrowdSec
*/
class ParsersController extends ApiControllerBase
class HubController extends ApiControllerBase
{
/**
* retrieve list of registered parsers
* @return array of parsers
* retrieve the registered hub items
* @return dictionary of items, by type
* @throws \OPNsense\Base\ModelException
* @throws \ReflectionException
*/
public function getAction()
{
$backend = new Backend();
$bckresult = json_decode(trim($backend->configdRun("crowdsec parsers-list")), true);
$bckresult = json_decode(trim($backend->configdRun("crowdsec hub-items")), true);
if ($bckresult !== null) {
// only return valid json type responses
return $bckresult;
}
return array("message" => "unable to list parsers");
return array("message" => "unable to list hub items");
}
}
@@ -1,33 +0,0 @@
<?php
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: © 2021 CrowdSec <info@crowdsec.net>
namespace OPNsense\CrowdSec\Api;
use OPNsense\Base\ApiControllerBase;
use OPNsense\CrowdSec\CrowdSec;
use OPNsense\Core\Backend;
/**
* @package OPNsense\CrowdSec
*/
class PostoverflowsController extends ApiControllerBase
{
/**
* retrieve list of registered postoverflows
* @return array of postoverflows
* @throws \OPNsense\Base\ModelException
* @throws \ReflectionException
*/
public function getAction()
{
$backend = new Backend();
$bckresult = json_decode(trim($backend->configdRun("crowdsec postoverflows-list")), true);
if ($bckresult !== null) {
// only return valid json type responses
return $bckresult;
}
return array("message" => "unable to list postoverflows");
}
}
@@ -1,33 +0,0 @@
<?php
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: © 2021 CrowdSec <info@crowdsec.net>
namespace OPNsense\CrowdSec\Api;
use OPNsense\Base\ApiControllerBase;
use OPNsense\CrowdSec\CrowdSec;
use OPNsense\Core\Backend;
/**
* @package OPNsense\CrowdSec
*/
class ScenariosController extends ApiControllerBase
{
/**
* retrieve list of registered scenarios
* @return array of scenarios
* @throws \OPNsense\Base\ModelException
* @throws \ReflectionException
*/
public function getAction()
{
$backend = new Backend();
$bckresult = json_decode(trim($backend->configdRun("crowdsec scenarios-list")), true);
if ($bckresult !== null) {
// only return valid json type responses
return $bckresult;
}
return array("message" => "unable to list scenarios");
}
}
@@ -3,7 +3,7 @@
<!-- agent_enabled -->
<field>
<id>general.agent_enabled</id>
<label>Enable CrowdSec (IDS)</label>
<label>Enable Log Processor (IDS)</label>
<type>checkbox</type>
<help>Enable/disable the CrowdSec agent. Keep this enabled to detect
attacks and receive alerts from the CrowSec central service.</help>
@@ -21,9 +21,9 @@
<!-- firewall_bouncer_enabled -->
<field>
<id>general.firewall_bouncer_enabled</id>
<label>Enable Firewall Bouncer (IPS)</label>
<label>Enable Remediation Component (IPS)</label>
<type>checkbox</type>
<help>Enable/disable the firewall bouncer. Keep this enabled to block
<help>Enable/disable the remediation component. Keep this enabled to block
packets from the attacking IP addresses.</help>
</field>
@@ -1,7 +1,7 @@
<model>
<mount>//OPNsense/crowdsec/general</mount>
<description>CrowdSec general configuration</description>
<version>1.0.6</version>
<version>1.0.8</version>
<items>
<agent_enabled type="BooleanField">
@@ -43,8 +43,8 @@
</rules_log>
<rules_tag type="TextField">
<default></default>
<Required>N</Required>
<Mask>/^([0-9a-zA-Z]{1,63})$/u</Mask>
<ValidationMessage>A tag must only contain numbers and letters and must be between 1 and 63 characters.</ValidationMessage>
</rules_tag>
<crowdsec_firewall_verbose type="BooleanField">
@@ -71,7 +71,7 @@
the possibilities.</p>
<p>For the latest plugin documentation, including how to use it with an external LAPI, see <a
href="https://docs.crowdsec.net/docs/next/getting_started/install_crowdsec_opnsense">Install
href="https://docs.crowdsec.net/u/getting_started/installation/opnsense">Install
CrowdSec (OPNsense)</a></p>
<p>A few remarks:</p>
@@ -79,7 +79,7 @@
<ul>
<li>
New acquisition files go under <code>/usr/local/etc/crowdsec/acquis.d</code>. See opnsense.yaml for details.
The option <code>poll_without_inotify: true</code> is required if the acquitision targets are symlinks (which
The option <code>poll_without_inotify: true</code> is required if the log sources are symlinks (which
is the case for most opnsense logs).
</li>
<li>
@@ -91,7 +91,7 @@
At the moment, the CrowdSec package for OPNsense is fully functional on the
command line but its web interface is limited; you can only list the installed objects and revoke
<a href="https://docs.crowdsec.net/docs/user_guides/decisions_mgmt/">decisions</a>. For anything else
you need the shell.
you need the shell or the <a href="https://app.crowdsec.net">CrowdSec Console</a>.
</li>
<li>
Do not enable/start the agent and bouncer services with <code>sysrc</code> or <code>/etc/rc.conf</code>
@@ -54,7 +54,7 @@ ul.nav>li>a {
<table class="table table-condensed table-hover table-striped">
<thead>
<tr>
<th data-column-id="name">Name</th>
<th data-column-id="name" data-order="asc">Name</th>
<th data-column-id="ip_address">IP Address</th>
<th data-column-id="last_update" data-formatter="datetime">Last Update</th>
<th data-column-id="validated" data-formatter="yesno" data-searchable="false">Validated?</th>
@@ -74,7 +74,7 @@ ul.nav>li>a {
<table class="table table-condensed table-hover table-striped">
<thead>
<tr>
<th data-column-id="name">Name</th>
<th data-column-id="name" data-order="asc">Name</th>
<th data-column-id="ip_address">IP Address</th>
<th data-column-id="valid" data-formatter="yesno" data-searchable="false">Valid</th>
<th data-column-id="last_pull" data-formatter="datetime">Last API Pull</th>
@@ -95,10 +95,11 @@ ul.nav>li>a {
<table class="table table-condensed table-hover table-striped">
<thead>
<tr>
<th data-column-id="name">Name</th>
<th data-column-id="name" data-order="asc">Collection</th>
<th data-column-id="status">Status</th>
<th data-column-id="local_version">Version</th>
<th data-column-id="local_path">Local Path</th>
<th data-visible="false" data-column-id="local_path">Path</th>
<th data-column-id="description">Description</th>
</tr>
</thead>
<tbody>
@@ -114,10 +115,10 @@ ul.nav>li>a {
<table class="table table-condensed table-hover table-striped">
<thead>
<tr>
<th data-column-id="name">Name</th>
<th data-column-id="name" data-order="asc">Scenario</th>
<th data-column-id="status">Status</th>
<th data-column-id="local_version">Version</th>
<th data-column-id="local_path">Path</th>
<th data-visible="false" data-column-id="local_path">Path</th>
<th data-column-id="description">Description</th>
</tr>
</thead>
@@ -134,10 +135,10 @@ ul.nav>li>a {
<table class="table table-condensed table-hover table-striped">
<thead>
<tr>
<th data-column-id="name">Name</th>
<th data-column-id="name" data-order="asc">Parser</th>
<th data-column-id="status">Status</th>
<th data-column-id="local_version">Version</th>
<th data-column-id="local_path">Local Path</th>
<th data-visible="false" data-column-id="local_path">Path</th>
<th data-column-id="description">Description</th>
</tr>
</thead>
@@ -154,10 +155,10 @@ ul.nav>li>a {
<table class="table table-condensed table-hover table-striped">
<thead>
<tr>
<th data-column-id="name">Name</th>
<th data-column-id="name" data-order="asc">Postoverflow</th>
<th data-column-id="status">Status</th>
<th data-column-id="local_version">Version</th>
<th data-column-id="local_path">Local Path</th>
<th data-visible="false" data-column-id="local_path">Path</th>
<th data-column-id="description">Description</th>
</tr>
</thead>
@@ -174,7 +175,7 @@ ul.nav>li>a {
<table class="table table-condensed table-hover table-striped">
<thead>
<tr>
<th data-column-id="id" data-type="numeric">ID</th>
<th data-column-id="id" data-type="numeric" data-order="asc">ID</th>
<th data-column-id="value">Value</th>
<th data-column-id="reason">Reason</th>
<th data-column-id="country">Country</th>
@@ -198,17 +199,19 @@ ul.nav>li>a {
<table class="table table-condensed table-hover table-striped">
<thead>
<tr>
<th data-column-id="delete" data-formatter="delete" data-visible-in-selection="false"></th>
<th data-column-id="id" data-identifier="true" data-type="numeric">ID</th>
<th data-column-id="source">Source</th>
<th data-column-id="delete" data-formatter="delete"
data-visible-in-selection="false"></th>
<th data-column-id="id" data-visible="false" data-identifier="true" data-type="numeric"
data-order="asc">ID</th>
<th data-visible="false" data-column-id="source">Source</th>
<th data-column-id="scope_value">Scope:Value</th>
<th data-column-id="reason">Reason</th>
<th data-column-id="action">Action</th>
<th data-visible="false" data-column-id="action">Action</th>
<th data-column-id="country">Country</th>
<th data-column-id="as">AS</th>
<th data-column-id="events_count" data-type="numeric">Events</th>
<th data-column-id="expiration" data-formatter="duration">Expiration</th>
<th data-column-id="alert_id" data-type="numeric">Alert&nbsp;ID</th>
<th data-visible="false" data-column-id="alert_id" data-type="numeric">Alert&nbsp;ID</th>
</tr>
</thead>
<tbody>
@@ -10,11 +10,11 @@ if [ ! -e "/usr/local/etc/crowdsec/collections/opnsense.yaml" ]; then
/usr/local/bin/cscli --error collections install crowdsecurity/opnsense
fi
if [ -n "$upgraded" ]; then
if service crowdsec enabled; then
if ! service crowdsec status >/dev/null 2>&1; then
service crowdsec start >/dev/null 2>&1 || :
else
if service crowdsec enabled; then
if ! service crowdsec status >/dev/null 2>&1; then
service crowdsec start >/dev/null 2>&1 || :
else
if [ -n "$upgraded" ]; then
service crowdsec reload >/dev/null 2>&1 || :
fi
fi
@@ -45,6 +45,7 @@ def configure_agent(settings):
config['common']['log_dir'] = '/var/log/crowdsec'
config['crowdsec_service']['acquisition_dir'] = '/usr/local/etc/crowdsec/acquis.d/'
config['db_config']['use_wal'] = True
if not int(settings.get('lapi_manual_configuration', '0')):
config['api']['server']['listen_uri'] = get_netloc(settings)
@@ -10,7 +10,6 @@ set -e
# apply configuration options specific to opnsense
/usr/local/opnsense/scripts/OPNsense/CrowdSec/reconfigure.py
# enable pf anchor here - the tables and rules will be created by the bouncer
/usr/local/sbin/configctl filter reload >/dev/null
# the hub is upgraded by cron too
@@ -19,7 +19,7 @@ message: oscrowdsec status
[restart]
command:/usr/local/etc/rc.d/oscrowdsec restart
type: script
message: stopping crowdsec services
message: restarting crowdsec services
[reload]
command:/usr/local/etc/rc.d/oscrowdsec reload
@@ -37,22 +37,17 @@ type:script_output
message: request crowdsec_firewall status
[alerts-list]
command:/usr/local/bin/cscli alerts list -l 0 -o json | sed 's/^null$/\[\]/'
command:/usr/local/bin/cscli alerts list -l 0 -o json
type:script_output
message:crowdsec alerts list
[bouncers-list]
command:/usr/local/bin/cscli bouncers list -o json | sed 's/^null$/\[\]/'
command:/usr/local/bin/cscli bouncers list -o json
type:script_output
message:crowdsec bouncers list
[collections-list]
command:/usr/local/bin/cscli collections list -o json
type:script_output
message:crowdsec collections list
[decisions-list]
command:/usr/local/bin/cscli decisions list -l 0 -o json | sed 's/^null$/\[\]/'
command:/usr/local/bin/cscli decisions list -l 0 -o json
type:script_output
message:crowdsec decisions list
@@ -62,26 +57,16 @@ parameters:--id %s
type:script_output
message:crowdsec decisions delete
[hub-items]
command:/usr/local/bin/cscli hub list -o json
type:script_output
message:crowdsec hub list
[machines-list]
command:/usr/local/bin/cscli machines list -o json | sed 's/^null$/\[\]/'
command:/usr/local/bin/cscli machines list -o json
type:script_output
message:crowdsec machines list
[parsers-list]
command:/usr/local/bin/cscli parsers list -o json
type:script_output
message:crowdsec parsers list
[postoverflows-list]
command:/usr/local/bin/cscli postoverflows list -o json
type:script_output
message:crowdsec postoverflows list
[scenarios-list]
command:/usr/local/bin/cscli scenarios list -o json
type:script_output
message:crowdsec scenarios list
[version]
command:/usr/local/bin/cscli version 2>&1
type:script_output
@@ -6,6 +6,7 @@
var CrowdSec = (function () {
'use strict';
var crowdsec_path = '/usr/local/etc/crowdsec/';
var _refreshTemplate = '<button class="btn btn-default" type="button" title="Refresh"><span class="icon glyphicon glyphicon-refresh"></span></button>';
var _dataFormatters = {
@@ -87,8 +88,9 @@ var CrowdSec = (function () {
timestamp = $freshness.data('refresh_timestamp');
}
var howlongHuman = '???';
var howlongms;
if (timestamp) {
var howlongms = moment() - moment(timestamp);
howlongms = moment() - moment(timestamp);
howlongHuman = moment.duration(howlongms).humanize();
}
$freshness.text(howlongHuman + ' ago');
@@ -129,7 +131,8 @@ var CrowdSec = (function () {
dectypes[decision.type] = dectypes[decision.type] ? (dectypes[decision.type] + 1) : 1;
});
var ret = '';
for (var type in dectypes) {
var type;
for (type in dectypes) {
if (ret !== '') {
ret += ' ';
}
@@ -217,7 +220,7 @@ var CrowdSec = (function () {
}
function _initCollections () {
var url = '/api/crowdsec/collections/get';
var url = '/api/crowdsec/hub/get';
var dataCallback = function (data) {
var rows = [];
data.collections.map(function (row) {
@@ -225,7 +228,8 @@ var CrowdSec = (function () {
name: row.name,
status: row.status,
local_version: row.local_version || ' ',
local_path: row.local_path || ' '
local_path: row.local_path ? row.local_path.replace(crowdsec_path, '') : ' ',
description: row.description || ' '
});
});
$('#collections table').bootgrid('clear').bootgrid('append', rows);
@@ -234,7 +238,7 @@ var CrowdSec = (function () {
}
function _initScenarios () {
var url = '/api/crowdsec/scenarios/get';
var url = '/api/crowdsec/hub/get';
var dataCallback = function (data) {
var rows = [];
data.scenarios.map(function (row) {
@@ -242,7 +246,7 @@ var CrowdSec = (function () {
name: row.name,
status: row.status,
local_version: row.local_version || ' ',
local_path: row.local_path || ' ',
local_path: row.local_path ? row.local_path.replace(crowdsec_path, '') : ' ',
description: row.description || ' '
});
});
@@ -252,7 +256,7 @@ var CrowdSec = (function () {
}
function _initParsers () {
var url = '/api/crowdsec/parsers/get';
var url = '/api/crowdsec/hub/get';
var dataCallback = function (data) {
var rows = [];
data.parsers.map(function (row) {
@@ -260,7 +264,7 @@ var CrowdSec = (function () {
name: row.name,
status: row.status,
local_version: row.local_version || ' ',
local_path: row.local_path || ' ',
local_path: row.local_path ? row.local_path.replace(crowdsec_path, '') : ' ',
description: row.description || ' '
});
});
@@ -270,7 +274,7 @@ var CrowdSec = (function () {
}
function _initPostoverflows () {
var url = '/api/crowdsec/postoverflows/get';
var url = '/api/crowdsec/hub/get';
var dataCallback = function (data) {
var rows = [];
data.postoverflows.map(function (row) {
@@ -278,7 +282,7 @@ var CrowdSec = (function () {
name: row.name,
status: row.status,
local_version: row.local_version || ' ',
local_path: row.local_path || ' ',
local_path: row.local_path ? row.local_path.replace(crowdsec_path, '') : ' ',
description: row.description || ' '
});
});