dns_one 0.4.5 → 0.4.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f453b1c3de16a0ad2b5554fe8523ec273d0a357b
4
- data.tar.gz: 9f1c9f5f11051b485b4240928499480e4debaea7
3
+ metadata.gz: 34e353b91f2c725a06a2bc095d1990e48e0ab914
4
+ data.tar.gz: dbed7b26aa08686cfceafd0dbd659df692dd5aef
5
5
  SHA512:
6
- metadata.gz: 3b01bc36084734be73f3261f57506e535080f386893a459bf98f16c49873a355d292d64eda5680cceaa216d23db02369518b8e22d0f3de128e1f0217112b8e6d
7
- data.tar.gz: d04807c66a45320c7a3038deae8f73011ff304bee095483ac6866226a6ef125f6125b52570210e3aded4ceeae6d57a7ac3d9bf7e4d2f35eca3630e074038579c
6
+ metadata.gz: 1e5cbbad25694937f59a0e2b4271b3ea2f180264b6f11f4d7209d2d5f4f51b1e69e2c511fbea333e0e768cb645db3160e30adfc028d2f23dc56edb2b6195c654
7
+ data.tar.gz: b59b7281f46ad5233461d07bb62ff8e6973bf51dea119a089a7d883699bb671200d79b1a7890213ca0dc71897c417409715511f837a4f32210bfe1e22c29acba
@@ -1,7 +1,7 @@
1
1
  module Backend; class BackendDB
2
2
  def initialize conf
3
3
  @query = conf.delete :query
4
- @db_conf = conf
4
+ @conf = conf
5
5
  setup_db
6
6
  end
7
7
 
@@ -44,7 +44,27 @@ module Backend; class BackendDB
44
44
 
45
45
  def setup_db
46
46
  ActiveRecord::Base.logger = Log.logger
47
- ActiveRecord::Base.establish_connection @db_conf
47
+
48
+ gem_name = {
49
+ 'postgresql' => 'pg',
50
+ 'mysql' => 'mysql',
51
+ 'mysql2' => 'mysql2'
52
+ }[ @conf[:adapter] ]
53
+
54
+ unless gem_name
55
+ Util.die "Database adapter '#{@conf[:adapter]}' not supported. Aborting."
56
+ end
57
+
58
+ begin
59
+ require gem_name.to_s
60
+
61
+ rescue LoadError => e
62
+ Util.die "Error loading database dependency.\nMake sure #{gem_name} it is installed, if it is not, install with 'gem install #{gem_name}'\nError Details: #{e.desc}"
63
+ rescue => e
64
+ Util.die "Error loading database dependency.\n#{e.desc}"
65
+ end
66
+
67
+ ActiveRecord::Base.establish_connection @conf
48
68
  end
49
69
 
50
70
  end; end
data/lib/dns_one/cache.rb CHANGED
@@ -18,5 +18,9 @@ module DnsOne; class Cache
18
18
  def find k
19
19
  @cache[k]
20
20
  end
21
+
22
+ def stat
23
+ "#{@cache.length}/#{@max_size}"
24
+ end
21
25
 
22
26
  end; end
data/lib/dns_one/cli.rb CHANGED
@@ -10,8 +10,9 @@ class DnsOne::CLI < Thor
10
10
  desc "run", "run server"
11
11
  option :conf
12
12
  option :log
13
+ option :work_dir
13
14
  def run_srv
14
- DnsOne::DnsOne.new(conf_file: options[:conf], log_file: options[:log]).start
15
+ DnsOne::DnsOne.new(conf_file: options[:conf], log_file: options[:log], work_dir: options[:work_dir]).start
15
16
  end
16
17
  default_task :run_srv
17
18
 
@@ -0,0 +1,160 @@
1
+
2
+ # activesupport-5.1.1/lib/active_support/core_ext/regexp.rb
3
+
4
+ class Regexp #:nodoc:
5
+ def multiline?
6
+ options & MULTILINE == MULTILINE
7
+ end
8
+
9
+ def match?(string, pos = 0)
10
+ !!match(string, pos)
11
+ end unless //.respond_to?(:match?)
12
+ end
13
+
14
+ # activesupport-5.1.1/lib/active_support/core_ext/object/blank.rb
15
+
16
+ class Object
17
+ # An object is blank if it's false, empty, or a whitespace string.
18
+ # For example, +false+, '', ' ', +nil+, [], and {} are all blank.
19
+ #
20
+ # This simplifies
21
+ #
22
+ # !address || address.empty?
23
+ #
24
+ # to
25
+ #
26
+ # address.blank?
27
+ #
28
+ # @return [true, false]
29
+ def blank?
30
+ respond_to?(:empty?) ? !!empty? : !self
31
+ end
32
+
33
+ # An object is present if it's not blank.
34
+ #
35
+ # @return [true, false]
36
+ def present?
37
+ !blank?
38
+ end
39
+
40
+ # Returns the receiver if it's present otherwise returns +nil+.
41
+ # <tt>object.presence</tt> is equivalent to
42
+ #
43
+ # object.present? ? object : nil
44
+ #
45
+ # For example, something like
46
+ #
47
+ # state = params[:state] if params[:state].present?
48
+ # country = params[:country] if params[:country].present?
49
+ # region = state || country || 'US'
50
+ #
51
+ # becomes
52
+ #
53
+ # region = params[:state].presence || params[:country].presence || 'US'
54
+ #
55
+ # @return [Object]
56
+ def presence
57
+ self if present?
58
+ end
59
+ end
60
+
61
+ class NilClass
62
+ # +nil+ is blank:
63
+ #
64
+ # nil.blank? # => true
65
+ #
66
+ # @return [true]
67
+ def blank?
68
+ true
69
+ end
70
+ end
71
+
72
+ class FalseClass
73
+ # +false+ is blank:
74
+ #
75
+ # false.blank? # => true
76
+ #
77
+ # @return [true]
78
+ def blank?
79
+ true
80
+ end
81
+ end
82
+
83
+ class TrueClass
84
+ # +true+ is not blank:
85
+ #
86
+ # true.blank? # => false
87
+ #
88
+ # @return [false]
89
+ def blank?
90
+ false
91
+ end
92
+ end
93
+
94
+ class Array
95
+ # An array is blank if it's empty:
96
+ #
97
+ # [].blank? # => true
98
+ # [1,2,3].blank? # => false
99
+ #
100
+ # @return [true, false]
101
+ alias_method :blank?, :empty?
102
+ end
103
+
104
+ class Hash
105
+ # A hash is blank if it's empty:
106
+ #
107
+ # {}.blank? # => true
108
+ # { key: 'value' }.blank? # => false
109
+ #
110
+ # @return [true, false]
111
+ alias_method :blank?, :empty?
112
+ end
113
+
114
+ class String
115
+ unless BLANK_RE
116
+ BLANK_RE = /\A[[:space:]]*\z/
117
+ end
118
+
119
+ # A string is blank if it's empty or contains whitespaces only:
120
+ #
121
+ # ''.blank? # => true
122
+ # ' '.blank? # => true
123
+ # "\t\n\r".blank? # => true
124
+ # ' blah '.blank? # => false
125
+ #
126
+ # Unicode whitespace is supported:
127
+ #
128
+ # "\u00a0".blank? # => true
129
+ #
130
+ # @return [true, false]
131
+ def blank?
132
+ # The regexp that matches blank strings is expensive. For the case of empty
133
+ # strings we can speed up this method (~3.5x) with an empty? call. The
134
+ # penalty for the rest of strings is marginal.
135
+ empty? || BLANK_RE.match?(self)
136
+ end
137
+ end
138
+
139
+ class Numeric #:nodoc:
140
+ # No number is blank:
141
+ #
142
+ # 1.blank? # => false
143
+ # 0.blank? # => false
144
+ #
145
+ # @return [false]
146
+ def blank?
147
+ false
148
+ end
149
+ end
150
+
151
+ class Time #:nodoc:
152
+ # No Time is blank:
153
+ #
154
+ # Time.now.blank? # => false
155
+ #
156
+ # @return [false]
157
+ def blank?
158
+ false
159
+ end
160
+ end
@@ -0,0 +1,9 @@
1
+
2
+ class Exception
3
+ def desc
4
+ "#{self.class}: #{ message }\n#{ backtrace&.join "\n" }"
5
+ end
6
+ def puts_stderr
7
+ STDERR.puts e.desc
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+
2
+ class String
3
+ def to_a
4
+ [self]
5
+ end
6
+ def strip_text
7
+ split("\n")
8
+ .map{|l| l.strip}
9
+ .join("\n")
10
+ end
11
+ end
12
+
13
+
data/lib/dns_one/log.rb CHANGED
@@ -2,6 +2,7 @@
2
2
  class Log < Logger
3
3
  class << self
4
4
 
5
+ # 'def [d|i|w|e|f] msg' for DEBUG INFO WARN ERROR FATAL
5
6
  Logger::Severity::constants.each_with_index do |severity, severity_num|
6
7
  next if severity == :UNKNOWN
7
8
  method_name = severity.to_s[0].downcase
@@ -10,42 +11,67 @@ class Log < Logger
10
11
  end
11
12
  end
12
13
 
13
- def setup file, syslog_name
14
+ def setup file, syslog_name, syslog_min_severity = Logger::WARN
15
+ @syslog_min_severity = syslog_min_severity
14
16
  @syslog = Syslog::Logger.new syslog_name
15
17
  @log_file = setfile file
16
18
  @logger = Logger.new @log_file
17
19
  end
18
20
 
19
- def setfile file
20
- if File.exists? file and File.writable? file
21
- file
22
- elsif File.writable? File.dirname(file)
23
- file
21
+ def change_log_file file
22
+ new_log_file = setfile file, allow_stdout: false
23
+ if new_log_file and new_log_file != @log_file
24
+ @log_file = new_log_file
25
+ @logger = Logger.new @log_file
26
+ end
27
+ end
28
+
29
+ def exc e
30
+ e e.desc
31
+ end
32
+
33
+ def logger
34
+ @logger
35
+ end
36
+
37
+ def log_file_desc
38
+ case @log_file
39
+ when STDOUT
40
+ 'STDOUT'
41
+ when STDERR
42
+ 'STDERR'
24
43
  else
44
+ @log_file
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def setfile file, allow_stdout: true
51
+ if [STDOUT, STDERR].include? file or
52
+ File.writable? file or
53
+ File.writable? File.dirname(file)
54
+ file
55
+ elsif allow_stdout
25
56
  STDOUT
26
57
  end
27
58
  end
28
59
 
29
60
  def log severity, msg
30
61
  met_name = Logger::Severity::constants[severity].downcase
62
+
31
63
  @logger.send met_name, msg
32
- if severity >= Logger::WARN
64
+
65
+ if severity >= @syslog_min_severity
33
66
  @syslog.send met_name, msg
34
67
  end
68
+
35
69
  if severity == Logger::FATAL and
36
70
  @log_file != STDOUT and
37
71
  @log_file != STDERR
38
72
  STDERR.puts msg
39
73
  end
40
74
  end
41
-
42
- def exc e
43
- e e.desc
44
- end
45
-
46
- def logger
47
- @logger
48
- end
49
75
  end
50
76
  end
51
77
 
@@ -3,21 +3,23 @@ module DnsOne; class Server # < RExec::Daemon::Base
3
3
 
4
4
  DNS_DAEMON_RUN_AS = "dnsserver"
5
5
  DNS_DAEMON_INTERFACES = [
6
- [:udp, "0.0.0.0", 153],
7
- [:tcp, "0.0.0.0", 153],
8
- [:udp, "::", 15300],
9
- [:tcp, "::", 15300]
6
+ [:udp, "0.0.0.0", 53],
7
+ [:tcp, "0.0.0.0", 53],
8
+ [:udp, "::", 5300],
9
+ [:tcp, "::", 5300]
10
10
  ]
11
11
 
12
- def initialize conf
13
- ZoneSearch.instance.setup conf
12
+ def initialize conf, conf_zone_search
13
+ @conf = conf
14
+ ZoneSearch.instance.setup conf_zone_search
14
15
  end
15
16
 
16
17
  def run
18
+ conf = @conf
17
19
  RubyDNS::run_server(listen: dns_daemon_interfaces, logger: Log.logger) do
18
20
  on(:start) do
19
- if RExec.current_user == 'root' and @conf.config.run_as
20
- RExec.change_user @conf.config.run_as
21
+ if RExec.current_user == 'root' and conf[:run_as]
22
+ RExec.change_user conf[:run_as]
21
23
  end
22
24
  Log.i "Running as #{RExec.current_user}"
23
25
  end
@@ -42,7 +44,7 @@ module DnsOne; class Server # < RExec::Daemon::Base
42
44
  end
43
45
 
44
46
  def dns_daemon_interfaces
45
- if Process.pid == 0
47
+ if RExec.current_user == 'root'
46
48
  DNS_DAEMON_INTERFACES
47
49
  else
48
50
  ports = DNS_DAEMON_INTERFACES.map do |port|
data/lib/dns_one/util.rb CHANGED
@@ -22,4 +22,8 @@ module DnsOne; class Util; class << self
22
22
  end
23
23
  end
24
24
 
25
+ def match_root stat
26
+ stat.uid == 0 && stat.gid == 0
27
+ end
28
+
25
29
  end; end; end
@@ -1,3 +1,3 @@
1
1
  module DnsOne
2
- VERSION = "0.4.5"
2
+ VERSION = "0.4.7"
3
3
  end
@@ -9,10 +9,10 @@ module DnsOne; class ZoneSearch
9
9
  @conf = conf
10
10
  check_record_sets
11
11
  @backend = set_backend
12
- @cache = Cache.new @conf.config[:cache_max]
12
+ @cache = Cache.new @conf[:cache_max]
13
13
 
14
14
  @ignore_subdomains_re = nil
15
- if ignore_subdomains = @conf.config[:ignore_subdomains]
15
+ if ignore_subdomains = @conf[:ignore_subdomains]
16
16
  unless ignore_subdomains.empty?
17
17
  subdoms = ignore_subdomains.strip.split(/\s+/).map(&:downcase).join('|')
18
18
  @ignore_subdomains_re = /^(#{ subdoms })\./i
@@ -26,22 +26,24 @@ module DnsOne; class ZoneSearch
26
26
  Log.d "searching #{ dom_name }..."
27
27
 
28
28
  rec_set_name = find_record_set dom_name
29
- Log.d "record set name #{ rec_set_name ? 'found' : 'not_found' }"
29
+ Log.d "record set name #{ rec_set_name ? 'found' : 'not found' } for #{dom_name} #{res_class}"
30
30
  rec_set_name or return
31
31
 
32
32
  if rec_set_name == ''
33
- rec_set_name = @conf.record_sets.keys.first.to_s
33
+ rec_set_name = @conf[:ecord_sets].keys.first.to_s
34
34
  end
35
35
 
36
- rec_set = @conf.record_sets[rec_set_name.to_sym]
37
- Log.d "record set #{ rec_set ? 'found' : 'not found' }"
36
+ rec_set = @conf[:record_sets][rec_set_name.to_sym]
37
+ Log.d "record set #{ rec_set ? 'found' : 'not found' } for #{dom_name} #{res_class}"
38
38
  rec_set or return
39
39
 
40
40
  answer = nil
41
41
 
42
42
  unless res_class == IN::NS
43
- answer = rec_set[ res_class.to_s.split('::').last.to_sym ]
44
- answer = [answer] unless answer.is_a? Array
43
+ if rec = rec_set[ res_class.to_s.split('::').last.to_sym ]
44
+ answer = rec
45
+ answer = [answer] unless answer.is_a? Array
46
+ end
45
47
  end
46
48
 
47
49
  other_records = []
@@ -57,13 +59,13 @@ module DnsOne; class ZoneSearch
57
59
  private
58
60
 
59
61
  def set_backend
60
- if file = @conf.backend[:file]
62
+ if file = @conf[:backend][:file]
61
63
  unless File.exists? file
62
64
  Util.die "Domain list file #{file} not found."
63
65
  end
64
66
  Backend::BackendFile.new file
65
67
  else
66
- Backend::BackendDB.new @conf.backend
68
+ Backend::BackendDB.new @conf[:backend]
67
69
  end
68
70
  end
69
71
 
@@ -83,7 +85,7 @@ module DnsOne; class ZoneSearch
83
85
  enabled_cache = use_cache && @backend.allow_cache
84
86
 
85
87
  if enabled_cache and rec_set = @cache.find(dom_name)
86
- Log.d "found in cache"
88
+ Log.d "found in cache (#{@cache.stat})"
87
89
  rec_set
88
90
  else
89
91
  if rec_set = @backend.find(dom_name)
@@ -96,11 +98,11 @@ module DnsOne; class ZoneSearch
96
98
  end
97
99
 
98
100
  def check_record_sets
99
- unless @conf.record_sets and not @conf.record_sets.empty?
101
+ if @conf[:record_sets].blank?
100
102
  Util.die "Record sets cannot be empty. Check file."
101
103
  end
102
104
 
103
- @conf.record_sets.each_pair do |rec_set_name, records|
105
+ @conf[:record_sets].each_pair do |rec_set_name, records|
104
106
  unless records[:NS] and records[:NS].length >= 1
105
107
  Util.die "Record set #{rec_set_name} is invalid. It must have at least 1 NS record."
106
108
  end
data/lib/dns_one.rb CHANGED
@@ -10,7 +10,10 @@ require 'rexec'
10
10
 
11
11
  # DnsOne
12
12
 
13
- require "dns_one/core_extensions"
13
+ require "dns_one/core_ext/exception"
14
+ require "dns_one/core_ext/string"
15
+ require "dns_one/core_ext/blank"
16
+
14
17
  require "dns_one/log"
15
18
  require "dns_one/util"
16
19
 
@@ -24,30 +27,42 @@ require 'dns_one/backend/db'
24
27
 
25
28
  module DnsOne; class DnsOne
26
29
 
27
- DEFAULT_LOG_FILE = "/var/log/dns_server.log"
30
+ DEFAULT_LOG_FILE = "/var/log/dns_one.log"
28
31
  DEFAULT_CONF_FILE = '/etc/dns_one/conf.yml'
29
- WORK_DIR = "/var/local/dnsserver"
32
+ WORK_DIR = "/var/local/dns_one"
30
33
 
31
34
  CONF_DIR = "/etc/dns_one"
32
35
  SYSLOG_NAME = 'dns_one'
33
36
 
34
- def initialize conf_file: nil, log_file: nil
35
- log_file ||= DEFAULT_LOG_FILE
36
- conf_file ||= DEFAULT_CONF_FILE
37
-
37
+ def initialize conf_file: nil, log_file: nil, work_dir: nil
38
+ cmd_log_file = log_file
39
+ log_file ||= DEFAULT_LOG_FILE
38
40
  Log.setup log_file, SYSLOG_NAME
39
- @conf = parse_conf conf_file
40
41
 
41
- # check_root
42
+ conf_file ||= DEFAULT_CONF_FILE
43
+ @conf_all = parse_conf conf_file
44
+ @conf = @conf_all.main
45
+
46
+ work_dir ||= WORK_DIR
47
+
48
+ # Redefine log file if set in conf file
49
+ unless cmd_log_file
50
+ if f = @conf[:log_file].presence
51
+ unless Log.change_log_file f
52
+ Log.w "Unable to change logfile to #{f}. Will continue with #{Log.log_file_desc}."
53
+ end
54
+ end
55
+ end
56
+
42
57
  begin
43
- Dir.chdir (@conf.config[:work_dir] || WORK_DIR)
58
+ Dir.chdir work_dir
44
59
  rescue => e
45
60
  Log.w "Cannot change working dir to #{WORK_DIR}. Will continue in #{Dir.pwd}."
46
61
  end
47
62
  end
48
63
 
49
64
  def start
50
- Server.new(@conf).run
65
+ Server.new(@conf_all.server, @conf_all.zone_search).run
51
66
  end
52
67
 
53
68
  private
@@ -58,9 +73,21 @@ module DnsOne; class DnsOne
58
73
  conf = YAML.load_file conf_file
59
74
  conf.deep_symbolize_keys!
60
75
 
61
- conf[:config] ||= {}
62
-
63
- OpenStruct.new conf
76
+ OpenStruct.new(
77
+ main: {
78
+ work_dir: conf[:work_dir],
79
+ log_file: conf[:log_file]
80
+ },
81
+ server: {
82
+ run_as: conf[:run_as]
83
+ },
84
+ zone_search: {
85
+ ignore_subdomains: conf[:ignore_subdomains],
86
+ cache_max: conf[:cache_max],
87
+ record_sets: conf[:record_sets],
88
+ backend: conf[:backend]
89
+ }
90
+ )
64
91
  end
65
92
 
66
93
  def check_conf_file conf_file
@@ -74,7 +101,7 @@ module DnsOne; class DnsOne
74
101
  # Util.die "Conf file #{conf_file} must have mode 0600. Aborting."
75
102
  end
76
103
 
77
- unless match_root conf_stat
104
+ unless Util.match_root conf_stat
78
105
  # Util.die "Conf file #{conf_file} must have uid/gid set to root. Aborting."
79
106
  end
80
107
  end
data/util/sample_conf.yml CHANGED
@@ -1,8 +1,9 @@
1
1
 
2
2
  config:
3
3
  run_as: dnsserver # optional, but highly recommended! adduser --system dnsserver
4
- ignore_subdomains: www en it es pt ru fr at # optional
4
+ ignore_subdomains: www en it es pt ru fr at # optional, defaults to an empty list
5
5
  # cache_max: 100000 # optional, defaults to 10000
6
+ # log_file: /var/log/dns_one.log # optional, defaults to /var/log/dns_one.log
6
7
 
7
8
  backend:
8
9
  ##############
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dns_one
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Lobato
@@ -136,7 +136,9 @@ files:
136
136
  - lib/dns_one/backend/file.rb
137
137
  - lib/dns_one/cache.rb
138
138
  - lib/dns_one/cli.rb
139
- - lib/dns_one/core_extensions.rb
139
+ - lib/dns_one/core_ext/blank.rb
140
+ - lib/dns_one/core_ext/exception.rb
141
+ - lib/dns_one/core_ext/string.rb
140
142
  - lib/dns_one/log.rb
141
143
  - lib/dns_one/server.rb
142
144
  - lib/dns_one/setup.rb
@@ -1,24 +0,0 @@
1
-
2
- class String
3
- def to_a
4
- [self]
5
- end
6
- def strip_text
7
- split("\n")
8
- .map{|l| l.strip}
9
- .join("\n")
10
- end
11
- end
12
-
13
- class Exception
14
- def desc
15
- "#{e.class}: #{ message }\n#{ backtrace&.join "\n" }"
16
- end
17
- def puts_stderr
18
- STDERR.puts e.desc
19
- end
20
- end
21
-
22
- def match_root stat
23
- stat.uid == 0 && stat.gid == 0
24
- end