From cec3659b5103eb9e9d3ae0198e2c1a66e63b5bb8 Mon Sep 17 00:00:00 2001 From: Roman Gershman Date: Thu, 22 Aug 2024 11:33:29 +0300 Subject: [PATCH] fix: named volume permissions in docker (#3518) Fixes #2917 The problem is described in this "working as intended" issue https://github.com/moby/moby/issues/3124 So the advised approach of using "USER dfly" directive does not really work because it requires that the host will also define 'dfly' user with the same id. It's unrealistic expectation. Therefore, we revert the fix done in #1775 and follow valkey approach: https://github.com/valkey-io/valkey-container/blob/mainline/docker-entrypoint.sh#L12 1. we run the entrypoint in the container as root which later spawns the dragonfly process 2. if we run as root: a. we chmod files under /data to dfly. b. use setpriv to exec ourselves as dfly. 3. if we do not run as root we execute the docker command. So even though the process starts as root, the server runs as dfly and only the bootstrap part has elevated permissions is used to fix the volume access. While we are at it, we also switched to setpriv following the change of https://github.com/valkey-io/valkey-container/pull/24/files Signed-off-by: Roman Gershman --- tools/docker/entrypoint.sh | 13 +++++++++++-- tools/packaging/Dockerfile.alpine-dev | 4 +--- tools/packaging/Dockerfile.ubuntu-dev | 8 +------- tools/packaging/Dockerfile.ubuntu-prod | 8 -------- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/tools/docker/entrypoint.sh b/tools/docker/entrypoint.sh index 618b2eb60..305143112 100755 --- a/tools/docker/entrypoint.sh +++ b/tools/docker/entrypoint.sh @@ -11,12 +11,21 @@ set -e # first arg is `-some-option` if [ "${1#-}" != "$1" ]; then # override arguments by prepending "dragonfly --logtostderr" to them. - set -- dragonfly --logtostderr "$@" + set -- dragonfly --logtostderr "$@" fi # allow the docker container to be started with `--user` if [ "$1" = 'dragonfly' -a "$(id -u)" = '0' ]; then - exec su-exec dfly "$0" "$@" # runs this script under user dfly + # find all the files in the WORKDIR including the dir itself that do not + # have dfly user on them and chmod them to dfly. + find . \! -user dfly -exec chown dfly '{}' + + # runs this script under user dfly + exec setpriv --reuid=dfly --regid=dfly --clear-groups -- "$0" "$@" +fi + +um="$(umask)" +if [ "$um" = '0022' ]; then + umask 0077 # restrict access permissions only to the owner fi exec "$@" diff --git a/tools/packaging/Dockerfile.alpine-dev b/tools/packaging/Dockerfile.alpine-dev index 252d9a7ae..598a0ebf7 100644 --- a/tools/packaging/Dockerfile.alpine-dev +++ b/tools/packaging/Dockerfile.alpine-dev @@ -30,7 +30,7 @@ COPY tools/docker/healthcheck.sh /usr/local/bin/healthcheck.sh COPY --from=builder /build/build-release/dragonfly /usr/local/bin/ RUN apk --no-cache add libgcc libstdc++ \ - su-exec netcat-openbsd boost-context && ldd /usr/local/bin/dragonfly + setpriv netcat-openbsd boost-context && ldd /usr/local/bin/dragonfly RUN addgroup -S -g 1000 dfly && adduser -S -G dfly -u 999 dfly RUN mkdir /data && chown dfly:dfly /data @@ -43,6 +43,4 @@ ENTRYPOINT ["entrypoint.sh"] EXPOSE 6379 -USER dfly - CMD ["dragonfly", "--logtostderr"] diff --git a/tools/packaging/Dockerfile.ubuntu-dev b/tools/packaging/Dockerfile.ubuntu-dev index af16f066b..6fd9e024e 100644 --- a/tools/packaging/Dockerfile.ubuntu-dev +++ b/tools/packaging/Dockerfile.ubuntu-dev @@ -12,10 +12,7 @@ RUN make release RUN build-release/dragonfly --version -RUN curl -O https://raw.githubusercontent.com/ncopa/su-exec/212b75144bbc06722fbd7661f651390dc47a43d1/su-exec.c && \ - gcc -Wall -O2 su-exec.c -o su-exec - -FROM debian:12-slim +FROM ubuntu:22.04 RUN --mount=type=tmpfs,target=/var/cache/apt \ --mount=type=tmpfs,target=/var/lib/apt/lists \ @@ -30,7 +27,6 @@ WORKDIR /data COPY tools/docker/entrypoint.sh /usr/local/bin/entrypoint.sh COPY tools/docker/healthcheck.sh /usr/local/bin/healthcheck.sh -COPY --from=builder /build/su-exec /usr/local/bin/ COPY --from=builder /build/build-release/dragonfly /usr/local/bin/ HEALTHCHECK CMD /usr/local/bin/healthcheck.sh @@ -39,6 +35,4 @@ ENTRYPOINT ["entrypoint.sh"] # For inter-container communication. EXPOSE 6379 -USER dfly - CMD ["dragonfly", "--logtostderr"] diff --git a/tools/packaging/Dockerfile.ubuntu-prod b/tools/packaging/Dockerfile.ubuntu-prod index 2b94c423c..8eb8530f5 100644 --- a/tools/packaging/Dockerfile.ubuntu-prod +++ b/tools/packaging/Dockerfile.ubuntu-prod @@ -7,11 +7,6 @@ WORKDIR /build COPY tools/docker/fetch_release.sh /tmp/ COPY releases/dragonfly-* /tmp/ -ARG SUEXEC_HASH=d6c40440609a23483f12eb6295b5191e94baf08298a856bab6e15b10c3b82891 -RUN curl -O https://raw.githubusercontent.com/ncopa/su-exec/212b75144bbc06722fbd7661f651390dc47a43d1/su-exec.c && \ - if [ "$SUEXEC_HASH" != $(sha256sum su-exec.c | awk '{print $1}') ]; then echo "Wrong hash!" && exit 1; fi && \ - gcc -Wall -O2 su-exec.c -o su-exec - RUN /tmp/fetch_release.sh ${TARGETPLATFORM} # Now prod image @@ -35,7 +30,6 @@ WORKDIR /data COPY tools/docker/entrypoint.sh /usr/local/bin/entrypoint.sh COPY tools/docker/healthcheck.sh /usr/local/bin/healthcheck.sh -COPY --from=builder /build/su-exec /usr/local/bin/ COPY --from=builder /build/dragonfly /usr/local/bin/ HEALTHCHECK CMD /usr/local/bin/healthcheck.sh @@ -44,6 +38,4 @@ ENTRYPOINT ["entrypoint.sh"] # For inter-container communication. EXPOSE 6379 -USER dfly - CMD ["dragonfly", "--logtostderr"]