仮想化セキュリティーガイド
仮想化環境のセキュリティー保護
概要
第1章 はじめに
1.1. 仮想化環境と非仮想化環境
非仮想化環境では、ホストは物理的に相互分離しており、各ホストには Web サーバーや DNS サーバーなどのサービスで構成される自己完結型の環境があります。これらのサービスは、独自のユーザースペース、ホストカーネル、物理ホストと直接通信して、ネットワークにサービスを直接提供します。下図は、非仮想化環境を示しています。

図1.1 非仮想化環境
仮想化環境では、複数のオペレーティングシステムを (「ゲスト」として) 単一のホストカーネルおよび物理ホストに格納することができます。下図は仮想化環境を示しています。

図1.2 仮想化環境
1.2. 仮想化セキュリティーが重要である理由
- ホスト/ハイパーバイザーは第一のターゲットであり、ゲストとデータの単一障害点となることが多くあります。
- 仮想マシンは望ましくない方法で相互干渉する場合があります。これを防ぐためのアクセス制御が導入されていないとすると、悪意のあるゲストが脆弱なハイパーバイザーをバイパスし、他のゲストのストレージなど、ホストシステム上の他のリソースに直接アクセスする可能性があります。
- 仮想化システムを迅速にデプロイすると、十分なパッチ、モニタリング、メンテナンスなどのリソース管理の必要性が増大するため、リソースとサービスのトラッキングおよび維持管理が難しくなる場合があります。
- 仮想化環境における技術スタッフの知識不足、技能の格差、経験不足などの問題が存在する可能性があります。このような問題は、多くの場合、脆弱性へとつながります。
- ストレージなどのリソースが複数のマシンに散在し、それらのマシンに依存している場合があります。このような場合には環境が過度に複雑化してしまい、システムの管理とメンテナンスが不十分となる可能性があります。
- 仮想化によって、環境内に存在する従来のセキュリティーリスクは排除されません。仮想化レイヤーのみでなく、ソリューションスタック全体のセキュリティーを保護する必要があります。
1.3. sVirt を使用した SELinux の活用
第2章 ホストのセキュリティー
2.1. ホストのセキュリティーが重要である理由
2.2. ホスト物理マシンのセキュリティー保護
- 強制 (enforcing) モードで SELinux を実行します。
setenforceコマンドを使って SELinux を強制 (enforcing) モードで実行するように設定します。# setenforce 1
- すべての不必要なサービスを削除するか、または無効にします (
AutoFS、NFS、FTP、HTTP、NIS、telnetd、sendmailなど)。 - サーバー上にはプラットフォームの管理に必要な最低限のユーザーアカウントのみを追加します。不必要なユーザーアカウントは削除してください。
- ホストでは不必要なアプリケーションは実行しないようにしてください。ホストでアプリケーションを実行すると仮想マシンのパフォーマンスに影響を与えるため、その影響がサーバーの安定性に及ぶ可能性があります。サーバーをクラッシュさせる可能性のあるアプリケーションは、サーバー上のすべての仮想マシンをダウンさせてしまう原因ともなります。
- 仮想マシンのインストールおよびイメージには集中管理できる場所を使用します。仮想マシンのイメージは
/var/lib/libvirt/images/に格納してください。仮想マシンのイメージをこれ以外のディレクトリーに格納する場合は、そのディレクトリーを SELinux ポリシーに追加し、インストールを開始する前にラベルの再設定を必ず行ってください。集中管理ができる共有可能なネットワークストレージの使用を強くお勧めします。
注記
2.2.1. セキュリティー導入計画
- 動作仕様
- ご使用のゲスト仮想マシンで必要なサービスの指定
- ホスト物理サーバーとこれらのサービスに必要なサポートの指定
- ホスト物理マシン上では必要となるサービスのみを実行する。ホスト物理マシン上で実行されているプロセスやサービスが少ないほど、セキュリティーのレベルとパフォーマンスが高くなります。
- ハイパーバイザー上で SELinux を有効にする。SELinux と仮想化の使い方については、「SELinux と強制アクセス制御 (MAC)」を参照してください。
- ファイアーウォールを使用してホスト物理マシンへのトラフィックを制限する。攻撃からホスト物理マシンを保護するデフォルト拒否ルールでファイアウォールをセットアップできます。また、ネットワークを介するサービスを制限することも重要です。
- 標準ユーザーのホストのオペレーティングシステムに対するアクセスを許可しない。ホストのオペレーティングシステムの特権アカウントが設定されている場合、特権のないアカウントにアクセスを許可すると、セキュリティーが危険にさらされる可能性があります。
2.2.2. クライアントアクセス制御
libvirtd デーモンには 3 つのレベルのアクセス制御があります。最初は、すべての接続が非認証状態で行われます。この状態では、認証を完了するために必要な API 操作のみが許可されます。認証が成功した後は、クライアント接続に使用されたソケットによって、接続はすべての API 呼び出しへの完全な無制限アクセスを持つか、または「読み取り専用」操作に制限されます。アクセス制御フレームワークでは、管理者が、認証された接続に細かいアクセス権ルールを定義することができます。libvirt のすべての API 呼び出しには、使用されるオブジェクトに対して検証される一連の権限があります。さらに、特定のフラグが API 呼び出しに設定されているかについて権限のチェックが行われます。API 呼び出しに渡されるオブジェクトのチェックのほかにも、一部のメソッドは結果をフィルタリングします。
2.2.2.1. アクセス制御ドライバー
access_drivers パラメーターを使用して libvirtd.conf 設定ファイルで設定されます。このパラメーターは、さまざまなアクセス制御ドライバー名を受け入れます。複数のアクセス制御ドライバーが必要とされる場合は、すべてのアクセス制御ドライバーのアクセスが付与されるようにそれらが処理される必要があります。「polkit」をドライバーとして有効にするには、以下のコマンドを実行します。
# augtool -s set '/files/etc/libvirt/libvirtd.conf/access_drivers[1]' polkit# augtool -s rm /files/etc/libvirt/libvirtd.conf/access_driverslibvirtd.conf に変更を加えると、libvirtd デーモンの再起動が必要になることに注意してください。
2.2.2.2. オブジェクトおよびアクセス権
2.2.2.3. ブロックデバイスをゲストに追加する際のセキュリティー上の懸念事項
- ホスト物理マシンでは、ファイルシステムを特定するために、
fstabファイルや、initrdファイルまたはカーネルコマンドラインなどでファイルシステムのラベルを使用しないようにしてください。ゲスト仮想マシンがパーティションや LVM ボリューム全体への書き込みアクセスを持つ場合、ファイルシステムのラベルを使用するとセキュリティー上のリスクが発生します。ゲスト仮想マシンが、ホスト物理マシンに属するファイルシステムのラベルを独自のブロックデバイスストレージに書き込む可能性があるためです。これにより、ホスト物理マシンの再起動時に、ホスト物理マシンがこのゲスト仮想マシンのディスクをシステムディスクとして誤って使用してしまう可能性があり、ホスト物理マシンシステムが危険にさらされる可能性があります。fstabファイル、initrdファイルまたはカーネルコマンドラインなどで使用する場合、デバイスの識別にはその UUID を使用した方がよいでしょう。それでも、特定のファイルシステムでは UUID の使用が完全に安全であるとは言えませんが、UUID を使用した場合には同様のセキュリティー侵害の可能性は確実に低くなります。 - ゲスト仮想マシンはディスク全域、またはブロックデバイス全域 (例:
/dev/sdb) に書き込みアクセスを持つべきではありません。ブロックデバイス全域にアクセスを持つゲスト仮想マシンはボリュームラベルを修正できる場合があり、これがホスト物理マシンシステムの攻撃に使用される可能性があります。パーティション (例:/dev/sdb1) または LVM ボリュームを使用して、この問題を回避してください。LVM 管理および設定例については、「CLI コマンドでの LVM 管理」または「LVM 設定の例」を参照してください。/dev/sdb1または/dev/sdbなどの raw ディスクなどのパーティションへの raw アクセスを使用する場合、global_filter設定を使用して、安全なディスクのみをスキャンできるよう LVM を設定する必要があります。global_filterコマンドを使用した LVM 設定スクリプトの例については、「サンプル lvm.conf ファイル」を参照してください。
2.3. Red Hat Enterprise Linux のホストセキュリティー推奨プラクティス
- ゲストシステムの使用と管理のサポートに必要なサービスのみを実行します。ファイルサービスや印刷サービスなどのサービスを追加で提供する必要がある場合には、それらのサービスを Red Hat Enterprise Linux ゲストで実行することを検討した方がよいでしょう。
- システムへの直接のアクセスはシステムの管理を行う必要がある人に制限してください。共有の root アクセスを無効にして、代わりに
sudoなどのツールを使用して、管理ロールに基づいて管理者に特権的アクセスを付与することを検討してください。 - SELinux がご使用のインストールに応じて適切に設定され、enforcing モードで稼働していることを確認します。これは、適正なプラクティスである上、sVirt によって提供される高度な仮想化セキュリティー機能は SELinux に依存しています。SELinux と sVirt に関する詳しい情報は「4章sVirt」を参照してください。
- ホストシステムで監査が有効化され、libvirt が監査レコードを生成するように設定されていることを確認します。監査が有効化されると、libvirt はゲストの設定変更および起動/停止イベントの監査レコードを生成します。これは、ゲストの状態をトラッキングするのに役立ちます。また、libvirt の監査イベントは、標準の監査ログ検査ツール以外に、専用の
auvirtツールでも確認することができます。 - システムのリモート管理はすべてセキュアなネットワークチャネル上のみで実行されるようにしてください。SSH のようなツールや、TLS または SSL などのネットワークプロトコルは認証とデータ暗号化の両方を提供し、承認済みの管理者のみがシステムをリモートで管理できるようにするのに役立ちます。
- ご使用のインストールに応じてファイアウォールが適切に設定されており、ブート時にアクティブ化されることを確認します。システムの使用および管理に必要なネットワークポートのみを許可する必要があります。
- ディスク全体またはブロックデバイス (例:
/dev/sdb) への直接のアクセスをゲストに許可するのは控えて、代わりにゲストストレージにはパーティション (例:/dev/sdb1) や LVM ボリュームを使用します。 - スタッフが仮想化環境における十分なトレーニングを受けており、知識が十分にあることを確認してください。
警告
注記
2.3.1. パブリッククラウドオペレーター向けの特殊な考慮事項
- ゲストからハードウェアへの直接のアクセスを無効にしてください。PCI、USB、FireWire、Thunderbolt、eSATA などのデバイスパススルーメカニズムは、管理を難しくする上、多くの場合は基礎となるハードウェアに依存してゲスト間の分離を強制します。
- クラウドオペレーターのプライベート管理ネットワークを顧客のゲストネットワークと分離して、顧客ネットワークを相互に分離することにより、以下が可能になります。
- ゲストがネットワーク経由でホストシステムにアクセスできないようにする。
- 顧客がクラウドプロバイダーの内部ネットワーク経由で別の顧客のゲストシステムに直接アクセスできないようにする。
第3章 ゲストのセキュリティー
3.1. ゲストのセキュリティーが重要である理由
3.2. ゲストセキュリティーの推奨プラクティス
- ゲストの管理はすべてリモートで実行される可能性が高いため、システムの管理は必ずセキュリティー保護されたネットワークチャネルで行うようにしてください。SSH などのツールや TLS または SSL などのネットワークプロトコルは、認証とデータの暗号化の両方を提供し、承認された管理者のみがシステムをリモートで管理できるようにします。
- 一部の仮想化テクノロジーでは、特殊なゲストエージェントまたはドライバーを使用して仮想化固有の機能を有効にします。このようなエージェントやアプリケーションは、SELinux のような Red Hat Enterprise Linux の標準のセキュリティー機能を使用して確実に保護してください。
- 仮想化環境では、ゲストシステムの保護境界線の外部から機密データがアクセスされるリスクがより高くなります。保管されている機密データは dm-crypt や GnuPG などの暗号化ツールを使用して保護してください。ただし、暗号化キーの機密性の確保には特に注意が必要です。
注記
第4章 sVirt
4.1. 概要

図4.1 SELinux によって分離される攻撃パス
注記
4.2. SELinux と強制アクセス制御 (MAC)
4.3. sVirt の設定
setsebool boolean_name {on|off}、再起動時に変更を永続化する場合は setsebool -P boolean_name {on|off} のいずれかを実行することによって切り替えることができます。
getsebool -a|grep virt を実行することにより確認できます。
表4.1 KVM SELinux のブール値
| SELinux のブール値 | 説明 |
|---|---|
| staff_use_svirt | staff ユーザーによる sVirt ドメイン作成、およびそのドメインへの移行を有効にします。 |
| unprivuser_use_svirt | 非特権ユーザーによる sVirt ドメイン作成、およびそのドメインへの移行を有効にします。 |
| virt_sandbox_use_audit | サンドボックスコンテナーによる監査メッセージの送信を有効にします。 |
| virt_sandbox_use_netlink | サンドボックスコンテナーによるネットリンクシステム呼び出しの使用を有効にします。 |
| virt_sandbox_use_sys_admin | サンドボックスコンテナーによる sys_admin システム呼び出し (mount 等) の使用を有効にします。 |
| virt_transition_userdomain | ユーザードメインとしての仮想プロセスの実行を有効にします。 |
| virt_use_comm | virt によるシリアルおよびパラレル通信ポートの使用を有効にします。 |
| virt_use_execmem | 制限された仮想ゲストによる実行可能メモリーおよび実行可能スタックの使用を有効にします。 |
| virt_use_fusefs | virt による FUSE マウントされたファイルの読み取りを有効にします。 |
| virt_use_nfs | virt による NFS マウントされたファイルの管理を有効にします。 |
| virt_use_rawip | virt による rawip ソケットとの通信を有効にします。 |
| virt_use_samba | virt による CIFS マウントされたファイルの管理を有効にします。 |
| virt_use_sanlock | 制限された仮想ゲストによる sanlock との通信を有効にします。 |
| virt_use_usb | virt による USB デバイスの使用を有効にします。 |
| virt_use_xserver | 仮想マシンによる X Window System との通信を有効にします。 |
注記
4.4. sVirt のラベル
4.4.1. sVirt ラベルのタイプ
表4.2 sVirt ラベル
| タイプ | SELinux コンテキスト | 説明/効果 |
|---|---|---|
| 仮想マシンプロセス | system_u:system_r:svirt_t:MCS1 | MCS1 は無作為に選択されたフィールドです。現在は、約 500,000 のラベルがサポートされています。 |
| 仮想マシンのイメージ | system_u:object_r:svirt_image_t:MCS1 | これらのイメージファイルやデバイスの読み取り/書き込みができるのは、同じ MCS1 フィールドが付いた svirt_t プロセスのみです。 |
| 仮想マシンの共有読み取り/書き込みコンテンツ | system_u:object_r:svirt_image_t:s0 | svirt_t プロセスはすべて、svirt_image_t:s0 のファイルおよびデバイスに書き込むことができます。 |
| 仮想マシンの共有読み取り専用コンテンツ | system_u:object_r:svirt_content_t:s0 | svirt_t プロセスはすべて、このラベルがついたファイル/デバイスを読み取ることができます。 |
| 仮想マシンのイメージ | system_u:object_r:virt_content_t:s0 | イメージが存在する場合に使用されるシステムのデフォルトラベルです。svirt_t 仮想プロセスは、このラベルの付いたファイル/デバイスを読み取ることはできません。 |
4.4.2. 動的設定
# ps -eZ | grep qemu-kvm system_u:system_r:svirt_t:s0:c87,c520 27950 ? 00:00:17 qemu-kvm
qemu-kvm プロセスに system_u:system_r:svirt_t:s0 のベースラベルが付いています。libvirt システムは、このプロセス用に一意の MCS ラベル c87,c520 を生成しています。ベースラベルと MCS ラベルを組み合わせることにより、そのプロセス用の完全なセキュリティーラベルが形成されます。同様に、libvirt は同じ MCS ラベルとベースラベルを使用してイメージラベルを形成します。このイメージラベルは次に、ディスクイメージやディスクデバイス、PCI デバイス、USB デバイス、kernel/initrd ファイルなど、仮想マシンがアクセスする必要のある全ホストファイルに自動的に適用されます。各プロセスは、異なるラベルを使用して、他の仮想マシンから分離されます。
/var/lib/libvirt/images 内のゲストディスクイメージに適用された、仮想マシンの一意のセキュリティーラベル (この場合は、対応する MCS ラベルが c87,c520) を示しています。
# ls -lZ /var/lib/libvirt/images/* system_u:object_r:svirt_image_t:s0:c87,c520 image1
<seclabel type='dynamic' model='selinux' relabel='yes'> <label>system_u:system_r:svirt_t:s0:c87,c520</label> <imagelabel>system_u:object_r:svirt_image_t:s0:c87,c520</imagelabel> </seclabel>
4.4.3. ベースラベルを使用した動的設定
<baselabel> オプションを手動で設定することができます。
<seclabel type='dynamic' model='selinux' relabel='yes'> <baselabel>system_u:system_r:svirt_custom_t:s0</baselabel> <label>system_u:system_r:svirt_custom_t:s0:c87,c520</label> <imagelabel>system_u:object_r:svirt_image_t:s0:c87,c520</imagelabel> </seclabel>
4.4.4. 動的リソースラベルを使用した静的設定
<seclabel type='static' model='selinux' relabel='yes'> <label>system_u:system_r:svirt_custom_t:s0:c87,c520</label> </seclabel>
4.4.5. リソースラベルを使用しない静的設定
<seclabel type='static' model='selinux' relabel='no'> <label>system_u:system_r:svirt_custom_t:s0:c87,c520</label> </seclabel>
第5章 仮想化環境におけるネットワークセキュリティー
5.1. ネットワークセキュリティーの概要
5.2. ネットワークセキュリティー推奨プラクティス
- システムのリモート管理はすべてセキュアなネットワークチャネル上のみで実行されるようにしてください。SSH のようなツールや、TLS または SSL などのネットワークプロトコルは認証とデータ暗号化の両方を提供し、システムへのセキュアなアクセスとその制御を行います。
- ゲストアプリケーションによる機密データの転送はセキュアなネットワークチャネルで行われるようにします。TLS や SSL などのプロトコルが利用できない場合には、IPsec などを使用することを検討してください。
- ファイアウォールを設定して、ブート時にアクティブ化されるようにします。システムの使用と管理に必要なネットワークポートのみを許可してください。ファイアウォールルールは、定期的にテストと見直しを行ってください。
5.2.1. SPICE への接続のセキュリティー保護
5.2.2. ストレージへの接続のセキュリティー保護
注記
付録A 追加情報
A.1. SELinux および sVirt
- sVirt のメイン Web サイト: http://selinuxproject.org/page/SVirt
- Dan Walsh 氏のブログ: http://danwalsh.livejournal.com/
- 非公式の SELinux FAQ: http://www.crypt.gen.nz/selinux/faq.html
A.2. 仮想化セキュリティー
- NIST (National Institute of Standards and Technology) 完全仮想化セキュリティーガイドライン: http://www.nist.gov/itl/csd/virtual-020111.cfm
付録B 改訂履歴
| 改訂履歴 | |||
|---|---|---|---|
| 改訂 1.0-18.2 | Tue Feb 27 2018 | ||
| |||
| 改訂 1.0-18.1 | Sun Sep 24 2017 | ||
| |||
| 改訂 1.0-18 | Thu Jul 27 2017 | ||
| |||
| 改訂 1.0-15 | Mon Oct 17 2016 | ||
| |||
| 改訂 1.0-9 | Thu Oct 08 2015 | ||
| |||
| 改訂 1.0-8 | Wed Feb 18 2015 | ||
| |||
