Run SMB dev connector as non-root
This commit is contained in:
@@ -9,6 +9,7 @@ binds services to localhost high ports.
|
|||||||
```bash
|
```bash
|
||||||
cd /mnt/DATA/git/govoplan-files/dev/connectors
|
cd /mnt/DATA/git/govoplan-files/dev/connectors
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
|
mkdir -p data/smb data/webdav
|
||||||
docker compose up -d nextcloud nextcloud-db webdav smb
|
docker compose up -d nextcloud nextcloud-db webdav smb
|
||||||
docker compose up -d seafile-db seafile-memcached seafile
|
docker compose up -d seafile-db seafile-memcached seafile
|
||||||
```
|
```
|
||||||
@@ -128,3 +129,10 @@ the script:
|
|||||||
The SMB service is built from `dev/connectors/smb/` so the development share is
|
The SMB service is built from `dev/connectors/smb/` so the development share is
|
||||||
deterministic: one `files` share backed by `data/smb`, with the credentials from
|
deterministic: one `files` share backed by `data/smb`, with the credentials from
|
||||||
`.env`.
|
`.env`.
|
||||||
|
|
||||||
|
The SMB image runs as the non-root `govoplan` user with UID/GID `1000` and
|
||||||
|
listens on unprivileged container port `1445`. The default host endpoint remains
|
||||||
|
`smb://127.0.0.1:1445/files`. `SMB_USER` must stay `govoplan` unless the image is
|
||||||
|
rebuilt with a matching user; `SMB_PORT` must be `1024` or higher. `SMB_PASSWORD`
|
||||||
|
is applied when the image is built, so rebuild the `smb` service after changing
|
||||||
|
it in `.env`.
|
||||||
|
|||||||
@@ -86,16 +86,16 @@ services:
|
|||||||
smb:
|
smb:
|
||||||
build:
|
build:
|
||||||
context: ./smb
|
context: ./smb
|
||||||
|
args:
|
||||||
|
SMB_PASSWORD: ${SMB_PASSWORD:-govoplan-smb}
|
||||||
image: govoplan-files-samba-dev:latest
|
image: govoplan-files-samba-dev:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
SMB_SHARE_NAME: ${SMB_SHARE_NAME:-files}
|
SMB_SHARE_NAME: ${SMB_SHARE_NAME:-files}
|
||||||
SMB_USER: ${SMB_USER:-govoplan}
|
SMB_USER: ${SMB_USER:-govoplan}
|
||||||
SMB_PASSWORD: ${SMB_PASSWORD:-govoplan-smb}
|
SMB_PORT: ${SMB_PORT:-1445}
|
||||||
SMB_UID: ${SMB_UID:-1000}
|
|
||||||
SMB_GID: ${SMB_GID:-1000}
|
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:${SMB_HOST_PORT:-1445}:445"
|
- "127.0.0.1:${SMB_HOST_PORT:-1445}:${SMB_PORT:-1445}"
|
||||||
volumes:
|
volumes:
|
||||||
- ./data/smb:/storage
|
- ./data/smb:/storage
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,29 @@
|
|||||||
FROM alpine:3.20
|
FROM alpine:3.20
|
||||||
|
|
||||||
RUN apk add --no-cache samba-server samba-common-tools
|
ARG SMB_PASSWORD=govoplan-smb
|
||||||
|
|
||||||
|
RUN apk add --no-cache samba-server samba-common-tools \
|
||||||
|
&& addgroup -S -g 1000 govoplan \
|
||||||
|
&& adduser -S -D -H -h /nonexistent -s /sbin/nologin -u 1000 -G govoplan govoplan \
|
||||||
|
&& mkdir -p /storage /var/lib/samba/private /var/cache/samba /run/samba /etc/samba /var/log/samba/cores \
|
||||||
|
&& printf '%s\n' \
|
||||||
|
'[global]' \
|
||||||
|
' passdb backend = tdbsam' \
|
||||||
|
' private dir = /var/lib/samba/private' \
|
||||||
|
' lock directory = /run/samba' \
|
||||||
|
' state directory = /var/lib/samba' \
|
||||||
|
' cache directory = /var/cache/samba' \
|
||||||
|
' pid directory = /run/samba' \
|
||||||
|
> /etc/samba/smb.conf \
|
||||||
|
&& printf '%s\n%s\n' "$SMB_PASSWORD" "$SMB_PASSWORD" | smbpasswd -s -a govoplan \
|
||||||
|
&& smbpasswd -e govoplan \
|
||||||
|
&& chown -R govoplan:govoplan /storage /var/lib/samba /var/cache/samba /run/samba /etc/samba /var/log/samba
|
||||||
|
|
||||||
COPY entrypoint.sh /usr/local/bin/govoplan-samba-entrypoint
|
COPY entrypoint.sh /usr/local/bin/govoplan-samba-entrypoint
|
||||||
RUN chmod +x /usr/local/bin/govoplan-samba-entrypoint
|
RUN chmod +x /usr/local/bin/govoplan-samba-entrypoint
|
||||||
|
|
||||||
EXPOSE 445
|
EXPOSE 1445
|
||||||
|
|
||||||
|
USER govoplan:govoplan
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/bin/govoplan-samba-entrypoint"]
|
ENTRYPOINT ["/usr/local/bin/govoplan-samba-entrypoint"]
|
||||||
|
|||||||
@@ -3,21 +3,42 @@ set -eu
|
|||||||
|
|
||||||
share_name="${SMB_SHARE_NAME:-files}"
|
share_name="${SMB_SHARE_NAME:-files}"
|
||||||
user_name="${SMB_USER:-govoplan}"
|
user_name="${SMB_USER:-govoplan}"
|
||||||
password="${SMB_PASSWORD:-govoplan-smb}"
|
smb_port="${SMB_PORT:-1445}"
|
||||||
uid="${SMB_UID:-1000}"
|
runtime_user="$(id -un)"
|
||||||
gid="${SMB_GID:-1000}"
|
runtime_group="$(id -gn)"
|
||||||
|
|
||||||
mkdir -p /storage /var/lib/samba/private /run/samba
|
case "$share_name" in
|
||||||
|
"" | *[!A-Za-z0-9_.-]*)
|
||||||
|
printf 'SMB_SHARE_NAME must contain only letters, numbers, dot, dash, or underscore.\n' >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
if ! getent group "$user_name" >/dev/null 2>&1; then
|
case "$user_name" in
|
||||||
addgroup -g "$gid" "$user_name"
|
"" | *[!A-Za-z0-9_.-]*)
|
||||||
|
printf 'SMB_USER must contain only letters, numbers, dot, dash, or underscore.\n' >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$smb_port" in
|
||||||
|
"" | *[!0-9]*)
|
||||||
|
printf 'SMB_PORT must be numeric.\n' >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "$smb_port" -lt 1024 ]; then
|
||||||
|
printf 'SMB_PORT must be >= 1024 because the dev Samba container runs as a non-root user.\n' >&2
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! id "$user_name" >/dev/null 2>&1; then
|
if [ "$user_name" != "$runtime_user" ]; then
|
||||||
adduser -D -H -s /sbin/nologin -u "$uid" -G "$user_name" "$user_name"
|
printf 'SMB_USER=%s is not supported by the non-root dev image; use %s or rebuild the image with a matching user.\n' "$user_name" "$runtime_user" >&2
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
chown -R "$user_name:$user_name" /storage
|
mkdir -p /storage /var/lib/samba/private /var/cache/samba /run/samba /etc/samba
|
||||||
|
|
||||||
cat > /etc/samba/smb.conf <<EOF
|
cat > /etc/samba/smb.conf <<EOF
|
||||||
[global]
|
[global]
|
||||||
@@ -25,12 +46,20 @@ cat > /etc/samba/smb.conf <<EOF
|
|||||||
workgroup = WORKGROUP
|
workgroup = WORKGROUP
|
||||||
security = user
|
security = user
|
||||||
map to guest = Never
|
map to guest = Never
|
||||||
|
guest account = $runtime_user
|
||||||
server min protocol = SMB2
|
server min protocol = SMB2
|
||||||
|
server signing = mandatory
|
||||||
|
smb ports = $smb_port
|
||||||
load printers = no
|
load printers = no
|
||||||
printing = bsd
|
printing = bsd
|
||||||
disable spoolss = yes
|
disable spoolss = yes
|
||||||
log level = 1
|
log level = 1
|
||||||
passdb backend = tdbsam
|
passdb backend = tdbsam
|
||||||
|
private dir = /var/lib/samba/private
|
||||||
|
lock directory = /run/samba
|
||||||
|
state directory = /var/lib/samba
|
||||||
|
cache directory = /var/cache/samba
|
||||||
|
pid directory = /run/samba
|
||||||
|
|
||||||
[$share_name]
|
[$share_name]
|
||||||
path = /storage
|
path = /storage
|
||||||
@@ -38,13 +67,16 @@ cat > /etc/samba/smb.conf <<EOF
|
|||||||
read only = no
|
read only = no
|
||||||
guest ok = no
|
guest ok = no
|
||||||
valid users = $user_name
|
valid users = $user_name
|
||||||
force user = $user_name
|
force user = $runtime_user
|
||||||
force group = $user_name
|
force group = $runtime_group
|
||||||
create mask = 0664
|
create mask = 0664
|
||||||
directory mask = 0775
|
directory mask = 0775
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
printf '%s\n%s\n' "$password" "$password" | smbpasswd -s -a "$user_name" >/dev/null
|
if ! pdbedit -L -u "$user_name" >/dev/null 2>&1; then
|
||||||
smbpasswd -e "$user_name" >/dev/null
|
printf 'Samba user %s is missing from passdb. Rebuild the smb image so the non-root passdb is seeded.\n' "$user_name" >&2
|
||||||
|
printf 'Run: docker compose build --no-cache smb && docker compose up -d smb\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
exec smbd --foreground --no-process-group --debug-stdout
|
exec smbd --foreground --no-process-group --debug-stdout -p "$smb_port"
|
||||||
|
|||||||
Reference in New Issue
Block a user