この記事を作った動機

 LinuxクライアントからWindows側にRDP接続などをするとき、いちいちIPアドレスを直接入力しているのは気持ち悪いと思っていた。今まではそれでいいやと放置していたが、最近いい加減どうにかしようということで、具体的な解決を試みようと思って、案の定手間取ったので記録する。

 具体的には、mDNSを使って、Linuxクライアント側から、WindowsクライアントのプライベートIPアドレスを割り出したいということをしていた。基本的には以下のポイントがあった。

  • ファイアウォールの設定で、mDNSを受け付けるようになっているか?
  • Linuxクライアントに必要なパッケージがインストールされ、必要なデーモンが動いているか?
  • 接続先対象としてのWindows側のホスト名は間違っていないか?
  • Linux側から名前解決を試みるとき、.localのTLDをつけ忘れていないか?

環境

 前提としては、個人的なLAN内での利用を想定している。今回は、パブリックネットワーク向けのセキュリティー重視という観点では書いていない。

 また重要な前提として、接続先と接続元は、同じプライベートネットワークに属していることとする。

接続先 (Windows)

  • Windows 11 24H2 を使っている

接続元 (Linux)

  • NetworkManger を使っている
  • systemd-resolved を使っていない、無効にしている
  • GNOME 環境
  • arch linux 環境

仮定

 今回は説明のために以下の仮定をしている。Linux側に関しては、/etc/hostnameにすでに適切なホスト名が設定されているという前提である。

Windows側

  • ホスト名:
    WinHost
  • IPアドレス
    192.168.1.33

Linux側

  • ホスト名:
    LinuxHost
  • IPアドレス
    192.168.1.55

設定手順

Windows側 (接続される側、mDNSで名前解決される側)

ファイアウォールの設定を確認する

 今回はmDNSだけでなく、そもそも接続されているか確認するために、pingも通るように設定する。

Win-ファイアウォール設定例-mDNS
Win-ファイアウォール設定例-PING

ネットワーク探索が無効になっていないか確認する

Win-共有設定

Linux側 (接続を試みる側、mDNSで名前解決をしようとする側)

パッケージのインストール

yay -S avahi nss-mdns
# pacman -S avahi nss-mdns

デーモンの有効化

sudo systemctl enable --now avahi-daemon.service

/etc/nsswitch.confを設定する

 以下はAvahi - ArchWikiを参考に設定した一部の例である。今回は IPv4 を対象として、mdns4_minimalを指定した。試してはいないが、mdns_minimalmdnsmdns6_minimal(IPv6)としても、Avahi - ArchWikiを見る限り設定できる模様である。

...
hosts: mymachines mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] files myhostname dns wins
...

mDNS をファイアウォールから許可する

 今回は検証のために逆方向からも mDNS で名前解決するテストを行ったため、ポートを開ける。

# 必要であれば、--zone=[ゾーン名] も指定すること
sudo firewall-cmd --add-service=mdns
sudo firewall-cmd --add-service=mdns --permanent

mDNSの動作確認

 異なるホスト間だけではなく、動作確認として、LinuxHost -> LinuxHost や WinHost -> WinHost 間といった同じホスト間でもテストしてみると良いと思われる。また、異なるホスト間において、そもそもpingコマンドで疎通が取れるかも確認すると良いと思われる。

LinuxHost -> WinHost

  • 成功例
avahi-resolve -4 -n WinHost.local
# WinHost.local	192.168.1.33

ping WinHost.local
# PING WinHost.local (192.168.1.33) 56(84) bytes of data.
# 64 bytes from 192.168.1.33: icmp_seq=1 ttl=128 time=1.85 ms
# 64 bytes from 192.168.1.33: icmp_seq=2 ttl=128 time=1.62 ms
# ^C
# --- WinHost.local ping statistics ---
# 2 packets transmitted, 2 received, 0% packet loss, time 1001ms
# rtt min/avg/max/mdev = 1.617/1.734/1.852/0.117 ms
  • 失敗例
avahi-resolve -4 -n WinHost.local
# Failed to resolve host name 'WinHost.local': Timeout reached

ping -4 WinHost.local
# ping: WinHost.local: Name or service not known

WinHost -> LinuxHost

  • 成功例
Resolve-DnsName -Name LinuxHost -Type ALL

# Name                                    Type   TTL   Section    IPAddress
# ----                                    ----   ---   -------    ---------
# LinuxHost.local                         AAAA   120   Answer     xxxx::xxxx:xxxx:xxxx:xxxx
# LinuxHost.local                         A      120   Answer     192.168.1.55

ping LinuxHost -4

# LinuxHost.local [192.168.1.55]に ping を送信しています 32 バイトのデータ:
# 192.168.1.55 からの応答: バイト数 =32 時間 =1ms TTL=64
# 192.168.1.55 からの応答: バイト数 =32 時間 =1ms TTL=64
# 
# 192.168.1.55 の ping 統計:
#     パケット数: 送信 = 2、受信 = 2、損失 = 0 (0% の損失)、
# ラウンド トリップの概算時間 (ミリ秒):
#     最小 = 1ms、最大 = 1ms、平均 = 1ms
# Ctrl+C
  • 失敗例
Resolve-DnsName -Name LinuxHost -Type ALL
# Resolve-DnsName : LinuxHost : ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。
# 発生場所 行:1 文字:1
# + Resolve-DnsName -Name LinuxHost -Type ALL
# + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#     + CategoryInfo          : ResourceUnavailable: (LinuxHost:String) [Resolve-DnsName], Win32Exception
#     + FullyQualifiedErrorId : ERROR_INVALID_NAME,Microsoft.DnsClient.Commands.ResolveDnsName

ping LinuxHost -4
# ping 要求ではホスト LinuxHost が見つかりませんでした。ホスト名を確認してもう一度実行してください。

躓いたところ

 今回私が作業するにあたって引っかかり記録に残したいことについては、以下に記録することにする。

avahi-resolveでは名前解決できるのに、pingできない

 nss-mdnsがインストールされていない場合に、以下のようなエラーになった。/etc/nsswitch.confで、hostsの項目にmdns4_minimalを含めたにもかかわらず、名前解決に失敗する。

ping -4 A.local
# ping: A.local: System error

 私の場合は、nss-mdnsをインストールすることで解決されたように思われる。

yay -S nss-mdns
# pacman -S nss-mdns

参考にしたサイトとか