Falco + Falcosidekick + Kubelessを使って、Falcoのイベントトリガーで任意のサーバレスコードを実行してみた

Kenji Tsutsusmi

2021.3.25

スリーシェイクのSREの堤です。

Falcoってご存知でしょうか?Falcoはオープンソースのセキュリティランタイムで、もともとはSysdig社が開発して、現在はそのオープンソース版としてCNCF傘下で管理されています。

FalcoはLinuxカーネルのシステムコールを監視して、怪しい動きなどを検出することが出来ます。Falcosidekickと連携することで、SlackやPagerDuty、そして今回紹介するKubelessとの連携もできます。Falcosidekickは、Falco本体に補助するためのツールで、主に外部連携をする際のプロキシ的な役割をします。

Falcoは、EC2やGCEにデプロイしているLinuxホストで動かすことも出来ますが、Kubernetes用のセキュリティランタイムの色が強いです。そのため、Falcoの公式HPでも「Kubernetesのデファクトスタンダードなセキュリティツール」と書かれています。

なお、Falcoのエンタープライズ版はSysdig Secureというものもあります。実は私はこのエンタープライズ版も扱ったこともあります。両者の機能差に関しては以下のページを御覧ください。

Enterprise Falco Open-Source Cloud-Native Security Project | Sysdig

なお、ファルコといえば北斗の拳の登場人物を連想するのは、世代


Kubelessについて

Kubelessは、Kubernetes上でデプロイできるFaaSです。簡単にいうと、Kubernetes上でLambda(AWS)やCloud Functions(GCP)のようなことが出来ます。FaaSは、他にはKnativeやOpenFaaSなどがあります。Kubelessは、Bitnamiが開発したものです。

言語は、Python, Node.js, Ruby, PHP, Golang, .NET, Ballerinaを標準でサポート。またコンテナイメージを渡せば、任意の言語でも動かせるようです(試してないので、詳細は不明です)

Kubelessのインストール

まずはKubernetsクラスタ側にKubelessをデプロイします。下記は公式HPの解説をそのままのやり方です。

$ export RELEASE=$(curl -s
https://api.github.com/repos/kubeless/kubeless/releases/latest |
grep tag_name | cut -d ‘”‘ -f 4) $ kubectl create ns kubeless $
kubectl create -f https://github.com/kubeless/kubeless/releases/download/$RELEASE/kube
less-$RELEASE.yaml


$ kubectl get pods -n kubeless NAME
READY STATUS RESTARTS AGE kubeless-controller-manager-
567dcb6c48-ssx8x 1/1 Running 0 1h

KubelessのCLIツールのインストールを行います。macOSの場合は、brewでサクッとインストールが出来ます。

% brew install kubeless

kubelessコマンドを使って、実際に任意のサーバレスコードをデプロイします。今回はGo言語で実装してみたいと思う。今回使用するサンプルはkubelessのGitHubページにあるものをそのまま流用。

package kubeless

import (
	"fmt"

	"github.com/kubeless/kubeless/pkg/functions"
)

// Handler sample function with data
func Handler(event functions.Event, context functions.Context) (string, error) {
	fmt.Println(event)
	return event.Data, nil
}

そして、下記をkubelessコマンドを実行する。

% kubeless function deploy hello \
–runtime go1.14 \
–from-file main.go \
–handler main.Handler

kubeless function ls コマンドでデプロイ状況を確認します。STATSUが「1/1 READY」となっていればOKです。

% kubeless function ls hello
NAME NAMESPACE HANDLER RUNTIME DEPENDENCIES STATUS
hello default main.Handler go1.14 1/1 READY

Falcoのインストール

helmを使うのが便利です。

https://github.com/falcosecurity/charts

インストール手順はすべて上記のGitHubにかかれているのですが、日本語訳したものを簡単に記載します。

Helm リポジトリーの追加

helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update

HelmでのFalco/Falcosidekickのインストール

公式ページはdefaultのネームスペースに入れる感じで書いてますが、個人的には分けてやりたいので、 「falco」というネームスペースを作ってやります。

kubectl create namespace falco

そして、helmを使うとfalcoとfalcosidekickが同時にインストールすることが出来ます。下記yamlファイルを読み込むことで、falcosidekcikのインストールと、kubelessの連携も一斉に行えます。

helm install -n falco falco falcosecurity/falco -f falco-value.yaml

auditLog:
  enabled: true

falcosidekick:
  enabled: true
  config:
    debug: true
    kubeless:
      function: "hello"
      namespace: "default"
      port: 8080
      minimumpriority: "notice"     
  webui:
    enabled: false

デプロイするとこんな感じになります。

% kubectl -n falco get pods
NAME                                   READY   STATUS    RESTARTS   AGE
falco-4mdfd                            1/1     Running   0          18h
falco-c4tlg                            1/1     Running   0          18h
falco-c5c2g                            1/1     Running   0          18h
falco-dfn65                            1/1     Running   0          18h
falco-falcosidekick-5f6958577b-28m4w   1/1     Running   0          18h
falco-falcosidekick-5f6958577b-46db8   1/1     Running   0          18h
falco-glnhk                            1/1     Running   0          18h
falco-vlsgd                            1/1     Running   0          18h

Falcoで何かをイベントトリガーをする

Falcoはコンテナセキュリティツールなので、不審なアクティビティがあると検出します。例えば、既存のコンテナの中に入って操作する、 /etc 配下になにかファイルを作ったり、権限を変えたりすると検出します。

% kubectl -n falco exec -it <Pod名> — bash
% touch /etc/hoge.conf
% kubectl logs <KubelessでデプロイしたPod名>

2021/03/25 03:50:50 10.0.16.201:35522 “POST / HTTP/1.1” 200
Falcosidekick
{{“output”:”03:50:51.127556729: Error File below /etc opened for writing (user=root user_loginuid=-1 command=touch /etc/hoge.conf parent=bash pcmdline=bash file=/etc/hoge.conf program=touch

<<中略>>

今回展開したkubelessの関数は、Falco/Falcosidekickから受け取ったイベント内容をそのままprintするだけの簡単なものです。これを工夫すれば、他のAPIと連携してデータ連携させることも可能ですし、LINEとかに通知させることもできるはずです。

もちろん、Falcosidekickは、Slackやメール通知、PagerDuty通知など多くのOutputに対応。多くのことはこれで解決できそうですし、開発も活発なので、どんどん新しいOutputが作成されています。これに加えて、もう少し凝ったことをしたい場合は、KubelessやOpenFaasを使えばより柔軟なことができるのではないかと思います。

また、これを応用することで、不審なコンテナが起動すると、強制的にそのコンテナをシャットダウンすることも可能。これらは、Falcoの公式ページでも紹介されています。

Falcosidekick + Kubeless = a Kubernetes Response Engine

この記事は以上です。