Add optional SSH debug access and stale lock cleanup

- Add CLAWDBOT_ENABLE_SSH build arg to optionally install OpenSSH server
- Add SSH_AUTHORIZED_KEYS build arg to configure authorized keys
- Add docker-entrypoint.sh that clears stale session locks on startup
- Install gosu for secure privilege dropping (runs as node user)
- SSH access uses key-based auth only, no root login, only node user allowed

To build with SSH enabled:
docker build --build-arg CLAWDBOT_ENABLE_SSH=true \
  --build-arg SSH_AUTHORIZED_KEYS="ssh-ed25519 AAAA... user@host" .

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Harry Winkler 2026-01-26 11:03:31 -05:00
parent 8b68cdd9bc
commit 1d29f772a6
2 changed files with 63 additions and 4 deletions

View File

@ -6,6 +6,12 @@ ENV PATH="/root/.bun/bin:${PATH}"
RUN corepack enable
# Install gosu for secure privilege dropping in entrypoint
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends gosu && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
WORKDIR /app
ARG CLAWDBOT_DOCKER_APT_PACKAGES=""
@ -16,6 +22,31 @@ RUN if [ -n "$CLAWDBOT_DOCKER_APT_PACKAGES" ]; then \
rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*; \
fi
# Install SSH server for remote debug access (optional, disabled by default)
ARG CLAWDBOT_ENABLE_SSH="false"
RUN if [ "$CLAWDBOT_ENABLE_SSH" = "true" ]; then \
apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends openssh-server && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/* && \
mkdir -p /run/sshd && \
mkdir -p /home/node/.ssh && \
chown node:node /home/node/.ssh && \
chmod 700 /home/node/.ssh && \
sed -i 's/#PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config && \
sed -i 's/#PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config && \
sed -i 's/#PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config && \
echo "AllowUsers node" >> /etc/ssh/sshd_config; \
fi
# Add SSH authorized keys for debug access (only if SSH is enabled)
ARG SSH_AUTHORIZED_KEYS=""
RUN if [ "$CLAWDBOT_ENABLE_SSH" = "true" ] && [ -n "$SSH_AUTHORIZED_KEYS" ]; then \
echo "$SSH_AUTHORIZED_KEYS" > /home/node/.ssh/authorized_keys && \
chown node:node /home/node/.ssh/authorized_keys && \
chmod 600 /home/node/.ssh/authorized_keys; \
fi
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
COPY ui/package.json ./ui/package.json
COPY patches ./patches
@ -32,9 +63,14 @@ RUN pnpm ui:build
ENV NODE_ENV=production
# Security hardening: Run as non-root user
# The node:22-bookworm image includes a 'node' user (uid 1000)
# This reduces the attack surface by preventing container escape via root privileges
USER node
# Copy entrypoint script
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
# Security hardening notes:
# - When CLAWDBOT_ENABLE_SSH=false (default): runs as node user for security
# - When CLAWDBOT_ENABLE_SSH=true: runs as root to start sshd, then drops to node via gosu
# The entrypoint handles privilege dropping when SSH is enabled
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["node", "dist/index.js"]

23
docker-entrypoint.sh Normal file
View File

@ -0,0 +1,23 @@
#!/bin/bash
set -e
# Clear stale session locks on startup (handles both root and node ownership)
rm -f /data/agents/main/sessions/*.lock 2>/dev/null || true
# Start SSH daemon if installed and running as root
if [ "$(id -u)" = "0" ] && [ -f /usr/sbin/sshd ]; then
echo "Starting SSH daemon..."
/usr/sbin/sshd
fi
# If running as root and gosu is available, drop to node user for main process
if [ "$(id -u)" = "0" ] && command -v gosu > /dev/null 2>&1; then
# Ensure node user owns the data directory
if [ -d /data ]; then
chown -R node:node /data 2>/dev/null || true
fi
exec gosu node "$@"
fi
# Otherwise run as current user
exec "$@"