Docker 向け Seccomp セキュリティプロファイル
読む時間の目安: 5 分
セキュリティコンピューティングモード(secure computing mode; seccomp)は Linux カーネルの機能です。
これを使うと、コンテナー内で利用できる処理を限定することができます。
システムコールseccomp()は呼び出し側プロセスの seccomp 状態を操作します。
この機能は、アプリケーションのアクセス処理を制限するものとして利用することができます。
この機能を利用するためには、Docker がseccompを使ってビルドされていること、そしてカーネルがCONFIG_SECCOMPを有効にしていることが必要です。
カーネルがseccompをサポートしているかどうかは、以下のようにして確認します。
$ grep CONFIG_SECCOMP= /boot/config-$(uname -r)
CONFIG_SECCOMP=y
メモ
seccompプロファイルは seccomp 2.2.1 を必要としますが、これは Ubuntu 14.04、Debian Wheezy、Debian Jessie では利用できません。 そのディストリビューションにおいてseccompを利用する場合は、(パッケージをインストールするのではなく)最新の Linux 実行モジュール をダウンロードして利用する必要があります。
コンテナーへのプロファイルの受け渡し
デフォルトのseccompプロファイルは、seccomp を使ってコンテナーを実行するための、十分に考慮されたデフォルトを提供します。
そして 300 以上あるシステムコールのうち 44 個を無効とします。
これは幅広くアプリケーションとの互換性を提供しつつ、適度なセキュリティ保護を実現します。
デフォルトの Docker プロファイルは こちら にあります。
実際にプロファイルは許可リスト方式をとるものであり、デフォルトではシステムコールのアクセスを拒否します。
そして特定のシステムコールを許可します。
プロファイルはSCMP_ACT_ERRNOのdefaultActionを定義することで動作し、指定したシステムコールのみ、その動作をオーバーライドします。
SCMP_ACT_ERRNOの効果はPermission Deniedエラーを発生させることです。
次にプロファイルにおいては、システムコールのうち、完全に動作を許容するものを列記します。
これによって各actionをSCMP_ACT_ALLOWとしてオーバーライドするためです。
そして最後に、personalityのような個別のシステムコールに対して、特定のルールを定めます。
そのシステムコールに特定の引数を加えるといったことを行うことができます。
seccompは Docker コンテナーを最小限の権限により実行します。
デフォルトのseccompプロファイルを修正することは推奨されていません。
コンテナーの起動時にはデフォルトのプロファイルが利用されます。
ただし--security-optオプションを指定した場合は、それをオーバーライドすることができます。
たとえば以下の例は、ポリシーを明示的に指定するものです。
$ docker run --rm \
-it \
--security-opt seccomp=/path/to/seccomp/profile.json \
hello-world
デフォルトプロファイルによりブロックされる重要なシステムコール
Docker 向けの seccomp プロファイルは許可リスト方式をとります。 したがって許可したいシステムコールを指定する必要があります。 以下の表では、重要な(ただしすべてではない)システムコールの中で、許可リストに指定されなかったことから拒否されてしまうものの一覧です。 表の中では、許可リスト化されずにブロックされてしまう理由についても触れています。
| システムコール | 内容説明 |
|---|---|
acct |
Accounting syscall which could let containers disable their own resource limits or process accounting. Also gated by CAP_SYS_PACCT. |
add_key |
Prevent containers from using the kernel keyring, which is not namespaced. |
bpf |
Deny loading potentially persistent bpf programs into kernel, already gated by CAP_SYS_ADMIN. |
clock_adjtime |
Time/date is not namespaced. Also gated by CAP_SYS_TIME. |
clock_settime |
Time/date is not namespaced. Also gated by CAP_SYS_TIME. |
clone |
Deny cloning new namespaces. Also gated by CAP_SYS_ADMIN for CLONE_* flags, except CLONE_NEWUSER. |
create_module |
Deny manipulation and functions on kernel modules. Obsolete. Also gated by CAP_SYS_MODULE. |
delete_module |
Deny manipulation and functions on kernel modules. Also gated by CAP_SYS_MODULE. |
finit_module |
Deny manipulation and functions on kernel modules. Also gated by CAP_SYS_MODULE. |
get_kernel_syms |
Deny retrieval of exported kernel and module symbols. Obsolete. |
get_mempolicy |
Syscall that modifies kernel memory and NUMA settings. Already gated by CAP_SYS_NICE. |
init_module |
Deny manipulation and functions on kernel modules. Also gated by CAP_SYS_MODULE. |
ioperm |
Prevent containers from modifying kernel I/O privilege levels. Already gated by CAP_SYS_RAWIO. |
iopl |
Prevent containers from modifying kernel I/O privilege levels. Already gated by CAP_SYS_RAWIO. |
kcmp |
Restrict process inspection capabilities, already blocked by dropping CAP_SYS_PTRACE. |
kexec_file_load |
Sister syscall of kexec_load that does the same thing, slightly different arguments. Also gated by CAP_SYS_BOOT. |
kexec_load |
Deny loading a new kernel for later execution. Also gated by CAP_SYS_BOOT. |
keyctl |
Prevent containers from using the kernel keyring, which is not namespaced. |
lookup_dcookie |
Tracing/profiling syscall, which could leak a lot of information on the host. Also gated by CAP_SYS_ADMIN. |
mbind |
Syscall that modifies kernel memory and NUMA settings. Already gated by CAP_SYS_NICE. |
mount |
Deny mounting, already gated by CAP_SYS_ADMIN. |
move_pages |
Syscall that modifies kernel memory and NUMA settings. |
name_to_handle_at |
Sister syscall to open_by_handle_at. Already gated by CAP_DAC_READ_SEARCH. |
nfsservctl |
Deny interaction with the kernel nfs daemon. Obsolete since Linux 3.1. |
open_by_handle_at |
Cause of an old container breakout. Also gated by CAP_DAC_READ_SEARCH. |
perf_event_open |
Tracing/profiling syscall, which could leak a lot of information on the host. |
personality |
Prevent container from enabling BSD emulation. Not inherently dangerous, but poorly tested, potential for a lot of kernel vulns. |
pivot_root |
Deny pivot_root, should be privileged operation. |
process_vm_readv |
Restrict process inspection capabilities, already blocked by dropping CAP_SYS_PTRACE. |
process_vm_writev |
Restrict process inspection capabilities, already blocked by dropping CAP_SYS_PTRACE. |
ptrace |
Tracing/profiling syscall. Blocked in Linux kernel versions before 4.8 to avoid seccomp bypass. Tracing/profiling arbitrary processes is already blocked by dropping CAP_SYS_PTRACE, because it could leak a lot of information on the host. |
query_module |
Deny manipulation and functions on kernel modules. Obsolete. |
quotactl |
Quota syscall which could let containers disable their own resource limits or process accounting. Also gated by CAP_SYS_ADMIN. |
reboot |
Don’t let containers reboot the host. Also gated by CAP_SYS_BOOT. |
request_key |
Prevent containers from using the kernel keyring, which is not namespaced. |
set_mempolicy |
Syscall that modifies kernel memory and NUMA settings. Already gated by CAP_SYS_NICE. |
setns |
Deny associating a thread with a namespace. Also gated by CAP_SYS_ADMIN. |
settimeofday |
Time/date is not namespaced. Also gated by CAP_SYS_TIME. |
stime |
Time/date is not namespaced. Also gated by CAP_SYS_TIME. |
swapon |
Deny start/stop swapping to file/device. Also gated by CAP_SYS_ADMIN. |
swapoff |
Deny start/stop swapping to file/device. Also gated by CAP_SYS_ADMIN. |
sysfs |
Obsolete syscall. |
_sysctl |
Obsolete, replaced by /proc/sys. |
umount |
Should be a privileged operation. Also gated by CAP_SYS_ADMIN. |
umount2 |
Should be a privileged operation. Also gated by CAP_SYS_ADMIN. |
unshare |
Deny cloning new namespaces for processes. Also gated by CAP_SYS_ADMIN, with the exception of unshare --user. |
uselib |
Older syscall related to shared libraries, unused for a long time. |
userfaultfd |
Userspace page fault handling, largely needed for process migration. |
ustat |
Obsolete syscall. |
vm86 |
カーネルにおける x86 リアルモード仮想マシン。 CAP_SYS_ADMIN からも呼び出される。 |
vm86old |
カーネルにおける x86 リアルモード仮想マシン。 CAP_SYS_ADMIN からも呼び出される。 |
デフォルトの seccomp プロファイルがない状態での実行
コンテナーを実行する際にunconfinedを指定すれば、デフォルトの seccomp プロファイルをなしにして実行することができます。
profile.
$ docker run --rm -it --security-opt seccomp=unconfined debian:jessie \
unshare --map-root-user --user sh -c whoami