rubydns 2.0.2 → 2.1.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.
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'rubydns'
3
-
4
- INTERFACES = [
5
- [:udp, "0.0.0.0", 5300],
6
- [:tcp, "0.0.0.0", 5300],
7
- ]
8
-
9
- IN = Resolv::DNS::Resource::IN
10
-
11
- # Use upstream DNS for name resolution.
12
- UPSTREAM = RubyDNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
13
-
14
- # Start the RubyDNS server
15
- RubyDNS::run_server(INTERFACES) do
16
- match(%r{test.local}, IN::A) do |transaction|
17
- transaction.respond!("10.0.0.80")
18
- end
19
-
20
- # Default DNS handler
21
- otherwise do |transaction|
22
- transaction.passthrough!(UPSTREAM)
23
- end
24
- end
data/examples/cname.rb DELETED
@@ -1,25 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rubydns'
4
- require 'rubydns/system'
5
-
6
- INTERFACES = [
7
- [:udp, "0.0.0.0", 5300],
8
- [:tcp, "0.0.0.0", 5300]
9
- ]
10
-
11
- Name = Resolv::DNS::Name
12
- IN = Resolv::DNS::Resource::IN
13
-
14
- UPSTREAM = RubyDNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
15
-
16
- RubyDNS::run_server(INTERFACES) do
17
- # How to respond to something other than what was requested.
18
- match(//, IN::A) do |transaction|
19
- transaction.respond!(Name.create('foo.bar'), resource_class: IN::CNAME)
20
- end
21
-
22
- otherwise do |transaction|
23
- transaction.passthrough!(UPSTREAM)
24
- end
25
- end
@@ -1,72 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require 'process/daemon'
24
-
25
- require 'rubydns'
26
- require 'rubydns/system'
27
-
28
- INTERFACES = [
29
- [:udp, '0.0.0.0', 5300]
30
- ]
31
-
32
- # A DNS server that selectively drops queries based on the requested domain
33
- # name. Queries for domains that match specified regular expresssions
34
- # (like 'microsoft.com' or 'sco.com') return NXDomain, while all other
35
- # queries are passed to upstream resolvers.
36
- class FlakeyDNS < Process::Daemon
37
- Name = Resolv::DNS::Name
38
- IN = Resolv::DNS::Resource::IN
39
-
40
- def startup
41
- RubyDNS.run_server(INTERFACES) do
42
- # Use a Celluloid supervisor so the system recovers if the actor dies
43
- fallback_resolver_supervisor =
44
- RubyDNS::Resolver.supervise(RubyDNS::System.nameservers)
45
-
46
- # Fail the resolution of certain domains ;)
47
- match(/(m?i?c?r?o?s?o?f?t)/) do |transaction, match_data|
48
- if match_data[1].size > 7
49
- logger.info 'Dropping domain MICROSOFT...'
50
- transaction.fail!(:NXDomain)
51
- else
52
- logger.info 'Passing DNS request upstream...'
53
- transaction.passthrough!(fallback_resolver_supervisor.actors.first)
54
- end
55
- end
56
-
57
- # Hmm....
58
- match(/^(.+\.)?sco\./) do |transaction|
59
- logger.info 'Dropping domain SCO...'
60
- transaction.fail!(:NXDomain)
61
- end
62
-
63
- # Default DNS handler
64
- otherwise do |transaction|
65
- logger.info 'Passing DNS request upstream...'
66
- transaction.passthrough!(fallback_resolver_supervisor.actors.first)
67
- end
68
- end
69
- end
70
- end
71
-
72
- FlakeyDNS.daemonize
@@ -1,106 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- # Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
5
- #
6
- # Permission is hereby granted, free of charge, to any person obtaining a copy
7
- # of this software and associated documentation files (the "Software"), to deal
8
- # in the Software without restriction, including without limitation the rights
9
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- # copies of the Software, and to permit persons to whom the Software is
11
- # furnished to do so, subject to the following conditions:
12
- #
13
- # The above copyright notice and this permission notice shall be included in
14
- # all copies or substantial portions of the Software.
15
- #
16
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- # THE SOFTWARE.
23
-
24
- require 'process/daemon'
25
- require 'process/daemon/privileges'
26
-
27
- require 'rubydns'
28
- require 'rubydns/extensions/string'
29
-
30
- require 'digest/md5'
31
-
32
- # You might need to change the user name "daemon". This can be a user name
33
- # or a user id.
34
- RUN_AS = 'daemon'
35
-
36
- if Process::Daemon::Privileges.current_user != 'root'
37
- $stderr.puts 'Sorry, this command needs to be run as root!'
38
- exit 1
39
- end
40
-
41
- # A DNS server that allows a client to generate fortunes and fetch them with
42
- # subsequent requests. The server 'remembers' the fortunes it generates,
43
- # and can serve them to future requests.
44
- class FortuneDNS < Process::Daemon
45
- Name = Resolv::DNS::Name
46
- IN = Resolv::DNS::Resource::IN
47
-
48
- def startup
49
- cache = {}
50
- stats = { requested: 0 }
51
-
52
- # Start the RubyDNS server
53
- RubyDNS.run_server do
54
- on(:start) do
55
- Process::Daemon::Privileges.change_user(RUN_AS)
56
-
57
- if ARGV.include?('--debug')
58
- @logger.level = Logger::DEBUG
59
- $stderr.sync = true
60
- else
61
- @logger.level = Logger::WARN
62
- end
63
- end
64
-
65
- match(/short\.fortune/, IN::TXT) do |transaction|
66
- fortune = `fortune -s`.gsub(/\s+/, ' ').strip
67
-
68
- transaction.respond!(*fortune.chunked, ttl: 0)
69
- end
70
-
71
- match(/stats\.fortune/, IN::TXT) do |transaction|
72
- $stderr.puts "Sending stats: #{stats.inspect}"
73
- transaction.respond!(stats.inspect)
74
- end
75
-
76
- match(/([a-f0-9]*)\.fortune/, IN::TXT) do |transaction, match|
77
- fortune = cache[match[1]]
78
- stats[:requested] += 1
79
-
80
- if fortune
81
- transaction.respond!(*fortune.chunked)
82
- else
83
- transaction.fail!(:NXDomain)
84
- end
85
- end
86
-
87
- match(/fortune/, [IN::CNAME, IN::TXT]) do |transaction|
88
- fortune = `fortune`.gsub(/\s+/, ' ').strip
89
- checksum = Digest::MD5.hexdigest(fortune)
90
- cache[checksum] = fortune
91
-
92
- answer_txt = "Text Size: #{fortune.size} Byte Size: #{fortune.bytesize}"
93
- transaction.respond!(answer_txt, resource_class: IN::TXT, ttl: 0)
94
- answer_cname = Name.create(checksum + '.fortune')
95
- transaction.respond!(answer_cname, resource_class: IN::CNAME, ttl: 0)
96
- end
97
-
98
- # Default DNS handler
99
- otherwise do |transaction|
100
- transaction.fail!(:NXDomain)
101
- end
102
- end
103
- end
104
- end
105
-
106
- FortuneDNS.daemonize
@@ -1,115 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require 'geoip'
24
-
25
- require 'process/daemon'
26
-
27
- require 'rubydns'
28
- require 'rubydns/system'
29
-
30
- INTERFACES = [
31
- [:udp, '0.0.0.0', 5300]
32
- ]
33
-
34
- # Path to the GeoIP file downloaded from
35
- # http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
36
- # If you have renamed the ungzipped file, or have placed it somewhere other than
37
- # the repository root directory you will need to update this path.
38
- PATH_TO_GEOIP_DAT_FILE =
39
- File.expand_path('../GeoIP.dat', File.dirname(__FILE__))
40
-
41
- # A sample DNS daemon that demonstrates how to use RubyDNS to build responses
42
- # that vary based on the geolocation of the requesting peer. Clients of
43
- # this server who request A records will get an answer IP address based
44
- # on the continent of the client IP address.
45
- #
46
- # Please note that use of this example requires that the peer have a public
47
- # IP address. IP addresses on private networks or the localhost IP (127.0.0.1)
48
- # cannot be resolved to a location, and so will always yield the unknown result.
49
- # This daemon requires the file downloaded from
50
- # http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
51
- # For more information, please see http://www.maxmind.com/en/geolite and
52
- # http://geoip.rubyforge.org
53
- class GeoIPDNS < Process::Daemon
54
- GEO = GeoIP.new(PATH_TO_GEOIP_DAT_FILE)
55
-
56
- Name = Resolv::DNS::Name
57
- IN = Resolv::DNS::Resource::IN
58
-
59
- def startup
60
- RubyDNS.run_server(INTERFACES) do
61
- fallback_resolver_supervisor = RubyDNS::Resolver.supervise(RubyDNS::System.nameservers)
62
-
63
- match(//, IN::A) do |transaction|
64
- logger.debug 'In block'
65
-
66
- # The IP Address of the peer is stored in the transaction options
67
- # with the key :remote_address
68
- ip_address = transaction.options[:remote_address].ip_address
69
- logger.debug "Looking up geographic information for peer #{ip_address}"
70
- location = GeoIPDNS.ip_to_location(ip_address)
71
-
72
- if location
73
- logger.debug "Found location #{location} for #{ip_address}"
74
- else
75
- logger.debug "Could not resolve location for #{ip_address}"
76
- end
77
-
78
- code = location ? location.continent_code : nil
79
- answer = GeoIPDNS.answer_for_continent_code(code)
80
- logger.debug "Answer is #{answer}"
81
- transaction.respond!(answer)
82
- end
83
-
84
- # Default DNS handler
85
- otherwise do |transaction|
86
- logger.debug 'In otherwise'
87
- transaction.passthrough!(fallback_resolver_supervisor.actors.first)
88
- end
89
- end
90
- end
91
-
92
- # Maps each continent code to a fixed IP address for the response.
93
- # A simple mapper to demonstrate the behavior.
94
- def self.answer_for_continent_code(code)
95
- case code
96
- when 'AF' then '1.1.1.1'
97
- when 'AN' then '1.1.2.1'
98
- when 'AS' then '1.1.3.1'
99
- when 'EU' then '1.1.4.1'
100
- when 'NA' then '1.1.5.1'
101
- when 'OC' then '1.1.6.1'
102
- when 'SA' then '1.1.7.1'
103
- else '1.1.8.1'
104
- end
105
- end
106
-
107
- # Finds the continent code for the specified IP address.
108
- # Returns nil if the IP address cannot be mapped to a location.
109
- def self.ip_to_location(ip_address)
110
- return nil unless ip_address
111
- GEO.country(ip_address)
112
- end
113
- end
114
-
115
- GeoIPDNS.daemonize
data/examples/simple.rb DELETED
@@ -1,25 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'rubydns'
3
-
4
- INTERFACES = [
5
- [:udp, '0.0.0.0', 5300],
6
- [:tcp, '0.0.0.0', 5300]
7
- ]
8
-
9
- Name = Resolv::DNS::Name
10
- IN = Resolv::DNS::Resource::IN
11
-
12
- # Use upstream DNS for name resolution.
13
- UPSTREAM = RubyDNS::Resolver.new([[:udp, '8.8.8.8', 53], [:tcp, '8.8.8.8', 53]])
14
-
15
- # Start the RubyDNS server
16
- RubyDNS.run_server(INTERFACES) do
17
- match(/test.mydomain.org/, IN::A) do |transaction|
18
- transaction.respond!('10.0.0.80')
19
- end
20
-
21
- # Default DNS handler
22
- otherwise do |transaction|
23
- transaction.passthrough!(UPSTREAM)
24
- end
25
- end
data/examples/soa-dns.rb DELETED
@@ -1,82 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require 'rubygems'
24
- require 'rubydns'
25
-
26
- $R = Resolv::DNS.new
27
- Name = Resolv::DNS::Name
28
- IN = Resolv::DNS::Resource::IN
29
-
30
- RubyDNS.run_server([[:udp, '0.0.0.0', 5400]]) do
31
- # SOA Record
32
- # dig @localhost -p 5400 SOA mydomain.org
33
- match('mydomain.org', IN::SOA) do |transaction|
34
- #
35
- # For more details about these headers please see:
36
- # http://www.ripe.net/ripe/docs/ripe-203.html
37
- #
38
-
39
- transaction.respond!(
40
- Name.create('ns.mydomain.org.'), # Master Name
41
- Name.create('admin.mydomain.org.'), # Responsible Name
42
- File.mtime(__FILE__).to_i, # Serial Number
43
- 1200, # Refresh Time
44
- 900, # Retry Time
45
- 3_600_000, # Maximum TTL / Expiry Time
46
- 172_800 # Minimum TTL
47
- )
48
-
49
- transaction.append!(transaction.question, IN::NS, section: :authority)
50
- end
51
-
52
- # Default NS record
53
- # dig @localhost -p 5400 mydomain.org NS
54
- match('mydomain.org', IN::NS) do |transaction|
55
- transaction.respond!(Name.create('ns.mydomain.org.'))
56
- end
57
-
58
- # For this exact address record, return an IP address
59
- # dig @localhost -p 5400 CNAME bob.mydomain.org
60
- match(/([^.]+).mydomain.org/, IN::CNAME) do |transaction|
61
- transaction.respond!(Name.create('www.mydomain.org'))
62
- transaction.append!('www.mydomain.org', IN::A)
63
- end
64
-
65
- match('80.0.0.10.in-addr.arpa', IN::PTR) do |transaction|
66
- transaction.respond!(Name.create('www.mydomain.org.'))
67
- end
68
-
69
- match('www.mydomain.org', IN::A) do |transaction|
70
- transaction.respond!('10.0.0.80')
71
- end
72
-
73
- match('ns.mydomain.org', IN::A) do |transaction|
74
- transaction.respond!('10.0.0.10')
75
- end
76
-
77
- # Default DNS handler
78
- otherwise do |transaction|
79
- # Non-Existant Domain
80
- transaction.fail!(:NXDomain)
81
- end
82
- end
@@ -1,83 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require 'rubygems'
24
- require 'rubydns'
25
- require 'rubydns/system'
26
-
27
- # You can specify other DNS servers easily
28
- # $R = Resolv::DNS.new(:nameserver => ["xx.xx.1.1", "xx.xx.2.2"])
29
-
30
- R = RubyDNS::Resolver.new(RubyDNS::System.nameservers)
31
- Name = Resolv::DNS::Name
32
- IN = Resolv::DNS::Resource::IN
33
- INTERFACES = [
34
- [:udp, '0.0.0.0', 5300],
35
- [:tcp, '0.0.0.0', 5300],
36
- # [:udp, '::0', 5300],
37
- # [:tcp, '::0', 5300],
38
- ]
39
-
40
- RubyDNS.run_server(INTERFACES) do
41
- # % dig +nocmd +noall +answer @localhost ANY dev.mydomain.org
42
- # dev.mydomain.org. 16000 IN A 10.0.0.80
43
- # dev.mydomain.org. 16000 IN MX 10 mail.mydomain.org.
44
- match(/dev.mydomain.org/, IN::ANY) do |transaction|
45
- transaction.append_question!
46
-
47
- [IN::A, IN::CNAME, IN::MX].each do |resource_class|
48
- logger.debug "Appending query for #{resource_class}..."
49
- transaction.append!(transaction.name, resource_class)
50
- end
51
- end
52
-
53
- # For this exact address record, return an IP address
54
- match('dev.mydomain.org', IN::A) do |transaction|
55
- transaction.respond!('10.0.0.80')
56
- end
57
-
58
- match('80.0.0.10.in-addr.arpa', IN::PTR) do |transaction|
59
- transaction.respond!(Name.create('dev.mydomain.org.'))
60
- end
61
-
62
- match('dev.mydomain.org', IN::MX) do |transaction|
63
- transaction.respond!(10, Name.create('mail.mydomain.org.'))
64
- end
65
-
66
- match(/^test([0-9]+).mydomain.org$/, IN::A) do |transaction, match_data|
67
- offset = match_data[1].to_i
68
-
69
- if offset > 0 && offset < 10
70
- logger.info "Responding with address #{'10.0.0.' + (90 + offset).to_s}..."
71
- transaction.respond!('10.0.0.' + (90 + offset).to_s)
72
- else
73
- logger.info "Address out of range: #{offset}!"
74
- false
75
- end
76
- end
77
-
78
- # Default DNS handler
79
- otherwise do |transaction|
80
- logger.info 'Passing DNS request upstream...'
81
- transaction.passthrough!(R)
82
- end
83
- end
@@ -1,83 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require 'rubydns'
24
- require 'process-daemon'
25
-
26
- # To run this command, use the standard daemon syntax as root
27
- # ./daemon2.rb start
28
-
29
- # You should be able to see that the server has dropped priviledges
30
- # # ps aux | grep daemon2.rb
31
- # daemon 16555 0.4 0.0 81392 2024 ?? S 3:35am 0:00.28 ruby ../test/daemon2.rb start
32
-
33
- # Test using the following command
34
- # dig @localhost test.mydomain.org
35
- # dig +tcp @localhost test.mydomain.org
36
-
37
- # You might need to change the user name "daemon". This can be a user name or a user id.
38
- RUN_AS = 'daemon'
39
-
40
- INTERFACES = [
41
- [:udp, '0.0.0.0', 53],
42
- [:tcp, '0.0.0.0', 53]
43
- ]
44
-
45
- # We need to be root in order to bind to privileged port
46
- if RExec.current_user != 'root'
47
- $stderr.puts 'Sorry, this command needs to be run as root!'
48
- exit 1
49
- end
50
-
51
- # The Daemon itself
52
- class Server < Process::Daemon
53
- Name = Resolv::DNS::Name
54
- IN = Resolv::DNS::Resource::IN
55
-
56
- # Use upstream DNS for name resolution.
57
- UPSTREAM = RubyDNS::Resolver.new([[:udp, '8.8.8.8', 53], [:tcp, '8.8.8.8', 53]])
58
-
59
- def startup
60
- # Don't buffer output (for debug purposes)
61
- $stderr.sync = true
62
-
63
- # Start the RubyDNS server
64
- RubyDNS.run_server(INTERFACES) do
65
- on(:start) do
66
- RExec.change_user(RUN_AS)
67
- end
68
-
69
- match('test.mydomain.org', IN::A) do |transaction|
70
- transaction.respond!('10.0.0.80')
71
- end
72
-
73
- # Default DNS handler
74
- otherwise do |transaction|
75
- logger.info "Passthrough: #{transaction}"
76
- transaction.passthrough!(UPSTREAM)
77
- end
78
- end
79
- end
80
- end
81
-
82
- # RExec daemon runner
83
- Server.daemonize