LinuCエヴァンジェリスト・Open Source Summit Japan 2022ボランティアリーダーの鯨井貴博@opensourcetechです。
はじめに
今回は、kubernetesのPodにLinux Kernel Capabilityを設定してみます。
Linux Kernel Capabilityとは
LinuxカーネルのCapability(権限)は、プロセスの特権とアクセス権を制御するための仕組みです。Linuxはセキュリティとアクセス管理の観点から、プロセスが実行できる操作やリソースへのアクセスを制御するためにCapabilityを使用します。
通常、Linuxではスーパーユーザー権限(root権限)を持つプロセスがシステム全体にアクセスできる特権を持ちますが、Capabilityを使用することで、プロセスに特定の特権だけを付与できます。これにより、セキュリティが向上し、特権の濫用を防ぐことができます。
Capabilityは、具体的なアクセス権限や操作(例: ファイルの所有者変更、ネットワーク設定の変更、特定のシステムリソースへのアクセスなど)を表現するビットの集合であり、それぞれ異なる権限を示します。プロセスは必要なCapabilityを持つことで、それに対応する操作やアクセスを実行できます。
Capabilityは、最小特権の原則を強化し、セキュリティを向上させるために重要な役割を果たします。特定の操作を実行するプロセスに対して、最小限の特権を与え、それ以外の操作から隔離することができます。これにより、システム全体のセキュリティが強化され、セキュリティホールや悪意のある操作を制限できます。
詳細は、こちら
https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h
Linux Kernel Capabilityの種類
以下の0~40(全41種)があります。
設定名 | 番号 | 意味 |
---|---|---|
CAP_CHOWN | 0 | ファイルの所有者を変更できる |
CAP_DAC_OVERRIDE | 1 | DACアクセス権を無視できる |
CAP_DAC_READ_SEARCH | 2 | ファイルを読み取りおよび検索できる |
CAP_FOWNER | 3 | ファイルの所有者を変更できる |
CAP_FSETID | 4 | ファイルIDを設定できる |
CAP_KILL | 5 | 他のプロセスを終了できる |
CAP_SETGID | 6 | グループIDを変更できる |
CAP_SETUID | 7 | ユーザIDを変更できる |
CAP_SETPCAP | 8 | inheritableなCapabilityを設定できる |
CAP_LINUX_IMMUTABLE | 9 | ファイルの不変フラグを設定できる |
CAP_NET_BIND_SERVICE | 10 | 特権ポート番号をバインドできる |
CAP_NET_BROADCAST | 11 | ブロードキャストトラフィックを送信できる |
CAP_NET_ADMIN | 12 | ネットワーク設定を変更できる |
CAP_NET_RAW | 13 | RAWソケットを作成できる |
CAP_IPC_LOCK | 14 | 共有メモリセグメントをロックできる |
CAP_IPC_OWNER | 15 | IPCリソースのオーナーとなれる |
CAP_SYS_MODULE | 16 | カーネルモジュールをロードできる |
CAP_SYS_RAWIO | 17 | ハードウェアへのアクセスが可能 |
CAP_SYS_CHROOT | 18 | ルートディレクトリを変更できる |
CAP_SYS_PTRACE | 19 | 他のプロセスをトレースできる |
CAP_SYS_PACCT | 20 | アカウンティングデータを読み書きできる |
CAP_SYS_ADMIN | 21 | システム管理作業を行える |
CAP_SYS_BOOT | 22 | システムをシャットダウンできる |
CAP_SYS_NICE | 23 | 他のプロセスの優先度を変更できる |
CAP_SYS_RESOURCE | 24 | 資源制限の変更が可能 |
CAP_SYS_TIME | 25 | システム時刻を変更できる |
CAP_SYS_TTY_CONFIG | 26 | ターミナル設定を変更できる |
CAP_MKNOD | 27 | デバイスファイルを作成できる |
CAP_LEASE | 28 | ファイルリースを設定できる |
CAP_AUDIT_WRITE | 29 | カーネル監査ログに書き込み可能 |
CAP_AUDIT_CONTROL | 30 | カーネル監査設定を変更できる |
CAP_SETFCAP | 31 | inheritableなファイルCapabilityを設定できる |
CAP_MAC_OVERRIDE | 32 | セキュリティモジュールの実行権限を無視 |
CAP_MAC_ADMIN | 33 | セキュリティモジュールの設定を変更 |
CAP_SYSLOG | 34 | syslogに書き込み可能 |
CAP_WAKE_ALARM | 35 | RTCアラームを設定できる |
CAP_BLOCK_SUSPEND | 36 | シスペンド/ハイバネーションをブロック |
CAP_AUDIT_READ | 37 | カーネル監査ログを読み取り可能 |
CAP_PERFMON | 38 | パフォーマンスモニタリングモジュールへのアクセス |
CAP_BPF | 39 | Berkeley Packet Filterプログラムのロード |
CAP_CHECKPOINT_RESTORE | 40 | プロセスのチェックポイントを復元 |
Kubernetes PodにLinux Kernel Capabilityを設定してみる
設定方法は、以下の本家ドキュメントで確認出来ます。
https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
https://kubernetes.io/ja/docs/tasks/configure-pod-container/security-context/
では、実際にやってみましょう♪
まずyamlファイルの作成。
kubeuser@master01:~$ kubectl run capability-pod --image=nginx --dry-run=client -o yaml > capability.yaml kubeuser@master01:~$ vi capability.yaml kubeuser@master01:~$ cat capability.yaml apiVersion: v1 kind: Pod metadata: labels: run: capability-pod name: capability-pod spec: containers: - image: nginx name: capability-pod securityContext: capabilities: add: ["NET_ADMIN", "SYS_TIME"]
Podの作成。
kubeuser@master01:~$ kubectl apply -f capability.yaml pod/capability-pod created kubeuser@master01:~$ kubectl get pods | grep capability capability-pod 1/1 Running 0 2m48s
Podに設定されたLinux Kernel Capabilityの確認。
kubeuser@master01:~$ kubectl exec -it capability-pod -- sh # cat /proc/1/status | grep CapPrm CapPrm: 00000000aa0435fb # exit
00000000aa0435fbと分かったので、
capshで設定名を確かめます。
cap_net_adminとcap_sys_timeが確認出来ます。
kubeuser@master01:~$ capsh --decode=00000000aa0435fb 0x00000000aa0435fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_admin,cap_net_raw,cap_sys_chroot,cap_sys_time,cap_mknod,cap_audit_write,cap_setfcap
00000000aa0435fbを2進数にして、
NET_ADMINとSYS_TIMEのビットがON(1)となっていることを確認します。
00000000aa0435fb ⇒ 0000 0000 0000 0000 0000 0000 0000 0000 1010 1010 0000 0100 0011 0101 1111 1011
なお、上記は右から順に並んでおり、
NET_ADMINは12(0から始まるので13bit目)、
SYS_TIMEは25(26bit目)となります。
おわりに
今回はPodにLinux Kernel Capabilityを設定しつつ、
その各設定値の意味などについて深堀してみました。
設定出来るだけではなく、ちゃんと理解して使おうという大事さを改めて感じました。