Skip to content

Commit

Permalink
Build with podman & Containerfile (#1)
Browse files Browse the repository at this point in the history
* dev: preparing podman build files

* dev: update to Go 1.18 and latest knative

* dev: Containerfile

* dev: Makefile

* gitignore vendor folder

* dev: add bin dir

* dev: add a build stage for go mod vendor

* add vendor folder to gitignore list

* doc: update

Co-authored-by: thedetective <[email protected]>
Co-authored-by: nicop311 <[email protected]>
  • Loading branch information
3 people authored Jul 26, 2022
1 parent fd4bcf9 commit 07bb7a0
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 498 deletions.
2 changes: 2 additions & 0 deletions .containerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.cache/
.git/
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# GoLang
vendor/
52 changes: 52 additions & 0 deletions Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# This is a Containerfile/Dockerfile
#==============================================================================#
# Build me localy:
# $ podman build -f Containerfile -t localhost/c2-drop:latest
#==============================================================================#

# Go version
ARG GOLANG_VERSION=1.18

# Registry and images
ARG BUILDER_REGISTRY=docker.io/library
ARG BUILDER_IMAGE=golang
ARG BUILDER_IMAGE_TAG=${GOLANG_VERSION}-alpine

ARG FINAL_REGISTRY=docker.io/library
ARG FINAL_IMAGE=alpine
ARG FINAL_IMAGE_TAG=3.15

#==============================================================================#
# Setup the Go builder image
#==============================================================================#
FROM ${BUILDER_REGISTRY}/${BUILDER_IMAGE}:${BUILDER_IMAGE_TAG} AS gosetup

ENV CGO_ENABLED=0

WORKDIR /opt/knative/c2-drop
COPY cmd cmd
COPY go.mod .
COPY go.sum .

RUN go mod vendor

#==============================================================================#
# Building the Go Knative application
#==============================================================================#
FROM gosetup AS gobuilder

RUN mkdir -p /opt/knative/c2-drop/bin
WORKDIR /opt/knative/c2-drop

RUN go build -v -o /opt/knative/c2-drop/bin/c2-drop cmd/c2-drop/main.go

#==============================================================================#
# Final image
#==============================================================================#
FROM ${FINAL_REGISTRY}/${FINAL_IMAGE}:${FINAL_IMAGE_TAG} AS Final

RUN mkdir -p /opt/knative/c2-drop/bin
WORKDIR /opt/knative/c2-drop/bin
COPY --from=gobuilder /opt/knative/c2-drop/bin/c2-drop .

ENTRYPOINT ["/opt/knative/c2-drop/bin/c2-drop"]
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ GOCLEAN=$(GOCMD) clean
# App parameters
NAME := c2-drop
APP_MAIN_PATH := ./cmd/$(NAME)
BINARY_FOLDER := ./bin
BINARY_NAME := falco-$(NAME).so

# Go debug
Expand All @@ -21,6 +22,7 @@ endif
all: build

build:
$(GOCMD) mod vendor
@$(GODEBUGFLAGS) $(GOBUILD) -v -o $(BINARY_NAME) $(APP_MAIN_PATH)

clean:
Expand Down
213 changes: 18 additions & 195 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,225 +1,48 @@
# c2-drop

Falco + Knative drop pod if a connection to a C2 server is detected.

Inspired by:
* https://github.com/n3wscott/falco-drop
* https://falco.org/blog/falcosidekick-response-engine-part-3-knative/

## Build Container Image

**BUILD IS FAILING** See below.


See these issues:

* https://github.com/knative/pkg/issues/2452
* https://github.com/n3wscott/falco-drop/issues/3

I copy/paste the issue here below.

***
Hello,

I read your Falco blog post and I tried to reproduce and rebuild your container images.
https://falco.org/blog/falcosidekick-response-engine-part-3-knative/
Several methods can be used to build the container image

## Steps to build n3wscott/falco-drop without github actions
### `podman build`

I clone your repo:
```
git clone https://github.com/n3wscott/falco-drop.git
$ podman build -f Containerfile -t localhost/c2-drop:latest
```

I move to the folder:
```
cd falco-drop
```

I do have Google ko installed:
```
$ ko version
v0.10.0
```
### Google ko `ko build`

I do have GoLang installed:
```
$ go version
go version go1.17.7 linux/amd64
```

I customize Google ko to point to my own local `registryv2` instance (a local container registry):
```
export KO_DOCKER_REPO=mycustomreg.my.domain.net:5000
```

I manually run Google ko since I do not have Github action or CI/CD tools availables:
```
ko build --insecure-registry ./cmd/drop
```
And this is a success: an image is built and pushed to my registry.

I tested the image with Falco and a k8s cluster : it does the response engine thing.


## Building a small variation of n3wscott/falco-drop app

Now lets say I want to experiment on an other Falco rule. For example, I want to replace `"Terminal shell in container"` with `"Outbound Connection to C2 Servers"`.

Lets duplicate your Knative app:
```
mkdir cmd/c2-drop
cp cmd/drop/main.go cmd/c2-drop/main.go
```

In the file `cmd/c2-drop/main.go`, I replace one line in your code: I replace `"Terminal shell in container"` with `"Outbound Connection to C2 Servers"`. I have something like this:

```go
if payload.Rule == "Outbound Connection to C2 Servers" {
if err := kc.CoreV1().Pods(payload.Fields.Namespace).Delete(ctx, payload.Fields.Pod, metav1.DeleteOptions{}); err != nil {
```
Now lets build this new Knative service app with Google ko:
```
ko build --insecure-registry ./cmd/c2-drop/
```
And this is a success: an image is built and pushed to my registry.

I tested the image with Falco and a k8s cluster : it does the response engine thing for C2 server alerts.
### [TODO] Build using `make` or Go `mage`

## Handle Go modules and vendors myself
> Note: As of now, a `Makefile` exists but it only builds the Go code. It is
> not used to build the container image.
Now if I want to create my own Go module, I start by creating the following folder:
```
c2-drop/
├── cmd
└── c2-drop
└── main.go
```
Where `cmd/c2-drop/main.go` is a copy paste of the "`Outbound Connection to C2 Servers`" Knative app.
## Usage

I do have Google ko installed:
```
$ ko version
v0.10.0
```
TODO

I do have GoLang installed:
```
$ go version
go version go1.17.7 linux/amd64
```
## Troubleshouting

Then I init my Go module:
```
go mod init github.com/nicop311/c2-drop
```
```
go: creating new go.mod: module github.com/nicop311/c2-drop
go: to add module requirements and sums:
go mod tidy
```
My `go.mod` looks like this:
```
module github.com/nicop311/c2-drop

go 1.17
```
Then I run `go mod tidy`, but it seems there are some packages not available with Go 1.17:
```
[...]
c2-drop/cmd/c2-drop imports
knative.dev/pkg/client/injection/kube/client imports
k8s.io/client-go/applyconfigurations/admissionregistration/v1 imports
k8s.io/apimachinery/pkg/util/managedfields imports
k8s.io/kube-openapi/pkg/util/proto tested by
k8s.io/kube-openapi/pkg/util/proto.test imports
github.com/onsi/gomega imports
github.com/onsi/gomega/matchers imports
github.com/onsi/gomega/matchers/support/goraph/bipartitegraph imports
github.com/onsi/gomega/matchers/support/goraph/util loaded from github.com/onsi/gomega@v1.10.1,
but go 1.16 would select v1.16.0

To upgrade to the versions selected by go 1.16, leaving some packages unresolved:
go mod tidy -e -go=1.16 && go mod tidy -e -go=1.17
If reproducibility with go 1.16 is not needed:
go mod tidy -compat=1.17
For other options, see:
https://golang.org/doc/modules/pruning
```
I run this:
```
go mod tidy -e -go=1.16 && go mod tidy -e -go=1.17
```
I end up with that:
```
c2-drop/
├── cmd
│ └── c2-drop
│ └── main.go
├── go.mod
└── go.sum
```
Now I add the vendor folder:
```
go mod vendor
```
I customize Google ko to point to my own local `registryv2` instance (a local container registry):
```
export KO_DOCKER_REPO=mycustomreg.my.domain.net:5000
```
Now I try to build, but I have errors:
```
ko build --insecure-registry ./cmd/c2-drop
```
```
2022/03/01 17:14:10 No matching credentials were found, falling back on anonymous
2022/03/01 17:14:12 Using base gcr.io/distroless/static:nonroot@sha256:80c956fb0836a17a565c43a4026c9c80b2013c83bea09f74fa4da195a59b7a99 for c2-drop/cmd/c2-drop
2022/03/01 17:14:13 Building c2-drop/cmd/c2-drop for linux/amd64
2022/03/01 17:14:14 Unexpected error running "go build": exit status 2
# k8s.io/client-go/tools/cache
vendor/k8s.io/client-go/tools/cache/reflector.go:180:119: cannot use realClock (type *"k8s.io/apimachinery/pkg/util/clock".RealClock) as type "k8s.io/utils/clock".Clock in argument to wait.NewExponentialBackoffManager:
*"k8s.io/apimachinery/pkg/util/clock".RealClock does not implement "k8s.io/utils/clock".Clock (wrong type for NewTimer method)
have NewTimer(time.Duration) "k8s.io/apimachinery/pkg/util/clock".Timer
want NewTimer(time.Duration) "k8s.io/utils/clock".Timer
vendor/k8s.io/client-go/tools/cache/reflector.go:181:119: cannot use realClock (type *"k8s.io/apimachinery/pkg/util/clock".RealClock) as type "k8s.io/utils/clock".Clock in argument to wait.NewExponentialBackoffManager:
*"k8s.io/apimachinery/pkg/util/clock".RealClock does not implement "k8s.io/utils/clock".Clock (wrong type for NewTimer method)
have NewTimer(time.Duration) "k8s.io/apimachinery/pkg/util/clock".Timer
want NewTimer(time.Duration) "k8s.io/utils/clock".Timer
Error: failed to publish images: error building "ko://c2-drop/cmd/c2-drop": exit status 2
2022/03/01 17:14:14 error during command execution:failed to publish images: error building "ko://c2-drop/cmd/c2-drop": exit status 2
```
***
## Building with `go build` (no Google Ko)
After failing to build with Google Ko, I try to build with `go build`
```
go build -v -o c2-drop cmd/c2-drop/main.go
```
```
k8s.io/client-go/tools/cache
# k8s.io/client-go/tools/cache
vendor/k8s.io/client-go/tools/cache/reflector.go:180:119: cannot use realClock (type *"k8s.io/apimachinery/pkg/util/clock".RealClock) as type "k8s.io/utils/clock".Clock in argument to wait.NewExponentialBackoffManager:
*"k8s.io/apimachinery/pkg/util/clock".RealClock does not implement "k8s.io/utils/clock".Clock (wrong type for NewTimer method)
have NewTimer(time.Duration) "k8s.io/apimachinery/pkg/util/clock".Timer
want NewTimer(time.Duration) "k8s.io/utils/clock".Timer
vendor/k8s.io/client-go/tools/cache/reflector.go:181:119: cannot use realClock (type *"k8s.io/apimachinery/pkg/util/clock".RealClock) as type "k8s.io/utils/clock".Clock in argument to wait.NewExponentialBackoffManager:
*"k8s.io/apimachinery/pkg/util/clock".RealClock does not implement "k8s.io/utils/clock".Clock (wrong type for NewTimer method)
have NewTimer(time.Duration) "k8s.io/apimachinery/pkg/util/clock".Timer
want NewTimer(time.Duration) "k8s.io/utils/clock".Timer
```
### Knative and k8s API version

See these issues:

## Knative Go libs seems to be broken
* https://github.com/knative/pkg/issues/2452
* https://github.com/n3wscott/falco-drop/issues/3

The error seems to be triggered by the lib `"knative.dev/pkg/injection"`.
Make sure [the k8s API version](https://github.com/knative/pkg/blob/e60d250dc6378c387c8c9d149774ee21e9a827ab/go.mod#L44-L48)
in your `go.mod` file matches the version supported by Knative.
18 changes: 9 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
module github.com/nicop311/c2-drop

go 1.17
go 1.18

require (
github.com/cloudevents/sdk-go/v2 v2.8.0
k8s.io/apimachinery v0.23.4
knative.dev/pkg v0.0.0-20220301150941-76a28b066d64
k8s.io/apimachinery v0.23.8
knative.dev/pkg v0.0.0-20220721014205-1a5e1682be3a
)

require (
Expand Down Expand Up @@ -38,7 +38,7 @@ require (
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/gomega v1.16.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.11.0 // indirect
github.com/prometheus/client_golang v1.11.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
Expand All @@ -64,12 +64,12 @@ require (
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/api v0.22.5 // indirect
k8s.io/client-go v0.22.5 // indirect
k8s.io/klog/v2 v2.40.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.23.8 // indirect
k8s.io/client-go v0.23.8 // indirect
k8s.io/klog/v2 v2.60.1-0.20220317184644-43cc75f9ae89 // indirect
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
k8s.io/utils v0.0.0-20211116205334-6203023598ed // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
Expand Down
Loading

0 comments on commit 07bb7a0

Please sign in to comment.