AvahiもResponderも要らない。そう、systemdならね


このフレーズはAppleのCMに使われていないらしいですね。

TL;DR

systemd-networkd&systemd-resolvedなマシンにこいつを置いてみろ:

/etc/systemd/dnssd/ssh.dnssd
[Service]
Name=%H ssh daemon
Type=_ssh._tcp
Port=22

詳しくはman 5 systemd.dnssd。以上終わり!

詳説

systemd-resolved(8)がmDNSだけではなくDNS-SDも吹けるようになりましたNEWSによれば、version 236にて

systemd-resolved's gained support for registering DNS-SD services on the local network using MulticastDNS. Services may either be registered by dropping in a .dnssd file in /etc/systemd/dnssd/ (or the same dir below /run, /usr/lib), or through its D-Bus API.

とあるのでこれ以降のバージョンであればおそらく使えます。

さて、注意深いあなたは/etc/systemd/dnssd/に突撃する前にsystemd-networkd(8)の設定を確認しましょう。目的のネットワークを構成するユニットファイルにMulticastDNS=trueをセットし、systemd-networkdを再起動させてください。すでに有効になっていればそのままでOKです。

なお、この時注意する必要があるのはIPv6環境でカスタムカーネルを用いている人はsystemd-networkdをリスタートするとリンクローカルアドレスでしかアクセスできなくなる危険があることです。これはカーネルコンフィグでCONFIG_IPV6_MULTIPLE_TABLESNになっているとICMPv6 Router Solicitationの送信に失敗するという問題らしく、(それが本質的解決かどうかはさておき)こいつを有効にしてカーネルをリビルドすれば問題は起きなくなります。

上記の例では、SSHサーバを手動設定するファイルを設置しています。サービスタイプについては公式リストを参照して記述しましょう。追加の説明書きとかを一緒に配りたい場合は、ポート番号の次にTxtText=説明書きと付けてあげればこれも一緒に吹きます。2バイト文字も行けるはず。ちなみにmanpageではTxtData=データ名=base64エンコードした文字列なるデータ貼付法も書かれていますが、例えばアイコン配ったらホスト一覧画面で使ってくれる仕組みとかどっかにあるんでしょうかね。

なお、例に登場した%Hはsystemd.unit(5)で使える、自マシンのホストネームを表す表現ですが誤って%hと書くと"Invalid slot."という謎のエラーが出るので確実に大文字としましょう。私はこれのために半年くらいフイにしました

というわけでGoodbye, Avahi!

まあデーモン同士で直接連携する仕組みとかはまだまだ追いつかないようですから、ユニットファイルの手書きを強いられるのは仕方ないところですが。
今後のNetatalkとかSambaとかがD-Bus経由でサクッと吹くようになることを期待しましょう。