Improve security and modernize Docker configuration
- Replace deprecated MAINTAINER with LABEL and add OCI metadata - Pin Alpine version via ARG for reproducible builds - Fix command injection vulnerability by replacing eval with safe parser - Modernize docker-compose: remove version, add resource limits - Move passwords to environment variables instead of hardcoded values - Improve healthcheck with start-period and retries - Add .env.example template and update .gitignore 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
8
.env.example
Normal file
8
.env.example
Normal file
@@ -0,0 +1,8 @@
|
||||
# Samba configuration
|
||||
# Copy this file to .env and set your values
|
||||
|
||||
# User passwords
|
||||
SAMBA_BOB_PASSWORD=changeme
|
||||
|
||||
# Timezone
|
||||
TZ=EST5EDT
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1 +1,3 @@
|
||||
.idea/
|
||||
.idea/
|
||||
.env
|
||||
.DS_Store
|
||||
12
Dockerfile
12
Dockerfile
@@ -1,5 +1,9 @@
|
||||
FROM hub.docker.struchkov.dev/alpine:latest
|
||||
MAINTAINER Struchkov Mark <mark@struchkov.dev>
|
||||
ARG ALPINE_VERSION=3.21
|
||||
FROM hub.docker.struchkov.dev/alpine:${ALPINE_VERSION}
|
||||
|
||||
LABEL maintainer="Struchkov Mark <mark@struchkov.dev>"
|
||||
LABEL org.opencontainers.image.source="https://github.com/upagge/samba"
|
||||
LABEL org.opencontainers.image.description="Samba file server with Time Machine support"
|
||||
|
||||
# Install samba
|
||||
RUN apk --no-cache --no-progress upgrade && \
|
||||
@@ -59,8 +63,8 @@ COPY samba.sh /usr/bin/
|
||||
|
||||
EXPOSE 137/udp 138/udp 139 445
|
||||
|
||||
HEALTHCHECK --interval=60s --timeout=15s \
|
||||
CMD smbclient -L \\localhost -U % -m SMB3
|
||||
HEALTHCHECK --interval=60s --timeout=15s --start-period=10s --retries=3 \
|
||||
CMD smbclient -L \\localhost -U % -m SMB3 || exit 1
|
||||
|
||||
VOLUME ["/etc", "/var/cache/samba", "/var/lib/samba", "/var/log/samba",\
|
||||
"/run/samba"]
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
version: '3.4'
|
||||
|
||||
services:
|
||||
samba:
|
||||
image: docker.struchkov.dev/samba
|
||||
environment:
|
||||
TZ: 'EST5EDT'
|
||||
# Use environment variables for shares and users instead of command line
|
||||
# SHARE: "Mount;/mnt"
|
||||
# SHARE2: "Bobs Volume;/mnt2;yes;no;no;bob"
|
||||
# USER: "bob;${SAMBA_BOB_PASSWORD}"
|
||||
# PERMISSIONS: "true"
|
||||
env_file:
|
||||
- .env # Put sensitive data like passwords here
|
||||
networks:
|
||||
- default
|
||||
ports:
|
||||
@@ -21,7 +26,13 @@ services:
|
||||
volumes:
|
||||
- /mnt:/mnt:z
|
||||
- /mnt2:/mnt2:z
|
||||
command: '-s "Mount;/mnt" -s "Bobs Volume;/mnt2;yes;no;no;bob" -u "bob;bobspasswd" -p'
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
reservations:
|
||||
memory: 128M
|
||||
command: '-s "Mount;/mnt" -s "Bobs Volume;/mnt2;yes;no;no;bob" -u "bob;${SAMBA_BOB_PASSWORD:-changeme}" -p'
|
||||
|
||||
networks:
|
||||
default:
|
||||
default:
|
||||
|
||||
34
samba.sh
34
samba.sh
@@ -18,6 +18,28 @@
|
||||
|
||||
set -o nounset # Treat unset variables as an error
|
||||
|
||||
### parse_args: safely parse semicolon-separated arguments
|
||||
# Arguments:
|
||||
# input) semicolon-separated string
|
||||
# Return: array PARSED_ARGS with parsed values
|
||||
parse_args() {
|
||||
local input="$1"
|
||||
PARSED_ARGS=()
|
||||
local current=""
|
||||
local i=0
|
||||
while [ $i -lt ${#input} ]; do
|
||||
local char="${input:$i:1}"
|
||||
if [ "$char" = ";" ]; then
|
||||
PARSED_ARGS+=("$current")
|
||||
current=""
|
||||
else
|
||||
current+="$char"
|
||||
fi
|
||||
i=$((i + 1))
|
||||
done
|
||||
PARSED_ARGS+=("$current")
|
||||
}
|
||||
|
||||
### charmap: setup character mapping for file/directory names
|
||||
# Arguments:
|
||||
# chars) from:to character mappings separated by ','
|
||||
@@ -245,15 +267,15 @@ while getopts ":hc:G:g:i:nprs:Su:Ww:I:" opt; do
|
||||
case "$opt" in
|
||||
h) usage ;;
|
||||
c) charmap "$OPTARG" ;;
|
||||
G) eval generic $(sed 's/^/"/; s/$/"/; s/;/" "/g' <<< $OPTARG) ;;
|
||||
G) parse_args "$OPTARG"; generic "${PARSED_ARGS[@]}" ;;
|
||||
g) global "$OPTARG" ;;
|
||||
i) import "$OPTARG" ;;
|
||||
n) NMBD="true" ;;
|
||||
p) PERMISSIONS="true" ;;
|
||||
r) recycle ;;
|
||||
s) eval share $(sed 's/^/"/; s/$/"/; s/;/" "/g' <<< $OPTARG) ;;
|
||||
s) parse_args "$OPTARG"; share "${PARSED_ARGS[@]}" ;;
|
||||
S) smb ;;
|
||||
u) eval user $(sed 's/^/"/; s/$/"/; s/;/" "/g' <<< $OPTARG) ;;
|
||||
u) parse_args "$OPTARG"; user "${PARSED_ARGS[@]}" ;;
|
||||
w) workgroup "$OPTARG" ;;
|
||||
W) widelinks ;;
|
||||
I) include "$OPTARG" ;;
|
||||
@@ -265,7 +287,7 @@ shift $(( OPTIND - 1 ))
|
||||
|
||||
[[ "${CHARMAP:-""}" ]] && charmap "$CHARMAP"
|
||||
while read i; do
|
||||
eval generic $(sed 's/^/"/; s/$/"/; s/;/" "/g' <<< $i)
|
||||
parse_args "$i"; generic "${PARSED_ARGS[@]}"
|
||||
done < <(env | awk '/^GENERIC[0-9=_]/ {sub (/^[^=]*=/, "", $0); print}')
|
||||
while read i; do
|
||||
global "$i"
|
||||
@@ -273,11 +295,11 @@ done < <(env | awk '/^GLOBAL[0-9=_]/ {sub (/^[^=]*=/, "", $0); print}')
|
||||
[[ "${IMPORT:-""}" ]] && import "$IMPORT"
|
||||
[[ "${RECYCLE:-""}" ]] && recycle
|
||||
while read i; do
|
||||
eval share $(sed 's/^/"/; s/$/"/; s/;/" "/g' <<< $i)
|
||||
parse_args "$i"; share "${PARSED_ARGS[@]}"
|
||||
done < <(env | awk '/^SHARE[0-9=_]/ {sub (/^[^=]*=/, "", $0); print}')
|
||||
[[ "${SMB:-""}" ]] && smb
|
||||
while read i; do
|
||||
eval user $(sed 's/^/"/; s/$/"/; s/;/" "/g' <<< $i)
|
||||
parse_args "$i"; user "${PARSED_ARGS[@]}"
|
||||
done < <(env | awk '/^USER[0-9=_]/ {sub (/^[^=]*=/, "", $0); print}')
|
||||
[[ "${WORKGROUP:-""}" ]] && workgroup "$WORKGROUP"
|
||||
[[ "${WIDELINKS:-""}" ]] && widelinks
|
||||
|
||||
Reference in New Issue
Block a user