dnsbl-client 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +0 -0
- data/README.rdoc +5 -5
- data/lib/dnsbl-client/dnsbl-client.rb +50 -6
- data/lib/dnsbl-client/dnsbl.yaml +10 -3
- metadata +39 -40
- metadata.gz.sig +0 -0
- data/test/helper.rb +0 -18
- data/test/test_dnsbl-client.rb +0 -44
data.tar.gz.sig
CHANGED
Binary file
|
data/README.rdoc
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
dnsbl-client queries DNS Blacklists for listings. Currently this only does IP lookups, but the next version will handle domains.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
require "dnsbl-client"
|
6
|
+
c = DNSBL::Client.new
|
7
|
+
c.lookup("203.150.14.85")
|
8
|
+
=> [#<struct DNSBL::DNSBLResult dnsbl="UCEPROTECT1", query="85.14.150.203.dnsbl-1.uceprotect.net", result="127.0.0.2", meaning="Blacklisted", timing=0.0247988700866699>, #<struct DNSBL::DNSBLResult dnsbl="BARRACUDA", query="85.14.150.203.b.barracudacentral.org", result="127.0.0.2", meaning="Listed", timing=0.0266849994659424>]
|
9
|
+
|
10
10
|
== Contributing to dnsbl-client
|
11
11
|
|
12
12
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
@@ -12,7 +12,7 @@ class Resolv::DNS::Config
|
|
12
12
|
if self.respond_to? :nameserver_port
|
13
13
|
@nameservers = nameserver_port
|
14
14
|
else
|
15
|
-
@nameserver ||= ['4.2.2.2','4.2.2.5','8.8.4.4','8.8.8.8','208.67.222.222','208.67.220.220']
|
15
|
+
@nameserver ||= ['4.2.2.2','4.2.2.5','8.8.4.4','8.8.8.8','208.67.222.222','208.67.220.220'].sort {rand}
|
16
16
|
@nameservers ||= @nameserver.map {|i| [i, 53] }
|
17
17
|
end
|
18
18
|
@nameservers
|
@@ -33,10 +33,10 @@ module DNSBL
|
|
33
33
|
# initialize a new DNSBL::Client object
|
34
34
|
# the config file automatically points to a YAML file containing the list of DNSBLs and their return codes
|
35
35
|
# the two-level-tlds file lists most of the two level tlds, needed for hostname to domain normalization
|
36
|
-
def initialize(
|
36
|
+
def initialize(config = YAML.load(File.open(File.dirname(__FILE__)+"/dnsbl.yaml").read),
|
37
37
|
two_level_tldfile = File.dirname(__FILE__)+"/two-level-tlds",
|
38
38
|
three_level_tldfile = File.dirname(__FILE__)+"/three-level-tlds")
|
39
|
-
@dnsbls =
|
39
|
+
@dnsbls = config
|
40
40
|
@two_level_tld = []
|
41
41
|
@three_level_tld = []
|
42
42
|
File.open(two_level_tldfile).readlines.each do |l|
|
@@ -86,7 +86,7 @@ module DNSBL
|
|
86
86
|
end
|
87
87
|
|
88
88
|
# converts an ip or a hostname into the DNS query packet requires to lookup the result
|
89
|
-
def _encode_query(item,itemtype,domain)
|
89
|
+
def _encode_query(item,itemtype,domain,apikey=nil)
|
90
90
|
label = nil
|
91
91
|
if itemtype == 'ip'
|
92
92
|
label = item.split(/\./).reverse.join(".")
|
@@ -94,6 +94,9 @@ module DNSBL
|
|
94
94
|
label = normalize(item)
|
95
95
|
end
|
96
96
|
lookup = "#{label}.#{domain}"
|
97
|
+
if apikey
|
98
|
+
lookup = "#{apikey}.#{lookup}"
|
99
|
+
end
|
97
100
|
txid = lookup.sum
|
98
101
|
message = Resolv::DNS::Message.new(txid)
|
99
102
|
message.rd = 1
|
@@ -120,7 +123,14 @@ module DNSBL
|
|
120
123
|
else
|
121
124
|
@dnsbls.each do |dnsblname, config|
|
122
125
|
if name.to_s.end_with?(config['domain'])
|
123
|
-
meaning =
|
126
|
+
meaning = nil
|
127
|
+
if config['decoder']
|
128
|
+
meaning = self.send(("__"+config['decoder']).to_sym, data.address.to_s)
|
129
|
+
elsif config[data.address.to_s]
|
130
|
+
meaning = config[data.address.to_s]
|
131
|
+
else
|
132
|
+
meaning = data.address.to_s
|
133
|
+
end
|
124
134
|
results << DNSBLResult.new(dnsblname, name.to_s.gsub("."+config['domain'],''), name.to_s, data.address.to_s, meaning, Time.now.to_f - @starttime)
|
125
135
|
break
|
126
136
|
end
|
@@ -130,6 +140,39 @@ module DNSBL
|
|
130
140
|
results
|
131
141
|
end
|
132
142
|
|
143
|
+
def __phpot_decoder(ip)
|
144
|
+
octets = ip.split(/\./)
|
145
|
+
if octets.length != 4 or octets[0] != "127"
|
146
|
+
return "invalid response"
|
147
|
+
elsif octets[3] == "0"
|
148
|
+
search_engines = ["undocumented", "AltaVista", "Ask", "Baidu", "Excite", "Google", "Looksmart", "Lycos", "MSN", "Yahoo", "Cuil", "InfoSeek", "Miscellaneous"]
|
149
|
+
sindex = octets[2].to_i
|
150
|
+
if sindex >= search_engines.length
|
151
|
+
return "type=search engine,engine=unknown"
|
152
|
+
else
|
153
|
+
return "type=search engine,engine=#{search_engines[sindex]}"
|
154
|
+
end
|
155
|
+
else
|
156
|
+
days, threatscore, flags = octets[1,3]
|
157
|
+
flags = flags.to_i
|
158
|
+
types = []
|
159
|
+
if (flags & 0x1) == 0x1
|
160
|
+
types << "suspicious"
|
161
|
+
end
|
162
|
+
if (flags & 0x2) == 0x2
|
163
|
+
types << "harvester"
|
164
|
+
end
|
165
|
+
if (flags & 0x4) == 0x4
|
166
|
+
types << "comment spammer"
|
167
|
+
end
|
168
|
+
if (flags & 0xf8) > 0
|
169
|
+
types << "reserved"
|
170
|
+
end
|
171
|
+
type = types.join(",")
|
172
|
+
return "days=#{days},score=#{threatscore},type=#{type}"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
133
176
|
# the main method of this class, lookup performs the sending of DNS queries for the items
|
134
177
|
def lookup(item)
|
135
178
|
# if item is an array, use it, otherwise make it one
|
@@ -150,9 +193,10 @@ module DNSBL
|
|
150
193
|
# for each dnsbl that supports our type, create the DNS query packet and send it
|
151
194
|
# rotate across our configured name servers and increment sent
|
152
195
|
@dnsbls.each do |name,config|
|
196
|
+
next if config['disabled']
|
153
197
|
next unless config['type'] == itemtype
|
154
198
|
begin
|
155
|
-
msg = _encode_query(item,itemtype,config['domain'])
|
199
|
+
msg = _encode_query(item,itemtype,config['domain'],config['apikey'])
|
156
200
|
@sockets[@socket_index].send(msg,0)
|
157
201
|
@socket_index += 1
|
158
202
|
@socket_index %= @sockets.length
|
data/lib/dnsbl-client/dnsbl.yaml
CHANGED
@@ -102,6 +102,7 @@ DRONEBL:
|
|
102
102
|
127.0.0.13: Brute force attackers
|
103
103
|
127.0.0.14: Open Wingate Proxy
|
104
104
|
127.0.0.15: Compromised router / gateway
|
105
|
+
127.0.0.17: Automatically determined botnet IPs (experimental)
|
105
106
|
127.0.0.255: Unknown
|
106
107
|
BARRACUDA:
|
107
108
|
domain: b.barracudacentral.org
|
@@ -179,7 +180,7 @@ NOMOREFUN:
|
|
179
180
|
127.0.0.7: Ignoring complaints of spamming by customers
|
180
181
|
127.0.0.8: Please update your formmail.pl script
|
181
182
|
127.0.0.9: See http://moensted.dk/spam/no-more-funn/?addr=$
|
182
|
-
127.0.0.10:
|
183
|
+
127.0.0.10: Possible open proxy
|
183
184
|
127.0.0.11: Please stop testing our servers
|
184
185
|
SPAMCANNIBAL:
|
185
186
|
domain: bl.spamcannibal.org
|
@@ -202,6 +203,12 @@ WHITELIST:
|
|
202
203
|
type: ip
|
203
204
|
127.0.0.2: Whitelisted
|
204
205
|
BACKSCATTERER:
|
205
|
-
|
206
|
+
domain: ips.backscatterer.org
|
206
207
|
type: ip
|
207
|
-
127.0.0.2: Backscatterer
|
208
|
+
127.0.0.2: Backscatterer
|
209
|
+
PROJECTHONEYPOT:
|
210
|
+
domain: dnsbl.httpbl.org
|
211
|
+
type: ip
|
212
|
+
apikey: abcdefghijkl
|
213
|
+
disabled: true
|
214
|
+
decoder: phpot_decoder
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dnsbl-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
4
|
+
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
7
|
+
- 4
|
8
|
+
- 0
|
9
|
+
version: 0.4.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Chris Lee
|
@@ -37,68 +36,74 @@ cert_chain:
|
|
37
36
|
6yhklP75
|
38
37
|
-----END CERTIFICATE-----
|
39
38
|
|
40
|
-
date:
|
39
|
+
date: 2012-09-28 00:00:00 -04:00
|
40
|
+
default_executable: dnsbl-client
|
41
41
|
dependencies:
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
|
+
prerelease: false
|
44
|
+
type: :development
|
45
|
+
name: shoulda
|
43
46
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
44
|
-
none: false
|
45
47
|
requirements:
|
46
48
|
- - ">="
|
47
49
|
- !ruby/object:Gem::Version
|
48
|
-
hash: 3
|
49
50
|
segments:
|
50
51
|
- 0
|
51
52
|
version: "0"
|
52
53
|
requirement: *id001
|
54
|
+
- !ruby/object:Gem::Dependency
|
53
55
|
prerelease: false
|
54
|
-
name: shoulda
|
55
56
|
type: :development
|
56
|
-
|
57
|
+
name: rdoc
|
57
58
|
version_requirements: &id002 !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
59
|
requirements:
|
60
60
|
- - ~>
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
hash: 23
|
63
62
|
segments:
|
64
|
-
-
|
65
|
-
-
|
66
|
-
|
67
|
-
version: 1.0.0
|
63
|
+
- 3
|
64
|
+
- 12
|
65
|
+
version: "3.12"
|
68
66
|
requirement: *id002
|
67
|
+
- !ruby/object:Gem::Dependency
|
69
68
|
prerelease: false
|
70
|
-
name: bundler
|
71
69
|
type: :development
|
72
|
-
|
70
|
+
name: bundler
|
73
71
|
version_requirements: &id003 !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
72
|
requirements:
|
76
73
|
- - ~>
|
77
74
|
- !ruby/object:Gem::Version
|
78
|
-
hash: 7
|
79
75
|
segments:
|
80
76
|
- 1
|
77
|
+
- 1
|
81
78
|
- 5
|
82
|
-
|
83
|
-
version: 1.5.2
|
79
|
+
version: 1.1.5
|
84
80
|
requirement: *id003
|
81
|
+
- !ruby/object:Gem::Dependency
|
85
82
|
prerelease: false
|
86
|
-
name: jeweler
|
87
83
|
type: :development
|
88
|
-
|
84
|
+
name: jeweler
|
89
85
|
version_requirements: &id004 !ruby/object:Gem::Requirement
|
90
|
-
none: false
|
91
86
|
requirements:
|
92
|
-
- -
|
87
|
+
- - ~>
|
93
88
|
- !ruby/object:Gem::Version
|
94
|
-
hash: 3
|
95
89
|
segments:
|
96
|
-
-
|
97
|
-
|
90
|
+
- 1
|
91
|
+
- 8
|
92
|
+
- 4
|
93
|
+
version: 1.8.4
|
98
94
|
requirement: *id004
|
95
|
+
- !ruby/object:Gem::Dependency
|
99
96
|
prerelease: false
|
100
|
-
name: rcov
|
101
97
|
type: :development
|
98
|
+
name: rcov
|
99
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
segments:
|
104
|
+
- 0
|
105
|
+
version: "0"
|
106
|
+
requirement: *id005
|
102
107
|
description: simple interface to lookup blacklists results
|
103
108
|
email: rubygems@chrislee.dhs.org
|
104
109
|
executables:
|
@@ -117,8 +122,7 @@ files:
|
|
117
122
|
- lib/dnsbl-client/two-level-tlds
|
118
123
|
- LICENSE.txt
|
119
124
|
- README.rdoc
|
120
|
-
|
121
|
-
- test/test_dnsbl-client.rb
|
125
|
+
has_rdoc: true
|
122
126
|
homepage: http://github.com/chrislee35/dnsbl-client
|
123
127
|
licenses:
|
124
128
|
- MIT
|
@@ -128,30 +132,25 @@ rdoc_options: []
|
|
128
132
|
require_paths:
|
129
133
|
- lib
|
130
134
|
required_ruby_version: !ruby/object:Gem::Requirement
|
131
|
-
none: false
|
132
135
|
requirements:
|
133
136
|
- - ">="
|
134
137
|
- !ruby/object:Gem::Version
|
135
|
-
hash: 3
|
136
138
|
segments:
|
137
139
|
- 0
|
138
140
|
version: "0"
|
139
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
-
none: false
|
141
142
|
requirements:
|
142
143
|
- - ">="
|
143
144
|
- !ruby/object:Gem::Version
|
144
|
-
hash: 3
|
145
145
|
segments:
|
146
146
|
- 0
|
147
147
|
version: "0"
|
148
148
|
requirements: []
|
149
149
|
|
150
150
|
rubyforge_project:
|
151
|
-
rubygems_version: 1.
|
151
|
+
rubygems_version: 1.3.6
|
152
152
|
signing_key:
|
153
153
|
specification_version: 3
|
154
154
|
summary: queries various DNS Blacklists
|
155
|
-
test_files:
|
156
|
-
|
157
|
-
- test/test_dnsbl-client.rb
|
155
|
+
test_files: []
|
156
|
+
|
metadata.gz.sig
CHANGED
Binary file
|
data/test/helper.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bundler'
|
3
|
-
begin
|
4
|
-
Bundler.setup(:default, :development)
|
5
|
-
rescue Bundler::BundlerError => e
|
6
|
-
$stderr.puts e.message
|
7
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
-
exit e.status_code
|
9
|
-
end
|
10
|
-
require 'test/unit'
|
11
|
-
require 'shoulda'
|
12
|
-
|
13
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
-
require 'dnsbl-client'
|
16
|
-
|
17
|
-
class Test::Unit::TestCase
|
18
|
-
end
|
data/test/test_dnsbl-client.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class TestDnsblClient < Test::Unit::TestCase
|
4
|
-
should "return no hits for 127.0.0.255" do
|
5
|
-
c = DNSBL::Client.new
|
6
|
-
res = c.lookup("127.0.0.255")
|
7
|
-
assert_equal(0,res.length)
|
8
|
-
end
|
9
|
-
should "return all lists for 127.0.0.2" do
|
10
|
-
c = DNSBL::Client.new
|
11
|
-
res = c.lookup("127.0.0.2")
|
12
|
-
assert(res.length >= c.dnsbls.length)
|
13
|
-
end
|
14
|
-
should "return results for bad domains" do
|
15
|
-
c = DNSBL::Client.new
|
16
|
-
res = c.lookup("pfizer.viagra.aqybasej.gurdoctor.com")
|
17
|
-
assert(res.length >= 0)
|
18
|
-
end
|
19
|
-
|
20
|
-
should "normalize domains to two levels if it's neither in two-level nor three-level list" do
|
21
|
-
c = DNSBL::Client.new
|
22
|
-
|
23
|
-
assert_equal("example.org", c.normalize("example.org"))
|
24
|
-
assert_equal("example.org", c.normalize("www.example.org"))
|
25
|
-
assert_equal("example.org", c.normalize("foo.bar.baz.example.org"))
|
26
|
-
end
|
27
|
-
|
28
|
-
should "normaize domains to three levels if it's in two-level list" do
|
29
|
-
c = DNSBL::Client.new
|
30
|
-
|
31
|
-
assert_equal("example.co.uk", c.normalize("example.co.uk"))
|
32
|
-
assert_equal("example.co.uk", c.normalize("www.example.co.uk"))
|
33
|
-
assert_equal("example.co.uk", c.normalize("foo.bar.baz.example.co.uk"))
|
34
|
-
assert_equal("example.blogspot.com", c.normalize("example.blogspot.com"))
|
35
|
-
end
|
36
|
-
|
37
|
-
should "normalize domains to four levels if it's in three-level list" do
|
38
|
-
c = DNSBL::Client.new
|
39
|
-
|
40
|
-
assert_equal("example.act.edu.au", c.normalize("example.act.edu.au"))
|
41
|
-
assert_equal("example.act.edu.au", c.normalize("www.example.act.edu.au"))
|
42
|
-
assert_equal("example.act.edu.au", c.normalize("foo.bar.example.act.edu.au"))
|
43
|
-
end
|
44
|
-
end
|