💡

WSLで外のネットワークにアクセスできないときの解決策

2023/12/06に公開
2

概要

  • 「 WSL がインターネットに繋がらない」という曖昧なものを分割し,解決した.
  • この記事でも解決できない可能性を考慮し,問題解決に有効だと考えられる情報を最後にまとめた

背景

私はよく WSL2 を利用している[1]おり,幾度かネットワーク関係が不調になったことがある,
しかし,これらの記事は少ないように思える.[2]そこで,解決策をまとめることにした.

対象読者

  • WSL2 利用者
  • 未来の自分

本論

各問題解決に関する文献は,この記事の最後にまとめて述べている.
また,以降で WSL と表記したときは WSL2 に限定し,Windows は Windows11 を想定する.
さらに,再起動などは全て試行済みだとする.

命名解決に失敗している場合

この場合は,よく見られるもので,原因の解決が簡単かつ情報も豊富である.
外部へアクセスすることはできるが,命名解決に(DNS 関係で)失敗している.
本記事では,WSL側 で問題が起きている(Windows側 は問題ない)場合の解決策を以下の述べる.

この場合の特徴

この場合は,WSL で以下を実行すると,上のコマンドは失敗するが,下のコマンドは成功する という結果が得られる.

wsl
ping google.com
ping 8.8.8.8

PowerShell でも同じコマンドを実行したとき,両行が成功する場合は,WSL側 の問題である.
そうではない場合は,WSL ではなく Windows側 の問題である.

原因

通常 DNSサーバー名を記述したファイルは自動で生成される.
しかし,何らかの理由[3]によりうまく動作していない場合がある.
今回は これが原因だと考え,手動でバインドすることで解決を図る策を次に述べる.
(その為,通常は自動で生成される設定[4]にしておくべきである.)

解決策1

最も簡単な方法である.

/etc/resolv.confの変更

/etc/resolv.confを次の1行に変更する.

/etc/resolv.conf
nameserver 8.8.8.8

これでうまく行かない場合でも,この操作に加えてwsl --shutdownなどの WSL のシャットダウンを行い再起動すると解決することもよくある.

解決策2

前述した解決策1の永続化である.

1./etc/wsl.confへの追記

まず,/etc/wsl.confに次の2行を追記する.

/etc/wsl.conf
[network]
generateResolvConf = false

2.wslの再起動

PowerShellで次のコマンドを実行すると,任意のディストリビューションをシャットダウンできる.

posh
wsl --terminate ディストーション名

その後,いつもの方法で起動する.

3./etc/resolv.confの変更

/etc/resolv.confを次の1行に変更する.

/etc/resolv.conf
nameserver 8.8.8.8

補足1

/etc/wsl.confを変更する前に/etc/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

補足2

systemd-resolved などに書き換えられる場合がある.
このような場合は,

wsl
sudo unlink /etc/resolv.conf

で,シンボリックリンクを削除した上で,resolv.conf を作成し,

wsl
sudo chattr +i /etc/resolv.conf

により,変更を禁止すれば良い.
なお,sudo rm なども制限されるので,変更を加えたい場合は 先程のコマンドの +i-i に変更し,実行すれば良い.

ネットワークのバインドがうまくいかない場合

この場合は,前述の場合とは異なり,ping 8.8.8.8なども失敗する.

原因

通常 WSL 起動時に,WSL側 のネットワークと Windows側 の仮想ネットワークは自動でバインドされる.
しかし,このバインドがうまく動作していない場合がある.
今回は これが原因だと考え,手動でバインドすることで解決を図る策を次に述べる.

解決策1

wsl2上のLinux からインターネットにアクセスできない場合の暫定解決策 – 株式会社シーポイントラボ | 浜松のシステム・RTK-GNSS開発
という記事が参考になる.リンク先がアクセスできなくなる可能性に備え,コマンドは以下に述べておく.

wsl
sudo ip l set eth0 up

解決策2

こちらも同記事が参考になる: wsl2上のLinux からインターネットにアクセスできない場合の暫定解決策

wsl
ip route show | grep -i default | awk '{ print $3}'

の出力結果が172.17.224.1の時,次を実行する(出力結果が異なる場合は自分で数値を書き換える)

wsl
sudo ip address add 172.17.224.10/20 broadcast 172.17.224.255 dev eth0
sudo ip route add default via 172.17.224.1

ネットワークアダプターが不調の場合

この場合は,前々述の場合とは異なり,ping 8.8.8.8なども失敗する.

原因

今回は ネットワークアダプターの不調が原因だと考え,手動で再起動することで解決を図る策を次に述べる.

解決策

管理者権限の付いた PowerShell で以下を実行する.

posh
Restart-Service LxssManager # WSL Service の再起動

Stop-Service -name "hns"    # Host Network Service の停止
Start-Service -name "hns"   # Host Network Service の起動

Get-NetAdapter -IncludeHidden | Where-Object `
    {$_.InterfaceDescription.StartsWith('Hyper-V Virtual Switch Extension Adapter')} `
    | Disable-NetAdapter -Confirm:$False # Hyper-V adapters の再起動
Get-NetAdapter -IncludeHidden | Where-Object `
    {$_.InterfaceDescription.StartsWith('Hyper-V Virtual Switch Extension Adapter')} `
    | Enable-NetAdapter -Confirm:$False  # Hyper-V adapters の再起動

補足

Winキー + iなどで Windows の設定を起動し,
システム > トラブルシューティング > その他のトラブルシューティング > ネットワークとインターネット > Wi-Fi ネットワーク アダプターを再起動します > アダプターを再起動する
からでも再起動できるが,私の環境では効果がなかった場合もあった.


解決できないとき用の記事

コマンド

WSLのローカルIPアドレス

Windows側 から見るので,PowerShell で実行する.仕組みとしては,WSLの既定に設定されたディストーション上で hostname -I を実行しているだけである.(実質WSL側から見ている)

posh
wsl hostname -I

筆者の環境(ディストーションは Arch Linux)で起こったことだが,hostname-I オプションが存在しなかた.
そのような場合,こちらのWindows上で実行した ipconfig の結果を grep していることに相当するコマンドを用いる.

posh
Get-NetIPConfiguration -InterfaceAlias "vEthernet (WSL (Hyper-V firewall))" | Select-Object -Property IPv4Address

なお,WSL側から見たいのであれば,次のコマンドを使用できる.

wsl
cat /etc/resolv.conf

WindowsのローカルIPアドレス

WSL側 から見るので,WSL で実行する.

wsl
ip route show | grep -i default | awk '{ print $3}'

netshコマンドをWindows側で実行し,WinSocketを再起動する方法

いくつかの知見が集まった質問

WSLのバックアップ

WSLの再インストール

Microsoftの記事

Hyper-Vとの関係に関する記事

Windowsのデータを保持して再インストール


参考文献

関連項目: 命名解決に失敗している場合

関連項目: ネットワークのバインドがうまくいかない場合

関連項目: ネットワークアダプターが不調の場合

脚注
  1. zenn に公開している記事からもわかる ↩︎

  2. 私の検索能力が不十分である可能性は否めない ↩︎

  3. Wi-Fi を普段とは異なるものを使用したり,Docker が悪さをしたりなどが考えられる ↩︎

  4. generateResolvConf = trueのこと ↩︎

GitHubで編集を提案

Discussion

mio256mio256

三日三晩悩んでいたので、大変助かりました!!!

hibikihibiki

この記事のおかげでMacユーザーからの迫害を受けなくて済みそうです!

ありがとうございます!!