- Fix YAML tags in auth config struct (json -> yaml) - Update CLI configs to use pre-hashed API keys - Remove double hashing in WebSocket client - Fix port mapping (9102 -> 9103) in CLI commands - Update permission keys to use jobs:read, jobs:create, etc. - Clean up all debug logging from CLI and server - All user roles now authenticate correctly: * Admin: Can queue jobs and see all jobs * Researcher: Can queue jobs and see own jobs * Analyst: Can see status (read-only access) Multi-user authentication is now fully functional.
147 lines
5.8 KiB
Docker
147 lines
5.8 KiB
Docker
# Homelab Secure Production Dockerfile
|
|
FROM golang:1.25-alpine AS builder
|
|
|
|
# Install dependencies
|
|
RUN apk add --no-cache git make
|
|
|
|
# Set working directory
|
|
WORKDIR /app
|
|
|
|
# Copy go mod files
|
|
COPY go.mod go.sum ./
|
|
|
|
# Download dependencies
|
|
RUN go mod download
|
|
|
|
# Copy source code
|
|
COPY . .
|
|
|
|
# Build Go binaries
|
|
RUN go build -o bin/api-server cmd/api-server/main.go && \
|
|
go build -o bin/worker cmd/worker/worker_server.go cmd/worker/worker_config.go
|
|
|
|
# Final stage with security hardening
|
|
FROM alpine:3.19
|
|
|
|
# Install security packages and runtime dependencies
|
|
RUN apk add --no-cache \
|
|
ca-certificates \
|
|
redis \
|
|
openssl \
|
|
curl \
|
|
podman \
|
|
openssh \
|
|
sudo \
|
|
fail2ban \
|
|
logrotate \
|
|
&& rm -rf /var/cache/apk/*
|
|
|
|
# Create app user and worker user with no shell by default
|
|
RUN addgroup -g 1001 -S appgroup && \
|
|
adduser -u 1001 -S appuser -G appgroup -s /sbin/nologin && \
|
|
addgroup -g 1002 -S workergroup && \
|
|
adduser -u 1002 -S worker -G workergroup -s /bin/sh && \
|
|
echo "worker:HomelabWorker2024!" | chpasswd && \
|
|
mkdir -p /home/worker/.ssh && \
|
|
chown -R worker:workergroup /home/worker
|
|
|
|
# Set working directory
|
|
WORKDIR /app
|
|
|
|
# Copy binaries from builder
|
|
COPY --from=builder /app/bin/ /usr/local/bin/
|
|
|
|
# Copy configs
|
|
COPY --from=builder /app/configs/ /app/configs/
|
|
|
|
# Create necessary directories with proper permissions
|
|
RUN mkdir -p /app/data/experiments /app/logs /app/ssl /tmp/fetchml-jobs && \
|
|
chown -R appuser:appgroup /app && \
|
|
chmod 750 /app/data/experiments /app/logs
|
|
|
|
# Generate SSL certificates with stronger crypto
|
|
RUN openssl req -x509 -newkey rsa:4096 -keyout /app/ssl/key.pem -out /app/ssl/cert.pem -days 365 -nodes \
|
|
-subj "/C=US/ST=Homelab/L=Local/O=ML/OU=Experiments/CN=localhost" && \
|
|
chmod 600 /app/ssl/key.pem && \
|
|
chmod 644 /app/ssl/cert.pem
|
|
|
|
# Generate SSH keys with stronger crypto
|
|
RUN ssh-keygen -t rsa -b 4096 -f /home/worker/.ssh/id_rsa -N "" && \
|
|
cp /home/worker/.ssh/id_rsa.pub /home/worker/.ssh/authorized_keys && \
|
|
chmod 700 /home/worker/.ssh && \
|
|
chmod 600 /home/worker/.ssh/id_rsa && \
|
|
chmod 644 /home/worker/.ssh/id_rsa.pub /home/worker/.ssh/authorized_keys && \
|
|
chown -R worker:workergroup /home/worker/.ssh
|
|
|
|
# Configure SSH with security hardening
|
|
RUN echo "Port 2222" >> /etc/ssh/sshd_config && \
|
|
echo "PermitRootLogin no" >> /etc/ssh/sshd_config && \
|
|
echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config && \
|
|
echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config && \
|
|
echo "AuthorizedKeysFile %h/.ssh/authorized_keys" >> /etc/ssh/sshd_config && \
|
|
echo "AllowUsers worker" >> /etc/ssh/sshd_config && \
|
|
echo "MaxAuthTries 3" >> /etc/ssh/sshd_config && \
|
|
echo "ClientAliveInterval 300" >> /etc/ssh/sshd_config && \
|
|
echo "ClientAliveCountMax 2" >> /etc/ssh/sshd_config && \
|
|
echo "X11Forwarding no" >> /etc/ssh/sshd_config && \
|
|
echo "AllowTcpForwarding no" >> /etc/ssh/sshd_config && \
|
|
echo "Banner /etc/ssh/banner" >> /etc/ssh/sshd_config && \
|
|
echo "Protocol 2" >> /etc/ssh/sshd_config && \
|
|
echo "Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com" >> /etc/ssh/sshd_config && \
|
|
echo "MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512" >> /etc/ssh/sshd_config && \
|
|
echo "KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group16-sha512" >> /etc/ssh/sshd_config
|
|
|
|
# Create SSH banner
|
|
RUN echo "=================================================" > /etc/ssh/banner && \
|
|
echo " ML Experiments Homelab Server" >> /etc/ssh/banner && \
|
|
echo " Unauthorized access is prohibited" >> /etc/ssh/banner && \
|
|
echo " All connections are monitored and logged" >> /etc/ssh/banner && \
|
|
echo "=================================================" >> /etc/ssh/banner
|
|
|
|
# Generate SSH host keys
|
|
RUN ssh-keygen -A
|
|
|
|
# Configure fail2ban for SSH protection
|
|
RUN echo "[DEFAULT]" > /etc/fail2ban/jail.local && \
|
|
echo "bantime = 3600" >> /etc/fail2ban/jail.local && \
|
|
echo "findtime = 600" >> /etc/fail2ban/jail.local && \
|
|
echo "maxretry = 3" >> /etc/fail2ban/jail.local && \
|
|
echo "" >> /etc/fail2ban/jail.local && \
|
|
echo "[sshd]" >> /etc/fail2ban/jail.local && \
|
|
echo "enabled = true" >> /etc/fail2ban/jail.local && \
|
|
echo "port = 2222" >> /etc/fail2ban/jail.local && \
|
|
echo "filter = sshd" >> /etc/fail2ban/jail.local && \
|
|
echo "logpath = /var/log/messages" >> /etc/fail2ban/jail.local
|
|
|
|
# Configure sudo with restricted access
|
|
RUN echo "appuser ALL=(ALL) NOPASSWD: /app/start-security.sh" >> /etc/sudoers && \
|
|
echo "appuser ALL=(ALL) NOPASSWD: /usr/sbin/sshd" >> /etc/sudoers && \
|
|
echo "appuser ALL=(ALL) NOPASSWD: /usr/bin/ssh-keygen" >> /etc/sudoers && \
|
|
echo "worker ALL=(ALL) NOPASSWD: /usr/bin/podman" >> /etc/sudoers && \
|
|
echo "Defaults:appuser !requiretty" >> /etc/sudoers && \
|
|
echo "Defaults:worker !requiretty" >> /etc/sudoers && \
|
|
echo "Defaults:appuser !lecture" >> /etc/sudoers && \
|
|
echo "Defaults:worker !lecture" >> /etc/sudoers
|
|
|
|
# Security hardening - remove setuid binaries except sudo
|
|
RUN find / -perm /4000 -type f -not -path "/usr/bin/sudo" -exec chmod 755 {} \; 2>/dev/null || true
|
|
|
|
# Create startup script for security services
|
|
RUN echo "#!/bin/sh" > /app/start-security.sh && \
|
|
echo "ssh-keygen -A" >> /app/start-security.sh && \
|
|
echo "/usr/sbin/sshd -D -p 2222" >> /app/start-security.sh && \
|
|
echo "# End of security services" >> /app/start-security.sh && \
|
|
chmod 755 /app/start-security.sh
|
|
|
|
# Switch to app user for application
|
|
USER appuser
|
|
|
|
# Expose ports
|
|
EXPOSE 9101 2222
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
|
CMD curl -k -f https://localhost:9101/health || exit 1
|
|
|
|
# Default command for API server
|
|
CMD ["/usr/local/bin/api-server", "-config", "/app/configs/config.yaml"]
|