mod_net_proxy/mod_net_proxy.lua
changeset 2967 504bb330e910
parent 2966 6b01600b9c02
child 2979 7eb6fa9b03fd
equal deleted inserted replaced
2966:6b01600b9c02 2967:504bb330e910
    65 	PROXYv1 = { signature = hex.from("50524F5859"), callback = nil },
    65 	PROXYv1 = { signature = hex.from("50524F5859"), callback = nil },
    66 	PROXYv2 = { signature = hex.from("0D0A0D0A000D0A515549540A"), callback = nil }
    66 	PROXYv2 = { signature = hex.from("0D0A0D0A000D0A515549540A"), callback = nil }
    67 };
    67 };
    68 local PROTO_HANDLER_STATUS = { SUCCESS = 0, POSTPONE = 1, FAILURE = 2 };
    68 local PROTO_HANDLER_STATUS = { SUCCESS = 0, POSTPONE = 1, FAILURE = 2 };
    69 
    69 
       
    70 -- Configuration Variables
       
    71 local config_mappings = module:get_option("proxy_port_mappings", {});
       
    72 local config_ports = module:get_option_set("proxy_ports", {});
       
    73 local config_trusted_proxies = module:get_option_set("proxy_trusted_proxies", {"127.0.0.1", "::1"});
       
    74 
    70 -- Persistent In-Memory Storage
    75 -- Persistent In-Memory Storage
    71 local sessions = {};
    76 local sessions = {};
    72 local mappings = {};
    77 local mappings = {};
       
    78 local trusted_networks = set.new();
    73 
    79 
    74 -- Proxy Data Methods
    80 -- Proxy Data Methods
    75 local proxy_data_mt = {}; proxy_data_mt.__index = proxy_data_mt;
    81 local proxy_data_mt = {}; proxy_data_mt.__index = proxy_data_mt;
    76 
    82 
    77 function proxy_data_mt:describe()
    83 function proxy_data_mt:describe()
   312 		service_listener.onconnect(conn);
   318 		service_listener.onconnect(conn);
   313 	end
   319 	end
   314 	return service_listener.onincoming(conn, session.buffer);
   320 	return service_listener.onincoming(conn, session.buffer);
   315 end
   321 end
   316 
   322 
       
   323 local function is_trusted_proxy(conn)
       
   324 	-- If no trusted proxies were configured, trust any incoming connection
       
   325 	-- While this may seem insecure, the module defaults to only trusting 127.0.0.1 and ::1
       
   326 	if trusted_networks:empty() then
       
   327 		return true;
       
   328 	end
       
   329 
       
   330 	-- Iterate through all trusted proxies and check for match against connected IP address
       
   331 	local conn_ip = ip.new_ip(conn:ip());
       
   332 	for trusted_network in trusted_networks:items() do
       
   333 		if ip.match(trusted_network.ip, conn_ip, trusted_network.cidr) then
       
   334 			return true;
       
   335 		end
       
   336 	end
       
   337 
       
   338 	-- Connection does not match any trusted proxy
       
   339 	return false;
       
   340 end
       
   341 
   317 -- Network Listener Methods
   342 -- Network Listener Methods
   318 local listener = {};
   343 local listener = {};
   319 
   344 
   320 function listener.onconnect(conn)
   345 function listener.onconnect(conn)
       
   346 	-- Check if connection is coming from a trusted proxy
       
   347 	if not is_trusted_proxy(conn) then
       
   348 		conn:close();
       
   349 		module:log("warn", "Dropped connection from untrusted proxy: %s", conn:ip());
       
   350 		return;
       
   351 	end
       
   352 
       
   353 	-- Initialize session variables
   321 	sessions[conn] = {
   354 	sessions[conn] = {
   322 		handler = nil;
   355 		handler = nil;
   323 		buffer = nil;
   356 		buffer = nil;
   324 	};
   357 	};
   325 end
   358 end
   386 	sessions[conn] = nil;
   419 	sessions[conn] = nil;
   387 end
   420 end
   388 
   421 
   389 listener.ondetach = listener.ondisconnect;
   422 listener.ondetach = listener.ondisconnect;
   390 
   423 
       
   424 -- Parse trusted proxies which can either contain single hosts or networks
       
   425 if not config_trusted_proxies:empty() then
       
   426 	for trusted_proxy in config_trusted_proxies:items() do
       
   427 		local network = {};
       
   428 		network.ip, network.cidr = ip.parse_cidr(trusted_proxy);
       
   429 		trusted_networks:add(network);
       
   430 	end
       
   431 else
       
   432 	module:log("warn", "No trusted proxies configured, all connections will be accepted - this might be dangerous");
       
   433 end
       
   434 
   391 -- Process all configured port mappings and generate a list of mapped ports
   435 -- Process all configured port mappings and generate a list of mapped ports
   392 local mapped_ports = {};
   436 local mapped_ports = {};
   393 local config_mappings = module:get_option("proxy_port_mappings", {});
       
   394 for port, mapping in pairs(config_mappings) do
   437 for port, mapping in pairs(config_mappings) do
   395 	table.insert(mapped_ports, port);
   438 	table.insert(mapped_ports, port);
   396 	mappings[port] = {
   439 	mappings[port] = {
   397 		service_name = mapping,
   440 		service_name = mapping,
   398 		service = nil,
   441 		service = nil,
   399 	};
   442 	};
   400 end
   443 end
   401 
   444 
   402 -- Log error message when user manually specifies ports without configuring the necessary port mappings
   445 -- Log error message when user manually specifies ports without configuring the necessary port mappings
   403 local config_ports = module:get_option_set("proxy_ports", {});
       
   404 if not config_ports:empty() then
   446 if not config_ports:empty() then
   405 	local missing_ports = config_ports - set.new(mapped_ports);
   447 	local missing_ports = config_ports - set.new(mapped_ports);
   406 	if not missing_ports:empty() then
   448 	if not missing_ports:empty() then
   407 		module:log("error", "Missing port<>service mappings for these ports: %s", tostring(missing_ports));
   449 		module:log("error", "Missing port<>service mappings for these ports: %s", tostring(missing_ports));
   408 	end
   450 	end