diff --git a/cmd/seccompagent/seccompagent.go b/cmd/seccompagent/seccompagent.go index 5d3d37c0..e530df78 100644 --- a/cmd/seccompagent/seccompagent.go +++ b/cmd/seccompagent/seccompagent.go @@ -42,9 +42,9 @@ import ( ) var ( - socketFile string - resolverParam string - logflags string + socketFile string + resolverParam string + logflags string metricsBindAddress string ) @@ -97,6 +97,16 @@ func main() { switch resolverParam { case "none", "": resolver = nil + case "falco": + resolver = func(state *specs.ContainerProcessState) *registry.Registry { + r := registry.New() + podCtx := &kuberesolver.PodContext{ + Pid: state.State.Pid, + Pid1: state.Pid, + } + r.MiddlewareHandlers = append(r.MiddlewareHandlers, falco.NotifyFalco(podCtx)) + return r + } case "demo-basic": // Using the resolver allows to implement different behaviour // depending on the container. For example, you could connect to the diff --git a/falco-plugin/Dockerfile b/falco-plugin/Dockerfile index 4b14dd0c..6cbe227d 100644 --- a/falco-plugin/Dockerfile +++ b/falco-plugin/Dockerfile @@ -8,8 +8,21 @@ RUN cd /src && go mod download COPY ./ /src RUN cd /src && make -C falco-plugin -# Use the following command to get the built files: -# DOCKER_BUILDKIT=1 docker build -f falco-plugin/Dockerfile --output=falco-plugin/ . -FROM scratch AS deploy-source -COPY --from=builder /src/falco-plugin/*.so / +FROM falcosecurity/falco-no-driver:0.35.1 + +SHELL ["/bin/bash", "-c"] + +COPY falco-plugin/falco-config-plugin-snippet.yaml /etc/falco/ +COPY falco-plugin/seccomp_agent_rules.yaml /etc/falco/rules.d/ + +RUN \ + SNIPPET="$(jq -Rs . < /etc/falco/falco-config-plugin-snippet.yaml)" && \ + SNIPPET="${SNIPPET:1}" && \ + SNIPPET="${SNIPPET/%?/}" && \ + sed -i \ + -e '/^plugins:$/a \'"$SNIPPET" \ + -e 's/^load_plugins:.*$/load_plugins: [seccompagent]/' \ + /etc/falco/falco.yaml && \ + rm -f /etc/falco/falco-config-plugin-snippet.yaml +COPY --from=builder /src/falco-plugin/*.so /usr/share/falco/plugins/ diff --git a/falco-plugin/Dockerfile.dockerignore b/falco-plugin/Dockerfile.dockerignore new file mode 100644 index 00000000..dd449725 --- /dev/null +++ b/falco-plugin/Dockerfile.dockerignore @@ -0,0 +1 @@ +*.md diff --git a/falco-plugin/README.md b/falco-plugin/README.md new file mode 100644 index 00000000..e54717bd --- /dev/null +++ b/falco-plugin/README.md @@ -0,0 +1,48 @@ +# seccompagent Falco plugin + +## Build the plugin standalone + +``` +make -C falco-plugin +ls -l falco-plugin/libseccompagent.so +``` + +## Build a Falco container image with the plugin + +``` +export CONTAINER_REPO=${USER}test.azurecr.io/falco-with-seccompagent +export TAG=$CONTAINER_REPO:dev +docker build -f falco-plugin/Dockerfile -t $TAG . +docker push $TAG +``` + +## Run Falco with the plugin + +Start Falco in a container as previously compiled: +``` +docker run --rm -i -t \ + --privileged \ + -v /var/run/docker.sock:/host/var/run/docker.sock \ + -v /run/seccomp-agent-falco-plugin:/run/seccomp-agent-falco-plugin \ + -v /proc:/host/proc:ro \ + $TAG falco --modern-bpf +``` + +Start the Seccomp Agent: +``` +sudo ./seccompagent -resolver=falco -log trace +``` + +Launch a container and run a command: +``` +$ docker run --rm -it \ + --security-opt \ + seccomp=falco-plugin/seccomp-profile-demo.json \ + busybox +/ # mkdir /a +``` + +Falco logs the following: +``` +Notice The seccomp agent detected a mkdir... +``` diff --git a/falco-plugin/falco-config-plugin-snippet.yaml b/falco-plugin/falco-config-plugin-snippet.yaml new file mode 100644 index 00000000..643f1910 --- /dev/null +++ b/falco-plugin/falco-config-plugin-snippet.yaml @@ -0,0 +1,5 @@ + - name: seccompagent + library_path: libseccompagent.so + init_config: + socketFile: /run/seccomp-agent-falco-plugin/seccomp-agent-falco-plugin.sock + flushInterval: 30 diff --git a/falco-plugin/seccomp-profile-demo.json b/falco-plugin/seccomp-profile-demo.json new file mode 100644 index 00000000..2dcbaf20 --- /dev/null +++ b/falco-plugin/seccomp-profile-demo.json @@ -0,0 +1,16 @@ +{ + "defaultAction": "SCMP_ACT_ALLOW", + "architectures": [ + "SCMP_ARCH_X86_64" + ], + "listenerPath": "/run/seccomp-agent.socket", + "listenerMetadata": "MIDDLEWARE=falco", + "syscalls": [ + { + "action": "SCMP_ACT_NOTIFY", + "names": [ + "mkdir" + ] + } + ] +} diff --git a/falco-plugin/seccomp_agent_rules.yaml b/falco-plugin/seccomp_agent_rules.yaml index 37267593..2b38796a 100644 --- a/falco-plugin/seccomp_agent_rules.yaml +++ b/falco-plugin/seccomp_agent_rules.yaml @@ -2,8 +2,19 @@ - rule: Seccomp Agent desc: Seccomp Agent - condition: seccompagent.syscall != "" - output: id=%seccompagent.id pid=%seccompagent.pid syscall=%seccompagent.syscall k8s=(namespace=%seccompagent.k8s.namespace pod=%seccompagent.k8s.pod container=%seccompagent.k8s.container pid=%seccompagent.k8s.pid pidfilter=%seccompagent.k8s.pidfilter) - priority: DEBUG + condition: seccompagent.syscall == "mkdir" + output: > + The seccomp agent detected a mkdir: + id=%seccompagent.id + pid=%seccompagent.pid + syscall=%seccompagent.syscall + k8s=( + namespace=%seccompagent.k8s.namespace + pod=%seccompagent.k8s.pod + container=%seccompagent.k8s.container + pid=%seccompagent.k8s.pid + pidfilter=%seccompagent.k8s.pidfilter + ) + priority: NOTICE source: seccompagent tags: [seccompagent] diff --git a/pkg/handlers/falco/falco.go b/pkg/handlers/falco/falco.go index e4ef4f75..a14a1e12 100644 --- a/pkg/handlers/falco/falco.go +++ b/pkg/handlers/falco/falco.go @@ -18,16 +18,17 @@ import ( "context" "time" - pb "github.com/kinvolk/seccompagent/falco-plugin/api" libseccomp "github.com/seccomp/libseccomp-golang" log "github.com/sirupsen/logrus" "google.golang.org/grpc" + pb "github.com/kinvolk/seccompagent/falco-plugin/api" + "github.com/kinvolk/seccompagent/pkg/kuberesolver" "github.com/kinvolk/seccompagent/pkg/registry" ) -const socketfile = "/run/seccomp-agent-falco-plugin.sock" +const socketfile = "/run/seccomp-agent-falco-plugin/seccomp-agent-falco-plugin.sock" func NotifyFalco(podCtx *kuberesolver.PodContext) func(h registry.HandlerFunc) registry.HandlerFunc { return func(h registry.HandlerFunc) registry.HandlerFunc { @@ -77,11 +78,16 @@ func NotifyFalco(podCtx *kuberesolver.PodContext) func(h registry.HandlerFunc) r }).Error("Error in sending event to Falco") } - r := h(fd, req) + var r registry.HandlerResult + if h != nil { + r = h(fd, req) + } else { + r = registry.HandlerResultContinue() + } log.WithFields(log.Fields{ "pod": podCtx, - }).Error("Falco middleware completed") + }).Debug("Falco middleware completed") return r } }