diff --git a/scripts/lua/modules/alert_definitions/other/alert_device_disconnection.lua b/attic/scripts/lua/modules/alert_definitions/alert_device_disconnection.lua
similarity index 100%
rename from scripts/lua/modules/alert_definitions/other/alert_device_disconnection.lua
rename to attic/scripts/lua/modules/alert_definitions/alert_device_disconnection.lua
diff --git a/scripts/lua/modules/alert_definitions/other/alert_unexpected_new_device.lua b/attic/scripts/lua/modules/alert_definitions/device_connection.lua
similarity index 100%
rename from scripts/lua/modules/alert_definitions/other/alert_unexpected_new_device.lua
rename to attic/scripts/lua/modules/alert_definitions/device_connection.lua
diff --git a/attic/device_connection_disconnection/locales/en.lua b/attic/scripts/plugins/alerts/interface/device_connection_disconnection/locales/en.lua
similarity index 100%
rename from attic/device_connection_disconnection/locales/en.lua
rename to attic/scripts/plugins/alerts/interface/device_connection_disconnection/locales/en.lua
diff --git a/attic/device_connection_disconnection/manifest.lua b/attic/scripts/plugins/alerts/interface/device_connection_disconnection/manifest.lua
similarity index 100%
rename from attic/device_connection_disconnection/manifest.lua
rename to attic/scripts/plugins/alerts/interface/device_connection_disconnection/manifest.lua
diff --git a/attic/device_connection_disconnection/user_scripts/interface/device_connection_disconnection.lua b/attic/scripts/plugins/alerts/interface/device_connection_disconnection/user_scripts/interface/device_connection_disconnection.lua
similarity index 100%
rename from attic/device_connection_disconnection/user_scripts/interface/device_connection_disconnection.lua
rename to attic/scripts/plugins/alerts/interface/device_connection_disconnection/user_scripts/interface/device_connection_disconnection.lua
diff --git a/scripts/locales/en.lua b/scripts/locales/en.lua
index d3972919ec..b3031c0a90 100644
--- a/scripts/locales/en.lua
+++ b/scripts/locales/en.lua
@@ -107,6 +107,7 @@ local lang = {
["delete_alerts"] = "Delete Alerts",
["delete_disabled_alerts"] = "Delete Alerts",
["delete_obs_point"] = "Delete Observation Point",
+ ["denied"] = "Denied",
["description"] = "Description",
["destination"] = "Destination",
["developer"] = "Developer",
@@ -1945,13 +1946,19 @@ local lang = {
["author"] = "Author",
["category"] = "Category",
["delete_alert_exclusions"] = "Deleting alert exclusions will cause new alerts to be triggered again. Do you really want to delete alert exclusions for",
+ ["delete_device_exclusion"] = "Deleting device exclusions will cause new alerts to be triggered again. Do you really want to delete exclusions for",
["delete_all_alert_exclusions"] = "Delete Check Exclusions",
+ ["delete_all_device_exclusions"] = "Delete Device Exclusions",
["delete_all_alert_exclusions_message"] = "Do you really want to delete all configured alert exclusions?",
+ ["delete_all_device_exclusions_message"] = "Do you really want to delete all configured excluded devices?",
["description"] = "Description",
- ["device_exclusion"] = "Device Exclusions",
+ ["device_exclusion"] = "Devices Exclusion",
+ ["device_exclusion_list"] = "Devices Exclusion List",
+ ["device_status"] = "Device Status",
["domain_names"] = "Domain Names",
["excluded_domain_name"] = "Excluded Domain Name",
["excluded_host"] = "Excluded Host",
+ ["excluded_device"] = "Excluded Device",
["excluded_host_name"] = "Excluded Host Name",
["excluded_issuer_dn"] = "Excluded Issuer DN",
["exclusion_list"] = "Behavioural Check Exclusions",
diff --git a/scripts/lua/inc/menu.lua b/scripts/lua/inc/menu.lua
index caf71a99f7..edd13226ac 100644
--- a/scripts/lua/inc/menu.lua
+++ b/scripts/lua/inc/menu.lua
@@ -615,6 +615,15 @@ page_utils.add_menubar_section(
{
entry = page_utils.menu_entries.divider,
},
+--[[ {
+ entry = page_utils.menu_entries.device_exclusions,
+ section = page_utils.menu_sections.device_exclusions,
+ hidden = not is_admin or not auth.has_capability(auth.capabilities.checks) or not ntop.isPro(),
+ url = '/lua/pro/admin/edit_device_exclusions.lua',
+ },
+ {
+ entry = page_utils.menu_entries.divider,
+ },]]
{
entry = page_utils.menu_entries.scripts_config,
section = page_utils.menu_sections.checks,
diff --git a/scripts/lua/mac_details.lua b/scripts/lua/mac_details.lua
index 392b18cf5f..088c7dc542 100644
--- a/scripts/lua/mac_details.lua
+++ b/scripts/lua/mac_details.lua
@@ -255,9 +255,9 @@ if((page == "overview") or (page == nil)) then
print("\n")
end
- local first_observed = ntop.getHashCache(getFirstSeenDevicesHashKey(ifId), mac_info["mac"])
+ local first_observed = ntop.getHashCache(getDevicesHashMapKey(ifId), mac_info["mac"])
- if(not isEmptyString(first_observed)) then
+ if(not isEmptyString(first_observed)) and (tonumber(first_observed)) then
print("
| " .. i18n("details.first_observed_on") .. " | ")
print(formatEpoch(first_observed))
print(" |
\n")
diff --git a/scripts/lua/modules/alert_definitions/other/alert_device_connection.lua b/scripts/lua/modules/alert_definitions/other/alert_device_connection_disconnection.lua
similarity index 94%
rename from scripts/lua/modules/alert_definitions/other/alert_device_connection.lua
rename to scripts/lua/modules/alert_definitions/other/alert_device_connection_disconnection.lua
index bcce490279..3c1801142b 100644
--- a/scripts/lua/modules/alert_definitions/other/alert_device_connection.lua
+++ b/scripts/lua/modules/alert_definitions/other/alert_device_connection_disconnection.lua
@@ -19,7 +19,7 @@ local alert_device_connection = classes.class(alert)
-- ##############################################
alert_device_connection.meta = {
- alert_key = other_alert_keys.alert_device_connection,
+ alert_key = other_alert_keys.alert_device_connection_disconnection,
i18n_title = "alerts_dashboard.device_connection",
icon = "fas fa-fw fa-sign-in",
entities = {
@@ -50,7 +50,7 @@ end
-- @return A human-readable string
function alert_device_connection.format(ifid, alert, alert_type_params)
return(i18n("alert_messages.device_has_connected", {
- device = info.device,
+ device = alert_type_params.device,
url = getMacUrl(alert.entity_val),
}))
end
diff --git a/scripts/lua/modules/alert_keys/other_alert_keys.lua b/scripts/lua/modules/alert_keys/other_alert_keys.lua
index 8a30156af8..e61f4dc969 100644
--- a/scripts/lua/modules/alert_keys/other_alert_keys.lua
+++ b/scripts/lua/modules/alert_keys/other_alert_keys.lua
@@ -61,7 +61,7 @@ local other_alert_keys = {
alert_lateral_movement = OTHER_BASE_KEY + 48, -- No longer user (moved to the flows)
alert_list_download_succeeded = OTHER_BASE_KEY + 49,
alert_no_if_activity = OTHER_BASE_KEY + 50,
- alert_unexpected_new_device = OTHER_BASE_KEY + 51,
+ alert_device_connection_disconnection = OTHER_BASE_KEY + 51,
alert_shell_script_executed = OTHER_BASE_KEY + 52,
alert_periodicity_update = OTHER_BASE_KEY + 53, -- No longer user (moved to the flows)
alert_dns_positive_error_ratio = OTHER_BASE_KEY + 54,
diff --git a/scripts/lua/modules/check_definitions/interface/device_connection_disconnection.lua b/scripts/lua/modules/check_definitions/interface/device_connection_disconnection.lua
new file mode 100644
index 0000000000..65eb132f8a
--- /dev/null
+++ b/scripts/lua/modules/check_definitions/interface/device_connection_disconnection.lua
@@ -0,0 +1,66 @@
+--
+-- (C) 2019-22 - ntop.org
+--
+
+local alert_consts = require "alert_consts"
+local checks = require("checks")
+local callback_utils = require "callback_utils"
+
+-- #################################################################
+
+local script
+
+-- ###########################################
+
+local function check_allowed_mac(params)
+ local ifid = interface.getId()
+ local seen_devices_hash = getDevicesHashMapKey(ifid)
+
+ -- Retrieving the list of the addresses already seen (both allowed and disallowed) and whitelisted
+ local seen_devices = ntop.getHashAllCache(seen_devices_hash) or {}
+
+ callback_utils.foreachDevice(getInterfaceName(ifid), function(devicename, devicestats, devicebase)
+ local mac_addr = devicestats["mac"]:upper()
+
+ local alert = alert_consts.alert_types.alert_device_connection_disconnection.new(
+ mac_addr
+ )
+
+ alert:set_score_warning()
+ alert:set_subtype(getInterfaceName(ifid))
+ alert:set_device_type(devicestats["devtype"])
+ alert:set_device_name(mac_addr)
+ alert:set_granularity(params.granularity)
+
+ if (devicestats["location"] == "lan") and not (devicestats["special_mac"]) then
+ -- This is a LAN MAC address, let's trigger an alert
+ -- Add this mac to the seen devices on the network
+ ntop.setHashCache(seen_devices_hash, mac_addr:upper(), 'denied')
+ alert:trigger(params.alert_entity, nil, params.cur_alerts)
+ elseif (seen_devices[mac_addr]) and (seen_devices[mac_addr] == 'allowed') then
+ -- No alert needs to be triggered or a MAC has been moved from denied to allowed
+ alert:release(params.alert_entity, nil, params.cur_alerts)
+ end
+ end)
+end
+
+-- #################################################################
+
+script = {
+ -- Script category
+ category = checks.check_categories.network,
+ default_enabled = false,
+
+ hooks = {
+ min = check_allowed_mac,
+ },
+
+ gui = {
+ i18n_title = "checks.device_connection_disconnection_title",
+ i18n_description = "checks.device_connection_disconnection_description",
+ },
+}
+
+-- #################################################################
+
+return script
diff --git a/scripts/lua/modules/check_definitions/interface/unexpected_new_device.lua b/scripts/lua/modules/check_definitions/interface/unexpected_new_device.lua
deleted file mode 100644
index 47d1f1e5c9..0000000000
--- a/scripts/lua/modules/check_definitions/interface/unexpected_new_device.lua
+++ /dev/null
@@ -1,108 +0,0 @@
---
--- (C) 2019-22 - ntop.org
---
-
-local alert_consts = require "alert_consts"
-local alerts_api = require "alerts_api"
-local alert_utils = require "alert_utils"
-local checks = require("checks")
-local callback_utils = require "callback_utils"
-
--- #################################################################
-
-local script
-
--- #################################################################
-
-local function check_allowed_mac(params)
- local seen_devices_hash = getFirstSeenDevicesHashKey(interface.getId())
- -- Saving the mac address list into a local variable and swapping keys with value due to performance issues
- local mac_list = {}
-
- -- Retrieving the list of the addresses already seen
- local seen_devices = ntop.getHashAllCache(seen_devices_hash) or {}
-
- -- This is the whitelist, that is, MACs configured here won't trigger any alert
- for key, mac in ipairs(params.check_config.items) do
- mac_list[mac:upper()] = 1
- end
-
- local macs_stats = interface.getMacsInfo(nil --[[ sortColumn --]], nil --[[ perPage --]], nil --[[ to_skip --]],
- nil --[[ sOrder --]], nil --[[ source_macs_only --]], nil --[[ manufacturer --]],
- nil, nil --[[ device_type --]], "")
-
- for _, mac in pairs(macs_stats["macs"] or {}) do
- local addr = mac["mac"]:upper()
-
- if mac_list[addr] then
- -- MAC belongs to the whitelist, no alert
- goto continue
- end
-
- if seen_devices[addr] then
- -- MAC already seen, no alert
- goto continue
- end
-
- if mac["location"] == "lan" and not mac["special_mac"] then
- -- This is a LAN MAC address, let's trigger an alert
- -- Add this mac to the already seen devices
- ntop.setHashCache(seen_devices_hash, addr, 1)
-
- local device = getDeviceName(addr)
-
- -- Check if the new mac address is expected or not
- local alert = alert_consts.alert_types.alert_unexpected_new_device.new(
- device,
- addr
- )
-
- alert:set_score_warning()
- alert:set_subtype(device)
- alert:set_device_type(mac["devtype"])
- alert:set_device_name(device)
-
- alert:store(alerts_api.macEntity(addr))
- end
-
- ::continue::
- end
-end
-
--- #################################################################
-
-script = {
- -- Script category
- category = checks.check_categories.network,
-
- default_enabled = false,
-
-
- -- Specify the default value whe clicking on the "Reset Default" button
- default_value = {
- items = {},
- },
-
- hooks = {
- min = check_allowed_mac,
- },
-
- gui = {
- i18n_title = "checks.unexpected_new_device_title",
- i18n_description = "checks.unexpected_new_device_description",
-
- input_builder = "items_list",
- item_list_type = "mac_address",
- input_title = i18n("checks.unexpected_new_device_exclusion_title"),
- input_description = i18n("checks.unexpected_new_device_exclusion_description"),
-
- input_action_i18n = "Reset Learned Devices",
- input_action_url = "lua/rest/v2/delete/host/new_devices.lua",
- input_action_confirm = true,
- input_action_i18n_confirm = "Are you sure to reset the learned devices?",
- },
-}
-
--- #################################################################
-
-return script
diff --git a/scripts/lua/modules/http_lint.lua b/scripts/lua/modules/http_lint.lua
index e600a30c8a..7ce79d74c1 100644
--- a/scripts/lua/modules/http_lint.lua
+++ b/scripts/lua/modules/http_lint.lua
@@ -1004,6 +1004,16 @@ local function validateMac(p)
end
end
+-- ##############################################
+
+-- @brief Returns true if inputstr is a Mac or all string
+local function validateDeviceOrAll(inputstr)
+ return (validateMac(inputstr) or inputstr == 'all')
+end
+http_lint.validateDeviceOrAll = validateDeviceOrAll
+
+-- ##############################################
+
local function validateZoom(zoom)
if string.match(zoom, "%d+%a") == zoom then
return true
@@ -1558,6 +1568,9 @@ local known_parameters = {
["delete_alerts"] = validateBool,
["alert_generation"] = { jsonCleanup, validateJSON },
+-- EXCLUDE DEVICES
+ ["device"] = validateDeviceOrAll,
+
-- UI TOASTS
["toast_id"] = validateSingleWord,
diff --git a/scripts/lua/modules/lua_utils.lua b/scripts/lua/modules/lua_utils.lua
index d1dc0e1405..92edcba42c 100644
--- a/scripts/lua/modules/lua_utils.lua
+++ b/scripts/lua/modules/lua_utils.lua
@@ -4013,8 +4013,8 @@ end
-- ###########################################
-- A redis hash mac -> first_seen
-function getFirstSeenDevicesHashKey(ifid)
- return "ntopng.seen_devices.ifid_" .. ifid
+function getDevicesHashMapKey(ifid)
+ return "ntopng.checks.device_connection_disconnection.ifid_" .. ifid
end
-- ###########################################
diff --git a/scripts/lua/modules/page_utils.lua b/scripts/lua/modules/page_utils.lua
index 5d509ac427..01a747298c 100644
--- a/scripts/lua/modules/page_utils.lua
+++ b/scripts/lua/modules/page_utils.lua
@@ -49,6 +49,7 @@ page_utils.menu_sections = {
system_stats = {key = "system_stats", i18n_title = "system", icon = "fas fa-desktop"},
admin = {key = "admin", i18n_title = "settings", icon = "fas fa-cog"},
alert_exclusions = {key = "alert_exclusions", i18n_title = "edit_check.exclusion_list", icon = "fas fa-bell-slash"},
+ device_exclusions = {key = "device_exclusions", i18n_title = "edit_check.device_exclusions", icon = "fas fa-bell-slash"},
dev = {key = "dev", i18n_title = "developer", icon = "fas fa-code"},
about = {key = "about", i18n_title = "help", icon = "fas fa-life-ring"},
health = {key = "health", i18n_title = "health", icon = "fas fa-laptop-medical"},
@@ -141,6 +142,7 @@ page_utils.menu_entries = {
scripts_config_flows = {key = "scripts_config", subkey="flows", i18n_title = alert_entities.flow.i18n_label, section = "admin", help_link = "https://www.ntop.org/guides/ntopng/web_gui/checks.html"},
scripts_config_system = {key = "scripts_config", subkey="system", i18n_title = alert_entities.system.i18n_label, section = "admin", help_link = "https://www.ntop.org/guides/ntopng/web_gui/checks.html"},
scripts_config_syslog = {key = "scripts_config", subkey="syslog", i18n_title = "syslog.syslog", section = "admin", help_link = "https://www.ntop.org/guides/ntopng/web_gui/checks.html"},
+ device_exclusions = {key = "device_exclusions", i18n_title = "edit_check.device_exclusion", section = "device_exclusions"},
alert_exclusions = {key = "alert_exclusions", i18n_title = "edit_check.exclusion_list", section = "alert_exclusions", help_link = "https://www.ntop.org/guides/ntopng/web_gui/checks.html"},
alert_exclusions_hosts = {key = "alert_exclusions", subkey="hosts", i18n_title = alert_entities.host.i18n_label, section = "alert_exclusions", help_link = "https://www.ntop.org/guides/ntopng/web_gui/checks.html"},
alert_exclusions_flows = {key = "alert_exclusions", subkey="flows", i18n_title = alert_entities.flow.i18n_label, section = "alert_exclusions", help_link = "https://www.ntop.org/guides/ntopng/web_gui/checks.html"},