DNS周りの問題でインターネット接続が不安定になる出来事があったので、そのトラブルシューティングについてまとめました。

1. 環境

 Windows 10 Home Insider Preview:2004 (ビルド:20201.1000)+ Ubuntsu 20.04

2. 問題

 先日、不意にインターネットに接続できなくなることがありました。Teamsの会議だけはなぜか通信がうまくいっている状態で、それ以外は全端末でネットにアクセスできず。結局1時間ほどしたら治ったため、一時的に解決したと思っていたのですが、その後再び異変が起きました。WSL2上で立ち上げたDockerコンテナ内で、Jupyter Notebookを用いてPythonコードを書いていた際に、「!pip install hoge」を実行したところ、以下のエラーが出ました。

WARNING Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7ff100714b90>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': hoge

 何やら名前解決関係のエラーのようですが、Windows側のインターネット接続はうまくいっていたので、前述の問題とはまた別でLinux周りの設定に原因があるのかと当初は思っていました。「wsl2 internet not working」とかでググってみると、同様の問題に悩まされている人がそれなりにいるようなので、いくつか記事を見ながら次のことを試しました。

3. resolve.confを書き換える

 こちらのissueに書かれている方法を試してみました。が、結果的にうまく行きませんでした。やっていることをざっくりと言うと、WSL2の起動の度に「resolve.conf」が生成、上書きされてしまい、かつその内容では通信がうまくいかないため、これをうまく書き換え、かつ自動生成によって上書きされないようにする、というものでした。一応手順を記載しておきます。

3-1. wsl.confの編集

 次のコマンドを実行して、「wsl.conf」の中身を書き換えます。

$ sudo vim /etc/wsl.conf

 これは後述する「resolv.conf」の中身にあったコメントアウトの通りに内容を書き換えることで、再起動時の「resolv.conf」の上書きを防止します。

 [network]
generateResolvConf = false

3-2. WSL2をシャットダウン&再起動

 cmd上で以下のコマンドを実行し、WSL2をシャットダウンします。

wsl --shutdown

 そして再びWSL2を起動して次に移りましょう。

3-3. resolv.confの場所を確認

$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 29 Jul 21 22:56 /etc/resolv.conf -> ../run/resolvconf/resolv.conf

 場所は「/run/resolvconf/resolv.conf」にあるみたいです。

3-4. resolv.confの中身の確認

$ cat /run/resolvconf/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver x.x.x.x

 「x.x.x.x」は実際に使用するDNSサーバーのアドレスが表示されます。

3-5. resolv.confの中身の編集

 次のコマンドを実行し、

$ sudo vim /run/resolvconf/resolv.conf

 vimを用いて、以下の内容に書き換えます。

# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 8.8.8.8

 vimでも何でも良いのですが、「nameserver x.x.x.x」の部分を「nameserver 8.8.8.8」に書き換えました。ここで、「8.8.8.8」というのはGoogleが無償で提供しているGoogle Public DNS1と呼ばれるDNSサーバーのアドレスで、元々「x.x.x.x」をDNSサーバーとして設定していたものを、Google Public DNSに変えようというのが今回の策です。Google以外にもPublic DNSを提供しているものは、いくつかあるようですので、そちらを使っても大丈夫かとは思います。

 上記の手順で解決した人もいるようでしたが、私の場合はうまくいきませんでした。実際に解決したのは次の手法です。

4. ルーター側のDNSサーバーの設定をPublic DNSに変える

 Linuxからインターネット接続ができない問題が解決できずに放置していたのですが、Windowsやその他端末でもインターネットに接続できなくなる問題が再び発生したため、そもそもLinuxだけの問題ではないと確信しました。そこでルーターのDNSサーバーの設定を上記のGoogle Public DNSに変えたら、見事に解決しました。使用しているルーターに応じてやり方は若干異なりますが、ブラウザにルーターのIPアドレスを入力して、設定画面に移動します。どこかに「DNSサーバーアドレス」を入力するところがあると思いますので、設定を次のものに変えます。

 プライマリー:8.8.8.8
 セカンダリー:8.8.4.4

 これによって、ルーターを介したインターネット接続の際には、Googleから提供されるPublic DNSに問い合わせを行うようになり、無事Linux側からもアクセスできるようになりました。ただし、従来設定ではなぜうまく動作しないのかは原因がわかっていないので、そこは別途調査が必要です。インフラ周りもちゃんと勉強したいですね。とりあえず治りました。