App-Armorを理解する

# タイトル
App-Armorを理解する

# 目的
- App-Armor を理解する
- App-Armor トラブルシュート方法を理解する

# 手段
killercoda 環境で手を動かす

### ざっくり理解する
![App-Armorを理解する.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474478/9c37a1ab-09ee-c34c-2e7a-5b87deb079b5.jpeg)

### 環境
killercoda 

### App-Armor とは
App-Armor はプロセスやアプリケーションに対してプロファイルと呼ばれる設定ファイルでファイルやネットワークリソースへのアクセスを制御する機能です。App-Armor は Linuxカーネルのセキュリティモジュール（LSM: Linux Security Modules）を利用して動作します。Linux カーネル起動時、LSM を通じて App-Armor モジュールがロードされます。つまり、LSM は Linux カーネルにモジュールをロードするインタフェースを提供しています。

App-Armor 機能を利用するには、そもそも Linux カーネル側で App-Armor 機能を有効化する必要があります。App-Armor 機能を有効にした Linux カーネルは、App-Armor プロファイルに基づいてシステムコールを監視し、プロファイルに応じた制御を実施します。 

なお、App-Armor 機能は `/sys/module/apparmor/parameters/enabled` を確認します。

```bash
cat /sys/module/apparmor/parameters/enabled
Y
```

### k8s 上で App-Armor 機能を有効化するには
App-Armor 機能は securityContest で設定可能です。(Container レベル及び Pod レベル)Container 及び Pod の両方で設定した場合、Pod 側の設定が優先される動作になります。また、前提条件として、Pod はどの Node にアサインされるか分からない為、全ての Node でプロファイルをロードする必要があります。

```bash
controlplane $ apparmor_status -h|more
Usage: /usr/sbin/apparmor_status [OPTIONS]
Displays various information about the currently loaded AppArmor policy.
# apparmor_status コマンドは現在ロードされている App-Armor ポリシーの一覧を確認可能
```

```bash
controlplane $ apparmor_parser -h|more
Usage: apparmor_parser [options] [profile]

Options:
--------
-a, --add               Add apparmor definitions [default]
# apparmor_parser -a [profilename] で新規プロファイルをカーネルにロード可能
```

### コンテナはどのプロファイルで実行されているのか？
Pod はどのプロファイルで実行されているか確認可能なコマンドが存在します。

```bash
controlplane $ k exec -it -n moon spacecow-7566fd7fc6-fhc8t -- cat /proc/1/attr/current
docker-default (enforce)
# k exec -it -n [namespace] [pod] -- cat /proc/1/attr/current コマンドで確認可能
```

```bash
controlplane $ k exec spacecow-7566fd7fc6-f9dlg -n moon -- cat /proc/1/attr/current 
docker-default (enforce)
# `cat /proc/1/attr/current` コマンドでコンテナに適用されているプロファイル名を確認可能

node01 $ crictl inspect c4ce1da479afe |grep apparmor
          "apparmor": {
          "apparmor_profile": "localhost/docker-default",
        "apparmorProfile": "docker-default",
# crictl inspect コマンドでもコンテナに適用されているプロファイル名を確認可能
```


```bash(apparmor-status コマンドとcat /sys/kernel/security/apparmor/profilesを比較)
controlplane $ diff apparmor_status.txt profiles-list.txt 
1,56c1,37
< apparmor module is loaded.
< 37 profiles are loaded.
< 37 profiles are in enforce mode.
<    /snap/snapd/23545/usr/lib/snapd/snap-confine
<    /snap/snapd/23545/usr/lib/snapd/snap-confine//mount-namespace-capture-helper
<    /usr/bin/man
<    /usr/lib/NetworkManager/nm-dhcp-client.action
<    /usr/lib/NetworkManager/nm-dhcp-helper
<    /usr/lib/connman/scripts/dhclient-script
<    /usr/lib/cups/backend/cups-pdf
<    /usr/lib/lightdm/lightdm-guest-session
<    /usr/lib/lightdm/lightdm-guest-session//chromium
<    /usr/lib/snapd/snap-confine
<    /usr/lib/snapd/snap-confine//mount-namespace-capture-helper
<    /usr/sbin/cups-browsed
<    /usr/sbin/cupsd
<    /usr/sbin/cupsd//third_party
<    /usr/sbin/tcpdump
<    /{,usr/}sbin/dhclient
<    cri-containerd.apparmor.d
<    docker-default
<    ippusbxd
<    lsb_release
<    man_filter
<    man_groff
<    nvidia_modprobe
<    nvidia_modprobe//kmod
<    snap-update-ns.lxd
<    snap.lxd.activate
<    snap.lxd.benchmark
<    snap.lxd.buginfo
<    snap.lxd.check-kernel
<    snap.lxd.daemon
<    snap.lxd.hook.configure
<    snap.lxd.hook.install
<    snap.lxd.hook.remove
<    snap.lxd.lxc
<    snap.lxd.lxc-to-lxd
<    snap.lxd.lxd
<    snap.lxd.migrate
< 0 profiles are in complain mode.
< 11 processes have profiles defined.
< 11 processes are in enforce mode.
<    /usr/sbin/cups-browsed (641) 
<    /usr/sbin/cupsd (574) 
<    /usr/sbin/dhclient (759) /{,usr/}sbin/dhclient
<    /usr/sbin/dhclient (974) /{,usr/}sbin/dhclient
<    /usr/sbin/dhclient (1070) /{,usr/}sbin/dhclient
<    /usr/local/bin/kube-scheduler (1983) cri-containerd.apparmor.d
<    /usr/local/bin/kube-controller-manager (1997) cri-containerd.apparmor.d
<    /usr/local/bin/etcd (2012) cri-containerd.apparmor.d
<    /usr/local/bin/kube-apiserver (2018) cri-containerd.apparmor.d
<    /usr/bin/kube-controllers (3859) cri-containerd.apparmor.d
<    /usr/bin/local-path-provisioner (4172) cri-containerd.apparmor.d
< 0 processes are in complain mode.
< 0 processes are unconfined but have a profile defined.
---
> cri-containerd.apparmor.d (enforce)
> docker-default (enforce)
> snap.lxd.migrate (enforce)
> snap.lxd.lxd (enforce)
> snap.lxd.lxc-to-lxd (enforce)
> snap.lxd.lxc (enforce)
> snap.lxd.hook.remove (enforce)
> snap.lxd.hook.install (enforce)
> snap.lxd.hook.configure (enforce)
> snap.lxd.daemon (enforce)
> snap.lxd.check-kernel (enforce)
> snap.lxd.buginfo (enforce)
> snap.lxd.benchmark (enforce)
> snap.lxd.activate (enforce)
> snap-update-ns.lxd (enforce)
> /snap/snapd/23545/usr/lib/snapd/snap-confine (enforce)
> /snap/snapd/23545/usr/lib/snapd/snap-confine//mount-namespace-capture-helper (enforce)
> /usr/lib/lightdm/lightdm-guest-session (enforce)
> /usr/lib/lightdm/lightdm-guest-session//chromium (enforce)
> /{,usr/}sbin/dhclient (enforce)
> /usr/lib/connman/scripts/dhclient-script (enforce)
> /usr/lib/NetworkManager/nm-dhcp-helper (enforce)
> /usr/lib/NetworkManager/nm-dhcp-client.action (enforce)
> man_groff (enforce)
> man_filter (enforce)
> /usr/bin/man (enforce)
> lsb_release (enforce)
> nvidia_modprobe (enforce)
> nvidia_modprobe//kmod (enforce)
> /usr/sbin/tcpdump (enforce)
> ippusbxd (enforce)
> /usr/lib/snapd/snap-confine (enforce)
> /usr/lib/snapd/snap-confine//mount-namespace-capture-helper (enforce)
> /usr/sbin/cupsd (enforce)
> /usr/sbin/cupsd//third_party (enforce)
> /usr/lib/cups/backend/cups-pdf (enforce)
> /usr/sbin/cups-browsed (enforce)
```

# あとがき
apparmoer の設定ファイル(プロファイル)の書き方は今後の勉強でカバーしましょう。

# ソース
- [AppArmorを使用してコンテナのリソースへのアクセスを制限する](https://kubernetes.io/ja/docs/tutorials/security/apparmor/)
- [Linux kernel security constraints for Pods and containers](https://kubernetes.io/docs/concepts/security/linux-kernel-security-constraints/#apparmor)