aboutsummaryrefslogtreecommitdiff
path: root/cmd/anubis/internal/dnsbl/dnsbl.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/anubis/internal/dnsbl/dnsbl.go')
-rw-r--r--cmd/anubis/internal/dnsbl/dnsbl.go95
1 files changed, 95 insertions, 0 deletions
diff --git a/cmd/anubis/internal/dnsbl/dnsbl.go b/cmd/anubis/internal/dnsbl/dnsbl.go
new file mode 100644
index 0000000..60edd5c
--- /dev/null
+++ b/cmd/anubis/internal/dnsbl/dnsbl.go
@@ -0,0 +1,95 @@
+package dnsbl
+
+import (
+ "errors"
+ "fmt"
+ "net"
+ "strings"
+)
+
+//go:generate go tool golang.org/x/tools/cmd/stringer -type=DroneBLResponse
+
+type DroneBLResponse byte
+
+const (
+ AllGood DroneBLResponse = 0
+ IRCDrone DroneBLResponse = 3
+ Bottler DroneBLResponse = 5
+ UnknownSpambotOrDrone DroneBLResponse = 6
+ DDOSDrone DroneBLResponse = 7
+ SOCKSProxy DroneBLResponse = 8
+ HTTPProxy DroneBLResponse = 9
+ ProxyChain DroneBLResponse = 10
+ OpenProxy DroneBLResponse = 11
+ OpenDNSResolver DroneBLResponse = 12
+ BruteForceAttackers DroneBLResponse = 13
+ OpenWingateProxy DroneBLResponse = 14
+ CompromisedRouter DroneBLResponse = 15
+ AutoRootingWorms DroneBLResponse = 16
+ AutoDetectedBotIP DroneBLResponse = 17
+ Unknown DroneBLResponse = 255
+)
+
+func Reverse(ip net.IP) string {
+ if ip.To4() != nil {
+ return reverse4(ip)
+ }
+
+ return reverse6(ip)
+}
+
+func reverse4(ip net.IP) string {
+ splitAddress := strings.Split(ip.String(), ".")
+
+ // swap first and last octet
+ splitAddress[0], splitAddress[3] = splitAddress[3], splitAddress[0]
+ // swap middle octets
+ splitAddress[1], splitAddress[2] = splitAddress[2], splitAddress[1]
+
+ return strings.Join(splitAddress, ".")
+}
+
+func reverse6(ip net.IP) string {
+ ipBytes := []byte(ip)
+ var sb strings.Builder
+
+ for i := len(ipBytes) - 1; i >= 0; i-- {
+ // Split the byte into two nibbles
+ highNibble := ipBytes[i] >> 4
+ lowNibble := ipBytes[i] & 0x0F
+
+ // Append the nibbles in reversed order
+ sb.WriteString(fmt.Sprintf("%x.%x.", lowNibble, highNibble))
+ }
+
+ return sb.String()[:len(sb.String())-1]
+}
+
+func Lookup(ipStr string) (DroneBLResponse, error) {
+ ip := net.ParseIP(ipStr)
+ if ip == nil {
+ return Unknown, errors.New("dnsbl: input is not an IP address")
+ }
+
+ revIP := Reverse(ip) + ".dnsbl.dronebl.org"
+
+ ips, err := net.LookupIP(revIP)
+ if err != nil {
+ var dnserr *net.DNSError
+ if errors.As(err, &dnserr) {
+ if dnserr.IsNotFound {
+ return AllGood, nil
+ }
+ }
+
+ return Unknown, err
+ }
+
+ if len(ips) != 0 {
+ for _, ip := range ips {
+ return DroneBLResponse(ip.To4()[3]), nil
+ }
+ }
+
+ return UnknownSpambotOrDrone, nil
+}