NetBSD-7.0でCGD(cryptographic disk driver)を設定してみる

勉強会での発表や旅行先でコードを書いたりするため、NetBSDをインストールしたノートPCを持ち歩くのはよくある光景だと思います。とはいえ、あちこち持ち歩くPCでHDDやSSDの中身を暗号化しないのは少し不安な面もあります。そこでNetBSD Advent Calendar 22日目の記事では、NetBSDにおけるディスク暗号化機能のCGD(Cryptographic Device Driver)の設定方法を紹介してみます。

が、筆者もCGDを使ってみたいなと思いつつ、この記事を書くまではまったくCGDを設定したことがなかったので、完全に[The NetBSD Guide](https://www.netbsd.org/docs/guide/en/chap-cgd.html)からの受け売りです...。

## NetBSD-7.0とCGD

cgd(4)をみると、CGD自体はNetBSD-2.0の頃から提供されている機能のようです。では何故ここでCGDの話？と思われるかもしれませんが、NetBSD-7.0では以下のようにデフォルトでcgdが有効になるようような設定になっています。

![スクリーンショット 2015-12-22 22.22.13.png](https://qiita-image-store.s3.amazonaws.com/0/61137/49e159e6-4493-070d-7740-f2119865a109.png)

加えて私自身もCGDを使ってみたいこともあり、Advent Calendarの記事にしてみたという次第であります。

## CGDを設定してみる

ゆくゆくはノートPC上のNetBSDでCGDを設定したいところですが、今回はCGDの設定練習をかねて仮想マシン上で試してみます。CGDで暗号化するパーティションはルートパーティションと分けておく必要があるため、例として/mycgdのような別パーティションに分けておきます。

![スクリーンショット 2015-12-22 22.20.38.png](https://qiita-image-store.s3.amazonaws.com/0/61137/25071267-f52d-7255-5507-ede24d71f5cc.png)

上記のパーティション設定でインストールしたNetBSDのディスク構成は以下のようになります。この段階では/dev/wd0eとして/mycgdがマウントされていますが、この部分が最終的にCGDで暗号化された状態になります。

```
# df -h 
Filesystem         Size       Used      Avail %Cap Mounted on
/dev/wd0a          1.0G       651M       323M  66% /
/dev/wd0e          450M       1.0K       427M   0% /mycgd
kernfs             1.0K       1.0K         0B 100% /kern
ptyfs              1.0K       1.0K         0B 100% /dev/pts
procfs             4.0K       4.0K         0B 100% /proc
tmpfs              128M         0B       128M   0% /var/shm
```

手始めに/mycgdをアンマウントします。

```
# umount /mycgd 
```

CGDの設定はcgdconfig(8)を用いて行います。"-s"で標準入力から鍵を読み込むという指定です(ここでは/dev/urandomのデータを鍵にしている)。CGDのデバイス名としてcgd0、実際のデバイスとしてwd0e、暗号アルゴリズムはAES-CBC 256を指定しています。

余談ですが、The NetBSD Guideの[Chapter 14. The cryptographic device driver (CGD)](https://www.netbsd.org/docs/guide/en/chap-cgd.html)ではaes-cbc 128を指定していますが、cgd(4)をみると256ビットまで設定可能なようなので、ここではできるだけ長いビットを指定します。

```
# cgdconfig -s cgd0 /dev/wd0e aes-cbc 256 < /dev/urandom 
```

cgdのrawパーティションをゼロフィルします。NetBSD-i386,amd64では/dev/rcgd0dですが、他のプラットフォームでは/dev/rcdg0cなので注意が必要です。
(ラズパイ+NetBSDでCGDを設定したいときに思い出すとよさそうです)

```
# time dd if=/dev/zero of=/dev/rcgd0d bs=32k
```

以降のCGD設定のため、-uでCGDをunconfigします。

```
# cgdconfig -u cgd0  
```

paramsファイルを生成します(-gオプション)。ファイルの出力先は-oで指定します。

```
# cgdconfig -g -V mycgd_disk -o /etc/cgd/wd0e aes-cbc 256
```

以下のようなファイルが生成されます。

```
# cat /etc/cgd/wd0e   
algorithm aes-cbc;
iv-method encblkno1;
keylength 256;
verify_method none;
keygen pkcs5_pbkdf2/sha1 {
        iterations 445653;
        salt AAAAgJIkNE6FNZudfgIulzTEDcI=;
};
```

"cgdconfig -V re-enter"を実行するとパスフレーズの入力を求められます。初回の入力内容がパスフレーズとして設定されるので慎重に忘れないよう入力します。

```
# cgdconfig -V re-enter cgd0 /dev/wd0e  
/dev/wd0e's passphrase:
re-enter device's passphrase:
```

## CGDパーティションをnewfsする

あとは忘れずにCGDパーティションについてdisklabelを設定したのち、newfsします。

```
# disklabel -i -I cgd0d                                                        
Enter '?' for help
partition>P
4 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a:    979729         0     4.2BSD      0     0     0  # (Cyl.      0 -    478*)
 d:    979729         0     unused      0     0        # (Cyl.      0 -    478*)
partition>a
Filesystem type [4.2BSD]: 
Start offset ('x' to start after partition 'x') [0c, 0s, 0M]: 
Partition size ('$' for all remaining) [478.38330078125c, 979729s, 478.38330078125M]: $
partition>P
4 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a:    979729         0     4.2BSD      0     0     0  # (Cyl.      0 -    478*)
 d:    979729         0     unused      0     0        # (Cyl.      0 -    478*)
partition>W
Label disk [n]?
partition>Q
```

```
# newfs /dev/rcgd0a 
/dev/rcgd0a: 478.4MB (979728 sectors) block size 8192, fragment size 1024
	     using 11 cylinder groups of 43.49MB, 5567 blks, 10816 inodes.
super-block backups (for fsck_ffs -b #) at:
32, 89104, 178176, 267248, 356320, 445392, 534464, 623536, 712608, 801680,
...............................................................................
# 
```

## 起動時にCGDなパーティションをmountする

CGDなパーティションが作成できたので、NetBSDの起動時に暗号化したパーティションがmountされるように設定してみます。

まずは/etc/cgd/cgd.confに以下の設定を追加します。

```
# cat /etc/cgd/cgd.conf 
cgd0  /dev/wd0e
```

/etc/rc.confにcgd=YESを追加します。
(NetBSD-7.0ではデフォルトでcgdが有効になっているので、この記述は不要かも...)

```
# grep cgd /etc/rc.conf
cgd=YES
```

この状態で再起動すると、以下のように起動の途中でパスフレーズの入力を求められます。

![スクリーンショット 2015-12-22 23.01.39.png](https://qiita-image-store.s3.amazonaws.com/0/61137/9bb5366f-4d94-ede6-cb6f-891c1d507aaa.png)

パスフレーズを入力して起動すると、以下のようにCGDなパーティションがmountされます。(当たり前ですが)CGDパーティション上でファイルの読み書きも可能です。

```
# df -h
Filesystem         Size       Used      Avail %Cap Mounted on
/dev/wd0a          1.0G       651M       323M  66% /
/dev/cgd0a         464M       2.0K       440M   0% /mycgd
kernfs             1.0K       1.0K         0B 100% /kern
ptyfs              1.0K       1.0K         0B 100% /dev/pts
procfs             4.0K       4.0K         0B 100% /proc
tmpfs              128M         0B       128M   0% /var/shm
```

加えてcfgconfig -lでcgdデバイスの状態を確認できます。先に設定したwd0eがcgd0となっていますね。

```
# cgdconfig -l                                                                 
cgd0: wd0e 
cgd1: not in use
cgd2: not in use
cgd3: not in use
```

## まとめ

NetBSD-7.0でパーティションの暗号化機能を提供するCGDを試してみました。思いのほかすんなり設定ができたので内心驚いています(最悪今日中には設定できないかと思ってた...)。特に持ち歩き用のノートPC+NetBSDでCGDを有効活用したいところです。

## 参考URL

 * [The NetBSD Guide](https://www.netbsd.org/docs/guide/en/index.html)
   * [Chapter 14. The cryptographic device driver (CGD)](https://www.netbsd.org/docs/guide/en/chap-cgd.html)