1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
--
-- (C) 2017-22 - ntop.org
--
-- ######################################################################################
-- ################### HTTP HOST POOLS CONFIGURATION ####################################
-- ######################################################################################
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
if(ntop.isPro()) then
package.path = dirs.installdir .. "/pro/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/pro/scripts/callbacks/?.lua;" .. package.path
end
if ntop.isnEdge() then
package.path = dirs.installdir .. "/pro/scripts/lua/nedge/modules/?.lua;" .. package.path
end
require "lua_utils"
local json = require "dkjson"
local host_pools_nedge = require "host_pools_nedge"
local users_utils = require("users_utils")
local shaper_utils
if(ntop.isPro()) then
shaper_utils = require "shaper_utils"
end
local http_bridge_conf_utils = {}
-- set to a non-empty value to enable HTTP configuration, e.g.,
--http_bridge_conf_utils.HTTP_BRIDGE_CONFIGURATION_URL = "localhost:8000"
http_bridge_conf_utils.HTTP_BRIDGE_CONFIGURATION_URL = ""
function http_bridge_conf_utils.configureBridge()
if not isEmptyString(http_bridge_conf_utils.HTTP_BRIDGE_CONFIGURATION_URL) then
-- CLEANUP
shaper_utils.clearShapers()
-- empty pool members but don't delete pools
host_pools_nedge.emptyPools()
-- BASIC INITIALIZATION
host_pools_nedge.initPools()
shaper_utils.initShapers()
-- RETRIEVE BRIDGE CONFIGURATION
-- EXAMPLE RESPONSE STRUCTURE:
local rsp = {
-- ["users"] = {
-- ["Not Assigned"] = {
-- ["default_policy"] = "drop",
-- ["policies"] = {
-- ["ConnectivityCheck"] = "pass"
-- }
-- },
-- ["maina"] = {
-- ["full_name"] = "Maina Fast",
-- ["password"] = "ntop0101",
-- ["default_policy"] = "pass",
-- ["policies"] = {
-- [10] = "slow_pass", ["Facebook"] = "slower_pass", ["YouTube"] = "drop"
-- }
-- },
-- ["simon"] = {
-- ["full_name"] = "Simon Speed",
-- ["password"] = "ntop0202",
-- ["default_policy"] = "drop",
-- ["policies"] = {
-- ["MyCustomProtocol"]="pass", [20] = "slow_pass", [22] = "slower_pass"
-- }
-- }
-- }
}
local rsp = ntop.httpGet(http_bridge_conf_utils.HTTP_BRIDGE_CONFIGURATION_URL)
if rsp == nil then
host_pools_nedge.traceHostPoolEvent(TRACE_ERROR, "Unable to obtain a valid configuration from "..http_bridge_conf_utils.HTTP_BRIDGE_CONFIGURATION_URL)
return
end
if rsp["CONTENT"] then rsp = rsp["CONTENT"] end
if not rsp then rsp = {} end
if type(rsp) == "string" then
rsp = json.decode(rsp)
if rsp == nil then
print("Unable to decode response as valid JSON")
end
end
-- Read supported protocols
local ndpi_protocols = {}
for proto_name, proto_id in pairs(interface.getnDPIProtocols()) do
-- case-insensitive
ndpi_protocols[string.lower(proto_name)] = proto_id
end
-- Read supported categories
local ndpi_categories = {}
for cat_name, cat_id in pairs(interface.getnDPICategories()) do
ndpi_categories[string.lower(cat_name)] = cat_id
end
local nedge_shapers = {}
for _, shaper in ipairs(shaper_utils.nedge_shapers) do
nedge_shapers[string.lower(shaper.name)] = shaper
end
-- FOR EACH INTERFACE...
for _, ifname in pairs(interface.getIfNames()) do
interface.select(ifname)
local ifid = getInterfaceId(ifname)
-- SETUP HOST POOLS
for username, user_config in pairs(rsp["users"] or {}) do
if username ~= host_pools_nedge.DEFAULT_POOL_NAME then
users_utils.addUserIfNotExists(ifid, username, user_config["password"] or "", user_config["full_name"] or "")
end
local pool_id = host_pools_nedge.usernameToPoolId(username) or host_pools_nedge.DEFAULT_POOL_ID
host_pools_nedge.traceHostPoolEvent(TRACE_NORMAL, ifname..": creating user: "..username.. " pool id: "..pool_id)
if not isEmptyString(user_config["default_policy"]) then
local default_policy = string.lower(user_config["default_policy"])
if nedge_shapers[default_policy] and default_policy ~= "default" then -- default can't be default :)
host_pools_nedge.traceHostPoolEvent(TRACE_NORMAL, ifname..": setting default policy '"..default_policy.."' for user: "..username.. " pool id: "..pool_id)
shaper_utils.setPoolShaper(ifid, pool_id, nedge_shapers[default_policy].id)
end
for proto, policy in pairs(user_config["policies"] or {}) do
local proto_name = proto
local proto_id_or_category = proto
policy = nedge_shapers[string.lower(policy)]
if tonumber(proto_id_or_category) == nil then
-- proto_id_or_category is not a proto id, check for proto name or category
local lowercase_name = string.lower(proto)
if ndpi_protocols[lowercase_name] then
proto_id_or_category = ndpi_protocols[lowercase_name]
proto_name = string.format("Protocol %s/%d", proto, ndpi_protocols[lowercase_name])
elseif ndpi_categories[lowercase_name] then
proto_id_or_category = "cat_"..ndpi_categories[lowercase_name]
proto_name = string.format("Category %s/%d", proto, ndpi_categories[lowercase_name])
else
host_pools_nedge.traceHostPoolEvent(TRACE_ERROR, ifname..": unable to find protocol '"..proto.."' among known protocols for user: "..username.. " pool id: "..pool_id)
proto_id_or_category = nil
end
end
if policy and proto_id_or_category then
if (policy.name == "DEFAULT") and no_quota then
shaper_utils.deleteProtocol(ifid, pool_id, proto_id_or_category)
else
shaper_utils.setProtocolShapers(ifid, pool_id, proto_id_or_category,
policy.id, policy.id,
0 --[[traffic_quota--]], 0--[[time_quota--]])
host_pools_nedge.traceHostPoolEvent(TRACE_NORMAL, ifname..": setting '"..proto_name.."' policy '"..policy.name.."' for user: "..username.. " pool id: "..pool_id)
end
end
end
end
end
-- must leave it here as well to make sure the C part has updated with the new pools
ntop.reloadHostPools()
-- SETUP ASSOCIATIONS
for member, info in pairs(rsp["associations"] or {}) do
local pool = info["group"]
local connectivity = info["connectivity"]
local pool_id = host_pools_nedge.usernameToPoolId(pool)
if pool == host_pools_nedge.DEFAULT_POOL_NAME then
host_pools_nedge.traceHostPoolEvent(TRACE_ERROR, ifname..": members are associated automatically with default pool "..host_pools_nedge.DEFAULT_POOL_NAME.." skipping association with member: "..member)
elseif not pool_id then
host_pools_nedge.traceHostPoolEvent(TRACE_ERROR, ifname..": pool: "..pool.. " not existing. Unable to set association with: "..member)
else
if connectivity == "pass" then
if host_pools_nedge.addPoolMember(pool_id, member) == true then
host_pools_nedge.traceHostPoolEvent(TRACE_NORMAL, ifname..": member "..member.. " successfully associated to pool: "..pool)
else
host_pools_nedge.traceHostPoolEvent(TRACE_ERROR, ifname..": Unable to associate member "..member.. " to pool: "..pool)
end
end
end
end
end
ntop.reloadHostPools()
end
end
return http_bridge_conf_utils
-- ######################################################################################
-- ######################################################################################
-- ######################################################################################
|