Class: Rex::Proto::DNS::Server
- Inherits:
-
Object
- Object
- Rex::Proto::DNS::Server
- Includes:
- IO::GramServer
- Defined in:
- lib/rex/proto/dns/server.rb
Defined Under Namespace
Classes: Cache, MockDnsClient
Constant Summary collapse
Instance Attribute Summary collapse
-
#cache ⇒ Rex::Proto::DNS::Server
Create DNS Server.
-
#fwd_res ⇒ Rex::Proto::DNS::Server
Create DNS Server.
-
#lock ⇒ Object
readonly
Returns the value of attribute lock.
-
#serve_tcp ⇒ Rex::Proto::DNS::Server
Create DNS Server.
-
#serve_udp ⇒ Rex::Proto::DNS::Server
Create DNS Server.
-
#sock_options ⇒ Object
readonly
Returns the value of attribute sock_options.
-
#start_cache ⇒ Rex::Proto::DNS::Server
Create DNS Server.
-
#tcp_sock ⇒ Object
readonly
Returns the value of attribute tcp_sock.
-
#udp_sock ⇒ Object
readonly
Returns the value of attribute udp_sock.
Attributes included from IO::GramServer
#dispatch_request_proc, #listener_thread, #send_response_proc
Class Method Summary collapse
-
.hardcore_alias(*args) ⇒ Object
Returns the hardcore alias for the DNS service.
Instance Method Summary collapse
-
#alias ⇒ Object
DNS server.
-
#default_dispatch_request(cli, data) ⇒ Object
Default DNS request dispatcher, attempts to find response records in cache or forwards request upstream.
-
#dispatch_request(cli, data) ⇒ Object
Process client request, handled with dispatch_request_proc if set.
-
#initialize(lhost = '0.0.0.0', lport = 53, udp = true, tcp = false, start_cache = true, res = nil, comm = nil, ctx = {}, dblock = nil, sblock = nil) ⇒ Server
constructor
A new instance of Server.
-
#monitor_listener ⇒ Object
protected
This method monitors the listener socket for new connections and calls the
on_client_connect
callback routine. -
#on_client_data(cli) ⇒ Object
protected
Processes request coming from client.
-
#running? ⇒ Boolean
Check if server is running.
-
#start ⇒ Object
Start the DNS server and cache.
-
#stop(flush_cache = false) ⇒ Object
Stop the DNS server and cache.
-
#switchns(ns = []) ⇒ Object
Switch DNS forwarders in resolver with thread safety.
Methods included from IO::GramServer
Constructor Details
#initialize(lhost = '0.0.0.0', lport = 53, udp = true, tcp = false, start_cache = true, res = nil, comm = nil, ctx = {}, dblock = nil, sblock = nil) ⇒ Server
Returns a new instance of Server.
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/rex/proto/dns/server.rb', line 184 def initialize(lhost = '0.0.0.0', lport = 53, udp = true, tcp = false, start_cache = true, res = nil, comm = nil, ctx = {}, dblock = nil, sblock = nil) @serve_udp = udp @serve_tcp = tcp @sock_options = { 'LocalHost' => lhost, 'LocalPort' => lport, 'Context' => ctx, 'Comm' => comm } self.fwd_res = res.nil? ? Rex::Proto::DNS::Resolver.new(:comm => comm, :context => ctx) : res self.listener_thread = nil self.dispatch_request_proc = dblock self.send_response_proc = sblock self.start_cache = start_cache self.cache = Cache.new @lock = Mutex.new end |
Instance Attribute Details
#cache ⇒ Rex::Proto::DNS::Server
Create DNS Server
182 183 184 |
# File 'lib/rex/proto/dns/server.rb', line 182 def cache @cache end |
#fwd_res ⇒ Rex::Proto::DNS::Server
Create DNS Server
182 183 184 |
# File 'lib/rex/proto/dns/server.rb', line 182 def fwd_res @fwd_res end |
#lock ⇒ Object (readonly)
Returns the value of attribute lock.
183 184 185 |
# File 'lib/rex/proto/dns/server.rb', line 183 def lock @lock end |
#serve_tcp ⇒ Rex::Proto::DNS::Server
Create DNS Server
182 183 184 |
# File 'lib/rex/proto/dns/server.rb', line 182 def serve_tcp @serve_tcp end |
#serve_udp ⇒ Rex::Proto::DNS::Server
Create DNS Server
182 183 184 |
# File 'lib/rex/proto/dns/server.rb', line 182 def serve_udp @serve_udp end |
#sock_options ⇒ Object (readonly)
Returns the value of attribute sock_options.
183 184 185 |
# File 'lib/rex/proto/dns/server.rb', line 183 def @sock_options end |
#start_cache ⇒ Rex::Proto::DNS::Server
Create DNS Server
182 183 184 |
# File 'lib/rex/proto/dns/server.rb', line 182 def start_cache @start_cache end |
#tcp_sock ⇒ Object (readonly)
Returns the value of attribute tcp_sock.
183 184 185 |
# File 'lib/rex/proto/dns/server.rb', line 183 def tcp_sock @tcp_sock end |
#udp_sock ⇒ Object (readonly)
Returns the value of attribute udp_sock.
183 184 185 |
# File 'lib/rex/proto/dns/server.rb', line 183 def udp_sock @udp_sock end |
Class Method Details
.hardcore_alias(*args) ⇒ Object
Returns the hardcore alias for the DNS service
321 322 323 |
# File 'lib/rex/proto/dns/server.rb', line 321 def self.hardcore_alias(*args) "#{(args[0] || '')}-#{(args[1] || '')}-#{args[5] || ''}" end |
Instance Method Details
#alias ⇒ Object
DNS server.
328 329 330 |
# File 'lib/rex/proto/dns/server.rb', line 328 def alias "DNS Server" end |
#default_dispatch_request(cli, data) ⇒ Object
Default DNS request dispatcher, attempts to find response records in cache or forwards request upstream
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/rex/proto/dns/server.rb', line 286 def default_dispatch_request(cli,data) return if data.strip.empty? req = Packet.encode_drb(data) forward = req.dup # Find cached items, remove request from forwarded packet req.question.each do |ques| cached = self.cache.find(ques.qname, ques.qtype.to_s) if cached.empty? next else req.answer = req.answer + cached forward.question.delete(ques) end end # Forward remaining requests, cache responses if forward.question.count > 0 and @fwd_res forwarded = self.fwd_res.send(validate_packet(forward)) req.answer = req.answer + forwarded.answer forwarded.answer.each do |ans| self.cache.cache_record(ans) end req.header.ra = true # Set recursion bit end # Finalize answers in response # Check for empty response prior to sending if req.answer.size < 1 req.header.rCode = Dnsruby::RCode::NOERROR end req.header.qr = true # Set response bit send_response(cli, validate_packet(req).data) end |
#dispatch_request(cli, data) ⇒ Object
Process client request, handled with dispatch_request_proc if set
272 273 274 275 276 277 278 |
# File 'lib/rex/proto/dns/server.rb', line 272 def dispatch_request(cli, data) if self.dispatch_request_proc self.dispatch_request_proc.call(cli,data) else default_dispatch_request(cli,data) end end |
#monitor_listener ⇒ Object (protected)
This method monitors the listener socket for new connections and calls the on_client_connect
callback routine.
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
# File 'lib/rex/proto/dns/server.rb', line 338 def monitor_listener while true rds = [self.udp_sock] wds = [] eds = [self.udp_sock] r,_,_ = ::IO.select(rds,wds,eds,1) if (r != nil and r[0] == self.udp_sock) buf,host,port = self.udp_sock.recvfrom(65535) # Mock up a client object for sending back data cli = MockDnsClient.new(host, port, r[0]) dispatch_request(cli, buf) end end end |
#on_client_data(cli) ⇒ Object (protected)
Processes request coming from client
359 360 361 362 363 364 365 366 367 368 369 370 |
# File 'lib/rex/proto/dns/server.rb', line 359 def on_client_data(cli) begin data = cli.read(65535) raise ::EOFError if not data raise ::EOFError if data.empty? dispatch_request(cli, data) rescue EOFError => e self.tcp_socket.close_client(cli) if cli raise e end end |
#running? ⇒ Boolean
Check if server is running
219 220 221 |
# File 'lib/rex/proto/dns/server.rb', line 219 def running? self.listener_thread and self.listener_thread.alive? end |
#start ⇒ Object
Start the DNS server and cache
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/rex/proto/dns/server.rb', line 226 def start if self.serve_udp @udp_sock = Rex::Socket::Udp.create(self.) self.listener_thread = Rex::ThreadFactory.spawn("UDPDNSServerListener", false) { monitor_listener } end if self.serve_tcp @tcp_sock = Rex::Socket::TcpServer.create(self.) self.tcp_sock.on_client_data_proc = Proc.new { |cli| on_client_data(cli) } self.tcp_sock.start if !self.serve_udp self.listener_thread = tcp_sock.listener_thread end end self.cache.start if self.start_cache end |
#stop(flush_cache = false) ⇒ Object
Stop the DNS server and cache
253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/rex/proto/dns/server.rb', line 253 def stop(flush_cache = false) ensure_close = [self.udp_sock, self.tcp_sock].compact begin self.listener_thread.kill if self.listener_thread.respond_to?(:kill) self.listener_thread = nil ensure while csock = ensure_close.shift csock.stop if csock.respond_to?(:stop) csock.close unless csock.respond_to?(:close) and csock.closed? end end self.cache.stop(flush_cache) end |
#switchns(ns = []) ⇒ Object
Switch DNS forwarders in resolver with thread safety
207 208 209 210 211 212 213 214 |
# File 'lib/rex/proto/dns/server.rb', line 207 def switchns(ns = []) if ns.respond_to?(:split) ns = [ns] end self.lock.synchronize do self.fwd_res.nameserver = ns end end |