はじめに
PCを使っていると、どうしても様々なトラブルに遭遇します。OSが起動しなくなったり、設定ミスにでログインできなくなったり、そんなトラブルを経験したことのある方も多いのではないでしょうか。WSL2もLinuxというOSを動かしている仮想マシンなので、こうしたトラブルと無縁ではありません。
トラブルが起きた際も元通り復旧できれば理想的ですが、どうしようもないケースも存在します。そんな最悪の場合でも、バックアップされていないデータだけは救出したいですよね。今回はWSLにログインできなくなった際のデータのレスキュー方法を紹介します。
WSLにログイン不能になるときとは
WSLに正しくログインできなくなる原因はいくつか考えられます。今回はそのうち、よくありがちな2つのケースを考えてみましょう。
- WSL2は正しく起動しているが、ユーザーレベルの設定の問題でログインできない状態
- 重要なシステムファイルの破損などが原因で、WSL2の起動そのものが失敗する状態
実施にあたっての注意
本記事では解説の都合上、WSL2のシステムを意図的に破壊します。そのため、記事の内容を試す場合は必ず試験用の環境を作ってから実施してください。実際に運用している環境では絶対に行わないでください。
デフォルトユーザーでログインできないときは
WSLでは初回起動時にユーザーを作成しますが、設定ミスによりこのユーザーでログインできなくなった状況を考えてみましょう。例えば、ログインシェルが起動しなくなってしまった状態などです。
UbuntuをはじめとするLinuxでは、ログインシェルをユーザーが自由に選択できます。Ubuntuのデフォルトのシェルはbashですが、これをzshやtcsh、fishなどに変更できるわけです。各ユーザーのログインシェルは /etc/passwd に記述されており、このファイルには1行ごとに1ユーザーの設定が記載されています。行はコロンで区切られた7つのフィールドで構成されており、最初のフィールドがユーザー名、最後のフィールドがログインシェルです。
例えば、以下の例ではmizunoユーザーのログインシェルは/bin/bashであることが分かります。
$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
(...略...)
mizuno:x:1000:1000:,,,:/home/mizuno:/bin/bash
/etc/passwdを眺めていると、ログインシェルに「/usr/sbin/nologin」という見慣れないコマンドが指定されているユーザーがいることに気づくでしょう。nologinはそのユーザーアカウントが使用できない旨のメッセージを表示し、終了するだけのコマンドです。つまり、このコマンドがログインシェルに指定されているユーザーはbashのようなシェルが起動しないため、ログインできなくなるというわけです。
「こんなコマンドが何の役に立つのか」と思うかもしれませんが、これは主にセキュリティ確保のための措置です。Linuxには「バックグラウンドでプログラムを起動するためだけのユーザー」というものが多く存在します。これらのユーザーは人間が対話的に操作することを想定しておらず、直接ログインする必要がないためです。仮にこうしたユーザーがログイン可能に設定されていると、アカウントが乗っ取られた場合に、攻撃者に攻撃の足掛かりを与えてしまいます。
それでは「サービス起動用のユーザーのシェルを変更しようとしたら、うっかり別のユーザーを変更してしまい、ログイン不能になってしまった」というシナリオを想定して、自身のユーザーのログインシェルを「/usr/sbin/nologin」に変更してみましょう。ログインシェルは以下のコマンドで変更できます。
$ sudo usermod -s 指定するシェル ユーザー名
mizunoユーザーのログインシェルを/usr/sbin/nologinにする具体的なコマンドは以下の通りです。
$ sudo usermod -s /usr/sbin/nologin mizuno
コマンドを実行したら、一度WSLからログアウトし、再度ログインを試みてみましょう。ログインシェルに「/usr/sbin/nologin」が設定されている場合は所定のメッセージが表示された後、ただちにログイン処理は終了します。いわゆる「やらかしてしまった」状態ですね。
ところが、これはそれほど大した問題ではありません。というのも、特定のユーザーの設定がおかしくなっているだけであれば、別ユーザーでログインすることでバイパス可能だからです。WSLは起動時に「-u」オプションでログインするユーザーを指定できます。例えば、以下のコマンドを実行すればrootユーザーとしてUbuntu-24.04にログインできるのです。
$ wsl -d Ubuntu-24.04 -u root
rootのシェルが取れれば復旧は簡単です。以下のコマンドを実行して、ユーザーのログインシェルをデフォルトのbashに戻してあげましょう。なお、ここではrootとして直接ログインしているためsudoは不要になります。
# usermod -s /bin/bash mizuno
今回はシェルの変更を例に挙げましたが、それ以外のトラブルにも対応できます。例えば、ユーザーのホームディレクトリの中身を削除して初期状態に戻す、などです。Ubuntuにおいて日常的にrootアカウントを直接使用することは推奨されていませんが、緊急時の「伝家の宝刀」としてrootで直接ログインすればユーザーレベルの設定に起因する問題は解決できることを覚えておきましょう。
ディスクイメージを別環境にマウントする
前述の通り、WSLが起動さえしていれば、なんとでもやりようはあります。本格的にまずいのは、WSLそのものが起動しない状態です。具体的には、ディスク障害や重要なシステムファイルが欠損したなどの理由で、OSそのものが起動に失敗してしまうケースです。それでは、うっかり「sudo rm -rf /usr」コマンドを実行し、OSの起動に必要なファイルをディレクトリごと消し飛ばしてWSLを起動不能にしてみます。
繰り返しますが、以下の手順ではWSL2のシステムを破壊します。ユーザーが作成したデータは救出可能ですが、環境そのものは破棄して作り直す以外にありません。また、WSLでは/mnt以下にホストであるWindowsのドライブがマウントされています。誤ったファイルを削除するとホストに影響が出ることもあります。実際に運用している環境では、絶対に本記事の内容を行わないでください。
$ sudo rm -rf /usr
削除が完了したら、一度WSLからログアウトしてもう一度ログインしてみましょう。ログインシェルのbashも削除されているため、ログインに失敗します。
PowerShellから一度WSLをシャットダウンし、再起動してみましょう。致命的なエラーで起動に失敗します。
起動しない状態のWSLからファイルをなんとか救出する方法を考えてみましょう。と言ったものの、実はそれほど難しい問題ではありません。実際のサーバーでもディスクトラブルなどでOSが起動しなくなってしまうことはよくありますが、OSは起動しなくなっていてもディスクそのものは残っているわけです。つまり、USBメモリなどから別のLinuxシステムを起動したり、ディスクを取り出してUSB経由で別マシンにマウントすればデータの救出は可能です。WSL2も中身は仮想マシンで、そのディスクはイメージファイルとして存在します。このファイルを別のWSLディストリビューションにマウントしてあげれば良いわけです。
「そんなことをしなくても、WindowsのエクスプローラーからWSL内のファイルにアクセスできるじゃないか」と思われるかもしれません。実はこの機能はWSLのディスクイメージの中身をWindowsが直接見ているわけではなく、WSLに内蔵された9pサーバーとのネットワークを経由したファイル共有により実現されています。そのため、WSLが起動しない状態ではエクスプローラーからWSL内のファイルへアクセスできません。
それでは、レスキュー用のWSL環境を用意しましょう。以下のコマンドでUbuntu-24.04を別名でインストールします。
$ wsl --install -d Ubuntu-24.04 --name ubuntu-rescue
続いて、壊したディスクイメージをこの環境にマウントします。しかしWSL2のディスクイメージである「vhdk」は少々特殊な形式をしており、一般的な仮想マシンイメージのように、Linuxから簡単にマウントできません。そこで現在のWSLでは「wsl --mount」という専用のコマンドが用意されています。
まずは対象のvhdxファイルを探しましょう。以下のコマンドを実行してください。
$ Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss | ForEach-Object { [PSCustomObject]@{Name=(Get-ItemProperty $_.PSPath).DistributionName; VHDXPath=(Join-Path (Get-ItemProperty $_.PSPath).BasePath "ext4.vhdx")} }
実行すると、下図のようにインストールされているWSLディストリビューションごとにvhdxファイルのパスが表示されます。先ほど壊したのは「Ubuntu-24.04」なので、このvhdxファイルへのパスを控えておきましょう。
続いてディスクイメージをマウントしますが、これには管理者権限が必要となります。管理者権限で新しいPowerShellを起動してください。
以下のコマンドでディスクイメージをマウントします。vhdxへのパスは、先ほど控えた実際のパスに置き換えてください。
$ wsl --mount --vhd "vhdxへのパス"
すると、すべてのWSL内から「/mnt/wsl/(vhdkファイルのパスから特殊文字を除いたもの)」というパスで、このvhdkの中身にアクセスできるようになります。
あとは先ほどインストールしたレスキュー用のWSLを起動し、必要なファイルを救出してください。
必要なファイルのレスキューが完了したら、以下のコマンドでvhdkをアンマウントできます。アンマウントする際に「--vhd」オプションは不要です。
$ wsl --unmount "vhdxへのパス"
最後に、破損して起動しなくなったWSLディストリビューションを、以下のコマンドで削除してしまいましょう。
$ wsl --unregister Ubuntu-24.04
おわりに
このように、WSL環境にログインできなくなったり、そもそも起動しなくなってしまったとしても、ディスクそのものが読める形で残っていれば、まだ救いはあります。トラブルは起きないに越したことはありませんが、それでも起こるべくして起こってしまうものです。いざというときに備え、こうしたレスキュー方法もぜひ覚えておきましょう。
- この記事のキーワード