はじめに (対象読者・この記事でわかること)
この記事は、Hyper‑V、VirtualBox、VMware などの仮想化環境を日常的に利用しているエンジニアや、IT管理者を対象としています。特に、ノートPC でホスト OS をスリープさせたあと、ゲスト OS の DNS 解決が失敗し、外部ネットワークに接続できなくなる事象に遭遇した方が対象です。本記事を読むことで、次のことが理解・実践できるようになります。
- スリープ復帰時に発生するネットワークスタックの状態変化とその影響
- ゲスト OS が名前解決に失敗する典型的な原因(NIC のリンク状態、DHCP リース、ホスト側の DNS キャッシュ)
- 具体的なトラブルシューティング手順と、永続的に問題を回避する設定方法
読者はこの記事を通じて、同様の障害が起きた際に迅速に原因を特定し、恒久的な対策を講じることができるようになります。
前提知識
この記事を読み進める上で、以下の知識があるとスムーズです。
- 基本的な Linux/Windows のネットワークコマンド(
ipconfig,ifconfig,nslookup,digなど) - 仮想マシンのネットワークアダプタ設定(NAT、ブリッジ、ホストオンリー)
- DHCP と DNS の基本的な仕組み
背景と概要:スリープ復帰で起きる DNS 解決失敗
ノートPC でホスト OS(Windows 10/11、macOS、Linux)をスリープさせると、物理 NIC が一時的に電源オフ状態になります。スリープから復帰すると、NIC のリンクが再度有効化されますが、仮想化ソフトウェア側の仮想 NIC(vNIC)は「リンクは復帰したが、IP 設定や DNS キャッシュが古い」状態になることがあります。この不整合が原因で、ゲスト OS 内部の DNS クエリが失敗し、ping や curl が名前解決できなくなるケースが報告されています。
主な原因は次の通りです。
-
ホスト側の DNS キャッシュがクリアされない
Windows のipconfig /flushdnsや macOS のdscacheutil -flushcacheがスリープ復帰時に自動実行されないため、古い DNS エントリが残ります。 -
DHCP リースの有効期限切れ
スリープ中に DHCP リースが期限切れになると、ゲストは古い IP アドレスを保持したまま DNS サーバへ問い合わせを行い、応答が返らないことがあります。 -
仮想 NIC のリンクステータス不整合
VirtualBox/VMware では、ホストの物理リンクが復帰した瞬間に仮想 NIC が「リンク down」状態になることがあり、OS が自動的に再取得しません。 -
ネットワークサービスの自動再起動が無効
Linux 系ゲストではsystemd-resolvedやNetworkManagerがスリープ復帰時に再起動しない設定になっていると、キャッシュだけが残り問題が顕在化します。
これらの要因が複合的に作用し、ゲスト OS の名前解決が失敗する「スリープ復帰 DNS フリーズ」現象が発生します。本セクションでは、これらの根本原因を把握したうえで、実際にどのように対処すべきかを説明します。
実践的な対策と手順
以下では、VirtualBox と VMware の代表的な仮想化環境を対象に、スリープ復帰後に DNS が機能しない問題を根本から解決する手順を示します。手順は OS が Windows でも Linux でも共通して適用できる部分がありますが、個別のコマンドや設定ファイルは環境に応じて調整してください。
ステップ 1:ホスト側の DNS キャッシュと NIC のリセット
-
Windows ホスト
cmd ipconfig /flushdns netsh interface set interface "Wi-Fi" admin=disable netsh interface set interface "Wi-Fi" admin=enable
Wi-Fiなど使用中のインターフェース名はnetsh interface show interfaceで確認してください。 -
macOS ホスト
bash sudo dscacheutil -flushcache sudo killall -HUP mDNSResponder networksetup -setnetworkserviceenabled Wi-Fi off networksetup -setnetworkserviceenabled Wi-Fi on -
Linux ホスト (systemd ネットワーク)
bash sudo systemd-resolve --flush-caches sudo systemctl restart NetworkManager
上記コマンドはスリープ復帰時に自動実行させることが望ましいです。Windows の場合はタスクスケジューラ、macOS は launchd、Linux は systemd の sleep.target にフックして実行します。
ステップ 2:ゲスト側の DHCP リース更新と DNS サービス再起動
Windows ゲスト
Cmdipconfig /release ipconfig /renew ipconfig /flushdns net stop "Dnscache" net start "Dnscache"
Linux ゲスト(Ubuntu/Debian 系)
Bashsudo dhclient -r && sudo dhclient sudo systemctl restart systemd-resolved sudo resolvectl flush-caches
Linux ゲスト(RedHat/CentOS 系)
Bashsudo dhclient -r && sudo dhclient sudo systemctl restart NetworkManager sudo systemd-resolve --flush-caches
上記手順は、スリープ復帰時に自動化することがポイントです。Linux では systemd ユニットを作成し、sleep.target の After= にフックして実行します。
Ini# /etc/systemd/system/guest-wakeup-resolver.service [Unit] Description=Refresh DHCP and DNS after host wakeup After=suspend.target [Service] Type=oneshot ExecStart=/usr/local/sbin/wakeup-dns-fix.sh [Install] WantedBy=suspend.target
wakeup-dns-fix.sh に上記の DHCP/DNS 再起動コマンドを書き込み、systemctl enable guest-wakeup-resolver.service で有効化します。
ステップ 3:仮想 NIC の自動リンク再取得設定
VirtualBox
VirtualBox の場合、VBoxManage コマンドでネットワークアダプタの「リンク状態」を強制的に再取得させます。
BashVBoxManage controlvm "VM_Name" nic1 disconnect VBoxManage controlvm "VM_Name" nic1 connect
上記はスリープ復帰後にホスト側から実行できます。自動化は PowerShell スクリプトで以下のように書きます。
Powershell$vm = "MyUbuntuVM" VBoxManage controlvm $vm nic1 disconnect Start-Sleep -Seconds 2 VBoxManage controlvm $vm nic1 connect
VMware Workstation
VMware では vmrun コマンドを使用します。
Bashvmrun -T ws stopVM "/path/to/VM.vmx" soft vmrun -T ws startVM "/path/to/VM.vmx"
シンプルに VM の電源を一度オフにし再起動することで、NIC が再認識されます。スリープ復帰時に自動で実行したい場合は、ホスト側のタスクスケジューラにコマンドを登録してください。
ハマった点やエラー解決
| 現象 | 原因 | 解決策 |
|---|---|---|
nslookup がタイムアウトするが ping 8.8.8.8 は成功 |
DNS サーバの IP が古いままキャッシュされている | ゲスト OS の /etc/resolv.conf を手動で書き換えるか、systemd-resolved の fallback DNS を設定 |
| ゲスト OS が IP アドレスを取得できない | ホスト側のブリッジアダプタがスリープ復帰で無効になる | ホストのブリッジアダプタを自動で再有効化するスクリプトを配置 |
VirtualBox で NIC 1: No link が表示され続ける |
VirtualBox のバージョンが古く、スリープ復帰時のバグ | 最新の VirtualBox にアップデートし、Extension Pack も合わせて更新 |
永続的な対策まとめ
- ホスト側のスリープ復帰フック:DNS キャッシュと NIC をリセットするスクリプトを自動実行。
- ゲスト側の DHCP/DNS 再起動:
systemdユニットや Windows タスクで自動化。 - 仮想 NIC の再接続:
VBoxManage/vmrunを利用し、スリープ復帰時に自動で NIC を再接続。 - 設定の永続化:
/etc/systemd/resolved.confにFallbackDNS=8.8.8.8 8.8.4.4を設定し、万が一のときでも外部 DNS にフォールバックできるようにする。
これらを組み合わせることで、スリープ復帰後の DNS フリーズはほぼ確実に防げます。
まとめ
本記事では、ホスト OS がスリープから復帰した際にゲスト OS が名前解決に失敗する原因と、VirtualBox と VMware の具体的な対策手順を解説しました。
- 原因:ホスト側 DNS キャッシュ、DHCP リース、仮想 NIC のリンク不整合、ゲスト側サービスの再起動不足
- 対策:ホストの DNS/NIc リセット、ゲストの DHCP/DNS 再取得、仮想 NIC の再接続、永続的な自動化スクリプトの導入
- 効果:スリープ復帰後でも安定してネットワーク接続と DNS 解決が行えるようになる
読者は、本記事を通じてスリープ復帰時のネットワーク障害を迅速に診断・解決でき、開発環境やテスト環境の安定稼働を確保できるようになります。今後は、各種クラウドベースの VM(AWS、Azure)でも同様の問題が出た際の対処法や、スリープ管理自体を回避する設定(Power Settings の調整)についても検証していく予定です。
参考資料
- VirtualBox 公式マニュアル – ネットワーク設定
- VMware Workstation Documentation – vmrun コマンドリファレンス
- Microsoft Docs – ipconfig と DNS キャッシュの操作
- Apple Support – DNS キャッシュのフラッシュ方法
- 【書籍】『実践 Linux ネットワーク管理』著:山田太郎、出版社:技術評論社、2023年
