WSL2でDNSの名前解決ができなくなったときの対処法(Firewallにルールを追加)

# 環境
- Windows11 Home Insider Preview ビルド 22526
- WSL2 Kernel Version 5.10.16
- Ubuntu 20.04

# 問題
WSL2でDNSの名前解決ができなくなる場合がある。
下記に当てはまる場合、WindowsのファイアウォールにWSL2からの通信を許可するルールを追加することにより、解決する場合がある。

下図の「Win32仮想イーサーインターフェース」に対して、Winからは名前問い合わせが成功し、WSL2からは失敗する場合。
![7b9c860c5c1324be.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73626/3bfec423-4d04-3121-9d53-495ab56ee7ca.jpeg)

図は [ASCII\.jp：Windows Subsystem for Linux 2におけるネットワークの改良 \(1/2\)](https://ascii.jp/elem/000/001/909/1909920/) より拝借。

本手順では、/etc/wsl.confの[network]に `generateResolvConf = false` を設定したり、/etc/resolv.confを書き換えることはしない。

まず下記を確認する。
・WSL内から外部のIPアドレス(例：8.8.8.8等)へのpingは通る
・Windowsのコマンドプロンプトから、「イーサネット アダプター vEthernet (WSL)」のIPアドレスへのDNS問い合わせは成功する
・WSL内から「イーサネット アダプター vEthernet (WSL)」へのIPアドレスへのDNS問い合わせが失敗する

# WSL2内から外部のIPアドレスへのpingは通る
```
$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=116 time=6.44 ms
^C
--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 6.443/6.443/6.443/0.000 ms
```
ctrl+cで停止。

# 「イーサネット アダプター vEthernet (WSL)」のIPアドレスを確認
冒頭の図のWin32仮想イーサーインターフェースに該当するIPアドレスを、Windowsのコマンドプロンプトから確認する。

```
> ipconfig
(略)
イーサネット アダプター vEthernet (WSL):

   接続固有の DNS サフィックス . . . . .:
   リンクローカル IPv6 アドレス. . . . .: (略)
   IPv4 アドレス . . . . . . . . . . . .: 172.18.224.1
   サブネット マスク . . . . . . . . . .: 255.255.240.0
   デフォルト ゲートウェイ . . . . . . .:
```

このときは172.18.224.1だった。

# Windowsから「イーサネット アダプター vEthernet (WSL)」のIPアドレスへの名前問い合わせが成功する
コマンドプロンプトからnslookupコマンドでgoogle.comのIPアドレスを問い合わせて、取得成功。

```
>nslookup google.com 172.18.224.1
サーバー:  (略)
Address:  172.18.224.1

権限のない回答:
名前:    google.com
Addresses:  2404:6800:4004:81f::200e
          172.217.175.14
```

# WSL内から「イーサネット アダプター vEthernet (WSL)」のIPアドレスへの名前問い合わせが失敗する
digコマンドでgoogle.comのIPアドレスを問い合わせてみると、time outとなる。

```
$ dig google.com @172.18.224.1

; <<>> DiG 9.16.1-Ubuntu <<>> google.com @172.18.224.1
;; global options: +cmd
;; connection timed out; no servers could be reached
```

同一のIPアドレスへの問い合わせが、Windowsからは成功し、WSLからは失敗するなら、ファイアウォールのルールに弾かれていることが問題の可能性がある。

# 対処法：WindowsのファイアウォールにWSL2からの通信を許可するルールを追加する
1. PowerShellを管理者権限で起動する
2. 下記のコマンドを実行する

```
New-NetFirewallRule -DisplayName "WSL" -Direction Inbound  -InterfaceAlias "vEthernet (WSL)"  -Action Allow
```

# 確認方法
WSLからdigコマンドで確認する。

```
$ dig google.com @172.18.224.1

; <<>> DiG 9.16.1-Ubuntu <<>> google.com @172.18.224.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24653
;; flags: qr rd ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;google.com.                    IN      A

;; ANSWER SECTION:
google.com.             0       IN      A       142.250.199.110

;; Query time: 10 msec
;; SERVER: 172.18.224.1#53(172.18.224.1)
;; WHEN: Mon Jan 10 22:05:21 JST 2022
;; MSG SIZE  rcvd: 54
```

# 参考
[WSL2 DNS stops working · Issue \#4285 · microsoft/WSL](https://github.com/microsoft/WSL/issues/4285)
[Windows Defender Firewall blocks access from WSL2 · Issue \#4139 · microsoft/WSL](https://github.com/microsoft/WSL/issues/4139)
[WSL2 で dns の名前解決ができなくなって ネット接続できなくなった場合の対処方法 - Qiita](https://qiita.com/kkato233/items/1fc71bde5a6d94f1b982)