Add conditional root check to datanode entrypoint#306
Conversation
bernd
left a comment
There was a problem hiding this comment.
What's the reason to keep the possibility to run the container as root when the entrypoint switches to the unprivileged user anyways? Our server containers also use USER in Dockerfile to run as unprivileged user.
Also: please open PRs against the latest branch (7.2) and then backport once merged.
This allows the container to start as non-root (e.g., with fsGroup) while maintaining backward compatibility with root execution. When running as root: - Uses install -d with proper ownership and 0700 permissions - Performs chown on the data directory - Uses setpriv to drop privileges to the configured user When running as non-root: - Creates directories with mkdir (owned by current user) - Sets 0700 permissions via chmod (user can chmod directories it owns) - Executes datanode directly with no privilege operations - Assumes fsGroup handles volume ownership in Kubernetes This enables deployment in restricted environments (Pod Security Standards, policies, etc.) that don't allow root containers, while maintaining security posture and backward compatibility. Aligns with graylog-helm PR #100 security hardening approach.
ba593e9 to
dcc3463
Compare
|
thanks for the quick reply @bernd !
Well, the container is already running as docker exec -it datanode -- idwhich returns for any All non-optional operations that require root, all in the current entrypoint. Any attempts to run a graylog-datanode container as non-root today makes it crash immediately. Unless I'm missing something, there's no What I'm introducing with this PR is actually a way to run the container itself as non-root, in environments that let you set the user/group/permissions/capabilites beforehand, like on Kubernetes. if [ "$(id -u)" = "0" ]; then
# run exactly in the same way as it is running today. I.e. root is required for chown and setpriv
else
# NEW branch: run as a non root user; no setpriv required
# and chmod works because the same user running datanode owns the opensearch dirs
fi
done! Apologies, since 7.1 is still the default branch in this repo I thought of it as the main/master branch. I have rebased on 7.2 |
But if we chown the directories in the Dockerfile (like we do in server), we don't need to run it in the entrypoint. And existing instances already have the correct permissions, no? |
|
I believe we need to consider a couple things before using the the server pattern of
graylog-docker/docker-entrypoint.sh Lines 83 to 85 in 06af88a If the mounted volume doesn't have write permissions it skips the graylog-docker/docker/enterprise/Dockerfile Line 107 in 06af88a graylog-docker/docker/enterprise/Dockerfile Lines 170 to 173 in 06af88a In Kubernetes, write permissions are added to the dir using For datanode the story is different as it does an unconditional, hard-failing graylog-docker/docker/datanode/entrypoint.sh Lines 81 to 85 in 06af88a which is why running it non-root today crashes immediately with: So, we need a conditional
If the datanode volume was previously initialized by today's (root) entrypoint, then yes. The contents have already been Correct me if I'm wrong, but it seems to me we're actually agreeing on the goal (running datanode as non-root). The implementation choice is just how the entrypoint stops requiring root. Happy to switch this PR from the |
Summary
Add support for running the datanode container as non-root while maintaining backward compatibility with root execution.
This change allows the datanode to work in restricted environments that don't allow root containers, e.g. security-hardened Kubernetes clusters (Pod Security Standards, policies, OpenShift, etc.)
Changes
Add branching based on the user running the entrypoint:
install -dwith proper ownership, performschown, and drops privileges viasetpriv(traditional behavior)mkdir, setschmod 0700(user can chmod its own directories), and executes datanode directlyWhy is this necessary?
In order to make the official Graylog Helm chart ready for security-hardened production environments, DataNode must be able to run as non root. This is possible in Kubernetes as setting up the right
securityContextmakes thechownandsetprivoperations here unnecessary. A flag must be passed explicitly when running in this mode (as an env var:GDN_RUN_AS_NONROOT=true), so it doesn't occur by accident.Impact
fsGroupfor volume ownershipRelated
Graylog2/graylog-helm#100
Testing
Notes for Reviewers