mirror of
https://github.com/ntop/ntopng.git
synced 2026-05-06 03:45:26 +00:00
Implements flow callbacks and alerts in C++
This commit is contained in:
parent
3659188002
commit
aea9138bfb
353 changed files with 10790 additions and 4455 deletions
|
|
@ -802,13 +802,13 @@ else
|
|||
print("</tr>")
|
||||
end
|
||||
|
||||
local status_info = flow2statusinfo(flow)
|
||||
local alert_info = flow2alertinfo(flow)
|
||||
local forbidden_proto = flow["proto.ndpi_id"]
|
||||
local forbidden_peer = nil
|
||||
|
||||
if status_info then
|
||||
forbidden_proto = status_info["devproto_forbidden_id"] or forbidden_proto
|
||||
forbidden_peer = status_info["devproto_forbidden_peer"]
|
||||
if alert_info then
|
||||
forbidden_proto = alert_info["devproto_forbidden_id"] or forbidden_proto
|
||||
forbidden_peer = alert_info["devproto_forbidden_peer"]
|
||||
end
|
||||
|
||||
local cli_mac = flow["cli.mac"] and interface.getMacInfo(flow["cli.mac"])
|
||||
|
|
@ -1245,19 +1245,10 @@ else
|
|||
|
||||
-- ######################################
|
||||
|
||||
local alerted_status = nil
|
||||
|
||||
if flow["flow.alerted"] then
|
||||
alerted_status = flow["alerted_status"]
|
||||
local flow_alert = interface.flowAlertByKeyAndHashId(tonumber(flow_key), tonumber(flow_hash_id)) -- new API
|
||||
local message = alert_consts.alertTypeLabel(flow["predominant_alert"])
|
||||
|
||||
if flow_alert then
|
||||
flow_alert = json.decode(flow_alert)
|
||||
end
|
||||
|
||||
local message = alert_utils.formatAlertMessage(ifid, flow_alert, json.decode(flow_alert["alert_json"]), true --[[ skip live data, we're already in the live flow page --]])
|
||||
|
||||
message = message .. string.format(" [%s: %d]", i18n("score"), flow["alerted_status_score"])
|
||||
message = message .. string.format(" [%s: %d]", i18n("score"), flow["predominant_alert_score"])
|
||||
|
||||
print("<tr><th width=30%>"..i18n("flow_details.flow_alerted").."</th><td colspan=2>")
|
||||
print(message)
|
||||
|
|
@ -1265,17 +1256,17 @@ else
|
|||
end
|
||||
|
||||
-- Print additional flow statuses
|
||||
if flow["status_map"] then
|
||||
if flow["alert_map"] then
|
||||
local first = true
|
||||
local num_statuses = 0
|
||||
|
||||
for _, t in pairsByKeys(alert_consts.alert_types) do
|
||||
if t.meta and t.meta.status_key then
|
||||
local id = t.meta.status_key
|
||||
if t.meta and t.meta.alert_key then
|
||||
local id = t.meta.alert_key
|
||||
|
||||
if id ~= flow["alerted_status"] and flow["status_map"][id] then
|
||||
if id ~= flow["predominant_alert"] and flow["alert_map"][id] then
|
||||
if first then
|
||||
print("<tr><th width=30%>"..i18n("flow_details.additional_flow_status").."</th><td colspan=2>")
|
||||
print("<tr><th width=30%>"..i18n("flow_details.additional_alert_type").."</th><td colspan=2>")
|
||||
first = false
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ local inIfIdx = _GET["inIfIdx"]
|
|||
local outIfIdx = _GET["outIfIdx"]
|
||||
|
||||
local traffic_type = _GET["traffic_type"]
|
||||
local flow_status = _GET["flow_status"]
|
||||
local flow_status_severity = _GET["flow_status_severity"]
|
||||
local alert_type = _GET["alert_type"]
|
||||
local alert_type_severity = _GET["alert_type_severity"]
|
||||
local tcp_state = _GET["tcp_flow_state"]
|
||||
local port = _GET["port"]
|
||||
local network_id = _GET["network"]
|
||||
|
|
@ -135,12 +135,12 @@ if(traffic_type ~= nil) then
|
|||
page_params["traffic_type"] = traffic_type
|
||||
end
|
||||
|
||||
if(flow_status ~= nil) then
|
||||
page_params["flow_status"] = flow_status
|
||||
if(alert_type ~= nil) then
|
||||
page_params["alert_type"] = alert_type
|
||||
end
|
||||
|
||||
if(flow_status_severity ~= nil) then
|
||||
page_params["flow_status_severity"] = flow_status_severity
|
||||
if(alert_type_severity ~= nil) then
|
||||
page_params["alert_type_severity"] = alert_type_severity
|
||||
end
|
||||
|
||||
if(tcp_state ~= nil) then
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ local alerts_api = require "alerts_api"
|
|||
local alert_consts = require "alert_consts"
|
||||
local recording_utils = require "recording_utils"
|
||||
local user_scripts = require "user_scripts"
|
||||
local alert_exclusions = require "alert_exclusions"
|
||||
|
||||
sendHTTPHeader('application/json')
|
||||
|
||||
|
|
@ -121,6 +122,7 @@ for k,v in ipairs(alerts) do
|
|||
|
||||
local column_severity = alert_consts.alertSeverityLabel(tonumber(v["alert_severity"]))
|
||||
local column_type = alert_consts.alertTypeLabel(tonumber(v["alert_type"]))
|
||||
local column_type_str = alert_consts.alertTypeLabel(tonumber(v["alert_type"]), true)
|
||||
local column_count = format_utils.formatValue(tonumber(v["alert_counter"]))
|
||||
local column_score = format_utils.formatValue(tonumber(v["score"]))
|
||||
local alert_info = alert_utils.getAlertInfo(v)
|
||||
|
|
@ -196,6 +198,7 @@ for k,v in ipairs(alerts) do
|
|||
record["column_count"] = column_count
|
||||
record["column_score"] = column_score
|
||||
record["column_type"] = column_type
|
||||
record["column_type_str"] = column_type_str
|
||||
record["column_type_id"] = tonumber(v["alert_type"])
|
||||
record["column_msg"] = column_msg
|
||||
record["column_entity_id"] = alert_entity
|
||||
|
|
@ -209,10 +212,11 @@ for k,v in ipairs(alerts) do
|
|||
record["column_subdir"] = alert_info.alert_generation.subdir or nil
|
||||
|
||||
-- Checking if the filter column needs to be skipped
|
||||
if user_scripts.excludeScriptFilters(alert, alert_info, record["column_script_key"], record["column_subdir"]) == false then
|
||||
record["column_filter"] = user_scripts.getFilterPreset(alert, alert_info)
|
||||
elseif record["column_subdir"] == "flow" then
|
||||
record["column_filter_disabled"] = true
|
||||
if record["column_subdir"] == "flow" then
|
||||
-- Enabled, show the bell to disable
|
||||
record["column_filter"] = v["cli_addr"].."|"..v["srv_addr"]
|
||||
else
|
||||
record["column_filter"] = user_scripts.getFilterPreset(alert, alert_info)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -266,9 +266,9 @@ for _key, value in ipairs(flows_stats) do -- pairsByValues(vals, funct) do
|
|||
end
|
||||
|
||||
local column_proto_l4 = ''
|
||||
if value["alerted_status"] then
|
||||
local status_info = alert_consts.statusTypeLabel(value["alerted_status"], true)
|
||||
column_proto_l4 = alert_consts.statusTypeIcon(value["alerted_status"], value["alerted_severity"]) -- "<i class='fas fa-exclamation-triangle' style=' title='"..noHtml(status_info) .."'></i> "
|
||||
if value["predominant_alert"] then
|
||||
local alert_info = alert_consts.alertTypeLabel(value["predominant_alert"], true)
|
||||
column_proto_l4 = alert_consts.alertTypeIcon(value["predominant_alert"], value["alerted_severity"]) -- "<i class='fas fa-exclamation-triangle' style=' title='"..noHtml(alert_info) .."'></i> "
|
||||
end
|
||||
|
||||
column_proto_l4 = column_proto_l4..value["proto.l4"]
|
||||
|
|
|
|||
|
|
@ -631,21 +631,25 @@ if isScoreEnabled() then
|
|||
print("<tr><th rowspan=2>"..i18n("score").." " .. score_chart .."</th>")
|
||||
print("<th>"..i18n("host_details.client_score").."</th><th>"..i18n("host_details.server_score").."</th></tr>")
|
||||
|
||||
local c = host.score_pct["score_breakdown_client"]
|
||||
local s = host.score_pct["score_breakdown_server"]
|
||||
local c = host.score_pct and host.score_pct["score_breakdown_client"]
|
||||
local s = host.score_pct and host.score_pct["score_breakdown_server"]
|
||||
|
||||
print("<tr>")
|
||||
print("<td>")
|
||||
print("<div class='d-flex align-items-center'>")
|
||||
print("<span id='score_as_client'>".. host["score.as_client"] .."</span> <span class='ml-1' id='client_score_trend'></span>")
|
||||
scoreBreakdown(c)
|
||||
print("<span id='score_as_client'>".. (host["score.as_client"] or 0) .."</span> <span class='ml-1' id='client_score_trend'></span>")
|
||||
if c then
|
||||
scoreBreakdown(c)
|
||||
end
|
||||
print("</div>")
|
||||
print("</td>")
|
||||
|
||||
print("<td>")
|
||||
print("<div class='d-flex align-items-center'>")
|
||||
print("<span id='score_as_server'>".. host["score.as_server"] .."</span><span class='ml-1' id='server_score_trend'></span>")
|
||||
scoreBreakdown(s)
|
||||
print("<span id='score_as_server'>".. (host["score.as_server"] or 0).."</span><span class='ml-1' id='server_score_trend'></span>")
|
||||
if s then
|
||||
scoreBreakdown(s)
|
||||
end
|
||||
print("</div>")
|
||||
print("</td>")
|
||||
|
||||
|
|
@ -736,7 +740,7 @@ end
|
|||
|
||||
|
||||
if(host["active_alerted_flows"] > 0) then
|
||||
print("<tr><th>"..i18n("host_details.active_alerted_flows").."</th><td colspan=2></li>"..hostinfo2detailshref(host, {page = "flows", flow_status = "alerted"}, "<span id=num_flow_alerts>"..host["active_alerted_flows"] .. "</span>").." <span id=flow_alerts_trend></span></td></tr>\n")
|
||||
print("<tr><th>"..i18n("host_details.active_alerted_flows").."</th><td colspan=2></li>"..hostinfo2detailshref(host, {page = "flows", alert_type = "alerted"}, "<span id=num_flow_alerts>"..host["active_alerted_flows"] .. "</span>").." <span id=flow_alerts_trend></span></td></tr>\n")
|
||||
end
|
||||
|
||||
if ntop.isPro() and ifstats.inline and (host["has_blocking_quota"] or host["has_blocking_shaper"]) then
|
||||
|
|
@ -782,7 +786,7 @@ end
|
|||
end
|
||||
|
||||
if interfaceHasNindexSupport() then
|
||||
flows_th = flows_th .. ' <a class="btn btn-sm btn-info" href="?host='..hostinfo2hostkey(host_info)..'&page=historical&detail_view=flows&zoom=1h&flow_status=alerted"><i class="fas fa-search-plus"></i></a>'
|
||||
flows_th = flows_th .. ' <a class="btn btn-sm btn-info" href="?host='..hostinfo2hostkey(host_info)..'&page=historical&detail_view=flows&zoom=1h&alert_type=alerted"><i class="fas fa-search-plus"></i></a>'
|
||||
end
|
||||
|
||||
print("<tr><th></th><th>"..i18n("details.as_client").."</th><th>"..i18n("details.as_server").."</th></tr>\n")
|
||||
|
|
@ -1717,7 +1721,7 @@ print [[
|
|||
local page_params = {
|
||||
application = _GET["application"],
|
||||
category = _GET["category"],
|
||||
flow_status = _GET["flow_status"],
|
||||
alert_type = _GET["alert_type"],
|
||||
tcp_flow_state = _GET["tcp_flow_state"],
|
||||
flowhosts_type = _GET["flowhosts_type"],
|
||||
traffic_type = _GET["traffic_type"],
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ local inIfIdx = _GET["inIfIdx"]
|
|||
local outIfIdx = _GET["outIfIdx"]
|
||||
|
||||
local traffic_type = _GET["traffic_type"]
|
||||
local flow_status = _GET["flow_status"]
|
||||
local alert_type = _GET["alert_type"]
|
||||
local tcp_state = _GET["tcp_flow_state"]
|
||||
local port = _GET["port"]
|
||||
local container = _GET["container"]
|
||||
|
|
@ -115,8 +115,8 @@ if(traffic_type ~= nil) then
|
|||
page_params["traffic_type"] = traffic_type
|
||||
end
|
||||
|
||||
if(flow_status ~= nil) then
|
||||
page_params["flow_status"] = flow_status
|
||||
if(alert_type ~= nil) then
|
||||
page_params["alert_type"] = alert_type
|
||||
end
|
||||
|
||||
if(tcp_state ~= nil) then
|
||||
|
|
|
|||
|
|
@ -383,12 +383,12 @@ print[[
|
|||
}
|
||||
|
||||
if(rsp.alerted_flows_warning > 0 && !(systemInterfaceEnabled)) {
|
||||
msg += "<a href=\"]] print (ntop.getHttpPrefix()) print [[/lua/flows_stats.lua?flow_status_severity=warning\">"
|
||||
msg += "<a href=\"]] print (ntop.getHttpPrefix()) print [[/lua/flows_stats.lua?alert_type_severity=warning\">"
|
||||
msg += "<span class=\"badge badge-warning\">"+NtopUtils.addCommas(rsp.alerted_flows_warning)+ " <i class=\"fas fa-stream\"></i> ]] print[[ <i class=\"fas fa-exclamation-triangle\"></i></span></a>";
|
||||
}
|
||||
|
||||
if(rsp.alerted_flows_error > 0 && !(systemInterfaceEnabled)) {
|
||||
msg += "<a href=\"]] print (ntop.getHttpPrefix()) print [[/lua/flows_stats.lua?flow_status_severity=error_or_higher\">"
|
||||
msg += "<a href=\"]] print (ntop.getHttpPrefix()) print [[/lua/flows_stats.lua?alert_type_severity=error_or_higher\">"
|
||||
msg += "<span class=\"badge badge-danger\">"+NtopUtils.addCommas(rsp.alerted_flows_error)+ " <i class=\"fas fa-stream\"></i> ]] print[[ <i class=\"fas fa-exclamation-triangle\"></i></span></a>";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,10 +51,10 @@ end
|
|||
|
||||
-- ##############################################
|
||||
|
||||
function Alert:_build_flow_status_info()
|
||||
local flow_status_info = {
|
||||
-- TODO: remove when alerts triggered from C++
|
||||
function Alert:_build_alert_type_info()
|
||||
local alert_type_info = {
|
||||
status_type = {
|
||||
status_key = self.meta.status_key,
|
||||
alert_type = self.meta,
|
||||
},
|
||||
alert_severity = self.alert_severity,
|
||||
|
|
@ -63,14 +63,14 @@ function Alert:_build_flow_status_info()
|
|||
}
|
||||
|
||||
if self.alert_attacker ~= nil then
|
||||
flow_status_info.alert_type_params.alert_attacker = self.alert_attacker
|
||||
alert_type_info.alert_type_params.alert_attacker = self.alert_attacker
|
||||
end
|
||||
|
||||
if self.alert_victim ~= nil then
|
||||
flow_status_info.alert_type_params.alert_victim = self.alert_victim
|
||||
alert_type_info.alert_type_params.alert_victim = self.alert_victim
|
||||
end
|
||||
|
||||
return flow_status_info
|
||||
return alert_type_info
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
|
@ -95,22 +95,6 @@ end
|
|||
|
||||
-- ##############################################
|
||||
|
||||
function Alert:trigger_status(cli_score, srv_score, flow_score)
|
||||
local alerts_api = require "alerts_api"
|
||||
|
||||
if not self.meta.status_key then
|
||||
traceError(TRACE_ERROR, TRACE_CONSOLE, "alert.alert_error.configuration.no_status_key")
|
||||
end
|
||||
|
||||
if not self._check_alert_data() then
|
||||
return
|
||||
end
|
||||
|
||||
alerts_api.trigger_status(self:_build_flow_status_info(), self.alert_severity, cli_score, srv_score, flow_score)
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
function Alert:trigger(entity_info, when, cur_alerts)
|
||||
local alerts_api = require "alerts_api"
|
||||
|
||||
|
|
|
|||
|
|
@ -333,7 +333,6 @@ end
|
|||
-- See alert_consts.resetDefinitions()
|
||||
alert_consts.alert_types = {}
|
||||
local alerts_by_id = {} -- All available alerts keyed by alert id
|
||||
local alerts_by_flow_status_id = {} -- All available FLOW alerts keyed by flow status id
|
||||
|
||||
local function loadAlertsDefs()
|
||||
if(false) then
|
||||
|
|
@ -399,36 +398,27 @@ function alert_consts.loadDefinition(def_script, mod_fname, script_path)
|
|||
|
||||
-- Check the required metadata fields
|
||||
for _, k in pairs(required_fields) do
|
||||
if(def_script.meta[k] == nil) then
|
||||
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Missing required field '%s' in %s from %s", k, mod_fname, script_path))
|
||||
return(false)
|
||||
end
|
||||
if(def_script.meta[k] == nil) then
|
||||
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Missing required field '%s' in %s from %s", k, mod_fname, script_path))
|
||||
return(false)
|
||||
end
|
||||
end
|
||||
|
||||
-- Sanity check: make sure this is a valid alert key
|
||||
local parsed_alert_key, status = alert_keys.parse_alert_key(def_script.meta.alert_key)
|
||||
if not parsed_alert_key then
|
||||
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Invalid alert key specified %s in %s from %s", status, mod_fname, script_path))
|
||||
return(false)
|
||||
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Invalid alert key specified %s in %s from %s", status, mod_fname, script_path))
|
||||
return(false)
|
||||
end
|
||||
|
||||
|
||||
if(alerts_by_id[parsed_alert_key] ~= nil) then
|
||||
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Alert key %d redefined, skipping in %s from %s", parsed_alert_key, mod_fname, script_path))
|
||||
return(false)
|
||||
end
|
||||
|
||||
if def_script.meta.status_key and alerts_by_flow_status_id[def_script.meta.status_key] then
|
||||
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Status key %d redefined, skipping in %s from %s", def_script.meta.status_key, mod_fname, script_path))
|
||||
return(false)
|
||||
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Alert key %d redefined, skipping in %s from %s", parsed_alert_key, mod_fname, script_path))
|
||||
return(false)
|
||||
end
|
||||
|
||||
def_script.meta.alert_key = parsed_alert_key
|
||||
alert_consts.alert_types[mod_fname] = def_script
|
||||
alerts_by_id[parsed_alert_key] = mod_fname
|
||||
if def_script.meta.status_key then
|
||||
-- Add the module to the modules table keyd by flow status - if flow status is present for this alert
|
||||
alerts_by_flow_status_id[def_script.meta.status_key] = mod_fname
|
||||
end
|
||||
|
||||
-- Success
|
||||
return(true)
|
||||
|
|
@ -453,23 +443,6 @@ function alert_consts.alertTypeLabel(v, nohtml)
|
|||
|
||||
return(i18n("unknown"))
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Returns the label of an alert, given the flow status the alert is associated to
|
||||
function alert_consts.statusTypeLabel(flow_status_key, nohtml)
|
||||
if flow_status_key == 0 then
|
||||
return i18n("flows_page.normal")
|
||||
end
|
||||
|
||||
local alert_key = alert_consts.flowStatusTypeRaw(flow_status_key)
|
||||
|
||||
if alert_key then
|
||||
return alert_consts.alertTypeLabel(alert_consts.alertType(alert_key), nohtml)
|
||||
end
|
||||
|
||||
return i18n("unknown")
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
|
|
@ -477,12 +450,12 @@ end
|
|||
-- @param `status info`, A human readable (localized) status info
|
||||
-- @param `alerted_severity`, Integer severity of the alert associated to this status
|
||||
-- @return The HTML with icon and ALT text, or empty if no icon is available
|
||||
function alert_consts.statusTypeIcon(status_info, alerted_severity)
|
||||
function alert_consts.alertTypeIcon(alert_info, alerted_severity)
|
||||
local severity = alert_consts.alertSeverityById(alerted_severity)
|
||||
|
||||
if severity then
|
||||
local alert_consts = require "alert_consts"
|
||||
return "<i class='"..severity.icon.."' title='"..noHtml(alert_consts.statusTypeLabel(status_info, true)) .."'></i> "
|
||||
return "<i class='"..severity.icon.."' title='"..noHtml(alert_consts.alertTypeLabel(alert_info, true)) .."'></i> "
|
||||
end
|
||||
|
||||
return ""
|
||||
|
|
@ -570,13 +543,6 @@ function alert_consts.alertTypeRaw(type_id)
|
|||
return alerts_by_id[type_id]
|
||||
end
|
||||
|
||||
-- ################################################################################
|
||||
|
||||
function alert_consts.flowStatusTypeRaw(flow_status_type_id)
|
||||
flow_status_type_id = tonumber(flow_status_type_id)
|
||||
return alerts_by_flow_status_id[flow_status_type_id]
|
||||
end
|
||||
|
||||
-- ################################################################################
|
||||
|
||||
-- Rename engine -> granulariy
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@
|
|||
|
||||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
local status_keys = require "status_keys"
|
||||
local alert_keys = require "alert_keys"
|
||||
local alert_severities = require "alert_severities"
|
||||
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -20,12 +21,19 @@ local alert_blacklisted_country = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_blacklisted_country.meta = {
|
||||
status_key = status_keys.ntopng.status_blacklisted_country,
|
||||
alert_key = alert_keys.ntopng.alert_blacklisted_country,
|
||||
i18n_title = "alerts_dashboard.blacklisted_country",
|
||||
icon = "fas fa-exclamation",
|
||||
has_victim = true,
|
||||
has_attacker = true,
|
||||
|
||||
-- Default values
|
||||
default = {
|
||||
-- Default severity, must be one of `alert_severities` and can overridden from the UI
|
||||
severity = alert_severities.error,
|
||||
-- Fitlters to be applied on the alert, e.g., cli_port=23
|
||||
filters = {},
|
||||
}
|
||||
}
|
||||
|
||||
-- ##############################################
|
||||
|
|
@ -37,16 +45,9 @@ alert_blacklisted_country.meta = {
|
|||
-- @param cli_blacklisted Boolean indicating whether the client belongs to a blacklisted country
|
||||
-- @param srv_blacklisted Boolean indicating whether the server belongs to a blacklisted country
|
||||
-- @return A table with the alert built
|
||||
function alert_blacklisted_country:init(cli_country, srv_country, cli_blacklisted, srv_blacklisted)
|
||||
function alert_blacklisted_country:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
cli_country = cli_country,
|
||||
srv_country = srv_country,
|
||||
cli_blacklisted = cli_blacklisted,
|
||||
srv_blacklisted = srv_blacklisted,
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
local status_keys = require "status_keys"
|
||||
local format_utils = require "format_utils"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
|
|
@ -21,8 +20,7 @@ local alert_connection_issues = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_connection_issues.meta = {
|
||||
status_key = status_keys.ntopng.status_tcp_connection_issues,
|
||||
alert_key = alert_keys.ntopng.alert_connection_issues,
|
||||
alert_key = alert_keys.ntopng.alert_tcp_connection_issues,
|
||||
i18n_title = "alerts_dashboard.connection_issues",
|
||||
icon = "fas fa-exclamation",
|
||||
}
|
||||
|
|
@ -38,18 +36,9 @@ alert_connection_issues.meta = {
|
|||
-- @param client_issues A boolean indicating if the client has connection issues
|
||||
-- @param server_issues A boolean indicating if the server has connection issues
|
||||
-- @return A table with the alert built
|
||||
function alert_connection_issues:init(tcp_stats, cli2srv_pkts, srv2cli_pkts, is_severe, client_issues, server_issues)
|
||||
function alert_connection_issues:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
tcp_stats = tcp_stats,
|
||||
cli2srv_pkts = cli2srv_pkts,
|
||||
srv2cli_pkts = srv2cli_pkts,
|
||||
is_severe = is_severe,
|
||||
client_issues = client_issues,
|
||||
server_issues = server_issues,
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_data_exfiltration = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_data_exfiltration.meta = {
|
||||
status_key = status_keys.ntopng.status_data_exfiltration,
|
||||
alert_key = alert_keys.ntopng.alert_data_exfiltration,
|
||||
i18n_title = "flow_details.data_exfiltration",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,10 +30,6 @@ alert_data_exfiltration.meta = {
|
|||
function alert_data_exfiltration:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
-- No params
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -20,7 +19,6 @@ local alert_device_protocol_not_allowed = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_device_protocol_not_allowed.meta = {
|
||||
status_key = status_keys.ntopng.status_device_protocol_not_allowed,
|
||||
alert_key = alert_keys.ntopng.alert_device_protocol_not_allowed,
|
||||
i18n_title = "alerts_dashboard.suspicious_device_protocol",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -37,16 +35,9 @@ alert_device_protocol_not_allowed.meta = {
|
|||
-- @param devproto_forbidden_peer A string with the forbidden peer, one of 'cli' or 'srv'
|
||||
-- @param devproto_forbidden_id The nDPI ID of the forbidden application protocol
|
||||
-- @return A table with the alert built
|
||||
function alert_device_protocol_not_allowed:init(cli_devtype, srv_devtype, devproto_forbidden_peer, devproto_forbidden_id)
|
||||
function alert_device_protocol_not_allowed:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
["cli.devtype"] = cli_devtype,
|
||||
["srv.devtype"] = srv_devtype,
|
||||
devproto_forbidden_peer = devproto_forbidden_peer,
|
||||
devproto_forbidden_id = devproto_forbidden_id
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_dns_data_exfiltration = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_dns_data_exfiltration.meta = {
|
||||
status_key = status_keys.ntopng.status_dns_data_exfiltration,
|
||||
alert_key = alert_keys.ntopng.alert_dns_data_exfiltration,
|
||||
i18n_title = "flow_details.dns_data_exfiltration",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -31,10 +29,6 @@ alert_dns_data_exfiltration.meta = {
|
|||
function alert_dns_data_exfiltration:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
-- No params
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_dns_invalid_query = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_dns_invalid_query.meta = {
|
||||
status_key = status_keys.ntopng.status_dns_invalid_query,
|
||||
alert_key = alert_keys.ntopng.alert_dns_invalid_query,
|
||||
i18n_title = "flow_details.dns_invalid_query",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -31,10 +29,6 @@ alert_dns_invalid_query.meta = {
|
|||
function alert_dns_invalid_query:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
-- No params
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -16,14 +15,13 @@ local alert = require "alert"
|
|||
|
||||
-- ##############################################
|
||||
|
||||
local alert_elephant_local_to_remote = classes.class(alert)
|
||||
local alert_elephant_flow = classes.class(alert)
|
||||
|
||||
-- ##############################################
|
||||
|
||||
alert_elephant_local_to_remote.meta = {
|
||||
status_key = status_keys.ntopng.status_elephant_local_to_remote,
|
||||
alert_key = alert_keys.ntopng.alert_elephant_local_to_remote,
|
||||
i18n_title = "flow_details.elephant_flow_l2r",
|
||||
alert_elephant_flow.meta = {
|
||||
alert_key = alert_keys.ntopng.alert_elephant_flow,
|
||||
i18n_title = "flow_details.elephant_flow",
|
||||
icon = "fas fa-exclamation",
|
||||
}
|
||||
|
||||
|
|
@ -33,14 +31,9 @@ alert_elephant_local_to_remote.meta = {
|
|||
-- @param l2r_threshold Local-to-Remote threshold, in bytes, for a flow to be considered an elephant
|
||||
-- @param r2l_threshold Remote-to-Local threshold, in bytes, for a flow to be considered an elephant
|
||||
-- @return A table with the alert built
|
||||
function alert_elephant_local_to_remote:init(l2r_threshold, r2l_threshold)
|
||||
function alert_elephant_flow:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
["elephant.l2r_threshold"] = l2r_threshold,
|
||||
["elephant.r2l_threshold"] = r2l_threshold,
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
@ -50,12 +43,12 @@ end
|
|||
-- @param alert The alert description table, including alert data such as the generating entity, timestamp, granularity, type
|
||||
-- @param alert_type_params Table `alert_type_params` as built in the `:init` method
|
||||
-- @return A human-readable string
|
||||
function alert_elephant_local_to_remote.format(ifid, alert, alert_type_params)
|
||||
return formatElephantFlowStatus(alert_type_params, true --[[ l2r ]])
|
||||
function alert_elephant_flow.format(ifid, alert, alert_type_params)
|
||||
return formatElephantAlertType(alert_type_params)
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
||||
return alert_elephant_local_to_remote
|
||||
return alert_elephant_flow
|
||||
|
||||
-- #######################################################
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
--
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -17,7 +16,6 @@ local external_alert = classes.class(alert)
|
|||
|
||||
external_alert.meta = {
|
||||
alert_key = alert_keys.ntopng.alert_external,
|
||||
status_key = status_keys.ntopng.status_external_alert,
|
||||
i18n_title = "alerts_dashboard.external_alert",
|
||||
icon = "fas fa-eye",
|
||||
status_keep_increasing_scores = true, -- Every time an external alert is set, scores are increased accordingly
|
||||
|
|
@ -28,11 +26,9 @@ external_alert.meta = {
|
|||
-- @brief Prepare an alert table used to generate the alert
|
||||
-- @param info A generic table decoded from a JSON originated at the external alert source
|
||||
-- @return A table with the alert built
|
||||
function external_alert:init(info)
|
||||
function external_alert:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = info
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -20,8 +19,7 @@ local alert_flow_blacklisted = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_flow_blacklisted.meta = {
|
||||
status_key = status_keys.ntopng.status_blacklisted,
|
||||
alert_key = alert_keys.ntopng.alert_flow_blacklisted,
|
||||
alert_key = alert_keys.ntopng.alert_blacklisted,
|
||||
i18n_title = "alerts_dashboard.blacklisted_flow",
|
||||
icon = "fas fa-exclamation",
|
||||
has_victim = true,
|
||||
|
|
@ -33,13 +31,9 @@ alert_flow_blacklisted.meta = {
|
|||
-- @brief Prepare an alert table used to generate the alert
|
||||
-- @param info A flow info table fetched with `flow.getBlacklistedInfo()`
|
||||
-- @return A table with the alert built
|
||||
function alert_flow_blacklisted:init(info)
|
||||
function alert_flow_blacklisted:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
alert_type_params = info,
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_flow_blocked = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_flow_blocked.meta = {
|
||||
status_key = status_keys.ntopng.status_blocked, -- A flow status key
|
||||
alert_key = alert_keys.ntopng.alert_flow_blocked,
|
||||
i18n_title = "flow_details.flow_blocked_by_bridge",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -31,10 +29,6 @@ alert_flow_blocked.meta = {
|
|||
function alert_flow_blocked:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
-- No params
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
--
|
||||
-- (C) 2019-21 - ntop.org
|
||||
--
|
||||
--
|
||||
-- (C) 2019-21 - ntop.org
|
||||
--
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
local format_utils = require("format_utils")
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -16,30 +15,27 @@ local alert = require "alert"
|
|||
|
||||
-- ##############################################
|
||||
|
||||
local alert_elephant_remote_to_local = classes.class(alert)
|
||||
local alert_flow_low_goodput = classes.class(alert)
|
||||
|
||||
-- ##############################################
|
||||
|
||||
alert_elephant_remote_to_local.meta = {
|
||||
status_key = status_keys.ntopng.status_elephant_remote_to_local,
|
||||
alert_key = alert_keys.ntopng.alert_elephant_remote_to_local,
|
||||
i18n_title = "flow_details.elephant_flow_r2l",
|
||||
alert_flow_low_goodput.meta = {
|
||||
alert_key = alert_keys.ntopng.alert_low_goodput,
|
||||
i18n_title = "alerts_dashboard.flow_low_goodput",
|
||||
icon = "fas fa-exclamation",
|
||||
}
|
||||
|
||||
-- #######################################################
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Prepare an alert table used to generate the alert
|
||||
-- @param l2r_threshold Local-to-Remote threshold, in bytes, for a flow to be considered an elephant
|
||||
-- @param r2l_threshold Remote-to-Local threshold, in bytes, for a flow to be considered an elephant
|
||||
-- @param alert_severity A severity as defined in `alert_severities`
|
||||
-- @return A table with the alert built
|
||||
function alert_elephant_remote_to_local:init(l2r_threshold, r2l_threshold)
|
||||
function alert_flow_low_goodput:init(goodput_ratio)
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
["elephant.l2r_threshold"] = l2r_threshold,
|
||||
["elephant.r2l_threshold"] = r2l_threshold,
|
||||
goodput_ratio = goodput_ratio
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -50,12 +46,12 @@ end
|
|||
-- @param alert The alert description table, including alert data such as the generating entity, timestamp, granularity, type
|
||||
-- @param alert_type_params Table `alert_type_params` as built in the `:init` method
|
||||
-- @return A human-readable string
|
||||
function alert_elephant_remote_to_local.format(ifid, alert, alert_type_params)
|
||||
return formatElephantFlowStatus(alert_type_params, false --[[ r2l ]])
|
||||
function alert_flow_low_goodput.format(ifid, alert, alert_type_params)
|
||||
if alert_type_params and alert_type_params.goodput_ratio then
|
||||
return i18n("flow_details.flow_low_goodput", { ratio = format_utils.round(alert_type_params.goodput_ratio, 2) })
|
||||
end
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
||||
return alert_elephant_remote_to_local
|
||||
|
||||
-- #######################################################
|
||||
return alert_flow_low_goodput
|
||||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
local flow_risk_utils = require "flow_risk_utils"
|
||||
|
|
@ -21,7 +20,6 @@ local alert_flow_risk = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_flow_risk.meta = {
|
||||
status_key = status_keys.ntopng.status_flow_risk,
|
||||
alert_key = alert_keys.ntopng.alert_flow_risk,
|
||||
i18n_title = "alerts_dashboard.flow_risk",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,13 +30,9 @@ alert_flow_risk.meta = {
|
|||
-- @brief Prepare an alert table used to generate the alert
|
||||
-- @param risk_id Integer nDPI flow risk identifier
|
||||
-- @return A table with the alert built
|
||||
function alert_flow_risk:init(risk_id)
|
||||
function alert_flow_risk:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
risk_id = risk_id
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -15,13 +15,13 @@ local alert = require "alert"
|
|||
|
||||
-- ##############################################
|
||||
|
||||
local alert_iec104_error = classes.class(alert)
|
||||
local alert_iec_invalid_transition = classes.class(alert)
|
||||
|
||||
-- ##############################################
|
||||
|
||||
alert_iec104_error.meta = {
|
||||
alert_key = alert_keys.ntopng.alert_iec104_error,
|
||||
i18n_title = "alerts_dashboard.iec104_error",
|
||||
alert_iec_invalid_transition.meta = {
|
||||
alert_key = alert_keys.ntopng.alert_iec_invalid_transition,
|
||||
i18n_title = "alerts_dashboard.iec_invalid_transition",
|
||||
icon = "fas fa-subway",
|
||||
}
|
||||
|
||||
|
|
@ -30,13 +30,9 @@ alert_iec104_error.meta = {
|
|||
-- @brief Prepare an alert table used to generate the alert
|
||||
-- @param last_error A string with the lastest influxdb error
|
||||
-- @return A table with the alert built
|
||||
function alert_iec104_error:init(last_error)
|
||||
function alert_iec_invalid_transition:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
error_msg = last_error
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
@ -46,7 +42,7 @@ end
|
|||
-- @param alert The alert description table, including alert data such as the generating entity, timestamp, granularity, type
|
||||
-- @param alert_type_params Table `alert_type_params` as built in the `:init` method
|
||||
-- @return A human-readable string
|
||||
function alert_iec104_error.format(ifid, alert, alert_type_params)
|
||||
function alert_iec_invalid_transition.format(ifid, alert, alert_type_params)
|
||||
local msg = json.decode(alert_type_params.error_msg)
|
||||
local vlanId = alert.vlanId or 0
|
||||
local client = ip2label(msg.client.ip, msg.vlanId)
|
||||
|
|
@ -71,4 +67,4 @@ end
|
|||
|
||||
-- #######################################################
|
||||
|
||||
return alert_iec104_error
|
||||
return alert_iec_invalid_transition
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
--
|
||||
-- (C) 2019-21 - ntop.org
|
||||
--
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local json = require "dkjson"
|
||||
local format_utils = require "format_utils"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
local alert = require "alert"
|
||||
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local alert_iec_unexpected_type_id = classes.class(alert)
|
||||
|
||||
-- ##############################################
|
||||
|
||||
alert_iec_unexpected_type_id.meta = {
|
||||
alert_key = alert_keys.ntopng.alert_iec_unexpected_type_id,
|
||||
i18n_title = "alerts_dashboard.iec_unexpected_type_id",
|
||||
icon = "fas fa-subway",
|
||||
}
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Prepare an alert table used to generate the alert
|
||||
-- @param last_error A string with the lastest influxdb error
|
||||
-- @return A table with the alert built
|
||||
function alert_iec_unexpected_type_id:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
||||
-- @brief Format an alert into a human-readable string
|
||||
-- @param ifid The integer interface id of the generated alert
|
||||
-- @param alert The alert description table, including alert data such as the generating entity, timestamp, granularity, type
|
||||
-- @param alert_type_params Table `alert_type_params` as built in the `:init` method
|
||||
-- @return A human-readable string
|
||||
function alert_iec_unexpected_type_id.format(ifid, alert, alert_type_params)
|
||||
local msg = json.decode(alert_type_params.error_msg)
|
||||
|
||||
local rsp = "[CauseTX: "..msg.cause_tx.."][TypeId: "..msg.type_id.."][ASDU: ".. msg.asdu.."][Negative: "
|
||||
|
||||
if(msg.negatiive == false) then
|
||||
rsp = rsp .. "True]"
|
||||
else
|
||||
rsp = rsp .. "False]"
|
||||
end
|
||||
|
||||
-- tprint(rsp)
|
||||
|
||||
return(rsp)
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
||||
return alert_iec_unexpected_type_id
|
||||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_internals = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_internals.meta = {
|
||||
status_key = status_keys.ntopng.status_not_purged,
|
||||
alert_key = alert_keys.ntopng.alert_internals,
|
||||
i18n_title = "flow_details.not_purged",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -20,7 +19,6 @@ local alert_known_proto_on_non_std_port = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_known_proto_on_non_std_port.meta = {
|
||||
status_key = status_keys.ntopng.status_known_proto_on_non_std_port,
|
||||
alert_key = alert_keys.ntopng.alert_known_proto_on_non_std_port,
|
||||
i18n_title = "alerts_dashboard.known_proto_on_non_std_port",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,11 +30,9 @@ alert_known_proto_on_non_std_port.meta = {
|
|||
-- @param alert_severity A severity as defined in `alert_severities`
|
||||
-- @param info A lua table containing flow information obtained with `flow.getInfo()`
|
||||
-- @return A table with the alert built
|
||||
function alert_known_proto_on_non_std_port:init(info)
|
||||
function alert_known_proto_on_non_std_port:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = info
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_longlived = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_longlived.meta = {
|
||||
status_key = status_keys.ntopng.status_longlived,
|
||||
alert_key = alert_keys.ntopng.alert_longlived,
|
||||
i18n_title = "flow_details.longlived_flow",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -29,13 +27,9 @@ alert_longlived.meta = {
|
|||
-- @brief Prepare an alert table used to generate the alert
|
||||
-- @param longlived_threshold Threshold, in seconds, for a flow to be considered longlived
|
||||
-- @return A table with the alert built
|
||||
function alert_longlived:init(longlived_threshold)
|
||||
function alert_longlived:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
["longlived.threshold"] = longlived_threshold
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_malicious_signature = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_malicious_signature.meta = {
|
||||
status_key = status_keys.ntopng.status_malicious_signature, -- A flow status key
|
||||
alert_key = alert_keys.ntopng.alert_malicious_signature,
|
||||
i18n_title = "alerts_dashboard.malicious_signature_detected",
|
||||
icon = "fas fa-ban",
|
||||
|
|
@ -31,10 +29,6 @@ alert_malicious_signature.meta = {
|
|||
function alert_malicious_signature:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
-- No params
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_dns_suspicious_traffic = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_dns_suspicious_traffic.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_dns_suspicious_traffic,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_dns_suspicious_traffic,
|
||||
i18n_title = "alerts_dashboard.ndpi_dns_suspicious_traffic_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_dns_suspicious_traffic.meta = {
|
|||
function alert_ndpi_dns_suspicious_traffic:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_http_numeric_ip_host = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_http_numeric_ip_host.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_http_numeric_ip_host,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_http_numeric_ip_host,
|
||||
i18n_title = "alerts_dashboard.ndpi_http_numeric_ip_host_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_http_numeric_ip_host.meta = {
|
|||
function alert_ndpi_http_numeric_ip_host:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_http_suspicious_header = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_http_suspicious_header.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_http_suspicious_header,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_http_suspicious_header,
|
||||
i18n_title = "alerts_dashboard.ndpi_http_suspicious_header_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_http_suspicious_header.meta = {
|
|||
function alert_ndpi_http_suspicious_header:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_http_suspicious_url = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_http_suspicious_url.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_http_suspicious_url,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_http_suspicious_url,
|
||||
i18n_title = "alerts_dashboard.ndpi_http_suspicious_url_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_http_suspicious_url.meta = {
|
|||
function alert_ndpi_http_suspicious_url:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_http_suspicious_user_agent = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_http_suspicious_user_agent.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_http_suspicious_user_agent,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_http_suspicious_user_agent,
|
||||
i18n_title = "alerts_dashboard.ndpi_http_suspicious_user_agent_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_http_suspicious_user_agent.meta = {
|
|||
function alert_ndpi_http_suspicious_user_agent:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_malformed_packet = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_malformed_packet.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_malformed_packet,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_malformed_packet,
|
||||
i18n_title = "alerts_dashboard.ndpi_malformed_packet_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_malformed_packet.meta = {
|
|||
function alert_ndpi_malformed_packet:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_smb_insecure_version = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_smb_insecure_version.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_smb_insecure_version,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_smb_insecure_version,
|
||||
i18n_title = "alerts_dashboard.ndpi_smb_insecure_version_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_smb_insecure_version.meta = {
|
|||
function alert_ndpi_smb_insecure_version:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_ssh_obsolete = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_ssh_obsolete.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_ssh_obsolete,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_ssh_obsolete,
|
||||
i18n_title = "alerts_dashboard.ndpi_ssh_obsolete_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_ssh_obsolete.meta = {
|
|||
function alert_ndpi_ssh_obsolete:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_suspicious_dga_domain = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_suspicious_dga_domain.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_suspicious_dga_domain,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_suspicious_dga_domain,
|
||||
i18n_title = "alerts_dashboard.ndpi_suspicious_dga_domain_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_suspicious_dga_domain.meta = {
|
|||
function alert_ndpi_suspicious_dga_domain:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_tls_missing_sni = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_tls_missing_sni.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_tls_missing_sni,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_tls_missing_sni,
|
||||
i18n_title = "alerts_dashboard.ndpi_tls_missing_sni_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_tls_missing_sni.meta = {
|
|||
function alert_ndpi_tls_missing_sni:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_tls_not_carrying_https = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_tls_not_carrying_https.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_tls_not_carrying_https,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_tls_not_carrying_https,
|
||||
i18n_title = "alerts_dashboard.ndpi_tls_not_carrying_https_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_tls_not_carrying_https.meta = {
|
|||
function alert_ndpi_tls_not_carrying_https:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_tls_suspicious_esni_usage = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_tls_suspicious_esni_usage.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_tls_suspicious_esni_usage,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_tls_suspicious_esni_usage,
|
||||
i18n_title = "alerts_dashboard.ndpi_tls_suspicious_esni_usage_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_tls_suspicious_esni_usage.meta = {
|
|||
function alert_ndpi_tls_suspicious_esni_usage:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_unsafe_protocol = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_unsafe_protocol.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_unsafe_protocol,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_unsafe_protocol,
|
||||
i18n_title = "alerts_dashboard.ndpi_unsafe_protocol_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_unsafe_protocol.meta = {
|
|||
function alert_ndpi_unsafe_protocol:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_url_possible_rce_injection = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_url_possible_rce_injection.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_url_possible_rce_injection,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_url_possible_rce_injection,
|
||||
i18n_title = "alerts_dashboard.ndpi_url_possible_rce_injection_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_url_possible_rce_injection.meta = {
|
|||
function alert_ndpi_url_possible_rce_injection:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_url_possible_sql_injection = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_url_possible_sql_injection.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_url_possible_sql_injection,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_url_possible_sql_injection,
|
||||
i18n_title = "alerts_dashboard.ndpi_url_possible_sql_injection_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_url_possible_sql_injection.meta = {
|
|||
function alert_ndpi_url_possible_sql_injection:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -19,7 +18,6 @@ local alert_ndpi_url_possible_xss = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_ndpi_url_possible_xss.meta = {
|
||||
status_key = status_keys.ntopng.status_ndpi_url_possible_xss,
|
||||
alert_key = alert_keys.ntopng.alert_ndpi_url_possible_xss,
|
||||
i18n_title = "alerts_dashboard.ndpi_url_possible_xss_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,8 +30,6 @@ alert_ndpi_url_possible_xss.meta = {
|
|||
function alert_ndpi_url_possible_xss:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,8 +17,7 @@ local alert_potentially_dangerous_protocol = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_potentially_dangerous_protocol.meta = {
|
||||
status_key = status_keys.ntopng.status_potentially_dangerous,
|
||||
alert_key = alert_keys.ntopng.alert_potentially_dangerous_protocol,
|
||||
alert_key = alert_keys.ntopng.alert_potentially_dangerous,
|
||||
i18n_title = "flow_details.potentially_dangerous_protocol",
|
||||
icon = "fas fa-exclamation",
|
||||
}
|
||||
|
|
@ -31,10 +29,6 @@ alert_potentially_dangerous_protocol.meta = {
|
|||
function alert_potentially_dangerous_protocol:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
-- No params
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
|||
|
||||
local format_utils = require "format_utils"
|
||||
local json = require("dkjson")
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -22,7 +21,6 @@ local alert_remote_to_local_insecure_proto = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_remote_to_local_insecure_proto.meta = {
|
||||
status_key = status_keys.ntopng.status_remote_to_local_insecure_proto,
|
||||
alert_key = alert_keys.ntopng.alert_remote_to_local_insecure_proto,
|
||||
i18n_title = "alerts_dashboard.remote_to_local_insecure_proto",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -34,32 +32,18 @@ alert_remote_to_local_insecure_proto.meta = {
|
|||
-- @param one_flow_param The first alert param
|
||||
-- @param another_flow_param The second alert param
|
||||
-- @return A table with the alert built
|
||||
function alert_remote_to_local_insecure_proto:init(proto, category_name, breed_or_category)
|
||||
function alert_remote_to_local_insecure_proto:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
proto = proto,
|
||||
category_name = category_name,
|
||||
breed_or_category = breed_or_category,
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
||||
function alert_remote_to_local_insecure_proto.format(ifid, alert, alert_type_params)
|
||||
if breed_or_category == false then
|
||||
return i18n("alert_messages.remote_to_local_insecure_proto_category", {
|
||||
proto = alert_type_params.category_name,
|
||||
proto_id = alert_type_params.proto,
|
||||
})
|
||||
else
|
||||
return i18n("alert_messages.remote_to_local_insecure_proto_breed", {
|
||||
proto = alert_type_params.proto,
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
return i18n("alert_messages.remote_to_local_insecure_proto", {
|
||||
ndpi_breed = formatBreed(alert_type_params.ndpi_breed_name),
|
||||
ndpi_category = alert_type_params.ndpi_category_name,
|
||||
})
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
|||
|
||||
local format_utils = require "format_utils"
|
||||
local json = require("dkjson")
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -22,7 +21,6 @@ local alert_remote_to_remote = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_remote_to_remote.meta = {
|
||||
status_key = status_keys.ntopng.status_remote_to_remote,
|
||||
alert_key = alert_keys.ntopng.alert_remote_to_remote,
|
||||
i18n_title = "alerts_dashboard.remote_to_remote",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -35,9 +33,6 @@ alert_remote_to_remote.meta = {
|
|||
function alert_remote_to_remote:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -32,14 +32,9 @@ alert_request_reply_ratio.meta = {
|
|||
-- @param requests The number of requests
|
||||
-- @param replies The number of replies
|
||||
-- @return A table with the alert built
|
||||
function alert_request_reply_ratio:init(requests, replies)
|
||||
function alert_request_reply_ratio:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
requests = requests,
|
||||
replies = replies,
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -20,7 +19,6 @@ local alert_suspicious_file_transfer = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_suspicious_file_transfer.meta = {
|
||||
status_key = status_keys.ntopng.status_suspicious_file_transfer,
|
||||
alert_key = alert_keys.ntopng.alert_suspicious_file_transfer,
|
||||
i18n_title = "alerts_dashboard.suspicious_file_transfer",
|
||||
icon = "fas fa-file-download",
|
||||
|
|
@ -32,11 +30,9 @@ alert_suspicious_file_transfer.meta = {
|
|||
-- @param one_flow_param The first alert param
|
||||
-- @param another_flow_param The second alert param
|
||||
-- @return A table with the alert built
|
||||
function alert_suspicious_file_transfer:init(http_info)
|
||||
function alert_suspicious_file_transfer:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = http_info
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_suspicious_tcp_probing = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_suspicious_tcp_probing.meta = {
|
||||
status_key = status_keys.ntopng.status_suspicious_tcp_probing,
|
||||
alert_key = alert_keys.ntopng.alert_suspicious_tcp_probing,
|
||||
i18n_title = "flow_details.suspicious_tcp_probing",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -31,10 +29,6 @@ alert_suspicious_tcp_probing.meta = {
|
|||
function alert_suspicious_tcp_probing:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
-- No params
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_suspicious_tcp_syn_probing = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_suspicious_tcp_syn_probing.meta = {
|
||||
status_key = status_keys.ntopng.status_suspicious_tcp_syn_probing,
|
||||
alert_key = alert_keys.ntopng.alert_suspicious_tcp_syn_probing,
|
||||
i18n_title = "flow_details.suspicious_tcp_syn_probing",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -31,10 +29,6 @@ alert_suspicious_tcp_syn_probing.meta = {
|
|||
function alert_suspicious_tcp_syn_probing:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
-- No params
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_tcp_connection_refused = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_tcp_connection_refused.meta = {
|
||||
status_key = status_keys.ntopng.status_tcp_connection_refused,
|
||||
alert_key = alert_keys.ntopng.alert_tcp_connection_refused,
|
||||
i18n_title = "flow_details.tcp_connection_refused",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -31,10 +29,6 @@ alert_tcp_connection_refused.meta = {
|
|||
function alert_tcp_connection_refused:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
-- No params
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_tls_certificate_expired = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_tls_certificate_expired.meta = {
|
||||
status_key = status_keys.ntopng.status_tls_certificate_expired,
|
||||
alert_key = alert_keys.ntopng.alert_tls_certificate_expired,
|
||||
i18n_title = "flow_details.tls_certificate_expired",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -29,16 +27,9 @@ alert_tls_certificate_expired.meta = {
|
|||
-- @brief Prepare an alert table used to generate the alert
|
||||
-- @param tls_info A lua table with TLS info gererated calling `flow.getTLSInfo()`
|
||||
-- @return A table with the alert built
|
||||
function alert_tls_certificate_expired:init(tls_info)
|
||||
function alert_tls_certificate_expired:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
tls_info = tls_info or {}
|
||||
|
||||
self.alert_type_params = {
|
||||
["tls_crt.notBefore"] = tls_info["protos.tls.notBefore"],
|
||||
["tls_crt.notAfter"] = tls_info["protos.tls.notAfter"],
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_tls_certificate_mismatch = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_tls_certificate_mismatch.meta = {
|
||||
status_key = status_keys.ntopng.status_tls_certificate_mismatch,
|
||||
alert_key = alert_keys.ntopng.alert_tls_certificate_mismatch,
|
||||
i18n_title = "flow_details.tls_certificate_mismatch",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -29,18 +27,9 @@ alert_tls_certificate_mismatch.meta = {
|
|||
-- @brief Prepare an alert table used to generate the alert
|
||||
-- @param tls_info A lua table with TLS info gererated calling `flow.getTLSInfo()`
|
||||
-- @return A table with the alert built
|
||||
function alert_tls_certificate_mismatch:init(tls_info)
|
||||
function alert_tls_certificate_mismatch:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
tls_info = tls_info or {}
|
||||
local server_cn = tls_info["protos.tls.server_names"] or ""
|
||||
local client_cn = tls_info["protos.tls.client_requested_server_name"] or ""
|
||||
|
||||
self.alert_type_params = {
|
||||
["tls_crt.cli"] = client_cn,
|
||||
["tls_crt.srv"] = server_cn,
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_tls_certificate_selfsigned = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_tls_certificate_selfsigned.meta = {
|
||||
status_key = status_keys.ntopng.status_tls_certificate_selfsigned,
|
||||
alert_key = alert_keys.ntopng.alert_tls_certificate_selfsigned,
|
||||
i18n_title = "flow_details.tls_certificate_selfsigned",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -29,15 +27,9 @@ alert_tls_certificate_selfsigned.meta = {
|
|||
-- @brief Prepare an alert table used to generate the alert
|
||||
-- @param tls_info A lua table with TLS info gererated calling `flow.getTLSInfo()`
|
||||
-- @return A table with the alert built
|
||||
function alert_tls_certificate_selfsigned:init(tls_info)
|
||||
function alert_tls_certificate_selfsigned:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
tls_info = tls_info or {}
|
||||
|
||||
self.alert_type_params = {
|
||||
["tls_crt.issuerDN"] = tls_info["protos.tls.issuerDN"] or "",
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
@ -55,7 +47,15 @@ function alert_tls_certificate_selfsigned.format(ifid, alert, alert_type_params)
|
|||
local crts = {}
|
||||
crts[#crts + 1] = alert_type_params["tls_crt.issuerDN"]
|
||||
|
||||
return string.format("[Issuer/Subject: %s]", table.concat(crts, " - "))
|
||||
if alert_type_params["protos.tls.issuerDN"] then
|
||||
crts[#crts + 1] = "Issuer: "..alert_type_params["protos.tls.issuerDN"]
|
||||
end
|
||||
|
||||
if alert_type_params["protos.tls.subjectDN"] then
|
||||
crts[#crts + 1] = "Subject: "..alert_type_params["protos.tls.subjectDN"]
|
||||
end
|
||||
|
||||
return string.format("%s", table.concat(crts, " / "))
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_tls_old_protocol_version = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_tls_old_protocol_version.meta = {
|
||||
status_key = status_keys.ntopng.status_tls_old_protocol_version,
|
||||
alert_key = alert_keys.ntopng.alert_tls_old_protocol_version,
|
||||
i18n_title = "flow_details.tls_old_protocol_version",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -29,13 +27,9 @@ alert_tls_old_protocol_version.meta = {
|
|||
-- @brief Prepare an alert table used to generate the alert
|
||||
-- @param tls_version A number indicating the TLS version detected, or nil when version is not available
|
||||
-- @return A table with the alert built
|
||||
function alert_tls_old_protocol_version:init(tls_version)
|
||||
function alert_tls_old_protocol_version:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
tls_version = tls_version,
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_tls_unsafe_ciphers = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_tls_unsafe_ciphers.meta = {
|
||||
status_key = status_keys.ntopng.status_tls_unsafe_ciphers,
|
||||
alert_key = alert_keys.ntopng.alert_tls_unsafe_ciphers,
|
||||
i18n_title = "flow_details.tls_unsafe_ciphers",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -31,10 +29,6 @@ alert_tls_unsafe_ciphers.meta = {
|
|||
function alert_tls_unsafe_ciphers:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
-- No params
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
local alert_keys = require "alert_keys"
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -20,7 +19,6 @@ local alert_udp_unidirectional = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_udp_unidirectional.meta = {
|
||||
status_key = status_keys.ntopng.status_udp_unidirectional,
|
||||
alert_key = alert_keys.ntopng.alert_udp_unidirectional,
|
||||
i18n_title = "flow_details.udp_unidirectional",
|
||||
icon = "fas fa-info-circle",
|
||||
|
|
@ -33,8 +31,6 @@ alert_udp_unidirectional.meta = {
|
|||
function alert_udp_unidirectional:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -62,4 +62,4 @@ end
|
|||
|
||||
-- #######################################################
|
||||
|
||||
return alert_unexpected_behaviour
|
||||
return alert_unexpected_behaviour
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_unexpected_dhcp_server = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_unexpected_dhcp_server.meta = {
|
||||
status_key = status_keys.ntopng.status_unexpected_dhcp_server,
|
||||
alert_key = alert_keys.ntopng.alert_unexpected_dhcp_server,
|
||||
i18n_title = "unexpected_dhcp.alert_unexpected_dhcp_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,14 +30,9 @@ alert_unexpected_dhcp_server.meta = {
|
|||
-- @param one_flow_param The first alert param
|
||||
-- @param another_flow_param The second alert param
|
||||
-- @return A table with the alert built
|
||||
function alert_unexpected_dhcp_server:init(client_ip, server_ip)
|
||||
function alert_unexpected_dhcp_server:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
client_ip = client_ip,
|
||||
server_ip = server_ip
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_unexpected_dns_server = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_unexpected_dns_server.meta = {
|
||||
status_key = status_keys.ntopng.status_unexpected_dns_server,
|
||||
alert_key = alert_keys.ntopng.alert_unexpected_dns_server,
|
||||
i18n_title = "unexpected_dns.alert_unexpected_dns_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,14 +30,9 @@ alert_unexpected_dns_server.meta = {
|
|||
-- @param one_flow_param The first alert param
|
||||
-- @param another_flow_param The second alert param
|
||||
-- @return A table with the alert built
|
||||
function alert_unexpected_dns_server:init(client_ip, server_ip)
|
||||
function alert_unexpected_dns_server:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
client_ip = client_ip,
|
||||
server_ip = server_ip
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_unexpected_ntp_server = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_unexpected_ntp_server.meta = {
|
||||
status_key = status_keys.ntopng.status_unexpected_ntp_server,
|
||||
alert_key = alert_keys.ntopng.alert_unexpected_ntp_server,
|
||||
i18n_title = "unexpected_ntp.alert_unexpected_ntp_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -32,14 +30,9 @@ alert_unexpected_ntp_server.meta = {
|
|||
-- @param one_flow_param The first alert param
|
||||
-- @param another_flow_param The second alert param
|
||||
-- @return A table with the alert built
|
||||
function alert_unexpected_ntp_server:init(client_ip, server_ip)
|
||||
function alert_unexpected_ntp_server:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
client_ip = client_ip,
|
||||
server_ip = server_ip
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_unexpected_smtp_server = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_unexpected_smtp_server.meta = {
|
||||
status_key = status_keys.ntopng.status_unexpected_smtp_server,
|
||||
alert_key = alert_keys.ntopng.alert_unexpected_smtp_server,
|
||||
i18n_title = "unexpected_smtp.alert_unexpected_smtp_title",
|
||||
icon = "fas fa-exclamation",
|
||||
|
|
@ -28,14 +26,9 @@ alert_unexpected_smtp_server.meta = {
|
|||
|
||||
-- ##############################################
|
||||
|
||||
function alert_unexpected_smtp_server:init(client_ip, server_ip)
|
||||
function alert_unexpected_smtp_server:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {
|
||||
client_ip = client_ip,
|
||||
server_ip = server_ip
|
||||
}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
local status_keys = require "status_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
|
|
@ -18,7 +17,6 @@ local alert_web_mining = classes.class(alert)
|
|||
-- ##############################################
|
||||
|
||||
alert_web_mining.meta = {
|
||||
status_key = status_keys.ntopng.status_web_mining_detected,
|
||||
alert_key = alert_keys.ntopng.alert_web_mining,
|
||||
i18n_title = "alerts_dashboard.web_mining",
|
||||
icon = "fab fa-bitcoin",
|
||||
|
|
@ -33,8 +31,6 @@ alert_web_mining.meta = {
|
|||
function alert_web_mining:init()
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
|
||||
self.alert_type_params = {}
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
|
@ -49,4 +45,4 @@ return alert_web_mining
|
|||
|
||||
|
||||
--
|
||||
-- (C) 2019-20 - ntop.
|
||||
-- (C) 2019-20 - ntop.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
--
|
||||
-- (C) 2019-21 - ntop.org
|
||||
--
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local alert_keys = require "alert_keys"
|
||||
-- Import the classes library.
|
||||
local classes = require "classes"
|
||||
-- Make sure to import the Superclass!
|
||||
local alert = require "alert"
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local alert_zero_tcp_window = classes.class(alert)
|
||||
|
||||
-- ##############################################
|
||||
|
||||
alert_zero_tcp_window.meta = {
|
||||
alert_key = alert_keys.ntopng.alert_zero_tcp_window,
|
||||
i18n_title = "zero_tcp_window.zero_tcp_window_title",
|
||||
icon = "fas fa-arrow-circle-up",
|
||||
}
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Prepare an alert table used to generate the alert
|
||||
-- @param one_flow_param The first alert param
|
||||
-- @param another_flow_param The second alert param
|
||||
-- @return A table with the alert built
|
||||
function alert_zero_tcp_window:init(is_client, is_server)
|
||||
-- Call the parent constructor
|
||||
self.super:init()
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
||||
-- @brief Format an alert into a human-readable string
|
||||
-- @param ifid The integer interface id of the generated alert
|
||||
-- @param alert The alert description table, including alert data such as the generating entity, timestamp, granularity, type
|
||||
-- @param alert_type_params Table `alert_type_params` as built in the `:init` method
|
||||
-- @return A human-readable string
|
||||
function alert_zero_tcp_window.format(ifid, alert, alert_type_params)
|
||||
return i18n("zero_tcp_window.status_zero_tcp_window_description")
|
||||
end
|
||||
|
||||
-- #######################################################
|
||||
|
||||
return alert_zero_tcp_window
|
||||
189
scripts/lua/modules/alert_exclusions.lua
Normal file
189
scripts/lua/modules/alert_exclusions.lua
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
--
|
||||
-- (C) 2017-21 - ntop.org
|
||||
--
|
||||
-- Module to keep things in common across alert_exclusions of various type
|
||||
|
||||
local dirs = ntop.getDirs()
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
require "lua_utils"
|
||||
local alert_consts = require "alert_consts"
|
||||
local json = require "dkjson"
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local alert_exclusions = {}
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function _get_alert_exclusions_prefix_key()
|
||||
local key = string.format("ntopng.prefs.alert_exclusions")
|
||||
|
||||
return key
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function _get_alert_exclusions_lock_key()
|
||||
local key = string.format("ntopng.cache.alert_exclusions.alert_exclusions_lock")
|
||||
|
||||
return key
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function _lock()
|
||||
local max_lock_duration = 5 -- seconds
|
||||
local max_lock_attempts = 5 -- give up after at most this number of attempts
|
||||
local lock_key = _get_alert_exclusions_lock_key()
|
||||
|
||||
for i = 1, max_lock_attempts do
|
||||
local value_set = ntop.setnxCache(lock_key, "1", max_lock_duration)
|
||||
|
||||
if value_set then
|
||||
return true -- lock acquired
|
||||
end
|
||||
|
||||
ntop.msleep(1000)
|
||||
end
|
||||
|
||||
return false -- lock not acquired
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function _unlock()
|
||||
ntop.delCache(_get_alert_exclusions_lock_key())
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function _check_host_ip_alert_key(host_ip, alert_key)
|
||||
if not isIPv4(host_ip) and not isIPv6(host_ip) then
|
||||
-- Invalid host submitted
|
||||
return false
|
||||
end
|
||||
|
||||
if not alert_consts.alertTypeRaw(tonumber(alert_key)) then
|
||||
-- Invalid alert key submitted
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function _get_configured_alert_exclusions()
|
||||
local excl_key = _get_alert_exclusions_prefix_key()
|
||||
local configured_excl_str = ntop.getPref(excl_key)
|
||||
local configured_excl = json.decode(configured_excl_str) or {}
|
||||
|
||||
return configured_excl
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function _set_configured_alert_exclusions(exclusions)
|
||||
local excl_key = _get_alert_exclusions_prefix_key()
|
||||
|
||||
ntop.setPref(excl_key, json.encode(exclusions)) -- Add the preference
|
||||
ntop.reloadAlertExclusions() -- Tell ntopng to reload
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
--@brief Enables or disables an alert for an `host_ip`
|
||||
local function _toggle_alert(host_ip, alert_key, disable)
|
||||
local ret = false
|
||||
|
||||
if not _check_host_ip_alert_key(host_ip, alert_key) then
|
||||
-- Invalid params submitted
|
||||
return false
|
||||
end
|
||||
|
||||
local locked = _lock()
|
||||
|
||||
if locked then
|
||||
-- In JSON, keys are always strings
|
||||
alert_key = tostring(alert_key)
|
||||
local do_persist = false
|
||||
local exclusions = _get_configured_alert_exclusions()
|
||||
|
||||
-- Add an entry for the current alert key, if currently existing exclusions don't already have it
|
||||
if not exclusions[alert_key] then
|
||||
exclusions[alert_key] = {excluded_hosts = {}}
|
||||
end
|
||||
|
||||
-- Add an entry for excluded_hosts, if the currently existing exclusions don't already have it
|
||||
if not exclusions[alert_key]["excluded_hosts"] then
|
||||
exclusions[alert_key]["excluded_hosts"] = {}
|
||||
end
|
||||
|
||||
-- Now check if there is actually some work to do
|
||||
if not disable and exclusions[alert_key]["excluded_hosts"][host_ip] then
|
||||
-- Enable an host_ip that was disabled
|
||||
exclusions[alert_key]["excluded_hosts"][host_ip] = nil
|
||||
do_persist = true
|
||||
elseif disable and not exclusions[alert_key]["excluded_hosts"][host_ip] then
|
||||
-- Disable an host_ip that was not already disabled
|
||||
exclusions[alert_key]["excluded_hosts"][host_ip] = { --[[ Currently empty, will possibly contain values in the future, e.g., as_cli, as_srv--]]}
|
||||
do_persist = true
|
||||
end
|
||||
|
||||
if do_persist then
|
||||
_set_configured_alert_exclusions(exclusions)
|
||||
end
|
||||
|
||||
ret = true
|
||||
_unlock()
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
--@brief Marks an alert as disabled for a given `host_ip`
|
||||
--@return True, if alert is disabled with success, false otherwise
|
||||
function alert_exclusions.disable_alert(host_ip, alert_key)
|
||||
return _toggle_alert(host_ip, alert_key, true --[[ disable --]])
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
--@brief Marks an alert as enabled for a given `host_ip`
|
||||
--@return True, if alert is enabled with success, false otherwise
|
||||
function alert_exclusions.enable_alert(host_ip, alert_key)
|
||||
return _toggle_alert(host_ip, alert_key, false --[[ enable --]])
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Returns true if `host_ip` has the alert identified with `alert_key` disabled
|
||||
function alert_exclusions.has_disabled_alert(host_ip, alert_key)
|
||||
local exclusions = _get_configured_alert_exclusions()
|
||||
alert_key = tostring(alert_key)
|
||||
|
||||
return not not (exclusions[alert_key] and exclusions[alert_key]["excluded_hosts"] and exclusions[alert_key]["excluded_hosts"][host_ip])
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Delete all alert_exclusions
|
||||
function alert_exclusions.cleanup()
|
||||
local locked = _lock()
|
||||
|
||||
if locked then
|
||||
local excl_key = _get_alert_exclusions_prefix_key()
|
||||
|
||||
ntop.delCache(excl_key)
|
||||
ntop.reloadAlertExclusions() -- Tell ntopng to reload
|
||||
|
||||
_unlock()
|
||||
end
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
return alert_exclusions
|
||||
|
|
@ -11,126 +11,141 @@ local NO_PEN = 0
|
|||
|
||||
-- ##############################################
|
||||
|
||||
local BASE_ID = 1024 -- This is the first id reserved for non-flow-statuses.
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local alert_keys = {
|
||||
ntopng = {
|
||||
alert_blacklisted_country = {NO_PEN, 1},
|
||||
alert_broadcast_domain_too_large = {NO_PEN, 2},
|
||||
alert_device_connection = {NO_PEN, 3},
|
||||
alert_device_disconnection = {NO_PEN, 4},
|
||||
alert_device_protocol_not_allowed = {NO_PEN, 5},
|
||||
alert_dropped_alerts = {NO_PEN, 6},
|
||||
alert_external = {NO_PEN, 7},
|
||||
alert_flow_blacklisted = {NO_PEN, 8},
|
||||
alert_flow_blocked = {NO_PEN, 9},
|
||||
alert_flow_misbehaviour = {NO_PEN, 10}, -- No longer used
|
||||
alert_flows_flood = {NO_PEN, 11}, -- No longer used, check alert_flows_flood_attacker and alert_flows_flood_victim
|
||||
alert_ghost_network = {NO_PEN, 12},
|
||||
alert_host_pool_connection = {NO_PEN, 13},
|
||||
alert_host_pool_disconnection = {NO_PEN, 14},
|
||||
alert_influxdb_dropped_points = {NO_PEN, 15},
|
||||
alert_influxdb_error = {NO_PEN, 16},
|
||||
alert_influxdb_export_failure = {NO_PEN, 17},
|
||||
alert_internals = {NO_PEN, 18},
|
||||
alert_ip_outsite_dhcp_range = {NO_PEN, 19},
|
||||
alert_list_download_failed = {NO_PEN, 20},
|
||||
alert_login_failed = {NO_PEN, 21},
|
||||
alert_mac_ip_association_change = {NO_PEN, 22},
|
||||
alert_malicious_signature = {NO_PEN, 23},
|
||||
alert_misbehaving_flows_ratio = {NO_PEN, 24},
|
||||
alert_misconfigured_app = {NO_PEN, 25},
|
||||
alert_new_device = {NO_PEN, 26}, -- No longer used
|
||||
alert_nfq_flushed = {NO_PEN, 27},
|
||||
alert_none = {NO_PEN, 28}, -- No longer used
|
||||
alert_periodic_activity_not_executed = {NO_PEN, 29},
|
||||
alert_am_threshold_cross = {NO_PEN, 30},
|
||||
alert_port_duplexstatus_change = {NO_PEN, 31},
|
||||
alert_port_errors = {NO_PEN, 32},
|
||||
alert_port_load_threshold_exceeded = {NO_PEN, 33},
|
||||
alert_port_mac_changed = {NO_PEN, 34},
|
||||
alert_port_status_change = {NO_PEN, 35},
|
||||
alert_potentially_dangerous_protocol = {NO_PEN, 36},
|
||||
alert_process_notification = {NO_PEN, 37},
|
||||
alert_quota_exceeded = {NO_PEN, 38},
|
||||
alert_remote_to_remote = {NO_PEN, 39},
|
||||
alert_request_reply_ratio = {NO_PEN, 40},
|
||||
alert_slow_periodic_activity = {NO_PEN, 41},
|
||||
alert_slow_purge = {NO_PEN, 42},
|
||||
alert_snmp_device_reset = {NO_PEN, 43},
|
||||
alert_snmp_topology_changed = {NO_PEN, 44},
|
||||
alert_suspicious_activity = {NO_PEN, 45}, -- No longer used
|
||||
alert_tcp_syn_flood = {NO_PEN, 46}, -- No longer used, check alert_tcp_syn_flood_attacker and alert_tcp_syn_flood_victim
|
||||
alert_tcp_syn_scan = {NO_PEN, 47}, -- No longer used, check alert_tcp_syn_scan_attacker and alert_tcp_syn_scan_victim
|
||||
alert_test_failed = {NO_PEN, 48},
|
||||
alert_threshold_cross = {NO_PEN, 49},
|
||||
alert_too_many_drops = {NO_PEN, 50},
|
||||
alert_udp_unidirectional = {NO_PEN, 51},
|
||||
alert_unresponsive_device = {NO_PEN, 52},
|
||||
alert_user_activity = {NO_PEN, 53},
|
||||
alert_user_script_calls_drops = {NO_PEN, 54},
|
||||
alert_web_mining = {NO_PEN, 55},
|
||||
alert_connection_issues = {NO_PEN, 56},
|
||||
alert_suspicious_file_transfer = {NO_PEN, 57},
|
||||
alert_known_proto_on_non_std_port = {NO_PEN, 58},
|
||||
alert_host_log = {NO_PEN, 59},
|
||||
alert_attack_mitigation_via_snmp = {NO_PEN, 60},
|
||||
alert_iec104_error = {NO_PEN, 61},
|
||||
alert_flow_risk = {NO_PEN, 62},
|
||||
alert_unexpected_dns_server = {NO_PEN, 63},
|
||||
alert_unexpected_smtp_server = {NO_PEN, 64},
|
||||
alert_unexpected_dhcp_server = {NO_PEN, 65},
|
||||
alert_unexpected_ntp_server = {NO_PEN, 66},
|
||||
alert_too_many_retransmissions = {NO_PEN, 67}, -- No longer used
|
||||
alert_lateral_movement = {NO_PEN, 68},
|
||||
alert_list_download_succeeded = {NO_PEN, 69},
|
||||
alert_no_if_activity = {NO_PEN, 70}, -- scripts/plugins/alerts/internals/no_if_activity
|
||||
alert_zero_tcp_window = {NO_PEN, 71},
|
||||
alert_flow_low_goodput = {NO_PEN, 72},
|
||||
alert_unexpected_new_device = {NO_PEN, 73}, -- scripts/plugins/alerts/security/unexpected_new_device
|
||||
alert_shell_script_executed = {NO_PEN, 74}, -- scripts/plugins/endpoints/shell_alert_endpoint
|
||||
alert_periodicity_update = {NO_PEN, 75}, -- pro/scripts/enterprise_l_plugins/alerts/network/periodicity_update
|
||||
alert_dns_positive_error_ratio = {NO_PEN, 76}, -- pro/scripts/enterprise_l_plugins/alerts/network/dns_positive_error_ratio
|
||||
alert_elephant_local_to_remote = {NO_PEN, 77},
|
||||
alert_elephant_remote_to_local = {NO_PEN, 78},
|
||||
alert_longlived = {NO_PEN, 79},
|
||||
alert_tls_old_protocol_version = {NO_PEN, 80},
|
||||
alert_tls_certificate_mismatch = {NO_PEN, 81},
|
||||
alert_tls_certificate_expired = {NO_PEN, 82},
|
||||
alert_tls_unsafe_ciphers = {NO_PEN, 83},
|
||||
alert_tls_certificate_selfsigned = {NO_PEN, 84},
|
||||
alert_data_exfiltration = {NO_PEN, 85},
|
||||
alert_dns_data_exfiltration = {NO_PEN, 86},
|
||||
alert_tcp_connection_refused = {NO_PEN, 87},
|
||||
alert_suspicious_tcp_syn_probing = {NO_PEN, 88},
|
||||
alert_suspicious_tcp_probing = {NO_PEN, 89},
|
||||
alert_dns_invalid_query = {NO_PEN, 90},
|
||||
alert_iec_invalid_transition = {NO_PEN, 91},
|
||||
alert_fail2ban_executed = {NO_PEN, 92}, -- pro/scripts/pro_plugins/endpoints/fail2ban_alert_endpoint
|
||||
alert_flows_flood_attacker = {NO_PEN, 93},
|
||||
alert_flows_flood_victim = {NO_PEN, 94},
|
||||
alert_tcp_syn_flood_attacker = {NO_PEN, 95},
|
||||
alert_tcp_syn_flood_victim = {NO_PEN, 96},
|
||||
alert_tcp_syn_scan_attacker = {NO_PEN, 97},
|
||||
alert_tcp_syn_scan_victim = {NO_PEN, 98},
|
||||
alert_remote_to_local_insecure_proto = {NO_PEN, 99},
|
||||
alert_contacted_peers = {NO_PEN, 100},
|
||||
alert_unexpected_behaviour = {NO_PEN, 101},
|
||||
alert_ndpi_url_possible_xss = {NO_PEN, 102},
|
||||
alert_ndpi_url_possible_sql_injection = {NO_PEN, 103},
|
||||
alert_ndpi_url_possible_rce_injection = {NO_PEN, 104},
|
||||
alert_ndpi_http_suspicious_user_agent = {NO_PEN, 105},
|
||||
alert_ndpi_http_numeric_ip_host = {NO_PEN, 106},
|
||||
alert_ndpi_http_suspicious_url = {NO_PEN, 107},
|
||||
alert_ndpi_http_suspicious_header = {NO_PEN, 108},
|
||||
alert_ndpi_tls_not_carrying_https = {NO_PEN, 109},
|
||||
alert_ndpi_suspicious_dga_domain = {NO_PEN, 110},
|
||||
alert_ndpi_malformed_packet = {NO_PEN, 111},
|
||||
alert_ndpi_ssh_obsolete = {NO_PEN, 112},
|
||||
alert_ndpi_smb_insecure_version = {NO_PEN, 113},
|
||||
alert_ndpi_tls_suspicious_esni_usage = {NO_PEN, 114},
|
||||
alert_ndpi_unsafe_protocol = {NO_PEN, 115},
|
||||
alert_ndpi_dns_suspicious_traffic = {NO_PEN, 116},
|
||||
alert_ndpi_tls_missing_sni = {NO_PEN, 117},
|
||||
-- First 1024 (0 to 1023) IDs reserved for flow status alerts.
|
||||
-- Flow statuses are a Bitmap of 128 bits. 1024 is just to keep a safe margin
|
||||
-- and possibly enlarge Bitmap in the future
|
||||
-- NOTE: Keep them in sync with ntop_typedefs.h FlowAlertType
|
||||
alert_normal = {NO_PEN, 0},
|
||||
alert_blacklisted = {NO_PEN, 1},
|
||||
alert_blacklisted_country = {NO_PEN, 2},
|
||||
alert_flow_blocked = {NO_PEN, 3},
|
||||
alert_data_exfiltration = {NO_PEN, 4},
|
||||
alert_device_protocol_not_allowed = {NO_PEN, 5},
|
||||
alert_dns_data_exfiltration = {NO_PEN, 6},
|
||||
alert_dns_invalid_query = {NO_PEN, 7},
|
||||
alert_elephant_flow = {NO_PEN, 8},
|
||||
alert_elephant_remote_to_local = {NO_PEN, 9}, -- No longer used, can be recycled
|
||||
alert_external = {NO_PEN, 10},
|
||||
alert_longlived = {NO_PEN, 11},
|
||||
alert_low_goodput = {NO_PEN, 12},
|
||||
alert_malicious_signature = {NO_PEN, 13},
|
||||
alert_internals = {NO_PEN, 14},
|
||||
alert_potentially_dangerous = {NO_PEN, 15},
|
||||
alert_remote_to_remote = {NO_PEN, 16},
|
||||
alert_suspicious_tcp_probing = {NO_PEN, 17},
|
||||
alert_suspicious_tcp_syn_probing = {NO_PEN, 18},
|
||||
alert_tcp_connection_issues = {NO_PEN, 19},
|
||||
alert_tcp_connection_refused = {NO_PEN, 20},
|
||||
alert_tcp_severe_connection_issues = {NO_PEN, 21},
|
||||
alert_tls_certificate_expired = {NO_PEN, 22},
|
||||
alert_tls_certificate_mismatch = {NO_PEN, 23},
|
||||
alert_tls_old_protocol_version = {NO_PEN, 24},
|
||||
alert_tls_unsafe_ciphers = {NO_PEN, 25},
|
||||
alert_udp_unidirectional = {NO_PEN, 26},
|
||||
alert_web_mining = {NO_PEN, 27},
|
||||
alert_tls_certificate_selfsigned = {NO_PEN, 28},
|
||||
alert_suspicious_file_transfer = {NO_PEN, 29},
|
||||
alert_known_proto_on_non_std_port = {NO_PEN, 30},
|
||||
alert_flow_risk = {NO_PEN, 31},
|
||||
alert_unexpected_dhcp_server = {NO_PEN, 32},
|
||||
alert_unexpected_dns_server = {NO_PEN, 33},
|
||||
alert_unexpected_smtp_server = {NO_PEN, 34},
|
||||
alert_unexpected_ntp_server = {NO_PEN, 35},
|
||||
alert_zero_tcp_window = {NO_PEN, 36},
|
||||
alert_iec_invalid_transition = {NO_PEN, 37},
|
||||
alert_remote_to_local_insecure_proto = {NO_PEN, 38},
|
||||
alert_ndpi_url_possible_xss = {NO_PEN, 39},
|
||||
alert_ndpi_url_possible_sql_injection = {NO_PEN, 40},
|
||||
alert_ndpi_url_possible_rce_injection = {NO_PEN, 41},
|
||||
alert_ndpi_http_suspicious_user_agent = {NO_PEN, 42},
|
||||
alert_ndpi_http_numeric_ip_host = {NO_PEN, 43},
|
||||
alert_ndpi_http_suspicious_url = {NO_PEN, 44},
|
||||
alert_ndpi_http_suspicious_header = {NO_PEN, 45},
|
||||
alert_ndpi_tls_not_carrying_https = {NO_PEN, 46},
|
||||
alert_ndpi_suspicious_dga_domain = {NO_PEN, 47},
|
||||
alert_ndpi_malformed_packet = {NO_PEN, 48},
|
||||
alert_ndpi_ssh_obsolete = {NO_PEN, 49},
|
||||
alert_ndpi_smb_insecure_version = {NO_PEN, 50},
|
||||
alert_ndpi_tls_suspicious_esni_usage = {NO_PEN, 51},
|
||||
alert_ndpi_unsafe_protocol = {NO_PEN, 52},
|
||||
alert_ndpi_dns_suspicious_traffic = {NO_PEN, 53},
|
||||
alert_ndpi_tls_missing_sni = {NO_PEN, 54},
|
||||
alert_iec_unexpected_type_id = {NO_PEN, 55},
|
||||
|
||||
-- NOTE: for flow alerts not not go beyond the size of Bitmap alert_map inside Flow.h (currently 128)
|
||||
|
||||
--
|
||||
-- Here we have statuses >= 1024 that are reserved for non-flows
|
||||
--
|
||||
alert_broadcast_domain_too_large = {NO_PEN, BASE_ID },
|
||||
alert_device_connection = {NO_PEN, BASE_ID + 1 },
|
||||
alert_device_disconnection = {NO_PEN, BASE_ID + 2 },
|
||||
alert_dropped_alerts = {NO_PEN, BASE_ID + 3 },
|
||||
alert_flow_misbehaviour = {NO_PEN, BASE_ID + 4 }, -- No longer used
|
||||
alert_flows_flood = {NO_PEN, BASE_ID + 5 }, -- No longer used, check alert_flows_flood_attacker and alert_flows_flood_victim
|
||||
alert_ghost_network = {NO_PEN, BASE_ID + 6 },
|
||||
alert_host_pool_connection = {NO_PEN, BASE_ID + 7 },
|
||||
alert_host_pool_disconnection = {NO_PEN, BASE_ID + 8 },
|
||||
alert_influxdb_dropped_points = {NO_PEN, BASE_ID + 9 },
|
||||
alert_influxdb_error = {NO_PEN, BASE_ID + 10},
|
||||
alert_influxdb_export_failure = {NO_PEN, BASE_ID + 11},
|
||||
alert_ip_outsite_dhcp_range = {NO_PEN, BASE_ID + 13},
|
||||
alert_list_download_failed = {NO_PEN, BASE_ID + 14},
|
||||
alert_login_failed = {NO_PEN, BASE_ID + 15},
|
||||
alert_mac_ip_association_change = {NO_PEN, BASE_ID + 16},
|
||||
alert_misbehaving_flows_ratio = {NO_PEN, BASE_ID + 17},
|
||||
alert_misconfigured_app = {NO_PEN, BASE_ID + 18},
|
||||
alert_new_device = {NO_PEN, BASE_ID + 19}, -- No longer used
|
||||
alert_nfq_flushed = {NO_PEN, BASE_ID + 20},
|
||||
alert_none = {NO_PEN, BASE_ID + 21}, -- No longer used
|
||||
alert_periodic_activity_not_executed = {NO_PEN, BASE_ID + 22},
|
||||
alert_am_threshold_cross = {NO_PEN, BASE_ID + 23},
|
||||
alert_port_duplexstatus_change = {NO_PEN, BASE_ID + 24},
|
||||
alert_port_errors = {NO_PEN, BASE_ID + 25},
|
||||
alert_port_load_threshold_exceeded = {NO_PEN, BASE_ID + 26},
|
||||
alert_port_mac_changed = {NO_PEN, BASE_ID + 27},
|
||||
alert_port_status_change = {NO_PEN, BASE_ID + 28},
|
||||
alert_process_notification = {NO_PEN, BASE_ID + 29},
|
||||
alert_quota_exceeded = {NO_PEN, BASE_ID + 30},
|
||||
alert_request_reply_ratio = {NO_PEN, BASE_ID + 31},
|
||||
alert_slow_periodic_activity = {NO_PEN, BASE_ID + 32},
|
||||
alert_slow_purge = {NO_PEN, BASE_ID + 33},
|
||||
alert_snmp_device_reset = {NO_PEN, BASE_ID + 34},
|
||||
alert_snmp_topology_changed = {NO_PEN, BASE_ID + 35},
|
||||
alert_suspicious_activity = {NO_PEN, BASE_ID + 36}, -- No longer used
|
||||
alert_tcp_syn_flood = {NO_PEN, BASE_ID + 37}, -- No longer used, check alert_tcp_syn_flood_attacker and alert_tcp_syn_flood_victim
|
||||
alert_tcp_syn_scan = {NO_PEN, BASE_ID + 38}, -- No longer used, check alert_tcp_syn_scan_attacker and alert_tcp_syn_scan_victim
|
||||
alert_test_failed = {NO_PEN, BASE_ID + 39},
|
||||
alert_threshold_cross = {NO_PEN, BASE_ID + 40},
|
||||
alert_too_many_drops = {NO_PEN, BASE_ID + 41},
|
||||
alert_unresponsive_device = {NO_PEN, BASE_ID + 42},
|
||||
alert_user_activity = {NO_PEN, BASE_ID + 43},
|
||||
alert_user_script_calls_drops = {NO_PEN, BASE_ID + 44},
|
||||
alert_host_log = {NO_PEN, BASE_ID + 45},
|
||||
alert_attack_mitigation_via_snmp = {NO_PEN, BASE_ID + 46},
|
||||
alert_iec104_error = {NO_PEN, BASE_ID + 47}, -- No longer used
|
||||
alert_lateral_movement = {NO_PEN, BASE_ID + 48},
|
||||
alert_list_download_succeeded = {NO_PEN, BASE_ID + 49},
|
||||
alert_no_if_activity = {NO_PEN, BASE_ID + 50}, -- scripts/plugins/alerts/internals/no_if_activity
|
||||
alert_unexpected_new_device = {NO_PEN, BASE_ID + 51}, -- scripts/plugins/alerts/security/unexpected_new_device
|
||||
alert_shell_script_executed = {NO_PEN, BASE_ID + 52}, -- scripts/plugins/endpoints/shell_alert_endpoint
|
||||
alert_periodicity_update = {NO_PEN, BASE_ID + 53}, -- pro/scripts/enterprise_l_plugins/alerts/network/periodicity_update
|
||||
alert_dns_positive_error_ratio = {NO_PEN, BASE_ID + 54}, -- pro/scripts/enterprise_l_plugins/alerts/network/dns_positive_error_ratio
|
||||
alert_fail2ban_executed = {NO_PEN, BASE_ID + 55}, -- pro/scripts/pro_plugins/endpoints/fail2ban_alert_endpoint
|
||||
alert_flows_flood_attacker = {NO_PEN, BASE_ID + 56},
|
||||
alert_flows_flood_victim = {NO_PEN, BASE_ID + 57},
|
||||
alert_tcp_syn_flood_attacker = {NO_PEN, BASE_ID + 58},
|
||||
alert_tcp_syn_flood_victim = {NO_PEN, BASE_ID + 59},
|
||||
alert_tcp_syn_scan_attacker = {NO_PEN, BASE_ID + 60},
|
||||
alert_tcp_syn_scan_victim = {NO_PEN, BASE_ID + 61},
|
||||
alert_contacted_peers = {NO_PEN, BASE_ID + 62},
|
||||
alert_unexpected_behaviour = {NO_PEN, BASE_ID + 63},
|
||||
|
||||
-- Add here additional keys for alerts generated
|
||||
-- by ntopng plugins
|
||||
|
|
|
|||
|
|
@ -9,12 +9,43 @@ local json = require "dkjson"
|
|||
local rest_utils = require "rest_utils"
|
||||
local user_scripts = require "user_scripts"
|
||||
local alert_utils = require "alert_utils"
|
||||
|
||||
local alert_exclusions = require "alert_exclusions"
|
||||
|
||||
local alert_rest_utils = {}
|
||||
|
||||
-- #################################
|
||||
|
||||
-- @brief exclude an alert using the parameters that the POST has
|
||||
function _exclude_flow_alert(additional_filters, delete_alerts)
|
||||
local success = false
|
||||
|
||||
local alert_key = tonumber(_POST["alert_key"])
|
||||
local alert_addr = _POST["alert_addr"]
|
||||
|
||||
if alert_key and alert_addr then
|
||||
success = true
|
||||
end
|
||||
|
||||
if success then
|
||||
if alert_addr then
|
||||
alert_exclusions.disable_alert(alert_addr, alert_key)
|
||||
if delete_alerts == "true" then
|
||||
alert_utils.deleteFlowAlertsMatching(alert_addr, alert_key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if success then
|
||||
rc = rest_utils.consts.success.ok
|
||||
rest_utils.answer(rc)
|
||||
else
|
||||
rc = rest_utils.consts.err.invalid_args
|
||||
rest_utils.answer(rc)
|
||||
end
|
||||
end
|
||||
|
||||
-- #################################
|
||||
|
||||
-- @brief exclude an alert using the parameters that the POST has
|
||||
function alert_rest_utils.exclude_alert()
|
||||
-- POST parameters
|
||||
|
|
@ -31,11 +62,15 @@ function alert_rest_utils.exclude_alert()
|
|||
-- Parameters used for the rest answer
|
||||
local rc = ""
|
||||
local res = ""
|
||||
|
||||
if subdir == "flow" then
|
||||
return _exclude_flow_alert(additional_filters, delete_alerts)
|
||||
end
|
||||
|
||||
-- Checking that all parameters where given to the POST
|
||||
if not additional_filters or not subdir or not script_key then
|
||||
rest_utils.answer(rest_utils.consts.err.invalid_args)
|
||||
return
|
||||
return
|
||||
end
|
||||
|
||||
-- Getting the parameters
|
||||
|
|
|
|||
|
|
@ -443,6 +443,25 @@ end
|
|||
|
||||
-- #################################
|
||||
|
||||
--@brief Deletes all stored alerts matching an host and an IP
|
||||
-- @return nil
|
||||
function alert_utils.deleteFlowAlertsMatching(host_ip, alert_key)
|
||||
local res = {}
|
||||
local statement = "DELETE "
|
||||
|
||||
-- This is to match elements inside the alert_json
|
||||
local where = {
|
||||
string.format("(cli_addr = '%s' OR srv_addr = '%s')", host_ip, host_ip),
|
||||
string.format("alert_type = %u", alert_key),
|
||||
}
|
||||
|
||||
where = table.concat(where, " AND ")
|
||||
|
||||
res = interface.queryFlowAlertsRaw(statement, where, nil, true)
|
||||
end
|
||||
|
||||
-- #################################
|
||||
|
||||
-- this function returns an object with parameters specific for one tab
|
||||
function alert_utils.getTabParameters(_get, what)
|
||||
local opts = {}
|
||||
|
|
@ -508,24 +527,24 @@ end
|
|||
-- #################################
|
||||
|
||||
-- Return more information for the flow alert description
|
||||
local function getFlowStatusInfo(record, status_info)
|
||||
local function getAlertTypeInfo(record, alert_info)
|
||||
local res = ""
|
||||
|
||||
local l7proto_name = interface.getnDPIProtoName(tonumber(record["l7_proto"]) or 0)
|
||||
|
||||
if l7proto_name == "ICMP" then -- is ICMPv4
|
||||
-- TODO: old format - remove when the all the flow alers will be generated in lua
|
||||
local type_code = {type = status_info["icmp.icmp_type"], code = status_info["icmp.icmp_code"]}
|
||||
local type_code = {type = alert_info["icmp.icmp_type"], code = alert_info["icmp.icmp_code"]}
|
||||
|
||||
if table.empty(type_code) and status_info["icmp"] then
|
||||
if table.empty(type_code) and alert_info["icmp"] then
|
||||
-- This is the new format created when setting the alert from lua
|
||||
type_code = {type = status_info["icmp"]["type"], code = status_info["icmp"]["code"]}
|
||||
type_code = {type = alert_info["icmp"]["type"], code = alert_info["icmp"]["code"]}
|
||||
end
|
||||
|
||||
if status_info["icmp.unreach.src_ip"] then -- TODO: old format to be removed
|
||||
res = string.format("[%s]", i18n("icmp_page.icmp_port_unreachable_extra", {unreach_host=status_info["icmp.unreach.dst_ip"], unreach_port=status_info["icmp.unreach.dst_port"], unreach_protocol = l4_proto_to_string(status_info["icmp.unreach.protocol"])}))
|
||||
elseif status_info["icmp"] and status_info["icmp"]["unreach"] then -- New format
|
||||
res = string.format("[%s]", i18n("icmp_page.icmp_port_unreachable_extra", {unreach_host=status_info["icmp"]["unreach"]["dst_ip"], unreach_port=status_info["icmp"]["unreach"]["dst_port"], unreach_protocol = l4_proto_to_string(status_info["icmp"]["unreach"]["protocol"])}))
|
||||
if alert_info["icmp.unreach.src_ip"] then -- TODO: old format to be removed
|
||||
res = string.format("[%s]", i18n("icmp_page.icmp_port_unreachable_extra", {unreach_host=alert_info["icmp.unreach.dst_ip"], unreach_port=alert_info["icmp.unreach.dst_port"], unreach_protocol = l4_proto_to_string(alert_info["icmp.unreach.protocol"])}))
|
||||
elseif alert_info["icmp"] and alert_info["icmp"]["unreach"] then -- New format
|
||||
res = string.format("[%s]", i18n("icmp_page.icmp_port_unreachable_extra", {unreach_host=alert_info["icmp"]["unreach"]["dst_ip"], unreach_port=alert_info["icmp"]["unreach"]["dst_port"], unreach_protocol = l4_proto_to_string(alert_info["icmp"]["unreach"]["protocol"])}))
|
||||
else
|
||||
res = string.format("[%s]", icmp_utils.get_icmp_label(4 --[[ ipv4 --]], type_code["type"], type_code["code"]))
|
||||
end
|
||||
|
|
@ -548,8 +567,8 @@ local function formatRawFlow(ifid, alert, alert_json)
|
|||
end
|
||||
|
||||
-- TODO: adapter just to be compatible with old alerts, can be removed at some point
|
||||
if alert_json["status_info"] then
|
||||
alert_json = json.decode(alert_json["status_info"])
|
||||
if alert_json["alert_info"] then
|
||||
alert_json = json.decode(alert_json["alert_info"])
|
||||
end
|
||||
|
||||
-- active flow lookup
|
||||
|
|
@ -606,7 +625,7 @@ local function formatRawFlow(ifid, alert, alert_json)
|
|||
end
|
||||
|
||||
if alert_json then
|
||||
flow = flow..getFlowStatusInfo(alert, alert_json)
|
||||
flow = flow..getAlertTypeInfo(alert, alert_json)
|
||||
end
|
||||
|
||||
return flow
|
||||
|
|
@ -944,12 +963,11 @@ function alert_utils.drawAlertTables(has_past_alerts, has_engaged_alerts, has_fl
|
|||
template.gen("modal_alert_filter_dialog.html", {
|
||||
dialog={
|
||||
id = "filter_alert_dialog",
|
||||
action = "filterAlertByFilters(subdir, script_key)",
|
||||
action = "filterAlertByFilters(subdir, script_key, alert_key)",
|
||||
title = i18n("show_alerts.filter_alert"),
|
||||
message = i18n("show_alerts.confirm_filter_alert"),
|
||||
delete_message = i18n("show_alerts.confirm_delete_filtered_alerts"),
|
||||
field_input_title = i18n("current_filter"),
|
||||
delete_alerts = i18n("delete_alerts"),
|
||||
delete_alerts = i18n("delete_disabled_alerts"),
|
||||
alert_filter = "default_filter",
|
||||
confirm = i18n("filter"),
|
||||
confirm_button = "btn-warning",
|
||||
|
|
@ -958,6 +976,23 @@ function alert_utils.drawAlertTables(has_past_alerts, has_engaged_alerts, has_fl
|
|||
)
|
||||
|
||||
|
||||
-- Filtering for flow alerts
|
||||
print(
|
||||
template.gen("modal_flow_alerts_filter_dialog.html", {
|
||||
dialog={
|
||||
id = "flow_alerts_filter_dialog",
|
||||
action = "filterFlowAlerts(alert_key)",
|
||||
title = i18n("show_alerts.filter_alert"),
|
||||
message = i18n("show_alerts.confirm_filter_alert"),
|
||||
delete_message = i18n("show_alerts.confirm_delete_filtered_alerts"),
|
||||
delete_alerts = i18n("delete_disabled_alerts"),
|
||||
alert_filter = "default_filter",
|
||||
confirm = i18n("filter"),
|
||||
confirm_button = "btn-warning",
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
print(
|
||||
template.gen("modal_confirm_dialog.html", {
|
||||
|
|
@ -1089,7 +1124,7 @@ function deleteAlertById(alert_key) {
|
|||
form.appendTo('body').submit();
|
||||
}
|
||||
|
||||
function filterAlertByFilters(subdir, script_key) {
|
||||
function filterAlertByFilters(subdir, script_key, alert_key) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
contentType: "application/json",
|
||||
|
|
@ -1099,6 +1134,7 @@ function filterAlertByFilters(subdir, script_key) {
|
|||
filters: document.getElementById("name_input").value,
|
||||
subdir: subdir,
|
||||
script_key: script_key,
|
||||
alert_key: alert_key,
|
||||
status: getCurrentStatus(),
|
||||
delete_alerts: $('#delete_alert_switch').prop('checked'),
|
||||
csrf: "]] print(ntop.getRandomCSRFValue()) print[[",
|
||||
|
|
@ -1115,6 +1151,31 @@ function filterAlertByFilters(subdir, script_key) {
|
|||
});
|
||||
}
|
||||
|
||||
function filterFlowAlerts(alert_key) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
contentType: "application/json",
|
||||
dataType: "json",
|
||||
url: `${http_prefix}/lua/rest/v1/edit/user_script/filter.lua`,
|
||||
data: JSON.stringify({
|
||||
alert_addr: $("input[name='alert_addr']:checked").val(),
|
||||
subdir: "flow",
|
||||
alert_key: alert_key,
|
||||
delete_alerts: $('#delete_flow_alerts_switch').prop('checked'),
|
||||
csrf: "]] print(ntop.getRandomCSRFValue()) print[[",
|
||||
}),
|
||||
success: function(rsp) {
|
||||
let get_params = NtopUtils.paramsExtend(]] print(tableToJsObject(alert_utils.getTabParameters(url_params, nil))) print[[, {status:getCurrentStatus()});
|
||||
get_params.csrf = "]] print(ntop.getRandomCSRFValue()) print[[";
|
||||
let form = NtopUtils.paramsToForm('<form method="post"></form>', get_params);
|
||||
form.appendTo('body').submit();
|
||||
},
|
||||
error: function(rsp) {
|
||||
$("#filter_alert_dialog_error").text(rsp.responseJSON.rsp).show();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
var alert_to_toggle = null;
|
||||
var alert_to_release = null;
|
||||
|
||||
|
|
@ -1386,8 +1447,18 @@ function releaseAlert(idx) {
|
|||
var data = table_data[row_id];
|
||||
var explorer_url = data["column_explorer"];
|
||||
|
||||
if(data["column_filter"]) {
|
||||
datatableAddFilterButtonCallback.bind(this)(10, "subdir = '" + data["column_subdir"] + "'; script_key = '" + data["column_script_key"] + "'; $('#name_input').attr('value', '" + data["column_filter"] + "'); $('#filter_alert_dialog').modal('show');", "<i class='fas fa-bell-slash'></i>", "]] print(i18n("filter")) print[[");
|
||||
if(data["column_filter"] && data["column_subdir"] == "flow") {
|
||||
/* Extract client and server address that come into column_filter concatenated with a pipe */
|
||||
const cli_srv_addr = data["column_filter"].split('|'), cli_addr = cli_srv_addr[0], srv_addr = cli_srv_addr[1];
|
||||
|
||||
/* Populate client and server radio buttons */
|
||||
const srv_radio = " $('#srv_radio').attr('value', '" + srv_addr + "'); $('#srv_addr').html('" + srv_addr + "'); ";
|
||||
const cli_radio = " $('#cli_radio').attr('value', '" + cli_addr + "'); $('#cli_addr').html('" + cli_addr + "'); ";
|
||||
const alert_label = "$('.alert_label').html('" + data["column_type_str"] + "'); ";
|
||||
console.log(alert_label);
|
||||
datatableAddFilterButtonCallback.bind(this)(10, "alert_key = '" + data["column_type_id"] + "'; " + alert_label + srv_radio + cli_radio + " $('#flow_alerts_filter_dialog').modal('show');", "<i class='fas fa-bell-slash'></i>", "]] print(i18n("filter")) print[[");
|
||||
} else if(data["column_filter"]) {
|
||||
datatableAddFilterButtonCallback.bind(this)(10, "alert_key = '" + data["column_type_id"] + "'; alert_label = $('.alert_label').html('" + data["column_type_str"] + "'); subdir = '" + data["column_subdir"] + "'; script_key = '" + data["column_script_key"] + "'; $('#name_input').attr('value', '" + data["column_filter"] + "'); $('#filter_alert_dialog').modal('show');", "<i class='fas fa-bell-slash'></i>", "]] print(i18n("filter")) print[[");
|
||||
} else if(data["column_filter_disabled"]) {
|
||||
datatableAddFilterButtonCallback.bind(this)(10, "subdir = ''; script_key = '';", "<i class='fas fa-bell-slash'></i>", "]] print(i18n("filter")) print[[", false); }
|
||||
|
||||
|
|
@ -1893,7 +1964,7 @@ end
|
|||
-- #################################
|
||||
|
||||
function alert_utils.getConfigsetAlertLink(alert_json)
|
||||
local info = alert_json.alert_generation or (alert_json.status_info and alert_json.status_info.alert_generation)
|
||||
local info = alert_json.alert_generation or (alert_json.alert_info and alert_json.alert_info.alert_generation)
|
||||
|
||||
if(info and isAdministrator()) then
|
||||
return(' <a href="'.. ntop.getHttpPrefix() ..'/lua/admin/edit_configset.lua?'..
|
||||
|
|
|
|||
|
|
@ -153,15 +153,6 @@ local function addAlertHostInfo(triggered)
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
-- ##############################################
|
||||
|
||||
--! @param type_info data returned by one of the type_info building functions
|
||||
function alerts_api.trigger_status(type_info, alert_severity, cli_score, srv_score, flow_score)
|
||||
type_info.status_type.alert_severity = alert_severity
|
||||
flow.triggerStatus(type_info, flow_score, cli_score, srv_score)
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
--@brief Check if the `alert` belongs to an exclusion list
|
||||
|
|
|
|||
102
scripts/lua/modules/alerts_config.lua
Normal file
102
scripts/lua/modules/alerts_config.lua
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
--
|
||||
-- (C) 2013-21 - ntop.org
|
||||
--
|
||||
|
||||
local dirs = ntop.getDirs()
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
local alert_consts = require "alert_consts"
|
||||
local alert_severities = require "alert_severities"
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local alerts_config = {}
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local CONFIGSET_KEY = "ntopng.prefs.alerts_config.configset_v1" -- Keep in sync with ntop_defines.h FLOW_CALLBACKS_CONFIG
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function saveConfigset(configset)
|
||||
local v = json.encode(configset)
|
||||
ntop.setCache(CONFIGSET_KEY, v)
|
||||
|
||||
-- Reload the periodic scripts as the configuration has changed
|
||||
ntop.reloadPeriodicScripts()
|
||||
|
||||
-- TODO: Reload flow alerts in C++
|
||||
-- ntop.reloadFlowAlerts()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local cached_config_set = nil
|
||||
|
||||
-- Return the default config set
|
||||
-- Note: Other config sets are deprecated
|
||||
function alerts_config.getConfigset()
|
||||
if not cached_config_set then
|
||||
cached_config_set = json.decode(ntop.getCache(CONFIGSET_KEY))
|
||||
end
|
||||
|
||||
return cached_config_set
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Initializes a default configuration for user scripts
|
||||
-- @param overwrite If true, a possibly existing configuration is overwritten with default values
|
||||
function alerts_config.initDefaultConfig()
|
||||
-- Current (possibly not-existing, not yet created configset)
|
||||
local configset = alerts_config.getConfigset() or {}
|
||||
|
||||
for alert_type, alert in pairs(alert_consts.alert_types) do
|
||||
-- Alert metadata, including the alert key
|
||||
local meta = alert.meta
|
||||
|
||||
if not configset[alert_type] then
|
||||
-- This is a new alert, prepare to fill it with defaults
|
||||
configset[alert_type] = {}
|
||||
end
|
||||
|
||||
-- Populate config severity
|
||||
if not configset[alert_type]["severity"] then
|
||||
-- No severity found in the configuration, let's add a default
|
||||
local alert_severity = meta.default and meta.default.severity
|
||||
|
||||
if not alert_severity then
|
||||
traceError(TRACE_NORMAL, TRACE_CONSOLE, string.format("Alert %s has no default severity, assuming 'notice'", alert_type))
|
||||
alert_severity = alert_severities.notice
|
||||
end
|
||||
|
||||
configset[alert_type]["severity"] = alert_severity.severity_id
|
||||
end
|
||||
|
||||
-- Populate config filters
|
||||
if not configset[alert_type]["filters"] then
|
||||
-- No filters found in the configuration, let's see if there are default filters and add them
|
||||
local alert_filters = meta.default and meta.default.filters
|
||||
|
||||
configset[alert_type]["filters"] = alert_filters or {}
|
||||
end
|
||||
|
||||
saveConfigset(configset)
|
||||
end
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
function alerts_config.resetConfigset()
|
||||
cached_config_set = nil
|
||||
ntop.delCache(CONFIGSET_KEY)
|
||||
alerts_config.initDefaultConfig()
|
||||
|
||||
return(true)
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
return(alerts_config)
|
||||
441
scripts/lua/modules/control_groups.lua
Normal file
441
scripts/lua/modules/control_groups.lua
Normal file
|
|
@ -0,0 +1,441 @@
|
|||
--
|
||||
-- (C) 2017-21 - ntop.org
|
||||
--
|
||||
-- Module to keep things in common across control_groups of various type
|
||||
|
||||
local dirs = ntop.getDirs()
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
require "lua_utils"
|
||||
local json = require "dkjson"
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local control_groups = {}
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- This is the minimum control_group id which will be used to create new control_groups
|
||||
control_groups.MIN_ASSIGNED_CONTROL_GROUP_ID = 0
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function _get_control_groups_prefix_key()
|
||||
local key = string.format("ntopng.prefs.control_groups")
|
||||
|
||||
return key
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function _get_control_group_ids_key()
|
||||
local key = string.format("%s.control_group_ids", _get_control_groups_prefix_key())
|
||||
|
||||
return key
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function _get_control_group_lock_key()
|
||||
local key = string.format("ntopng.cache.control_groups.control_group_lock")
|
||||
|
||||
return key
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function _get_control_group_details_key(control_group_id)
|
||||
if not control_group_id then
|
||||
-- A control_group id is always needed
|
||||
return nil
|
||||
end
|
||||
|
||||
local key = string.format("%s.control_group_id_%d.details", _get_control_groups_prefix_key(), control_group_id)
|
||||
|
||||
return key
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Returns an array with all the currently assigned control_group ids
|
||||
local function _get_assigned_control_group_ids()
|
||||
local res = {}
|
||||
|
||||
local cur_control_group_ids = ntop.getMembersCache(_get_control_group_ids_key())
|
||||
|
||||
for _, cur_control_group_id in pairs(cur_control_group_ids) do
|
||||
cur_control_group_id = tonumber(cur_control_group_id)
|
||||
res[#res + 1] = cur_control_group_id
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function _assign_control_group_id()
|
||||
-- OVERRIDE
|
||||
-- To stay consistent with the old implementation control_groups_nedge.lua
|
||||
-- control_group_ids are re-used. This means reading the set of currently used control_group
|
||||
-- ids, and chosing the minimum not available control_group id
|
||||
-- This method is called from functions which perform locks so
|
||||
-- there's no risk to assign the same id multiple times
|
||||
local cur_control_group_ids = _get_assigned_control_group_ids()
|
||||
|
||||
local next_control_group_id = control_groups.MIN_ASSIGNED_CONTROL_GROUP_ID
|
||||
|
||||
-- Find the first available control_group id which is not in the set
|
||||
for _, control_group_id in pairsByValues(cur_control_group_ids, asc) do
|
||||
if control_group_id > next_control_group_id then break end
|
||||
|
||||
next_control_group_id = math.max(control_group_id + 1, next_control_group_id)
|
||||
end
|
||||
|
||||
ntop.setMembersCache(_get_control_group_ids_key(), string.format("%d", next_control_group_id))
|
||||
|
||||
return next_control_group_id
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function _lock()
|
||||
local max_lock_duration = 5 -- seconds
|
||||
local max_lock_attempts = 5 -- give up after at most this number of attempts
|
||||
local lock_key = _get_control_group_lock_key()
|
||||
|
||||
for i = 1, max_lock_attempts do
|
||||
local value_set = ntop.setnxCache(lock_key, "1", max_lock_duration)
|
||||
|
||||
if value_set then
|
||||
return true -- lock acquired
|
||||
end
|
||||
|
||||
ntop.msleep(1000)
|
||||
end
|
||||
|
||||
return false -- lock not acquired
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function _unlock()
|
||||
ntop.delCache(_get_control_group_lock_key())
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Persist control_group details to disk. Possibly assign a control_group id
|
||||
-- @param control_group_id The control_group_id of the control_group which needs to be persisted. If nil, a new control_group id is assigned
|
||||
local function _persist(control_group_id, name, members, disabled_alerts)
|
||||
local control_group_details_key = _get_control_group_details_key(control_group_id)
|
||||
|
||||
local control_group_details = {
|
||||
name = name,
|
||||
members = members or {},
|
||||
disabled_alerts = disabled_alerts or {}
|
||||
}
|
||||
|
||||
ntop.setCache(control_group_details_key, json.encode(control_group_details))
|
||||
|
||||
ntop.reloadControlGroups()
|
||||
|
||||
-- Return the assigned control_group_id
|
||||
return control_group_id
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
function control_groups.add_control_group(name, members)
|
||||
local locked = _lock()
|
||||
|
||||
if locked then
|
||||
if name and members then
|
||||
local checks_ok = true
|
||||
|
||||
-- Check if duplicate names exist
|
||||
local same_name_control_group = control_groups.get_control_group_by_name(name)
|
||||
if same_name_control_group then
|
||||
checks_ok = false
|
||||
end
|
||||
|
||||
-- Check if members are valid
|
||||
if check_ok and not control_groups.are_valid_members(members) then
|
||||
checks_ok = false
|
||||
end
|
||||
|
||||
if checks_ok then
|
||||
-- All the checks have succeeded
|
||||
-- Now that everything is ok, the id can be assigned and the control_group can be persisted with the assigned id
|
||||
control_group_id = _assign_control_group_id()
|
||||
_persist(control_group_id, name, members)
|
||||
end
|
||||
end
|
||||
|
||||
_unlock()
|
||||
end
|
||||
|
||||
return control_group_id
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
function control_groups.edit_control_group(control_group_id, new_name, new_members)
|
||||
local ret = false
|
||||
local locked = _lock()
|
||||
|
||||
-- If here, control_group_id has been found
|
||||
if locked then
|
||||
-- Make sure the control_group exists
|
||||
local cur_details = control_groups.get_control_group(control_group_id)
|
||||
|
||||
if cur_details and new_name then
|
||||
local checks_ok = true
|
||||
|
||||
if not new_members then
|
||||
-- In case members have not been sumbitted, new_members
|
||||
-- are assumed to be the existing members
|
||||
new_members = cur_details["members"]
|
||||
end
|
||||
|
||||
-- Check if new_name is not the name of any other existing control_group
|
||||
local same_name_control_group = control_groups.get_control_group_by_name(new_name)
|
||||
if same_name_control_group and same_name_control_group.control_group_id ~= control_group_id then
|
||||
checks_ok = false
|
||||
end
|
||||
|
||||
-- Check if members are valid
|
||||
if checks_ok and not control_groups.are_valid_members(new_members) then
|
||||
checks_ok = false
|
||||
end
|
||||
|
||||
if checks_ok then
|
||||
-- If here, all checks are valid and the control_group can be edited
|
||||
_persist(control_group_id, new_name, new_members, cur_details["disabled_alerts"])
|
||||
-- Control_Group edited successfully
|
||||
ret = true
|
||||
end
|
||||
end
|
||||
|
||||
_unlock()
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
--@brief Marks an alert as disabled for a given control group identified with `control_group_id`
|
||||
--@return True, if alert is disabled with success, false otherwise
|
||||
function control_groups.disable_control_group_flow_alert(control_group_id, alert_key)
|
||||
local ret = false
|
||||
local locked = _lock()
|
||||
|
||||
-- If here, control_group_id has been found
|
||||
if locked then
|
||||
-- Make sure the control_group exists
|
||||
local cur_details = control_groups.get_control_group(control_group_id)
|
||||
|
||||
if cur_details then
|
||||
local checks_ok = true
|
||||
|
||||
-- Check if alert_key is already disabled
|
||||
for _, disabled_alert in pairs(cur_details["disabled_alerts"]) do
|
||||
if tonumber(alert_key) == disabled_alert then
|
||||
checks_ok = false -- Already present, nothing to do
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if checks_ok then
|
||||
-- Disable the alert
|
||||
cur_details["disabled_alerts"][#cur_details["disabled_alerts"] + 1] = tonumber(alert_key)
|
||||
|
||||
-- If here, all checks are valid and the control_group can be edited
|
||||
_persist(control_group_id, cur_details["name"], cur_details["members"], cur_details["disabled_alerts"])
|
||||
|
||||
-- Control_Group edited successfully
|
||||
ret = true
|
||||
end
|
||||
end
|
||||
|
||||
_unlock()
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
--@brief Marks an alert as disabled for a given control group identified with `control_group_id`
|
||||
--@return True, if alert is disabled with success, false otherwise
|
||||
function control_groups.enable_control_group_flow_alert(control_group_id, alert_key)
|
||||
local ret = false
|
||||
local locked = _lock()
|
||||
|
||||
-- If here, control_group_id has been found
|
||||
if locked then
|
||||
-- Make sure the control_group exists
|
||||
local cur_details = control_groups.get_control_group(control_group_id)
|
||||
|
||||
if cur_details then
|
||||
local new_disabled_alerts = {}
|
||||
local checks_ok = false
|
||||
|
||||
-- Check if alert_key is among disabled alerts
|
||||
for _, disabled_alert in pairs(cur_details["disabled_alerts"]) do
|
||||
if tonumber(alert_key) == disabled_alert then
|
||||
checks_ok = true -- Present among the disabled alerts, can remove it
|
||||
-- Don't break, finish the loop to prepare `new_disabled_alerts`
|
||||
else
|
||||
new_disabled_alerts[#new_disabled_alerts + 1] = disabled_alert
|
||||
end
|
||||
end
|
||||
|
||||
if checks_ok then
|
||||
-- If here, all checks are valid and the control_group can be edited
|
||||
_persist(control_group_id, cur_details["name"], cur_details["members"], new_disabled_alerts)
|
||||
|
||||
-- Control_Group edited successfully
|
||||
ret = true
|
||||
end
|
||||
end
|
||||
|
||||
_unlock()
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
function control_groups.delete_control_group(control_group_id)
|
||||
local ret = false
|
||||
local locked = _lock()
|
||||
|
||||
if locked then
|
||||
-- Make sure the control_group exists
|
||||
local cur_details = control_groups.get_control_group(control_group_id)
|
||||
|
||||
if cur_details then
|
||||
-- Remove the key with all the control_group details (e.g., with members)
|
||||
ntop.delCache(_get_control_group_details_key(control_group_id))
|
||||
|
||||
-- Remove the control_group_id from the set of all currently existing control_group ids
|
||||
ntop.delMembersCache(_get_control_group_ids_key(), string.format("%d", control_group_id))
|
||||
|
||||
-- Tell the core to reload control groups
|
||||
ntop.reloadControlGroups()
|
||||
|
||||
ret = true
|
||||
end
|
||||
|
||||
_unlock()
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Returns all the defined control_groups. Control_Groups are returned in a lua table with control_group ids as keys
|
||||
function control_groups.get_all_control_groups()
|
||||
local cur_control_group_ids = _get_assigned_control_group_ids()
|
||||
local res = {}
|
||||
|
||||
for _, control_group_id in pairs(cur_control_group_ids) do
|
||||
local control_group_details = control_groups.get_control_group(control_group_id)
|
||||
|
||||
if control_group_details then res[#res + 1] = control_group_details end
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Returns the number of currently defined control_group ids
|
||||
function control_groups.get_num_control_groups()
|
||||
local cur_control_group_ids = _get_assigned_control_group_ids()
|
||||
|
||||
return #cur_control_group_ids
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
function control_groups.get_control_group(control_group_id, recipient_details)
|
||||
local recipient_details = recipient_details or true
|
||||
local control_group_details
|
||||
local control_group_details_key = _get_control_group_details_key(control_group_id)
|
||||
|
||||
-- Attempt at retrieving the control_group details key and at decoding it from JSON
|
||||
if control_group_details_key then
|
||||
local control_group_details_str = ntop.getCache(control_group_details_key)
|
||||
control_group_details = json.decode(control_group_details_str)
|
||||
|
||||
if control_group_details then
|
||||
-- Add the integer control_group id
|
||||
control_group_details["control_group_id"] = tonumber(control_group_id)
|
||||
end
|
||||
end
|
||||
-- Upon success, control_group details are returned, otherwise nil
|
||||
return control_group_details
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Delete all control_groups
|
||||
function control_groups.cleanup()
|
||||
-- Delete control_group details
|
||||
local cur_control_group_ids = _get_assigned_control_group_ids()
|
||||
for _, control_group_id in pairs(cur_control_group_ids) do
|
||||
control_groups.delete_control_group(control_group_id)
|
||||
end
|
||||
|
||||
local locked = _lock()
|
||||
if locked then
|
||||
-- Delete control_group ids
|
||||
ntop.delCache(_get_control_group_ids_key())
|
||||
|
||||
_unlock()
|
||||
end
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Returns a boolean indicating whether the member is a valid control_group member
|
||||
function control_groups.is_valid_member(member)
|
||||
return isIPv4Network(member)
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Returns a boolean indicating whether the array of members passed contains all valid members
|
||||
function control_groups.are_valid_members(members)
|
||||
for _, member in pairs(members) do
|
||||
if not control_groups.is_valid_member(member) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
function control_groups.get_control_group_by_name(name)
|
||||
local cur_control_group_ids = _get_assigned_control_group_ids()
|
||||
|
||||
for _, control_group_id in pairs(cur_control_group_ids) do
|
||||
local control_group_details = control_groups.get_control_group(control_group_id)
|
||||
|
||||
if control_group_details and control_group_details["name"] and control_group_details["name"] == name then
|
||||
return control_group_details
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
return control_groups
|
||||
|
|
@ -50,20 +50,20 @@ end
|
|||
|
||||
-- #######################
|
||||
|
||||
-- Extracts the information serialized into status_info from the flow
|
||||
-- Extracts the information serialized into alert_info from the flow
|
||||
-- user scripts
|
||||
function flow2statusinfo(flow)
|
||||
local status_info = flow["status_info"]
|
||||
function flow2alertinfo(flow)
|
||||
local alert_info = flow["alert_info"]
|
||||
|
||||
if(status_info and (string.sub(status_info, 1, 1) == "{")) then
|
||||
local res = json.decode(status_info)
|
||||
if(alert_info and (string.sub(alert_info, 1, 1) == "{")) then
|
||||
local res = json.decode(alert_info)
|
||||
|
||||
if(res ~= nil) then
|
||||
return(res)
|
||||
end
|
||||
end
|
||||
|
||||
return(status_info)
|
||||
return(alert_info)
|
||||
end
|
||||
|
||||
-- #######################
|
||||
|
|
@ -94,8 +94,8 @@ function getFlowsFilter()
|
|||
local icmp_type = _GET["icmp_type"]
|
||||
local icmp_code = _GET["icmp_cod"]
|
||||
local dscp_filter = _GET["dscp"]
|
||||
local flow_status = _GET["flow_status"]
|
||||
local flow_status_severity = _GET["flow_status_severity"]
|
||||
local alert_type = _GET["alert_type"]
|
||||
local alert_type_severity = _GET["alert_type_severity"]
|
||||
local deviceIP = _GET["deviceIP"]
|
||||
local inIfIdx = _GET["inIfIdx"]
|
||||
local outIfIdx = _GET["outIfIdx"]
|
||||
|
|
@ -196,21 +196,21 @@ function getFlowsFilter()
|
|||
end
|
||||
end
|
||||
|
||||
if not isEmptyString(flow_status) then
|
||||
if flow_status == "normal" then
|
||||
if not isEmptyString(alert_type) then
|
||||
if alert_type == "normal" then
|
||||
pageinfo["alertedFlows"] = false
|
||||
pageinfo["filteredFlows"] = false
|
||||
elseif flow_status == "alerted" then
|
||||
elseif alert_type == "alerted" then
|
||||
pageinfo["alertedFlows"] = true
|
||||
elseif flow_status == "filtered" then
|
||||
elseif alert_type == "filtered" then
|
||||
pageinfo["filteredFlows"] = true
|
||||
else
|
||||
pageinfo["statusFilter"] = tonumber(flow_status)
|
||||
pageinfo["statusFilter"] = tonumber(alert_type)
|
||||
end
|
||||
end
|
||||
|
||||
if not isEmptyString(flow_status_severity) then
|
||||
local s = alert_consts.severity_groups[flow_status_severity]
|
||||
if not isEmptyString(alert_type_severity) then
|
||||
local s = alert_consts.severity_groups[alert_type_severity]
|
||||
|
||||
if s then
|
||||
pageinfo["statusSeverityFilter"] = s.severity_group_id
|
||||
|
|
@ -1614,14 +1614,14 @@ function printActiveFlowsDropdown(base_url, page_params, ifstats, flowstats, is_
|
|||
|
||||
-- Status selector
|
||||
-- table.clone needed to modify some parameters while keeping the original unchanged
|
||||
local flow_status_params = table.clone(page_params)
|
||||
flow_status_params["flow_status"] = nil
|
||||
local alert_type_params = table.clone(page_params)
|
||||
alert_type_params["alert_type"] = nil
|
||||
|
||||
print[[, '\
|
||||
<div class="btn-group">\
|
||||
<button class="btn btn-link dropdown-toggle" data-toggle="dropdown">]] print(i18n("status")) print(getParamFilter(page_params, "flow_status")) print[[<span class="caret"></span></button>\
|
||||
<button class="btn btn-link dropdown-toggle" data-toggle="dropdown">]] print(i18n("status")) print(getParamFilter(page_params, "alert_type")) print[[<span class="caret"></span></button>\
|
||||
<ul class="dropdown-menu scrollable-dropdown" role="menu">\
|
||||
<li><a class="dropdown-item" href="]] print(getPageUrl(base_url, flow_status_params)) print[[">]] print(i18n("flows_page.all_flows")) print[[</a></li>\]]
|
||||
<li><a class="dropdown-item" href="]] print(getPageUrl(base_url, alert_type_params)) print[[">]] print(i18n("flows_page.all_flows")) print[[</a></li>\]]
|
||||
|
||||
local entries = {
|
||||
{"normal", i18n("flows_page.normal")},
|
||||
|
|
@ -1634,7 +1634,7 @@ function printActiveFlowsDropdown(base_url, page_params, ifstats, flowstats, is_
|
|||
-- Add labels to allow alphabetic sort
|
||||
for status_key, status in pairs(status_stats) do
|
||||
if status.count > 0 then
|
||||
status.label = alert_consts.statusTypeLabel(status_key, true --[[ no html --]])
|
||||
status.label = alert_consts.alertTypeLabel(status_key, true --[[ no html --]])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -1653,7 +1653,7 @@ function printActiveFlowsDropdown(base_url, page_params, ifstats, flowstats, is_
|
|||
entries[#entries + 1] = {"filtered", i18n("flows_page.blocked")}
|
||||
end
|
||||
|
||||
printDropdownEntries(entries, base_url, flow_status_params, "flow_status", page_params.flow_status)
|
||||
printDropdownEntries(entries, base_url, alert_type_params, "alert_type", page_params.alert_type)
|
||||
|
||||
print[[\
|
||||
</ul>\
|
||||
|
|
@ -1661,14 +1661,14 @@ function printActiveFlowsDropdown(base_url, page_params, ifstats, flowstats, is_
|
|||
']]
|
||||
|
||||
-- Flow Status Severity
|
||||
local flow_status_severity_params = table.clone(page_params)
|
||||
flow_status_severity_params["flow_status_severity"] = nil
|
||||
local alert_type_severity_params = table.clone(page_params)
|
||||
alert_type_severity_params["alert_type_severity"] = nil
|
||||
|
||||
print[[, '\
|
||||
<div class="btn-group">\
|
||||
<button class="btn btn-link dropdown-toggle" data-toggle="dropdown">]] print(i18n("flows_page.flow_status_severity")) print(getParamFilter(page_params, "flow_status_severity")) print[[<span class="caret"></span></button>\
|
||||
<button class="btn btn-link dropdown-toggle" data-toggle="dropdown">]] print(i18n("flows_page.alert_type_severity")) print(getParamFilter(page_params, "alert_type_severity")) print[[<span class="caret"></span></button>\
|
||||
<ul class="dropdown-menu scrollable-dropdown" role="menu">\
|
||||
<li><a class="dropdown-item" href="]] print(getPageUrl(base_url, flow_status_severity_params)) print[[">]] print(i18n("flows_page.all_flows")) print[[</a></li>]]
|
||||
<li><a class="dropdown-item" href="]] print(getPageUrl(base_url, alert_type_severity_params)) print[[">]] print(i18n("flows_page.all_flows")) print[[</a></li>]]
|
||||
|
||||
local entries
|
||||
|
||||
|
|
@ -1682,7 +1682,7 @@ function printActiveFlowsDropdown(base_url, page_params, ifstats, flowstats, is_
|
|||
end
|
||||
end
|
||||
|
||||
printDropdownEntries(entries, base_url, flow_status_severity_params, "flow_status_severity", page_params.flow_status_severity)
|
||||
printDropdownEntries(entries, base_url, alert_type_severity_params, "alert_type_severity", page_params.alert_type_severity)
|
||||
|
||||
print[[\
|
||||
</ul>\
|
||||
|
|
@ -1935,20 +1935,20 @@ function getFlowsTableTitle()
|
|||
local active_msg = ""
|
||||
local status_type
|
||||
|
||||
if _GET["flow_status"] then
|
||||
local flow_status_id = tonumber(_GET["flow_status"])
|
||||
if _GET["alert_type"] then
|
||||
local alert_type_id = tonumber(_GET["alert_type"])
|
||||
|
||||
if(flow_status_id ~= nil) then
|
||||
status_type = alert_consts.statusTypeLabel(tonumber(_GET["flow_status"]), true)
|
||||
if(alert_type_id ~= nil) then
|
||||
status_type = alert_consts.alertTypeLabel(tonumber(_GET["alert_type"]), true)
|
||||
else
|
||||
status_type = firstToUpper(_GET["flow_status"])
|
||||
status_type = firstToUpper(_GET["alert_type"])
|
||||
end
|
||||
end
|
||||
|
||||
if _GET["flow_status_severity"] then
|
||||
local flow_status_severity = _GET["flow_status_severity"]
|
||||
if _GET["alert_type_severity"] then
|
||||
local alert_type_severity = _GET["alert_type_severity"]
|
||||
|
||||
local s = alert_consts.severity_groups[flow_status_severity]
|
||||
local s = alert_consts.severity_groups[alert_type_severity]
|
||||
active_msg = active_msg .. " ".. i18n(s.i18n_title)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -301,12 +301,14 @@ function format_utils.formatConnectionIssues(info)
|
|||
what[#what + 1] = i18n("alerts_dashboard.x_lost", {lost = format_utils.formatValue(lost)})
|
||||
end
|
||||
|
||||
if info.cli2srv_pkts > 0 then
|
||||
what[#what + 1] = i18n("alerts_dashboard.out_of_x_total_packets", {tot = format_utils.formatValue(info.cli2srv_pkts)})
|
||||
end
|
||||
if retx + ooo + lost > 0 then
|
||||
if info.cli2srv_pkts > 0 then
|
||||
what[#what + 1] = i18n("alerts_dashboard.out_of_x_total_packets", {tot = format_utils.formatValue(info.cli2srv_pkts)})
|
||||
end
|
||||
|
||||
if #what > 0 then
|
||||
res = res.." "..string.format("[%s: %s]", i18n("client_to_server"), table.concat(what, ", "))
|
||||
if #what > 0 then
|
||||
res = res.." "..string.format("[%s: %s]", i18n("client_to_server"), table.concat(what, ", "))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -326,12 +328,15 @@ function format_utils.formatConnectionIssues(info)
|
|||
if lost > 0 then
|
||||
what[#what + 1] = i18n("alerts_dashboard.x_lost", {lost = format_utils.formatValue(lost)})
|
||||
end
|
||||
if info.srv2cli_pkts > 0 then
|
||||
what[#what + 1] = i18n("alerts_dashboard.out_of_x_total_packets", {tot = format_utils.formatValue(info.srv2cli_pkts)})
|
||||
end
|
||||
|
||||
if #what > 0 then
|
||||
res = res.." "..string.format("[%s: %s]", i18n("server_to_client"), table.concat(what, ", "))
|
||||
if retx + ooo + lost > 0 then
|
||||
if info.srv2cli_pkts > 0 then
|
||||
what[#what + 1] = i18n("alerts_dashboard.out_of_x_total_packets", {tot = format_utils.formatValue(info.srv2cli_pkts)})
|
||||
end
|
||||
|
||||
if #what > 0 then
|
||||
res = res.." "..string.format("[%s: %s]", i18n("server_to_client"), table.concat(what, ", "))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -430,7 +430,7 @@ local function validateBroadcastUnicast(mode)
|
|||
return validateChoice(modes, mode)
|
||||
end
|
||||
|
||||
local function validateFlowStatusNumber(status)
|
||||
local function validateAlertTypeNumber(status)
|
||||
if not validateNumber(status) then
|
||||
return false
|
||||
end
|
||||
|
|
@ -439,17 +439,17 @@ local function validateFlowStatusNumber(status)
|
|||
return((num >= 0) and (num < 2^8))
|
||||
end
|
||||
|
||||
local function validateFlowStatus(mode)
|
||||
local function validateAlertType(mode)
|
||||
local modes = {"normal", "alerted", "filtered"}
|
||||
|
||||
if validateFlowStatusNumber(mode) then
|
||||
if validateAlertTypeNumber(mode) then
|
||||
return true
|
||||
end
|
||||
|
||||
return validateChoice(modes, mode)
|
||||
end
|
||||
|
||||
local function validateFlowStatusSeverity(mode)
|
||||
local function validateAlertTypeSeverity(mode)
|
||||
local modes = {"notice_or_lower", "warning", "error_or_higher"}
|
||||
|
||||
return validateChoice(modes, mode)
|
||||
|
|
@ -1525,6 +1525,8 @@ local known_parameters = {
|
|||
["script_type"] = validateSingleWord,
|
||||
["script_subdir"] = validateSingleWord,
|
||||
["script_key"] = validateSingleWord,
|
||||
["alert_key"] = validateNumber,
|
||||
["alert_addr"] = validateIpAddress,
|
||||
["search_script"] = validateSingleWord,
|
||||
["field_alias"] = validateListOfTypeInline(validateFieldAlias),
|
||||
["dscp_class"] = validateSingleWord,
|
||||
|
|
@ -1837,9 +1839,9 @@ local known_parameters = {
|
|||
["delete_user"] = validateSingleWord,
|
||||
["drop_flow_policy"] = validateBool, -- true if target flow should be dropped
|
||||
["traffic_type"] = validateBroadcastUnicast, -- flows_stats.lua
|
||||
["flow_status"] = validateFlowStatus, -- flows_stats.lua
|
||||
["flow_status_severity"] = validateFlowStatusSeverity, -- flows_stats.lua
|
||||
["flow_status_num"] = validateFlowStatusNumber, -- charts
|
||||
["alert_type"] = validateAlertType, -- flows_stats.lua
|
||||
["alert_type_severity"] = validateAlertTypeSeverity, -- flows_stats.lua
|
||||
["alert_type_num"] = validateAlertTypeNumber, -- charts
|
||||
["tcp_flow_state"] = validateTCPFlowState, -- flows_stats.lua
|
||||
["traffic_profile"] = http_lint.validateTrafficProfile, -- flows_stats.lua
|
||||
["include_unlimited"] = validateBool, -- pool_details_ndpi.lua
|
||||
|
|
|
|||
|
|
@ -2802,33 +2802,28 @@ end
|
|||
|
||||
-- ###############################################
|
||||
|
||||
function formatElephantFlowStatus(flowstatus_info, local2remote)
|
||||
function formatElephantAlertType(flowalert_info)
|
||||
local threshold = ""
|
||||
local res = ""
|
||||
|
||||
if not flowstatus_info then
|
||||
if not flowalert_info then
|
||||
return i18n("flow_details.elephant_flow")
|
||||
end
|
||||
|
||||
if local2remote then
|
||||
res = i18n("flow_details.elephant_flow_l2r")
|
||||
local l2r_bytes = bytesToSize(flowalert_info["l2r_bytes"])
|
||||
|
||||
if flowstatus_info["elephant.l2r_threshold"] then
|
||||
threshold = flowstatus_info["elephant.l2r_threshold"]
|
||||
end
|
||||
else
|
||||
res = i18n("flow_details.elephant_flow_r2l")
|
||||
|
||||
if flowstatus_info["elephant.r2l_threshold"] then
|
||||
threshold = flowstatus_info["elephant.r2l_threshold"]
|
||||
end
|
||||
if flowalert_info["l2r_bytes"] > flowalert_info["l2r_threshold"] then
|
||||
l2r_bytes = l2r_bytes .." > "..bytesToSize(flowalert_info["l2r_threshold"])
|
||||
end
|
||||
|
||||
local r2l_bytes = bytesToSize(flowalert_info["r2l_bytes"])
|
||||
if flowalert_info["r2l_bytes"] > flowalert_info["r2l_threshold"] then
|
||||
r2l_bytes = r2l_bytes .. " > "..bytesToSize(flowalert_info["r2l_threshold"])
|
||||
end
|
||||
|
||||
res = i18n("flow_details.elephant_flow")
|
||||
res = string.format("%s<sup><i class='fas fa-info-circle' aria-hidden='true' title='"..i18n("flow_details.elephant_flow_descr").."'></i></sup>", res)
|
||||
|
||||
if threshold ~= "" then
|
||||
res = string.format("%s [%s]", res, i18n("flow_details.elephant_exceeded", {vol = bytesToSize(threshold)}))
|
||||
end
|
||||
res = string.format("%s %s", res, i18n("flow_details.elephant_exceeded", {l2r = l2r_bytes, r2l = r2l_bytes}))
|
||||
|
||||
return res
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ package.path = dirs.installdir .. "/scripts/lua/modules/pools/?.lua;" .. package
|
|||
local json = require "dkjson"
|
||||
local alert_severities = require "alert_severities"
|
||||
local alert_consts = require "alert_consts"
|
||||
local alert_severities = require "alert_severities"
|
||||
local user_scripts = require "user_scripts"
|
||||
local endpoints = require("endpoints")
|
||||
|
||||
-- ##############################################
|
||||
|
|
@ -26,12 +28,30 @@ local default_builtin_minimum_severity = alert_severities.info.severity_id -- mi
|
|||
|
||||
-- ##############################################
|
||||
|
||||
local function _bitmap_from_user_script_categories(user_script_categories)
|
||||
local bitmap = 0
|
||||
|
||||
for _, category_id in ipairs(user_script_categories) do
|
||||
bitmap = bitmap | (1 << category_id)
|
||||
end
|
||||
|
||||
return bitmap
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Performs Initialization operations performed during startup
|
||||
function recipients.initialize()
|
||||
-- Initialize builtin recipients, that is, recipients always existing an not editable from the UI
|
||||
-- For each builtin configuration type, a configuration and a recipient is created
|
||||
local all_categories = {}
|
||||
for _, category in pairs(user_scripts.script_categories) do
|
||||
all_categories[#all_categories + 1] = category.id
|
||||
end
|
||||
|
||||
for endpoint_key, endpoint in pairs(endpoints.get_types()) do
|
||||
if endpoint.builtin then
|
||||
|
||||
-- Add the configuration
|
||||
local res = endpoints.add_config(
|
||||
endpoint_key --[[ the type of the endpoint--]],
|
||||
|
|
@ -42,10 +62,11 @@ function recipients.initialize()
|
|||
-- Endpoint successfully created (or existing)
|
||||
if res and res.endpoint_id then
|
||||
-- And the recipient
|
||||
|
||||
local recipient_res = recipients.add_recipient(
|
||||
res.endpoint_id --[[ the id of the endpoint --]],
|
||||
"builtin_recipient_"..endpoint_key --[[ the name of the endpoint recipient --]],
|
||||
nil, -- User script categories
|
||||
all_categories,
|
||||
default_builtin_minimum_severity,
|
||||
false, -- Do Not add it to every pool automatically
|
||||
{} --[[ no recipient params --]]
|
||||
|
|
@ -57,8 +78,16 @@ function recipients.initialize()
|
|||
-- Register all existing recipients in C to make sure ntopng can start with all the
|
||||
-- existing recipients properly loaded and ready for notification enqueues/dequeues
|
||||
for _, recipient in pairs(recipients.get_all_recipients()) do
|
||||
ntop.recipient_register(recipient.recipient_id)
|
||||
ntop.recipient_register(recipient.recipient_id, recipient.minimum_severity, _bitmap_from_user_script_categories(recipient.user_script_categories))
|
||||
end
|
||||
|
||||
-- Now specify which recipients are "flow" recipients and tell this information to C++
|
||||
|
||||
local pools_alert_utils = require "pools_alert_utils"
|
||||
local flow_pools = require "flow_pools"
|
||||
|
||||
local all_flow_recipients = pools_alert_utils.get_entity_recipients_by_pool_id(alert_consts.alert_entities.flow.entity_id, flow_pools.DEFAULT_POOL_ID)
|
||||
flow_pools:create():set_flow_recipients(all_flow_recipients)
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
|
@ -243,6 +272,8 @@ function recipients.add_recipient(endpoint_id, endpoint_recipient_name, user_scr
|
|||
if locked then
|
||||
local ec = endpoints.get_endpoint_config(endpoint_id)
|
||||
|
||||
|
||||
|
||||
if ec["status"] == "OK" and endpoint_recipient_name then
|
||||
-- Is the endpoint already existing?
|
||||
local same_recipient = recipients.get_recipient_by_name(endpoint_recipient_name)
|
||||
|
|
@ -264,7 +295,7 @@ function recipients.add_recipient(endpoint_id, endpoint_recipient_name, user_scr
|
|||
_set_endpoint_recipient_params(endpoint_id, recipient_id, endpoint_recipient_name, user_script_categories, minimum_severity, safe_params)
|
||||
|
||||
-- Finally, register the recipient in C so we can start enqueuing/dequeuing notifications
|
||||
ntop.recipient_register(recipient_id)
|
||||
ntop.recipient_register(recipient_id, minimum_severity, _bitmap_from_user_script_categories(user_script_categories))
|
||||
|
||||
-- Set a flag to indicate that a recipient has been created
|
||||
if not ec.endpoint_conf.builtin and isEmptyString(ntop.getPref(recipients.FIRST_RECIPIENT_CREATED_CACHE_KEY)) then
|
||||
|
|
@ -331,7 +362,7 @@ function recipients.edit_recipient(recipient_id, endpoint_recipient_name, user_s
|
|||
|
||||
-- Finally, register the recipient in C to make sure also the C knows about this edit
|
||||
-- and periodic scripts can be reloaded
|
||||
ntop.recipient_register(tonumber(rc["endpoint_id"]))
|
||||
ntop.recipient_register(tonumber(rc["endpoint_id"]), minimum_severity, _bitmap_from_user_script_categories(user_script_categories))
|
||||
|
||||
res = {status = "OK"}
|
||||
end
|
||||
|
|
@ -472,7 +503,6 @@ end
|
|||
-- ##############################################
|
||||
|
||||
function recipients.get_recipient(recipient_id, include_stats)
|
||||
local user_scripts = require "user_scripts"
|
||||
local recipient_details
|
||||
local recipient_details_key = _get_recipient_details_key(recipient_id)
|
||||
|
||||
|
|
@ -608,7 +638,7 @@ function recipients.dispatch_notification(notification, current_script)
|
|||
local is_high_priority = is_notification_high_priority(notification)
|
||||
|
||||
for _, recipient_id in pairs(recipients) do
|
||||
ntop.recipient_enqueue(recipient_id, is_high_priority, json_notification, notification.alert_severity)
|
||||
ntop.recipient_enqueue(recipient_id, is_high_priority, json_notification, notification.alert_severity, current_script and current_script.category and current_script.category.id)
|
||||
end
|
||||
end
|
||||
else
|
||||
|
|
|
|||
|
|
@ -254,8 +254,14 @@ local function load_definitions(defs_dir, runtime_path)
|
|||
return(false)
|
||||
end
|
||||
|
||||
-- tprint({"copying", fname, defs_dir, runtime_path})
|
||||
file_utils.copy_file(fname, defs_dir, runtime_path)
|
||||
local ntopng_alert_definition = os_utils.fixPath(dirs.installdir .. "/scripts/lua/modules/alert_definitions/"..fname)
|
||||
if ntop.exists(ntopng_alert_definition) then
|
||||
-- Prevent plugin alert definitions from overwriting alert definitions under modules
|
||||
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Cannot copy plugin alert definition from %s (alert already defined in %s)", full_path, ntopng_alert_definition))
|
||||
else
|
||||
-- tprint({"copying", fname, defs_dir, runtime_path})
|
||||
file_utils.copy_file(fname, defs_dir, runtime_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -654,6 +660,10 @@ function plugins_utils.loadPlugins(community_plugins_only)
|
|||
-- Reload the periodic scripts to load the new plugins
|
||||
ntop.reloadPeriodicScripts()
|
||||
|
||||
-- Reload alerts configuration
|
||||
local alerts_config = require "alerts_config"
|
||||
alerts_config.initDefaultConfig()
|
||||
|
||||
-- Reload user scripts with their configurations
|
||||
local user_scripts = require "user_scripts"
|
||||
user_scripts.initDefaultConfig()
|
||||
|
|
|
|||
|
|
@ -42,6 +42,28 @@ function flow_pools:get_all_members() return {} end
|
|||
|
||||
-- ##############################################
|
||||
|
||||
--@brief Tells the C++ core about the flow recipients
|
||||
function flow_pools:set_flow_recipients(recipients)
|
||||
-- Create a bitmap of all recipients responsible for flows (pool_id in this case is ignored)
|
||||
local recipients_bitmap = 0
|
||||
|
||||
for _, recipient_id in ipairs(recipients) do
|
||||
recipients_bitmap = recipients_bitmap | (1 << recipient_id)
|
||||
end
|
||||
|
||||
-- Tell the C++ that flow recipients have changed
|
||||
ntop.recipient_set_flow_recipients(recipients_bitmap)
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
--@brief Method called after a successful execution of method persist
|
||||
function flow_pools:_post_persist(pool_id, name, members, recipients)
|
||||
self:set_flow_recipients(recipients)
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
function flow_pools:default_only()
|
||||
-- This is a dummy, default-only pool
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -239,6 +239,12 @@ function pools:_unlock() ntop.delCache(self:_get_pool_lock_key()) end
|
|||
|
||||
-- ##############################################
|
||||
|
||||
--@brief Method called after a successful execution of method persist
|
||||
function pools:_post_persist(pool_id, name, members, recipients)
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- @brief Persist pool details to disk. Possibly assign a pool id
|
||||
-- @param pool_id The pool_id of the pool which needs to be persisted. If nil, a new pool id is assigned
|
||||
function pools:_persist(pool_id, name, members, recipients)
|
||||
|
|
@ -259,6 +265,8 @@ function pools:_persist(pool_id, name, members, recipients)
|
|||
|
||||
ntop.setCache(pool_details_key, json.encode(pool_details))
|
||||
|
||||
self:_post_persist(pool_id, name, members, recipients)
|
||||
|
||||
ntop.reloadPeriodicScripts()
|
||||
|
||||
-- Return the assigned pool_id
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ function pools_alert_utils.get_entity_recipients_by_pool_id(entity_id, pool_id,
|
|||
end
|
||||
|
||||
if recipient_ok then
|
||||
if recipient["recipient_minimum_severity"] ~= nil and
|
||||
if alert_severity and recipient["recipient_minimum_severity"] ~= nil and
|
||||
alert_severity < recipient["recipient_minimum_severity"] then
|
||||
-- If the current alert severity is less than the minimum requested severity
|
||||
-- exclude the recipient
|
||||
|
|
|
|||
|
|
@ -1,87 +0,0 @@
|
|||
--
|
||||
-- (C) 2020 - ntop.org
|
||||
--
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local flow_keys = {
|
||||
ntopng = {
|
||||
status_normal = 0,
|
||||
status_blacklisted = 1,
|
||||
status_blacklisted_country = 2,
|
||||
status_blocked = 3,
|
||||
status_data_exfiltration = 4,
|
||||
status_device_protocol_not_allowed = 5,
|
||||
status_dns_data_exfiltration = 6,
|
||||
status_dns_invalid_query = 7,
|
||||
status_elephant_local_to_remote = 8,
|
||||
status_elephant_remote_to_local = 9,
|
||||
status_external_alert = 10,
|
||||
status_longlived = 11,
|
||||
status_low_goodput = 12,
|
||||
status_malicious_signature = 13,
|
||||
status_not_purged = 14,
|
||||
status_potentially_dangerous = 15,
|
||||
status_remote_to_remote = 16,
|
||||
status_suspicious_tcp_probing = 17,
|
||||
status_suspicious_tcp_syn_probing = 18,
|
||||
status_tcp_connection_issues = 19,
|
||||
status_tcp_connection_refused = 20,
|
||||
status_tcp_severe_connection_issues = 21,
|
||||
status_tls_certificate_expired = 22,
|
||||
status_tls_certificate_mismatch = 23,
|
||||
status_tls_old_protocol_version = 24,
|
||||
status_tls_unsafe_ciphers = 25,
|
||||
status_udp_unidirectional = 26,
|
||||
status_web_mining_detected = 27,
|
||||
status_tls_certificate_selfsigned = 28,
|
||||
status_suspicious_file_transfer = 29,
|
||||
status_known_proto_on_non_std_port = 30,
|
||||
status_flow_risk = 31,
|
||||
status_unexpected_dhcp_server = 32,
|
||||
status_unexpected_dns_server = 33,
|
||||
status_unexpected_smtp_server = 34,
|
||||
status_unexpected_ntp_server = 35,
|
||||
status_zero_tcp_window = 36,
|
||||
status_iec_invalid_transition = 37,
|
||||
status_remote_to_local_insecure_proto = 38,
|
||||
status_ndpi_url_possible_xss = 39,
|
||||
status_ndpi_url_possible_sql_injection = 40,
|
||||
status_ndpi_url_possible_rce_injection = 41,
|
||||
status_ndpi_http_suspicious_user_agent = 42,
|
||||
status_ndpi_http_numeric_ip_host = 43,
|
||||
status_ndpi_http_suspicious_url = 44,
|
||||
status_ndpi_http_suspicious_header = 45,
|
||||
status_ndpi_tls_not_carrying_https = 46,
|
||||
status_ndpi_suspicious_dga_domain = 47,
|
||||
status_ndpi_malformed_packet = 48,
|
||||
status_ndpi_ssh_obsolete = 49,
|
||||
status_ndpi_smb_insecure_version = 50,
|
||||
status_ndpi_tls_suspicious_esni_usage = 51,
|
||||
status_ndpi_unsafe_protocol = 52,
|
||||
status_ndpi_dns_suspicious_traffic = 53,
|
||||
status_ndpi_tls_missing_sni = 54,
|
||||
|
||||
-- Add here additional flow statuses when writing ntopng plugins.
|
||||
-- User plugins should use statuses under key user.
|
||||
-- WARNING: no not overlap with user; MAXIMUM status is 58 unless
|
||||
-- class Bitmap in Flow has been extended to accomodate more than
|
||||
-- 64 bits
|
||||
},
|
||||
user = {
|
||||
status_user_01 = 59,
|
||||
status_user_02 = 60,
|
||||
status_user_03 = 61,
|
||||
status_user_04 = 62,
|
||||
status_user_05 = 63, -- Seems this is not seen by Lua, use until 62
|
||||
-- WARNING: do not add any extra status greater than 63
|
||||
-- unless class Bitmap inside Flow has been extended to
|
||||
-- accomodate more than 64 bits.
|
||||
},
|
||||
}
|
||||
|
||||
-- ##############################################
|
||||
|
||||
return flow_keys
|
||||
|
||||
-- ##############################################
|
||||
|
|
@ -61,7 +61,7 @@ local REQUEST_PERIODIC_USER_SCRIPTS_RUN_KEY = "ntopng.cache.ifid_%i.user_scripts
|
|||
local NON_TRAFFIC_ELEMENT_CONF_KEY = "all"
|
||||
local NON_TRAFFIC_ELEMENT_ENTITY = "no_entity"
|
||||
local ALL_HOOKS_CONFIG_KEY = "all"
|
||||
local CONFIGSET_KEY = "ntopng.prefs.user_scripts.configset_v3"
|
||||
local CONFIGSET_KEY = "ntopng.prefs.user_scripts.configset_v3" -- Keep in sync with ntop_defines.h FLOW_CALLBACKS_CONFIG
|
||||
user_scripts.DEFAULT_CONFIGSET_ID = 0
|
||||
|
||||
-- NOTE: the subdir id must be unique
|
||||
|
|
@ -184,51 +184,26 @@ local available_subdirs = {
|
|||
-- User script execution filters (field names are those that arrive from the C Flow.cpp)
|
||||
filter = {
|
||||
-- Default fields populated automatically when creating filters
|
||||
default_fields = {"srv_addr", "srv_port", "l7_proto", "proto" },
|
||||
default_fields = { "srv_addr", },
|
||||
-- All possible filter fields
|
||||
available_fields = {
|
||||
cli_addr = {
|
||||
lint = http_lint.validateNetwork,
|
||||
match = function(context, val)
|
||||
local client_ip = flow.getClientIp()
|
||||
-- Attempt exact match
|
||||
if client_ip == val then return true end
|
||||
-- Attempt IPv4 network match
|
||||
local network, netmask = ipv4_utils.cidr_2_addr(val)
|
||||
if network and netmask then return ipv4_utils.includes(network, netmask, client_ip) end
|
||||
-- No match
|
||||
return false
|
||||
-- NO match, match is done in C++
|
||||
end,
|
||||
sqlite = function(val)
|
||||
-- Keep in sync with SQLite database schema declared in AlertsManager.cpp
|
||||
return string.format("cli_addr = '%s'", val)
|
||||
return string.format("cli_addr = '%s'", val)
|
||||
end,
|
||||
find = function(alert, alert_json, filter, val)
|
||||
return (alert[filter] and (alert[filter] == val))
|
||||
end,
|
||||
},
|
||||
cli_port = {
|
||||
lint = http_lint.validatePort,
|
||||
match = function(context, val) return flow.getClientPort() == tonumber(val) end,
|
||||
sqlite = function(val)
|
||||
-- Keep in sync with SQLite database schema declared in AlertsManager.cpp
|
||||
return string.format("cli_port = %u", val)
|
||||
end,
|
||||
find = function(alert, alert_json, filter, val)
|
||||
return (alert[filter] and (tonumber(alert[filter]) == tonumber(val)))
|
||||
end,
|
||||
},
|
||||
srv_addr = {
|
||||
lint = http_lint.validateNetwork,
|
||||
match = function(context, val)
|
||||
local server_ip = flow.getServerIp()
|
||||
-- Attempt exact match
|
||||
if server_ip == val then return true end
|
||||
-- Attempt IPv4 network match
|
||||
local network, netmask = ipv4_utils.cidr_2_addr(val)
|
||||
if network and netmask then return ipv4_utils.includes(network, netmask, server_ip) end
|
||||
-- No match
|
||||
return false
|
||||
-- NO match, match is done in C++
|
||||
end,
|
||||
sqlite = function(val)
|
||||
-- Keep in sync with SQLite database schema declared in AlertsManager.cpp
|
||||
|
|
@ -238,124 +213,6 @@ local available_subdirs = {
|
|||
return (alert[filter] and (alert[filter] == val))
|
||||
end,
|
||||
},
|
||||
srv_port = {
|
||||
lint = http_lint.validatePort,
|
||||
match = function(context, val) return flow.getServerPort() == tonumber(val) end,
|
||||
sqlite = function(val)
|
||||
-- Keep in sync with SQLite database schema declared in AlertsManager.cpp
|
||||
return string.format("srv_port = %u", val)
|
||||
end,
|
||||
find = function(alert, alert_json, filter, val)
|
||||
return (alert[filter] and (tonumber(alert[filter]) == tonumber(val)))
|
||||
end,
|
||||
},
|
||||
l7_proto = {
|
||||
lint = http_lint.validateProtocolIdOrName,
|
||||
match = function(context, val)
|
||||
-- If val is the application name, then it is converted to application id
|
||||
if not tonumber(val) then val = interface.getnDPIProtoId(val) end
|
||||
-- For integers represented as strings
|
||||
val = tonumber(val)
|
||||
-- Check for equality on either the master or application ids
|
||||
return flow.getnDPIMasterProtoId() == val or flow.getnDPIAppProtoId() == val
|
||||
end,
|
||||
sqlite = function(val)
|
||||
-- If val is the application name, then it is converted to application id
|
||||
if not tonumber(val) then val = interface.getnDPIProtoId(val) end
|
||||
-- Keep in sync with SQLite database schema declared in AlertsManager.cpp
|
||||
-- Match both on the master and app proto
|
||||
return string.format("(l7_proto = %u OR l7_master_proto = %u)", val, val)
|
||||
end,
|
||||
find = function(alert, alert_json, filter, val)
|
||||
-- Converting value into it's id if value is under string format
|
||||
local value = tonumber(val)
|
||||
if not value then value = interface.getnDPIProtoId(val) end
|
||||
|
||||
return (alert[filter] and (tonumber(alert[filter]) == value))
|
||||
end,
|
||||
},
|
||||
proto = {
|
||||
lint = http_lint.validateProtocolIdOrName,
|
||||
match = function(context, val)
|
||||
-- If val is the protocol name, then it is converted to L4 protocol id
|
||||
if not tonumber(val) then val = l4_proto_to_id(val) end
|
||||
-- Check for equality on either the master or application protocol
|
||||
return flow.getProtocol() == tonumber(val)
|
||||
end,
|
||||
sqlite = function(val)
|
||||
-- Keep in sync with SQLite database schema declared in AlertsManager.cpp
|
||||
return string.format("proto = %u", val)
|
||||
end,
|
||||
find = function(alert, alert_json, filter, val)
|
||||
-- Converting value into it's id if value is under string format
|
||||
local value = tonumber(val)
|
||||
if not value then value = l4_proto_to_id(val) end
|
||||
|
||||
return (alert[filter] and (tonumber(alert[filter]) == value))
|
||||
end,
|
||||
},
|
||||
flow_risk_bitmap = {
|
||||
lint = http_lint.validateNumber,
|
||||
match = function(context, val)
|
||||
-- Convert the string-bitmap to a number
|
||||
val = tonumber(val)
|
||||
-- Check if there's at least one risk in common between val
|
||||
-- and the actual flow bitmap of risks
|
||||
return (val & flow.getRiskBitmap()) ~= 0
|
||||
end,
|
||||
sqlite = function(val)
|
||||
-- Keep in sync with SQLite database schema declared in AlertsManager.cpp
|
||||
return string.format("flow_risk_bitmap = %u", val)
|
||||
end,
|
||||
find = function(alert, alert_json, filter, val)
|
||||
return (alert[filter] and (tonumber(alert[filter]) == tonumber(val)))
|
||||
end,
|
||||
},
|
||||
info = {
|
||||
lint = http_lint.validateSingleWord,
|
||||
match = function(context, val)
|
||||
-- Search for substring val inside the flow info field
|
||||
return not not flow.getFlowInfoField():find(val)
|
||||
end,
|
||||
sqlite = function(val)
|
||||
-- Keep in sync with SQLite database schema declared in AlertsManager.cpp
|
||||
-- As the info is stored inside the JSON alert, it is necessary to
|
||||
-- use sqlite json_extract to access it
|
||||
return string.format("json_extract(alert_json, '$.info') like '%%%s%%'", val)
|
||||
end,
|
||||
find = function(alert, alert_json, filter, val)
|
||||
-- Search for substring val inside the flow info field
|
||||
if alert_json and val then
|
||||
return (alert_json[filter] and alert_json[filter]:find(val))
|
||||
end
|
||||
return false
|
||||
end,
|
||||
},
|
||||
l7_cat = {
|
||||
lint = http_lint.validateCategory,
|
||||
match = function(context, val)
|
||||
-- If val is the application name, then it is converted to application id
|
||||
if not tonumber(val) then val = interface.getnDPICategoryId(val) end
|
||||
-- For integers represented as strings
|
||||
val = tonumber(val)
|
||||
-- Check for equality on either the master or application ids
|
||||
return flow.getnDPICategoryId() == val
|
||||
end,
|
||||
sqlite = function(val)
|
||||
-- If val is the application name, then it is converted to application id
|
||||
if not tonumber(val) then val = interface.getnDPICategoryId(val) end
|
||||
-- Keep in sync with SQLite database schema declared in AlertsManager.cpp
|
||||
-- Match both on the master and app proto
|
||||
return string.format("l7_cat = %u", val)
|
||||
end,
|
||||
find = function(alert, alert_json, filter, val)
|
||||
-- If val is the application name, then it is converted to application id
|
||||
local value = tonumber(val)
|
||||
if not value then value = interface.getnDPICategoryId(val) end
|
||||
|
||||
return (alert[filter] and (tonumber(alert[filter]) == value))
|
||||
end,
|
||||
},
|
||||
},
|
||||
},
|
||||
-- No pools for flows
|
||||
|
|
@ -789,7 +646,7 @@ local function init_user_script(user_script, mod_fname, full_path, plugin, scrip
|
|||
end
|
||||
|
||||
-- Expand hooks
|
||||
if(user_script.hooks["all"] ~= nil) then
|
||||
if(user_script.hooks and user_script.hooks["all"] ~= nil) then
|
||||
local callback = user_script.hooks["all"]
|
||||
user_script.hooks["all"] = nil
|
||||
|
||||
|
|
@ -834,7 +691,7 @@ local function loadAndCheckScript(mod_fname, full_path, plugin, script_type, sub
|
|||
return(nil)
|
||||
end
|
||||
|
||||
if(table.empty(user_script.hooks)) then
|
||||
if(subdir ~= "flow" and table.empty(user_script.hooks)) then
|
||||
traceError(TRACE_WARNING, TRACE_CONSOLE, string.format("No 'hooks' defined in user script '%s', skipping", mod_fname))
|
||||
return(nil)
|
||||
end
|
||||
|
|
@ -951,7 +808,7 @@ function user_scripts.load(ifid, script_type, subdir, options)
|
|||
-- Checks passed, now load the script information
|
||||
|
||||
-- Populate hooks fast lookup table
|
||||
for hook, hook_fn in pairs(user_script.hooks) do
|
||||
for hook, hook_fn in pairs(user_script.hooks or {}) do
|
||||
-- load previously computed benchmarks (if any)
|
||||
-- benchmarks are loaded even if their computation is disabled with a do_benchmark ~= true
|
||||
if(rv.hooks[hook] == nil) then
|
||||
|
|
@ -1125,6 +982,9 @@ local function saveConfigset(configset)
|
|||
-- Reload the periodic scripts as the configuration has changed
|
||||
ntop.reloadPeriodicScripts()
|
||||
|
||||
-- Reload flow callbacks executed in C++
|
||||
ntop.reloadFlowCallbacks()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
|
@ -1137,10 +997,6 @@ local cached_config_set = nil
|
|||
function user_scripts.getConfigset()
|
||||
if not cached_config_set then
|
||||
cached_config_set = json.decode(ntop.getCache(CONFIGSET_KEY))
|
||||
|
||||
if not cached_config_set then
|
||||
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Unable to load a valid configset"))
|
||||
end
|
||||
end
|
||||
|
||||
return cached_config_set
|
||||
|
|
@ -1441,23 +1297,16 @@ end
|
|||
|
||||
-- @brief Initializes a default configuration for user scripts
|
||||
-- @param overwrite If true, a possibly existing configuration is overwritten with default values
|
||||
function user_scripts.initDefaultConfig(overwrite)
|
||||
if not overwrite and json.decode(ntop.getCache(CONFIGSET_KEY)) then
|
||||
-- Nothing to do, already initialized
|
||||
return
|
||||
end
|
||||
|
||||
function user_scripts.initDefaultConfig()
|
||||
local ifid = getSystemInterfaceId()
|
||||
-- Default per user-script configuration
|
||||
local default_conf = {}
|
||||
-- Default per user-script filters
|
||||
local default_filters = {}
|
||||
|
||||
if default_conf then
|
||||
-- Drop possible nested values due to a previous bug
|
||||
default_conf.config = nil
|
||||
end
|
||||
|
||||
-- Current (possibly not-existing, not yet created configset)
|
||||
local configset = user_scripts.getConfigset() or {}
|
||||
-- Default per user-script configuration
|
||||
local default_conf = configset.config or {}
|
||||
-- Default per user-script filters
|
||||
local default_filters = configset.filters or {}
|
||||
|
||||
for type_id, script_type in pairs(user_scripts.script_types) do
|
||||
for _, subdir in pairs(script_type.subdirs) do
|
||||
local scripts = user_scripts.load(ifid, script_type, subdir, {return_all = true})
|
||||
|
|
@ -1485,25 +1334,31 @@ function user_scripts.initDefaultConfig(overwrite)
|
|||
|
||||
if usermod.filter and usermod.filter.default_filters then
|
||||
default_filters[subdir] = default_filters[subdir] or {}
|
||||
default_filters[subdir][key] = usermod.filter.default_filters
|
||||
|
||||
if not default_filters[subdir][key] then
|
||||
-- Do not override filter of an existing configuration
|
||||
default_filters[subdir][key] = usermod.filter.default_filters
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- This is the new configset with all defaults
|
||||
local configset = {
|
||||
config = default_conf,
|
||||
filters = default_filters,
|
||||
}
|
||||
|
||||
saveConfigset(configset)
|
||||
saveConfigset(configset)
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
function user_scripts.resetConfigset()
|
||||
cached_config_set = nil
|
||||
user_scripts.initDefaultConfig(true --[[ Overwrite a possibly existing configuration --]])
|
||||
ntop.delCache(CONFIGSET_KEY)
|
||||
user_scripts.initDefaultConfig()
|
||||
|
||||
return(true)
|
||||
end
|
||||
|
|
@ -1567,7 +1422,7 @@ function user_scripts.getScriptConfig(configset, script, subdir)
|
|||
local script_type = user_scripts.getScriptType(subdir)
|
||||
local hooks = ternary(script_type.has_per_hook_config, script.hooks, {[ALL_HOOKS_CONFIG_KEY]=1})
|
||||
|
||||
for hook in pairs(script.hooks) do
|
||||
for hook in pairs(script.hooks or {}) do
|
||||
rv[hook] = default_config
|
||||
end
|
||||
|
||||
|
|
@ -1659,18 +1514,9 @@ function user_scripts.getFilterPreset(alert, alert_info)
|
|||
return ''
|
||||
end
|
||||
|
||||
local script_key = alert_generation["script_key"]
|
||||
local subdir = alert_generation["subdir"]
|
||||
local filter_string = ''
|
||||
local script_type = user_scripts.getScriptType(subdir)
|
||||
local script = user_scripts.loadModule(interface.getId(), script_type, subdir, script_key)
|
||||
local filter_to_use = {}
|
||||
local subdir_id = getSubdirId(subdir)
|
||||
|
||||
if not script then
|
||||
return ''
|
||||
end
|
||||
|
||||
if subdir_id == -1 then
|
||||
return ''
|
||||
end
|
||||
|
|
@ -1679,11 +1525,9 @@ function user_scripts.getFilterPreset(alert, alert_info)
|
|||
return ''
|
||||
end
|
||||
|
||||
-- Checking if the script has default filter fields or not
|
||||
-- if not, getting the default for the subdir
|
||||
if script["filter"] and script["filter"]["default_fields"] then
|
||||
filter_to_use = script["filter"]["default_fields"]
|
||||
elseif available_subdirs[subdir_id]["filter"]["default_fields"] then
|
||||
local filter_to_use = {}
|
||||
|
||||
if available_subdirs[subdir_id]["filter"]["default_fields"] then
|
||||
filter_to_use = available_subdirs[subdir_id]["filter"]["default_fields"]
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue