From c93a8eb5464b6ac90ceb0641ca1e375d2ec75017 Mon Sep 17 00:00:00 2001 From: UNITRONIX <36471318+UNITRONIX@users.noreply.github.com> Date: Sun, 5 Apr 2026 21:13:41 +0200 Subject: [PATCH] Fix permission denied on id_ed25519 in Docker volumes (#78) Root cause: Dockerfile.server ran as USER betterdesk (UID 10001) but Docker volume files retain UID/GID from host or previous container. Private key id_ed25519 (mode 600) owned by different UID = unreadable. Fix: - Add docker/server-entrypoint.sh: starts as root, chown+chmod volume files to betterdesk user, then drops privileges via su-exec - Add su-exec to Dockerfile.server runtime packages - Remove USER betterdesk directive (entrypoint handles privilege drop) - Add explicit chmod 600 + chown for id_ed25519 in all-in-one entrypoint --- Dockerfile.server | 12 +++++++++--- docker/entrypoint.sh | 5 +++++ docker/server-entrypoint.sh | 24 ++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 docker/server-entrypoint.sh diff --git a/Dockerfile.server b/Dockerfile.server index 84663f9e..c54538bf 100644 --- a/Dockerfile.server +++ b/Dockerfile.server @@ -39,8 +39,9 @@ RUN apk add --no-cache \ curl \ sqlite \ tini \ + su-exec \ || { sleep 2 && apk add --no-cache \ - ca-certificates curl sqlite tini; } \ + ca-certificates curl sqlite tini su-exec; } \ && addgroup -g 10001 -S betterdesk \ && adduser -u 10001 -S -G betterdesk betterdesk @@ -50,6 +51,10 @@ RUN chmod +x /usr/local/bin/betterdesk-server # Create data directory RUN mkdir -p /opt/rustdesk && chown betterdesk:betterdesk /opt/rustdesk +# Entrypoint script: fixes volume permissions, then drops to betterdesk user +COPY docker/server-entrypoint.sh /server-entrypoint.sh +RUN chmod +x /server-entrypoint.sh + WORKDIR /opt/rustdesk # Ports: @@ -65,7 +70,8 @@ EXPOSE 21114 21115 21116/tcp 21116/udp 21117 21118 21119 HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \ CMD curl -sf http://localhost:21114/api/health || exit 1 -USER betterdesk +# Note: Container starts as root so entrypoint can fix volume permissions. +# server-entrypoint.sh drops to betterdesk user via su-exec before running the server. -ENTRYPOINT ["/sbin/tini", "--"] +ENTRYPOINT ["/sbin/tini", "--", "/server-entrypoint.sh"] CMD ["/usr/local/bin/betterdesk-server", "-mode", "all", "-key-file", "/opt/rustdesk/id_ed25519"] diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 1caffbd7..e8452e9b 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -23,6 +23,11 @@ echo "" # Ensure data directories exist and have correct permissions mkdir -p /opt/rustdesk /app/data /var/log/betterdesk 2>/dev/null || true chown -R betterdesk:betterdesk /opt/rustdesk /app/data /var/log/betterdesk 2>/dev/null || true +# Fix private key permissions (volume mounts may preserve wrong UID/mode) +if [ -f /opt/rustdesk/id_ed25519 ]; then + chmod 600 /opt/rustdesk/id_ed25519 + chown betterdesk:betterdesk /opt/rustdesk/id_ed25519 +fi # BD-2026-007: Warn about weak default secrets if [ -n "${SESSION_SECRET}" ] && [ ${#SESSION_SECRET} -lt 32 ]; then diff --git a/docker/server-entrypoint.sh b/docker/server-entrypoint.sh new file mode 100644 index 00000000..a1806f9c --- /dev/null +++ b/docker/server-entrypoint.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# BetterDesk Server — Docker Entrypoint +# Fixes volume file permissions before dropping to non-root user +set -e + +DATA_DIR="/opt/rustdesk" + +# Fix ownership of volume-mounted data directory. +# Docker volumes preserve UID/GID from the host or previous container, +# which may not match the betterdesk user (10001) in this container. +# This is especially important for id_ed25519 (mode 600) — if owned by +# a different UID, the server cannot read the private key. +if [ "$(id -u)" = "0" ]; then + chown -R betterdesk:betterdesk "$DATA_DIR" 2>/dev/null || true + # Ensure private key is readable by betterdesk + if [ -f "$DATA_DIR/id_ed25519" ]; then + chmod 600 "$DATA_DIR/id_ed25519" + chown betterdesk:betterdesk "$DATA_DIR/id_ed25519" + fi + # Drop privileges and re-exec + exec su-exec betterdesk "$@" +else + exec "$@" +fi