https://github.com/falcosecurity/client-go を使うと Falco の grpc API からイベントを取得できる。
Falco 側では grpc の設定をしておく。今回は Unix Domain Socket だが、TLS 証明書を使うこともできる。
grpc:
enabled: true
bind_address: "unix:///var/run/falco.sock"
# when threadiness is 0, Falco automatically guesses it depending on the number of online cores
threadiness: 0
grpc_output:
enabled: true
falcosecurity/client-go の使い方は README にある通り。
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/falcosecurity/client-go/pkg/api/outputs"
"github.com/falcosecurity/client-go/pkg/client"
"github.com/gogo/protobuf/jsonpb"
)
func printOutput(res *outputs.Response) error {
out, err := (&jsonpb.Marshaler{}).MarshalToString(res)
if err != nil {
return err
}
fmt.Println(out)
return nil
}
func main() {
c, err := client.NewForConfig(context.Background(), &client.Config{
UnixSocketPath: "unix:///var/run/falco.sock",
})
if err != nil {
log.Fatalf("unable to connect: %v", err)
}
defer c.Close()
ctx := context.Background()
err = c.OutputsWatch(ctx, printOutput, time.Second*1)
if err != nil {
log.Fatalf("outputs watch error: %v", err)
}
}
これを実行すると次のような Output を得られる。
{"time":{"seconds":"1629036701","nanos":217126376},"priority":"ERROR","rule":"Write below etc","output":"14:11:41.217126376: Error File below /etc opened for writing (user=root user_loginuid=1000 command=bash parent=su pcmdline=su file=/etc/mrtc0 program=bash gparent=sudo ggparent=bash gggparent=sshd container_id=host image=\u003cNA\u003e)","outputFields":{"container.id":"host","container.image.repository":"\u003cNA\u003e","evt.time":"14:11:41.217126376","fd.name":"/etc/mrtc0","proc.aname[2]":"sudo","proc.aname[3]":"bash","proc.aname[4]":"sshd","proc.cmdline":"bash","proc.name":"bash","proc.pcmdline":"su","proc.pname":"su","user.loginuid":"1000","user.name":"root"},"hostname":"sandbox"}
レスポンスの struct は https://github.com/falcosecurity/client-go/blob/20857902b18d945b66ceb0ec5d89f29de858e499/pkg/api/outputs/outputs.pb.go#L92-L104 にある通りなので、必要に応じてフィールドは抽出できそう。