12
12

More than 5 years have passed since last update.

Docker の capability --cap-add 及び --cap-drop オプションについて調べた

Posted at

メモ。
以下を読ませて頂きました

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 が許可されるためだと思われる。

12
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12