ディスクの完全消去
ディスクワイプを行うには全てのビットに新しいデータを書き込みます。
一般的なユースケース
デバイス上に残っているデータを全て消去
デバイスを完全に、二度と復旧できないように消去する最も一般的な理由としては、デバイスを廃棄するまたは売り飛ばす場合が考えられます。デバイス上に (暗号化されていない) データが残っている可能性を考えると、簡単にデータをとり出される前に対処しておいたほうが良いでしょう。データを盗むことはファイルリカバリソフトウェアなどを使えば朝飯前です。
ディスク上の全てのデータを素早く消去したいという場合、/dev/zero
のようなシンプルなパターンを使うのが一番効率がよく、それでいて十分なランダム性を確保できます。詳しくはデータの残留で説明しています。
ビットを全て上書きしてデータを消去すると通常のシステムの機能 (標準の ATA/SCSI コマンドなど) やハードウェアのインターフェイスでリカバリすることはできなくなります。上で述べたようなファイルリカバリソフトウェアがデータを復旧させようとしたら、プロプライエタリなストレージハードウェアの機能を使う必要が出てきます。
HDD の場合、ドキュメントになってないドライブコマンドが存在するとか、デバイスのコントローラやファームウェアを弄って再配置セクタ (S.M.A.R.T. が使用を止めた不良セクタ) を読み出すなどしないかぎり、データの復旧は不可能になります。
ディスク消去には物理ストレージの形式によって様々な問題が存在します。中でもフラッシュメモリデバイスや旧式の磁気ストレージ (古い HDD や、フロッピーディスク、テープなど) は注意する必要があります。
ブロックデバイス暗号化の準備
完全に消去した領域にディスク暗号化を設定したいという場合、暗号強度が高い乱数生成器 (Random Number Generator、以下 RNG と呼称します) による、ランダムデータを使用するべきでしょう。
Wikipedia:Random number generation を参照してください。
対象の選択
fdisk を使うことでユーザーが読み取りアクセスできる全ての読み書きデバイスを見つけることができます。
/dev/sdX
などのデバイスで始まる行の出力をチェックしてください。
以下は Linux システムを起動するようにフォーマットされた HDD の例です:
# fdisk -l
Disk /dev/sda: 250.1 GB, 250059350016 bytes, 488397168 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00ff784a Device Boot Start End Blocks Id System /dev/sda1 * 2048 206847 102400 83 Linux /dev/sda2 206848 488397167 244095160 83 Linux
4GB USB メモリードライブに書き込まれた Arch のインストールメディアの例:
# fdisk -l
Disk /dev/sdb: 4075 MB, 4075290624 bytes, 7959552 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x526e236e Device Boot Start End Blocks Id System /dev/sdb1 * 0 802815 401408 17 Hidden HPFS/NTFS
コンピュータの重要なデータが間違って破損してしまうのが心配であれば、仮想環境などの分離された環境 (VirtualBox, VMWare, QEMU など) を使用してディスクドライブを直接接続するか、あるいは消去する必要があるストレージディスクだけを接続してライブメディア (USB, CD, PXE など) から起動してください。
ブロックサイズの選択
Wikipedia:Dd (Unix)#Block size, blocksize io-limits も見て下さい。
Advanced Format のハードドライブを使用している場合、ブロックサイズをデフォルトの512バイトよりも大きく指定することを推奨します。高速に書き換え処理を行うために、あなたの使用しているドライブの物理的なジオメトリにブロックサイズを合わせて下さい。dd コマンドにブロックサイズオプションを追加することで指定できます (例: 4KB の場合 bs=4096
)。
fdisk は全てのディスクの物理セクタと論理セクタのサイズを出力します。
もしくは sysfs によっても情報を得ることができます:
/sys/block/sdX/size /sys/block/sdX/queue/physical_block_size /sys/block/sdX/queue/logical_block_size /sys/block/sdX/sdXY/alignment_offset /sys/block/sdX/sdXY/start /sys/block/sdX/sdXY/size
消去するブロックを手動で計算
以下では消去するべきデータ領域を決定する例を示します。
A block storage devices contains sectors and a size of a single sector that can be used to calculate the whole size of device in bytes. You can do it by multiplying sectors with size of the sector.
dd コマンドを使ってパーティションを消去するパラメータの例:
# dd if=data_source of=/dev/sdX bs=sector_size count=sector_number seek=partitions_start_sector
Here you will see only a part of output of fdisk -l /dev/sdX
with root, showing the example partition information:
Device Boot Start End Sectors Size Id Type /dev/sdXA 2048 3839711231 3839709184 1,8T 83 Linux /dev/sdXB 3839711232 3907029167 67317936 32,1G 5 Extended
fdisk の出力の最初の行からディスク容量と論理セクタがわかります:
Disk /dev/sdX: 1,8 TiB, 2000398934016 bytes, 3907029168 sectors
論理セクタのサイズを計算するには echo $((2000398934016 / 3907029168))
を実行するか fdisk の出力の2行目のデータを利用してください:
Units: sectors of 1 * 512 = 512 bytes
物理セクタの計算については3行目を使います:
Sector size (logical/physical): 512 bytes / 4096 bytes
To get disk size in the physical sectors you will need the known disk size in bytes divided with size of a single physical sector echo $((2000398934016 / 4096))
, you can get size of the storage device or partition on it even with the blockdev --getsize64 /dev/sd"XY"
command.
/dev/sdXA
パーティションを消去する場合、使用する論理セクタのパラメータは以下のようになります:
Start=2048 End=3839711231 BytesInSector=512
seek=
オプションでデバイスのパーティションの開始アドレスを使ってください:
# dd if=data_source of=/dev/sd"X" bs=${BytesInSector} count=${End} seek=${Start}
パーティションの名前を使用:
LogicalSectors=3839709184
# dd if=data_source of=/dev/sd"XA" bs=${BytesInSector} count=${LogicalSectors}
もしくは、ディスク全体を消去するには:
AllDiskPhysicalSectors=488378646 PhysicalSectorSizeBytes=4096
# dd if=data_source of=/dev/sd"X" bs=${PhysicalSectorSizeBytes} count=${AllDiskPhysicalSectors} seek=0
データソースの選択
先に述べた通り、重要なデータを消去したいときは、必要に応じて手段を選ぶことができます。
消去した後にブロックデバイスの暗号化をセットアップしたい場合、データソースとして暗号を使用して消去を行うべきでしょう。最低でも擬似乱数によるデータを使って下さい。
ランダムなデータを使わない場合、ディスクの書き込み速度によって実行時間が変わります。ランダムなデータが必要な場合、ランダムデータを生成するシステムの性能とエントロピーのソースによって実行時間は変わります。
ランダムではないデータ
大抵は /dev/zero
などのシンプルなパターンで上書きするので安全です。高速にディスク消去をしたい場合は十分でしょう。
パターン書き込みのテスト
Badblocks はシンプルなパターンをデバイスのブロックに書き込むことができ、壊れた領域がないか検索してチェックすることができます (memtest86* がメモリで行うのと同じようなテストです)。
アクセス可能なブロック全てにパターンが書き込まれるため、効率的にデバイスを消去することができます。
ランダムデータ
ランダムまたは擬似的にランダムなデータをソースとして使う場合、乱数生成を見て下さい。
暗号データ
フルディスク暗号化用にドライブを準備する際に、高品質なエントロピーを使用する必要はありません。暗号化されたデータストリームを使うことで間に合います。例えば、AES を使ってパーティションを暗号化する場合、ファイルシステムを作成する前に同じ暗号を使ってディスクを消去することで、使用している領域と空き領域を判断することができなくなります。
対象の上書き
選択したドライブをユーティリティを使って上書きします。都合に合わせて選択してください。単一のファイルだけ削除したい場合、ディスクの完全消去/ヒントとテクニック#単体ファイルの消去に以下で説明しているユーティリティの追加説明があります。
出力のリダイレクト
出力をリダイレクトすることで空き領域にファイルを作成するだけでなく、デバイスやパーティションを消去することもできます。
以下の例では他のユーティリティの stdout をリダイレクトしてパーティションやブロックデバイスを書き換えています:
$ cat /dev/urandom > /dev/sd"XY"
cat: write error: No space left on device
$ xz -z0 /dev/urandom -c > /dev/sd"XY"
xz: (stdout): Write error: No space left on device
$ dd if=/dev/urandom > /dev/sd"XY"
dd: writing to ‘standard output’: No space left on device 20481+0 records in 20480+0 records out 10485760 bytes (10 MB) copied, 2.29914 s, 4.6 MB/s
ファイルコピーコマンド cp
でもデバイスを書き換えられます:
$ cp /dev/urandom /dev/sd"XY"
cp: error writing ‘/dev/sd"XY"’: No space left on device cp: failed to extend ‘/dev/sd"XY"’: No space left on device
書き込み速度や残り時間を表示するには pv を使用:
# pv --timer --rate --stop-at-size -s "$(blockdev --getsize64 /dev/sd"XY" )" /dev/zero > /dev/sd"XY"
dd
Core Utilities#dd を参照してください。
/dev/zero ストリームを使用してディスク上の全ての領域をゼロバイトで埋める:
# dd if=/dev/zero of=/dev/sdX bs=4096
もしくは /dev/urandom ストリームを使用:
# dd if=/dev/urandom of=/dev/sdX bs=4096
dd が No space left on device
と報告したら処理は完了です:
dd: writing to ‘/dev/sdb’: No space left on device 7959553+0 records in 7959552+0 records out 4075290624 bytes (4.1 GB) copied, 1247.7 s, 3.3 MB/s
巨大なドライブを高速に消去する方法は、以下を見て下さい:
- ディスクの完全消去/ヒントとテクニック#dd - 高度な例では OpenSSL を使用します。
- ディスクの完全消去/ヒントとテクニック#テンプレートファイルを使うではランダムではないデータによって高速にデータを消去します。
- Dm-crypt/ドライブの準備#インストール前に dm-crypt で消去では dm-crypt を使います。
wipe
ファイルの消去に特化しているツールで、wipe パッケージでインストールできます。クイックワイプを実行するには以下のようなコマンドを使用します:
$ wipe -r -q /path/to/wipe
参照: man ページ。
shred
shred は個別のファイルやデバイスを安全に消去することができる Unix コマンドです。たとえ特殊な機械を使っても復元するのは難しく、あるいは不可能になります。shred は3つのパスを使って、擬似乱数データをデバイスに書き込みます。パスは増やしたり減らしたりできます。
以下のコマンドはデフォルト設定で shred を実行して進捗を表示します:
# shred -v /dev/sdX
もしくは /dev/urandom
のエントロピーだけを使って1つのパスで shred を実行することも可能です:
# shred --verbose --random-source=/dev/urandom -n1 /dev/sdX
Badblocks
badblocks でディスク消去を行うには、破壊的な read-write テストを実行します:
# badblocks -c <NUMBER_BLOCKS> -wsv /dev/<drive>
hdparm
hdparm は ATA Secure Erase をサポートしています。これはディスクをゼロで埋めるのと機能的には同一です。ただし、ハードドライブのファームウェアによって処理されるのが違っていて、"隠しデータ領域"も含まれます。そのため、今日における"ローレベルフォーマット"コマンドとして考えても良いでしょう。このコマンドを実行することで SSD ドライブは生産時のパフォーマンスを発揮することができると言われていますが、十分な消去とまでは言えない可能性もあります (#フラッシュメモリを参照)。
ドライブによっては、メーカーによって定義されたパターンを使用する Enhanced Secure Erase がサポートされていることがあります。hdparm -I
の出力で Enhanced 消去が利用できると表示される場合、デバイスにはハードウェア暗号化機能が備わっており、消去は暗号鍵だけで実行されます。
ATA Secure Erase の使用法に関する詳細はソリッドステートドライブ/メモリセルの消去や Linux ATA wiki を見て下さい。
secure-delete
AUR の secure-deleteAUR パッケージには安全な消去のためのユーティリティが複数含まれています。例えば sfill
は特定のマウントポイントの空き領域だけを消去します。例:
# sfill -v /
詳しくは ツールのリスト を見て下さい。
データの残留
Wikipedia:Data remanence を参照してください。
たとえデータの削除・消去を行った後でも、データが残留している可能性は存在します。
一回だけでなく複数回、繰り返しディスクに(ランダムな)データを書き込むことで残留データを消去できるかもしれませんが、複数回書き換えることでハードディスクドライブのデータを復元できる可能性が劇的に減るわけではありません。#残留磁気を見て下さい。
オペレーティングシステム、プログラム、ファイルシステム
オペレーティングシステムや実行プログラム、あるいはジャーナリングファイルシステムは暗号化されていないデータをブロックデバイスの至る所にコピーする可能性があります。暗号化されていないディスクに書き込みを行う場合にのみ関係してきます。
ディスク上のデータの位置を正確に把握することができるのであれば、エントロピープールさえ十分ならランダムデータによる消去は驚くほど高速に行われます。
/dev/urandom
を使って LUKS キースロットを消去する cryptsetup が良い例です。
ハードウェア特有の問題
フラッシュメモリ
ライトアンプリフィケーションなどの機能があるために、フラッシュメモリを完全に消去するのは厄介です。デバイスのコントローラチップから見えるデータと、オペレーティングシステムから見えるデータの間には、透過的な抽象レイヤーが多数存在しており、データの書き込まれる場所が食い違っているために、特定のブロックやファイルを消去したとしても確実にデータが書き換えられているとは限りません。
(SandForce の全ての SSD に搭載されている) 透過圧縮などの"機能"は /dev/zero
などのパターンストリームを圧縮してしまうことがあり、信じられないほど速く消去が終わってしまった場合、圧縮されてしまっている可能性があります。
Flash メモリデバイスを解体して、チップのハンダ付けを取り除き、中に入っているコントローラを使わずにデータの中身を解析することは 単純なハードウェア だけで簡単に行えてしまいます。データ復旧会社は安価にこれをしています。
詳細は次を参照: Reliably Erasing Data From Flash-Based Solid State Drives。
不良セクタ
ハードドライブが不良セクタを認識すると、セクタへのアクセスが遮断され、ソフトウェアからはその領域に書き込みできなくなります。それによって、完全な書き換えがその領域にまで及ばない可能性があります。ただし、ブロックサイズから考えて、理論上、その領域からリカバリできるサイズはあくまで数 KB ほどしかありません。
残留磁気
最近の高密度なストレージデバイスでは一回ゼロやランダムデータで上書きした時点でデータは全て消去されます [1]。残されたビットからバイトパターンを復元することは基本的に不可能です [2]。[3], [4], [5] も参照してください。