それは、一通の Slack メッセージが始まりでした。
WSL(Ubuntu 18.04) で .local を解決できるようにするのってどうすればいいんですかね
結論
powershell.exe
を WSL 内の bash から呼んでしまえばいい。
$ powershell.exe "Resolve-DnsName raspberrypi.local"
Name Type TTL Section IPAddress
---- ---- --- ------- ---------
raspberrypi.local A 120 Answer 192.168.1.116
環境
Windows 10 Pro
バージョン 1909 (November 2019 Update)
ビルド 18363.535
WSL: Version 1 (WSL2 の足音が聞こえているので明確に 1 としました)
Windows 10 で mDNS (.local アドレス) の名前解決は可能です
mDNSを使ってローカルDNSサーバーを廃止する によると、バージョン 1909(= November 2019 Update)で mDNS 周りの不具合がかなり解消されており、 PowerShell の Resolve-DnsName
や cmd.exe での ping で .local
アドレスが発見できるようになりました。
さて、 WSL1 にインストールした Ubuntu 等の ping
を始めとしたコマンドは、 libresolv.so.2
1 から nsswitch.conf
を経由して 2 名前解決が行われます。
要するに Windows 側の名前解決の仕組みは一切使われません。2016 年から話題になってたみたいですね。 Can't resolve ".local" (mDNS) hosnames
この時 mDNS なアドレスを解決するアプローチは2つあります。
-
libnss-mdns
を入れて Linux 上での名前解決ができるようにする - なんとかして Windows 側で名前解決する
libnss-mdns は討ち死にする
libnss-mdns は avahi-daemon を必要とし、そして avahi-daemon は dbus を必要としますが、 dbus が WSL1 で動きません。討ち死にです。
参考: Need help making mDNS work
Windows 側で名前解決する
今回の TIPS のメインです。
PowerShell の Resolv-DnsName
は Windows 側の名前解決を利用します(するようです)。
WSL の bash といっても所詮 cmd.exe
の代わりに bash.exe
が動いているだけなので、 bash 上で Windows の .exe も実行できちゃいます。
以上のことから powershell.exe
を bash シェルから呼び出すという今回の TIPS が成立したのです。
シェル芸、やりたい放題
PowerShell からの出力は bash の STDOUT に流れてくるため、パイプでつなげたい放題です。
PowerShell からは JSON で出力しつつ jq で受けるといったこともできます。
$ powershell.exe "Resolve-DnsName raspberrypi.local | ConvertTo-Json"
{
"IP4Address": "192.168.1.116",
"Name": "raspberrypi.local",
"Type": 1,
"CharacterSet": 1,
"Section": 1,
"DataLength": 4,
"TTL": 120,
"Address": "192.168.1.116",
"IPAddress": "192.168.1.116",
"QueryType": 1
}
$ powershell.exe "Resolve-DnsName raspberrypi.local | ConvertTo-Json" | jq -r .IPAddress
192.168.1.116
function を定義すればコマンド化も可能です。
nsfind() {
powershell.exe "Resolve-DnsName $1 | ConvertTo-Json" | jq -r .IPAddress
}
$ ssh pi@`nsfind raspberrypi.local`
※ ちょっと微妙な感じですが、とりあえず動く!
注意点
もちろん Windows 10 バージョン 1909 の話です。それ以前の方は、まず Windows 10 を最新にしましょう。話はそれからです。
WSL2 になったら Hyper-V 上の VM になるそうなので、たぶん dbus とか動くから avahi-daemon 経由で mDNS が解決できるような気がする。
あとがき
この方法を見つける前までは
なのでcmd.exeかPowerShellで解決したIPv4 or IPv6アドレスをコピペするという雑な解決方法
こんな事してたんですけど、自分の書込みをみて思ったわけです。「あれ?WSL から powershell 呼べればいいんじゃね?」と。
さて、、、、仕事しよう。暇じゃないよ。
EoT