EVOLUTION-MANAGER
Edit File: prefs.lua
-- -- (C) 2013-24 - ntop.org -- local dirs = ntop.getDirs() package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path package.path = dirs.installdir .. "/scripts/lua/modules/timeseries/drivers/?.lua;" .. package.path -- for influxdb if ((dirs.scriptdir ~= nil) and (dirs.scriptdir ~= "")) then package.path = dirs.scriptdir .. "/lua/modules/?.lua;" .. package.path end require "lua_utils" require "prefs_utils" local template = require "template_utils" local recording_utils = require "recording_utils" local data_retention_utils = require "data_retention_utils" local page_utils = require("page_utils") local ts_utils = require("ts_utils") local influxdb = require("influxdb") local script_manager = require("script_manager") local info = ntop.getInfo() local auth = require "auth" local email_peer_pattern = [[^([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*)$]] if ntop.isPro() or ntop.isnEdgeEnterprise() then package.path = dirs.installdir .. "/scripts/lua/pro/?.lua;" .. package.path package.path = dirs.installdir .. "/scripts/lua/pro/modules/?.lua;" .. package.path if hasClickHouseSupport() then flow_db_utils = require("flow_db_utils") end end sendHTTPContentTypeHeader('text/html') local alerts_disabled = false local product = ntop.getInfo().product local message_info = "" local message_severity = "alert-warning" -- ########################################### local function create_table(title) print('<form method="post">') print('<table class="table">') end local function add_section(title) print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. title .. '</th></tr></thead>') end -- ########################################### local function end_table() print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" />]] print [[ </form>]] print [[ </table>]] end -- ########################################### -- NOTE: all the auth methods should be listed below local auth_toggles = { ["local"] = "toggle_local_auth", ["ldap"] = "toggle_ldap_auth", ["http"] = "toggle_http_auth", ["authentication_log"] = "toggle_http_auth_log", ["radius"] = "toggle_radius_auth", ["menu_entries"] = { ["help"] = "toggle_menu_entry_help", ["developer"] = "toggle_menu_entry_developer" } } if auth.has_capability(auth.capabilities.preferences) then if not table.empty(_POST) then if _GET["tab"] == "auth" then local one_enabled = false for k, v in pairs(auth_toggles) do if _POST[v] == "1" then one_enabled = true break end end end end if (_GET["tab"] == "ext_alerts") then local available_endpoints = script_manager.getLoadedAlertEndpoints() for _, endpoint in ipairs(available_endpoints) do if (endpoint.handlePost) then local mi, ms = endpoint.handlePost() if mi then message_info = mi end if ms then message_severity = ms end end end end if (_POST["flows_and_alerts_data_retention_days"] and _POST["aggregated_flows_data_retention_days"]) then local aggregated = tonumber(_POST["aggregated_flows_data_retention_days"]) local raw = tonumber(_POST["flows_and_alerts_data_retention_days"]) if (aggregated <= raw) then _POST["aggregated_flows_data_retention_days"] = tostring(raw + 1) end end if (_POST["toggle_radius_auth"] == "1") and ((_POST["radius_server_address"] ~= ntop.getPref("ntopng.prefs.radius.radius_server_address")) or (_POST["radius_acct_server_address"] ~= ntop.getPref("ntopng.prefs.radius.radius_acct_server_address")) or (_POST["radius_secret"] ~= ntop.getPref("ntopng.prefs.radius.radius_secret")) or (_POST["radius_admin_group"] ~= ntop.getPref("ntopng.prefs.radius.radius_admin_group")) or (_POST["radius_auth_proto"] ~= ntop.getPref("ntopng.prefs.radius.radius_auth_proto")) or (_POST["radius_unpriv_capabilties_group"] ~= ntop.getPref("ntopng.prefs.radius.radius_unpriv_capabilties_group")) or (_POST["toggle_radius_accounting"] ~= ntop.getPref("ntopng.prefs.radius.accounting_enabled")) or (_POST["toggle_radius_external_auth_for_local_users"] ~= ntop.getPref("ntopng.prefs.radius.external_auth_for_local_users_enabled"))) then -- In the minute callback there is a periodic script that in case -- the auth changed, it's going to update the radius info ntop.setPref("ntopng.prefs.radius.radius_server_address", _POST["radius_server_address"]) ntop.setPref("ntopng.prefs.radius.radius_acct_server_address", _POST["radius_acct_server_address"]) ntop.setPref("ntopng.prefs.radius.radius_secret", _POST["radius_secret"]) ntop.setPref("ntopng.prefs.radius.radius_auth_proto", _POST["radius_auth_proto"]) ntop.setPref("ntopng.prefs.radius.radius_admin_group", _POST["radius_admin_group"]) ntop.setPref("ntopng.prefs.radius.radius_unpriv_capabilties_group", _POST["radius_unpriv_capabilties_group"]) ntop.setPref("ntopng.prefs.radius.toggle_radius_accounting", _POST["toggle_radius_accounting"]) ntop.setPref("ntopng.prefs.radius.external_auth_for_local_users_enabled", _POST["toggle_radius_external_auth_for_local_users"]) ntop.updateRadiusLoginInfo() end if (_POST["disable_alerts_generation"] == "1") then local alert_utils = require "alert_utils" alert_utils.disableAlertsGeneration() elseif (_POST["timeseries_driver"] == "influxdb") then local url = string.gsub(string.gsub(_POST["ts_post_data_url"], "http:__", "http://"), "https:__", "https://") if ntop.getPref("ntopng.prefs.timeseries_driver") ~= "influxdb" or (url ~= ntop.getPref("ntopng.prefs.ts_post_data_url")) or (_POST["influx_dbname"] ~= ntop.getPref("ntopng.prefs.influx_dbname")) or (_POST["influx_retention"] ~= ntop.getPref("ntopng.prefs.influx_retention")) or (_POST["toggle_influx_auth"] ~= ntop.getPref("ntopng.prefs.influx_auth_enabled")) or (_POST["influx_username"] ~= ntop.getPref("ntopng.prefs.influx_username")) or (_POST["influx_password"] ~= ntop.getPref("ntopng.prefs.influx_password")) then local username = nil local password = nil if _POST["toggle_influx_auth"] == "1" then username = _POST["influx_username"] password = _POST["influx_password"] end local ok, message = influxdb.init(_POST["influx_dbname"], url, tonumber(_POST["influx_retention"]), username, password, false --[[verbose]] ) if not ok then message_info = message message_severity = "alert-danger" -- reset driver to the old one _POST["timeseries_driver"] = nil elseif message then message_info = message message_severity = "alert-success" end end elseif (_POST["n2disk_license"] ~= nil) then recording_utils.setLicense(_POST["n2disk_license"]) end if _POST["timeseries_driver"] or _POST["ts_and_stats_data_retention_days"] then if ntop.getPref("ntopng.prefs.timeseries_driver") == 'influxdb' then ntop.setCache("ntopng.influxdb.retention_changed", 1) end ts_utils.setupAgain() end if _POST["toggle_snmp_trap"] and ntop.isEnterpriseXL() then ntop.snmpToggleTrapCollection(toboolean(_POST["toggle_snmp_trap"])) end page_utils.print_header_and_set_active_menu_entry(page_utils.menu_entries.preferences) dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua") prefs = ntop.getPrefs() if not isEmptyString(message_info) then print [[<div class="alert alert-dismissable ]] print(message_severity) print [[" role="alert">]] print(message_info) print [[<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>]] print [[</div>]] end local show_advanced_prefs = false local show_advanced_prefs_key = "ntopng.prefs.show_advanced_prefs" if _POST["show_advanced_prefs"] then show_advanced_prefs = toboolean(_POST["show_advanced_prefs"]) ntop.setPref(show_advanced_prefs_key, _POST["show_advanced_prefs"]) notifyNtopng(show_advanced_prefs_key, _POST["show_advanced_prefs"]) else show_advanced_prefs = toboolean(ntop.getPref(show_advanced_prefs_key)) if isEmptyString(show_advanced_prefs) then show_advanced_prefs = false end end if _GET['show_advanced_prefs'] ~= nil then show_advanced_prefs = (_GET['show_advanced_prefs'] == '1') end page_utils.print_page_title(i18n("prefs.runtime_prefs")) if (false) then io.write("------- SERVER ----------------\n") tprint(_SERVER) io.write("-------- GET ---------------\n") tprint(_GET) io.write("-------- POST ---------------\n") tprint(_POST) io.write("-----------------------\n") end if hasAlertsDisabled() then alerts_disabled = true end local subpage_active, tab = prefsGetActiveSubpage(show_advanced_prefs, _GET["tab"]) -- ================================================================================ function printInterfaces() print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.zmq_interfaces") .. '</th></tr></thead>') prefsInputFieldPrefs(subpage_active.entries["ignored_interfaces"].title, subpage_active.entries["ignored_interfaces"].description, "ntopng.prefs.", "ignored_interfaces", "", false, nil, nil, nil, { attributes = { spellcheck = "false", pattern = "^([0-9]+,)*[0-9]+$", maxlength = 32 } }) prefsToggleButton(subpage_active, { field = "toggle_dst_with_post_nat_dst", default = "0", pref = "override_dst_with_post_nat_dst" }) prefsToggleButton(subpage_active, { field = "toggle_src_with_post_nat_src", default = "0", pref = "override_src_with_post_nat_src" }) print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form> ]] end -- ================================================================================ function printActiveMonitoring() print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("active_monitoring_stats.active_monitoring") .. '</th></tr></thead>') prefsToggleButton(subpage_active, { field = "toggle_active_monitoring", default = "0", pref = "active_monitoring" }) print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form> ]] end function printAlerts() print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("show_alerts.alerts") .. '</th></tr></thead>') local elementToSwitch = {"row_toggle_emit_flow_alerts", "row_toggle_emit_host_alerts", "max_entity_alerts", "max_num_secs_before_delete_alert", "row_alert_page_refresh_rate_enabled"} prefsToggleButton(subpage_active, { field = "disable_alerts_generation", default = "0", to_switch = elementToSwitch, on_value = "0", -- On means alerts enabled and thus disable_alerts_generation == 0 off_value = "1" -- Off for enabled alerts implies 1 for disable_alerts_generation }) if ntop.getPref("ntopng.prefs.disable_alerts_generation") == "1" then showElements = false else showElements = true end prefsToggleButton(subpage_active, { field = "toggle_emit_flow_alerts", default = "1", pref = "emit_flow_alerts", on_value = "1", -- On flow alerts are generated off_value = "0", -- Off NO flow alerts are generated hidden = not showElements }) prefsToggleButton(subpage_active, { field = "toggle_emit_host_alerts", default = "1", pref = "emit_host_alerts", on_value = "1", -- On alerts are generated off_value = "0", -- Off NO alerts are generated hidden = not showElements }) prefsInputFieldPrefs(subpage_active.entries["max_entity_alerts"].title, subpage_active.entries["max_entity_alerts"].description, "ntopng.prefs.", "max_entity_alerts", prefs.max_entity_alerts, "number", showElements, false, nil, { min = 1 --[[ TODO check min/max ]] }) prefsInputFieldPrefs(subpage_active.entries["max_num_secs_before_delete_alert"].title, subpage_active.entries["max_num_secs_before_delete_alert"].description, "ntopng.prefs.", "max_num_secs_before_delete_alert", prefs.max_num_secs_before_delete_alert, "number", showElements, false, nil, { min = 1, tformat = "d" --[[ TODO check min/max ]] }) prefsToggleButton(subpage_active, { field = "alert_page_refresh_rate_enabled", default = "0", to_switch = {"alert_page_refresh_rate"}, on_value = "1", -- Refresh rate set off_value = "0", -- Refresh rate not set hidden = not showElements }) local showRefreshRate = false if ntop.getPref("ntopng.prefs.alert_page_refresh_rate_enabled") == "1" then showRefreshRate = showElements end prefsInputFieldPrefs(subpage_active.entries["alert_page_refresh_rate"].title, subpage_active.entries["alert_page_refresh_rate"].description, "ntopng.prefs.", "alert_page_refresh_rate", prefs.alert_page_refresh_rate, "number", showRefreshRate, false, nil, { min = 3, tformat = "m" --[[ TODO check min/max ]] }) print('<tr><th colspan=2 style="text-align:right;">') print( '<button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button>') print('</th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form> ]] end -- ================================================================================ function printProtocolPrefs() print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">HTTP / TLS / QUIC / DNS</th></tr></thead>') prefsToggleButton(subpage_active, { field = "toggle_top_sites", pref = "host_top_sites_creation", default = "0" }) print('<thead class="table-primary"><tr><th colspan=2 class="info">TLS / QUIC</th></tr></thead>') prefsToggleButton(subpage_active, { field = "toggle_tls_quic_hostnaming", pref = "tls_quic_hostnaming", default = "0" }) print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form> ]] end -- ================================================================================ function printNetworkDiscovery() print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.network_discovery") .. '</th></tr></thead>') local elementToSwitch = {"network_discovery_interval", "network_discovery_debug"} prefsToggleButton(subpage_active, { field = "toggle_network_discovery", default = "0", pref = "is_periodic_network_discovery_enabled", to_switch = elementToSwitch }) local showNetworkDiscoveryInterval = false if ntop.getPref("ntopng.prefs.is_periodic_network_discovery_enabled") == "1" then showNetworkDiscoveryInterval = true end local interval = ntop.getPref("ntopng.prefs.network_discovery_interval") if isEmptyString(interval) then -- set a default value interval = 15 * 60 -- 15 minutes ntop.setPref("ntopng.prefs.network_discovery_interval", tostring(interval)) end prefsInputFieldPrefs(subpage_active.entries["network_discovery_interval"].title, subpage_active.entries["network_discovery_interval"].description, "ntopng.prefs.", "network_discovery_interval", interval, "number", showNetworkDiscoveryInterval, nil, nil, { min = 60 * 15, tformat = "mhd" }) prefsToggleButton(subpage_active, { field = "toggle_network_discovery_debug", default = "0", pref = "network_discovery_debug" }) print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form>]] end -- ================================================================================ function printRecording() local n2disk_info = recording_utils.getN2diskInfo() print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.license") .. '</th></tr></thead>') prefsInputFieldPrefs(subpage_active.entries["n2disk_license"].title, subpage_active.entries["n2disk_license"].description .. i18n("prefs.n2disk_license_description_enterprise_l") .. "<br>" .. ternary(n2disk_info.version ~= nil, i18n("prefs.n2disk_license_version", { version = n2disk_info.version }) .. "<br>", "") .. ternary(n2disk_info.systemid ~= nil, i18n("prefs.n2disk_license_systemid", { systemid = n2disk_info.systemid }), ""), "ntopng.prefs.", "n2disk_license", ternary(n2disk_info.license ~= nil, n2disk_info.license, ""), false, nil, nil, nil, { style = { width = "25em;" }, min = 50, max = 64, pattern = getLicensePattern(), disabled = ntop.isEnterpriseL() }) print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("traffic_recording.settings") .. '</th></tr></thead>') prefsInputFieldPrefs(subpage_active.entries["max_extracted_pcap_bytes"].title, subpage_active.entries["max_extracted_pcap_bytes"].description, "ntopng.prefs.", "max_extracted_pcap_bytes", prefs.max_extracted_pcap_bytes, "number", true, nil, nil, { min = 10 * 1024 * 1024, format_spec = FMT_TO_DATA_BYTES, tformat = "mg" }) -- ###################### print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form>]] end -- ================================================================================ -- ##################### local function printMenuEntriesPrefs() if ntop.isEnterpriseM() then print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.menu_entries") .. '</th></tr></thead>') end prefsToggleButton(subpage_active, { field = auth_toggles["menu_entries"]["help"], pref = "menu_entries.help", hidden = not ntop.isEnterpriseM(), default = "1" }) prefsToggleButton(subpage_active, { field = auth_toggles["menu_entries"]["developer"], hidden = not ntop.isEnterpriseM(), pref = "menu_entries.developer", default = "1" }) end -- ##################### function printGUI() print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.web_user_interface") .. '</th></tr></thead>') if prefs.is_autologout_enabled == true then prefsToggleButton(subpage_active, { field = "toggle_autologout", default = "1", pref = "is_autologon_enabled" }) end -- ###################### local t_labels = {i18n("default"), i18n("white"), i18n("dark")} local t_values = {"default", "white", "dark"} local label = "toggle_theme" multipleTableButtonPrefs(subpage_active.entries[label].title, subpage_active.entries[label].description, t_labels, t_values, "default", "primary", label, "ntopng.user." .. _SESSION["user"] .. ".theme") -- ###################### local d_labels = {i18n("little_endian"), i18n("middle_endian"), i18n("big_endian")} local d_values = {"little_endian", "middle_endian", "big_endian"} local d_label = "toggle_date_type" multipleTableButtonPrefs(subpage_active.entries[d_label].title, subpage_active.entries[d_label].description, d_labels, d_values, "middle_endian", "primary", d_label, "ntopng.user." .. _SESSION["user"] .. ".date_format") -- ###################### prefsInputFieldPrefs(subpage_active.entries["max_ui_strlen"].title, subpage_active.entries["max_ui_strlen"].description, "ntopng.prefs.", "max_ui_strlen", prefs.max_ui_strlen, "number", nil, nil, nil, { min = 3, max = 128 }) prefsInputFieldPrefs(subpage_active.entries["mgmt_acl"].title, subpage_active.entries["mgmt_acl"].description, "ntopng.prefs.", "http_acl_management_port", "", false, nil, nil, nil, { style = { width = "25em;" }, attributes = { spellcheck = "false", maxlength = 512, pattern = getACLPattern() } }) -- ##################### prefsToggleButton(subpage_active, { field = "toggle_interface_name_only", default = "0", pref = "is_interface_name_only" }) printMenuEntriesPrefs() print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /></form>]] end -- ###################### function printMisc() print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.connectivity_check") .. '</th></tr></thead>') prefsInputFieldPrefs(subpage_active.entries["connectivity_check_url"].title, subpage_active.entries["connectivity_check_url"].description, "ntopng.prefs.", "connectivity_check_url", "", false, true, nil, nil, { attributes = { spellcheck = "false" }, pattern = getURLPattern(), required = false }) print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.report") .. '</th></tr></thead>') local t_labels = {i18n("bytes"), i18n("packets")} local t_values = {"bps", "pps"} multipleTableButtonPrefs(subpage_active.entries["toggle_thpt_content"].title, subpage_active.entries["toggle_thpt_content"].description, t_labels, t_values, "bps", "primary", "toggle_thpt_content", "ntopng.prefs.thpt_content") -- ###################### if ntop.isPro() then t_labels = {i18n("topk_heuristic.precision.disabled"), i18n("topk_heuristic.precision.more_accurate"), i18n("topk_heuristic.precision.less_accurate"), i18n("topk_heuristic.precision.aggressive")} t_values = {"disabled", "more_accurate", "accurate", "aggressive"} multipleTableButtonPrefs(subpage_active.entries["topk_heuristic_precision"].title, subpage_active.entries["topk_heuristic_precision"].description, t_labels, t_values, "more_accurate", "primary", "topk_heuristic_precision", "ntopng.prefs.topk_heuristic_precision") end -- ###################### if (isAdministratorOrPrintErr()) then print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("hosts") .. '</th></tr></thead>') local h_labels = {i18n("prefs.no_host_mask"), i18n("prefs.local_host_mask"), i18n("prefs.remote_host_mask")} local h_values = {"0", "1", "2"} multipleTableButtonPrefs(subpage_active.entries["toggle_host_mask"].title, subpage_active.entries["toggle_host_mask"].description, h_labels, h_values, "0", "primary", "toggle_host_mask", "ntopng.prefs.host_mask") prefsToggleButton(subpage_active, { field = "toggle_use_mac_in_flow_key", default = "0", pref = "use_mac_in_flow_key" }) prefsToggleButton(subpage_active, { field = "toggle_fingerprint_stats", default = "0", pref = "fingerprint_stats" }) end print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.flow_table") .. '</th></tr></thead>') prefsToggleButton(subpage_active, { field = "toggle_flow_begin", default = "0", pref = "first_seen_set" }) local h_labels = {i18n("prefs.duration"), i18n("prefs.last_seen")} local h_values = {"0", "1"} multipleTableButtonPrefs(subpage_active.entries["flow_table_time"].title, subpage_active.entries["flow_table_time"].description, h_labels, h_values, "0", "primary", "flow_table_time", "ntopng.prefs.flow_table_time") h_labels = {i18n("prefs.ip_order"), i18n("prefs.name_order")} multipleTableButtonPrefs(subpage_active.entries["flow_table_probe_order"].title, subpage_active.entries["flow_table_probe_order"].description, h_labels, h_values, "0", "primary", "flow_table_probe_order", "ntopng.prefs.flow_table_probe_order") print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form>]] end -- ================================================================================ function printUpdates() print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.updates") .. '</th></tr></thead>') prefsToggleButton(subpage_active, { field = "toggle_autoupdates", default = "0", pref = "is_autoupdates_enabled" }) -- ##################### print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form>]] end -- ================================================================================ local function printAuthDuration() print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.authentication_duration") .. '</th></tr></thead>') prefsInputFieldPrefs(subpage_active.entries["authentication_duration"].title, subpage_active.entries["authentication_duration"].description, "ntopng.prefs.", "auth_session_duration", prefs.auth_session_duration, "number", true, nil, nil, { min = 60 --[[ 1 minute --]] , max = 86400 * 7 --[[ 7 days --]] , tformat = "mhd" }) prefsToggleButton(subpage_active, { field = "toggle_auth_session_midnight_expiration", default = "0", pref = "auth_session_midnight_expiration" }) end -- ================================================================================ local function printLdapAuth() if not ntop.isPro() then return end print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.ldap_authentication") .. '</th></tr></thead>') local elementToSwitch = {"row_multiple_ldap_account_type", "row_toggle_ldap_anonymous_bind", "server", "bind_dn", "bind_pwd", "ldap_server_address", "search_path", "user_group", "admin_group", "row_toggle_ldap_referrals"} prefsToggleButton(subpage_active, { field = auth_toggles.ldap, pref = "ldap.auth_enabled", default = "0", to_switch = elementToSwitch, -- Similar to "to_switch" but for nested items (e.g. "local hosts cache" only -- enabled when both "host cache" and "cache" are enabled). -- The following inputs will be shown/hidden when this preference changes. nested_to_switch = { -- input: the input ID to toggle (e.g. the "local hosts cache") -- parent: the parent of the input which affects the input logic (e.g. "host cache") -- parent_enabled_value: the parent input value that should make the child input visible -- pref_enabled_value: this preference value that should make the child input visible (e.g. "1" when "cache" is enabled) { input = "bind_dn", parent = "input-toggle_ldap_anonymous_bind", parent_enabled_value = "0", pref_enabled_value = "1" }, { input = "bind_pwd", parent = "input-toggle_ldap_anonymous_bind", parent_enabled_value = "0", pref_enabled_value = "1" }} }) local showElements = (ntop.getPref("ntopng.prefs.ldap.auth_enabled") == "1") local labels_account = {i18n("prefs.posix"), i18n("prefs.samaccount")} local values_account = {"posix", "samaccount"} multipleTableButtonPrefs(subpage_active.entries["multiple_ldap_account_type"].title, subpage_active.entries["multiple_ldap_account_type"].description, labels_account, values_account, "posix", "primary", "multiple_ldap_account_type", "ntopng.prefs.ldap.account_type", nil, nil, nil, nil, showElements) prefsInputFieldPrefs(subpage_active.entries["ldap_server_address"].title, subpage_active.entries["ldap_server_address"].description, "ntopng.prefs.ldap", "ldap_server_address", "ldap://localhost:389", nil, showElements, true, true, { attributes = { pattern = "ldap(s)?://[0-9.\\-A-Za-z]+(:[0-9]+)?", spellcheck = "false", required = "required", maxlength = 255 } }) local elementToSwitchBind = {"bind_dn", "bind_pwd"} prefsToggleButton(subpage_active, { field = "toggle_ldap_anonymous_bind", default = "1", pref = "ldap.anonymous_bind", to_switch = elementToSwitchBind, reverse_switch = true, hidden = not showElements }) local showEnabledAnonymousBind = false if ntop.getPref("ntopng.prefs.ldap.anonymous_bind") == "0" then showEnabledAnonymousBind = true end local showElementsBind = showElements if showElements == true then showElementsBind = showEnabledAnonymousBind end prefsInputFieldPrefs(subpage_active.entries["bind_dn"].title, subpage_active.entries["bind_dn"].description .. "\"CN=ntop_users,DC=ntop,DC=org,DC=local\".", "ntopng.prefs.ldap", "bind_dn", "", nil, showElementsBind, true, false, { attributes = { spellcheck = "false", maxlength = 255 } }) prefsInputFieldPrefs(subpage_active.entries["bind_pwd"].title, subpage_active.entries["bind_pwd"].description, "ntopng.prefs.ldap", "bind_pwd", "", "password", showElementsBind, true, false, { attributes = { maxlength = 255 } }) prefsInputFieldPrefs(subpage_active.entries["search_path"].title, subpage_active.entries["search_path"].description, "ntopng.prefs.ldap", "search_path", "", "text", showElements, nil, nil, { attributes = { spellcheck = "false", maxlength = 255 } }) prefsInputFieldPrefs(subpage_active.entries["user_group"].title, subpage_active.entries["user_group"].description, "ntopng.prefs.ldap", "user_group", "", "text", showElements, nil, nil, { attributes = { spellcheck = "false", maxlength = 255 } }) prefsInputFieldPrefs(subpage_active.entries["admin_group"].title, subpage_active.entries["admin_group"].description, "ntopng.prefs.ldap", "admin_group", "", "text", showElements, nil, nil, { attributes = { spellcheck = "false", maxlength = 255 } }) prefsToggleButton(subpage_active, { field = "toggle_ldap_referrals", default = "1", pref = "ldap.follow_referrals", reverse_switch = true, hidden = not showElements }) end -- ##################### local function printRadiusAuth() if subpage_active.entries["toggle_radius_auth"].hidden then return end print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.radius_auth") .. '</th></tr></thead>') -- RADIUS GUI authentication local elementToSwitch = {"row_toggle_radius_accounting", "row_toggle_radius_external_auth_for_local_users", "radius_admin_group", "radius_unpriv_capabilties_group", "radius_server_address", "radius_acct_server_address", "radius_secret", "row_radius_auth_proto"} prefsToggleButton(subpage_active, { field = auth_toggles.radius, pref = "radius.auth_enabled", default = "0", to_switch = elementToSwitch }) -- RADIUS traffic accounting local showElements = (ntop.getPref("ntopng.prefs.radius.auth_enabled") == "1") -- RADIUS server settings (used for both RADIUS auth and accountign) prefsInputFieldPrefs(subpage_active.entries["radius_server"].title, subpage_active.entries["radius_server"].description, "ntopng.prefs.radius", "radius_server_address", "127.0.0.1:1812", nil, showElements, true, false, { attributes = { spellcheck = "false", maxlength = 255, required = "required", pattern = "[0-9.\\-A-Za-z]+:[0-9]+" } }) -- https://github.com/FreeRADIUS/freeradius-client/blob/7b7473ab78ca5f99e083e5e6c16345b7c2569db1/include/freeradius-client.h#L395 prefsInputFieldPrefs(subpage_active.entries["radius_secret"].title, subpage_active.entries["radius_secret"].description, "ntopng.prefs.radius", "radius_secret", "", "password", showElements, true, false, { attributes = { spellcheck = "false", maxlength = 48, required = "required" } }) local labels_auth_protocols = {i18n("prefs.pap"), i18n("prefs.chap")} local values_auth_protocols = {"pap", "chap"} multipleTableButtonPrefs(subpage_active.entries["radius_auth_proto"].title, subpage_active.entries["radius_auth_proto"].description, labels_auth_protocols, values_auth_protocols, "pap", "primary", "radius_auth_proto", "ntopng.prefs.radius.radius_auth_proto", nil, nil, nil, nil, showElements) local groupsElements = {"radius_admin_group", "radius_unpriv_capabilties_group"} local showGroupsElements = (ntop.getPref("ntopng.prefs.radius.external_auth_for_local_users_enabled") ~= "1") prefsToggleButton(subpage_active, { field = "toggle_radius_external_auth_for_local_users", pref = "radius.external_auth_for_local_users_enabled", default = "0", to_switch = groupsElements, reverse_switch = true, hidden = not showElements }) prefsInputFieldPrefs(subpage_active.entries["radius_admin_group"].title, subpage_active.entries["radius_admin_group"].description, "ntopng.prefs.radius", "radius_admin_group", "", nil, showElements and showGroupsElements, true, false, { attributes = { spellcheck = "false", maxlength = 255, pattern = "[^\\s]+" } }) prefsInputFieldPrefs(subpage_active.entries["radius_unpriv_capabilties_group"].title, subpage_active.entries["radius_unpriv_capabilties_group"].description, "ntopng.prefs.radius", "radius_unpriv_capabilties_group", "", nil, showElements and showGroupsElements, true, false, { attributes = { spellcheck = "false", maxlength = 255, pattern = "[^\\s]+" } }) local accountingElements = {"radius_acct_server_address"} prefsToggleButton(subpage_active, { field = "toggle_radius_accounting", pref = "radius.accounting_enabled", default = "0", to_switch = accountingElements, hidden = not showElements }) local showElementsAccounting = (ntop.getPref("ntopng.prefs.radius.accounting_enabled") == "1") -- RADIUS server settings (used for both RADIUS auth and accountign) prefsInputFieldPrefs(subpage_active.entries["radius_accounting_server"].title, subpage_active.entries["radius_accounting_server"].description, "ntopng.prefs.radius", "radius_acct_server_address", "127.0.0.1:1813", nil, showElements and showElementsAccounting, true, false, { attributes = { spellcheck = "false", maxlength = 255, required = "required", pattern = "[0-9.\\-A-Za-z]+:[0-9]+" } }) end -- ##################### local function printHttpAuth() print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.http_auth") .. '</th></tr></thead>') local elementToSwitch = {"http_auth_url"} prefsToggleButton(subpage_active, { field = auth_toggles.http, pref = "http_authenticator.auth_enabled", default = "0", to_switch = elementToSwitch }) local showElements = (ntop.getPref("ntopng.prefs.http_authenticator.auth_enabled") == "1") prefsInputFieldPrefs(subpage_active.entries["http_auth_server"].title, subpage_active.entries["http_auth_server"].description, "ntopng.prefs.http_authenticator", "http_auth_url", "", nil, showElements, true, true --[[ allowUrls ]] , { attributes = { spellcheck = "false", maxlength = 255, required = "required", pattern = getURLPattern() } }) local showElements = (ntop.getPref("ntopng.prefs.http_authenticator.log_positive_event_enabled") == "1") prefsInputFieldPrefs(subpage_active.entries["http_auth_server"].title, subpage_active.entries["http_auth_server"].description, "ntopng.prefs.http_authenticator.log_positive_event_enabled", "http_auth_url", "", nil, showElements, true, true --[[ allowUrls ]] , { attributes = { spellcheck = "false", maxlength = 255, required = "required", pattern = getURLPattern() } }) end -- ##################### local function printLocalAuth() print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.local_auth") .. '</th></tr></thead>') prefsToggleButton(subpage_active, { field = auth_toggles["local"], pref = "local.auth_enabled", default = "1" }) end -- ##################### function printAuthentication() print('<form method="post">') print('<table class="table">') local entries = subpage_active.entries printAuthDuration() -- Note: order must correspond to evaluation order in Ntop.cpp print('<thead class="table-primary"><tr><th class="info" colspan="2">' .. i18n("prefs.client_x509_auth") .. '</th></tr></thead>') prefsToggleButton(subpage_active, { field = "toggle_client_x509_auth", default = "0", pref = "is_client_x509_auth_enabled" }) if not entries.toggle_ldap_auth.hidden then printLdapAuth() end if not entries.toggle_radius_auth.hidden then printRadiusAuth() end if not entries.toggle_http_auth.hidden then printHttpAuth() end if not entries.toggle_local_auth.hidden then printLocalAuth() end if not ntop.isnEdge() then prefsInformativeField(i18n("notes"), i18n("prefs.auth_methods_order")) else prefsInformativeField(i18n("notes"), i18n("nedge.authentication_gui_and_captive_portal", { product = product, url = ntop.getHttpPrefix() .. "/lua/pro/nedge/system_setup_ui/captive_portal.lua" })) end print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" />]] print('</form>') end -- ##################### function printOTProtocols() print('<form method="post">') print('<table class="table">') -- ###################### print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.ot_protocols") .. '</th></tr></thead>') -- By default 1 hour of learning prefsInputFieldPrefs(subpage_active.entries["iec60870_learning_period"].title, subpage_active.entries["iec60870_learning_period"].description, "ntopng.prefs.", "iec60870_learning_period", prefs.iec60870_learning_period or 3600, "number", nil, nil, nil, { min = 21600, tformat = "hd" }) -- By default 6 hours of learning prefsInputFieldPrefs(subpage_active.entries["modbus_learning_period"].title, subpage_active.entries["modbus_learning_period"].description, "ntopng.prefs.", "modbus_learning_period", prefs.modbus_learning_period or 21600, "number", is_behaviour_analysis_enabled, nil, nil, { min = 3600, tformat = "hd" }) print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" />]] print('</form>') end -- ##################### function printNetworkBehaviour() local LEARNING_STATUS = { -- Keep it in sync with ntop_typedefs.h ServiceAcceptance ALLOWED = "0", DENIED = "1", UNDECIDED = "2" } print('<form method="post">') print('<table class="table">') -- ###################### print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.service_map") .. '</th></tr></thead>') -- Behavior analysis for asn, network and l7proto (iface) local is_behaviour_analysis_enabled = ntop.isEnterpriseL() prefsInputFieldPrefs(subpage_active.entries["behaviour_analysis_learning_period"].title, subpage_active.entries["behaviour_analysis_learning_period"].description, "ntopng.prefs.", "behaviour_analysis_learning_period", prefs.behaviour_analysis_learning_period, "number", is_behaviour_analysis_enabled, nil, nil, { min = 3600, tformat = "hd" }) multipleTableButtonPrefs(subpage_active.entries["behaviour_analysis_learning_status_during_learning"].title, subpage_active.entries["behaviour_analysis_learning_status_during_learning"].description, {i18n( "traffic_behaviour.undecided"), i18n("traffic_behaviour.allowed"), i18n("traffic_behaviour.denied")}, {LEARNING_STATUS.UNDECIDED, LEARNING_STATUS.ALLOWED, LEARNING_STATUS.DENIED}, LEARNING_STATUS.ALLOWED, -- [default value] "primary", -- [selected color] "behaviour_analysis_learning_status_during_learning", "ntopng.prefs.behaviour_analysis_learning_status_during_learning", -- [redis key] false, -- [disabled] {}, nil, nil, is_behaviour_analysis_enabled --[[show]] ) multipleTableButtonPrefs(subpage_active.entries["behaviour_analysis_learning_status_post_learning"].title, subpage_active.entries["behaviour_analysis_learning_status_post_learning"].description, {i18n( "traffic_behaviour.undecided"), i18n("traffic_behaviour.allowed"), i18n("traffic_behaviour.denied")}, {LEARNING_STATUS.UNDECIDED, LEARNING_STATUS.ALLOWED, LEARNING_STATUS.DENIED}, LEARNING_STATUS.ALLOWED, -- [default value] "primary", "behaviour_analysis_learning_status_post_learning", "ntopng.prefs.behaviour_analysis_learning_status_post_learning", false, {}, nil, nil, is_behaviour_analysis_enabled --[[show]] ) -- ##################### local is_device_connection_disconnection_analysis_enabled = ntop.isEnterpriseM() if is_device_connection_disconnection_analysis_enabled then print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.devices_behaviour") .. '</th></tr></thead>') -- Behavior analysis for asn, network and l7proto (iface) prefsInputFieldPrefs(subpage_active.entries["devices_learning_period"].title, subpage_active.entries["devices_learning_period"].description, "ntopng.prefs.", "devices_learning_period", prefs.devices_learning_period, "number", is_device_connection_disconnection_analysis_enabled, nil, nil, { min = 7200, tformat = "hd" }) multipleTableButtonPrefs(subpage_active.entries["devices_status_during_learning"].title, subpage_active.entries["devices_status_during_learning"].description, {i18n("traffic_behaviour.allowed"), i18n("traffic_behaviour.denied")}, {LEARNING_STATUS.ALLOWED, LEARNING_STATUS.DENIED}, LEARNING_STATUS.ALLOWED, -- [default value] "primary", -- [selected color] "devices_status_during_learning", "ntopng.prefs.devices_status_during_learning", -- [redis key] false, -- [disabled] {}, nil, nil, is_device_connection_disconnection_analysis_enabled --[[show]] ) multipleTableButtonPrefs(subpage_active.entries["devices_status_post_learning"].title, subpage_active.entries["devices_status_post_learning"].description, {i18n("traffic_behaviour.allowed"), i18n("traffic_behaviour.denied")}, {LEARNING_STATUS.ALLOWED, LEARNING_STATUS.DENIED}, LEARNING_STATUS.ALLOWED, -- [default value] "primary", "devices_status_post_learning", "ntopng.prefs.devices_status_post_learning", false, {}, nil, nil, is_device_connection_disconnection_analysis_enabled --[[show]] ) end -- ##################### print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.host_analysis") .. '</th></tr></thead>') prefsInputFieldPrefs(subpage_active.entries["host_port_learning_period"].title, subpage_active.entries["host_port_learning_period"].description, "ntopng.prefs.", "host_port_learning_period", prefs.host_port_learning_period, "number", ntop.isEnterpriseM(), nil, nil, { min = 7200, tformat = "hd" }) -- ##################### print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" />]] print('</form>') end -- ================================================================================ function printInMemory() print('<form id="localRemoteTimeoutForm" method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.stats_reset") .. '</th></tr></thead>') prefsToggleButton(subpage_active, { field = "toggle_midnight_stats_reset", default = "0", pref = "midnight_stats_reset_enabled" }) print( '<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.local_hosts_cache_settings") .. '</th></tr></thead>') prefsToggleButton(subpage_active, { field = "toggle_local_host_cache_enabled", default = "1", pref = "is_local_host_cache_enabled", to_switch = {"local_host_cache_duration", "row_toggle_active_local_host_cache_enabled", "active_local_host_cache_interval"}, -- Similar to "to_switch" but for nested items (e.g. "local hosts cache" only -- enabled when both "host cache" and "cache" are enabled). -- The following inputs will be shown/hidden when this preference changes. nested_to_switch = { -- input: the input ID to toggle (e.g. the "local hosts cache") -- parent: the parent of the input which affects the input logic (e.g. "host cache") -- parent_enabled_value: the parent input value that should make the child input visible -- pref_enabled_value: this preference value that should make the child input visible (e.g. "1" when "cache" is enabled) { input = "active_local_host_cache_interval", parent = "input-toggle_active_local_host_cache_enabled", parent_enabled_value = "1", pref_enabled_value = "1" }} }) local showLocalHostCacheInterval = false if ntop.getPref("ntopng.prefs.is_local_host_cache_enabled") == "1" then showLocalHostCacheInterval = true end prefsInputFieldPrefs(subpage_active.entries["local_host_cache_duration"].title, subpage_active.entries["local_host_cache_duration"].description, "ntopng.prefs.", "local_host_cache_duration", prefs.local_host_cache_duration, "number", showLocalHostCacheInterval, nil, nil, { min = 60, tformat = "mhd" }) prefsToggleButton(subpage_active, { field = "toggle_active_local_host_cache_enabled", default = "0", pref = "is_active_local_host_cache_enabled", to_switch = {"active_local_host_cache_interval"} }) local showActiveLocalHostCacheInterval = false if ntop.getPref("ntopng.prefs.is_active_local_host_cache_enabled") == "1" then showActiveLocalHostCacheInterval = true end prefsInputFieldPrefs(subpage_active.entries["active_local_host_cache_interval"].title, subpage_active.entries["active_local_host_cache_interval"].description, "ntopng.prefs.", "active_local_host_cache_interval", prefs.active_local_host_cache_interval or 3600, "number", showActiveLocalHostCacheInterval, nil, nil, { min = 60, tformat = "mhd" }) print('</table>') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.idle_timeout_settings") .. '</th></tr></thead>') prefsInputFieldPrefs(subpage_active.entries["flow_max_idle"].title, subpage_active.entries["flow_max_idle"].description, "ntopng.prefs.", "flow_max_idle", prefs.flow_max_idle, "number", nil, nil, nil, { min = 1, max = 3600, tformat = "smh" }) prefsInputFieldPrefs(subpage_active.entries["local_host_max_idle"].title, subpage_active.entries["local_host_max_idle"].description, "ntopng.prefs.", "local_host_max_idle", prefs.local_host_max_idle, "number", nil, nil, nil, { min = 1, max = 7 * 86400, tformat = "smh", attributes = { ["data-localremotetimeout"] = "localremotetimeout" } }) prefsInputFieldPrefs(subpage_active.entries["non_local_host_max_idle"].title, subpage_active.entries["non_local_host_max_idle"].description, "ntopng.prefs.", "non_local_host_max_idle", prefs.non_local_host_max_idle, "number", nil, nil, nil, { min = 1, max = 7 * 86400, tformat = "smh" }) print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form> <script> function localRemoteTimeoutValidator() { var form = $("#localRemoteTimeoutForm"); var local_timeout = resol_selector_get_raw($("input[name='local_host_max_idle']", form)); var remote_timeout = resol_selector_get_raw($("input[name='non_local_host_max_idle']", form)); if ((local_timeout != null) && (remote_timeout != null)) { if (local_timeout < remote_timeout) return false; } return true; } var idleFormValidatorOptions = { disable: true, custom: { localremotetimeout: localRemoteTimeoutValidator, }, errors: { localremotetimeout: "Cannot be less then Remote Host Idle Timeout", } } $("#localRemoteTimeoutForm") .validator(idleFormValidatorOptions); /* Retrigger the validation every second to clear outdated errors */ setInterval(function() { $("#localRemoteTimeoutForm").data("bs.validator").validate(); }, 1000); </script> ]] end -- ================================================================================ function printStatsTimeseries() print('<form method="post">') print('<table class="table">') local force_rrd = false -- ntop.isWindows() if not force_rrd then print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n('prefs.timeseries_database') .. '</th></tr></thead>') end local elementToSwitch = {"ts_post_data_url", "influx_dbname", "influx_retention", "row_toggle_influx_auth", "influx_username", "influx_password", "row_ts_high_resolution"} local showElementArray = {false, true, false} local active_driver = "rrd" local influx_active = false if not force_rrd then -- Similar to "to_switch" but for nested items (e.g. "local hosts cache" only -- enabled when both "host cache" and "cache" are enabled). -- The following inputs will be shown/hidden when this preference changes. local nested_to_switch = { -- input: the input ID to toggle (e.g. the "local hosts cache") -- parent: the parent of the input which affects the input logic (e.g. "host cache") -- parent_enabled_value: the parent input value that should make the child input visible -- pref_enabled_value: this preference value that should make the child input visible (e.g. "1" when "cache" is enabled) { input = "influx_username", parent = "input-toggle_influx_auth", parent_enabled_value = "1", pref_enabled_value = "influxdb" }, { input = "influx_password", parent = "input-toggle_influx_auth", parent_enabled_value = "1", pref_enabled_value = "influxdb" }} multipleTableButtonPrefs(subpage_active.entries["multiple_timeseries_database"].title, subpage_active.entries["multiple_timeseries_database"].description, {"RRD", "InfluxDB 1.x/2.x"}, {"rrd", "influxdb"}, "rrd", "primary", "timeseries_driver", "ntopng.prefs.timeseries_driver", nil, elementToSwitch, showElementArray, nested_to_switch, true --[[show]] ) active_driver = ntop.getPref("ntopng.prefs.timeseries_driver") influx_active = (active_driver == "influxdb") end prefsInputFieldPrefs(subpage_active.entries["influxdb_url"].title, subpage_active.entries["influxdb_url"].description, "ntopng.prefs.", "ts_post_data_url", "http://localhost:8086", false, influx_active, nil, nil, { attributes = { spellcheck = "false" }, pattern = getURLPattern(), required = true }) if ntop.isnEdge() and ntop.getPref("ntopng.prefs.influx_dbname") == "ntopng edge" then -- Fixes issue #1939 with wrong deployed nedge db name ntop.delCache("ntopng.prefs.influx_dbname") end prefsInputFieldPrefs(subpage_active.entries["influxdb_dbname"].title, subpage_active.entries["influxdb_dbname"].description, "ntopng.prefs.", "influx_dbname", product:gsub(' ', '_'), nil, influx_active, nil, nil, { pattern = "[A-z,0-9,_]+" }) prefsToggleButton(subpage_active, { field = "toggle_influx_auth", default = "0", pref = "influx_auth_enabled", to_switch = {"influx_username", "influx_password"}, hidden = not influx_active }) local auth_enabled = influx_active and (ntop.getPref("ntopng.prefs.influx_auth_enabled") == "1") prefsInputFieldPrefs(subpage_active.entries["influxdb_username"].title, subpage_active.entries["influxdb_username"].description, "ntopng.prefs.", "influx_username", "", false, auth_enabled, nil, nil, { attributes = { spellcheck = "false" }, pattern = "[^\\s]+" }) prefsInputFieldPrefs(subpage_active.entries["influxdb_password"].title, subpage_active.entries["influxdb_password"].description, "ntopng.prefs.", "influx_password", "", "password", auth_enabled, nil, nil, { attributes = { spellcheck = "false" }, pattern = "[^\\s]+" }) local resolutions_labels = {"1m", "5m"} local resolutions_values = {"60", "300"} multipleTableButtonPrefs(subpage_active.entries["timeseries_resolution_resolution"].title, subpage_active.entries["timeseries_resolution_resolution"].description .. "<br><b>" .. i18n("notes") .. [[</b>:<ul> <li>]] .. i18n("prefs.ts_resolution_note2", { external_icon = "<i class='fas fa-external-link-alt'></i>", url = "https://docs.influxdata.com/influxdb/v1.8/query_language/manage-database/#delete-a-database-with-drop-database" }) .. [[</li> </ul>]], resolutions_labels, resolutions_values, "300", "primary", "ts_high_resolution", "ntopng.prefs.ts_resolution", nil, nil, nil, nil, influx_active) prefsInputFieldPrefs(subpage_active.entries["influxdb_query_timeout"].title, subpage_active.entries["influxdb_query_timeout"].description, "ntopng.prefs.", "influx_query_timeout", "10", "number", influx_active, nil, nil, { min = 1 }) prefsInputFieldPrefs(subpage_active.entries["ts_data_retention"].title, subpage_active.entries["ts_data_retention"].description, "ntopng.prefs.", "ts_and_stats_data_retention_days", data_retention_utils.getDefaultRetention(), "number", nil, nil, nil, { min = 1, max = 365 * 10 }) print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n('prefs.interfaces_timeseries') .. '</th></tr></thead>') -- TODO: make also per-category interface RRDs local l7_rrd_labels = {i18n("prefs.none"), i18n("prefs.per_protocol"), i18n("prefs.per_category"), i18n("prefs.both")} local l7_rrd_values = {"none", "per_protocol", "per_category", "both"} local elementToSwitch = {} local showElementArray = nil -- { true, false, false } prefsToggleButton(subpage_active, { field = "toggle_interface_traffic_rrd_creation", default = "1", pref = "interface_rrd_creation", to_switch = {"row_interfaces_ndpi_timeseries_creation"} }) local showElement = ntop.getPref("ntopng.prefs.interface_rrd_creation") == "1" retVal = multipleTableButtonPrefs(subpage_active.entries["toggle_ndpi_timeseries_creation"].title, subpage_active.entries["toggle_ndpi_timeseries_creation"].description, l7_rrd_labels, l7_rrd_values, "per_protocol", "primary", "interfaces_ndpi_timeseries_creation", "ntopng.prefs.interface_ndpi_timeseries_creation", nil, elementToSwitch, showElementArray, nil, showElement) print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n('prefs.local_hosts_timeseries') .. '</th></tr></thead>') local hosts_rrd_labels = {i18n("off"), i18n("light"), i18n("full")} local hosts_rrd_values = {"off", "light", "full"} local hostElemsToSwitch = {"row_hosts_ndpi_timeseries_creation", "row_toggle_local_hosts_one_way_ts"} local hostShowElementArray = {{false, false, true} --[[ ndpi ]] , {false, true, true} --[[ one-way traffic ]] } multipleTableButtonPrefs(subpage_active.entries["toggle_local_hosts_ts_creation"].title, subpage_active.entries["toggle_local_hosts_ts_creation"].description, hosts_rrd_labels, hosts_rrd_values, "light", "primary", "hosts_ts_creation", "ntopng.prefs.hosts_ts_creation", nil, hostElemsToSwitch, hostShowElementArray, nil, true) local hosts_ts_creation = ntop.getPref("ntopng.prefs.hosts_ts_creation") local show_host_l7 = (hosts_ts_creation == "full") prefsToggleButton(subpage_active, { field = "toggle_local_hosts_one_way_ts", default = "0", pref = "hosts_one_way_traffic_rrd_creation", hidden = (hosts_ts_creation == "off") }) retVal = multipleTableButtonPrefs(subpage_active.entries["toggle_ndpi_timeseries_creation"].title, subpage_active.entries["toggle_ndpi_timeseries_creation"].description, l7_rrd_labels, l7_rrd_values, "none", "primary", "hosts_ndpi_timeseries_creation", "ntopng.prefs.host_ndpi_timeseries_creation", nil, elementToSwitch, showElementArray, nil, show_host_l7) print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n('prefs.l2_devices_timeseries') .. '</th></tr></thead>') prefsToggleButton(subpage_active, { field = "toggle_l2_devices_traffic_rrd_creation", default = "0", pref = "l2_device_rrd_creation", to_switch = {"row_l2_devices_ndpi_timeseries_creation"} }) local l7_rrd_labels = {i18n("prefs.none"), i18n("prefs.per_category")} local l7_rrd_values = {"none", "per_category"} local showElement = ntop.getPref("ntopng.prefs.l2_device_rrd_creation") == "1" retVal = multipleTableButtonPrefs(subpage_active.entries["toggle_ndpi_timeseries_creation"].title, subpage_active.entries["toggle_ndpi_timeseries_creation"].description, l7_rrd_labels, l7_rrd_values, "none", "primary", "l2_devices_ndpi_timeseries_creation", "ntopng.prefs.l2_device_ndpi_timeseries_creation", nil, elementToSwitch, showElementArray, nil, showElement) print( '<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n('prefs.system_probes_timeseries') .. '</th></tr></thead>') prefsToggleButton(subpage_active, { field = "toggle_system_probes_timeseries", default = "1", pref = "system_probes_timeseries" }) if ntop.isPro() then print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n('prefs.exporter_timeseries') .. '</th></tr></thead>') prefsToggleButton(subpage_active, { field = "toggle_flow_rrds", default = "0", pref = "flow_device_port_rrd_creation", disabled = not info["version.enterprise_edition"] }) prefsToggleButton(subpage_active, { field = "toggle_interface_usage_probes_timeseries", default = "1", pref = "interface_usage_probes_timeseries", disabled = not info["version.enterprise_edition"] }) end print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n('prefs.other_timeseries') .. '</th></tr></thead>') if ntop.isPro() then prefsToggleButton(subpage_active, { field = "toggle_intranet_traffic_rrd_creation", default = "0", pref = "intranet_traffic_rrd_creation" }) prefsToggleButton(subpage_active, { field = "toggle_observation_points_rrd_creation", default = "0", pref = "observation_points_rrd_creation", disabled = not info["version.enterprise_edition"] }) prefsToggleButton(subpage_active, { field = "toggle_pools_rrds", default = "0", pref = "host_pools_rrd_creation" }) end prefsToggleButton(subpage_active, { field = "toggle_vlan_rrds", default = "0", pref = "vlan_rrd_creation" }) prefsToggleButton(subpage_active, { field = "toggle_asn_rrds", default = "0", pref = "asn_rrd_creation" }) prefsToggleButton(subpage_active, { field = "toggle_country_rrds", default = "0", pref = "country_rrd_creation" }) prefsToggleButton(subpage_active, { field = "toggle_os_rrds", default = "0", pref = "os_rrd_creation" }) if ntop.isPro() then prefsToggleButton(subpage_active, { field = "toggle_ndpi_flows_rrds", default = "0", pref = "ndpi_flows_rrd_creation" }) end if info["version.enterprise_edition"] then prefsInformativeField("SNMP", i18n("prefs.snmp_timeseries_config_link", { url = "?tab=snmp&show_advanced_prefs=1" })) end prefsToggleButton(subpage_active, { field = "toggle_internals_rrds", default = "0", pref = "internals_rrd_creation" }) print('</table>') print('<table class="table">') if show_advanced_prefs and false --[[ hide these settings for now ]] then print( '<thead class="table-primary"><tr><th colspan=2 class="info">Network Interface Timeseries</th></tr></thead>') prefsInputFieldPrefs("Days for raw stats", "Number of days for which raw stats are kept. Default: 1.", "ntopng.prefs.", "intf_rrd_raw_days", prefs.intf_rrd_raw_days, "number", nil, nil, nil, { min = 1, max = 365 * 5 --[[ TODO check min/max ]] }) prefsInputFieldPrefs("Days for 1 min resolution stats", "Number of days for which stats are kept in 1 min resolution. Default: 30.", "ntopng.prefs.", "intf_rrd_1min_days", prefs.intf_rrd_1min_days, "number", nil, nil, nil, { min = 1, max = 365 * 5 --[[ TODO check min/max ]] }) prefsInputFieldPrefs("Days for 1 hour resolution stats", "Number of days for which stats are kept in 1 hour resolution. Default: 100.", "ntopng.prefs.", "intf_rrd_1h_days", prefs.intf_rrd_1h_days, "number", nil, nil, nil, { min = 1, max = 365 * 5 --[[ TODO check min/max ]] }) prefsInputFieldPrefs("Days for 1 day resolution stats", "Number of days for which stats are kept in 1 day resolution. Default: 365.", "ntopng.prefs.", "intf_rrd_1d_days", prefs.intf_rrd_1d_days, "number", nil, nil, nil, { min = 1, max = 365 * 5 --[[ TODO check min/max ]] }) print( '<thead class="table-primary"><tr><th colspan=2 class="info">Protocol/Networks Timeseries</th></tr></thead>') prefsInputFieldPrefs("Days for raw stats", "Number of days for which raw stats are kept. Default: 1.", "ntopng.prefs.", "other_rrd_raw_days", prefs.other_rrd_raw_days, "number", nil, nil, nil, { min = 1, max = 365 * 5 --[[ TODO check min/max ]] }) -- prefsInputFieldPrefs("Days for 1 min resolution stats", "Number of days for which stats are kept in 1 min resolution. Default: 30.", "ntopng.prefs.", "other_rrd_1min_days", prefs.other_rrd_1min_days) prefsInputFieldPrefs("Days for 1 hour resolution stats", "Number of days for which stats are kept in 1 hour resolution. Default: 100.", "ntopng.prefs.", "other_rrd_1h_days", prefs.other_rrd_1h_days, "number", nil, nil, nil, { min = 1, max = 365 * 5 --[[ TODO check min/max ]] }) prefsInputFieldPrefs("Days for 1 day resolution stats", "Number of days for which stats are kept in 1 day resolution. Default: 365.", "ntopng.prefs.", "other_rrd_1d_days", prefs.other_rrd_1d_days, "number", nil, nil, nil, { min = 1, max = 365 * 5 --[[ TODO check min/max ]] }) end print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form> ]] end -- ================================================================================ function printLogging() if prefs.has_cmdl_trace_lvl then return end print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.logging") .. '</th></tr></thead>') loggingSelector(subpage_active.entries["toggle_logging_level"].title, subpage_active.entries["toggle_logging_level"].description, "toggle_logging_level", "ntopng.prefs.logging_level") prefsToggleButton(subpage_active, { field = "toggle_log_to_file", default = "0", pref = "log_to_file" }) prefsToggleButton(subpage_active, { field = "toggle_access_log", default = "0", pref = "enable_access_log" }) prefsToggleButton(subpage_active, { field = "toggle_host_pools_log", default = "0", pref = "enable_host_pools_log" }) print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form> </table>]] end function printSnmp() if not ntop.isPro() then return end print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">SNMP</th></tr></thead>') local disabled = not info["version.enterprise_edition"] prefsToggleButton(subpage_active, { field = "toggle_snmp_rrds", default = "0", pref = "snmp_devices_rrd_creation", disabled = disabled }) prefsToggleButton(subpage_active, { field = "toggle_snmp_polling", default = "0", pref = "snmp_polling" }) local t_labels = {"v1", "v2c"} local t_values = {"0", "1"} multipleTableButtonPrefs(subpage_active.entries["default_snmp_proto_version"].title, subpage_active.entries["default_snmp_proto_version"].description, t_labels, t_values, "1", "primary", "default_snmp_version", "ntopng.prefs.default_snmp_version", disabled) prefsInputFieldPrefs(subpage_active.entries["default_snmp_community"].title, subpage_active.entries["default_snmp_community"].description, "ntopng.prefs.", "default_snmp_community", "public", false, nil, nil, nil, { attributes = { spellcheck = "false", maxlength = 64 }, disabled = disabled }) prefsInputFieldPrefs(subpage_active.entries["default_snmp_timeout"].title, subpage_active.entries["default_snmp_timeout"].description, "ntopng.prefs.", "snmp_timeout_sec", 3, -- default 3 sec "number", nil, nil, nil, { min = 1, max = 10 }) if(ntop.isEnterpriseXL()) then prefsToggleButton(subpage_active, { field = "toggle_snmp_trap", default = "0", pref = "toggle_snmp_trap" }) end prefsToggleButton(subpage_active, { field = "toggle_snmp_debug", default = "0", pref = "snmp_debug" }) if (disabled) then prefsInformativeField(i18n("notes"), i18n("enterpriseOnly")) end print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form> </table>]] end function printVulnerabilityScan() print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("hosts_stats.page_scan_hosts.prefs_tab_title") .. '</th></tr></thead>') prefsInputFieldPrefs(subpage_active.entries["vs_concurrently_scan_number"].title, subpage_active.entries["vs_concurrently_scan_number"].description, "ntopng.prefs.", "host_to_scan_max_num_scans", prefs.host_to_scan_max_num_scans or 4, "number", true, false, nil, { min = 1, max = 16 }) local default_vs_slow_scan_value = ternary(prefs.vs_slow_scan == false, "0", "1") prefsToggleButton(subpage_active, { field = "toggle_slow_mode", default = default_vs_slow_scan_value, pref = "vs.vs_slow_scan" }) print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form> </table>]] end function printDumpSettings() print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.flows_dump") .. '</th></tr></thead>') local elements_to_switch = {"row_toggle_tiny_flows_dump", "max_num_packets_per_tiny_flow", "max_num_bytes_per_tiny_flow"} if prefs.is_dump_flows_to_es_enabled then elements_to_switch[#elements_to_switch + 1] = "dump_frequency" end prefsToggleButton(subpage_active, { field = "toggle_enable_runtime_flows_dump", default = "1", pref = "enable_runtime_flows_dump", to_switch = elements_to_switch, -- Similar to "to_switch" but for nested items (e.g. "local hosts cache" only -- enabled when both "host cache" and "cache" are enabled). -- The following inputs will be shown/hidden when this preference changes. nested_to_switch = { -- input: the input ID to toggle (e.g. the "local hosts cache") -- parent: the parent of the input which affects the input logic (e.g. "host cache") -- parent_enabled_value: the parent input value that should make the child input visible -- pref_enabled_value: this preference value that should make the child input visible (e.g. "1" when "cache" is enabled) { input = "max_num_packets_per_tiny_flow", parent = "input-toggle_tiny_flows_dump", parent_enabled_value = "1", pref_enabled_value = "1" }, { input = "max_num_bytes_per_tiny_flow", parent = "input-toggle_tiny_flows_dump", parent_enabled_value = "1", pref_enabled_value = "1" }} }) local showAllElements = ntop.getPref("ntopng.prefs.enable_runtime_flows_dump") ~= "0" prefsInputFieldPrefs(subpage_active.entries["dump_frequency"].title, subpage_active.entries["dump_frequency"].description, "ntopng.prefs.", "dump_frequency", prefs.dump_frequency, "number", showAllElements and prefs.is_dump_flows_to_es_enabled, false, nil, { min = 1, max = 2 ^ 32 - 1, tformat = "sm" }) prefsToggleButton(subpage_active, { field = "toggle_tiny_flows_dump", default = "1", pref = "tiny_flows_export_enabled", to_switch = {"max_num_packets_per_tiny_flow", "max_num_bytes_per_tiny_flow"}, reverse_switch = true, hidden = not showAllElements }) local showTinyElements = showAllElements and ntop.getPref("ntopng.prefs.tiny_flows_export_enabled") ~= "1" prefsInputFieldPrefs(subpage_active.entries["max_num_packets_per_tiny_flow"].title, subpage_active.entries["max_num_packets_per_tiny_flow"].description, "ntopng.prefs.", "max_num_packets_per_tiny_flow", prefs.max_num_packets_per_tiny_flow, "number", showTinyElements, false, nil, { min = 1, max = 2 ^ 32 - 1 }) prefsInputFieldPrefs(subpage_active.entries["max_num_bytes_per_tiny_flow"].title, subpage_active.entries["max_num_bytes_per_tiny_flow"].description, "ntopng.prefs.", "max_num_bytes_per_tiny_flow", prefs.max_num_bytes_per_tiny_flow, "number", showTinyElements, false, nil, { min = 1, max = 2 ^ 32 - 1 }) print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form> </table>]] end function printClickHouseOptions() print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.clickhouse") .. '</th></tr></thead>') local showAggregateFlowsPrefs = ntop.isEnterpriseXL() and ntop.isClickHouseEnabled() prefsInputFieldPrefs(subpage_active.entries["flow_data_retention"].title, subpage_active.entries["flow_data_retention"].description, "ntopng.prefs.", "flows_and_alerts_data_retention_days", data_retention_utils.getDefaultRetention(), "number", nil, nil, nil, { min = 1, max = 365 * 10 }) prefsInputFieldPrefs(subpage_active.entries["aggregated_flows_data_retention"].title, subpage_active.entries["aggregated_flows_data_retention"].description, "ntopng.prefs.", "aggregated_flows_data_retention_days", data_retention_utils.getAggregatedFlowsDataRetention(), "number", showAggregateFlowsPrefs, nil, nil, { min = 2, max = 365 * 10 }) prefsInputFieldPrefs(subpage_active.entries["toggle_flow_aggregated_limit"].title, subpage_active.entries["toggle_flow_aggregated_limit"].description, "ntopng.prefs.", "max_aggregated_flows_upperbound", prefs.max_aggregated_flows_upperbound or 10000, "number", showAggregateFlowsPrefs, false, nil, { min = 1000, max = 10000000 }) prefsInputFieldPrefs(subpage_active.entries["toggle_flow_aggregated_traffic_limit"].title, subpage_active.entries["toggle_flow_aggregated_traffic_limit"].description, "ntopng.prefs.", "max_aggregated_flows_traffic_upperbound", prefs.max_aggregated_flows_traffic_upperbound or 5, "number", showAggregateFlowsPrefs, false, nil, { min = 0, max = 5000 }) prefsToggleButton(subpage_active, { field = "toggle_flow_aggregated_alerted_flows", default = "0", pref = "include_alerted_flows_in_aggregated_flows", hidden = not showAggregateFlowsPrefs }) print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" />]] print [[ </form>]] print [[ </table>]] end function printNames() print('<form method="post">') print('<table class="table">') -- ###################### print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.names") .. '</th></tr></thead>') local ntopng_host_info = ntop.getHostInformation() prefsInputFieldPrefs(subpage_active.entries["ntopng_host_address"].title, subpage_active.entries["ntopng_host_address"].description, "ntopng.prefs.", "ntopng_host_address", ntopng_host_info.ip or "", -- default false, true, nil, nil, { attributes = { spellcheck = "false" }, required = false }) prefsInputFieldPrefs(subpage_active.entries["ntopng_instance_name"].title, subpage_active.entries["ntopng_instance_name"].description, "ntopng.prefs.", "ntopng_instance_name", ntopng_host_info.instance_name or "", -- default false, true, nil, nil, { attributes = { spellcheck = "false" }, required = false, disabled = true, skip_redis = true }) print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print('</table>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" />]] print('</form>') end function printMessageBroker() local title = i18n("prefs.message_broker") local current_brokers_pref = "ntopng.prefs.selected_message_broker" local lint_preference = "message_broker" local showElement = (ntop.getPref("ntopng.prefs.toggle_message_broker") == "1") local brokers_list = { names = {i18n('prefs.nats') --[[, i18n('prefs.mqtt')]] }, ids = {'nats' --[[, 'mqtt']] } } local elementsToSwitch = {"row_message_broker", "message_broker_url", "message_broker_username", "message_broker_password", "message_broker_topics_list"} if (_POST["toggle_message_broker"]) then showElement = (_POST["toggle_message_broker"] == "1") end create_table() add_section(title) prefsToggleButton(subpage_active, { field = "toggle_message_broker", default = "0", pref = "toggle_message_broker", to_switch = elementsToSwitch }) local m_broker_type = ntop.getPref("ntopng.prefs.message_broker") local default_broker_id if (not isEmptyString(m_broker_type)) then default_broker_id = m_broker_type else default_broker_id = brokers_list.ids[1] end multipleTableButtonPrefs(subpage_active.entries["message_brokers_list"].title, subpage_active.entries["message_brokers_list"].description, brokers_list.names, brokers_list.ids, default_broker_id, "primary", lint_preference, "ntopng.prefs.message_broker", {nil}, nil, nil, nil, showElement, default_broker_id --[[show]] ) prefsInputFieldPrefs(subpage_active.entries["message_broker_url"].title, subpage_active.entries["message_broker_url"].description, "ntopng.prefs.", "message_broker_url", "", "text", showElement, nil, nil, { attributes = { spellcheck = "false" }, pattern = "[^\\s]+" }) prefsInputFieldPrefs(subpage_active.entries["message_broker_username"].title, subpage_active.entries["message_broker_username"].description, "ntopng.prefs.", "message_broker_username", "", "text", showElement, nil, nil, { attributes = { spellcheck = "false" }, pattern = "[^\\s]+" }) prefsInputFieldPrefs(subpage_active.entries["message_broker_password"].title, subpage_active.entries["message_broker_password"].description, "ntopng.prefs.", "message_broker_password", "", "text", showElement, nil, nil, { attributes = { spellcheck = "false" }, pattern = "[^\\s]+" }) end_table() end function printAssetsInventory() if not ntop.isPro() then return end local disabled = not info["version.enterprise_edition"] local netbox_activation_url = ntop.getPref("ntopng.prefs.netbox_activation_url") local netbox_default_site = ntop.getPref("ntopng.prefs.netbox_default_site") if isEmptyString(netbox_activation_url) then netbox_activation_url = "http://localhost:8000" end if isEmptyString(netbox_default_site) then netbox_default_site = "Default" end print('<form id="assetsInventory" method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">Assets Inventory</th></tr></thead>') -- show or not show table entries for netbox configuration local showNetboxConfiguration = false if ntop.getPref("ntopng.prefs.toggle_netbox") == "1" then showNetboxConfiguration = true end if (_POST["toggle_netbox"]) then showNetboxConfiguration = (_POST["toggle_netbox"] == "1") if (showNetboxConfiguration == true) then package.path = dirs.installdir .. "/pro/scripts/lua/modules/?.lua;" .. package.path local netbox_manager = require("netbox_manager") traceError(TRACE_NORMAL, TRACE_CONSOLE, "[NetBox] Initializing...\n") if (netbox_manager.netbox_initialization() == true) then traceError(TRACE_NORMAL, TRACE_CONSOLE, "[NetBox] Initialization completed") else traceError(TRACE_NORMAL, TRACE_CONSOLE, "[NetBox] Initialization failed") end end end -- ntop asset inventory --[[ prefsToggleButton(subpage_active, { field = "toggle_ntopng_assets_inventory", default = "0", pref = "toggle_ntopng_assets_inventory", to_switch = {} }) ]] -- Netbox toggle prefsToggleButton(subpage_active, { field = "toggle_netbox", default = "0", pref = "toggle_netbox", to_switch = {"netbox_activation_url", "netbox_default_site", "netbox_personal_access_token"} }) -- (label, comment, prekey, key, default_value, _input_type, showEnabled, disableAutocomplete, allowURLs, extra) -- Netbox Activation URL -- tprint(prefs) -- Render the NetBox Activation URL input field prefsInputFieldPrefs(subpage_active.entries["netbox_activation_url"].title, subpage_active.entries["netbox_activation_url"].description, "ntopng.prefs.", "netbox_activation_url", netbox_activation_url, false, showNetboxConfiguration, nil, nil, { attributes = { spellcheck = "false" }, required = true, disabled = disabled }) -- Render the NetBox Default Site input field prefsInputFieldPrefs(subpage_active.entries["netbox_default_site"].title, subpage_active.entries["netbox_default_site"].description, "ntopng.prefs.", "netbox_default_site", netbox_default_site, false, showNetboxConfiguration, nil, nil, { attributes = { spellcheck = "false" }, required = true, disabled = disabled }) -- Netbox Personal Access token prefsInputFieldPrefs(subpage_active.entries["netbox_personal_access_token"].title, subpage_active.entries["netbox_personal_access_token"].description, "ntopng.prefs.", "netbox_personal_access_token", ntop.getPref("ntopng.prefs.netbox_personal_access_token") or "", "text", showNetboxConfiguration, nil, nil, { required = true, inputBoxWidth = "24em", disabled = disabled }) if (disabled) then prefsInformativeField(i18n("notes"), i18n("enterpriseOnly")) end print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" /> </form> </table>]] end function printReportsOptions() print('<form method="post">') print('<table class="table">') print('<thead class="table-primary"><tr><th colspan=2 class="info">' .. i18n("prefs.reports") .. '</th></tr></thead>') prefsToggleButton(subpage_active, { field = "toggle_enable_automatic_reports", default = "0", pref = "automatic_reports_enabled", to_switch = {}, hidden = false }) prefsInputFieldPrefs(subpage_active.entries["reports_data_retention_time"].title, subpage_active.entries["reports_data_retention_time"].description, "ntopng.prefs.", "reports_data_retention_days", data_retention_utils.getDefaultRetention(), "number", nil, nil, nil, { min = 1, max = 365 * 10 }) print( '<tr><th colspan=2 style="text-align:right;"><button type="submit" class="btn btn-primary" style="width:115px" disabled="disabled">' .. i18n("save") .. '</button></th></tr>') print [[<input name="csrf" type="hidden" value="]] print(ntop.getRandomCSRFValue()) print [[" />]] print [[ </form>]] print [[ </table>]] end print [[ <table class="table"> <col width="20%"> <col width="80%"> <tr><td style="padding-right: 20px;">]] print(template.gen("prefs_search.template", { http_prefix = ntop.getHttpPrefix(), placeholder = i18n("prefs.search_preferences") })) print [[ <div class="list-group">]] printMenuSubpages(tab) local simple_view_class = (show_advanced_prefs and 'btn-secondary' or 'btn-primary active') local expert_view_class = (show_advanced_prefs and 'btn-primary active' or 'btn-secondary') print([[ </div> <div class="text-center"> <div id="prefs_toggle" class="btn-group"> <form method='post'> <input name="csrf" type="hidden" value="]] .. ntop.getRandomCSRFValue() .. [[" /> <div class="btn-group btn-toggle mt-2"> <button class='btn btn-sm ]] .. expert_view_class .. [[' name='show_advanced_prefs' value='true'>]] .. i18n("prefs.expert_view") .. [[</button> <button class='btn btn-sm ]] .. simple_view_class .. [[' name='show_advanced_prefs' value='false'>]] .. i18n("prefs.simple_view") .. [[</button> </div> </form> </div> </div> ]]) print [[ </td><td colspan=2>]] if (tab == "in_memory") then printInMemory() end if (tab == "clickhouse") then printClickHouseOptions() end if (tab == "dump_settings") then printDumpSettings() end if (tab == "on_disk_ts") then printStatsTimeseries() end if (tab == "alerts") then printAlerts() end if (tab == "active_monitoring") then printActiveMonitoring() end if (tab == "protocols") then printProtocolPrefs() end if (tab == "discovery") then printNetworkDiscovery() end if (tab == "recording") then printRecording() end if (tab == "traffic_behaviour") then printNetworkBehaviour() end if (tab == "ot_protocols") then printOTProtocols() end if (tab == "names") then printNames() end if (tab == "message_broker") then printMessageBroker() end if (tab == "misc") then printMisc() end if (tab == "gui") then printGUI() end if (tab == "updates") then printUpdates() end if (tab == "auth") then printAuthentication() end if (tab == "ifaces") then printInterfaces() end if (tab == "logging") then printLogging() end if (tab == "snmp") then printSnmp() end if (tab == "reports") then printReportsOptions() end if (tab == "vulnerability_scan") then printVulnerabilityScan() end --[[ if (tab == "assets_inventory") then printAssetsInventory() end ]] print [[ </td></tr> </table> ]] dofile(dirs.installdir .. "/scripts/lua/inc/footer.lua") print([[<script> aysHandleForm("form", { disable_on_dirty: '.disable-on-dirty', }); /* Use the validator script to override default chrome bubble, which is displayed out of window */ $("form[id!='search-host-form']").validator({disable:true}); </script>]]) end --[[ isAdministratorOrPrintErr ]]