我已经用分配给此任务的少量时间尽可能地解决了这个问题。
但不幸的是,我认为 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)。