💡

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

2023/12/06に公開
3

概要

  • 「 WSL がインターネットに繋がらない」の分割と解決
  • 当記事でも解決できない可能性を考慮し,役たちそうな情報を最後にまとめた

背景

  • WSL2 でネットワーク関係の不具合がよくあるが,情報が少なかったため

対象読者

  • WSL2 利用者
  • 未来の自分

本論

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

ネットワークの切り分け

次などを試すことで,原因の切り分けを行う.

  • 別のアクセスポイント
  • 別の接続方法(テザリング,テザリング以外,無線,有線,…)

もし,成功する組み合わせがあるならば,これ以降の情報は役に立たない可能性が高い.

例えば,モバイルデータ通信を利用したテザリングで,
アクセスポイント名設定(APNタイプ)や,モバイル側のDNS設定が不適切な場合など,
これ以降に述べる Windows 機の設定が原因ではない可能性があるということ.

Windows 側の設定

「Windows の機能の有効化または無効化」を起動(コントロール パネル\プログラム\プログラムと機能 から,Windows の検索 から など)し,以下の3つを有効化する.

  • Linux 用 Windows サブシステム
  • Windows ハイパーバイザー プラットフォーム
  • 仮想マシン プラットフォーム

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

外部へアクセスすることはできるが,命名解決に(DNS 関係で)失敗している.
本記事では,WSL側 で問題が起きている(Windows側 は問題ない)場合の解決策を以下の述べる.
その他の場合も検索で出て来やすい不具合である.

この場合の特徴

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

wsl
ping google.com
ping 8.8.8.8

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

原因

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

解決策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


関連文献

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

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

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

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

  2. generateResolvConf = trueのこと ↩︎

GitHubで編集を提案

Discussion

mio256mio256

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

hibikihibiki

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

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

rayfiyorayfiyo

2024年5月30日20時52分現在,5,623回閲覧されているらしい.
この記事は無理だったけど別の方法でうまくできたよ があればぜひコメントに残してもらえると他の人が助かる.
知りたい情報はこんなのだったけどこの記事に載ってなかった という場合もどんな情報がほしいか書いてくれれば(気が向いたら)私が調べるかもしれないし,同じように悩んだ人が産まれたときにコンタクトを取れるきっかけになると思う.
要約: コメントください