coreruleset / modsecurity-crs-docker

Official ModSecurity Docker + Core Rule Set (CRS) images
https://coreruleset.org
Apache License 2.0
269 stars 69 forks source link

Not running with readOnlyRootFilesystem set to true #172

Open enibache opened 10 months ago

enibache commented 10 months ago

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?

enibache commented 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

fzipi commented 10 months ago

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
fzipi commented 10 months ago

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
theseion commented 8 months ago

191 solves the root user issue.

ne20002 commented 7 months ago

Having the modsecurity-crs container being able to run in read-only mode would be a great improvement.

fzipi commented 7 months ago

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.

theseion commented 7 months ago

@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).

fzipi commented 7 months ago

You are right. Why I thought this was fixed? 🤔 Nevermind. Thanks for bringing this one back.

fzipi commented 7 months ago

Maybe we can add a similar chart with examples for k8s?

theseion commented 7 months ago

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?

ne20002 commented 7 months ago

I tried to run the container with --read-only parameter (aka readOnlyRootFileSystem) and found:

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.

theseion commented 7 months ago

Thanks @ne20002. I've opened a PR: https://github.com/coreruleset/modsecurity-crs-docker/pull/210