From 5554f053163c7d2a7a6eb70834a9ebc0d0b3bb41 Mon Sep 17 00:00:00 2001 From: Jose Angel Sanchez Velazquez Date: Wed, 26 Mar 2025 14:29:01 +0100 Subject: [PATCH 01/14] force update agent related services --- installer/docker.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/installer/docker.go b/installer/docker.go index 437d6d21a..3288ee93b 100644 --- a/installer/docker.go +++ b/installer/docker.go @@ -93,6 +93,13 @@ func PostInstallation() error { fmt.Println("Restarting Stack") + if err := utils.RunCmd("docker", "service", "update", "--force", "utmstack_agentmanager"); err != nil { + return err + } + if err := utils.RunCmd("docker", "service", "update", "--force", "utmstack_log-auth-proxy"); err != nil { + return err + } + time.Sleep(60 * time.Second) if err := utils.RunCmd("systemctl", "restart", "docker"); err != nil { From c0867362f462f725d2e45c9f0abd8fdc59bc1aae Mon Sep 17 00:00:00 2001 From: Jose Angel Sanchez Velazquez Date: Wed, 26 Mar 2025 14:30:32 +0100 Subject: [PATCH 02/14] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba16711a3..1740cac41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ -- Fixed issue where tabs remained open when navigating outside the Log Explorer scope to improve user experience. -- Fixed time filter issue where the date range was not applied correctly. -- Fixed incorrect query behavior when filtering incidents by ID. +-- Agent Services force update opening necessary ports ## New Features and Improvements From 7ef5e695dd991ebcbfc28bfe748c2fec024f5115 Mon Sep 17 00:00:00 2001 From: Jose Angel Sanchez Velazquez Date: Wed, 26 Mar 2025 14:53:47 +0100 Subject: [PATCH 03/14] force service update after final restart --- installer/docker.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/installer/docker.go b/installer/docker.go index 3288ee93b..fd1563b74 100644 --- a/installer/docker.go +++ b/installer/docker.go @@ -93,13 +93,6 @@ func PostInstallation() error { fmt.Println("Restarting Stack") - if err := utils.RunCmd("docker", "service", "update", "--force", "utmstack_agentmanager"); err != nil { - return err - } - if err := utils.RunCmd("docker", "service", "update", "--force", "utmstack_log-auth-proxy"); err != nil { - return err - } - time.Sleep(60 * time.Second) if err := utils.RunCmd("systemctl", "restart", "docker"); err != nil { @@ -110,6 +103,13 @@ func PostInstallation() error { return err } + if err := utils.RunCmd("docker", "service", "update", "--force", "utmstack_agentmanager"); err != nil { + return err + } + if err := utils.RunCmd("docker", "service", "update", "--force", "utmstack_log-auth-proxy"); err != nil { + return err + } + fmt.Println("Restarting Stack [OK]") fmt.Println("Cleaning up Docker system") From ab269360d6e112953f5fb7ae8cbaf40a9b6c7def Mon Sep 17 00:00:00 2001 From: JocLRojas Date: Wed, 26 Mar 2025 10:14:00 -0400 Subject: [PATCH 04/14] Revert online/offline mode check in Sophos integration. --- sophos/main.go | 4 ---- sophos/utils/check.go | 45 ------------------------------------------- 2 files changed, 49 deletions(-) delete mode 100644 sophos/utils/check.go diff --git a/sophos/main.go b/sophos/main.go index 2fc387f04..9ecb81056 100644 --- a/sophos/main.go +++ b/sophos/main.go @@ -21,10 +21,6 @@ func main() { client := utmconf.NewUTMClient(intKey, "http://"+panelServ) for { - if err := utils.ConnectionChecker(configuration.CHECKCON); err != nil { - utils.Logger.ErrorF("External connection failure detected: %v", err) - } - moduleConfig, err := client.GetUTMConfig(enum.SOPHOS) if err != nil { if strings.Contains(err.Error(), "invalid character '<'") { diff --git a/sophos/utils/check.go b/sophos/utils/check.go deleted file mode 100644 index 5ab7c1ccd..000000000 --- a/sophos/utils/check.go +++ /dev/null @@ -1,45 +0,0 @@ -package utils - -import ( - "context" - "fmt" - "net/http" - "time" -) - -const connectionTimeout = 5 * time.Second - -func ConnectionChecker(url string) error { - checkConn := func() error { - ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout) - defer cancel() - - if err := checkConnection(url, ctx); err != nil { - return fmt.Errorf("connection failed") - } - return nil - } - - if err := Logger.InfiniteRetryIfXError(checkConn, "connection failed"); err != nil { - return err - } - - return nil -} - -func checkConnection(url string, ctx context.Context) error { - client := &http.Client{} - - req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) - if err != nil { - return err - } - - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - return nil -} From 7f957699b8eda7322c2f780e0179a09eaf63b371 Mon Sep 17 00:00:00 2001 From: JocLRojas Date: Wed, 26 Mar 2025 10:14:22 -0400 Subject: [PATCH 05/14] Revert online/offline mode check in AWS integration. --- aws/main.go | 4 ---- aws/utils/check.go | 42 ------------------------------------------ 2 files changed, 46 deletions(-) delete mode 100644 aws/utils/check.go diff --git a/aws/main.go b/aws/main.go index 453e87f67..9b0578fda 100644 --- a/aws/main.go +++ b/aws/main.go @@ -23,10 +23,6 @@ func main() { st := time.Now().Add(-600 * time.Second) for { - if err := utils.ConnectionChecker(configuration.URL_CHECK_CONNECTION); err != nil { - utils.Logger.ErrorF("Failed to establish connection: %v", err) - } - et := st.Add(299 * time.Second) moduleConfig, err := client.GetUTMConfig(enum.AWS_IAM_USER) if err != nil { diff --git a/aws/utils/check.go b/aws/utils/check.go deleted file mode 100644 index f7212deb0..000000000 --- a/aws/utils/check.go +++ /dev/null @@ -1,42 +0,0 @@ -package utils - -import ( - "fmt" - "net/http" - "time" -) - -func ConnectionChecker(url string) error { - checkConn := func() error { - if err := checkPanelConnection(url); err != nil { - return fmt.Errorf("connection failed: %v", err) - } - - return nil - } - - if err := Logger.InfiniteRetryIfXError(checkConn, "connection failed"); err != nil { - return err - } - - return nil -} - -func checkPanelConnection(url string) error { - client := &http.Client{ - Timeout: 30 * time.Second, - } - - req, err := http.NewRequest(http.MethodGet, url, nil) - if err != nil { - return err - } - - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - return nil -} From 5b4a89f12b5aec96c7a7816373ccacd0b90d3954 Mon Sep 17 00:00:00 2001 From: JocLRojas Date: Wed, 26 Mar 2025 10:14:54 -0400 Subject: [PATCH 06/14] Revert online/offline mode check in Bitdefender integration. --- bitdefender/configuration/config.go | 5 ---- bitdefender/utils/check.go | 43 ----------------------------- 2 files changed, 48 deletions(-) delete mode 100644 bitdefender/utils/check.go diff --git a/bitdefender/configuration/config.go b/bitdefender/configuration/config.go index c5eaf7fd6..b0dfbb5a9 100644 --- a/bitdefender/configuration/config.go +++ b/bitdefender/configuration/config.go @@ -12,7 +12,6 @@ import ( "github.com/threatwinds/logger" "github.com/utmstack/UTMStack/bitdefender/constants" - "github.com/utmstack/UTMStack/bitdefender/utils" "github.com/utmstack/config-client-go/enum" "github.com/utmstack/config-client-go/types" @@ -37,10 +36,6 @@ func ConfigureModules(cnf *types.ConfigurationSection, mutex *sync.Mutex, h *log for { time.Sleep(delayCheckConfig) - if err := utils.ConnectionChecker(constants.URL_CHECK_CONNECTION, h); err != nil { - h.ErrorF("Failed to establish connection: %v", err) - } - tempModuleConfig, err := client.GetUTMConfig(enum.BITDEFENDER) if err != nil { if strings.Contains(err.Error(), "invalid character '<'") { diff --git a/bitdefender/utils/check.go b/bitdefender/utils/check.go deleted file mode 100644 index a39840a2f..000000000 --- a/bitdefender/utils/check.go +++ /dev/null @@ -1,43 +0,0 @@ -package utils - -import ( - "fmt" - "net/http" - "time" - - "github.com/threatwinds/logger" -) - -func ConnectionChecker(url string, h *logger.Logger) error { - checkConn := func() error { - if err := CheckConnection(url); err != nil { - return fmt.Errorf("connection failed: %v", err) - } - return nil - } - - if err := h.InfiniteRetryIfXError(checkConn, "connection failed"); err != nil { - return err - } - - return nil -} - -func CheckConnection(url string) error { - client := &http.Client{ - Timeout: 30 * time.Second, - } - - req, err := http.NewRequest(http.MethodGet, url, nil) - if err != nil { - return err - } - - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - return nil -} From 55c8d791764bff6847517e9998d660fb050e5d80 Mon Sep 17 00:00:00 2001 From: JocLRojas Date: Wed, 26 Mar 2025 10:15:17 -0400 Subject: [PATCH 07/14] Revert online/offline mode check in Office365 integration. --- office365/main.go | 4 ---- office365/utils/check.go | 45 ---------------------------------------- 2 files changed, 49 deletions(-) delete mode 100644 office365/utils/check.go diff --git a/office365/main.go b/office365/main.go index d59c98304..2b0d7d271 100644 --- a/office365/main.go +++ b/office365/main.go @@ -23,10 +23,6 @@ func main() { st := time.Now().Add(-600 * time.Second) for { - if err := utils.ConnectionChecker(configuration.LoginUrl); err != nil { - utils.Logger.ErrorF("External connection failure detected: %v", err) - } - et := st.Add(299 * time.Second) startTime := st.UTC().Format("2006-01-02T15:04:05") endTime := et.UTC().Format("2006-01-02T15:04:05") diff --git a/office365/utils/check.go b/office365/utils/check.go deleted file mode 100644 index 5ab7c1ccd..000000000 --- a/office365/utils/check.go +++ /dev/null @@ -1,45 +0,0 @@ -package utils - -import ( - "context" - "fmt" - "net/http" - "time" -) - -const connectionTimeout = 5 * time.Second - -func ConnectionChecker(url string) error { - checkConn := func() error { - ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout) - defer cancel() - - if err := checkConnection(url, ctx); err != nil { - return fmt.Errorf("connection failed") - } - return nil - } - - if err := Logger.InfiniteRetryIfXError(checkConn, "connection failed"); err != nil { - return err - } - - return nil -} - -func checkConnection(url string, ctx context.Context) error { - client := &http.Client{} - - req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) - if err != nil { - return err - } - - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - return nil -} From 4a10c5c51f7dfe9a9d28829d8492bffa27a18f6a Mon Sep 17 00:00:00 2001 From: Yorjander Hernandez Vergara Date: Wed, 26 Mar 2025 13:59:34 -0400 Subject: [PATCH 08/14] Revert "Revert online/offline mode check in Office365 integration." This reverts commit 55c8d791764bff6847517e9998d660fb050e5d80. --- office365/main.go | 4 ++++ office365/utils/check.go | 45 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 office365/utils/check.go diff --git a/office365/main.go b/office365/main.go index 2b0d7d271..d59c98304 100644 --- a/office365/main.go +++ b/office365/main.go @@ -23,6 +23,10 @@ func main() { st := time.Now().Add(-600 * time.Second) for { + if err := utils.ConnectionChecker(configuration.LoginUrl); err != nil { + utils.Logger.ErrorF("External connection failure detected: %v", err) + } + et := st.Add(299 * time.Second) startTime := st.UTC().Format("2006-01-02T15:04:05") endTime := et.UTC().Format("2006-01-02T15:04:05") diff --git a/office365/utils/check.go b/office365/utils/check.go new file mode 100644 index 000000000..5ab7c1ccd --- /dev/null +++ b/office365/utils/check.go @@ -0,0 +1,45 @@ +package utils + +import ( + "context" + "fmt" + "net/http" + "time" +) + +const connectionTimeout = 5 * time.Second + +func ConnectionChecker(url string) error { + checkConn := func() error { + ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout) + defer cancel() + + if err := checkConnection(url, ctx); err != nil { + return fmt.Errorf("connection failed") + } + return nil + } + + if err := Logger.InfiniteRetryIfXError(checkConn, "connection failed"); err != nil { + return err + } + + return nil +} + +func checkConnection(url string, ctx context.Context) error { + client := &http.Client{} + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return err + } + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} From c412467ce46d6e1112bb729a920c1a3d86d19df6 Mon Sep 17 00:00:00 2001 From: Yorjander Hernandez Vergara Date: Wed, 26 Mar 2025 14:00:34 -0400 Subject: [PATCH 09/14] Revert "Revert online/offline mode check in Bitdefender integration." This reverts commit 5b4a89f12b5aec96c7a7816373ccacd0b90d3954. --- bitdefender/configuration/config.go | 5 ++++ bitdefender/utils/check.go | 43 +++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 bitdefender/utils/check.go diff --git a/bitdefender/configuration/config.go b/bitdefender/configuration/config.go index b0dfbb5a9..c5eaf7fd6 100644 --- a/bitdefender/configuration/config.go +++ b/bitdefender/configuration/config.go @@ -12,6 +12,7 @@ import ( "github.com/threatwinds/logger" "github.com/utmstack/UTMStack/bitdefender/constants" + "github.com/utmstack/UTMStack/bitdefender/utils" "github.com/utmstack/config-client-go/enum" "github.com/utmstack/config-client-go/types" @@ -36,6 +37,10 @@ func ConfigureModules(cnf *types.ConfigurationSection, mutex *sync.Mutex, h *log for { time.Sleep(delayCheckConfig) + if err := utils.ConnectionChecker(constants.URL_CHECK_CONNECTION, h); err != nil { + h.ErrorF("Failed to establish connection: %v", err) + } + tempModuleConfig, err := client.GetUTMConfig(enum.BITDEFENDER) if err != nil { if strings.Contains(err.Error(), "invalid character '<'") { diff --git a/bitdefender/utils/check.go b/bitdefender/utils/check.go new file mode 100644 index 000000000..a39840a2f --- /dev/null +++ b/bitdefender/utils/check.go @@ -0,0 +1,43 @@ +package utils + +import ( + "fmt" + "net/http" + "time" + + "github.com/threatwinds/logger" +) + +func ConnectionChecker(url string, h *logger.Logger) error { + checkConn := func() error { + if err := CheckConnection(url); err != nil { + return fmt.Errorf("connection failed: %v", err) + } + return nil + } + + if err := h.InfiniteRetryIfXError(checkConn, "connection failed"); err != nil { + return err + } + + return nil +} + +func CheckConnection(url string) error { + client := &http.Client{ + Timeout: 30 * time.Second, + } + + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return err + } + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} From ba77eb73dd74359e14c2ce3d17c4fe1fe4b37b9f Mon Sep 17 00:00:00 2001 From: Yorjander Hernandez Vergara Date: Wed, 26 Mar 2025 14:00:41 -0400 Subject: [PATCH 10/14] Revert "Revert online/offline mode check in AWS integration." This reverts commit 7f957699b8eda7322c2f780e0179a09eaf63b371. --- aws/main.go | 4 ++++ aws/utils/check.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 aws/utils/check.go diff --git a/aws/main.go b/aws/main.go index 9b0578fda..453e87f67 100644 --- a/aws/main.go +++ b/aws/main.go @@ -23,6 +23,10 @@ func main() { st := time.Now().Add(-600 * time.Second) for { + if err := utils.ConnectionChecker(configuration.URL_CHECK_CONNECTION); err != nil { + utils.Logger.ErrorF("Failed to establish connection: %v", err) + } + et := st.Add(299 * time.Second) moduleConfig, err := client.GetUTMConfig(enum.AWS_IAM_USER) if err != nil { diff --git a/aws/utils/check.go b/aws/utils/check.go new file mode 100644 index 000000000..f7212deb0 --- /dev/null +++ b/aws/utils/check.go @@ -0,0 +1,42 @@ +package utils + +import ( + "fmt" + "net/http" + "time" +) + +func ConnectionChecker(url string) error { + checkConn := func() error { + if err := checkPanelConnection(url); err != nil { + return fmt.Errorf("connection failed: %v", err) + } + + return nil + } + + if err := Logger.InfiniteRetryIfXError(checkConn, "connection failed"); err != nil { + return err + } + + return nil +} + +func checkPanelConnection(url string) error { + client := &http.Client{ + Timeout: 30 * time.Second, + } + + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return err + } + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} From 73cac18fd3a637709971194a99c95a08b400eb00 Mon Sep 17 00:00:00 2001 From: Yorjander Hernandez Vergara Date: Wed, 26 Mar 2025 14:00:47 -0400 Subject: [PATCH 11/14] Revert "Revert online/offline mode check in Sophos integration." This reverts commit ab269360d6e112953f5fb7ae8cbaf40a9b6c7def. --- sophos/main.go | 4 ++++ sophos/utils/check.go | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 sophos/utils/check.go diff --git a/sophos/main.go b/sophos/main.go index 9ecb81056..2fc387f04 100644 --- a/sophos/main.go +++ b/sophos/main.go @@ -21,6 +21,10 @@ func main() { client := utmconf.NewUTMClient(intKey, "http://"+panelServ) for { + if err := utils.ConnectionChecker(configuration.CHECKCON); err != nil { + utils.Logger.ErrorF("External connection failure detected: %v", err) + } + moduleConfig, err := client.GetUTMConfig(enum.SOPHOS) if err != nil { if strings.Contains(err.Error(), "invalid character '<'") { diff --git a/sophos/utils/check.go b/sophos/utils/check.go new file mode 100644 index 000000000..5ab7c1ccd --- /dev/null +++ b/sophos/utils/check.go @@ -0,0 +1,45 @@ +package utils + +import ( + "context" + "fmt" + "net/http" + "time" +) + +const connectionTimeout = 5 * time.Second + +func ConnectionChecker(url string) error { + checkConn := func() error { + ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout) + defer cancel() + + if err := checkConnection(url, ctx); err != nil { + return fmt.Errorf("connection failed") + } + return nil + } + + if err := Logger.InfiniteRetryIfXError(checkConn, "connection failed"); err != nil { + return err + } + + return nil +} + +func checkConnection(url string, ctx context.Context) error { + client := &http.Client{} + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return err + } + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} From 07841bd06cc0a5169e92ee3501deb0f02f81c5ab Mon Sep 17 00:00:00 2001 From: Yorjander Hernandez Vergara Date: Wed, 26 Mar 2025 14:19:39 -0400 Subject: [PATCH 12/14] Update base images to ubuntu 24 --- agent-manager/Dockerfile | 6 +++--- aws/Dockerfile | 6 ++++-- bitdefender/Dockerfile | 6 ++++-- log-auth-proxy/Dockerfile | 6 +++--- office365/Dockerfile | 6 ++++-- sophos/Dockerfile | 6 ++++-- 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/agent-manager/Dockerfile b/agent-manager/Dockerfile index 8435564ac..fc24f3388 100644 --- a/agent-manager/Dockerfile +++ b/agent-manager/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 +FROM ubuntu:24.04 COPY agent-manager /app/ COPY ./dependencies/agent/ /dependencies/agent/ @@ -6,8 +6,8 @@ COPY ./dependencies/collector/ /dependencies/collector/ # Install jq RUN apt-get update && \ - apt-get install -y jq && \ - apt-get install -y wget && \ + apt-get install -y ca-certificates jq wget && \ + update-ca-certificates && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* diff --git a/aws/Dockerfile b/aws/Dockerfile index 8de052faf..3f0aae8a8 100644 --- a/aws/Dockerfile +++ b/aws/Dockerfile @@ -1,6 +1,8 @@ -FROM ubuntu:latest +FROM ubuntu:24.04 -RUN apt update +RUN apt-get update +RUN apt-get install -y ca-certificates +RUN update-ca-certificates COPY aws . diff --git a/bitdefender/Dockerfile b/bitdefender/Dockerfile index d5f5c3d75..827c1138b 100644 --- a/bitdefender/Dockerfile +++ b/bitdefender/Dockerfile @@ -1,6 +1,8 @@ -FROM ubuntu:latest +FROM ubuntu:24.04 -RUN apt update +RUN apt-get update +RUN apt-get install -y ca-certificates +RUN update-ca-certificates COPY bitdefender . diff --git a/log-auth-proxy/Dockerfile b/log-auth-proxy/Dockerfile index ed9c7c0e4..ac3a11969 100644 --- a/log-auth-proxy/Dockerfile +++ b/log-auth-proxy/Dockerfile @@ -1,11 +1,11 @@ -FROM ubuntu:22.04 +FROM ubuntu:24.04 COPY log-auth-proxy /app/ # Install jq RUN apt-get update && \ - apt-get install -y jq && \ - apt-get install -y wget && \ + apt-get install -y ca-certificates jq wget && \ + update-ca-certificates && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* diff --git a/office365/Dockerfile b/office365/Dockerfile index 5208d5af7..4c51570bc 100644 --- a/office365/Dockerfile +++ b/office365/Dockerfile @@ -1,6 +1,8 @@ -FROM ubuntu:latest +FROM ubuntu:24.04 -RUN apt update +RUN apt-get update +RUN apt-get install -y ca-certificates +RUN update-ca-certificates COPY office365 . diff --git a/sophos/Dockerfile b/sophos/Dockerfile index 1c3834142..a6d1936e1 100644 --- a/sophos/Dockerfile +++ b/sophos/Dockerfile @@ -1,6 +1,8 @@ -FROM ubuntu:latest +FROM ubuntu:24.04 -RUN apt update +RUN apt-get update +RUN apt-get install -y ca-certificates +RUN update-ca-certificates COPY sophos . From 637bdb6f555e7c3322f242bfea93464a9cbd16e1 Mon Sep 17 00:00:00 2001 From: Yorjander Hernandez Vergara Date: Wed, 26 Mar 2025 16:14:47 -0400 Subject: [PATCH 13/14] remove temporary healthcheck --- agent-manager/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent-manager/Dockerfile b/agent-manager/Dockerfile index fc24f3388..41e405726 100644 --- a/agent-manager/Dockerfile +++ b/agent-manager/Dockerfile @@ -24,7 +24,7 @@ EXPOSE 50051 EXPOSE 8080 # Set the health check -HEALTHCHECK --interval=60s --timeout=5s --start-period=5s --retries=3 CMD grpcurl -insecure -plaintext -d '{"service": ""}' localhost:50051 grpc.health.v1.Health/Check | jq -e '.status == "SERVING"' || exit 1 +# HEALTHCHECK --interval=60s --timeout=5s --start-period=5s --retries=3 CMD grpcurl -insecure -plaintext -d '{"service": ""}' localhost:50051 grpc.health.v1.Health/Check | jq -e '.status == "SERVING"' || exit 1 # Run the agent-manager binary From c206950c1ee827e96905386b1055cb17400c6f05 Mon Sep 17 00:00:00 2001 From: Yorjander Hernandez Vergara Date: Thu, 27 Mar 2025 16:48:44 -0400 Subject: [PATCH 14/14] change base image --- agent-manager/Dockerfile | 2 +- agent-manager/agent/agent_command.go | 3 +- agent-manager/agent/agent_imp.go | 61 ++++++++------------- agent-manager/agent/collector_imp.go | 43 ++++++--------- agent-manager/agent/ping_imp.go | 4 +- agent-manager/auth/interceptor.go | 10 ++-- agent-manager/main.go | 24 ++++---- agent-manager/migration/migrations.go | 27 ++++----- agent-manager/service/last_seen_service.go | 7 +-- agent-manager/updates/updates.go | 4 +- agent-manager/util/logger.go | 32 +++++++---- aws/Dockerfile | 3 +- aws/main.go | 6 ++ aws/utils/check.go | 42 ++++++++++++++ aws/utils/req.go | 8 +-- bitdefender/Dockerfile | 2 +- bitdefender/configuration/config.go | 56 ++++++++++--------- bitdefender/main.go | 12 ++-- bitdefender/server/server.go | 23 ++++---- bitdefender/server/syslog.go | 10 ++-- bitdefender/utils/check.go | 41 ++++++++++++++ bitdefender/utils/logger.go | 33 +++++++---- correlation/Dockerfile | 2 +- log-auth-proxy/Dockerfile | 2 +- log-auth-proxy/handlers/http_handler.go | 19 +++---- log-auth-proxy/handlers/tcp_handler.go | 5 +- log-auth-proxy/logservice/auth_service.go | 12 ++-- log-auth-proxy/logservice/output_service.go | 16 ++---- log-auth-proxy/main.go | 19 +++---- log-auth-proxy/middleware/log_auth.go | 6 +- log-auth-proxy/utils/logger.go | 32 +++++++---- office365/Dockerfile | 2 +- office365/main.go | 5 ++ office365/utils/check.go | 45 +++++++++++++++ sophos/Dockerfile | 2 +- sophos/main.go | 4 ++ sophos/utils/check.go | 45 +++++++++++++++ 37 files changed, 415 insertions(+), 254 deletions(-) create mode 100644 aws/utils/check.go create mode 100644 bitdefender/utils/check.go create mode 100644 office365/utils/check.go create mode 100644 sophos/utils/check.go diff --git a/agent-manager/Dockerfile b/agent-manager/Dockerfile index 27873785c..a42a9d2b1 100644 --- a/agent-manager/Dockerfile +++ b/agent-manager/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 +FROM debian:bookworm-slim COPY agent-manager /app/ COPY ./dependencies/agent/ /dependencies/agent/ diff --git a/agent-manager/agent/agent_command.go b/agent-manager/agent/agent_command.go index 6bcd8e632..73bf8d1c0 100644 --- a/agent-manager/agent/agent_command.go +++ b/agent-manager/agent/agent_command.go @@ -9,14 +9,13 @@ import ( ) func (s *Grpc) ListAgentCommands(ctx context.Context, req *ListRequest) (*ListAgentsCommandsResponse, error) { - h := util.GetLogger() page := util.NewPaginator(int(req.PageSize), int(req.PageNumber), req.SortBy) filter := util.NewFilter(req.SearchQuery) commands, total, err := agentCommandService.ListAgentCommands(page, filter) if err != nil { - h.ErrorF("failed to fetch agents: %v", err) + util.Logger.ErrorF("failed to fetch agents: %v", err) return nil, status.Errorf(codes.Internal, "failed to fetch agents: %v", err) } diff --git a/agent-manager/agent/agent_imp.go b/agent-manager/agent/agent_imp.go index 67d3a4656..c88defd34 100644 --- a/agent-manager/agent/agent_imp.go +++ b/agent-manager/agent/agent_imp.go @@ -17,7 +17,6 @@ import ( ) func (s *Grpc) RegisterAgent(ctx context.Context, req *AgentRequest) (*AuthResponse, error) { - h := util.GetLogger() agent := &models.Agent{ Ip: req.GetIp(), Hostname: req.GetHostname(), @@ -40,7 +39,7 @@ func (s *Grpc) RegisterAgent(ctx context.Context, req *AgentRequest) (*AuthRespo Key: oldAgent.AgentKey, }, nil } else { - h.ErrorF("Agent with hostname %s already exists", agent.Hostname) + util.Logger.ErrorF("Agent with hostname %s already exists", agent.Hostname) return nil, status.Errorf(codes.AlreadyExists, "hostname has already been registered") } } @@ -49,7 +48,7 @@ func (s *Grpc) RegisterAgent(ctx context.Context, req *AgentRequest) (*AuthRespo agent.AgentKey = key err = agentService.Create(agent) if err != nil { - h.ErrorF("Failed to create agent: %v", err) + util.Logger.ErrorF("Failed to create agent: %v", err) return nil, err } @@ -59,7 +58,7 @@ func (s *Grpc) RegisterAgent(ctx context.Context, req *AgentRequest) (*AuthRespo err = lastSeenService.Set(key, time.Now()) if err != nil { - h.ErrorF("Failed to set last seen: %v", err) + util.Logger.ErrorF("Failed to set last seen: %v", err) return nil, err } res := &AuthResponse{ @@ -67,13 +66,11 @@ func (s *Grpc) RegisterAgent(ctx context.Context, req *AgentRequest) (*AuthRespo Key: key, } - h.Info("Agent %s with id %d registered correctly", agent.Hostname, agent.ID) + util.Logger.Info("Agent %s with id %d registered correctly", agent.Hostname, agent.ID) return res, nil } func (s *Grpc) UpdateAgent(ctx context.Context, req *AgentRequest) (*AuthResponse, error) { - h := util.GetLogger() - md, ok := metadata.FromIncomingContext(ctx) if !ok { return &AuthResponse{}, status.Error(codes.Internal, "unable to get metadata from context") @@ -91,7 +88,7 @@ func (s *Grpc) UpdateAgent(ctx context.Context, req *AgentRequest) (*AuthRespons agent, err := agentService.FindByID(uint(id)) if err != nil { - h.ErrorF("Failed to find agent: %v", err) + util.Logger.ErrorF("Failed to find agent: %v", err) return nil, err } @@ -122,7 +119,7 @@ func (s *Grpc) UpdateAgent(ctx context.Context, req *AgentRequest) (*AuthRespons err = agentService.Update(agent) if err != nil { - h.ErrorF("Failed to update agent: %v", err) + util.Logger.ErrorF("Failed to update agent: %v", err) return nil, err } @@ -131,12 +128,11 @@ func (s *Grpc) UpdateAgent(ctx context.Context, req *AgentRequest) (*AuthRespons Key: agent.AgentKey, } - h.Info("Agent %s with id %d updated correctly", agent.Hostname, agent.ID) + util.Logger.Info("Agent %s with id %d updated correctly", agent.Hostname, agent.ID) return res, nil } func (s *Grpc) DeleteAgent(ctx context.Context, req *AgentDelete) (*AuthResponse, error) { - h := util.GetLogger() md, ok := metadata.FromIncomingContext(ctx) if !ok { return &AuthResponse{}, status.Error(codes.Internal, "unable to get metadata from context") @@ -150,7 +146,7 @@ func (s *Grpc) DeleteAgent(ctx context.Context, req *AgentDelete) (*AuthResponse id, err := agentService.Delete(uuid.MustParse(key), req.DeletedBy) if err != nil { - h.ErrorF("Unable to delete agent: %v", err) + util.Logger.ErrorF("Unable to delete agent: %v", err) return &AuthResponse{}, status.Error(codes.Internal, fmt.Sprintf("unable to delete agent: %v", err.Error())) } @@ -162,7 +158,7 @@ func (s *Grpc) DeleteAgent(ctx context.Context, req *AgentDelete) (*AuthResponse delete(s.AgentStreamMap, key) s.agentStreamMutex.Unlock() - h.Info("Agent with key %s deleted by %s", key, req.DeletedBy) + util.Logger.Info("Agent with key %s deleted by %s", key, req.DeletedBy) return &AuthResponse{ Id: uint32(id), @@ -171,21 +167,19 @@ func (s *Grpc) DeleteAgent(ctx context.Context, req *AgentDelete) (*AuthResponse } func (s *Grpc) ListAgents(ctx context.Context, req *ListRequest) (*ListAgentsResponse, error) { - h := util.GetLogger() page := util.NewPaginator(int(req.PageSize), int(req.PageNumber), req.SortBy) filter := util.NewFilter(req.SearchQuery) agents, total, err := agentService.ListAgents(page, filter) if err != nil { - h.ErrorF("failed to fetch agents: %v", err) + util.Logger.ErrorF("failed to fetch agents: %v", err) return nil, status.Errorf(codes.Internal, "failed to fetch agents: %v", err) } return convertToAgentResponse(agents, total) } func (s *Grpc) AgentStream(stream AgentService_AgentStreamServer) error { - h := util.GetLogger() agentKey, err := s.authenticateConnector(stream, ConnectorType_AGENT) if err != nil { return err @@ -208,7 +202,7 @@ func (s *Grpc) AgentStream(stream AgentService_AgentStreamServer) error { delete(s.AgentStreamMap, agentKey) s.agentStreamMutex.Unlock() - h.ErrorF("failed to reconnect to client: %v", err) + util.Logger.ErrorF("failed to reconnect to client: %v", err) return fmt.Errorf("failed to reconnect to client: %v", err) } @@ -232,10 +226,10 @@ func (s *Grpc) AgentStream(stream AgentService_AgentStreamServer) error { switch msg := in.StreamMessage.(type) { case *BidirectionalStream_Command: - h.Info("Received command: %s", msg.Command.CmdId) + util.Logger.Info("Received command: %s", msg.Command.CmdId) case *BidirectionalStream_Result: - h.Info("Received command result: %s", msg.Result.CmdId) + util.Logger.Info("Received command result: %s", msg.Result.CmdId) cmdID := msg.Result.GetCmdId() @@ -250,7 +244,7 @@ func (s *Grpc) AgentStream(stream AgentService_AgentStreamServer) error { }, }, }); err != nil { - h.ErrorF("Failed to send result to server: %v", err) + util.Logger.ErrorF("Failed to send result to server: %v", err) } s.resultChannelM.Lock() if resultChan, ok := s.ResultChannel[cmdID]; ok { @@ -262,7 +256,7 @@ func (s *Grpc) AgentStream(stream AgentService_AgentStreamServer) error { } } else { - h.ErrorF("Failed to find result channel for CmdID: %s", cmdID) + util.Logger.ErrorF("Failed to find result channel for CmdID: %s", cmdID) } s.resultChannelM.Unlock() } @@ -351,53 +345,49 @@ func (s *Grpc) ProcessCommand(stream PanelService_ProcessCommandServer) error { } func (s *Grpc) UpdateAgentGroup(ctx context.Context, req *AgentGroupUpdate) (*Agent, error) { - h := util.GetLogger() if req.AgentId == 0 || req.AgentGroup == 0 { - h.ErrorF("Error in req") + util.Logger.ErrorF("Error in req") return nil, status.Errorf(codes.FailedPrecondition, "error in req") } agent, err := agentService.UpdateAgentGroup(uint(req.AgentId), uint(req.AgentGroup)) if err != nil { - h.ErrorF("Unable to update group: %v", err) + util.Logger.ErrorF("Unable to update group: %v", err) return nil, status.Errorf(codes.Internal, "unable to update group: %v", err) } return parseAgentToProto(agent), nil } func (s *Grpc) GetAgentByHostname(ctx context.Context, req *Hostname) (*Agent, error) { - h := util.GetLogger() if req.Hostname == "" { - h.ErrorF("Error in req") + util.Logger.ErrorF("Error in req") return nil, status.Errorf(codes.FailedPrecondition, "error in req") } agent, err := agentService.FindByHostname(req.Hostname) if err != nil { - h.ErrorF("Unable to find agent with hostname: %v", err) + util.Logger.ErrorF("Unable to find agent with hostname: %v", err) return nil, status.Errorf(codes.NotFound, "unable to find agent with hostname: %v", err) } return parseAgentToProto(*agent), nil } func (s *Grpc) UpdateAgentType(ctx context.Context, req *AgentTypeUpdate) (*Agent, error) { - h := util.GetLogger() if req.AgentId == 0 || req.AgentType == 0 { return nil, status.Errorf(codes.FailedPrecondition, "error in req") } agent, err := agentService.UpdateAgentType(uint(req.AgentId), uint(req.AgentType)) if err != nil { - h.ErrorF("Unable to update type: %v", err) + util.Logger.ErrorF("Unable to update type: %v", err) return nil, status.Errorf(codes.Internal, "unable to update type: %v", err) } return parseAgentToProto(agent), nil } func (s *Grpc) LoadAgentCacheFromDatabase() error { - h := util.GetLogger() // Replace with your database loading logic // Fill the agentCache map with agentID and agentToken pairs agents, err := agentService.FindAll() if err != nil { - h.ErrorF("Failed to fetch agents from database: %v", err) + util.Logger.ErrorF("Failed to fetch agents from database: %v", err) return err } for _, agent := range agents { @@ -407,14 +397,13 @@ func (s *Grpc) LoadAgentCacheFromDatabase() error { } func (s *Grpc) ListAgentsWithCommands(ctx context.Context, req *ListRequest) (*ListAgentsResponse, error) { - h := util.GetLogger() page := util.NewPaginator(int(req.PageSize), int(req.PageNumber), req.SortBy) filter := util.NewFilter(req.SearchQuery) agents, total, err := agentService.ListAgentWithCommands(page, filter) if err != nil { - h.ErrorF("failed to fetch agents: %v", err) + util.Logger.ErrorF("failed to fetch agents: %v", err) return nil, status.Errorf(codes.Internal, "failed to fetch agents: %v", err) } @@ -457,7 +446,6 @@ func waitForStream(ctx context.Context, stream grpc.ServerStream) error { */ func createHistoryCommand(cmd *UtmCommand, cmdID string) { - h := util.GetLogger() cmdHistory := &models.AgentCommand{ AgentID: findAgentIdByKey(CacheAgent, cmd.AgentKey), Command: cmd.Command, @@ -471,15 +459,14 @@ func createHistoryCommand(cmd *UtmCommand, cmdID string) { } err := agentCommandService.Create(cmdHistory) if err != nil { - h.ErrorF("Unable to create a new command history") + util.Logger.ErrorF("Unable to create a new command history") } } func updateHistoryCommand(cmdResult *CommandResult, cmdID string) { - h := util.GetLogger() err := agentCommandService.UpdateCommandStatusAndResult(findAgentIdByKey(CacheAgent, cmdResult.AgentKey), cmdID, models.Executed, cmdResult.Result) if err != nil { - h.ErrorF("Failed to update command status") + util.Logger.ErrorF("Failed to update command status") } } diff --git a/agent-manager/agent/collector_imp.go b/agent-manager/agent/collector_imp.go index 97a4c7f53..e4708daef 100644 --- a/agent-manager/agent/collector_imp.go +++ b/agent-manager/agent/collector_imp.go @@ -15,7 +15,6 @@ import ( ) func (s *Grpc) RegisterCollector(ctx context.Context, req *RegisterRequest) (*AuthResponse, error) { - h := util.GetLogger() collector := &models.Collector{ Ip: req.GetIp(), Hostname: req.GetHostname(), @@ -31,7 +30,7 @@ func (s *Grpc) RegisterCollector(ctx context.Context, req *RegisterRequest) (*Au Key: oldCollector[0].CollectorKey, }, nil } else { - h.ErrorF("Collector %s(%s) with id %d already registered with different IP", oldCollector[0].Hostname, oldCollector[0].Module, oldCollector[0].ID) + util.Logger.ErrorF("Collector %s(%s) with id %d already registered with different IP", oldCollector[0].Hostname, oldCollector[0].Module, oldCollector[0].ID) return nil, status.Errorf(codes.AlreadyExists, "hostname has already been registered") } } @@ -40,7 +39,7 @@ func (s *Grpc) RegisterCollector(ctx context.Context, req *RegisterRequest) (*Au collector.CollectorKey = key err = collectorService.Create(collector) if err != nil { - h.ErrorF("Failed to create collector: %v", err) + util.Logger.ErrorF("Failed to create collector: %v", err) return nil, err } @@ -50,7 +49,7 @@ func (s *Grpc) RegisterCollector(ctx context.Context, req *RegisterRequest) (*Au err = lastSeenService.Set(key, time.Now()) if err != nil { - h.ErrorF("Failed to set last seen: %v", err) + util.Logger.ErrorF("Failed to set last seen: %v", err) return nil, err } res := &AuthResponse{ @@ -58,12 +57,11 @@ func (s *Grpc) RegisterCollector(ctx context.Context, req *RegisterRequest) (*Au Key: key, } - h.Info("Collector %s(%s) with id %d registered correctly", collector.Hostname, collector.Module, collector.ID) + util.Logger.Info("Collector %s(%s) with id %d registered correctly", collector.Hostname, collector.Module, collector.ID) return res, nil } func (s *Grpc) DeleteCollector(ctx context.Context, req *CollectorDelete) (*AuthResponse, error) { - h := util.GetLogger() md, ok := metadata.FromIncomingContext(ctx) if !ok { return nil, status.Error(codes.Internal, "unable to get metadata from context") @@ -77,7 +75,7 @@ func (s *Grpc) DeleteCollector(ctx context.Context, req *CollectorDelete) (*Auth id, err := collectorService.Delete(uuid.MustParse(key), req.DeletedBy) if err != nil { - h.ErrorF("unable to delete collector: %v", err) + util.Logger.ErrorF("unable to delete collector: %v", err) return nil, status.Error(codes.Internal, fmt.Sprintf("unable to delete collector: %v", err.Error())) } @@ -89,7 +87,7 @@ func (s *Grpc) DeleteCollector(ctx context.Context, req *CollectorDelete) (*Auth delete(s.CollectorStreamMap, key) s.collectorStreamMutex.Unlock() - h.Info("Collector with key %s deleted by %s", key, req.DeletedBy) + util.Logger.Info("Collector with key %s deleted by %s", key, req.DeletedBy) return &AuthResponse{ Id: uint32(id), @@ -98,22 +96,19 @@ func (s *Grpc) DeleteCollector(ctx context.Context, req *CollectorDelete) (*Auth } func (s *Grpc) ListCollector(ctx context.Context, req *ListRequest) (*ListCollectorResponse, error) { - h := util.GetLogger() page := util.NewPaginator(int(req.PageSize), int(req.PageNumber), req.SortBy) filter := util.NewFilter(req.SearchQuery) collectors, total, err := collectorService.ListCollectors(page, filter) if err != nil { - h.ErrorF("failed to fetch collectors: %v", err) + util.Logger.ErrorF("failed to fetch collectors: %v", err) return nil, status.Errorf(codes.Internal, "failed to fetch collectors: %v", err) } return convertToCollectorResponse(collectors, total) } func (s *Grpc) ProcessPendingConfigs() { - h := util.GetLogger() - go func() { ticker := time.NewTicker(5 * time.Minute) defer ticker.Stop() @@ -135,7 +130,7 @@ func (s *Grpc) ProcessPendingConfigs() { if ok { collector, err := collectorService.GetByKey(key) if err != nil { - h.ErrorF("unable to get collector config to send config to stream : %v", err) + util.Logger.ErrorF("unable to get collector config to send config to stream : %v", err) continue } @@ -145,7 +140,7 @@ func (s *Grpc) ProcessPendingConfigs() { }, }) if err != nil { - h.ErrorF("failed to send config to collector: %v", err) + util.Logger.ErrorF("failed to send config to collector: %v", err) } } } @@ -154,7 +149,6 @@ func (s *Grpc) ProcessPendingConfigs() { } func (s *Grpc) CollectorStream(stream CollectorService_CollectorStreamServer) error { - h := util.GetLogger() collectorKey, err := s.authenticateConnector(stream, ConnectorType_COLLECTOR) if err != nil { return err @@ -177,7 +171,7 @@ func (s *Grpc) CollectorStream(stream CollectorService_CollectorStreamServer) er delete(s.CollectorStreamMap, collectorKey) s.collectorStreamMutex.Unlock() - h.ErrorF("failed to reconnect to client: %v", err) + util.Logger.ErrorF("failed to reconnect to client: %v", err) return fmt.Errorf("failed to reconnect to client: %v", err) } @@ -201,7 +195,7 @@ func (s *Grpc) CollectorStream(stream CollectorService_CollectorStreamServer) er switch msg := in.StreamMessage.(type) { case *CollectorMessages_Result: - h.Info("Received Knowlodge: %s", msg.Result.RequestId) + util.Logger.Info("Received Knowlodge: %s", msg.Result.RequestId) s.pendingConfigM.Lock() if s.PendingConfigs[collectorKey] == msg.Result.RequestId { @@ -216,7 +210,6 @@ func (s *Grpc) CollectorStream(stream CollectorService_CollectorStreamServer) er } func (s *Grpc) GetCollectorConfig(ctx context.Context, in *ConfigRequest) (*CollectorConfig, error) { - h := util.GetLogger() md, ok := metadata.FromIncomingContext(ctx) if !ok { return nil, status.Error(codes.Internal, "unable to get metadata from context") @@ -230,7 +223,7 @@ func (s *Grpc) GetCollectorConfig(ctx context.Context, in *ConfigRequest) (*Coll collector, err := collectorService.GetByKey(key) if err != nil { - h.ErrorF("unable to get collector config: %v", err) + util.Logger.ErrorF("unable to get collector config: %v", err) return nil, status.Error(codes.Internal, fmt.Sprintf("unable to get collector config: %v", err.Error())) } @@ -238,7 +231,6 @@ func (s *Grpc) GetCollectorConfig(ctx context.Context, in *ConfigRequest) (*Coll } func (s *Grpc) RegisterCollectorConfig(ctx context.Context, in *CollectorConfig) (*ConfigKnowledge, error) { - h := util.GetLogger() collectorConfig := &CollectorConfig{ CollectorKey: in.GetCollectorKey(), Groups: in.GetGroups(), @@ -259,7 +251,7 @@ func (s *Grpc) RegisterCollectorConfig(ctx context.Context, in *CollectorConfig) err = collectorService.SaveCollectorConfigs(collectorConf, collector.ID) if err != nil { - h.ErrorF("error saving collector configuration: %v", err) + util.Logger.ErrorF("error saving collector configuration: %v", err) return nil, status.Errorf(codes.Internal, "error saving collector configuration: %v", err.Error()) } @@ -274,13 +266,12 @@ func (s *Grpc) RegisterCollectorConfig(ctx context.Context, in *CollectorConfig) } func (s *Grpc) ListCollectorHostnames(ctx context.Context, req *ListRequest) (*CollectorHostnames, error) { - h := util.GetLogger() page := util.NewPaginator(int(req.PageSize), int(req.PageNumber), req.SortBy) filter := util.NewFilter(req.SearchQuery) hostnames, _, err := collectorService.GetHostnames(page, filter) if err != nil { - h.ErrorF("failed to fetch hostnames: %v", err) + util.Logger.ErrorF("failed to fetch hostnames: %v", err) return nil, status.Errorf(codes.NotFound, "failed to fetch hostnames: %v", err) } @@ -290,10 +281,9 @@ func (s *Grpc) ListCollectorHostnames(ctx context.Context, req *ListRequest) (*C } func (s *Grpc) GetCollectorsByHostnameAndModule(ctx context.Context, filter *FilterByHostAndModule) (*ListCollectorResponse, error) { - h := util.GetLogger() collectors, err := collectorService.GetCollectorByHostnameAndModule(filter.GetHostname(), filter.GetModule().String()) if err != nil { - h.ErrorF("unable to get hostname: %v", err) + util.Logger.ErrorF("unable to get hostname: %v", err) return nil, status.Errorf(codes.NotFound, "unable to get hostname: %v", err) } @@ -301,10 +291,9 @@ func (s *Grpc) GetCollectorsByHostnameAndModule(ctx context.Context, filter *Fil } func (s *Grpc) LoadCollectorsCacheFromDatabase() error { - h := util.GetLogger() collectors, err := collectorService.FindAll() if err != nil { - h.ErrorF("Failed to fetch collectors from database: %v", err) + util.Logger.ErrorF("Failed to fetch collectors from database: %v", err) return err } for _, colect := range collectors { diff --git a/agent-manager/agent/ping_imp.go b/agent-manager/agent/ping_imp.go index a7fc40dde..73a67a73c 100644 --- a/agent-manager/agent/ping_imp.go +++ b/agent-manager/agent/ping_imp.go @@ -10,8 +10,6 @@ import ( ) func (s *Grpc) Ping(stream PingService_PingServer) error { - h := util.GetLogger() - authResponse, err := s.GetStreamAuth(stream) if err != nil { return err @@ -31,7 +29,7 @@ func (s *Grpc) Ping(stream PingService_PingServer) error { } err = lastSeenService.Set(key, time.Now()) if err != nil { - h.ErrorF("unable to update last seen for: %s with error:%s", key, err) + util.Logger.ErrorF("unable to update last seen for: %s with error:%s", key, err) } } } diff --git a/agent-manager/auth/interceptor.go b/agent-manager/auth/interceptor.go index 18e9fc894..1b9b7e883 100644 --- a/agent-manager/auth/interceptor.go +++ b/agent-manager/auth/interceptor.go @@ -96,10 +96,9 @@ func StreamInterceptor(srv interface{}, ss grpc.ServerStream, info *grpc.StreamS } func checkKeyAuth(token string, id uint64, fullMethod string) error { - h := util.GetLogger() authCache := getAuthCache(fullMethod) if authCache == nil { - h.ErrorF("unable to resolve auth cache") + util.Logger.ErrorF("unable to resolve auth cache") return status.Error(codes.Unauthenticated, "unable to resolve auth cache") } @@ -146,23 +145,22 @@ func convertMapToAuthResponses(m map[uint]string) []AuthResponse { } func authenticateRequest(md metadata.MD, authName string) error { - h := util.GetLogger() authHeader := md.Get(authName) if len(authHeader) == 0 { - h.ErrorF("%s must be provided", authName) + util.Logger.ErrorF("%s must be provided", authName) return status.Error(codes.Unauthenticated, fmt.Sprintf("%s must be provided", authName)) } if authName == "connection-key" && authHeader[0] != "" { if !validateToken(authHeader[0]) { - h.ErrorF("unable to connect with the panel to check the connection-key") + util.Logger.ErrorF("unable to connect with the panel to check the connection-key") return status.Error(codes.Unauthenticated, "unable to connect with the panel to check the connection-key") } } else if authName == "internal-key" && authHeader[0] != "" { internalKey := os.Getenv(config.UTMSharedKeyEnv) if authHeader[0] != internalKey { - h.ErrorF("internal key does not match") + util.Logger.ErrorF("internal key does not match") return status.Error(codes.Unauthenticated, "internal key does not match") } } else { diff --git a/agent-manager/main.go b/agent-manager/main.go index abb1281d4..85db62037 100644 --- a/agent-manager/main.go +++ b/agent-manager/main.go @@ -22,26 +22,28 @@ import ( ) func main() { - h := util.GetLogger() + util.Logger.Info("Starting UTMStack Agent Manager") defer func() { if r := recover(); r != nil { // Handle the panic here - h.ErrorF("Panic occurred: %v", r) + util.Logger.ErrorF("Panic occurred: %v", r) } }() + util.Logger.Info("Initializing database...") config.InitDb() - migration.MigrateDatabase(h) + migration.MigrateDatabase() + util.Logger.Info("[OK] Database initialized") s, err := pb.InitGrpc() if err != nil { - h.Fatal("Failed to inititialize gRPC: %v", err) + util.Logger.Fatal("Failed to inititialize gRPC: %v", err) } cert, err := tls.LoadX509KeyPair("/cert/utm.crt", "/cert/utm.key") if err != nil { - h.Fatal("failed to load server certificates: %v", err) + util.Logger.Fatal("failed to load server certificates: %v", err) } tlsConfig := &tls.Config{ @@ -77,15 +79,14 @@ func main() { s.InitPingSync() updates.InitUpdatesManager() - // Start the gRPC server lis, err := net.Listen("tcp", "0.0.0.0:50051") if err != nil { - h.Fatal("Failed to listen: %v", err) + util.Logger.Fatal("Failed to listen: %v", err) } - h.Info("Starting gRPC server on 0.0.0.0:50051") + util.Logger.Info("Starting gRPC server on 0.0.0.0:50051") if err := grpcServer.Serve(lis); err != nil { - h.Fatal("Failed to serve: %v", err) + util.Logger.Fatal("Failed to serve: %v", err) } } @@ -97,13 +98,10 @@ func recoverInterceptor( ) (resp interface{}, err error) { defer func() { if r := recover(); r != nil { - // Handle the panic here - h := util.GetLogger() - h.ErrorF("Panic occurred: %v", r) + util.Logger.ErrorF("Panic occurred: %v", r) err = status.Errorf(codes.Internal, "Internal server error") } }() - // Call the gRPC handler return handler(ctx, req) } diff --git a/agent-manager/migration/migrations.go b/agent-manager/migration/migrations.go index ff85aa22b..a38780732 100644 --- a/agent-manager/migration/migrations.go +++ b/agent-manager/migration/migrations.go @@ -4,7 +4,6 @@ import ( "fmt" "time" - "github.com/threatwinds/logger" "github.com/utmstack/UTMStack/agent-manager/config" "github.com/utmstack/UTMStack/agent-manager/models" "github.com/utmstack/UTMStack/agent-manager/util" @@ -18,11 +17,11 @@ type Changeset struct { RanAt time.Time // When the migration was applied } -func MigrateDatabase(h *logger.Logger) { +func MigrateDatabase() { db := config.GetDB() err := db.AutoMigrate(&Changeset{}) if err != nil { - h.ErrorF("failed to auto-migrate MigrationRecord table: %v", err) + util.Logger.ErrorF("failed to auto-migrate MigrationRecord table: %v", err) return } performMigration(db, "performInitialMigrations_15022024_001", "jdieguez89", performInitialMigrations) @@ -42,31 +41,27 @@ func MigrateDatabase(h *logger.Logger) { // - executedBy string: Identifier for who or what executed the migration. // - migrationFunc func(*gorm.DB) error: The function to execute for the migration. func performMigration(db *gorm.DB, migrationName string, executedBy string, migrationFunc func(*gorm.DB) error) { - h := util.GetLogger() var migrationRecord Changeset result := db.Where("name = ?", migrationName).First(&migrationRecord) // If migration hasn't been recorded, perform it if result.RowsAffected == 0 { err := migrationFunc(db) if err != nil { - h.ErrorF("Migration failed (%s): %v\n", migrationName, err) + util.Logger.ErrorF("Migration failed (%s): %v\n", migrationName, err) return } // Record successful migration db.Create(&Changeset{Name: migrationName, RanAt: time.Now(), ExecutedBy: executedBy}) - h.Info("Migration executed and recorded: %s\n", migrationName) - } else { - h.Info("Migration already executed: %s\n", migrationName) + util.Logger.Info("Migration executed and recorded: %s\n", migrationName) } } // executeSQLCommands execute sql statements func executeSQLCommands(db *gorm.DB, sqlCommands []string) error { - h := util.GetLogger() for _, sql := range sqlCommands { if err := db.Exec(sql).Error; err != nil { - h.ErrorF("Failed to execute SQL command: %v\n", err) + util.Logger.ErrorF("Failed to execute SQL command: %v\n", err) return err } } @@ -77,16 +72,15 @@ func executeSQLCommands(db *gorm.DB, sqlCommands []string) error { // tableName is the name of the table from which the column will be deleted. // columnName is the name of the column to be deleted. func deleteColumnFromTable(db *gorm.DB, table interface{}, columnName string) error { - h := util.GetLogger() // Check if the column exists before trying to delete it if db.Migrator().HasColumn(table, columnName) { err := db.Migrator().DropColumn(table, columnName) if err != nil { - h.ErrorF("Failed to delete column '%s' from table '%s': %v", columnName, table, err) + util.Logger.ErrorF("Failed to delete column '%s' from table '%s': %v", columnName, table, err) return err } } else { - h.ErrorF("Column '%s' does not exist in table '%s'.", columnName, table) + util.Logger.ErrorF("Column '%s' does not exist in table '%s'.", columnName, table) return nil } return nil @@ -119,17 +113,16 @@ func performInitialMigrations(db *gorm.DB) error { // renameLastSeenTableAndColumn renaming `agent_last_seens` table to `last_seen` // and the `agent_key` column to `key`. This table will be used by agents and collectors func renameLastSeenTableAndColumnOrCreateTable(db *gorm.DB) error { - h := util.GetLogger() // Rename the table from `agent_last_seens` to `last_seen` newName := "last_seens" oldName := "agent_last_seens" if db.Migrator().HasTable(oldName) { if err := db.Migrator().RenameTable("agent_last_seens", newName); err != nil { - h.ErrorF("Failed to rename table: %v\n", err) + util.Logger.ErrorF("Failed to rename table: %v\n", err) return err } if err := db.Migrator().RenameColumn(&models.LastSeen{}, "agent_key", "key"); err != nil { - h.ErrorF("Failed to rename column: %v\n", err) + util.Logger.ErrorF("Failed to rename column: %v\n", err) return err } sqlCommands := []string{ @@ -139,7 +132,7 @@ func renameLastSeenTableAndColumnOrCreateTable(db *gorm.DB) error { } err := executeSQLCommands(db, sqlCommands) if err == nil { - h.Info("Renamed table and column successfully.") + util.Logger.Info("Renamed table and column successfully.") } return err diff --git a/agent-manager/service/last_seen_service.go b/agent-manager/service/last_seen_service.go index b9d0e32f0..c78f6a830 100644 --- a/agent-manager/service/last_seen_service.go +++ b/agent-manager/service/last_seen_service.go @@ -29,11 +29,9 @@ func NewLastSeenService() *LastSeenService { } func (s *LastSeenService) Start() { - h := util.GetLogger() - // Populate cache from the database pings, err := s.repo.GetAll() if err != nil { - h.ErrorF("Failed to populate LastSeen cache: %v", err) + util.Logger.ErrorF("Failed to populate LastSeen cache: %v", err) } else { s.Populate(pings) } @@ -67,14 +65,13 @@ func (s *LastSeenService) flushCacheToDB() error { } func (s *LastSeenService) flushCachePeriodically() { - h := util.GetLogger() for { select { case <-s.ticker.C: // Flush the cache to the database err := s.flushCacheToDB() if err != nil { - h.ErrorF("Failed to flush LastSeen cache to database: %v", err) + util.Logger.ErrorF("Failed to flush LastSeen cache to database: %v", err) } case <-s.stopCh: return diff --git a/agent-manager/updates/updates.go b/agent-manager/updates/updates.go index 9d8369fc4..4431ddb9c 100644 --- a/agent-manager/updates/updates.go +++ b/agent-manager/updates/updates.go @@ -30,9 +30,9 @@ func ServeDependencies() { group := r.Group("/private", auth.HTTPAuthInterceptor()) group.StaticFS("/dependencies", http.Dir("/dependencies")) - util.GetLogger().Info("Starting HTTP server on port 8080") + util.Logger.Info("Starting HTTP server on port 8080") if err := r.RunTLS(":8080", "/cert/utm.crt", "/cert/utm.key"); err != nil { - util.GetLogger().ErrorF("error starting HTTP server: %v", err) + util.Logger.ErrorF("error starting HTTP server: %v", err) return } } diff --git a/agent-manager/util/logger.go b/agent-manager/util/logger.go index c2054ecab..ef198d18f 100644 --- a/agent-manager/util/logger.go +++ b/agent-manager/util/logger.go @@ -1,21 +1,31 @@ package util import ( - "sync" + "log" + "os" + "strconv" "github.com/threatwinds/logger" ) -var ( - aLogger *logger.Logger - loggerOnceInstance sync.Once -) +var Logger *logger.Logger + +func init() { + lenv := os.Getenv("LOG_LEVEL") + var level int + var err error + + if lenv != "" && lenv != " " { + level, err = strconv.Atoi(lenv) + if err != nil { + log.Fatalln(err) + } + } else { + level = 200 + } -func GetLogger() *logger.Logger { - loggerOnceInstance.Do(func() { - aLogger = logger.NewLogger( - &logger.Config{Format: "text", Level: 200, Output: "stdout"}, - ) + Logger = logger.NewLogger(&logger.Config{ + Format: "text", + Level: level, }) - return aLogger } diff --git a/aws/Dockerfile b/aws/Dockerfile index e6ac643e3..790dd98d6 100644 --- a/aws/Dockerfile +++ b/aws/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 +FROM debian:bookworm-slim RUN apt-get update RUN apt-get install -y ca-certificates @@ -8,4 +8,3 @@ COPY aws . RUN chmod +x aws ENTRYPOINT ./aws - diff --git a/aws/main.go b/aws/main.go index 9b0578fda..462bb5747 100644 --- a/aws/main.go +++ b/aws/main.go @@ -16,6 +16,7 @@ import ( const delayCheck = 300 func main() { + utils.Logger.Info("Starting aws module...") intKey := configuration.GetInternalKey() panelServ := configuration.GetPanelServiceName() client := utmconf.NewUTMClient(intKey, "http://"+panelServ) @@ -23,10 +24,15 @@ func main() { st := time.Now().Add(-600 * time.Second) for { + if err := utils.ConnectionChecker(configuration.URL_CHECK_CONNECTION); err != nil { + utils.Logger.ErrorF("Failed to establish connection: %v", err) + } + et := st.Add(299 * time.Second) moduleConfig, err := client.GetUTMConfig(enum.AWS_IAM_USER) if err != nil { if strings.Contains(err.Error(), "invalid character '<'") { + utils.Logger.LogF(100, "error getting configuration of the AWS module: %v", err) time.Sleep(time.Second * delayCheck) continue } diff --git a/aws/utils/check.go b/aws/utils/check.go new file mode 100644 index 000000000..f7212deb0 --- /dev/null +++ b/aws/utils/check.go @@ -0,0 +1,42 @@ +package utils + +import ( + "fmt" + "net/http" + "time" +) + +func ConnectionChecker(url string) error { + checkConn := func() error { + if err := checkPanelConnection(url); err != nil { + return fmt.Errorf("connection failed: %v", err) + } + + return nil + } + + if err := Logger.InfiniteRetryIfXError(checkConn, "connection failed"); err != nil { + return err + } + + return nil +} + +func checkPanelConnection(url string) error { + client := &http.Client{ + Timeout: 30 * time.Second, + } + + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return err + } + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} diff --git a/aws/utils/req.go b/aws/utils/req.go index 1650c396f..7d8efcd84 100644 --- a/aws/utils/req.go +++ b/aws/utils/req.go @@ -14,7 +14,7 @@ func DoReq[response any](url string, data []byte, method string, headers map[str req, err := http.NewRequest(method, url, bytes.NewBuffer(data)) if err != nil { - return result, http.StatusInternalServerError, Logger.ErrorF(err.Error()) + return result, http.StatusInternalServerError, Logger.ErrorF("%s", err.Error()) } for k, v := range headers { @@ -25,13 +25,13 @@ func DoReq[response any](url string, data []byte, method string, headers map[str resp, err := client.Do(req) if err != nil { - return result, http.StatusInternalServerError, Logger.ErrorF(err.Error()) + return result, http.StatusInternalServerError, Logger.ErrorF("%s", err.Error()) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { - return result, http.StatusInternalServerError, Logger.ErrorF(err.Error()) + return result, http.StatusInternalServerError, Logger.ErrorF("%s", err.Error()) } if resp.StatusCode != http.StatusAccepted && resp.StatusCode != http.StatusOK { @@ -40,7 +40,7 @@ func DoReq[response any](url string, data []byte, method string, headers map[str err = json.Unmarshal(body, &result) if err != nil { - return result, http.StatusInternalServerError, Logger.ErrorF(err.Error()) + return result, http.StatusInternalServerError, Logger.ErrorF("%s", err.Error()) } return result, resp.StatusCode, nil diff --git a/bitdefender/Dockerfile b/bitdefender/Dockerfile index 36a5d19b1..3c78ac32e 100644 --- a/bitdefender/Dockerfile +++ b/bitdefender/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 +FROM debian:bookworm-slim RUN apt-get update RUN apt-get install -y ca-certificates diff --git a/bitdefender/configuration/config.go b/bitdefender/configuration/config.go index b0dfbb5a9..561328117 100644 --- a/bitdefender/configuration/config.go +++ b/bitdefender/configuration/config.go @@ -10,8 +10,8 @@ import ( "sync" "time" - "github.com/threatwinds/logger" "github.com/utmstack/UTMStack/bitdefender/constants" + "github.com/utmstack/UTMStack/bitdefender/utils" "github.com/utmstack/config-client-go/enum" "github.com/utmstack/config-client-go/types" @@ -29,20 +29,24 @@ const delayCheckConfig = 30 * time.Second var configsSent = make(map[string]ModuleConfig) -func ConfigureModules(cnf *types.ConfigurationSection, mutex *sync.Mutex, h *logger.Logger) { +func ConfigureModules(cnf *types.ConfigurationSection, mutex *sync.Mutex) { intKey := constants.GetInternalKey() panelServ := constants.GetPanelServiceName() client := UTMStackConfigurationClient.NewUTMClient(intKey, "http://"+panelServ) for { time.Sleep(delayCheckConfig) + if err := utils.ConnectionChecker(constants.URL_CHECK_CONNECTION); err != nil { + utils.Logger.ErrorF("Failed to establish connection: %v", err) + } + tempModuleConfig, err := client.GetUTMConfig(enum.BITDEFENDER) if err != nil { if strings.Contains(err.Error(), "invalid character '<'") { continue } if (err.Error() != "") && (err.Error() != " ") { - h.ErrorF("error getting configuration of the Bitdefender module: %v", err) + utils.Logger.ErrorF("error getting configuration of the Bitdefender module: %v", err) } continue } @@ -54,18 +58,18 @@ func ConfigureModules(cnf *types.ConfigurationSection, mutex *sync.Mutex, h *log isNecessaryConfig := compareConfigs(configsSent, group) if isNecessaryConfig { if !araAnyEmpty(group.Configurations[0].ConfValue, group.Configurations[1].ConfValue, group.Configurations[2].ConfValue, group.Configurations[3].ConfValue) { - h.Info("new configuration found: groupName: %s, master: %s, CompanyIDs: %s", group.GroupName, group.Configurations[2].ConfValue, group.Configurations[3].ConfValue) - if err := confBDGZApiPush(group, "sendConf", h); err != nil { - h.ErrorF("error sending configuration") + utils.Logger.Info("new configuration found: groupName: %s, master: %s, CompanyIDs: %s", group.GroupName, group.Configurations[2].ConfValue, group.Configurations[3].ConfValue) + if err := confBDGZApiPush(group, "sendConf"); err != nil { + utils.Logger.ErrorF("error sending configuration") continue } time.Sleep(15 * time.Second) - if err := confBDGZApiPush(group, "getConf", h); err != nil { - h.ErrorF("error getting configuration") + if err := confBDGZApiPush(group, "getConf"); err != nil { + utils.Logger.ErrorF("error getting configuration") continue } - if err := confBDGZApiPush(group, "sendTest", h); err != nil { - h.ErrorF("error sending test event") + if err := confBDGZApiPush(group, "sendTest"); err != nil { + utils.Logger.ErrorF("error sending test event") continue } @@ -81,8 +85,8 @@ func ConfigureModules(cnf *types.ConfigurationSection, mutex *sync.Mutex, h *log } } -func confBDGZApiPush(config types.ModuleGroup, operation string, h *logger.Logger) error { - operationFunc := map[string]func(types.ModuleGroup, *logger.Logger) (*http.Response, error){ +func confBDGZApiPush(config types.ModuleGroup, operation string) error { + operationFunc := map[string]func(types.ModuleGroup) (*http.Response, error){ "sendConf": sendPushEventSettings, "getConf": getPushEventSettings, "sendTest": sendTestPushEvent, @@ -94,22 +98,22 @@ func confBDGZApiPush(config types.ModuleGroup, operation string, h *logger.Logge } for i := 0; i < 5; i++ { - response, err := fn(config, h) + response, err := fn(config) if err != nil { - h.ErrorF("%v", err) + utils.Logger.ErrorF("%v", err) time.Sleep(1 * time.Minute) continue } defer response.Body.Close() - h.Info("Status: %s", response.Status) + utils.Logger.Info("Status: %s", response.Status) myBody, _ := io.ReadAll(response.Body) - h.Info(string(myBody)) + utils.Logger.Info("%s", string(myBody)) if operation == "sendConf" { regex := regexp.MustCompile(`result":true`) match := regex.Match([]byte(string(myBody))) if match { - h.Info("Configuration sent correctly") + utils.Logger.Info("Configuration sent correctly") } } return nil @@ -117,34 +121,34 @@ func confBDGZApiPush(config types.ModuleGroup, operation string, h *logger.Logge return fmt.Errorf("error sending configuration") } -func sendPushEventSettings(config types.ModuleGroup, h *logger.Logger) (*http.Response, error) { - h.Info("Sending configuration...") +func sendPushEventSettings(config types.ModuleGroup) (*http.Response, error) { + utils.Logger.Info("Sending configuration...") byteTemplate := getTemplateSetPush(config) body, err := json.Marshal(byteTemplate) if err != nil { - h.ErrorF("error when marshaling the request body to send the configuration: %v", err) + utils.Logger.ErrorF("error when marshaling the request body to send the configuration: %v", err) return nil, err } return sendRequest(body, config) } -func getPushEventSettings(config types.ModuleGroup, h *logger.Logger) (*http.Response, error) { - h.Info("Checking configuration...") +func getPushEventSettings(config types.ModuleGroup) (*http.Response, error) { + utils.Logger.Info("Checking configuration...") byteTemplate := getTemplateGet() body, err := json.Marshal(byteTemplate) if err != nil { - h.ErrorF("error when marshaling the request body to send the configuration: %v", err) + utils.Logger.ErrorF("error when marshaling the request body to send the configuration: %v", err) return nil, err } return sendRequest(body, config) } -func sendTestPushEvent(config types.ModuleGroup, h *logger.Logger) (*http.Response, error) { - h.Info("Sending Event Test...") +func sendTestPushEvent(config types.ModuleGroup) (*http.Response, error) { + utils.Logger.Info("Sending Event Test...") byteTemplate := getTemplateTest() body, err := json.Marshal(byteTemplate) if err != nil { - h.ErrorF("error when marshaling the request body to send the configuration: %v", err) + utils.Logger.ErrorF("error when marshaling the request body to send the configuration: %v", err) return nil, err } return sendRequest(body, config) diff --git a/bitdefender/main.go b/bitdefender/main.go index 89632b2cd..79168f13b 100644 --- a/bitdefender/main.go +++ b/bitdefender/main.go @@ -19,26 +19,24 @@ var ( ) func main() { - h := utils.GetLogger() path, err := utils.GetMyPath() if err != nil { - h.Fatal("failed to get current path: %v", err) + utils.Logger.Fatal("failed to get current path: %v", err) } - // Generate Certificates certsPath := filepath.Join(path, "certs") err = utils.CreatePathIfNotExist(certsPath) if err != nil { - h.Fatal("error creating path: %s", err) + utils.Logger.Fatal("error creating path: %s", err) } err = utils.GenerateCerts(certsPath) if err != nil { - h.Fatal("error generating certificates: %v", err) + utils.Logger.Fatal("error generating certificates: %v", err) } - server.ServerUp(&moduleConfig, certsPath, h) - go configuration.ConfigureModules(&moduleConfig, mutex, h) + server.ServerUp(&moduleConfig, certsPath) + go configuration.ConfigureModules(&moduleConfig, mutex) sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, syscall.SIGINT) diff --git a/bitdefender/server/server.go b/bitdefender/server/server.go index d11f8ef36..81ee9a4bc 100644 --- a/bitdefender/server/server.go +++ b/bitdefender/server/server.go @@ -7,7 +7,6 @@ import ( "time" "github.com/gorilla/mux" - "github.com/threatwinds/logger" "github.com/utmstack/UTMStack/bitdefender/constants" "github.com/utmstack/UTMStack/bitdefender/schema" "github.com/utmstack/UTMStack/bitdefender/utils" @@ -17,15 +16,15 @@ import ( var syslogHelper EpsSyslogHelper // GetBDGZLogs gets the Bitdefender Api Push logs and sends them to the syslog server -func GetBDGZLogs(config *types.ConfigurationSection, h *logger.Logger) http.HandlerFunc { +func GetBDGZLogs(config *types.ConfigurationSection) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - h.Info("New group of events received") + utils.Logger.Info("New group of events received") // Check if the Bitdefender Module is active if config.ModuleActive { //Check if the authorization exist if r.Header.Get("authorization") == "" { messag := "401 Missing Authorization Header" - h.ErrorF(messag) + utils.Logger.ErrorF("%s", messag) j, _ := json.Marshal(messag) w.WriteHeader(http.StatusUnauthorized) w.Write(j) @@ -41,7 +40,7 @@ func GetBDGZLogs(config *types.ConfigurationSection, h *logger.Logger) http.Hand } if !isAuth { messag := "401 Invalid Authentication Credentials" - h.ErrorF(messag) + utils.Logger.ErrorF("%s", messag) j, _ := json.Marshal(messag) w.WriteHeader(http.StatusUnauthorized) w.Write(j) @@ -52,30 +51,30 @@ func GetBDGZLogs(config *types.ConfigurationSection, h *logger.Logger) http.Hand var newBody schema.BodyEvents err := json.NewDecoder(r.Body).Decode(&newBody) if err != nil { - h.ErrorF("error to decode body: %v", err) + utils.Logger.ErrorF("error to decode body: %v", err) return } // Process the events and send them to the syslog server events := newBody.Events - syslogHelper.SentToSyslog(config, events, h) + syslogHelper.SentToSyslog(config, events) // Return a successful HTTP response j, _ := json.Marshal("HTTP 200 OK") w.WriteHeader(http.StatusOK) w.Write(j) } else { - h.ErrorF("Bitdefender module disabled") + utils.Logger.ErrorF("Bitdefender module disabled") } } } // ServerUp raises the connector that will receive the data and process it so that it is sent to the syslog server -func ServerUp(cnf *types.ConfigurationSection, certsPath string, h *logger.Logger) { +func ServerUp(cnf *types.ConfigurationSection, certsPath string) { syslogHelper.Init() r := mux.NewRouter().StrictSlash(false) - r.HandleFunc("/api", (GetBDGZLogs(cnf, h))).Methods("POST") + r.HandleFunc("/api", (GetBDGZLogs(cnf))).Methods("POST") r.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte("Server is up and running")) @@ -90,10 +89,10 @@ func ServerUp(cnf *types.ConfigurationSection, certsPath string, h *logger.Logge } go func() { - h.Info("Listening in port %s...\n", constants.GetConnectorPort()) + utils.Logger.Info("Listening in port %s...\n", constants.GetConnectorPort()) err := server.ListenAndServeTLS(filepath.Join(certsPath, "server.crt"), filepath.Join(certsPath, "server.key")) if err != nil { - h.ErrorF("%v", err) + utils.Logger.ErrorF("%v", err) } //Close connection with syslogServer syslogHelper.clientSyslog.Close() diff --git a/bitdefender/server/syslog.go b/bitdefender/server/syslog.go index 1b70e38e3..32c09c9da 100644 --- a/bitdefender/server/syslog.go +++ b/bitdefender/server/syslog.go @@ -6,8 +6,8 @@ import ( "time" syslog "github.com/RackSec/srslog" - "github.com/threatwinds/logger" "github.com/utmstack/UTMStack/bitdefender/constants" + "github.com/utmstack/UTMStack/bitdefender/utils" "github.com/utmstack/config-client-go/types" ) @@ -30,7 +30,7 @@ func (g *EpsSyslogHelper) Init() { } // SentToSyslog send event by event to syslog server -func (g *EpsSyslogHelper) SentToSyslog(config *types.ConfigurationSection, events []string, h *logger.Logger) { +func (g *EpsSyslogHelper) SentToSyslog(config *types.ConfigurationSection, events []string) { for _, syslogMessage := range events { for _, cnf := range config.ConfigurationGroups { companiesIDs := strings.Split(cnf.Configurations[3].ConfValue, ",") @@ -38,16 +38,16 @@ func (g *EpsSyslogHelper) SentToSyslog(config *types.ConfigurationSection, event pattern := "BitdefenderGZCompanyId=" + compID match, err := regexp.MatchString(pattern, syslogMessage) if err != nil { - h.ErrorF("error matching pattern: %v", err) + utils.Logger.ErrorF("error matching pattern: %v", err) continue } if match { syslogMessage += " UTM_TENANT=" + cnf.GroupName g.clientSyslog.Warning(syslogMessage) - h.Info("message recived: %s", syslogMessage) + utils.Logger.Info("message recived: %s", syslogMessage) break } else { - h.Info("Event received that is not within the configured CompanyId: %s", syslogMessage) + utils.Logger.Info("Event received that is not within the configured CompanyId: %s", syslogMessage) } } } diff --git a/bitdefender/utils/check.go b/bitdefender/utils/check.go new file mode 100644 index 000000000..2a6780db8 --- /dev/null +++ b/bitdefender/utils/check.go @@ -0,0 +1,41 @@ +package utils + +import ( + "fmt" + "net/http" + "time" +) + +func ConnectionChecker(url string) error { + checkConn := func() error { + if err := CheckConnection(url); err != nil { + return fmt.Errorf("connection failed: %v", err) + } + return nil + } + + if err := Logger.InfiniteRetryIfXError(checkConn, "connection failed"); err != nil { + return err + } + + return nil +} + +func CheckConnection(url string) error { + client := &http.Client{ + Timeout: 30 * time.Second, + } + + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return err + } + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} diff --git a/bitdefender/utils/logger.go b/bitdefender/utils/logger.go index 8f490eeec..510b36c6c 100644 --- a/bitdefender/utils/logger.go +++ b/bitdefender/utils/logger.go @@ -1,22 +1,31 @@ package utils import ( - "sync" + "log" + "os" + "strconv" "github.com/threatwinds/logger" ) -var ( - bLogger *logger.Logger - loggerOnceInstance sync.Once -) +var Logger *logger.Logger + +func init() { + lenv := os.Getenv("LOG_LEVEL") + var level int + var err error + + if lenv != "" && lenv != " " { + level, err = strconv.Atoi(lenv) + if err != nil { + log.Fatalln(err) + } + } else { + level = 400 + } -// GetLogger returns a single instance of a Logger configured to save logs to a rotating file. -func GetLogger() *logger.Logger { - loggerOnceInstance.Do(func() { - bLogger = logger.NewLogger( - &logger.Config{Format: "text", Level: 200, Output: "stdout", Retries: 3, Wait: 5}, - ) + Logger = logger.NewLogger(&logger.Config{ + Format: "text", + Level: level, }) - return bLogger } diff --git a/correlation/Dockerfile b/correlation/Dockerfile index 4e49806fb..15bfc8274 100644 --- a/correlation/Dockerfile +++ b/correlation/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 +FROM debian:bookworm-slim RUN apt-get update RUN apt-get install -y ca-certificates git wget COPY correlation /app/ diff --git a/log-auth-proxy/Dockerfile b/log-auth-proxy/Dockerfile index 69e1b9409..c07c28bec 100644 --- a/log-auth-proxy/Dockerfile +++ b/log-auth-proxy/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 +FROM debian:bookworm-slim COPY log-auth-proxy /app/ diff --git a/log-auth-proxy/handlers/http_handler.go b/log-auth-proxy/handlers/http_handler.go index ab8aa50c7..9c18de307 100644 --- a/log-auth-proxy/handlers/http_handler.go +++ b/log-auth-proxy/handlers/http_handler.go @@ -12,19 +12,18 @@ import ( ) func HttpLog(logOutputService *logservice.LogOutputService) gin.HandlerFunc { - h := utils.GetLogger() return func(c *gin.Context) { var body map[string]interface{} if err := c.ShouldBindJSON(&body); err != nil { - h.ErrorF("Error binding http JSON: %v", err) + utils.Logger.ErrorF("Error binding http JSON: %v", err) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } logType, source, err := getHeaderAndSource(c) if err != nil { - h.ErrorF("Error getting header and source: %v", err) + utils.Logger.ErrorF("Error getting header and source: %v", err) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } @@ -37,7 +36,7 @@ func HttpLog(logOutputService *logservice.LogOutputService) gin.HandlerFunc { jsonBytes, err := json.Marshal(body) if err != nil { - h.ErrorF("Error marshalling http JSON: %v", err) + utils.Logger.ErrorF("Error marshalling http JSON: %v", err) c.JSON(http.StatusInternalServerError, gin.H{"error": "unable to convert JSON to string"}) return } @@ -51,18 +50,17 @@ func HttpLog(logOutputService *logservice.LogOutputService) gin.HandlerFunc { } func HttpBulkLog(logOutputService *logservice.LogOutputService) gin.HandlerFunc { - h := utils.GetLogger() return func(c *gin.Context) { var body []interface{} if err := c.ShouldBindJSON(&body); err != nil { - h.ErrorF("Error binding bulk JSON: %v", err) + utils.Logger.ErrorF("Error binding bulk JSON: %v", err) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } logType, source, err := getHeaderAndSource(c) if err != nil { - h.ErrorF("Error getting header and source: %v", err) + utils.Logger.ErrorF("Error getting header and source: %v", err) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } @@ -81,7 +79,7 @@ func HttpBulkLog(logOutputService *logservice.LogOutputService) gin.HandlerFunc str, err := json.Marshal(v) if err != nil { - h.ErrorF("Error marshalling bulk JSON: %v", err) + utils.Logger.ErrorF("Error marshalling bulk JSON: %v", err) continue } log := string(str) @@ -98,19 +96,18 @@ func HttpPing(c *gin.Context) { } func HttpGitHubHandler(logOutputService *logservice.LogOutputService) gin.HandlerFunc { - h := utils.GetLogger() return func(c *gin.Context) { var body interface{} if err := c.ShouldBindJSON(&body); err != nil { - h.ErrorF("Error binding github JSON: %v", err) + utils.Logger.ErrorF("Error binding github JSON: %v", err) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } jsonBytes, err := json.Marshal(body) if err != nil { - h.ErrorF("Error marshalling github JSON: %v", err) + utils.Logger.ErrorF("Error marshalling github JSON: %v", err) c.JSON(http.StatusInternalServerError, gin.H{"error": "unable to convert JSON to string"}) return } diff --git a/log-auth-proxy/handlers/tcp_handler.go b/log-auth-proxy/handlers/tcp_handler.go index ad0e69469..cdf404a7f 100644 --- a/log-auth-proxy/handlers/tcp_handler.go +++ b/log-auth-proxy/handlers/tcp_handler.go @@ -12,7 +12,6 @@ import ( ) func HandleRequest(conn net.Conn, interceptor *middleware.LogAuthInterceptor, logOutputService *logservice.LogOutputService) { - h := utils.GetLogger() defer conn.Close() scanner := bufio.NewScanner(conn) @@ -21,7 +20,7 @@ func HandleRequest(conn net.Conn, interceptor *middleware.LogAuthInterceptor, lo parts := strings.Split(message, ",LOG:") if len(parts) != 2 { - h.ErrorF("INVALID FORMAT expecting AUTH:,LOG:") + utils.Logger.ErrorF("INVALID FORMAT expecting AUTH:,LOG:") conn.Write([]byte("INVALID FORMAT expecting AUTH:,LOG:\n")) continue } @@ -40,6 +39,6 @@ func HandleRequest(conn net.Conn, interceptor *middleware.LogAuthInterceptor, lo } if err := scanner.Err(); err != nil { - h.ErrorF("Error reading from connection: %s", err.Error()) + utils.Logger.ErrorF("Error reading from connection: %s", err.Error()) } } diff --git a/log-auth-proxy/logservice/auth_service.go b/log-auth-proxy/logservice/auth_service.go index a1d3eb217..d937ed94d 100644 --- a/log-auth-proxy/logservice/auth_service.go +++ b/log-auth-proxy/logservice/auth_service.go @@ -52,10 +52,9 @@ func (auth *LogAuthService) SyncAuth() { } func (auth *LogAuthService) syncKeys(typ agent.ConnectorType) { - h := utils.GetLogger() serverAddress := os.Getenv(config.UTMAgentManagerHostEnv) if serverAddress == "" { - h.Fatal("Failed to get the SERVER_ADDRESS ") + utils.Logger.Fatal("Failed to get the SERVER_ADDRESS ") } tlsConfig := &tls.Config{InsecureSkipVerify: true} @@ -64,7 +63,7 @@ func (auth *LogAuthService) syncKeys(typ agent.ConnectorType) { conn, err := grpc.NewClient(serverAddress, opts, grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(maxMessageSize))) if err != nil { - h.ErrorF("Failed to connect to gRPC server: %v", err) + utils.Logger.ErrorF("Failed to connect to gRPC server: %v", err) return } defer conn.Close() @@ -83,7 +82,7 @@ func (auth *LogAuthService) syncKeys(typ agent.ConnectorType) { SortBy: "", }) if err != nil { - h.ErrorF("Error sync collector keys: %v", err) + utils.Logger.ErrorF("Error sync collector keys: %v", err) return } @@ -105,7 +104,7 @@ func (auth *LogAuthService) syncKeys(typ agent.ConnectorType) { SortBy: "", }) if err != nil { - h.ErrorF("Error sync agent keys: %v", err) + utils.Logger.ErrorF("Error sync agent keys: %v", err) return } @@ -120,10 +119,9 @@ func (auth *LogAuthService) syncKeys(typ agent.ConnectorType) { } func (auth *LogAuthService) syncConnectionKey() { - h := utils.GetLogger() panelKey, err := panelservice.GetConnectionKey() if err != nil { - h.ErrorF("Failed to get connection key: %v", err) + utils.Logger.ErrorF("Failed to get connection key: %v", err) return } auth.Mutex.Lock() diff --git a/log-auth-proxy/logservice/output_service.go b/log-auth-proxy/logservice/output_service.go index 5544e79a5..8465048ed 100644 --- a/log-auth-proxy/logservice/output_service.go +++ b/log-auth-proxy/logservice/output_service.go @@ -41,12 +41,11 @@ func NewLogOutputService() *LogOutputService { } func (out *LogOutputService) SendLog(logType config.LogType, logData string) { - h := utils.GetLogger() out.Mutex.Lock() defer out.Mutex.Unlock() port, err := out.getConnectionPort(logType) if err != nil { - h.ErrorF("error getting connection port: %v", err) + utils.Logger.ErrorF("error getting connection port: %v", err) return } singleLog := logData + config.UTMLogSeparator @@ -54,7 +53,6 @@ func (out *LogOutputService) SendLog(logType config.LogType, logData string) { } func (out *LogOutputService) SendBulkLog(logType config.LogType, logDataArray []string) { - h := utils.GetLogger() out.Mutex.Lock() defer out.Mutex.Unlock() @@ -65,7 +63,7 @@ func (out *LogOutputService) SendBulkLog(logType config.LogType, logDataArray [] port, err := out.getConnectionPort(logType) if err != nil { - h.ErrorF("error getting connection port: %v", err) + utils.Logger.ErrorF("error getting connection port: %v", err) return } @@ -89,22 +87,21 @@ func (out *LogOutputService) getConnectionPort(logType config.LogType) (string, } func (out *LogOutputService) sendLogsToLogstash(port string, logs string) { - h := utils.GetLogger() url := fmt.Sprintf(config.LogstashPipelinesEndpoint, config.LogstashHost(), port) req, err := http.NewRequest("POST", url, bytes.NewBufferString(logs)) if err != nil { - h.ErrorF("error creating request: %v", err) + utils.Logger.ErrorF("error creating request: %v", err) } resp, err := out.Client.Do(req) if err != nil { if !strings.Contains(err.Error(), "Client.Timeout exceeded while awaiting headers") { - h.ErrorF("error sending logs with error: %v", err.Error()) + utils.Logger.ErrorF("error sending logs with error: %v", err.Error()) } return } if resp.StatusCode != http.StatusOK { - h.ErrorF("error sending logs with http code %d", resp.StatusCode) + utils.Logger.ErrorF("error sending logs with http code %d", resp.StatusCode) return } } @@ -122,13 +119,12 @@ func getServiceMap() (map[config.LogType]string, error) { } func (out *LogOutputService) SyncOutputs() { - h := utils.GetLogger() out.Ticker = time.NewTicker(60 * time.Second) go func() { for range out.Ticker.C { serviceMap, err := getServiceMap() if err != nil { - h.ErrorF("error getting service map: %v", err) + utils.Logger.ErrorF("error getting service map: %v", err) continue } out.Mutex.Lock() diff --git a/log-auth-proxy/main.go b/log-auth-proxy/main.go index 56b0cf707..e25436677 100644 --- a/log-auth-proxy/main.go +++ b/log-auth-proxy/main.go @@ -17,6 +17,7 @@ import ( ) func main() { + utils.Logger.Info("Starting Log Auth Proxy...") autService := logservice.NewLogAuthService() go autService.SyncAuth() authInterceptor := middleware.NewLogAuthInterceptor(autService) @@ -31,8 +32,6 @@ func main() { } func startHTTPServer(interceptor *middleware.LogAuthInterceptor, logOutputService *logservice.LogOutputService) { - h := utils.GetLogger() - gin.SetMode(gin.ReleaseMode) router := gin.Default() router.POST("/v1/log", interceptor.HTTPAuthInterceptor(), handlers.HttpLog(logOutputService)) @@ -42,7 +41,7 @@ func startHTTPServer(interceptor *middleware.LogAuthInterceptor, logOutputServic cert, err := tls.LoadX509KeyPair("/cert/utm.crt", "/cert/utm.key") if err != nil { - h.Fatal("failed to load server certificates: %v", err) + utils.Logger.Fatal("failed to load server certificates: %v", err) } tlsConfig := &tls.Config{ @@ -56,19 +55,17 @@ func startHTTPServer(interceptor *middleware.LogAuthInterceptor, logOutputServic TLSConfig: tlsConfig, } - h.Info("Starting HTTP server on 0.0.0.0:8080") + utils.Logger.Info("Starting HTTP server on 0.0.0.0:8080") err = server.ListenAndServeTLS("", "") if err != nil { - h.Fatal("Failed to start HTTP server: %v", err) + utils.Logger.Fatal("Failed to start HTTP server: %v", err) } } func startGRPCServer(interceptor *middleware.LogAuthInterceptor, logOutputService *logservice.LogOutputService) { - h := utils.GetLogger() - cert, err := tls.LoadX509KeyPair("/cert/utm.crt", "/cert/utm.key") if err != nil { - h.Fatal("failed to load server certificates: %v", err) + utils.Logger.Fatal("failed to load server certificates: %v", err) } tlsConfig := &tls.Config{ @@ -96,11 +93,11 @@ func startGRPCServer(interceptor *middleware.LogAuthInterceptor, logOutputServic lis, err := net.Listen("tcp", "0.0.0.0:50051") if err != nil { - h.Fatal("failed to listen grpc server: %v", err) + utils.Logger.Fatal("failed to listen grpc server: %v", err) } - h.Info("Starting gRPC server on 0.0.0.0:50051") + utils.Logger.Info("Starting gRPC server on 0.0.0.0:50051") if err := grpcServer.Serve(lis); err != nil { - h.Fatal("Failed to serve grpc: %v", err) + utils.Logger.Fatal("Failed to serve grpc: %v", err) } } diff --git a/log-auth-proxy/middleware/log_auth.go b/log-auth-proxy/middleware/log_auth.go index 926829fc7..2a0329928 100644 --- a/log-auth-proxy/middleware/log_auth.go +++ b/log-auth-proxy/middleware/log_auth.go @@ -62,11 +62,10 @@ func (interceptor *LogAuthInterceptor) GrpcRecoverInterceptor( info *grpc.UnaryServerInfo, handler grpc.UnaryHandler, ) (resp interface{}, err error) { - h := utils.GetLogger() defer func() { if r := recover(); r != nil { // Handle the panic here - h.ErrorF("Panic occurred: %v", r) + utils.Logger.ErrorF("Panic occurred: %v", r) err = status.Errorf(codes.Internal, "Internal server error") } }() @@ -91,11 +90,10 @@ func (interceptor *LogAuthInterceptor) HTTPAuthInterceptor() gin.HandlerFunc { } } func (interceptor *LogAuthInterceptor) HTTPGitHubAuthInterceptor() gin.HandlerFunc { - h := utils.GetLogger() return func(c *gin.Context) { body, err := io.ReadAll(c.Request.Body) if err != nil { - h.ErrorF("error reading request body: %v", err) + utils.Logger.ErrorF("error reading request body: %v", err) c.AbortWithStatusJSON(http.StatusInternalServerError, "error reading request body") return } diff --git a/log-auth-proxy/utils/logger.go b/log-auth-proxy/utils/logger.go index 2c95fd09b..510b36c6c 100644 --- a/log-auth-proxy/utils/logger.go +++ b/log-auth-proxy/utils/logger.go @@ -1,21 +1,31 @@ package utils import ( - "sync" + "log" + "os" + "strconv" "github.com/threatwinds/logger" ) -var ( - aLogger *logger.Logger - loggerOnceInstance sync.Once -) +var Logger *logger.Logger + +func init() { + lenv := os.Getenv("LOG_LEVEL") + var level int + var err error + + if lenv != "" && lenv != " " { + level, err = strconv.Atoi(lenv) + if err != nil { + log.Fatalln(err) + } + } else { + level = 400 + } -func GetLogger() *logger.Logger { - loggerOnceInstance.Do(func() { - aLogger = logger.NewLogger( - &logger.Config{Format: "text", Level: 200, Output: "stdout"}, - ) + Logger = logger.NewLogger(&logger.Config{ + Format: "text", + Level: level, }) - return aLogger } diff --git a/office365/Dockerfile b/office365/Dockerfile index 6723f632f..ea2014650 100644 --- a/office365/Dockerfile +++ b/office365/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 +FROM debian:bookworm-slim RUN apt-get update RUN apt-get install -y ca-certificates diff --git a/office365/main.go b/office365/main.go index 2b0d7d271..5d93ef1ad 100644 --- a/office365/main.go +++ b/office365/main.go @@ -16,6 +16,7 @@ import ( const delayCheck = 300 func main() { + utils.Logger.Info("Starting O365 module") intKey := configuration.GetInternalKey() panelServ := configuration.GetPanelServiceName() client := utmconf.NewUTMClient(intKey, "http://"+panelServ) @@ -23,6 +24,10 @@ func main() { st := time.Now().Add(-600 * time.Second) for { + if err := utils.ConnectionChecker(configuration.LoginUrl); err != nil { + utils.Logger.ErrorF("External connection failure detected: %v", err) + } + et := st.Add(299 * time.Second) startTime := st.UTC().Format("2006-01-02T15:04:05") endTime := et.UTC().Format("2006-01-02T15:04:05") diff --git a/office365/utils/check.go b/office365/utils/check.go new file mode 100644 index 000000000..5ab7c1ccd --- /dev/null +++ b/office365/utils/check.go @@ -0,0 +1,45 @@ +package utils + +import ( + "context" + "fmt" + "net/http" + "time" +) + +const connectionTimeout = 5 * time.Second + +func ConnectionChecker(url string) error { + checkConn := func() error { + ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout) + defer cancel() + + if err := checkConnection(url, ctx); err != nil { + return fmt.Errorf("connection failed") + } + return nil + } + + if err := Logger.InfiniteRetryIfXError(checkConn, "connection failed"); err != nil { + return err + } + + return nil +} + +func checkConnection(url string, ctx context.Context) error { + client := &http.Client{} + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return err + } + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} diff --git a/sophos/Dockerfile b/sophos/Dockerfile index e36d4b770..52c4eec81 100644 --- a/sophos/Dockerfile +++ b/sophos/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 +FROM debian:bookworm-slim RUN apt-get update RUN apt-get install -y ca-certificates diff --git a/sophos/main.go b/sophos/main.go index 9ecb81056..2fc387f04 100644 --- a/sophos/main.go +++ b/sophos/main.go @@ -21,6 +21,10 @@ func main() { client := utmconf.NewUTMClient(intKey, "http://"+panelServ) for { + if err := utils.ConnectionChecker(configuration.CHECKCON); err != nil { + utils.Logger.ErrorF("External connection failure detected: %v", err) + } + moduleConfig, err := client.GetUTMConfig(enum.SOPHOS) if err != nil { if strings.Contains(err.Error(), "invalid character '<'") { diff --git a/sophos/utils/check.go b/sophos/utils/check.go new file mode 100644 index 000000000..5ab7c1ccd --- /dev/null +++ b/sophos/utils/check.go @@ -0,0 +1,45 @@ +package utils + +import ( + "context" + "fmt" + "net/http" + "time" +) + +const connectionTimeout = 5 * time.Second + +func ConnectionChecker(url string) error { + checkConn := func() error { + ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout) + defer cancel() + + if err := checkConnection(url, ctx); err != nil { + return fmt.Errorf("connection failed") + } + return nil + } + + if err := Logger.InfiniteRetryIfXError(checkConn, "connection failed"); err != nil { + return err + } + + return nil +} + +func checkConnection(url string, ctx context.Context) error { + client := &http.Client{} + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return err + } + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +}