Skip to content

Commit 4ee170d

Browse files
Rootless Buildkitd (#62)
* rootless * Fix AppArmor config on new K8s versions * Fix buildkitd config file mount path This fixes the "server gave HTTP response to HTTPS client" error * Update security considerations section of the README --------- Co-authored-by: FluxCapacitor2 <31071265+FluxCapacitor2@users.noreply.github.com>
1 parent 5a198a4 commit 4ee170d

3 files changed

Lines changed: 26 additions & 5 deletions

File tree

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,15 @@ AnvilOps is not designed for public use. Access to AnvilOps should only be share
6161

6262
#### Builds
6363

64-
- By default, builds are run in a shared BuildKit pod with `privileged: true`. **This is an insecure default while we wait for rootless options to become more compatible.** In the event of a container escape vulnerability, attackers could escalate their privileges and take over the host system. If your Kubernetes and container runtime versions are recent enough, you should use [user namespaces](https://kubernetes.io/docs/concepts/workloads/pods/user-namespaces/) to avoid running the BuildKit daemon in privileged mode. For additional isolation, consider running the BuildKit daemon in a virtual machine outside the cluster.
64+
- By default, builds are run in a shared, rootless BuildKit pod. Because this setup is rootless, the `--oci-worker-no-process-sandbox` flag needs to be set, which results in this warning on startup:
65+
66+
> NoProcessSandbox is enabled. Note that NoProcessSandbox allows build containers to kill (and potentially ptrace) an arbitrary process in the BuildKit host namespace. NoProcessSandbox should be enabled only when the BuildKit is running in a container as an unprivileged user.
67+
68+
The other widely-supported alternative is to run the container in privileged mode as the root user. However, that would give attackers much more access to the system in the event of a container escape vulnerability.
69+
70+
If your environment supports it, the best solution seems to be enabling [user namespaces](https://kubernetes.io/docs/concepts/workloads/pods/user-namespaces/). This allows you to use the rootful mode (removing the NoProcessSandbox flag) while mapping the root user in the container to a nonroot user on the system. However, the feature was behind a flag until Kubernetes version 1.36, and it requires support from the Linux kernel and file system, so AnvilOps does not enable it by default.
71+
72+
For additional isolation, consider running the BuildKit daemon in a virtual machine outside the cluster.
6573

6674
#### Images
6775

charts/anvilops/templates/buildkitd/buildkitd-deployment.yaml

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,21 @@ spec:
1515
metadata:
1616
labels:
1717
{{- include "anvilops.buildkitd.labels" . | nindent 8 }}
18+
{{ if semverCompare "<1.30" .Capabilities.KubeVersion.Version }}
19+
annotations:
20+
container.apparmor.security.beta.kubernetes.io/buildkitd: unconfined
21+
{{ end }}
1822
spec:
1923
{{ if .Values.buildkitd.enableUserNamespaces -}}
2024
hostUsers: false
2125
{{- end }}
2226
containers:
2327
- name: buildkitd
24-
image: moby/buildkit:master
28+
image: moby/buildkit:v0.29.0-rootless
2529
args:
30+
- --oci-worker-no-process-sandbox
2631
- --addr
27-
- unix:///run/buildkit/buildkitd.sock
32+
- unix:///run/user/1000/buildkit/buildkitd.sock
2833
- --addr
2934
- tcp://0.0.0.0:1234
3035
- --tlscacert
@@ -58,8 +63,16 @@ spec:
5863
initialDelaySeconds: 5
5964
periodSeconds: 30
6065
securityContext:
61-
privileged: true
66+
privileged: false
6267
allowPrivilegeEscalation: true
68+
seccompProfile:
69+
type: Unconfined
70+
runAsUser: 1000
71+
runAsGroup: 1000
72+
{{ if semverCompare ">=1.30" .Capabilities.KubeVersion.Version }}
73+
appArmorProfile:
74+
type: Unconfined
75+
{{ end }}
6376
ports:
6477
- containerPort: 1234
6578
volumeMounts:

tilt/Tiltfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ for i, object in enumerate(parsed):
161161
# Make the BuildKit Daemon use insecure HTTP for our registry instead of the default HTTPS
162162
if object["kind"] == "Deployment" and object["metadata"]["name"] == "anvilops-buildkitd":
163163
object["spec"]["template"]["spec"]["volumes"].append({"name": "config", "configMap": {"name": "anvilops-buildkitd-config"}})
164-
object["spec"]["template"]["spec"]["containers"][0]["volumeMounts"].append({"name": "config", "mountPath": "/etc/buildkit"})
164+
object["spec"]["template"]["spec"]["containers"][0]["volumeMounts"].append({"name": "config", "mountPath": "/home/user/.config/buildkit"})
165165
# Make the ingress point to the frontend (which proxies to the backend when necessary) instead of to the backend
166166
if separate_frontend_and_backend and object["kind"] == "Ingress" and object["metadata"]["name"] == "anvilops":
167167
object["spec"]["rules"][0]["http"]["paths"][0]["backend"]["service"]["name"] = "anvilops-frontend"

0 commit comments

Comments
 (0)