dns-sniper 0.0.1pre → 0.0.1.pre2
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.
- checksums.yaml +4 -4
- data/Gemfile +3 -1
- data/MIT-LICENSE +20 -0
- data/README.md +77 -0
- data/Rakefile +5 -3
- data/bin/dns-sniper +15 -14
- data/dns-sniper.gemspec +28 -16
- data/lib/dns-sniper.rb +5 -3
- data/lib/dns-sniper/formatter.rb +2 -0
- data/lib/dns-sniper/formatters.rb +12 -5
- data/lib/dns-sniper/formatters/bind8.rb +20 -0
- data/lib/dns-sniper/formatters/dnsmasq.rb +18 -0
- data/lib/dns-sniper/formatters/hosts.rb +18 -0
- data/lib/dns-sniper/formatters/netgear.rb +18 -0
- data/lib/dns-sniper/formatters/text.rb +4 -2
- data/lib/dns-sniper/formatters/unbound.rb +6 -3
- data/lib/dns-sniper/hostnames.rb +50 -69
- metadata +17 -24
- data/.gitignore +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e0cfd33b8c953620c67bd40ea77e26ed12f7a9a10716918ee130a87a8617975
|
4
|
+
data.tar.gz: 9c74827c20d2d3a6cef9ca2876eb9659475401088e05d963778eed19c6d11374
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57d9eaeeb39531a8ec3a5ca9bc0ea21e4dd8277c97b7ecb01fbd49f3109db725efc58096ce60768fb20585d19de26880e34c97e10f2011d2e4ea4e58d09d8d00
|
7
|
+
data.tar.gz: e673010ec9e40910411c4cb63f9f018c70faff0704bc96fc060900cf1188d74df37571821509e06bc98b7092c31b6cf0c8fab615f78fe086ecf892f199ddbbd8
|
data/Gemfile
CHANGED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2020 Brody Hoskins
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# dns-sniper
|
2
|
+
|
3
|
+
dns-sniper is a command line utility that combines online DNS blacklists and combines them into the desired configuration format.
|
4
|
+
|
5
|
+
## Supported Formats
|
6
|
+
|
7
|
+
### Input formats
|
8
|
+
|
9
|
+
* HOSTS
|
10
|
+
* plaintext (hostnames as newline-seperated list)
|
11
|
+
|
12
|
+
### Output formats
|
13
|
+
|
14
|
+
* bind 8
|
15
|
+
* dnsmasq
|
16
|
+
* HOSTS
|
17
|
+
* plaintext (hostnames as newline-seperated list)
|
18
|
+
* unbound
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
Using bundler, add to the `Gemfile`:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
gem 'dns-sniper'
|
26
|
+
```
|
27
|
+
|
28
|
+
Or standalone:
|
29
|
+
|
30
|
+
```
|
31
|
+
$ gem install dns-sniper
|
32
|
+
```
|
33
|
+
|
34
|
+
## Sample Usage
|
35
|
+
|
36
|
+
### From within Ruby
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
require 'dns-sniper'
|
40
|
+
|
41
|
+
hostnames = DNSSniper::Hostnames.new
|
42
|
+
|
43
|
+
# Block domain names
|
44
|
+
hostnames.add_from('https://pgl.yoyo.org/as/serverlist.php?hostformat=hosts;showintro=0;mimetype=plaintext') # From the web
|
45
|
+
hostnames.add_from('https://raw.githubusercontent.com/brodyhoskins/dns-blocklists/master/tracking.list')
|
46
|
+
hostnames.add_from('~/.config/dns-sniper/blocklists.list') # From filesystem
|
47
|
+
|
48
|
+
# Manually add domain name
|
49
|
+
hostnames.add('ads.yahoo.com')
|
50
|
+
hostnames.add(['ads.doubleclick.net', 'ads.msn.com'])
|
51
|
+
|
52
|
+
# Remove whitelisted domain names
|
53
|
+
hostnames.remove_from('~/.config/dns-sniper/whitelisted-hostnames.list')
|
54
|
+
hostnames.remove_from('https://example.com/whitelisted.hosts')
|
55
|
+
|
56
|
+
# Manually remove domain name
|
57
|
+
hostnames.remove('favoritewebsite.com')
|
58
|
+
hostnames.remove(['favoritewebsite.com', 'otherfavoritewebsite.com'])
|
59
|
+
|
60
|
+
# Convert to configuration file
|
61
|
+
hostnames.to_format('dnsmasq')
|
62
|
+
hostnames.to_format('unbound')
|
63
|
+
```
|
64
|
+
|
65
|
+
### From CLI
|
66
|
+
|
67
|
+
See `dns-sniper --help`
|
68
|
+
|
69
|
+
Using the CLI version makes it easy to update configuration formats automatically. For example:
|
70
|
+
|
71
|
+
```bash
|
72
|
+
#!/usr/bin/env bash
|
73
|
+
|
74
|
+
/path/to/dns-sniper -f ~/.config/dns-sniper/blacklist.list -w ~/.config/dns-sniper/whitelist.list -o unbound > /etc/unbound/unbound.conf.t/blocklist.conf
|
75
|
+
|
76
|
+
service unbound reload
|
77
|
+
```
|
data/Rakefile
CHANGED
data/bin/dns-sniper
CHANGED
@@ -1,50 +1,51 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require 'optparse'
|
5
|
+
require 'set'
|
6
|
+
require 'dns-sniper'
|
6
7
|
|
7
|
-
VALID_FORMATS = [
|
8
|
+
VALID_FORMATS = DNSSniper::Formatters.all.inject([]) { |arr, f| arr << f.name.to_s.sub('DNSSniper::', '').downcase }
|
8
9
|
Options = Struct.new(:blacklist_urls_file, :whitelisted_hosts_file, :format)
|
9
10
|
|
10
11
|
class Parser
|
11
12
|
def self.parse(options)
|
12
|
-
args = Options.new(
|
13
|
+
args = Options.new('world')
|
13
14
|
opt_parser = OptionParser.new do |opts|
|
14
15
|
opts.banner = "Usage: #{File.basename(__FILE__)} -f PATH -o FORMAT [options]\n#{File.basename(__FILE__)} combines online DNS blacklists and combines them into the desired configuration FORMAT.\n\n"
|
15
|
-
opts.on(
|
16
|
+
opts.on('-f', '--blacklist=PATH', 'PATH to file with line-separated list of URL’s of blacklists') do |path|
|
16
17
|
args.blacklist_urls_file = path
|
17
18
|
end
|
18
|
-
opts.on(
|
19
|
+
opts.on('-w', '--whitelist=path', 'Path to file with line-separated list of whitelisted hostnames') do |path|
|
19
20
|
args.whitelisted_hosts_file = path
|
20
21
|
end
|
21
|
-
opts.on(
|
22
|
+
opts.on('-o', '--output=FORMAT', "FORMAT to output — one of #{VALID_FORMATS.join(', ')}") do |format|
|
22
23
|
args.format = format
|
23
24
|
end
|
24
|
-
opts.on(
|
25
|
+
opts.on('-h', '--help', 'Prints this help') do
|
25
26
|
puts opts
|
26
27
|
exit
|
27
28
|
end
|
28
29
|
end
|
29
30
|
opt_parser.parse!(options)
|
30
|
-
|
31
|
+
args
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
34
35
|
options = Parser.parse ARGV
|
35
36
|
|
36
37
|
unless VALID_FORMATS.include?(options[:format])
|
37
|
-
|
38
|
+
warn options[:format].blank? ? 'Error: Format not defined' : "Error: Invalid format \"#{options[:format]}\""
|
38
39
|
exit(-1)
|
39
40
|
end
|
40
41
|
|
41
42
|
unless File.exist?(options[:blacklist_urls_file])
|
42
|
-
|
43
|
+
warn "Error: Unable to access ”#{options[:blacklist_urls_file]}”"
|
43
44
|
exit(-1)
|
44
45
|
end
|
45
46
|
|
46
|
-
if options[:whitelisted_hosts_file]
|
47
|
-
|
47
|
+
if options[:whitelisted_hosts_file] && !File.exist?(options[:whitelisted_hosts_file])
|
48
|
+
warn "Error: Unable to access ”#{options[:whitelisted_hosts_file]}”"
|
48
49
|
exit(-1)
|
49
50
|
end
|
50
51
|
|
data/dns-sniper.gemspec
CHANGED
@@ -1,23 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
Gem::Specification.new do |spec|
|
2
|
-
spec.name =
|
3
|
-
spec.license =
|
4
|
-
spec.version =
|
5
|
-
spec.date =
|
6
|
-
|
7
|
-
spec.
|
4
|
+
spec.name = 'dns-sniper'
|
5
|
+
spec.license = 'MIT'
|
6
|
+
spec.version = '0.0.1.pre2'
|
7
|
+
spec.date = '2020-11-01'
|
8
|
+
|
9
|
+
spec.authors = ['Brody Hoskins']
|
10
|
+
spec.email = ['brody@brody.digital']
|
8
11
|
|
9
|
-
spec.summary =
|
10
|
-
spec.description =
|
11
|
-
|
12
|
+
spec.summary = 'Combine DNS blacklists into desired configuration format'
|
13
|
+
spec.description = <<~DESC.gsub(/\n/, ' ').strip
|
14
|
+
dns-sniper generates DNS configuration files based on various user-defined
|
15
|
+
blacklists online. Configuration files can be generated for use in Ruby
|
16
|
+
applications or from the command line.
|
17
|
+
DESC
|
18
|
+
spec.homepage = 'https://github.com/brodyhoskins/dns-sniper'
|
12
19
|
|
13
|
-
spec.
|
20
|
+
spec.metadata = {
|
21
|
+
'homepage_uri' => 'https://github.com/brodyhoskins/dns-sniper',
|
22
|
+
'source_code_uri' => 'https://github.com/brodyhoskins/dns-sniper'
|
23
|
+
}
|
14
24
|
|
15
|
-
spec.
|
16
|
-
spec.
|
17
|
-
spec.
|
25
|
+
spec.files = Dir['lib/**/*']
|
26
|
+
spec.files += Dir['[A-Z]*'] + Dir['test/**/*']
|
27
|
+
spec.files.reject! { |fn| fn.include? 'CVS' }
|
28
|
+
spec.require_paths = ['lib']
|
18
29
|
|
19
|
-
spec.
|
30
|
+
spec.bindir = 'bin'
|
31
|
+
spec.executables = 'dns-sniper'
|
20
32
|
|
21
|
-
spec.
|
22
|
-
spec.
|
33
|
+
spec.add_dependency 'down', '~> 5.1'
|
34
|
+
spec.add_dependency 'hosts_file', '~> 1.0'
|
23
35
|
end
|
data/lib/dns-sniper.rb
CHANGED
data/lib/dns-sniper/formatter.rb
CHANGED
@@ -1,24 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DNSSniper
|
2
4
|
module Formatters
|
3
5
|
extend self
|
6
|
+
# module_function
|
4
7
|
|
5
8
|
attr_reader :registered
|
6
9
|
@registered = []
|
7
10
|
|
8
11
|
def register(class_name, autoload_require)
|
9
12
|
DNSSniper.autoload(class_name, autoload_require)
|
10
|
-
|
13
|
+
@registered << class_name
|
11
14
|
end
|
12
15
|
|
13
16
|
def all
|
14
|
-
|
17
|
+
@registered.map { |name| DNSSniper.const_get(name) }
|
15
18
|
end
|
16
19
|
|
17
20
|
def find(name)
|
18
|
-
all.find { |c| c.name.downcase == name.to_s.downcase } or raise NameError, "
|
21
|
+
all.find { |c| c.name.downcase == name.to_s.downcase } or raise NameError, "Unknown formatter \"#{name}\""
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
22
25
|
|
23
|
-
DNSSniper::Formatters.register :
|
24
|
-
DNSSniper::Formatters.register :
|
26
|
+
DNSSniper::Formatters.register :Bind8, 'dns-sniper/formatters/bind8'
|
27
|
+
DNSSniper::Formatters.register :Dnsmasq, 'dns-sniper/formatters/dnsmasq'
|
28
|
+
DNSSniper::Formatters.register :Hosts, 'dns-sniper/formatters/hosts'
|
29
|
+
DNSSniper::Formatters.register :Netgear, 'dns-sniper/formatters/netgear'
|
30
|
+
DNSSniper::Formatters.register :Text, 'dns-sniper/formatters/text'
|
31
|
+
DNSSniper::Formatters.register :Unbound, 'dns-sniper/formatters/unbound'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DNSSniper
|
4
|
+
class Bind8 < Formatter
|
5
|
+
def initialize(hostnames, options = {})
|
6
|
+
@hostnames = hostnames
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
def output(options = {})
|
11
|
+
raise ArgumentError, 'zone_file is required' unless defined?(options[:zone_file])
|
12
|
+
|
13
|
+
str = ''.dup
|
14
|
+
@hostnames.each do |hostname|
|
15
|
+
str << "zone \"#{hostname}\" { type master; notify no; file \"#{options[:zone_file]}\"; };#{$INPUT_RECORD_SEPARATOR}"
|
16
|
+
end
|
17
|
+
str
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DNSSniper
|
4
|
+
class Dnsmasq < Formatter
|
5
|
+
def initialize(hostnames, options = {})
|
6
|
+
@hostnames = hostnames
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
def output(_options = {})
|
11
|
+
str = ''.dup
|
12
|
+
@hostnames.each do |hostname|
|
13
|
+
str << "server=/#{hostname}/#{$INPUT_RECORD_SEPARATOR}"
|
14
|
+
end
|
15
|
+
str
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DNSSniper
|
4
|
+
class Hosts < Formatter
|
5
|
+
def initialize(hostnames, options = {})
|
6
|
+
@hostnames = hostnames
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
def output(_options = {})
|
11
|
+
str = ''.dup
|
12
|
+
@hostnames.each do |hostname|
|
13
|
+
str << "127.0.0.1\t#{hostname}#{$INPUT_RECORD_SEPARATOR}"
|
14
|
+
end
|
15
|
+
str
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DNSSniper
|
4
|
+
class Netgear < Formatter
|
5
|
+
def initialize(hostnames, options = {})
|
6
|
+
@hostnames = hostnames
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
def output(_options = {})
|
11
|
+
str = ''.dup
|
12
|
+
@hostnames.each_with_index do |hostname, i|
|
13
|
+
str << "[517003_e]: #{i + 1}) #{hostname}\n"
|
14
|
+
end
|
15
|
+
str
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DNSSniper
|
2
4
|
class Text < Formatter
|
3
5
|
def initialize(hostnames, options = {})
|
@@ -5,8 +7,8 @@ module DNSSniper
|
|
5
7
|
@options = options
|
6
8
|
end
|
7
9
|
|
8
|
-
def output
|
9
|
-
@hostnames.to_a.join(
|
10
|
+
def output(_options = {})
|
11
|
+
@hostnames.to_a.join($INPUT_RECORD_SEPARATOR)
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DNSSniper
|
2
4
|
class Unbound < Formatter
|
3
5
|
def initialize(hostnames, options = {})
|
@@ -5,10 +7,11 @@ module DNSSniper
|
|
5
7
|
@options = options
|
6
8
|
end
|
7
9
|
|
8
|
-
def output
|
9
|
-
str =
|
10
|
+
def output(_options = {})
|
11
|
+
str = ''.dup
|
12
|
+
str << "server:#{$INPUT_RECORD_SEPARATOR}"
|
10
13
|
@hostnames.each do |hostname|
|
11
|
-
str << " local-zone: \"#{hostname}\" static#{
|
14
|
+
str << " local-zone: \"#{hostname}\" static#{$INPUT_RECORD_SEPARATOR}"
|
12
15
|
end
|
13
16
|
str
|
14
17
|
end
|
data/lib/dns-sniper/hostnames.rb
CHANGED
@@ -1,31 +1,27 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'down'
|
4
|
+
require 'hosts_file'
|
5
|
+
require 'open-uri'
|
6
|
+
require 'resolv'
|
5
7
|
|
6
8
|
module DNSSniper
|
7
9
|
class Hostnames
|
8
|
-
def initialize(
|
10
|
+
def initialize(_options = {})
|
9
11
|
@hostnames = [].to_set
|
10
12
|
self
|
11
13
|
end
|
12
14
|
|
13
|
-
def add(
|
14
|
-
|
15
|
-
@hostnames
|
16
|
-
self
|
17
|
-
end
|
18
|
-
|
19
|
-
def add_many(hostnames)
|
20
|
-
hostnames.each { |hostname| add(hostname) }
|
15
|
+
def add(hostnames)
|
16
|
+
hostnames = clean(hostnames.class == String ? [hostnames] : hostnames)
|
17
|
+
@hostnames += hostnames unless hostnames.empty?
|
21
18
|
self
|
22
19
|
end
|
23
20
|
|
24
21
|
def add_from(paths_or_urls)
|
25
22
|
return self unless paths_or_urls
|
26
|
-
|
27
|
-
|
28
|
-
end
|
23
|
+
|
24
|
+
paths_or_urls = [paths_or_urls] if paths_or_urls.class == String
|
29
25
|
|
30
26
|
paths_or_urls.each do |path_or_url|
|
31
27
|
path_or_url = path_or_url.strip
|
@@ -38,44 +34,38 @@ module DNSSniper
|
|
38
34
|
path_or_url = down.path
|
39
35
|
contents = down.readlines
|
40
36
|
rescue Down::NotFound
|
41
|
-
|
37
|
+
warn "\"#{path_or_url}\" does not exist"
|
42
38
|
return self
|
43
39
|
rescue Down::ResponseError
|
44
|
-
|
40
|
+
warn "\"#{path_or_url}\": No data from server"
|
45
41
|
return self
|
46
42
|
end
|
47
43
|
end
|
48
44
|
|
49
45
|
case syntax(path_or_url, contents)
|
50
46
|
when nil
|
51
|
-
|
47
|
+
warn "Error: Syntax: Syntax of \"#{path_or_url}\" not recognized, ignored"
|
52
48
|
return self
|
53
|
-
when
|
54
|
-
|
55
|
-
when
|
56
|
-
|
49
|
+
when 'hosts'
|
50
|
+
add from_hosts_file(path_or_url)
|
51
|
+
when 'hostnames'
|
52
|
+
add from_hostnames_file(contents)
|
57
53
|
end
|
58
54
|
end
|
59
55
|
|
60
56
|
self
|
61
57
|
end
|
62
58
|
|
63
|
-
def remove(
|
64
|
-
|
65
|
-
@hostnames
|
66
|
-
self
|
67
|
-
end
|
68
|
-
|
69
|
-
def remove_many(hostnames)
|
70
|
-
hostnames.each { |hostname| remove(hostname) }
|
59
|
+
def remove(hostnames)
|
60
|
+
hostnames = clean(hostnames.class == String ? [hostnames] : hostnames)
|
61
|
+
@hostnames -= hostnames unless hostnames.empty?
|
71
62
|
self
|
72
63
|
end
|
73
64
|
|
74
65
|
def remove_from(paths_or_urls)
|
75
66
|
return self unless paths_or_urls
|
76
|
-
|
77
|
-
|
78
|
-
end
|
67
|
+
|
68
|
+
paths_or_urls = [paths_or_urls] if paths_or_urls.class == String
|
79
69
|
|
80
70
|
paths_or_urls.each do |path_or_url|
|
81
71
|
path_or_url = path_or_url.strip
|
@@ -88,35 +78,35 @@ module DNSSniper
|
|
88
78
|
path_or_url = down.path
|
89
79
|
contents = down.readlines
|
90
80
|
rescue Down::NotFound
|
91
|
-
|
81
|
+
warn "\"#{path_or_url}\" does not exist"
|
92
82
|
return self
|
93
83
|
rescue Down::ResponseError
|
94
|
-
|
84
|
+
warn "\"#{path_or_url}\": No data from server"
|
95
85
|
return self
|
96
86
|
end
|
97
87
|
end
|
98
88
|
|
99
89
|
case syntax(path_or_url, contents)
|
100
90
|
when nil
|
101
|
-
|
91
|
+
warn "Error: Syntax: Syntax of \"#{path_or_url}\" not recognized, ignored"
|
102
92
|
return self
|
103
|
-
when
|
104
|
-
|
105
|
-
when
|
106
|
-
|
93
|
+
when 'hosts'
|
94
|
+
remove from_hosts_file(path_or_url)
|
95
|
+
when 'hostnames'
|
96
|
+
remove from_hostnames_file(contents)
|
107
97
|
end
|
108
98
|
end
|
109
99
|
|
110
100
|
self
|
111
101
|
end
|
112
102
|
|
113
|
-
def to_format(format)
|
103
|
+
def to_format(format, options = {})
|
114
104
|
format = format.capitalize
|
115
105
|
begin
|
116
|
-
klass =
|
117
|
-
klass.new(@hostnames.to_a).output
|
106
|
+
klass = DNSSniper.const_get(format)
|
107
|
+
klass.new(@hostnames.to_a).output(options)
|
118
108
|
rescue NameError
|
119
|
-
|
109
|
+
false
|
120
110
|
end
|
121
111
|
end
|
122
112
|
|
@@ -124,41 +114,32 @@ module DNSSniper
|
|
124
114
|
@hostnames.to_a
|
125
115
|
end
|
126
116
|
|
127
|
-
def to_text
|
128
|
-
@hostnames.to_a.join("\n")
|
129
|
-
end
|
130
|
-
|
131
|
-
def to_unbound
|
132
|
-
str = "server:\n"
|
133
|
-
@hostnames.each do |hostname|
|
134
|
-
str << " local-zone: \"#{hostname}\" static\n"
|
135
|
-
end
|
136
|
-
str
|
137
|
-
end
|
138
|
-
|
139
117
|
private
|
140
118
|
|
141
|
-
def clean(
|
142
|
-
|
143
|
-
|
144
|
-
|
119
|
+
def clean(hostnames)
|
120
|
+
cleaned_hostnames = []
|
121
|
+
hostnames.each do |hostname|
|
122
|
+
hostname = hostname.downcase.strip
|
123
|
+
hostname = hostname.sub('www.', '')
|
124
|
+
hostname_top_domain = "#{hostname.split('.')[-2]}.#{hostname.split('.')[-1]}"
|
145
125
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
nil
|
126
|
+
if !hostname.include?('#') && !['broadcasthost', 'localhost', ''].include?(hostname) && !@hostnames.include?(hostname_top_domain)
|
127
|
+
cleaned_hostnames << hostname
|
128
|
+
end
|
150
129
|
end
|
130
|
+
cleaned_hostnames
|
151
131
|
end
|
152
132
|
|
153
133
|
def syntax(path_or_url, contents)
|
154
134
|
contents.each do |line|
|
155
|
-
next if line.include?(
|
135
|
+
next if line.include?('#')
|
136
|
+
|
156
137
|
line = line.downcase
|
157
138
|
|
158
139
|
if line.strip.split(/\s/).first =~ Regexp.union([Resolv::IPv4::Regex, Resolv::IPv6::Regex])
|
159
|
-
return
|
160
|
-
elsif line.include?
|
161
|
-
return
|
140
|
+
return 'hosts'
|
141
|
+
elsif line.include?('.') && (!line.include? 'http') && path_or_url.end_with?('.list')
|
142
|
+
return 'hostnames'
|
162
143
|
end
|
163
144
|
end
|
164
145
|
nil
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dns-sniper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1.pre2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brody Hoskins
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 2.1.2
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 2.1.2
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: down
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -31,7 +17,7 @@ dependencies:
|
|
31
17
|
- - "~>"
|
32
18
|
- !ruby/object:Gem::Version
|
33
19
|
version: '5.1'
|
34
|
-
type: :
|
20
|
+
type: :runtime
|
35
21
|
prerelease: false
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
@@ -45,15 +31,16 @@ dependencies:
|
|
45
31
|
- - "~>"
|
46
32
|
- !ruby/object:Gem::Version
|
47
33
|
version: '1.0'
|
48
|
-
type: :
|
34
|
+
type: :runtime
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
38
|
- - "~>"
|
53
39
|
- !ruby/object:Gem::Version
|
54
40
|
version: '1.0'
|
55
|
-
description:
|
56
|
-
|
41
|
+
description: dns-sniper generates DNS configuration files based on various user-defined
|
42
|
+
blacklists online. Configuration files can be generated for use in Ruby applications
|
43
|
+
or from the command line.
|
57
44
|
email:
|
58
45
|
- brody@brody.digital
|
59
46
|
executables:
|
@@ -61,22 +48,29 @@ executables:
|
|
61
48
|
extensions: []
|
62
49
|
extra_rdoc_files: []
|
63
50
|
files:
|
64
|
-
- ".gitignore"
|
65
51
|
- Gemfile
|
66
52
|
- Gemfile.lock
|
53
|
+
- MIT-LICENSE
|
54
|
+
- README.md
|
67
55
|
- Rakefile
|
68
56
|
- bin/dns-sniper
|
69
57
|
- dns-sniper.gemspec
|
70
58
|
- lib/dns-sniper.rb
|
71
59
|
- lib/dns-sniper/formatter.rb
|
72
60
|
- lib/dns-sniper/formatters.rb
|
61
|
+
- lib/dns-sniper/formatters/bind8.rb
|
62
|
+
- lib/dns-sniper/formatters/dnsmasq.rb
|
63
|
+
- lib/dns-sniper/formatters/hosts.rb
|
64
|
+
- lib/dns-sniper/formatters/netgear.rb
|
73
65
|
- lib/dns-sniper/formatters/text.rb
|
74
66
|
- lib/dns-sniper/formatters/unbound.rb
|
75
67
|
- lib/dns-sniper/hostnames.rb
|
76
68
|
homepage: https://github.com/brodyhoskins/dns-sniper
|
77
69
|
licenses:
|
78
70
|
- MIT
|
79
|
-
metadata:
|
71
|
+
metadata:
|
72
|
+
homepage_uri: https://github.com/brodyhoskins/dns-sniper
|
73
|
+
source_code_uri: https://github.com/brodyhoskins/dns-sniper
|
80
74
|
post_install_message:
|
81
75
|
rdoc_options: []
|
82
76
|
require_paths:
|
@@ -95,6 +89,5 @@ requirements: []
|
|
95
89
|
rubygems_version: 3.0.3
|
96
90
|
signing_key:
|
97
91
|
specification_version: 4
|
98
|
-
summary:
|
99
|
-
into the desired configuration format
|
92
|
+
summary: Combine DNS blacklists into desired configuration format
|
100
93
|
test_files: []
|