kakakakakku blog

Weekly Tech Blog : Keep on Learning 👍

kubectl で Taint を一覧するコマンド例

Kubernetes でノードの Taint を確認するときに「一覧する」コマンドがなくて困るときがある.--show-labels オプションのように --show-taints オプションがあったら良いのに!例えば kubectl describe node xxx | grep Taints コマンドを実行すれば「ノードごとに」確認することはできるけど,ノードが多いと面倒だったりする.今回は個人的に使っているコマンド例をまとめる.もっとイイ Tips があったら教えて欲しいのだ💡

コマンド例

最初にコマンド例をまとめておく.実際に調べると -o custom-columns を使うコマンドもあれば -o go-template や -o jsonpath を使うコマンドもある.また kubectl コマンドに依存せず jq でまとめるコマンドもある.普段使いをするためにあまり複雑にしたくなく,今回は -o custom-columns を使うコマンドと jq を使うコマンドを紹介する.

# -o custom-columns を使う
$ kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

# jq を使う
$ kubectl get nodes -o json | jq '.items[]|{name:.metadata.name, taints:.spec.taints}'

フォーラムにも関連するスレッドがあった.

discuss.kubernetes.io

動作確認

今回は kind を使って構築した Kubernetes クラスタを使う.

$ kubectl get nodes
NAME                 STATUS   ROLES           AGE   VERSION
kind-control-plane   Ready    control-plane   15m   v1.24.0
kind-worker          Ready    <none>          15m   v1.24.0
kind-worker2         Ready    <none>          15m   v1.24.0
kind-worker3         Ready    <none>          15m   v1.24.0

あくまでサンプルとして kind-worker2 と kind-worker3 に Taint を付けておく.

$ kubectl taint nodes kind-worker2 gpu=true:NoSchedule
node/kind-worker2 tainted

$ kubectl taint nodes kind-worker3 gpu=true:NoSchedule
node/kind-worker3 tainted

-o custom-columns を使うと以下のように Taint を確認できる.map 表記だったりするけど,シンプルだと思う.

$ kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
NAME                 TAINTS
kind-control-plane   [map[effect:NoSchedule key:node-role.kubernetes.io/master] map[effect:NoSchedule key:node-role.kubernetes.io/control-plane]]
kind-worker          <none>
kind-worker2         [map[effect:NoSchedule key:gpu value:true]]
kind-worker3         [map[effect:NoSchedule key:gpu value:true]]

jq を使うと縦長にはなるけど,結果としてはわかりやすく確認できる.やはり jq は便利!

$  kubectl get nodes -o json | jq '.items[]|{name:.metadata.name, taints:.spec.taints}'
{
  "name": "kind-control-plane",
  "taints": [
    {
      "effect": "NoSchedule",
      "key": "node-role.kubernetes.io/master"
    },
    {
      "effect": "NoSchedule",
      "key": "node-role.kubernetes.io/control-plane"
    }
  ]
}
{
  "name": "kind-worker",
  "taints": null
}
{
  "name": "kind-worker2",
  "taints": [
    {
      "effect": "NoSchedule",
      "key": "gpu",
      "value": "true"
    }
  ]
}
{
  "name": "kind-worker3",
  "taints": [
    {
      "effect": "NoSchedule",
      "key": "gpu",
      "value": "true"
    }
  ]
}

次は kind-worker3 に Taint を追加する.

$ kubectl taint nodes kind-worker3 spot=true:PreferNoSchedule
node/kind-worker3 tainted

-o custom-columns を使うと以下のように Taint を確認できる.右に長くなってしまうけどまだ許容範囲だと思う.

$ kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
NAME                 TAINTS
kind-control-plane   [map[effect:NoSchedule key:node-role.kubernetes.io/master] map[effect:NoSchedule key:node-role.kubernetes.io/control-plane]]
kind-worker          <none>
kind-worker2         [map[effect:NoSchedule key:gpu value:true]]
kind-worker3         [map[effect:PreferNoSchedule key:spot value:true] map[effect:NoSchedule key:gpu value:true]]

Taint を追加しても jq だとわかりやすく確認できる.

$ kubectl get nodes -o json | jq '.items[]|{name:.metadata.name, taints:.spec.taints}'
{
  "name": "kind-control-plane",
  "taints": [
    {
      "effect": "NoSchedule",
      "key": "node-role.kubernetes.io/master"
    },
    {
      "effect": "NoSchedule",
      "key": "node-role.kubernetes.io/control-plane"
    }
  ]
}
{
  "name": "kind-worker",
  "taints": null
}
{
  "name": "kind-worker2",
  "taints": [
    {
      "effect": "NoSchedule",
      "key": "gpu",
      "value": "true"
    }
  ]
}
{
  "name": "kind-worker3",
  "taints": [
    {
      "effect": "PreferNoSchedule",
      "key": "spot",
      "value": "true"
    },
    {
      "effect": "NoSchedule",
      "key": "gpu",
      "value": "true"
    }
  ]
}

関連記事

kakakakakku.hatenablog.com

Pandas で指数表記を無効化する

Jupyter Notebook で Pandas のコードを実装しているときに「指数表記を無効化」する場合は pd.options の display.float_format を設定する.以下にサンプルとして「桁数 2」と「桁数 6」の例を載せておく.

# 小数点以下 桁数 2
pd.options.display.float_format = '{:.2f}'.format

# 小数点以下 桁数 6
pd.options.display.float_format = '{:.6f}'.format

pandas.pydata.org

DataFrame で動作確認する 🎯

random.uniform で取得した乱数を3乗した適当な値を DataFrame にする.デフォルト設定だと e+08 のように指数表記になる.

import pandas as pd
import random

df = pd.DataFrame(
    {
        'id': [1, 2, 3],
        'dest': [random.uniform(100, 1000) ** 3, random.uniform(100, 1000) ** 3, random.uniform(100, 1000) ** 3]
    }
)
df

#    id          dest
# 0   1  5.343391e+08
# 1   2  1.095209e+08
# 2   3  5.267437e+08

次に pd.options の display.float_format に '{:.2f}'.format を設定する.桁数 2 で指数表記を無効化できた!

pd.options.display.float_format = '{:.2f}'.format
df

#    id         dest
# 0   1 534339073.50
# 1   2 109520894.40
# 2   3 526743661.86

今度は pd.options の display.float_format に '{:.6f}'.format を設定する.桁数 6 で指数表記を無効化できた!

pd.options.display.float_format = '{:.6f}'.format
df

#    id             dest
# 0   1 534339073.500472
# 1   2 109520894.397633
# 2   3 526743661.855074

Jupyter Notebook の実行結果も載せておく!

関連記事

kakakakakku.hatenablog.com

Re:VIEW で「節単位」に分割したファイルをビルドする

Re:VIEW で catalog.yml に設定するファイルの分割粒度は「章単位 (Chapter)」になっている.しかし,文章量が増えてくると運用面で「節単位 (Section)」にファイルを分割したくなってくることもある.例えば,以下のように「1章(1節)」と「2章(2節)」と「3章(3節)」でファイルを分割して catalog.yml に設定できる(できるにはできる...).

PREDEF:

CHAPS:
  - chapter1.re
  - section1-1.re
  - chapter2.re
  - section2-1.re
  - section2-2.re
  - chapter3.re
  - section3-1.re
  - section3-2.re
  - section3-3.re

APPENDIX:

POSTDEF:

でも実際にビルドをして PDF を確認すると,@<chap> や @<img> を使った参照があると採番がズレてしまう.例えば @<chap>{chapter3} で参照すると catalog.yml で6番目なので 第6章 と表示されてしまう.また,2018年に関連する issue も出ている.

github.com

解決案💡

Re:VIEW で「節単位」に分割したファイルをビルドするために,一時的に .re ファイルを「章単位」にまとめてからビルドをする解決案を考えた.変更点は大きく以下の3点ある.

1. config.yml

まず,config.yml に contentdir を設定して,ビルド対象ディレクトリをデフォルトの . から ./build に変更する../build ディレクトリはビルド専用になるため .gitignore にも追加してコミット対象外にしておく.

contentdir: ./build

2. catalog.yml

次に catalog.yml を変更する.実際に 1.re や 2.re はなく,「章単位」にまとめたファイル名を指定している.まとめる作業は次に紹介する Makefile を使って実行する.

PREDEF:

CHAPS:
  - 1.re
  - 2.re
  - 3.re

APPENDIX:

POSTDEF:

3. Makefile

最後は Makefile を作る.正確に言えば Makefile である必要性はなく build.sh など適当にスクリプトを実装しても OK!簡単に言うと「章単位」にまとめたファイルを ./build ディレクトリにリダイレクトしている.<(echo) を使っているのは .re ファイル同士をまとめるときに空行を含めないと @<chap> や @<img> を使った参照ができなかったという理由がある.あくまで実装例として!

SHELL := $(shell which bash)

build:
    mkdir -p build
    cat chapter1.re <(echo) \
        section1-1.re > build/1.re
    cat chapter2.re <(echo) \
        section2-1.re <(echo) \
        section2-2.re > build/2.re
    cat chapter3.re <(echo) \
        section3-1.re <(echo) \
        section3-2.re <(echo) \
        section3-3.re > build/3.re
    rake pdf

準備ができたら make build を実行すればビルドできる.注意点は「章単位」でまとめるため @<chap>{3} などビルド後の ID を使うところ!確認すると @<chap> や @<img> を使った参照も期待した通りに動いている.やったー👏

$ make build

ビルド確認まで終われば,後は GitHub Actions などで make build を実行すれば OK!詳しくは以下の記事を見てもらえれば!

kakakakakku.hatenablog.com

CKS (Certified Kubernetes Security Specialist) に合格した : 勉強方法をまとめる

Kubernetes の資格 CKS (Certified Kubernetes Security Specialist) に合格した 🎉 やったー!Kubernetes 関連は3個目!

今回の記事では「勉強方法」をまとめようと思う.

www.cncf.io

時系列で書くと,2021年2-3月に CKAD (Certified Kubernetes Application Developer) と CKA (Certified Kubernetes Administrator) に合格していて,詳しくは以下の記事にまとめてある.せっかくなら CKS まで連続で受験しようと思っていたけど,仕事に忙殺されて時間が捻出できなくなったのと,当時はまだ CKS を日本語で受験することができず,結果的に受験するタイミングを逃してしまった.なお,2021年7月に日本語化されている!

そこで今月(2022年4月)にやるぞ!と決めて,3週間ほど平日夜にコツコツ勉強を続けた.週末はもっと時間を捻出したと思う.また個人用だけど毎日学んだメモをブログとは別に TIL (Today I Learned) としてまとめたのも効果的だったと思う.うまく学習サイクルを回しながら自信を持って合格できた!CKAD や CKA のときにも感じたけど,試験中は本当に楽しくハッカソンに参加している気持ちになる.

kakakakakku.hatenablog.com

前提と結果 🐳

CKAD / CKA の記事にも書いたけど,僕は技術講師として研修で Kubernetes と Amazon EKS を教える機会があったり,Kubernetes 上のアプリケーション開発の経験も少しある.逆に言えば,プロダクションワークロードでの大規模な運用経験はなかったりする.またセキュリティ関連の知識も少なく,CKS で出題される技術トピックの多くは未経験だった.よって,あくまで個人的には「CKAD < CKA < CKS」の順番で難しく感じたし,最初は CKS の出題範囲の広さにも圧倒された.

結果は以下の通りだった.1問(6点)は確実に間違えたけど,他にもう1問どこを間違えたんだろう...!正直2時間では時間ギリギリで見直しは5問しかできなかった.そして,今回 CKS を受験して(勉強過程も含めて)1番良かったのは「"知らないこと" に気付けた」ことだった!

受験日 試験名 得点 結果 バージョン
2022/04/27 CKS (Certified Kubernetes Security Specialist) 88 点 合格 Kubernetes v1.23

出題範囲 🐳

カリキュラム(出題範囲)は GitHub に PDF として公開されている.

Domain Weight
Cluster Setup 10 %
Cluster Hardening 15 %
System Hardening 15 %
Minimize Microservice Vulnerabilities 20 %
Supply Chain Security 20 %
Monitoring, Logging, and Runtime Security 20 %

github.com

とは言え,出題範囲だけだと勉強するべき具体的な技術トピックを把握しにくくもある.以下の GitHub リポジトリ walidshaari/Certified-Kubernetes-Security-Specialist と echoboomer/k8s-cks-notes はとてもよくまとまっている.おすすめ!

github.com

github.com

CKS 勉強方法 🐳

今回は大きく「3種類」の勉強方法を組み合わせた.詳しく紹介する!

  • [A] 座学("知らないこと" に気付くためにインプットする)
  • [B] 検証 & ブログ(気になったら検証をしてブログにアウトプットする)
  • [C] 実践演習(演習環境を使ってとにかく実践する)

[A] 座学("知らないこと" に気付くためにインプットする)

A-1. Udemy : Kubernetes CKS 2022 Complete Course

まず,有名な Udemy コース「Kubernetes CKS 2022 Complete Course」を1.5倍速でザッと視聴した(正確には購入したときは 2021 だった).e-Learning は本当にわかりやすくて,デモも多くて,学習項目ごとにコツコツ学べた.とにかく「"知らないこと" に気付く」ために1番有効だったと思う.2021年に購入したときには Exam Simulator も同梱されていたけど,現在は同梱されなくなっている(後述する).

www.udemy.com

講師をしている Kim のブログに Udemy Discount Code も載っているため,購入する前に確認すると良いかと!

wuestkamp.medium.com

A-2. 書籍 : Docker/Kubernetes 開発・運用のためのセキュリティ実践ガイド

並行して書籍「Docker/Kubernetes 開発・運用のためのセキュリティ実践ガイド」も読んだ.CKS 対策本ではないけど,学べる技術トピックは近く,何よりも日本語で読めるのは素晴らしかった.今度書評記事も書く予定!

英語の書籍だと「Learn Kubernetes Security」も CKS 対策として使えるという話を聞いたこともある.今回は読まなかった.

[B] 検証 & ブログ(気になったら検証をしてブログにアウトプットする)

B-1. ブログ

座学で大量にインプットをして,気になったり,理解があやふやに感じたところはどんどん検証をしてブログにまとめた.個人的にはブログにまとめることで,客観的に学び直せて理解が深まる感覚がある.また単純にブログネタも増やせたのも良かった.実は2021年にも少し CKS を勉強していた時期があり,以下に CKS に関連する記事の一覧をまとめておく.

[C] 実践演習(演習環境を使ってとにかく実践する)

C-1. Killercoda

演習環境「Killercoda」は本当に価値があった.Udemy コース「Kubernetes CKS 2022 Complete Course」と繋がっていて,e-Learning を観た後に Killercoda で演習をする流れになっている.とすると Udemy 購入者限定のように思うけど,そんなことはなく,登録すれば無料で何度でも使える.絶対にやるべき!現時点で以下の「40種類」もある!全て完璧に正解できるようにしておくと良いと思う.

  • Playground
  • Vim Setup
  • Apiserver Crash
  • Apiserver Misconfigured
  • Apiserver NodeRestriction
  • AppArmor
  • Auditing Enable Audit Logging
  • CIS Benchmarks fix Controlplane
  • CertificateSigningRequests sign manually
  • CertificateSigningRequests sign via API
  • Container Hardening
  • Container Image Footprint User
  • Container Namespaces Docker
  • Container Namespaces Podman
  • Falco Change Rule
  • Image Use Digest
  • Image Vulnerability Scanning Trivy
  • ImagePolicyWebhook Setup
  • Immutability Readonly Filesystem
  • Ingress Create
  • Ingress Secure
  • NetworkPolicy Create Default Deny
  • NetworkPolicy Metadata Protection
  • NetworkPolicy Namespace Selector
  • Privilege Escalation Containers
  • Privileged Containers
  • RBAC ServiceAccount Permissions
  • RBAC User Permissions
  • Sandbox gVisor
  • Secret Access in Pods
  • Secret ETCD Encryption
  • Secret Read and Decode
  • Secret ServiceAccount Pod
  • ServiceAccount Token Mounting
  • Static Manual Analysis Docker
  • Static Manual Analysis K8s
  • Syscall Activity Strace
  • System Hardening Close Open Ports
  • System Hardening Manage Packages
  • Verify Platform Binaries

killercoda.com

C-2. A Cloud Guru : Certified Kubernetes Security Specialist (CKS)

A Cloud Guru の「Certified Kubernetes Security Specialist (CKS)」は e-Learning を使わず,演習環境「HANDS-ON LAB」を中心に使った.特に最後にある Practice Exam には「計12種類」の演習を試せて RBAC / Pod Security Policies / CIS Kubernetes Benchmarks / Network Policy / ImagePolicyWebhook / Trivy / AppArmor / Falco などを試せる.手順や回答例が充実してるのはメリットだけど「答え合わせ」の機能はなく,受験直前だと使いにくく感じた.

acloudguru.com

C-3. Kodekloud : CKS – Challenges

有料コースの Kodekloud から2021年4月に新しくリリースされた「無料の」演習環境として「CKS – Challenges」がある.タイミング良く受験前にリリースされたため試した.現時点だと Challenges 1-3 まで公開されていて,Challenges 4-5 は公開されていなかった.難易度は高く複雑な演習に取り組めて良かった.個人的には UI が使いにくく,問題を確認するために「コンポーネント」や「矢印」をクリックする必要があると理解するまでに時間がかかった.

kodekloud.com

C-4. Kubernetes Exam Simulator

最後は Kubernetes Exam Simulator で,もともとは Udemy コースに同梱されていて,Killer Shell (Killer.sh) という名前だった.現在は資格自体に「公式に」同梱されているため,試験を購入すれば模擬試験として最大2回まで受験できる.試験日を決める前に受験できるので,ある程度準備できたと感じたら受験してみるのが良いと思う.

killer.sh

Kubernetes Exam Simulator はドキュメントにも書かれている通り,実際の試験よりも難しく作られている.実際に「2時間」を計測して受験したら「41 / 75(55点ぐらい)」でガッカリした(´・ω・`) その後に答えを見ずにドキュメントを使って続けたら「53 / 75(70点ぐらい)」まで上がった.残りは難しく,答えを見て理解を深めた.また Kubernetes Exam Simulator は「36時間」の制限時間内なら何度でも環境をリセットできるため,もう一度「2時間」で再挑戦したら「72 / 75(96点ぐらい)」まで取れるようになった.

唯一残念だったのは Kubernetes Exam Simulator は日本語化されてなく,受験後のアンケートにフィードバックを入れておいた.

training.linuxfoundation.org

まとめ

受験しようと思って後回しにしていた CKS (Certified Kubernetes Security Specialist) に合格できて良かった 🎉

本記事が何かの参考になれば✌️

Kubernetes と Falco を組み合わせて脅威検出に入門する

Kubernetes でコンテナワークロードの脅威検出として使える「Falco」に入門する.CNCF (Cloud Native Computing Foundation) で Incubating に位置しているプロジェクトで,今回は実際に Falco を使って Pod に対する操作(振る舞い)を検出したり,独自ルールを作る.Falco はコンテナに限らず,ホスト側のプロセスも監視できる.

falco.org

インストールをする 🦅

以下の検証環境を使う.ドキュメントに書いてある Ubuntu の手順をそのまま使って,ワーカーノードに簡単に Falco v0.31.1 をインストールできた.また Helm を使って Kubernetes 上に Falco を DaemonSet としてインストールをする選択肢もある.Falco は日本語ドキュメントがとても充実しててイイ✨

  • Kubernetes v1.23.0
  • ワーカーノード : Ubuntu 20.04.3 LTS
node01 $ curl -s https://falco.org/repo/falcosecurity-3672BA8F.asc | apt-key add -
node01 $ echo "deb https://download.falco.org/packages/deb stable main" | tee -a /etc/apt/sources.list.d/falcosecurity.list
node01 $ apt-get update -y
node01 $ apt-get -y install linux-headers-$(uname -r)
node01 $ apt-get install -y falco

node01 $ systemctl start falco
node01 $ systemctl status falco

falco.org

/etc/falco を確認すると falco.yaml(設定ファイル)や falco_rules.yaml(ルール)や falco_rules.local.yaml(独自ルール)など Falco 関連のファイルがあった.

node01 $ ls -l /etc/falco
total 200
-rw-r--r-- 1 root root  12400 Mar  9 17:20 aws_cloudtrail_rules.yaml
-rw-r--r-- 1 root root  11384 Mar  9 17:20 falco.yaml
-rw-r--r-- 1 root root   1136 Mar  9 17:20 falco_rules.local.yaml
-rw-r--r-- 1 root root 133017 Mar  9 17:20 falco_rules.yaml
-rw-r--r-- 1 root root  27287 Mar  9 17:20 k8s_audit_rules.yaml
drwxr-xr-x 2 root root   4096 Apr 16 12:14 rules.available
drwxr-xr-x 2 root root   4096 Mar  9 17:42 rules.d

動作確認をする 🦅

まず,動作確認をする.今回は Pod(コンテナ)に対してシェル接続が発生したことを検出する.運用上必要になる場面以外では不正な操作の可能性があり,検出できるのは便利だと思う.さっそく kubectl run コマンドを使って nginx Pod を起動して,kubectl exec コマンドを使って Pod にシェル接続をする.

controlplane $ kubectl run nginx --image nginx:1.21
pod/nginx created

controlplane $ kubectl exec -it nginx -- sh
# 

syslog を確認すると A shell was spawned in a container with an attached terminal という振る舞いが検出されている.container_id や image など,詳細情報も確認できる.

  • container_id=aaee21e42016
  • image=docker.io/library/nginx
node01 $ grep falco /var/log/syslog
(中略)

Apr 16 14:00:00 node01 falco: 14:00:00.000000000: Notice A shell was spawned in a container with an attached terminal (user=kc-internal user_loginuid=-1 nginx (id=aaee21e42016) shell=sh parent=runc cmdline=sh terminal=34817 container_id=aaee21e42016 image=docker.io/library/nginx)

設定ファイルを確認する 🦅

まず /etc/falco/falco.yaml を確認すると Falco で検出した結果を syslog に出力する設定になっている.

# Send information logs to stderr and/or syslog Note these are *not* security
# notification logs! These are just Falco lifecycle (and possibly error) logs.
log_stderr: true
log_syslog: true

次に /etc/falco/falco_rules.yaml を確認すると,A shell was spawned in a container からはじまる今回検出された振る舞いがルールとして設定されている.

- rule: Terminal shell in container
  desc: A shell was used as the entrypoint/exec point into a container with an attached terminal.
  condition: >
    spawned_process and container
    and shell_procs and proc.tty != 0
    and container_entrypoint
    and not user_expected_terminal_shell_in_container_conditions
  output: >
    A shell was spawned in a container with an attached terminal (user=%user.name user_loginuid=%user.loginuid %container.info
    shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline terminal=%proc.tty container_id=%container.id image=%container.image.repository)
  priority: NOTICE
  tags: [container, shell, mitre_execution]

ルールを一部変更する 🦅

検証のため /etc/falco/falco_rules.yaml を直接変更して,output として tag=%container.image.tag(コンテナイメージタグ)と pod_name=%k8s.pod.name(Pod 名)を追加する.以下のドキュメントを読むと,Falco は他にも多くのフィールドをサポートしている.

falco.org

- rule: Terminal shell in container
  desc: A shell was used as the entrypoint/exec point into a container with an attached terminal.
  condition: >
    spawned_process and container
    and shell_procs and proc.tty != 0
    and container_entrypoint
    and not user_expected_terminal_shell_in_container_conditions
  output: >
    A shell was spawned in a container with an attached terminal (user=%user.name user_loginuid=%user.loginuid %container.info
    shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline terminal=%proc.tty container_id=%container.id image=%container.image.repository tag=%container.image.tag pod_name=%k8s.pod.name)
  priority: NOTICE
  tags: [container, shell, mitre_execution]

Falco を再起動して,もう一度 kubectl exec コマンドを使って Pod にシェル接続をする.

node01 $ systemctl restart falco

controlplane $ kubectl exec -it nginx -- sh
# 

すると期待した通りに tag と pod_name も確認できるようになった.

  • tag=1.21
  • pod_name=nginx
node01 $ grep falco /var/log/syslog
(中略)

Apr 16 14:00:00 node01 falco: 14:00:00.000000000: Notice A shell was spawned in a container with an attached terminal (user=kc-internal user_loginuid=-1 nginx (id=aaee21e42016) shell=sh parent=runc cmdline=sh terminal=34817 container_id=aaee21e42016 image=docker.io/library/nginx tag=1.21 pod_name=nginx)

デフォルトマクロ 🦅

Falco ルールの condition には条件が書いてある.今回だと spawned_process や container など,簡易的な表現になっていて,これは Falco の「デフォルトマクロ」と言う.実際に /etc/falco/falco_rules.yaml を確認すると spawned_process(新規プロセスが生成された)や container(コンテナオブジェクトである)というよく使う条件がプリセットされている.

- macro: spawned_process
  condition: evt.type in (execve, execveat) and evt.dir=<

- macro: container
  condition: (container.id != host)

独自ルールを作る 🦅

検証のため,簡単な独自ルールを作る.今回は Pod 上で mkdir コマンドを使って「新規ディレクトリを作ったこと」を検出する.以下のルールを /etc/falco/falco_rules.local.yaml に追加した.

- rule: mkdir_in_container
  desc: mkdir_in_container
  condition: container and mkdir
  output: mkdir_in_container
  priority: NOTICE
  tags: [container, shell]

Falco を再起動して,もう一度 kubectl exec コマンドを使って Pod にシェル接続をしてから mkdir コマンドを実行した.

node01 $ systemctl restart falco

controlplane $ kubectl exec -it nginx -- sh
# mkdir falco
# 

すると,簡単ではあるけど,期待した通りに mkdir コマンドの実行を検出できた.

node01 $ grep falco /var/log/syslog
(中略)

Apr 16 14:00:00 node01 falco: 14:00:00.000000000: Notice mkdir_in_container

まとめ

Kubernetes でコンテナワークロードの脅威検出として使える「Falco」を試した.今回はお手軽に Pod への「シェル接続」と「mkdir コマンドの実行」を検出した.他にも「yum などのパッケージマネージャの実行」や「ホスト側に危険性のあるディレクトリのマウント」などを検出できたりもする.「Docker/Kubernetes 開発・運用のためのセキュリティ実践ガイド」 にも Falco の紹介が載っていて参考になった.