-
Notifications
You must be signed in to change notification settings - Fork 349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Update KubeArmor to use OCI hooks instead of depending on container runtime socket #1714
base: main
Are you sure you want to change the base?
Conversation
9d510ed
to
86c5478
Compare
dab1324
to
4e65d92
Compare
Container created before KubeArmor now are handled with a simple detached process that waits on KubeArmor to start then sends all previous containers. |
Also, in order to try out this PR. You only need to build this code and run it on a CRI-O Kubernetes cluster and operator with snitch will take care of setting up the cluster. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1/2
KubeArmor/core/hook_handler.go
Outdated
listenPath := filepath.Join(kubearmorDir, "ka.sock") | ||
_ = os.Remove(listenPath) // in case kubearmor crashed and the socket wasn't removed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
listenPath := filepath.Join(kubearmorDir, "ka.sock") | |
_ = os.Remove(listenPath) // in case kubearmor crashed and the socket wasn't removed | |
_ = os.Remove(listenPath) // in case kubearmor crashed and the socket wasn't removed | |
listenPath := filepath.Join(kubearmorDir, "ka.sock") | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just reordering for better clarity
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, listenPath
is defined in the first line, so that wouldn't work?
KubeArmor/core/hook_handler.go
Outdated
listenPath := filepath.Join(kubearmorDir, "ka.sock") | ||
_ = os.Remove(listenPath) // in case kubearmor crashed and the socket wasn't removed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you need to handle the error case
for { | ||
conn, err := socket.Accept() | ||
if err != nil { | ||
log.Fatal(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we really sure we want to stop the entier execution if a single connection is not handled ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for some of the fatal error handling is because if we just logged that there is an error and continued, some containers might go unnoticed for the duration of KubeArmor lifetime. Do you think it's better if we leave KubeArmor running and not monitoring some containers or restart KubeArmor and get all containers from the start (using some form of exiting)?
return | ||
} | ||
if err != nil { | ||
log.Fatal(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment as above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please handle in other parts in the code as well
KubeArmor/core/hook_handler.go
Outdated
data := struct { | ||
Operation string `json:"operation"` | ||
Detached bool `json:"detached"` | ||
Container types.Container `json:"container"` | ||
}{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Define the struct outside function at the top of the file
KubeArmor/core/hook_handler.go
Outdated
return | ||
} | ||
|
||
if data.Operation == "create" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to use enums
KubeArmor/core/hook_handler.go
Outdated
dm.ContainersLock.Lock() | ||
if _, ok := dm.Containers[container.ContainerID]; !ok { | ||
dm.Containers[container.ContainerID] = container | ||
dm.ContainersLock.Unlock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to unlock once outside the if-else block rather than unlocking at each branch
pkg/KubeArmorOperator/hook/crio.go
Outdated
} | ||
|
||
func (h *crioHandler) close() { | ||
_ = h.conn.Close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handle error
pkg/KubeArmorOperator/hook/crio.go
Outdated
if err != nil { | ||
return nil, err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we sure we want to quit at the first error ?
pkg/KubeArmorOperator/hook/crio.go
Outdated
type containerInfo struct { | ||
SandboxID string `json:"sandboxID"` | ||
Pid int `json:"pid"` | ||
RuntimeSpec specs.Spec `json:"runtimeSpec"` | ||
Privileged bool `json:"privileged"` | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move this to the top of the file
83996bc
to
74160c2
Compare
8eb8ead
to
145a7c3
Compare
Signed-off-by: AbdelrahmanElawady <[email protected]>
Signed-off-by: AbdelrahmanElawady <[email protected]>
Signed-off-by: AbdelrahmanElawady <[email protected]>
Signed-off-by: AbdelrahmanElawady <[email protected]>
145a7c3
to
255e9c2
Compare
Purpose of PR?:
This PR utilizes OCI hooks to get container details inside KubeArmor instead of using container runtime socket. It depends on some Kubernetes annotations to get container name, pod name, namespace name and AppArmor profile (it looks like AppArmor is the only one required out of those but further testing is required).
This PR also updates snitch to configure hooks on the host (currently only CRI-O is supported).
Fixes #1390
Does this PR introduce a breaking change?
No, the goal is to have the same functionality as mounting container runtime socket without the security concerns of doing that.
If the changes in this PR are manually verified, list down the scenarios covered::
Tested with Getting Started example for now but more testing will be done.
Additional information for reviewer? :
Checklist:
<type>(<scope>): <subject>