How to implement a local subdomain dns server that is avahi aware?
I've built a mini dns server with twisted that is avahi aware.
What it does is look for request that ends with .local; If it's the url of the host something like {{hostname}}.local
the dns server let the os resolve the adress. If it's something like {{subdomain}}.{{hostname}}.local
the server route it to {{hostname}}.local
.
The feature that brings this program is not clear, it let you play with subdomains easly without having to add each and every subdomain you need to /etc/hosts, and the plus side it support also machine that are in the local network and have also avahi dnsconfd server running.
here is the code:
edit: now the开发者_开发百科 server returns a A answer with the correct ip
import socket
from twisted.internet import reactor
from twisted.names import dns
from twisted.names import client, server
hostname = socket.gethostbyaddr(socket.gethostname())[0]
magic_number = + 5 + 1 + len(hostname)
class Resolver(client.Resolver):
def lookupAddress(self, name, timeout = None):
if name.endswith('.local'):
local_name = name[-magic_number:]
ip = reactor.resolve(local_name)
if local_name == name:
ip = reactor.resolve(local_name)
def answer(adress):
a = dns.RRHeader(name=name, ttl=0)
payload = dns.Record_A(adress)
a.payload = payload
return ([a], [], [])
d = ip.addCallback(answer)
return d
else:
def answer(adress):
a = dns.RRHeader(name=name, type=dns.A, ttl=10)
payload = dns.Record_A(adress, ttl=10)
a.payload = payload
return ([a], [], [])
d = ip.addCallback(answer)
return d
else:
return self._lookup(name, dns.IN, dns.A, timeout)
resolver = Resolver(servers=[('212.27.40.241', 53)])
factory = server.DNSServerFactory(clients=[resolver])
protocol = dns.DNSDatagramProtocol(factory)
reactor.listenUDP(53, protocol)
reactor.listenTCP(53, factory)
reactor.run()
I have done some tests with dig and everything looks like good. My hostname is tachtev
.
here is the output of dig www.tachtev.local
; <<>> DiG 9.7.3 <<>> www.tachtev.local
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12794
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;www.tachtev.local. IN A
;; ANSWER SECTION:
www.tachtev.local. 500 IN CNAME tachtev.local.
;; Query time: 2 msec
;; SERVER: 192.168.0.6#53(192.168.0.6)
;; WHEN: Sun Jun 26 15:51:41 2011
;; MSG SIZE rcvd: 49
here is the output of nslookup
root@tachtev:~# nslookup -debug www.tachtev.local
Server: 127.0.0.1
Address: 127.0.0.1#53
------------
QUESTIONS:
www.tachtev.local, type = A, class = IN
ANSWERS:
-> www.tachtev.local
internet address = 192.168.0.4
ttl = 10
AUTHORITY RECORDS:
ADDITIONAL RECORDS:
------------
Non-authoritative answer:
Name: www.tachtev.local
Address: 192.168.0.4
Everything looks good when I dig the urls. But now when I try to curl www.tachtev.local I get a host not found error.
Where does the error come from ?
edit: dependencies : avahi + avahi-dnsconfd + twisted + twisted names (which can not be pip'ed) edit: I did not find solution, but there is a software that does what I want to achieve http://pow.cx/
Client OSes use something called a stub resolver. Stub resolvers expect that their DNS server will be a full-blown recursive resolver, and supply them a full-formed answer.
CNAME replies to a stub resolver must include the target of the CNAME; that is, you must include the A record in the DNS payload as well as the CNAME.
精彩评论