如何使用mDNS将所有子域路由到单个主机?

Joh*_*Mee 22 mdns bonjour zeroconf

我有一个开发网络服务器托管为"myhost.local",使用Bonjour/mDNS.服务器正在运行avahi-daemon.

网络服务器也想处理自己的任何子域.例如"cat.myhost.local"和"dog.myhost.local"和"guppy.myhost.local".

鉴于myhost.local位于dhcp的动态ip地址上,是否还有办法将子域的所有请求路由到myhost.local?

我开始认为目前不可能......

http://marc.info/?l=freedesktop-avahi&m=119561596630960&w=2

您可以使用/ etc/avahi/hosts文件执行此操作.或者,您可以
使用avahi-publish-host-name.

不,他不行.因为他想要定义一个别名,而不是一个新的主机名.即他只想注册A RR,没有反向PTR RR.但是如果你在/ etc/avahi/hosts中粘贴了一些内容,那么它会注册两者,如果PTR RR是非唯一的,则检测到冲突,这就是别名的情况.

air*_*nix 12

我已经分配给这项任务的时间很少,我已尽力解决了这个问题.

但不幸的是,我不认为avahi/msdns/bonjour的windows实现支持别名(如果我错误地解释了如何支持这个问题,请纠正我).

我做的是从avahi网站上提供的示例python脚本开始:

创建 : /usr/bin/avahi-announce-alias

使其可执行并填写

#! /usr/bin/env python
# avahi-alias.py

import avahi, dbus
from encodings.idna import ToASCII

# Got these from /usr/include/avahi-common/defs.h
CLASS_IN = 0x01
TYPE_CNAME = 0x05

TTL = 60

def publish_cname(cname):
    bus = dbus.SystemBus()
    server = dbus.Interface(bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER),
            avahi.DBUS_INTERFACE_SERVER)
    group = dbus.Interface(bus.get_object(avahi.DBUS_NAME, server.EntryGroupNew()),
            avahi.DBUS_INTERFACE_ENTRY_GROUP)

    rdata = createRR(server.GetHostNameFqdn())
    cname = encode_dns(cname)

    group.AddRecord(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, dbus.UInt32(0),
        cname, CLASS_IN, TYPE_CNAME, TTL, rdata)
    group.Commit()


def encode_dns(name):
    out = []
    for part in name.split('.'):
        if len(part) == 0: continue
        out.append(ToASCII(part))
    return '.'.join(out)

def createRR(name):
    out = []
    for part in name.split('.'):
        if len(part) == 0: continue
        out.append(chr(len(part)))
        out.append(ToASCII(part))
    out.append('\0')
    return ''.join(out)

if __name__ == '__main__':
    import time, sys, locale
    for each in sys.argv[1:]:
        name = unicode(each, locale.getpreferredencoding())
        publish_cname(name)
    try:
        # Just loop forever
        while 1: time.sleep(60)
    except KeyboardInterrupt:
        print "Exiting"
Run Code Online (Sandbox Code Playgroud)

此脚本处理每个别名的公告,并将一直运行,直到您将其终止.(因此,我们需要创建另一个脚本,我在下面显示)

创建文本文件 /etc/avahi/aliases

我们用它来为每台机器存储一个别名

创建目录 /etc/avahi/aliases.d/

我还没有在我现在展示的任何脚本中使用过这个,但对于那些有进取心的人来说,你可以看到需要做什么.

这个想法是你可以将别名分组到单独的文本文件中(当你在apache中处理虚拟主机时更有意义),这是*nix上已经提供的许多守护程序应用程序(apache和apt只是两个例子).

创建 /usr/bin/avahi-announce-aliases

使其可执行并填写

#!/usr/bin/env python

import os, sys
from subprocess import Popen


def ensure_file (path):
    """
        Looks for  file at provided path, creates it if it does not exist.
        Returns the file.
    """
    rfile = None    
    if not os.path.exists(path) and os.path.isfile(path) :
        rfile = open(path,"w+");
        print("ensuring file : %s " % path)

    print("file ensured : %s " % path)
    return rfile


command = '/usr/bin/avahi-announce-alias'
alias_pid_path = "/tmp/avahi-aliases.pid"
alias_file_path = "/etc/avahi/aliases"

alias_file = open(alias_file_path)
if not os.path.exists(alias_pid_path) :
    open(alias_pid_path,"w").close()

alias_pid = open(alias_pid_path,"r")


for line in alias_pid :
    txt = line.strip('\n')
    if len(txt) > 0 :
        print("kill %s" % txt )
        os.system("kill %s" % txt)          
alias_pid.close()
alias_pid = open(alias_pid_path,"w+")

for line in alias_file :
    txt = line.strip('\n')
    if len(txt) > 0 :
        print("publishing : << %s >>" % txt)
        process = Popen([command, txt])
        alias_pid.write("%s\n" % str(process.pid))    
alias_pid.close()

print("done")
Run Code Online (Sandbox Code Playgroud)

它绝不意味着成为python编程的巅峰之作,所以请随意在您认为合适的地方进行改进.

用法

如果我们的主机名是"server"并且avahi-hostname是"server.local",那么我们可以/etc/avahi/aliases用你的额外主机名填充文本文件,如下所示:

deluge.server.local
username.server.local
accounts.server.local
something-else.server.local
another.hostname.home
Run Code Online (Sandbox Code Playgroud)

(但实际上,我很确定你可以在那里有任何主机名,只要你确定它在网络上不存在,这就是为什么我只创建普通avahi主机名的'子域')

然后我们运行:

sudo avahi-publish-aliases

我设置这个的主要原因是为了便于在我的笔记本电脑上模拟django和drupal网站开发.

注意事项

我唯一的失望是,Bonjour/Avahi的Windows实现不支持此实现宣布的别名,它只会看到通常宣布的主要avahi主机名(即上面示例中的server.local).


Joh*_*Mee 5

我当时认为不可能,就放弃了,从那以后我就没有再考虑过这个问题。

我当前的解决方案是费力地将每个感兴趣的子域添加到本地计算机上的主机文件中。

  • 如果您只想让它在 localhost 上工作,您可以在 localhost 上运行普通的 dns 服务器。例如 dnsmasq,使用此设置:address=/loc/127.0.0.1 将以 127.0.0.1 回复 x.loc 和 xyloc 等。如果您将 dnsmasq 设置为使用一些全局可用的名称服务器(例如 google 的),您可以将 /etc/resolv.conf 设置为 localhost (dnsmasq) 并使用 chattr +i /etc/resolv.conf 来阻止 dhcp/whatever 修改 /etc/resolv.conf。 (3认同)

Rob*_*ger 5

看起来像airtonix实现了这一点,并在https://github.com/airtonix/avahi-aliases上提供

我在Ubuntu 11.04上测试过的最近更新的fork是https://github.com/hmalphettes/avahi-aliases