From 4df4ea2411a7ad4f2a3c6e07f0de45cc534233c9 Mon Sep 17 00:00:00 2001 From: Vittorio Parrella Date: Tue, 24 Sep 2024 22:44:57 +0200 Subject: [PATCH] feature: #61 - Port filter on outgoing connections via 'ignored_ports' configuration value --- service/service.go | 2 +- workers/client/client_impl_linux.go | 14 ++++-- workers/client/client_impl_windows.go | 2 +- workers/gateway/gateway_interface_linux.go | 46 +++++++++++--------- workers/gateway/gateway_interface_windows.go | 12 +++-- 5 files changed, 47 insertions(+), 29 deletions(-) diff --git a/service/service.go b/service/service.go index 19a0d88..7b575f1 100644 --- a/service/service.go +++ b/service/service.go @@ -271,7 +271,7 @@ func (p *QPepService) Main() error { } // be sure to clear proxy and diverter settings on exit gateway.SetSystemProxy(false) - gateway.SetConnectionDiverter(false, "", "", 0, 0, 0, 0) + gateway.SetConnectionDiverter(false, "", "", 0, 0, 0, 0, []int{}) }() logger.Info("Main") diff --git a/workers/client/client_impl_linux.go b/workers/client/client_impl_linux.go index 8219972..6815480 100644 --- a/workers/client/client_impl_linux.go +++ b/workers/client/client_impl_linux.go @@ -8,10 +8,16 @@ import ( // initDiverter method wraps the logic for initializing the windiverter engine, returns true if the diverter // succeeded initialization and false otherwise func initDiverter() bool { + clientConfig := configuration.QPepConfig.Client + filteredPorts := configuration.QPepConfig.Limits.IgnoredPorts + + listenPort := clientConfig.LocalListenPort + listenHost := clientConfig.LocalListeningAddress + redirected = gateway.SetConnectionDiverter(true, "", - configuration.QPepConfig.Client.LocalListeningAddress, 0, - configuration.QPepConfig.Client.LocalListenPort, 0, - 0) + listenHost, 0, + listenPort, 0, + 0, filteredPorts) return redirected } @@ -19,7 +25,7 @@ func initDiverter() bool { // stopDiverter method wraps the calls for stopping the diverter func stopDiverter() { redirected = false - gateway.SetConnectionDiverter(false, "", "", 0, 0, 0, 0) + gateway.SetConnectionDiverter(false, "", "", 0, 0, 0, 0, []int{}) } // initProxy method wraps the calls for initializing the proxy diff --git a/workers/client/client_impl_windows.go b/workers/client/client_impl_windows.go index 1cc7215..808a726 100644 --- a/workers/client/client_impl_windows.go +++ b/workers/client/client_impl_windows.go @@ -41,7 +41,7 @@ func initDiverter() bool { // stopDiverter method wraps the calls for stopping the diverter func stopDiverter() { - gateway.SetConnectionDiverter(false, "", "", 0, 0, 0, 0) + gateway.SetConnectionDiverter(false, "", "", 0, 0, 0, 0, []int{}) redirected = false } diff --git a/workers/gateway/gateway_interface_linux.go b/workers/gateway/gateway_interface_linux.go index 5e29db5..4d3f386 100644 --- a/workers/gateway/gateway_interface_linux.go +++ b/workers/gateway/gateway_interface_linux.go @@ -7,25 +7,14 @@ import ( "github.com/parvit/qpep/shared/logger" "net" "net/url" + "strconv" ) -const ( - // 25 smtp - // 21 ftp - // 22 ssh - // 23 telnet - // 53 dns - // 67, 68. dhcp - // 80, 443 http/https - // 143 imap - // 161, 162 snmp - // 636 ldap - // 989, 990 sftp - // 1025:65535 other tcp - PROTOCOLS_PORTS_LIST = `21:25,53,67,68,80,443,143,636,161:162,989:990,1025:65535` -) +var ( + redirectOn = false -var redirectOn = false + defaultPortsIgnored = []int{53} +) func getRouteGatewayInterfaces() ([]int64, []string, error) { defaultIP, err := gateway.DiscoverInterface() @@ -43,11 +32,13 @@ func GetSystemProxyEnabled() (bool, *url.URL) { return false, nil } -func SetConnectionDiverter(active bool, gatewayAddr, listenAddr string, gatewayPort, listenPort, numThreads int, gatewayInterface int64) bool { +func SetConnectionDiverter(active bool, gatewayAddr, listenAddr string, gatewayPort, listenPort, numThreads int, + gatewayInterface int64, ignoredPorts []int) bool { redirectOn = active if active { - logger.Info("Setting system iptables\n") + logger.Info("Initializing iptables: %v %v %v %v %v %v %v\n", + gatewayAddr, listenAddr, gatewayPort, listenPort, numThreads, gatewayInterface) _, err, _ := shared.RunCommand("bash", "-c", "iptables -P FORWARD ACCEPT") if err != nil { @@ -55,15 +46,30 @@ func SetConnectionDiverter(active bool, gatewayAddr, listenAddr string, gatewayP return false } + var allIgnoredPorts = append([]int{}, defaultPortsIgnored...) + allIgnoredPorts = append(allIgnoredPorts, gatewayPort) + allIgnoredPorts = append(allIgnoredPorts, listenPort) + allIgnoredPorts = append(allIgnoredPorts, ignoredPorts...) + + var allIgnoredStr = "" + for i := 0; i < len(allIgnoredPorts); i++ { + if i == 0 { + allIgnoredStr = strconv.FormatInt(int64(allIgnoredPorts[i]), 10) + continue + } + + allIgnoredStr += "," + strconv.FormatInt(int64(allIgnoredPorts[i]), 10) + } + _, err, _ = shared.RunCommand("bash", "-c", - fmt.Sprintf("iptables -t nat -A OUTPUT -j DNAT -p tcp --to-destination %s:%d -m multiport --destination-ports %s", listenAddr, listenPort, PROTOCOLS_PORTS_LIST)) + fmt.Sprintf("iptables -t nat -A OUTPUT -j DNAT -p tcp --to-destination %s:%d -m multiport ! --dports %s", listenAddr, listenPort, allIgnoredStr)) if err != nil { logger.Error("%v\n", err) return false } _, err, _ = shared.RunCommand("bash", "-c", - fmt.Sprintf("iptables -t nat -A POSTROUTING -j MASQUERADE -p tcp -m multiport --destination-ports %s", PROTOCOLS_PORTS_LIST)) + fmt.Sprintf("iptables -t nat -A POSTROUTING -j MASQUERADE -p tcp -m multiport ! --dports %s", allIgnoredStr)) if err != nil { logger.Error("%v\n", err) return false diff --git a/workers/gateway/gateway_interface_windows.go b/workers/gateway/gateway_interface_windows.go index 0e1a8fd..5b27071 100644 --- a/workers/gateway/gateway_interface_windows.go +++ b/workers/gateway/gateway_interface_windows.go @@ -277,10 +277,16 @@ func preloadRegistryKeysForUsers() { } } -func SetConnectionDiverter(active bool, gatewayAddr, listenAddr string, gatewayPort, listenPort, numThreads int, gatewayInterface int64) bool { +func SetConnectionDiverter(active bool, gatewayAddr, listenAddr string, + gatewayPort, listenPort, numThreads int, + gatewayInterface int64, ignoredPorts []int) bool { + if active { - logger.Info("Initializing WinDivert: %v %v %v %v %v %v\n", gatewayAddr, listenAddr, gatewayPort, listenPort, numThreads, gatewayInterface) - code := windivert.InitializeWinDivertEngine(gatewayAddr, listenAddr, gatewayPort, listenPort, numThreads, gatewayInterface) + logger.Info("Initializing WinDivert: %v %v %v %v %v %v %v\n", + gatewayAddr, listenAddr, gatewayPort, listenPort, numThreads, gatewayInterface) + + code := windivert.InitializeWinDivertEngine(gatewayAddr, listenAddr, gatewayPort, + listenPort, numThreads, gatewayInterface, ignoredPorts) logger.Info("WinDivert code: %v\n", code) if code != windivert.DIVERT_OK { logger.Error("Could not initialize WinDivert engine, code %d\n", code)