Skip to main content

TRG 4.07 - Read-only filesystems

caution

Proposed release date: 1st of Nov 2023

StatusCreatedPost-History
Draft03-Oct-2023Initial contribution
Draft11-Nov-2023Added fixes to overwrite tmp

Why

The read-only root filesystem right can limit the impact of container compromise when set properly. This can prevent malicious processes or applications from writing back to the host file system. Such a setting can be an extra protection layer to prevent an attack.

Description

The read-only filesystem configuration is defined in the deployment yaml. The security context parameters are assigned to the pod. This ensures that unprivileged access cannot be abused to install malicious software of write to the file system. This control is by default false. Therefore it is to be considered for each deployment if the flag can be set to the recommended value "true". Only read in this case.

Implementation

The container's Pod resource file (yaml) has to be modified to set rights to read-only.

Mounts the container's root filesystem as read-only:

apiVersion: v1
kind: Pod
metadata:
name: read-only
spec:
containers:
...
# The [container security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) defines privilege and access control settings for a Container within a pod
securityContext:
capabilities:
# -- Specifies which capabilities to drop to reduce syscall attack surface
drop:
- ALL
# -- Specifies which capabilities to add to issue specialized syscalls
add: []
# -- Whether the root filesystem is mounted in read-only mode
readOnlyRootFilesystem: true
# -- Controls [Privilege Escalation](https://kubernetes.io/docs/concepts/security/pod-security-policy/#privilege-escalation) enabling setuid binaries changing the effective user ID
allowPrivilegeEscalation: false
# -- Requires the container to run without root privileges
runAsNonRoot: true
# -- The container's process will run with the specified uid
runAsUser: 10001

In some cases you might encounter the issue that tmp cannot be overwritten:

[emerg] 1#1: mkdir() "/tmp/proxy_temp" failed (30: Read-only file system)
nginx: [emerg] mkdir() "/tmp/proxy_temp" failed (30: Read-only file system)

To fix this you need to make tmp writeable and mount /tmp to emptyDir.

      spec:
securityContext:
runAsUser: 999
containers:
- image: nginxinc/nginx-unprivileged:latest
imagePullPolicy: Always
name: nginx
ports:
- containerPort: 8080 //ONLY open ports that are necessary to run
protocol: TCP
securityContext:
capabilities:
drop:
- NET_RAW //ONLY required if your containers have NET_RAW capability
runAsNonRoot: true
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
resources: //Set proper limits for your container
.
.
.
volumeMounts:
- mountPath: /tmp
name: tmp
volumes:
- emptyDir: {}
name: tmp

Checkout these great Tractus-X template examples.

K8s Deployment:

EDC Security Context 1

EDC Security Context 2

Values.yaml:

EDC Security Context 3

EDC Security Context 4

Temporary Folders (If needed)

A temporary filesystem (tmpfs) works similar like a regular volume. Everything written to this filesystem will be removed when the container gets terminated. In the case that an executable in your container should need a temporary folder for logging or spooling purposes, you can mount a writable emptydir volume as follows:

apiVersion: v1
kind: Pod
metadata:
name: temporary-folder
spec:
containers:
- name: sample-container-which-needs-temporary-folder
image: your-image
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: tempfolder
mountPath: /tmp
readOnly: false
volumes:
- name: tempfolder
emptyDir: {}