ひねり出したメモ

主にコンピューター関連の話を書きます。

HDD・SSDなどに記録されたデータを消去する際の上書き回数(NIST SP 800-88 rev.1「媒体のデータ抹消処理(サニタイズ)に関するガイドライン」より)

まえがき

HDDなどに記録されたデータを消去する際の上書き回数について調べると、 35回上書き1するGutmann方式(1996年発表)や、3回上書き[^1]するDoD 5220.22-M規格(1995年発表)などが見つかりますが、 「上記の規格は古く、現在のHDDでは1回の上書きで十分」という情報も見つかります。

また、フラッシュメモリー(SSD、SD、USBメモリー)の場合、ウェアレベリング(書き込み場所を分散させメディアの寿命を延ばす処理)が行われるため、 上書きが困難という情報も見つかります。参考URL

そこで、記録メディアの上書き回数についてより新しい基準がないか調べたところ、 NIST(米国国立標準技術研究所)のSP 800-88 rev.1 (2014年12月)「媒体のデータ抹消処理(サニタイズ)に関するガイドラインという文章を IPAが翻訳していることを知りました。

「媒体のデータ抹消処理(サニタイズ)に関するガイドライン」には、電子媒体のほか、紙などの抹消方法や組織内での運用、消去後の検証についても記載がありますが、 この記事ではHDDなどの上書き回数に限ってまとめています。

なお、翻訳版は下記のURLにあります。
https://www.ipa.go.jp/security/reports/oversea/nist/ug65p90000019cp4-att/000094547.pdf

データ抹消処理の種類

ガイドラインではデータ抹消処理を消去(Clear)除去(Purge)破壊(Destroy)の3種類に分類しており、 抹消処理と記録媒体の種類ごとに処理方法が記載されています。

各処理方法の定義はガイドラインの「2.5 データ抹消処理の種類」に記載されています。

消去

消去(Clear)は、すべてのユーザアドレス指定可能なストレージ領域のデータに対してデータ抹 消処理を行うための論理的な技術を適用し、単純な非侵襲のデータ回復技術から保護する。通常 は、新しい値で書き換えたり、メニューオプションを使用してデバイスを工場出荷時の状態にリ セットしたりする(書き換えがサポートされていない場合)など、ストレージデバイスへの標準 的な読み書きコマンドを介して実行される。

除去

除去(Purge)は、物理的又は論理的な技術を適用して、最先端の研究室レベルの技術を使用し ても対象データの回復を不可能にする。

破壊

破壊(Destroy)は、最新の研究室レベルの技術を使用しても対象データの回復を不可能にし、且 つその後のデータの保存に当該媒体が使用できないようにする。

それぞれの処理方法の詳細はガイドラインの「5 データ抹消処理方法のまとめ」に記載されています。

HDDやSSDなどの上書きに限れば、消去は「デバイスの標準的な読み書きコマンドを使用」、 除去は「専用の標準化されたデバイスのデータ抹消処理コマンドを使用」という違いがあるようです。

消去の説明には「機微データが保持されている可能性のあるデバイスのすべての領域に対応できない場合がある」とあり、 例としてフラッシュメモリーのウェアレベリングが挙げられています。

除去の場合は、「一般的な読み書きコマンドに内在する抽出機能を迂回するように媒体固有の技術を適用する」とあり、 おそらくウェアレベリングのような処理を迂回して確実に上書きするのが除去になると思われます。

上書き回数

上書き回数についてはガイドラインの「付録 A - 最低限のデータ抹消処理についての推奨事項」に記載されています。

HDDの場合

HDDは4種類が記載されています。

  • 磁気ディスク(フレキシブル又は固定)
  • ATA ハードディスクドライブ
  • SCSI ハードディスクドライブ
  • 外付けローカル接続ハードドライブ

消去の上書き回数については、4種類とも「すべて 0 の列などの固定データ値を持つ少なくとも 1 回書き込みパスであるべきである。複数の書き込みパスやより複雑な値もオプションとして使用することができる」と記載されています。

除去の場合、ATASCSIでは接続方式ごとの機能を使用して上書きする方法が記載されていますが、 「磁気ディスク(フレキシブル又は固定)」では上書きによる除去は記載がなく、消磁による除去のみ記載があります。 おそらく「磁気ディスク(フレキシブル又は固定)」は接続方式に関係なく利用できる方法を記載していると思われます。

フラッシュメモリーの場合

SSD

SSDは3種類が記載されています。

  • ATA ソリッドステートドライブ
  • SCSI ソリッドステートドライブ
  • NVM Express SSD

消去の上書き回数については「すべて 0 の列などの固定データ値を持つ少なくとも 1 回パスの書き込みで構成されるべきである。複数パスやより複雑な値も代替として使用することができる。」となっています。 また「マッピングされていない物理媒体のデータ抹消処理が行えない(つまり、古いデータが当該媒体上に残っている)可能性があることに留意することが重要である」との注意書きがあります。 ただしNVMeのみ注意書きがありません。2

除去の場合は、接続方式ごとの機能を使用して上書きする方法が記載されています。

USBメモリーやSDカード

USB リムーバブル媒体(USBメモリー)、メモリカード(SD、SDHC、MMC)の場合は、 「消去パターンは少なくとも 2 回パスであるべきであり、1 回目パスにパターンを、2 回目パスにその補数3を含むようにする。追加のパスを使用することもできる。」となっています。


  1. 上書き回数だけでなく書き込む内容も規定されている。
  2. なんでだろう?
  3. 反転させたパターンを書き込めばよいのだろうか?

【Debian】【QEMU/KVM】Ryzen2のPCでGPUパススルーしてWindows8.1のゲストを動かす

Ryzen2を搭載したPCでGPUとUSBコントローラーをPCIパススルーして、ゲストのWindows8.1を快適に使用できる環境を作ります。

目的

自宅で使用しているメインPCがWindows7を使用しており、サポート期限が迫っているので移行先の環境を作ります。
Winodws8.1はRyzenをサポートしておらずWindows Updateがエラーになりますが、QEMU/KVMの設定でゲストマシンのCPUを古いモデルに設定してこれを回避します。

ゲストのWindows8.1は通常のデスクトップ機と同様に使えるようにします。
そのためGPUをゲストマシンへパススルーして、物理マシンと同程度のグラフィック性能を確保します。
さらにUSBコントローラーをパススルーすることで、仮想環境であるとこを意識せずにUSBデバイスを使用できるようにします。

ゲストのOSにWindows8.1を使用していますが、同様の手順でWindows10のゲストを動かすことも可能なはずです。 (Windows8.1なのは、Windows10があまり好きではないからです)

構成

  • ハードウェア
    • MB: Asrock Fatal1ty X370 Professional Gaming
    • CPU : AMD Ryzen7 2700X
    • RAM : 32GB (16GB 2枚)
    • グラフィック(1) : MSI GeForce GTX 1050 Ti 4GT LP ※ゲストにパススルーする用
    • グラフィック(2) : 玄人志向 GF-GT710-E1GB/LP ※ホストの操作用
    • サウンドASUS XONAR U7 MK II ※音の良いPCにするためパススルーしたUSBコントローラーの先に接続する。
    • そのほか、USB接続のキーボード・マウス(ゲストの操作用)、十分な容量HDD
  • ソフトウェア
    • Debian9 x64 →動作に問題があったのでテスト版のDebian10にアップグレードしています。OSインストールから始める場合は始めからDebian10使用したほうが良いと思います(できれば正式版を待ってから)。理由は最後に記載。

環境構築

Debian9のインストール

Debian9のインストールはウィザードに沿ってすすめるだけです。
ソフトウェアの選択では「Debianデスクトップ環境」と「MATE」を選びました。後ほどvirt-manageをインストールしてGUI仮想マシンの設定を可能にします。

OSのインストール後、/etc/apt/sources.listを編集してcontribとnon-freeのセクションを有効にしています。 そして、ホスト操作に使用するGPUのドライバをインストールしています。

# nano /etc/apt/sources.list
    各リポジトリにcontribとnon-freeのセクションを追加する
# apt update
# apt install nvidia-driver

必要なパッケージのインストール

QEMU/KVM関連のパッケージをインストールします。 なお、当方の環境ではすでにブリッジインターフェースの作成に必要なbridge-utilsはインストール済みでした。
Debinaインストール時のソフトウェアの選択次第ではbridge-utilsのインストールも必要になると思われます。

apt install qemu-kvm libvirt-clients qemu-utils libvirt-daemon-system ovmf virt-manager

ブリッジの設定

ホストとゲストで物理NICを共有できるようにブリッジインターフェースを作成します。
ブリッジの作成はNetworkManagerで作成する方法と設定ファイルを編集する方法があります。
私ははじめNetworkManagerで作成したのですが、ゲストをシャットダウン→起動すると、ゲストがネットワークにつながらなくなる問題が発生しました。
そのため、NetworkManagerを停止して設定ファイルを編集してブリッジを作成しています。
なお、IPv4は固定アドレス、IPv6は自動構成です。

# systemctl disable NetworkManager
  ※NetworkManagerを無効化した後DNSの名前解決ができなくなって何か設定変更したはず。
# nano /etc/network/interfaces

auto enp42s0
iface enp42s0 inet manual

auto br0
iface br0 inet static
        address 192.168.0.2
        netmask 255.255.255.0
        network 192.168.0.0
        broadcast 192.168.0.255
        gateway 192.168.0.1
        dns-nameservers 192.168.0.1
        bridge_ports enp42s0
        bridge_stp off

次に、ブリッジを通過する通信に対するNetfilterを無効化します。 ArckWikiによるとセキュリティとパフォーマンス上の理由から推奨とのこと。

# nano /etc/sysctl.conf

net.bridge.bridge-nf-call-ip6tables=0
net.bridge.bridge-nf-call-iptables=0
net.bridge.bridge-nf-call-arptables=0

PCIパススルー関連の設定

事前にUEFIの設定でAMD-V(SVM)とIOMMUを有効化しておきます。

次に/etc/default/grubを編集してLinux側でもIOMMUを有効化します。
kvm_amd.npt=1はNPTの有効化。なくても問題ないかも?)

# nano /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt kvm_amd.npt=1"

# update-grub
# reboot

再起動したらIOMMUが有効になっていることを確認します。

# dmesg | grep -e DMAR -e IOMMU

[    0.420123] AMD-Vi: IOMMU performance counters supported
[    0.421728] AMD-Vi: Found IOMMU at 0000:00:00.2 cap 0x40
[    0.422049] perf/amd_iommu: Detected AMD IOMMU #0 (2 banks, 4 counters/bank).
[    0.537226] AMD IOMMUv2 driver by Joerg Roedel <jroedel@suse.de>

次にIOMMUグループを確認します。
PCIパススルーはIOMMUグループ単位で行われるため、1つのIOMMUグループに複数のデバイスが存在する場合は注意が必要です。
ArchWikiに記載されているスクリプトを使用します。

# nano iommu-group
-----------
#!/bin/bash
shopt -s nullglob
for d in /sys/kernel/iommu_groups/*/devices/*; do 
    n=${d#*/iommu_groups/*}; n=${n%%/*}
    printf 'IOMMU Group %s ' "$n"
    lspci -nns "${d##*/}"
done;
------------

# chmod 755 iommu-group
# ./iommu-group

以下は出力の抜粋です。
IOMMU Group 13 2d:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] [10de:1c82] (rev a1)
IOMMU Group 13 2d:00.1 Audio device [0403]: NVIDIA Corporation GP107GL High Definition Audio Controller [10de:0fb9] (rev a1)
IOMMU Group 16 2e:00.3 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD] USB 3.0 Host controller [1022:145f]

私のPCでは、IOMMU Group 13にゲストに割り当てるGPUGPU内蔵のオーディオが接続されているようです。
また、オンボードUSBコントローラーの1つがIOMMU Group 16に単独で接続されていたため、これもパススルーします。
各行の最後のほうにあるPCI ID([10de:1c82]等)は後で使うので控えておきます。

次にPCIパススルーするデバイスにVFIOドライバを割り当てます。
ArchWikiによると、VFIOドライバの割り当ては仮想マシンの起動時に動的に行われるがGPUドライバは巨大で複雑だから先にやっておけ、とのことです。
この設定方法を調べてみると、/etc/modulesや/etc/modprobe.d/あたりをいじる方法が出てくるのですが、私の環境ではこちらを参考に/etc/initramfs-tools/modulesを編集する方法でVFIOドライバの割り当てに成功しています。

# nano /etc/initramfs-tools/modules
以下を追記。idsにはPCI IDをカンマ区切りで記載します。
vfio_pci ids=10de:1c82,10de:0fb9,1022:145f

# update-initramfs -u
# reboot

再起動後にVFIOドライバが割り当てられていることを確認します。

$ lspci -nnk -d 10de:1c82
2d:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] [10de:1c82] (rev a1)
        Subsystem: Micro-Star International Co., Ltd. [MSI] GP107 [GeForce GTX 1050 Ti] [1462:8c96]
        Kernel driver in use: vfio-pci
        Kernel modules: nvidia

$ lspci -nnk -d 10de:0fb9
2d:00.1 Audio device [0403]: NVIDIA Corporation GP107GL High Definition Audio Controller [10de:0fb9] (rev a1)
        Subsystem: Micro-Star International Co., Ltd. [MSI] GP107GL High Definition Audio Controller [1462:8c96]
        Kernel driver in use: vfio-pci
        Kernel modules: snd_hda_intel

$ lspci -nnk -d 1022:145f
2e:00.3 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD] USB 3.0 Host controller [1022:145f]
        Subsystem: ASRock Incorporation USB 3.0 Host controller [1849:7914]
        Kernel driver in use: vfio-pci
        Kernel modules: xhci_pci

ゲストマシンを作成する

ゲストマシンの作成はvirt-managerを使用してGUIで行いますが、仮想マシンを作成するウィザードの最後で「インストール前に設定をカスタマイズする」にチェックを入れて設定の編集を行います。
編集する箇所は

  • 「ハードウェアを追加」から「ホストPCIバイス」を選択してパススルーするデバイスをゲストに追加する。
  • 仮想のビデオとディスプレイは不要なので削除する。
  • Windows8.1を動作させるためCPUの設定でWindows8.1がサポートしているCPUを選択する。私の環境ではOpteron G3を選択しました。G5とG4ではホストのCPUがサポートしていない命令があるためゲストの起動ができませんでした。
  • 「概要」のファームウェアUEFIを選択する。
  • 「概要」のチップセットで「Q35」を選択する。Q35にしないとUSBオーディオGPU内蔵オーディオの音が途切れたり変になったりします。私はi440FXにしてトラブりました。詳細は最後に記載。

以上の設定が完了したらゲストのインストールを開始します。

最後にNvidiaのドライバをインストール可能にするため、こちらに従ってゲストの設定を編集します。

はじめはトラブった

記事の途中に書いていますが、当初Debian9を使用したこととゲストのチップセットをi440FXにしたことが原因で動作に問題がありました。 参考のため記載しておきます。

  1. 1コアで2スレッドにならない
    RyzenはSMT(インテルの表現ではハイパースレッディング)に対応していますが、Debian9に搭載のカーネルRyzenのSMTに未対応です。対応はkernel 4.10からのようですWindows8.1ゲストのCPUモデルOpteron G3はそもそもSMT未対応なのですが、Windows10ゲスト用にCPU設定をいじっているとエラーが出るなどして問題に気が付きました。

  2. NPT(Nested Page Table)のバグがありPCIパススルーの性能が落ちる
    Debian9に搭載のカーネルはNPTのバグがあり、AMDのCPUでPCIパススルーをした際に20%程度性能が低下するそう。一方、NPTを無効にするとゲストの性能が低下するとのこと。(参考) このバグはKernel 4.15rc1で修正されているらしいです。

  3. USBオーディオが止まる、音かプツプツ途切れる
    パススルーしているUSBコントローラーの先にUSBオーディオ(XONAR U7 MK II)を接続して音を出すと止まることが判明しました。

    • Firefox+ニコニコ動画だと数秒再生したところで停止。
    • Windows Media Playerだと1秒も再生できない。
    • XONAR U7 MK II付属の設定ツールを起動しても画面が表示されない。
    • USBオーディオ以外にも、DisplayPortからの音もおかしい(遅れてエコーがかかったような状態)

上記のNTPバグが原因と疑ってkernel 4.19搭載のDebian10(テスト版)にアップグレードしたところ、音かプツプツ途切れるが停止することはなくなりました。

さらに原因を調べると、ArchWikiにゲストが使用する割り込み方法の問題との記載がありました。

ArchWikiに記載の解決策はゲストのレジストリを編集するとのことでしたが、ふと「ゲストのチップセットをi440FXより新しいQ35にしたら解決するのでは?」と思ってゲストを再作成して試したところ無事解決。
ゲストが使用する割り込みの方法がLine-Based InterruptsではなくMSI (Message Signaled-Based Interrupts)になっており、音が正常に再生されるようになりました。

Windoww7のサポート終了に向けて移行先OSを考える

Windoww7のサポート終了と移行先OS

Windows7のサポートが2020年1月14日で終了します。 私が自宅で使用しているメインのPCはWindows7なので別のOSへ移行しなければならないのですが、 そのOSの選択に困る事態になっています。

信用できないOS:Windows10

現時点での最新版Windowsといえば勿論Windows10ですが、以下のように問題がありメインのPCでは使いたくありません。

  • 頻繁な機能更新と強制アップデート。そして不具合。
    Windows10の特徴といえば制御困難なWindows Update、それに乗っかってくる不具合と半年ごとの機能更新です。 OSはハードウェアを制御し、アプリケーションを動かし、データを管理する、PCを支えるインフラです。 そんなインフラが頻繁に仕様変更される状況では安定してPCを使用することは出来ません。しかも不具合が多い。

  • Microsoftへの情報送信。設定箇所は複数、しかも奥の方にある。
    Windows10では、初回起動時に使用状況データの送信量を「基本」と「完全」から選択できます。 しかし使用状況データの設定とは別に、Microsoftへの情報送信に関連する設定が複数存在しています。
    Windows Defenderのサンプル送信や、アプリケーションが異常終了した際のエラー報告の設定などです。 デフォルトで自動送信が有効になっています。
    しかも、これらの設定項目は機能更新の際に追加・削除・変更が行われる可能性があります。 Windows10を使用している限り、機能更新→設定項目を探す→設定修正という事を繰り返さなければなりません。

Linuxへすぐに移行するのは厳しい

Windows10が信用出来ない以上、いずれはLinuxへ移行しなければならないと考えています。 しかしながら、Linuxはそこそこ使用しているもののサーバー用途が主であり、デスクトップ用途では殆ど使用したことがありません。 その様な状況で、長年使用し続けたWindowsをいきなり手放すことは困難です。

とりあえずWindows8.1移行しよう

Windows8.1なら2023年1月11日までサポートが続きます。 人気のないOSですが、その原因はスタートメニューを初めとしたUI周りがほぼ全てでしょう。 つまり、Classic shellなどでカスタマイズすれば何も問題の無いOSです。

最新CPUの対応が打ち切られた問題

MicrosoftIntelの第7世代以降のCPUやAMDの第7世代以降のCPUをサポートするOSはWindows10のみであると発表しました。 Windows8.1をサポート対象外のCPUを搭載したPCにインストールしてもWindows Updateが出来ないそうです。
この問題を回避する手法として、Windows Update関連のシステムファイルを古いバージョンに戻したり非公式のパッチを当てると言う方法が存在してるようですが、 その様な方法では安定した運用を期待することは難しいと思われます。

旧世代のハードウェアを使用するという方法もありますが、そうしたハードウェアの入手は時が経つほど難しくなり、故障時の代替が出来なくなります。

QEMU/KVMで仮想化する

Linuxで使用されている仮想マシンQEMU/KVMでは、設定項目としてゲストマシンのCPUモデルを選択可能です。 仮想マシン側で旧世代のCPUを設定することで、その中で動作するWindows8.1は「サポート対象のCPUである」と騙されるのではないか?と考えました。

試しに第7世代(Kaby Lake)のIntel Pentium G4560上にDebian9をインストールして仮想環境を構築してみたところ、 「ハードウェアがサポートされていません」などのメッセージは表示されず、Windows Updateも問題なく実施できました。 しかし、仮想グラフィックの性能の低さや、USBデバイスを気軽に接続出来ない(その都度ゲストマシンの設定変更が必要)といった問題があります。 そこでPCIパススルーをしてGPUとUSBコントローラーを直接ゲストマシンに接続することにしました。

次期メインPCとしてRyzen7 2700Xを搭載したPCを組み上げて、GPUとUSBコントローラーのパススルー設定をしました。勿論CPUモデルは旧世代に設定しています。 しばらくの試行錯誤の末、最新CPU上で(仮想化して)快適なWindows8.1環境が出来ました。 あとは、この環境が安定して動作する事を祈るだけです。

余談:仮想化するもう一つのメリット

仮想環境なので同じPCでLinuxやWindows10を動かせます。

Linuxへの移行準備を進める環境としても使用できますし、 Windows8.1サポート終了後にどうしてもWindowsが必要な場合にはWindows10を起動するも可能です。