Docker privileged オプションについて

訳そう訳そうと思いつつ放置していたのを訳しました

* docker 1.9.0 build 76d6bc9

```sh
Runtime privilege and Linux capabilities
--cap-add: Add Linux capabilities
--cap-drop: Drop Linux capabilities
--privileged=false: Give extended privileges to this container
--device=[]: Allows you to run devices inside the container without the --privileged flag.
```

> Note: Docker 1.10 以上では、 `--cap-add` がコンテナに渡されたかどうかにかかわらず、デフォルトの seccopm profile が syscall をブロックします。このような場合は、用意されているデフォルトのものをベースにご自身でカスタムした seccomp profile を作成することをオススメします。そうでなく [default](https://github.com/docker/docker/blob/master/profiles/seccomp/default.json) で起動したくないのであれば、 `--security-opt=seccomp=unconfined` を渡して起動してください。

デフォルトでは、 Docker コンテナは "unprivileged" であり、例えば、 Docker コンテナ内で Docker daemon の起動を行うことができません。これは、デフォルトではコンテナがあらゆるデバイスへのアクセスが許されていないためです。しかし、 "privileged" なコンテナはすべてのデバイスへのアクセスが許可されます (see the documentation on [cgroups devices](https://www.kernel.org/doc/Documentation/cgroup-v1/devices.txt))。

`docker run --privileged` を実行したすると、 AppArmor や SELinux で設定するのと同じように、コンテナ以外のホスト上のプロセスとほとんど同じレベルでホストへのアクセスを許可するように、そのホストのすべてのデバイスへのアクセスが可能になります。 `--privileged` での起動についての付与的な情報は [Docker Blog](http://blog.docker.com/2013/09/docker-can-now-run-within-docker/) で確認してください。

もし、特定のデバイスへのアクセスを制限したければ、 `--device` フラグを利用できます。コンテナ内からアクセス可能な1つ以上のデバイスを指定することができます。

```console
$ docker run --device=/dev/snd:/dev/snd ...
```

デフォルトで、コンテナはこれらのデバイスに対して `read`、`write`および`mknod` が可能です。`--device` フラグのそれぞれのオプションに対して 3つぐみの `:rwm` を用いることで上書きすることができます。


```console
$ docker run --device=/dev/sda:/dev/xvdc --rm -it ubuntu fdisk  /dev/xvdc

Command (m for help): q
$ docker run --device=/dev/sda:/dev/xvdc:r --rm -it ubuntu fdisk  /dev/xvdc
You will not be able to write the partition table.

Command (m for help): q

$ docker run --device=/dev/sda:/dev/xvdc:w --rm -it ubuntu fdisk  /dev/xvdc
    crash....

$ docker run --device=/dev/sda:/dev/xvdc:m --rm -it ubuntu fdisk  /dev/xvdc
fdisk: unable to open /dev/xvdc: Operation not permitted
```

`--privileged` に追加して、`--cap-add` および `--cap-drop` を使うことで、capability をより適切な粒度で制御することができます。デフォルトでは、 Docker は 下記の利用可能性を保持しています。下記のテーブルに追加や削除が可能な Linux capability options を記載します。

|Capability Key|	Capability Description|
|--------------|--------------------------|
|SETPCAP	|process capabilities の変更|
|SYS_MODULE	|kernel modules のロードまたはアンロード															|
|SYS_RAWIO	|I/O port の操作(iopl(2) and ioperm(2)).  USB message とか|
|SYS_PACCT	|acct(2) を使って, process accounting on or off のスイッチが可能						|
|SYS_ADMIN	|System Admin の操作範囲の実行			|
|SYS_NICE	|プロセス nice 値 (nice(2), setpriority(2)) を上げる、および 任意のプロセスの nice 値の変更|
|SYS_RESOURCE|	リソース制限の上書き.																			|
|SYS_TIME	|System clock (settimeofday(2), stime(2), adjtimex(2)) の設定; real-time (hardware) clock の設定				|
|SYS_TTY_CONFIG	|vhangup(2) の実行; employ various privileged ioctl(2) operations on virtual terminals.				|
|MKNOD			| mknod(2) を利用して special files の作成 |
|AUDIT_WRITE	|kernel auditing log への records の記載  |
|AUDIT_CONTROL	|kernel auditing の有効化/無効化; auditing filter rules の変更; auditing status と filtering rules の取得 |
|MAC_OVERRIDE	|MAC configuration の許可または state の変更. Smack LSM で実装されている|
|MAC_ADMIN		|Mandatory Access Control (MAC) の上書き. Smack Linux Security Module (LSM) で実装されている.|
|NET_ADMIN		|various network-related operations の実行|
|SYSLOG			|privileged syslog(2) operations の実行|
|CHOWN			|file UIDs and GIDs (see chown(2)) の任意の変更|
|NET_RAW		|RAW と PACKET sockets の利用|
|DAC_OVERRIDE	|file read, write, and execute permission check のバイパス.|
|FOWNER			|Bypass permission checks on operations that normally require the file system UID of the process to match the UID of the file.|
|DAC_READ_SEARCH	|ファイル読み込みおよび直接読み込みと実行の権限チェックのバイパス									  |
|FSETID			|ファイルが修正された時に set-user-ID と set-group-ID の権限ビットをクリアしない|
|KILL			|シグナル送信の時に権限チェックをバイパスする																		  |
|SETGID			|プロセス GID および 補助 GID の任意の操作											  |
|SETUID			|プロセス UID の任意の操作															  |
|LINUX_IMMUTABLE	|FS_APPEND_FL and FS_IMMUTABLE_FL i-node flags の付与							  |
|NET_BIND_SERVICE	|特権ポートでのインターネットへのソケットの利用									  |
|NET_BROADCAST	|broadcast ソケットの作成とマルチキャストへの listen																  |
|IPC_LOCK		|Lock memory (mlock(2), mlockall(2), mmap(2), shmctl(2)).																	  |
|IPC_OWNER		|operations on System V IPC objects の権限チェックのバイパス								  |
|SYS_CHROOT		|chroot(2), change root directory の許可																					  |
|SYS_PTRACE		|ptrace(2) を利用した任意のプロセスの trace														  |
|SYS_BOOT		|reboot(2) and kexec_load(2) を利用して reboot と新しいカーネルのロード load 									  |
|LEASE			|任意のファイルのリース Establish (see fcntl(2)).																		  |
|SETFCAP		|file capabilities のセット.									|
|WAKE_ALARM		|システム起動に対してトリガーを送る	|
|BLOCK_SUSPEND	|block system をサスペンドさせるような機能を適用する		|

より詳細なリファレンスは  [capabilities(7) - Linux man page](http://linux.die.net/man/7/capabilities) で御覧ください。

(`--cap-add` / `--cap-drop`)両方のフラグの値として `ALL` をサポートしているので、例えば、 `MKNOD` 以外のすべての権限を付けたい場合は、下記のようにすることが可能です。

```console
$ docker run --cap-add=ALL --cap-drop=MKNOD ...
```

ネットワークスタックを操作するのであれば、 `--privileged` ではなく、 `--cap-add=NET_ADMIN` として、ネットワークインターフェイスを変更するべきでしょう。

```console
$ docker run -it --rm  ubuntu:14.04 ip link add dummy0 type dummy
RTNETLINK answers: Operation not permitted
$ docker run -it --rm --cap-add=NET_ADMIN ubuntu:14.04 ip link add dummy0 type dummy
To mount a FUSE based filesystem, you need to combine both --cap-add and --device:

$ docker run --rm -it --cap-add SYS_ADMIN sshfs sshfs sven@10.10.10.20:/home/sven /mnt
fuse: failed to open /dev/fuse: Operation not permitted
$ docker run --rm -it --device /dev/fuse sshfs sshfs sven@10.10.10.20:/home/sven /mnt
fusermount: mount failed: Operation not permitted
$ docker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs
# sshfs sven@10.10.10.20:/home/sven /mnt
The authenticity of host '10.10.10.20 (10.10.10.20)' can't be established.
ECDSA key fingerprint is 25:34:85:75:25:b0:17:46:05:19:04:93:b5:dd:5f:c6.
Are you sure you want to continue connecting (yes/no)? yes
sven@10.10.10.20's password:
root@30aa0cfaf1b5:/# ls -la /mnt/src/docker
total 1516
drwxrwxr-x 1 1000 1000   4096 Dec  4 06:08 .
drwxrwxr-x 1 1000 1000   4096 Dec  4 11:46 ..
-rw-rw-r-- 1 1000 1000     16 Oct  8 00:09 .dockerignore
-rwxrwxr-x 1 1000 1000    464 Oct  8 00:09 .drone.yml
drwxrwxr-x 1 1000 1000   4096 Dec  4 06:11 .git
-rw-rw-r-- 1 1000 1000    461 Dec  4 06:08 .gitignore
....
```

* [capabilities](https://linuxjm.osdn.jp/html/LDP_man-pages/man7/capabilities.7.html)
* [SECCOMP と Androidの関係](http://qiita.com/hidenorly/items/25f4ec043e3bbe9cf1a7)
* [今回のお題 - AppArmor をおおまかに理解する](http://www.usupi.org/sysad/220.html)