Opensourcetechブログ

OpensourcetechによるNGINX/Kubernetes/Zabbix/Neo4j/Linuxなどオープンソース技術に関するブログです。

Linux Kernel CapabilityをKubernetes Podで設定する


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_admincap_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を設定しつつ、
その各設定値の意味などについて深堀してみました。

設定出来るだけではなく、ちゃんと理解して使おうという大事さを改めて感じました。

Opensourcetech by Takahiro Kujirai