From 95c7f998b3e429a0e6de96ba8ebf71ccf5ac0e38 Mon Sep 17 00:00:00 2001 From: Roman Gershman Date: Thu, 15 Aug 2024 09:11:50 +0300 Subject: [PATCH] fix: named volume permissions in docker 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 su-exec to run 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 618b2eb6072a..30514311207a 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 252d9a7ae761..598a0ebf77dc 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 af16f066b7d0..6fd9e024ee01 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 2b94c423cf67..8eb8530f5c97 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"]