Open enibache opened 10 months ago
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-generate-certificate.sh /usr/local/bin/generate-certificate: using existing key / certificate /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 10-listen-on-ipv6-by-default.sh: info: can not modify /etc/nginx/conf.d/default.conf (read-only file system?) /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh 20-envsubst-on-templates.sh: Running envsubst on /etc/nginx/templates/conf.d/default.conf.template to /etc/nginx/conf.d/default.conf /docker-entrypoint.d/20-envsubst-on-templates.sh: line 33: can't create /etc/nginx/conf.d/default.conf: Read-only file system
There are two problems:
The second one can be solved by using a persistent volume like:
apiVersion: apps/v1
kind: Deployment
metadata:
name: modsecurity-deployment
spec:
replicas: 1
selector:
matchLabels:
app: modsecurity
template:
metadata:
labels:
app: modsecurity
spec:
containers:
- name: modsecurity-container
image: owasp/modsecurity-crs:v3-nginx-<date>
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: modsecurity-logs
mountPath: /var/log/nginx
volumes:
- name: modsecurity-logs
persistentVolumeClaim:
claimName: modsecurity-logs-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: modsecurity-logs-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi # Adjust the storage size as needed
The nginx ingress controller solves the first part by ... copying everything to a mounted directory:
# volumes:
# - name: nginx-etc
# emptyDir: {}
# - name: nginx-cache
# emptyDir: {}
# - name: nginx-lib
# emptyDir: {}
# - name: nginx-log
# emptyDir: {}
.
.
.
# readOnlyRootFilesystem: true
.
.
.
# volumeMounts:
# - mountPath: /etc/nginx
# name: nginx-etc
# - mountPath: /var/cache/nginx
# name: nginx-cache
# - mountPath: /var/lib/nginx
# name: nginx-lib
# - mountPath: /var/log/nginx
# name: nginx-log
.
.
.
# initContainers:
# - image: <repository>:<tag>
# imagePullPolicy: IfNotPresent
# name: init-nginx-ingress
# command: ['cp', '-vdR', '/etc/nginx/.', '/mnt/etc']
# securityContext:
# allowPrivilegeEscalation: false
# readOnlyRootFilesystem: true
# runAsUser: 101 #nginx
# runAsNonRoot: true
# capabilities:
# drop:
# - ALL
# volumeMounts:
# - mountPath: /mnt/etc
# name: nginx-etc
Having the modsecurity-crs container being able to run in read-only mode would be a great improvement.
Latest pushed images should include the fix (E.g. ghcr.io/coreruleset/modsecurity-crs:3.3.5-nginx-202402070602), so please check and come back if something is not working.
@fzipi No, I don't think so. @ne20002 is talking about read-only filesystems, while the change is simply to use a non-root user (which has some similar implications, of course).
You are right. Why I thought this was fixed? 🤔 Nevermind. Thanks for bringing this one back.
Maybe we can add a similar chart with examples for k8s?
What kind of chart are you thinking about? A Helm chart? Or are you talking about the examples for the ingress controller you gave above?
I tried to run the container with --read-only parameter (aka readOnlyRootFileSystem) and found:
conf.d
, includes
and modsecurity.d
in /etc/nginx/
and to the nginx.conf
file itself.
Mounting the three folders as tmpfs fixed the errors but I found no way to fix the problems with nginx.conf
.In my setup I use my own nginx.conf which is passed as nginx.conf.template to the container.
A simple option to let a user run the container with read-only file system would be to provide a parameter that disables the creation of the config files leaving the user responsible for mounting the configuration manually (which is not really a hard thing to do). At least, it would solve it for my use case.
A more general solution would be to move everything from /etc/nginx
into another folder, mount /etc/nginx
as tmpfs in the container/image by default and copy the whole configuration during startup as it is now (but just from a folder outside of /etc/nginx
).
I believe, this should do the trick. Running containers read-only is a big security improvement.
Thanks @ne20002. I've opened a PR: https://github.com/coreruleset/modsecurity-crs-docker/pull/210
I'm trying to run this image in my helm chart running in OCP4 whereby we have a quality gate that only allows pods with readOnlyRootFilesystem set to true. Is there perhaps hints on how to accomplish this using this image in my deployment.yaml?