1 /** 2 * Client for DNS blacklist services. 3 * 4 * License: 5 * This Source Code Form is subject to the terms of 6 * the Mozilla Public License, v. 2.0. If a copy of 7 * the MPL was not distributed with this file, You 8 * can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * Authors: 11 * Vladimir Panteleev <ae@cy.md> 12 */ 13 14 15 module ae.net.dns.dnsbl; 16 17 import std.socket; 18 import std.string; 19 import ae.net.asockets; 20 21 /// Resolve a hostname to an IPv4 dotted quad. 22 string getIP(string hostname) 23 { 24 try 25 return (new InternetAddress(hostname, 0)).toAddrString; 26 catch (Exception o) 27 return null; 28 } 29 30 /// Look up an IP address against a specific DNS blacklist. 31 /// Returns: the numeric code (generally indicating a 32 /// blacklist-specific list reason). 33 int lookupAgainst(string ip, string db) 34 { 35 string[] sections = split(ip, "."); 36 assert(sections.length == 4); 37 string addr = sections[3] ~ "." ~ sections[2] ~ "." ~ sections[1] ~ "." ~ sections[0] ~ "." ~ db; 38 InternetHost ih = new InternetHost; 39 if (ih.getHostByName(addr)) 40 return ih.addrList[0] & 0xFF; 41 else 42 return 0; 43 } 44 45 /// Look up an IP address against DroneBL. 46 /// Returns: a string describing the reason this IP is listed, 47 /// or `null` if the IP is not listed. 48 string lookupDroneBL(string ip) 49 { 50 switch (lookupAgainst(ip, "dnsbl.dronebl.org")) 51 { 52 case 0: return null; 53 case 2: return "Sample"; 54 case 3: return "IRC Drone"; 55 case 5: return "Bottler"; 56 case 6: return "Unknown spambot or drone"; 57 case 7: return "DDOS Drone"; 58 case 8: return "SOCKS Proxy"; 59 case 9: return "HTTP Proxy"; 60 case 10: return "ProxyChain"; 61 case 13: return "Brute force attackers"; 62 case 14: return "Open Wingate Proxy"; 63 case 15: return "Compromised router / gateway"; 64 default: return "Unknown"; 65 } 66 } 67 68 /// Look up an IP address against DroneBL. 69 /// Returns: a string describing the reason this IP is listed, 70 /// or `null` if the IP is not listed. 71 string lookupEfnetRBL(string ip) 72 { 73 switch (lookupAgainst(ip, "rbl.efnetrbl.org")) 74 { 75 case 0: return null; 76 case 1: return "Open Proxy"; 77 case 2: return "spamtrap666"; 78 case 3: return "spamtrap50"; 79 case 4: return "TOR"; 80 case 5: return "Drones / Flooding"; 81 default: return "Unknown"; 82 } 83 } 84 85 /// Look up an IP address in all implemented DNS blacklists. 86 /// Returns: null, or an array with three elements: 87 /// 0. a string describing the reason this IP is listed 88 /// 1. the name of the DNS blacklist service 89 /// 2. an URL with more information about the listing. 90 string[] blacklistCheck(string hostname) 91 { 92 string ip = getIP(hostname); 93 94 if (!ip) 95 throw new Exception("Can't resolve hostname to IPv4 address: " ~ hostname); 96 97 string result; 98 99 result = lookupDroneBL(ip); 100 if (result) return [result, "DroneBL" , "http://dronebl.org/lookup?ip="~ip]; 101 102 result = lookupEfnetRBL(ip); 103 if (result) return [result, "EFnet RBL", "http://rbl.efnetrbl.org/?i=" ~ip]; 104 105 return null; 106 }