ハードディスク内のデータを本当の意味で完全消去する方法

# はじめに
Ubuntu をインストールしたマシンを他人に渡す機会があり、ハードディスクの中にあるデータを完全に消去しました。この記事では、その方法と、完全に消去するとはどういうことなのか、`rm` コマンドではダメなのか、ということについて説明したいと思います。

## 注意事項 1
タイトルには「本当の意味で完全消去する」という表現を使いましたが、**ハードディスクのプロがデータを復元しようとして、一部でも復元できてしまう可能性がないことを保証するものではありません**。あらかじめご了承ください。

## 注意事項 2
データを完全消去するだけで、ハードディスクが壊れるわけではないですが、**万が一ハードディスクが故障してしまっても責任は負いません**。自己責任にてお願いします。また、ハードディスクをハンマーで粉々にする場合はこの限りではありません。当然壊れます。

## 注意事項 3
当たり前なのですが、本当の意味で完全にデータが消去されるので、**一度実行するとデータは二度と元には戻せません**。実行する前に大切なデータを事前にバックアップしてください。

# TL;DR
#### 不良品のためマシンを交換したり、返品したり、売却したり、他人に譲渡したりする場合 (論理的削除)
1. `df` コマンドを実行して `Mounted on` が `/` になっている行のファイルシステム名 (`Filesystem`) をコピーする
2. 以下のコマンドを実行する

```bash
$ sudo shred -uvz <ファイルシステム名>
```

#### 廃棄する場合 (物理的削除)
1. マシンからハードディスクを取り出し、ハンマーなどでハードディスクを粉々にする (**注意: ハードディスクが壊れます**)

# rm コマンドではダメなのか？
「データを削除する」と聞いて一番最初に思いつくのは `rm` コマンドではないでしょうか。`rm` コマンドを利用して削除すると、OS の操作では復元することはできませんが、ハードディスクの中身を解析すれば復元することは可能です。そのため、他人に渡すような場合は、もし相手がハードディスクに詳しければ中に入っていたデータを復元されてしまう可能性を否定できません。

もう使わなくなったからといって、興味本位で `rm -rf --no-preserve-root /` を実行する人がいますが、これだけではハードディスク内のデータが本当の意味で消去されたわけではないことを覚えておきましょう。

# shred コマンドを使おう
ここで登場するのが `shred` コマンドです。このコマンドを使用するとハードディスク内にランダムな値を書き込んだり、`0` で埋めたりすることができます。

「[ファイルを完全に消去するには](http://www.atmarkit.co.jp/flinux/rensai/linuxtips/662delfile.html)」に記載されている通り、`0` で埋めただけだと、「0 を 0 に上書きした場合」と「1 を 0 に上書きした場合」の違いを読み取って、元のデータを取り出すことができてしまいます。なので、確実にデータを消去するためには、ランダムな値を書き込んだ後に、`0` で埋める処理をすることになります。`0` で埋めなくてもデータを復元することは相当困難になりますが、より確実になります。他人に譲渡するときなどはやっておくと良いでしょう。

では、実際に `shred` コマンドを使用してデータを完全消去する手順について説明します。

## ファイルシステム名を調べる
`df` コマンドを使用して、`/` (root) がマウントされているファイルシステムを調べます。

```bash
$ df
```

上記コマンドを実行するといくつかのファイルシステムと空き容量などの情報が表示されます。この中で、一番右の項目の `Mounted on` が `/` になっているものを見つけます。`Mounted on` が `/` になっている部分の一番左の項目の `Filesystem` をコピーしておきます。今後、このファイルシステム名を仮に `<ファイルシステム名>` と表記します。`<ファイルシステム名>` は各人の環境によって異なるため、`df` コマンドで調べた結果を元に置き換えてください。

## shred コマンドの実行
あとは、以下のコマンドを実行するだけで完了です。

```bash
$ sudo shred -uvz <ファイルシステム名>
```

### 注意点
このコマンドの実行にはかなりの時間がかかります。Intel Pentium、メモリ 4GB の Ubuntu マシンで約 30GB のハードディスクのデータを完全消去したところ、コマンドが実行完了するまでに **1 時間以上** かかりました。ハードディスクやマシンの性能によって実行時間は変動しますが、ハードディスクの容量が大きければ大きいほど実行にかかる時間は当然増えます。

注意点としては、**このコマンド実行中にスリープモードになったりサスペンド状態になったりしないように、あらかじめ設定を変更** しておきましょう。

### macOS の場合
クリーンな状態の (環境構築などを一切していない) macOS が手元にないので確かなことは言えないのですが、おそらく初期状態の macOS だと `shred` コマンドはインストールされていないのではないかと思われます。もしインストールされていなかった場合は以下のコマンドでインストールできるはずです。

```bash
$ brew install coreutils
```

Homebrew のインストールや環境変数の設定についてはここでは割愛します。環境変数の設定が面倒な場合は、インストール後、`shred` の代わりに `gshred` とすれば実行できそうな気もしますが、試していないのでなんとも言えません。

参考: [Using `shred` from the command line](https://superuser.com/questions/617515/using-shred-from-the-command-line)

また、macOS では `shred` コマンドを試していないので、この記事と同じ手順でデータの完全消去ができるかどうかの保証はできません。ご了承ください。

### オプションの説明
ここでオプションについて説明しておきます。

#### Remove file
`-u` は、ランダム値での書き込みや `0` 埋めを行った後にファイルを削除するオプションです。デフォルトだとファイルの削除は行いません。

#### Output verbosely
`-v` は、コマンド実行の進捗状況を表示するオプションです。`shred` コマンドの実行にはかなりの時間がかかるため、実行完了まで何も表示がないと、ちゃんと実行が進んでいるのかフリーズしているのかわかりません。なので `-v` はつけておくことをおすすめします。

#### Fill with zero
`-z` は、ランダム値での書き込みを行った後に `0` 埋めを行うオプションです。デフォルトだと `0` 埋めは行われません。

#### Overwrite N times
また、今回は使用しませんでしたが `-n` というオプションもあります。これは直後の引数に数字を渡すことによって、その回数分、ランダム値の書き込みを行います。この回数が増えれば増えるほどデータの復元は困難になりますが、当然実行時間が長くなります。

目安として、3 回行えばデータの復元はほぼ不可能と言われています。ですが、3 回行ったからといって、絶対にデータが復元できなくなることを保証するものではありません。あくまで目安です。

デフォルトは 3 回です。なので、このオプションを指定しなければ 3 回実行されることになります。

他にもいくつかオプションがありますが、基本的にはこのあたりをおさえておけば問題ないと思います。もっと詳しく知りたい方は `man shred` などで調べると良いでしょう。

# コマンド実行後
コマンドの実行が終わった後、本当の意味でデータが完全消去されているかを確認するのは容易ではないですが、簡易的には `ls` コマンドなどを実行して、元々あったファイルがきれいになくなっていればおそらく問題ないと思われます。

なお、このコマンド実行後は、すでに起動している端末を除くすべてのアプリケーションが起動不可能になります。root ごと削除しているので、いくつかのコマンドも使えなくなっています。シャットダウンや再起動を行おうにも `shutdown` コマンドや `reboot` コマンドも使用できなくなっています。

GUI の操作でシャットダウンや再起動を行うことはできますが、一旦シャットダウン・再起動をしてしまうと、もうその状態では OS をブートすることはできなくなります。Ubuntu の場合だと GRUB の画面が出てきますが、元々のファイルシステムでブートすることはおそらくできないはずです (もしかしたらできるのかもしれませんが、試した限りではできませんでした)。

この状態になっていればデータの完全消去はできているはずですので、そのまま電源を落として譲渡するなり売却するなりしてください。

# おまけ: dd コマンドを使用する方法 (実行不要)
これはおまけなので試す必要はありません。あくまで知識として共有しておきます。

調べれば簡単に出てきますが、`shred` コマンドではなく `dd` コマンドを使ってデータを完全消去する方法もあります。やっていることは `shred` コマンドと同じです。というより、`shred` コマンドの実行内容に相当する処理を `dd` コマンドで代用することも可能という程度です。


```bash
# 実行不要
$ sudo dd if=/dev/urandom of=<ファイルシステム名>
$ sudo dd if=/dev/urandom of=<ファイルシステム名>
$ sudo dd if=/dev/urandom of=<ファイルシステム名>
$ sudo dd if=/dev/zero    of=<ファイルシステム名>
```

`/dev/urandom` を使ってランダム値を書き込むという処理を `<ファイルシステム名>` に対して 3 回行います。その後、`/dev/zero` を使って `0` 埋めします。

ちなみにこちらのコマンドは試していないので上記コマンドが正しいかどうかの保証はできません。

参考: [オペレーティングシステムの標準コマンドを用いた消去処理の例 - データの完全消去 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E5%AE%8C%E5%85%A8%E6%B6%88%E5%8E%BB#%E3%82%AA%E3%83%9A%E3%83%AC%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AE%E6%A8%99%E6%BA%96%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E7%94%A8%E3%81%84%E3%81%9F%E6%B6%88%E5%8E%BB%E5%87%A6%E7%90%86%E3%81%AE%E4%BE%8B)

# さいごに
ハードディスク内のデータを完全消去する方法について説明しました。この方法を使えばハードディスク内のデータの復元は、実質、ほぼ、限りなく 0 に近いくらい不可能になります。ただし、繰り返しになりますが、この方法でデータが絶対に復元できなくなることを保証することはできません。やはり、絶対にデータを復元されたくない場合は、ハードディスクをハンマーなどで粉々にするしかないと思います。その場合は他人に譲渡したりできなくなりますが。

また、この記事の趣旨でもあるので当然ですが、この手順を実行すると、データは二度と元には戻せなくなります。データ復旧サービスというものもありますが、おそらくこの方法を試した後では無理でしょう。なので、コマンドを実行する前に、本当にデータを完全消去しても大丈夫かどうか、今一度確認してください。大切なデータが消えてしまっても、責任は負いません。

それから、この方法を試したことでハードディスクが壊れることはない (ハンマーで粉々にする場合は別) ですが、こちらも保証はできません。一応、自分の環境で、`shred` コマンドでデータを完全消去した後、Ubuntu を再インストールしてみましたが、特に問題なく使えました。あまり何度も書き込みを繰り返すと、ハードディスクの書き込み上限に達して使えなくなる可能性は否定できないので注意してください。

# 参考サイト
- [秘密にしたいファイルを完全に削除する方法](https://tech.nosuz.jp/2015/12/ubuntu-delete-files/)
- [ファイルを完全に消去するには](http://www.atmarkit.co.jp/flinux/rensai/linuxtips/662delfile.html)
- [[FreeBSD][Linux] ファイル/デバイス完全消去には(g)shred](http://d.hatena.ne.jp/flageo/20130117/p1)
- [Using `shred` from the command line](https://superuser.com/questions/617515/using-shred-from-the-command-line)
- [オペレーティングシステムの標準コマンドを用いた消去処理の例 - データの完全消去 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E5%AE%8C%E5%85%A8%E6%B6%88%E5%8E%BB#%E3%82%AA%E3%83%9A%E3%83%AC%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AE%E6%A8%99%E6%BA%96%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E7%94%A8%E3%81%84%E3%81%9F%E6%B6%88%E5%8E%BB%E5%87%A6%E7%90%86%E3%81%AE%E4%BE%8B)