メモ。
以下を読ませて頂きました
capablity について詳しい訳ではないため、認識が異なった部分などあればご指摘頂けますと助かります。
TL:DR
- Linux には、root が持っている絶対的な権限を小分けにし、 細かくした権限をプロセスに与えられるようにする機構がある。その細かい権限のことを、ケーパビリティ(capablity)と呼ぶらしい ケーパビリティ で権限を少しだけ与える
- Docker ではデフォルトでいくつかの capability は有効化されている。具体的有効化されているものは公式ドキュメントに記載ありで
pscap
コマンドでも確認出来る -
--cap-drop
オプションを指定することでデフォルトで有効化されている capability を無効化出来る - 逆に
--cap-add
オプションを指定することでデフォルトで無効化されている capability を有効化出来る -
--privileged
オプションを付与した場合、明示的に有効化されていない capability も利用でき、すべての capability が有効化されている -
--user
オプションを指定した場合、capablity が無効化(?)されていた(Root 以外は基本的に capablity がないためだと思われます)
環境
docker info
Containers: 59
Running: 5
Paused: 0
Stopped: 54
Images: 27
Server Version: 18.06.1-ce
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 468a545b9edcd5932818eb9de8e72413e616e86e
runc version: 69663f0bd4b60df09991c08812a60108003fa340
init version: fec3683
Security Options:
seccomp
Profile: default
Kernel Version: 4.14.77-80.57.amzn2.x86_64
Operating System: Amazon Linux 2
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 985.7MiB
Name: ip-172-31-30-50.ap-northeast-1.compute.internal
ID: M5OF:USUI:CHU4:NPLX:6TPC:DJ52:6C6O:DEHT:2BUM:WDHN:DSCO:HFHD
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
試す
--cap-drop
Runtime privilege and Linux capabilities
The following table lists the Linux capability options which are allowed by default and can be dropped.
と書いてあり、CHOWN
はデフォルトでは許可されている。
$docker run -it ubuntu chown root:staff tmp
デフォルトで許可されている capability を無効化する場合 --cap-drop
を指定する。
$docker run -it --cap-drop CHOWN ubuntu chown root:staff tmp
chown: changing ownership of 'tmp': Operation not permitted
capability は pscap
で見れそうなので確認
Ubuntu の場合、apt-get install libcap-ng-utils
で良さそう
libcap-ng-utils_0.7.7-3.1_amd64.deb
# デフォルト
$docker run -it ubuntu /bin/bash
#apt-get update
#apt-get install libcap-ng-utils
#pscap -a
ppid pid name command capabilities
0 1 root bash chown, dac_override, fowner, fsetid, kill, setgid, setuid, setpcap, net_bind_service, net_raw, sys_chroot, mknod, audit_write, setfcap
# drop してみる
$docker run -it --cap-drop CHOWN ubuntu /bin/bash
#apt-get update
#apt-get install libcap-ng-utils
#pscap -a
ppid pid name command capabilities
0 1 root bash dac_override, fowner, fsetid, kill, setgid, setuid, setpcap, net_bind_service, net_raw, sys_chroot, mknod, audit_write, setfcap
確かに drop すると capability から CHOWN
が無くなっていた。
ちなみに --privileged
を付与するとどうなる?
$docker run -it --privileged --cap-drop CHOWN ubuntu chown root:staff tmp
成功してしまう
こちらも pscap
で確認(細かいコマンドは除外)
# privilledge を付与すると capability full となり、すべて許可される
$docker run -it --privileged ubuntu /bin/bash
# pscap -a
ppid pid name command capabilities
0 1 root bash full
# cap-drop しても full
$docker run -it --privileged --cap-drop CHOWN ubuntu /bin/bash
#pscap -a
ppid pid name command capabilities
0 1 root bash full
なるほど。
ちなみに --user
オプションを変えるとどうなる?
$docker run --user nobody -it ubuntu whoami
nobody
# ユーザーのみ指定。権限がないのでエラー
$docker run --user nobody -it ubuntu chown root:staff tmp
chown: changing ownership of 'tmp': Operation not permitted
# priviledge をつけてもエラー
$docker run --privileged --user nobody -it ubuntu chown root:staff tmp
chown: changing ownership of 'tmp': Operation not permitted
capability も確認してみようと思ったが、入ってなかったのでさくっとイメージを作る。
(最初からこうすればよかった。。。)
FROM ubuntu
RUN apt-get update && apt-get install -y \
libcap-ng-utils
$docker build -t pscap-ubuntu .
確認。
# 何も出ない
$docker run --user nobody -it pscap-ubuntu pscap -a
# 何も出ない
$docker run --privileged --user nobody -it pscap-ubuntu pscap -a
もしかすると root 以外は capablity はない?
root のプロセスは、基本的にはすべてのケーパビリティを持っていますが、 必要のないケーパビリティを外していくことで、 セキュリティを向上させることができます。
また、root でないプロセスは、基本的にはどのケーパビリティも持っていません。 ですが、実行するコマンドにケーパビリティが設定されている場合は、 そのケーパビリティを持つことができます。
なるほど。
--cap-add
以下を参考にさせて頂き検証。
(ヽ´ω`) < Dockerで--cap-addオプションを試す
デフォルトで許可されていない SYS_TIME
を利用。
$docker run -it ubuntu date -s "2000/01/01 00:00:00"
date: cannot set date: Operation not permitted
Sat Jan 1 00:00:00 UTC 2000
想定通り NG。
許可してみる
$docker run -it --cap-add=SYS_TIME ubuntu date -s "2000/01/01 00:00:00"
エラーが無くなった。
--privileged
を付与した場合も実行できてしまう
$docker run -it --privileged ubuntu date -s "2000/01/01 00:00:00"
Sat Jan 1 00:00:00 UTC 2000
これは先程の検証の通り、--priviledge
を付与することですべての capability が許可されるためだと思われる。