Как реализовать локальный субдомен DNS-сервер, который знает avahi? - PullRequest
2 голосов
/ 26 июня 2011

Я построил мини-сервер DNS с витой, которая знает avahi.

Что он делает, так это ищет запрос, заканчивающийся на .local; Если это URL-адрес хоста, например, {{hostname}}.local, то сервер DNS разрешает ОС разрешать адрес. Если это что-то вроде {{subdomain}}.{{hostname}}.local, сервер перенаправляет его на {{hostname}}.local.

Функция, которая приносит эту программу, не ясна, она позволяет вам легко играть с поддоменами, не добавляя каждый субдомен, который вам нужен, в / etc / hosts, а плюс он также поддерживает машину, находящуюся в локальной сети. а также работает сервер avahi dnsconfd.

вот код:

edit: теперь сервер возвращает ответ A с правильным 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()

Я провел несколько тестов с копанием, и все выглядит хорошо. Мое имя хоста tachtev.

вот вывод копания 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

здесь вывод 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

Все выглядит хорошо, когда я копаю URL. Но теперь, когда я пытаюсь свернуться www.tachtev.local, я получаю сообщение об ошибке «Хост не найден».

Откуда берется ошибка?

edit: зависимости: avahi + avahi-dnsconfd + скрученные + скрученные имена (которые не могут быть переданы по конвейеру) редактировать: я не нашел решения, но есть программное обеспечение, которое делает то, что я хочу достичь http://pow.cx/

1 Ответ

1 голос
/ 27 июня 2011

Клиентские ОС используют так называемый преобразователь заглушек. Решатели-заглушки ожидают, что их DNS-сервер будет полноценным рекурсивным преобразователем, и предоставят им полный ответ.

Ответы CNAME для обработчика заглушки должны содержать цель CNAME; то есть вы должны включить запись A в полезную нагрузку DNS, а также CNAME.

...