开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜