From 0e160dc20c5b69113791cdf86a4b7a2396569221 Mon Sep 17 00:00:00 2001 From: Jose Carlos Luna <Jose.Carlos.Luna@cern.ch> Date: Thu, 16 May 2024 10:21:45 +0200 Subject: [PATCH] Improved logging & alerts - Separate IPs and Ports in logs and alerts - Added timestamps in alerts - Escape URL paths in alerts --- .gitignore | 3 +++ alert/alert.go | 25 +++++++++++++++++-------- server/dns/dns.go | 30 +++++++++++++++++++++++++++--- server/http/http.go | 31 +++++++++++++++++++++++++++---- 4 files changed, 74 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index a3fff09..873cb04 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ gocanary +cert.key +cert.pem + diff --git a/alert/alert.go b/alert/alert.go index 4ba3f81..4841efb 100644 --- a/alert/alert.go +++ b/alert/alert.go @@ -26,12 +26,15 @@ type Canary struct { Tag string Level string Type string + Time string } type HTTPCanary struct { Canary - RemoteAddr string - LocalAddr string + RemoteIP string + RemotePort uint16 + LocalIP string + LocalPort uint16 UserAgent string FullUrl string Referer string @@ -39,8 +42,10 @@ type HTTPCanary struct { type DNSCanary struct { Canary - RemoteAddr string - LocalAddr string + RemoteIP string + RemotePort uint16 + LocalIP string + LocalPort uint16 Proto string } @@ -111,8 +116,10 @@ func HTTPAlert(canaryinfo HTTPCanary, alertType string) { "Level", canaryinfo.Canary.Level, "FullUrl", canaryinfo.FullUrl, "UserAgent", canaryinfo.UserAgent, - "RemoteAddr", canaryinfo.RemoteAddr, - "LocalAddr", canaryinfo.LocalAddr, + "RemoteIP", canaryinfo.RemoteIP, + "RemotePort", canaryinfo.RemotePort, + "LocalIP", canaryinfo.LocalIP, + "LocalPort", canaryinfo.LocalPort, "Referer", canaryinfo.Referer, "Type", "token-http", ) @@ -135,8 +142,10 @@ func DNSAlert(canaryinfo DNSCanary, alertType string) { "Key", canaryinfo.Canary.Key, "Tag", canaryinfo.Canary.Tag, "Level", canaryinfo.Canary.Level, - "RemoteAddr", canaryinfo.RemoteAddr, - "LocalAddr", canaryinfo.LocalAddr, + "RemoteIP", canaryinfo.RemoteIP, + "RemotePort", canaryinfo.RemotePort, + "LocalIP", canaryinfo.LocalIP, + "LocalPort", canaryinfo.LocalPort, "Type", "token-dns", ) } diff --git a/server/dns/dns.go b/server/dns/dns.go index 90b511f..56186e2 100644 --- a/server/dns/dns.go +++ b/server/dns/dns.go @@ -4,8 +4,11 @@ import ( "fmt" "log" "log/slog" + "net" "slices" + "strconv" "strings" + "time" "github.com/miekg/dns" "gitlab.cern.ch/ComputerSecurity/gocanary/alert" @@ -22,15 +25,31 @@ type DNSServerConfig struct { var serverConfig DNSServerConfig func getCanaryInfo(t tokens.CanaryRecord, w dns.ResponseWriter) alert.DNSCanary { + + rIP, rPortStr, err := net.SplitHostPort(w.RemoteAddr().String()) + if err != nil { + rIP = w.RemoteAddr().String() + } + rPort, _ := strconv.Atoi(rPortStr) + + lIP, lPortStr, err := net.SplitHostPort(w.LocalAddr().String()) + if err != nil { + lIP = w.LocalAddr().String() + } + lPort, _ := strconv.Atoi(lPortStr) + return alert.DNSCanary{ Canary: alert.Canary{ Key: t.Key, Tag: t.Tag, Level: t.Level, Type: "token-dns", + Time: time.Now().Format(time.RFC3339), }, - RemoteAddr: w.RemoteAddr().String(), - LocalAddr: w.LocalAddr().String(), + RemoteIP: rIP, + RemotePort: uint16(rPort), + LocalIP: lIP, + LocalPort: uint16(lPort), Proto: w.RemoteAddr().Network(), } } @@ -52,10 +71,15 @@ func checkAndAlert(q dns.Question, w dns.ResponseWriter, r *dns.Msg) bool { } func logRequest(q dns.Question, w dns.ResponseWriter) { + rIP, rPortStr, err := net.SplitHostPort(w.RemoteAddr().String()) + if err != nil { + rIP = w.RemoteAddr().String() + } slog.Info("dns-request", "Type", "dns-request", "Query", q.Name, - "RemoteAddr", w.RemoteAddr().String(), + "RemoteIP", rIP, + "RemotePort", rPortStr, ) } diff --git a/server/http/http.go b/server/http/http.go index 3bf1a09..0c00381 100644 --- a/server/http/http.go +++ b/server/http/http.go @@ -9,6 +9,7 @@ import ( "net/http" "path" "slices" + "strconv" "strings" "time" @@ -43,23 +44,40 @@ func getSchema(r *http.Request) string { // Returns full URL of request, including schema func getFullUrl(r *http.Request) string { - return fmt.Sprintf("%s://%s%s", getSchema(r), r.Host, r.URL.Path) + return fmt.Sprintf("%s://%s%s", getSchema(r), r.Host, r.URL.EscapedPath()) } // Builds the canary alert info func getCanaryInfo(t tokens.CanaryRecord, r *http.Request) alert.HTTPCanary { + + rIP, rPortStr, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + rIP = r.RemoteAddr + } + rPort, _ := strconv.Atoi(rPortStr) + + lAddr := r.Context().Value(http.LocalAddrContextKey).(net.Addr).String() + lIP, lPortStr, err := net.SplitHostPort(lAddr) + if err != nil { + lIP = lAddr + } + lPort, _ := strconv.Atoi(lPortStr) + return alert.HTTPCanary{ Canary: alert.Canary{ Key: t.Key, Tag: t.Tag, Level: t.Level, Type: "token-http", + Time: time.Now().Format(time.RFC3339), }, UserAgent: r.UserAgent(), FullUrl: getFullUrl(r), Referer: r.Header.Get("Referer"), - RemoteAddr: r.RemoteAddr, - LocalAddr: r.Context().Value(http.LocalAddrContextKey).(net.Addr).String(), + RemoteIP: rIP, + RemotePort: uint16(rPort), + LocalIP: lIP, + LocalPort: uint16(lPort), } } @@ -81,6 +99,10 @@ func getNormalizedHostDomain(rHost string) (string, string) { // Log all requests func logRequest(r *http.Request) { + rIP, rPortStr, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + rIP = r.RemoteAddr + } slog.Info("http-request", "Type", "http-request", "Uri", r.RequestURI, @@ -88,7 +110,8 @@ func logRequest(r *http.Request) { "Method", r.Method, "Host", r.Host, "UserAgent", r.UserAgent(), - "RemoteAddr", r.RemoteAddr, + "RemoteIP", rIP, + "RemotePort", rPortStr, "Referer", r.Header.Get("Referer"), ) } -- GitLab