From 54d55e9210982cb4f818033833ca4b1f8b17084d Mon Sep 17 00:00:00 2001
From: ale <ale@incal.net>
Date: Sat, 17 Oct 2020 21:31:10 +0100
Subject: [PATCH] Replace IP address with ASN in logged events

---
 collector.go |  4 +++-
 go.mod       |  1 +
 go.sum       |  5 +++++
 ip.go        | 37 +++++++++++++++++++++++++++++++++++++
 4 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/collector.go b/collector.go
index 8b785d0..21d06a6 100644
--- a/collector.go
+++ b/collector.go
@@ -78,7 +78,9 @@ hloop:
 	// from the HTTP request, and send them to the forwarder.
 	ip := getRemoteIP(req)
 	for _, e := range events {
-		e.Set("ip", ip)
+		if asn, ok := lookupASN(ip); ok {
+			e.Set("asn", asn)
+		}
 		c.sink.Send(e)
 		reportsByType.WithLabelValues(
 			e.GetString("type"), e.GetString("domain")).Inc()
diff --git a/go.mod b/go.mod
index bd99aa1..d20925b 100644
--- a/go.mod
+++ b/go.mod
@@ -2,6 +2,7 @@ module git.autistici.org/ai3/tools/reports-collector
 
 require (
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/oschwald/geoip2-golang v1.4.0 // indirect
 	github.com/prometheus/client_golang v1.8.0
 	gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
 )
diff --git a/go.sum b/go.sum
index 8296436..aef073a 100644
--- a/go.sum
+++ b/go.sum
@@ -187,6 +187,10 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxS
 github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
 github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
 github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/oschwald/geoip2-golang v1.4.0 h1:5RlrjCgRyIGDz/mBmPfnAF4h8k0IAcRv9PvrpOfz+Ug=
+github.com/oschwald/geoip2-golang v1.4.0/go.mod h1:8QwxJvRImBH+Zl6Aa6MaIcs5YdlZSTKtzmPGzQqi9ng=
+github.com/oschwald/maxminddb-golang v1.6.0 h1:KAJSjdHQ8Kv45nFIbtoLGrGWqHFajOIm7skTyz/+Dls=
+github.com/oschwald/maxminddb-golang v1.6.0/go.mod h1:DUJFucBg2cvqx42YmDa/+xHvb0elJtOm3o4aFQ/nb/w=
 github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
@@ -322,6 +326,7 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/ip.go b/ip.go
index 81467cf..b4bcc63 100644
--- a/ip.go
+++ b/ip.go
@@ -1,10 +1,47 @@
 package reportscollector
 
 import (
+	"fmt"
+	"log"
 	"net"
 	"net/http"
+	"os"
+	"sync"
+
+	geoip2 "github.com/oschwald/geoip2-golang"
+)
+
+var (
+	geoipDbPath = "/var/lib/GeoIP/GeoLite2-ASN.mmdb"
+	geodb       *geoip2.Reader
+	geodbInit   sync.Once
 )
 
+func initGeoIP() {
+	if s := os.Getenv("GEOIP_DB_PATH"); s != "" {
+		geoipDbPath = s
+	}
+
+	var err error
+	geodb, err = geoip2.Open(geoipDbPath)
+	if err != nil {
+		log.Printf("warning: could not open GeoIP db: %v", err)
+		return
+	}
+}
+
+func lookupASN(addr string) (string, bool) {
+	geodbInit.Do(initGeoIP)
+
+	if geodb != nil {
+		asn, err := geodb.ASN(net.ParseIP(addr))
+		if err == nil {
+			return fmt.Sprintf("AS%d", asn.AutonomousSystemNumber), true
+		}
+	}
+	return "", false
+}
+
 func getRemoteIP(req *http.Request) string {
 	if addr := req.Header.Get("X-Forwarded-For"); addr != "" {
 		return addr
-- 
GitLab