register host without reverse entry in /etc/avahi/hosts
I'm trying to permanently register a subdomain project.machine.local for my computer in /etc/avahi/hosts. Doing that and restarting avahi-daemon gives me an error in syslog:
avahi-daemon[24327]: Static host name project.machine.local: avahi_server_add_address failure: Local name collision
I can register the name with avahi-publish when giving the --no-reverse option:
$ avahi-publish -a -R project.machine.local 192.168.178.13
Established under name 'project.machine.local'
It would be nice if there was a way to specify this option in the hosts file, too.
Thanks for the request. This has been a commonly desired feature over the years and the reverse DNS issue has caused problems to most approaches as you suggest.
I will look at how to best address this in the next release, either through an alias configuration file option or some other API.
I feel like a most ideal way to do this would be through a special-case service (and thus service file) that created a local hostname alias... to also give programs a way to create such alias hostnames via the API.
its a bit of an abuse of mDNS and almost side-steps DNS -SD but it seems like a commonly desired feature
This would be a useful feature when publishing a docker-machine via Avahi back to your host machine.
i was just here to ask for this :)
the alternative is using this: https://gist.github.com/gdamjan/3168336
but i wouldn't want to keep track of another service
Would love to have this, too, so UBOS could easily publish multiple virtual hostnames as users deploy sites. Creating a separate avahi-publish daemon for each entry is not so great.
Duplicate #109 made note that it would be nice not to have to specify the IP (but perhaps have the option). Should be included in the feature.
https://github.com/lathiat/avahi/issues/40#issuecomment-302860656 specifically to specify a local interface name to get the ip from
i don't mean to be rude but whats the status on this? both the hosts file without reverse lookups and getting ip by interface/all interfaces
i am also having an issue where i can not use the avahi hosts file for addresses but can use the command with no reverse lookups just fine
FWIW I currently just use the following (slightly hacky) service for this:
$ cat /etc/systemd/system/[email protected]
[Unit]
Description=Publish %I.%H.local via mdns
[Service]
Type=simple
ExecStart=/bin/bash -c "/usr/bin/avahi-publish -a -R %I.$(avahi-resolve -4 -n %H.local)"
[Install]
WantedBy=multi-user.target
To enable and start a subdomain test under your published host just:
$ systemctl enable --now [email protected]
Do I understand correctly that this means it is not possible to add host names / ip addresses in /etc/avahi/hosts?
My observation based on testing /etc/avahi/hosts is that if the IP address already has a reverse DNS entry, then another name cannot be associated with it, resulting in the "Local name collision" error. If you use another IP address that has no reverse DNS entry for it, then it works just fine. The avahi-publish is not an option for me because I am using avahi in an embedded system and I don't want to add dbus to the system. This issue is 4 years old now. I am wondering if the alias feature has been implemented, either via the hosts file or via the service file. @lathiat - any comments?
FWIW, I used the following patch to avahi-0.6.31 to work around the "Local name collision" issue with static entries in /etc/avahi/hosts:
Index: avahi-0.6.31/avahi-daemon/static-hosts.c
===================================================================
--- avahi-0.6.31.orig/avahi-daemon/static-hosts.c
+++ avahi-0.6.31/avahi-daemon/static-hosts.c
@@ -138,7 +138,7 @@ static void add_static_host_to_server(St
p = (h->address.proto == AVAHI_PROTO_INET && config->publish_a_on_ipv6) ||
(h->address.proto == AVAHI_PROTO_INET6 && config->publish_aaaa_on_ipv4) ? AVAHI_PROTO_UNSPEC : h->address.proto;
- if ((err = avahi_server_add_address(avahi_server, h->group, AVAHI_IF_UNSPEC, p, 0, h->host, &h->address)) < 0) {
+ if ((err = avahi_server_add_address(avahi_server, h->group, AVAHI_IF_UNSPEC, p, AVAHI_PUBLISH_NO_REVERSE, h->host, &h->address)) < 0) {
avahi_log_error ("Static host name %s: avahi_server_add_address failure: %s", h->host, avahi_strerror(err));
return;
}
It would make sense I guess to add syntax to the avahi hosts file as well as avahi-publish-address to not add the reverse DNS
For anyone wanting to do an alias instead of a subdomain, here's a variant of @mattiasb's approach.
It's very similar, but lets you specify the entire domain name like test.local instead of just a subdomain of the current hostname, like test.hostname.local.
$ cat /etc/systemd/system/[email protected]
[Unit]
Description=Publish %I as alias for %H.local via mdns
[Service]
Type=simple
ExecStart=/bin/bash -c "echo avahi-alias %I $(avahi-resolve -4 -n %H.local > /dev/null && hostname -I | head -1) && /usr/bin/avahi-publish -a -R %I $(avahi-resolve -4 -n %H.local > /dev/null && hostname -I | head -1)"
[Install]
WantedBy=multi-user.target
Then to make the current machine available as test.local in addition to its current hostname.local, you would enable the service with:
systemctl enable --now [email protected]
(Edit: As @viraptor mentioned below, if there is another device publishing the same name, we still want this to register the alias with our local IP address, and not the other device's address. Therefore, this uses hostname -I to get the current IP address. However, there's an annoying startup issue where avahi is not yet available, so the avahi-resolve piped to /dev/null is used to make sure that avahi has already started up before checking the local IP address to provide to avahi-publish. It may be a bit of a hack, but it works in my installations.)
Unfortunately the systemd units above do not solve the issue for multi-homed devices. They will register only one result given by avahi-resolve, which may not be the one you want. (in my case it gets the vpn interface, but I want to publish both that one and a local lan address)
@viraptor Funny you should mention this. I ran across something similar and edited my systemd unit. See edit above.
Too bad /etc/avahi/hosts is unusable right now :cry:
@carter-thaxton Btw. your systemd service fails for me with the following error:
Feb 18 16:00:39 nas bash[17425]: avahi-alias riot.local 192.168.178.2 172.18.0.1 172.17.0.1 192.168.224.1 192.168.240.1 192.168.48.1 192.168.64.1 192.168.96.1 172.22.0.1 172.23.0.1 172.24.0.1 172.25.0.1 2a01:c22:b02b:9100:7285:c2ff:fea8:7caa
Feb 18 16:00:39 nas bash[17425]: Bad number of arguments
FWIW, I fixed my problem by coming up with yet another systemd service definition. The important expression to determine my main IP is ip route get 1 | awk '{print $7;exit}.
In whole:
[Unit]
Description=Publish %I as alias for %H.local via mdns
[Service]
Type=simple
ExecStart=/bin/bash -c "/usr/bin/avahi-publish -a -R %I $(avahi-resolve -4 -n %H.local > /dev/null && ip route get 1 | awk '{print $7;exit}')"
[Install]
WantedBy=multi-user.target
@schildbach It saved me! But your systemd service may fail at startup with the following error:
Feb 29 20:50:14 lcdhrpi systemd[1]: Started Publish gitlcdhpi.local as alias for lcdhrpi.local via mdns.
Feb 29 20:50:20 lcdhrpi bash[327]: Failed to resolve host name 'lcdhrpi.local': Timeout reached
Feb 29 20:50:20 lcdhrpi bash[327]: RTNETLINK answers: Network is unreachable
Feb 29 20:50:20 lcdhrpi bash[327]: Bad number of arguments
It seems the [email protected] must start after avahi-daemon.service. So I modified it as follows
$ cat /etc/systemd/system/[email protected]
[Unit]
Description=Publish %I as alias for %H.local via mdns
Requires=avahi-daemon.service
After=avahi-daemon.service
[Service]
Type=simple
ExecStart=/bin/bash -c "/usr/bin/avahi-publish -a -R %I $(avahi-resolve -4 -n %H.local > /dev/null && ip route get 1 | awk '{print $7;exit}')"
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
Now it starts after avahi-daemon.service and tries to restart several times with a restart interval of 3s
Can someone please summarize the state of this? There's a long history. Will additional hostnames support be added to avahi? If not, is there a principle behind it? If the reason is just lack of a PR, can a maintainer suggest a course of action, like "We probably just need to add a loop in blah.c, but watch out for ...".
Why does avahi-daemon consider the failure of registering a reverse entry as a fatal error? Shouldn't it just fall back to providing forward DNS resolution?
bite by this issue too, I resolved it by enabling "enable-wide-area=yes" and use a local hostname not in ".local" domain and served by dnsmasq, such as "my-airplay.lan".
It's sad that no one solves this problem
Suggestion for a solution:
Traditionally, /etc/hosts entries can look like the following:
192.168.12.34 somehost.canonical.domain some.other.fqdn.domain localalias1 localalias2
Putting such an entry into /etc/avahi/hosts generates an error, though:
Junk on the end of the line!
Perhaps the code could be tweaked to instead tokenize based on whitespace, treat the first entry just exactly as it does now (unless there are other enhancements that seem relevant), but then treat any additional entries as aliases -- i.e. register them as hosts, without registering the reverse mapping for them.
It's possible this could result in unwieldy long lines for anyone who wants many aliases, but for just a few, it should be quite usable. However, given that the current behavior seems to be that multiple identical entries happily tolerated, it could just be that as long as the address and first name are duplicates of an existing entry, that will continue to be tolerated, and and any additional aliases will be added. The redundancy would be a little clunky, but makes for a pretty workable workaround, in my mind.
I hope these thoughts prove helpful. Sorry I don't have cycles to try to submit a patch currently.
There's some repos that get this done. combined with the systemd you can get reloads if the deamon restarts. As the only issue is the format of the hosts file they use, the C binding can be used..
see https://andrewdupont.net/2022/01/27/using-mdns-aliases-within-your-home-network/
The python package he uses looks quite dated but....
ping blog.local
PING main.local (192.168.0.162): 56 data bytes
64 bytes from 192.168.0.162: icmp_seq=0 ttl=64 time=2.409 ms
64 bytes from 192.168.0.162: icmp_seq=1 ttl=64 time=3.682 ms
^C
--- main.local ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 2.409/3.045/3.682/0.637 ms
I found that avahi-publish requires specifying an IP, this is not very practical when you have multiple interfaces.
I wrote a lightweight program that automatically links to the current machine (uses C API - DBus).
https://github.com/grishy/go-avahi-cname
> ./go-avahi-cname git photo.local. example.lab.local.
2023/07/27 08:37:14 Creating publisher
2023/07/27 08:37:14 Formating CNAMEs:
2023/07/27 08:37:14 > 'git.lab.local.' (added current FQDN)
2023/07/27 08:37:14 > 'photo.local.'
2023/07/27 08:37:14 > 'example.lab.local.'
2023/07/27 08:37:14 Publishing every 5m0s and CNAME TTL=600s.
^C
2023/07/27 08:37:16 Closing publisher...
I have a related issue, which I couldn't figure out how to make it working, https://github.com/grishy/go-avahi-cname only works with cnames sharing the same IP address. I have two nic cards with different IPs on a machine, I would like to have different mDNS names, i.e. name1.local for 10.0.0.2, name2.local for 10.0.0.3.
Is this something supported by avahi? Any pointer is appreciated, thanks!
I would like to have different mDNS names, i.e. name1.local for 10.0.0.2, name2.local for 10.0.0.3. Is this something supported by avahi?
It's possible to publish separate names on separate interfaces using the avahi-client/D-Bus API. avahi_entry_group_add_address and AddAddress support the "interface" argument. That being said currently interfaces can't be set explicitly via static host files (or avahi-publish): https://github.com/avahi/avahi/issues/317. (Static service files would probably have to be edited too to point services to the right names (with the <host-name> directive) but interfaces aren't supported there either yet. There was a PR somewhere though). Depending on the use case publish_addresses should probably be set to no to prevent avahi from publishing its "canonical" name on all interfaces.
Too bad
/etc/avahi/hostsis unusable right now 😢
Indeed. Even 4 years later, Fedora ships this file, I add 192.168.11.2 mp3.local and restart the avahi service, and the hostname still fails to resolve, locally or on the network.
avahi-browse -a shows the base host name being advertised as the service is restarted, but not the alias.
Does it work for anyone or should I file a Fedora bug ?
Does it work for anyone or should I file a Fedora bug ?
It isn't implemented yet. It should be possible to file a Fedora bug but it's likely to be forwarded back here. One of the avahi Fedora package maintainers (@pemensik) is here so I think it should be safe to assume that it's known there.