🦩

QEMU で x86_64 Linux 環境を構築する

2024/09/16に公開

TL;DR

# QEMU のインストール
brew install qemu

# ディスクイメージの作成
qemu-img create -f qcow2 ubuntu-disk.img 32G

# Ubuntu Server のインストール
wget https://ubuntu.com/download/server/thank-you?version=24.04.1&architecture=amd64&lts=true
qemu-system-x86_64 -accel tcg -boot menu=on -cdrom ubuntu-24.04-live-server-amd64.iso -m 4G ubuntu-disk.img

# ホスト側の端末からログイン
qemu-system-x86_64 -accel tcg -m 4G -nic user,hostfwd=tcp::60022-:22 ubuntu-disk.img
ssh <user>@localhost -p 60022  # from host

概要

この記事では、QEMU を用いて x86_64 Linux VM 環境を構築する方法を紹介します。
また、利便性のためホスト側の端末から ssh 接続できるようにします。

QEMU は CPU 等のハードウェアレベルを含めた Full-system emulation を提供するので、この記事で紹介する方法は基本的にはホスト側の CPU アーキテクチャ, OS に関わらず利用できると思います。

今回の内容は aarch64 Mac OS 13.3.1 (Apple Silicon) 上で検証しています。

調べたきっかけ

筆者は普段 M2 Mac (ARM マシン) を使用しています。
Apple Silicon 登場当時から時間も経って、もはや日常作業には ARM だから困るということはほぼ無いという実感なのですが、それでもときどき x86_64 環境が欲しくなることがあります。

筆者の場合特に困ったのは、セキュリティコンテスト (CTF) 向けの環境構築でした。
Docker (Docker Desktop) でも x86_64 コンテナを実行することはできますが、CTF 用途としては gdb (デバッガ) が実行できないのが致命的でした[1] [2]

そのような中知ったのが QEMU で、公式ページにも Full-system emulation できると書いてあるのでこちらであれば自分の目的を達成できるのではないかと思いました。
実際この見込みは正しかったのですが、全く触れたことが無い身からすると QEMU は使い方がかなり複雑でわからないことが多く、満足いく使いかたができるまでには苦労した部分がありました。

苦労した一因として、QEMU を知らない・使ったことが無い人向けに丁寧に導入方法を説明している記事はあまり多くないように感じられたので今回記事としてまとめたいと思いました。

QEMU のインストール

Download QEMU を参考に行ってください。Homebrew を使う場合であれば以下になります。

brew install qemu

手順の概要

今回は QEMU の system emulation というモードを利用します。
System emulation は、CPU やメモリのハードウェアを含めて仮想化を行い、仮想化したハードウェアの上でゲスト OS を動作させるモードです。

System emulation を用いてゲスト OS を起動するまでには、以下のような手順を順に行います。

  1. ディスクイメージの作成
  2. ゲスト OS のインストール
  3. インストール済みのゲスト OS (VM) の起動

はじめに、OS のインストール先となるディスクイメージを作成します。ゲスト OS 上のデータもこのディスクイメージ上に保存されます。
次に、OS の iso イメージを利用してハードディスクにインストールするのと同様の OS インストール作業を行います。今回は広く利用されておりインストールも比較的簡単な Ubuntu を利用します。
最後に、ディスクイメージ上にインストールしたゲスト OS を起動します。

以下、各手順について詳しく見ていきます。

ディスクイメージの作成

まずはじめに VM が利用するディスクイメージを作成する必要があります。今回は ubuntu-disk.img という名前で 32GB のディスクイメージを作成します。今回は qcow2 というフォーマットを利用します。

qemu-img create -f qcow2 ubuntu-disk.img 32G

ここで 32GB という容量を指定しましたが、ディスクイメージを作成して直ちに 32GB の実ディスク容量が消費されるわけではありません。
基本的には実際に書き込みが発生した分だけ実ディスク容量が消費されていくので、大きめに設定しておいてもそれほど弊害は無いかと思います。

ゲスト OS のインストール

次に、作成したディスクイメージ上にゲスト OS をインストールします。
はじめに、インストールしたい OS の iso イメージをダウンロードしてきます。今回はメジャーなディストリビューションで、インストールも比較的簡単な Ubuntu を利用してみます [3]

# Ubuntu Server のインストール
wget https://ubuntu.com/download/server/thank-you?version=24.04.1&architecture=amd64&lts=true

インストール用に ubuntu を起動するには以下のコマンドを使用します。

qemu-system-x86_64 -accel tcg -boot menu=on -cdrom ubuntu-24.04-live-server-amd64.iso -m 4G ubuntu-disk.img
起動オプションについて
  • -accel はエミュレーションのためのアクセラレータを指定するオプションです。tcg は QEMU に組み込みで入っているアクセラレータです [4]
  • -boot はどのドライブからブートを行うか指定するオプションです。menu=on ではブートメニューが表示されて、ユーザーが選択します。
  • -cdrom は CD-ROM として使うイメージを指定します。OS を新規にインストールする場合はこのオプションを使うのが簡単です。
  • -m は VM のメモリ使用量を設定します。今回の設定では 4GB です。
  • ubuntu-disk.img は先ほど作成した VM 用のディスクイメージです。

QEMU の起動直後、QEMU のウィンドウがフォアグラウンドのウィンドウ (e.g. 現在操作しているターミナル) に隠れて見えないかもしれません。その場合は、ホスト側の仮想デスクトップの操作などで QEMU のウィンドウを探してあげてください。

QEMU のウィンドウに一度フォーカスすると、マウス操作が QEMU ウィンドウ内で閉じるようになってウィンドウの外を選択できなくなります。この状態を解除するには Ctrl + Alt + g を同時に押してください。

起動に成功すれば以下のようなブートメニューのウィンドウが出てきます。

Try or Install Ubuntu Server を選択すると、ブートのログがしばらく流れた後インストールメニューが開始されます。

後はメニューの指示に従ってインストール作業を進めてください。

インストールはそこそこ (数十分程度) 時間がかかると思いますが、気長に待ちましょう 💤

ゲスト OS の起動

一度インストールできたら、CD-ROM 無しで起動することができます。以下のようなコマンドで ubuntu-disk.img にインストールされたゲスト OS を起動します。

qemu-system-x86_64 -accel tcg -m 4G ubuntu-disk.img

ブートするのに多少 (1分程度) 時間がかかりますが、一度起動してしまえば簡単な CLI 操作ぐらいであればさほど性能上の問題は気にならないのではないかと思います。

起動が終了すると以下のようなログイン画面が出てくるので、インストール時に設定したユーザー名・パスワードを入力すればログインできます。

ネットワークもデフォルトで設定されているので、apt install 等のコマンドでインターネット上からパッケージをダウンロードしてくることもできます。

VM を終了する際は shutdown -h now 等のコマンドを実行するか、QEMU のメニューから "Machine > Power Down" を選択してください。

ホスト側からゲスト OS に ssh ログイン

以上のセットアップで一通りゲスト OS が利用できる状態になり、QEMU の提供する GUI window から操作を行うことができるようになりました。
しかし、QEMU のウィンドウからの操作では以下のような点で不満が残ります。

  • ゲスト OS を操作するためにウィンドウの切りかえが必要
  • フォントや色が見づらい
  • 日本語の入力および表示できない

そこで、ゲスト OS 上に SSH サーバーを立ち上げ、ホスト側で動かしている端末からログインできるようにすることで以上のような作業上の問題を解消することができます。

ゲスト OS 上のポートにホスト側から接続できるようにするためには、ゲスト OS の起動時にネットワークの設定が必要です。具体的には、以下のようなオプションを用いれば良いです。

-nic user,hostfwd=tcp::60022-:22
起動コマンドの全体
qemu-system-x86_64 -accel tcg -m 4G -nic user,hostfwd=tcp::60022-:22 ubuntu-disk.img

こちらは、ホスト OS 上の 60022 番ポートをゲスト OS 上の 22 番ポートに forward するという意味になります (参考)。

ゲスト OS 側で sudo apt install openssh-server などで sshd をインストールして起動しておくことで、ホスト側から以下のようなコマンドで SSH 接続することができます。

ssh <user-name>@localhost -p 60022

おわりに

この記事では、QEMU を用いて x86_64 Linux 環境を構築する方法を紹介しました。
この方法は QEMU がサポートしている環境であれば CPU アーキテクチャや OS を問わず使える汎用的な方法と思われるため、どこかで使いたくなることがあるかもしれません。

QEMU をある程度使ったことがある方にとってはごく初歩的な内容かと思いますが、QEMU を使ってみたい、使いかたを調べてみたことがあるがよくわからなかったという方に参考になっていれば幸いです。

最後まで読んでいただきありがとうございました!

参考

公式ドキュメントは慣れていないとどこを読んでいいかよくわからないかもしれません。
今回参考にした部分は主に System Emulation の以下の項目になります。

Arch Wiki の説明はかなり充実していて、今回かなり参考にしました。
今回の記事で紹介している内容はほとんどカバーされています。

また今回は検証していないですが、QEMU のコマンド操作がわかりにくいなどの理由で GUI による操作をベースに行いたい方は UTM というプロジェクトを試してみると良いかもしれません。

脚注
  1. Mac M1 Ptrace - warning: ptrace: Function not implemented ↩︎

  2. Unable to debug amd64 binaries on apple silicon ↩︎

  3. Ubuntu には GUI が搭載された Desktop 版もあります。QEMU でも Desktop 版を利用することもできますが、今回試した構成 (x86_64 Linux on aarch64 Mac) では著しく動作が重かったためオススメはしません。このような構成でも Desktop 版を軽快に動かすような方法があればぜひ教えてください... ↩︎

  4. Linux の kvm や Apple Hypervisor Framework hvf が使える場合にはそちらを利用した方が性能的には良いのではないかと思います (未検証)。今回の構成 (x86_64 Linux on aarch64 Mac) では、試した範囲では hvf は利用できないようです ↩︎

GitHubで編集を提案

Discussion