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 |