rubydns 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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