28

我有一个开发网络服务器托管为“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 不唯一时检测到冲突,这就是别名的情况。

4

5 回答 5

13

我已经用分配给此任务的少量时间尽可能地解决了这个问题。

但不幸的是,我认为 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"

此脚本处理每个别名的公告,并将一直运行直到您将其杀死。(因此,我们需要创建另一个脚本,如下所示)

创建文本文件/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")

它绝不是 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

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

然后我们运行:

sudo avahi-publish-aliases

我设置它的主要原因是为了便于在我的笔记本电脑上更轻松地模拟 django 和 drupal 网站开发。

注意事项

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

于 2010-10-09T08:05:15.197 回答
5

我当时因为不可能而放弃了它,从那以后我就再也没有重新审视过这个问题。

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

于 2010-03-14T01:01:40.730 回答
5

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

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

于 2011-12-31T01:02:48.633 回答
4

您可以使用 Avahi API 注册其他记录。Avahi wiki 上的此示例演示了如何在 Python 中发布其他 CNAME(别名)记录。

于 2009-05-10T04:15:42.860 回答
0

我知道这很旧,但更好的解决方案是dnsmasq

这可以简单地完成......通过参数/配置......

返回指定域中所有主机的 ipaddr。

-A, --address=/<domain>/<ipaddr>

address=/yourdomain.com/10.0.1.100

瞧!

于 2015-02-02T11:44:57.190 回答