エラーの内容
WSL2のターミナルを開き、パッケージのインストールやリポジトリのクローンを試みると、以下のエラーが表示されます:
Temporary failure in name resolution
2つの簡単なテストで原因を素早く絞り込めます:
$ ping google.com
ping: google.com: Temporary failure in name resolution
$ 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=113 time=11.4 ms
IP接続は機能しています。ドメイン解決ができていません。これはネットワーク全体の障害ではなく、DNSの問題です。
発生原因
WSL2は独自の仮想ネットワークアダプターを持つHyper-V VM内で動作しています。起動時に、WindowsホストゲートウェイをDNSサーバーとして指定する/etc/resolv.confを自動生成します。通常の状態では機能しますが、以下の場合に壊れます:
- VPNクライアント(Cisco AnyConnect、OpenVPN、WireGuard)がルーティングテーブルを変更し、ゲートウェイに到達できなくなった場合
- Windows FirewallがWSL2仮想アダプターからのトラフィックをブロックしている場合
- 自動生成された
resolv.confが古いアドレスや誤ったアドレスを指している場合 resolv.confを手動で編集したが、WSL2が次回の再起動時に上書きしてしまう場合
デバッグ手順
ステップ1:現在のDNS設定を確認する
cat /etc/resolv.conf
おそらく以下のような内容が表示されます:
# このファイルはWSLによって自動生成されました。
# [network]
# generateResolvConf = false
nameserver 172.31.16.1
この172.x.x.xアドレスはWindowsホストゲートウェイです。これに到達できない場合、すべてのDNSルックアップが失敗します。
ステップ2:ネームサーバーが応答するか確認する
nc -zv $(grep nameserver /etc/resolv.conf | awk '{print $2}') 53
タイムアウトする場合、WSL2の内部からネームサーバーに到達できない状態です。これが根本原因です。
修正1:DNSを即座に上書きする(動作確認用)
壊れたネームサーバーをパブリックDNSサーバーに置き換えます:
sudo rm /etc/resolv.conf
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
すぐにテストします:
nslookup github.com
nslookupが結果を返せば、DNSが問題だったことが確認できます。ただし、WSL2を再起動するとresolv.confが再生成されて変更が消えてしまいます。恒久的な解決策は修正2を参照してください。
修正2:DNSの恒久的な上書き(推奨)
自動生成を無効にして設定ファイルを固定します。
ステップ1: /etc/wsl.confを編集します:
sudo nano /etc/wsl.conf
以下を追加します:
[network]
generateResolvConf = false
ステップ2: WSLが作成したシンボリックリンクを削除し、実際のファイルに置き換えます:
sudo unlink /etc/resolv.conf
echo -e "nameserver 8.8.8.8\nnameserver 1.1.1.1" | sudo tee /etc/resolv.conf
ステップ3: ファイルをロックして上書きされないようにします:
sudo chattr +i /etc/resolv.conf
ステップ4: PowerShellからWSLを再起動します。ターミナルを閉じるだけでは不十分です:
wsl --shutdown
WSLターミナルを再度開き、修正が維持されているか確認します:
cat /etc/resolv.conf
nslookup github.com
修正3:VPNがWSL2のルーティングを壊している場合
VPNクライアントはルーティングテーブルを乗っ取り、WSL2のホストへのネットワーク経路を切断することがよくあります。Windows上の**PowerShell(管理者)**から実行します:
# WSL仮想アダプターでフォワーディングを有効化する
Get-NetIPInterface | Where-Object {
$_.InterfaceAlias -like '*WSL*'
} | Set-NetIPInterface -Forwarding Enabled
# WSLトラフィックが優先されるようにメトリックを下げる
Set-NetIPInterface -InterfaceAlias "vEthernet (WSL)" -InterfaceMetric 1
その後、WSLをシャットダウンして再起動します:
wsl --shutdown
特にCisco AnyConnectは、再接続するたびにこれらの設定を元に戻します。その場合は、VPNセッションのたびに上記のコマンドを実行するか、ネットワーク変更時に起動するスケジュールタスクにまとめてください。
修正4:Windows FirewallがDNSをブロックしている場合
これまでの方法で解決しない場合、Windows FirewallがWSL2サブネットからのUDP/TCPポート53パケットを破棄している可能性があります。**PowerShell(管理者)**から明示的な許可ルールを追加します:
New-NetFirewallRule -DisplayName "WSL2 DNS UDP" `
-Direction Inbound `
-InterfaceAlias "vEthernet (WSL)" `
-Action Allow -Protocol UDP -LocalPort 53
New-NetFirewallRule -DisplayName "WSL2 DNS TCP" `
-Direction Inbound `
-InterfaceAlias "vEthernet (WSL)" `
-Action Allow -Protocol TCP -LocalPort 53
修正の確認
# DNSの名前解決を確認する
nslookup github.com
# HTTPSのエンドツーエンド接続を確認する
curl -s -o /dev/null -w "%{http_code}" https://google.com
# パッケージマネージャーの完全テスト
sudo apt update
apt updateがエラーなく完了すれば、完全に修正されています。
補足情報
WSL2は仮想サブネット(通常172.16.0.0/12の範囲)上で動作しています。VPNのサブネット競合は、このエラーの隠れた原因としてよくあります。VPNが重複するCIDRブロックを取得し、WSL2のトラフィックがDNSのないデッドエンドにルーティングされてしまいます。2つのCIDR範囲が重複しているかどうかをすばやく確認するために、ToolCraftのサブネット計算ツールを使っています。デバッグ作業での試行錯誤を大幅に減らすことができます。
学んだこと
- IPのpingは成功するがドメインのpingが失敗する場合は、必ずDNSの問題です。ネームサーバーが問題なのにTCP/IPのデバッグに時間を費やさないようにしましょう。
- VPNを定期的に使用する場合は、
/etc/wsl.confにgenerateResolvConf = falseを事前に設定しておきましょう。問題を根本から防ぐことができます。 chattr +iフラグは、wsl.confだけでは効かない場合にWSL2がresolv.confを再生成するのを防ぐ、シンプルで確実な方法です。- ネットワーク設定を変更したあとは、必ずPowerShellから
wsl --shutdownでWSLを再起動してください。ターミナルウィンドウを閉じるだけではWSL2 VMは停止しません。

