security: restrict picoclaw access to tailscale tailnet only

- Bind Docker port to 127.0.0.1 only (not publicly exposed)
- Remove UFW rule that opened port 18790 to the internet
- Install Tailscale in setup-server.sh with optional auth key
- Configure tailscale serve to proxy tailnet -> localhost:18790
- Add deploy workflow step to ensure tailscale serve stays active

Port 18790 is now only reachable via the tailnet, not the public internet.

https://claude.ai/code/session_019vXaqxGmkdCjM8m3jp6rYj
This commit is contained in:
Claude 2026-02-17 18:34:51 +00:00
parent 091cd28cd5
commit 7520aff373
No known key found for this signature in database
3 changed files with 50 additions and 8 deletions

View file

@ -110,6 +110,29 @@ jobs:
echo "Docker deploy complete" echo "Docker deploy complete"
EOF EOF
- name: Ensure Tailscale serve is active
env:
SSHPASS: ${{ secrets.HOSTINGER_SSH_PASSWORD }}
run: |
SSH_PORT="${{ secrets.HOSTINGER_SSH_PORT }}"
SSH_PORT="${SSH_PORT:-22}"
SSH_USER="${{ secrets.HOSTINGER_SSH_USER }}"
SSH_USER="${SSH_USER:-root}"
sshpass -e ssh \
-o StrictHostKeyChecking=accept-new \
-o ConnectTimeout=15 \
-p "${SSH_PORT}" \
"${SSH_USER}@${{ secrets.HOSTINGER_HOST }}" <<'EOF'
if command -v tailscale &>/dev/null && tailscale status &>/dev/null 2>&1; then
tailscale serve --bg http://localhost:18790 2>/dev/null || true
echo "Tailscale serve active on tailnet"
tailscale ip -4 2>/dev/null && echo "(use the IP above or tailnet hostname to access)"
else
echo "::warning::Tailscale not installed or not authenticated. Run setup-server.sh first."
fi
EOF
- name: Health check - name: Health check
env: env:
SSHPASS: ${{ secrets.HOSTINGER_SSH_PASSWORD }} SSHPASS: ${{ secrets.HOSTINGER_SSH_PASSWORD }}

View file

@ -15,7 +15,7 @@ services:
container_name: picoclaw-gateway container_name: picoclaw-gateway
restart: unless-stopped restart: unless-stopped
ports: ports:
- "18790:18790" - "127.0.0.1:18790:18790"
volumes: volumes:
# Configuration (read-only) # Configuration (read-only)
- /opt/picoclaw/config/config.json:/root/.picoclaw/config.json:ro - /opt/picoclaw/config/config.json:/root/.picoclaw/config.json:ro

View file

@ -130,18 +130,37 @@ if command -v ufw &>/dev/null; then
ufw default deny incoming ufw default deny incoming
ufw default allow outgoing ufw default allow outgoing
ufw allow ssh ufw allow ssh
ufw allow 18790/tcp comment "PicoClaw Gateway" # Port 18790 is NOT opened publicly - accessible only via Tailscale
# Uncomment if you need webhook ports:
# ufw allow 18791/tcp comment "PicoClaw Line Webhook"
ufw --force enable ufw --force enable
log "UFW firewall configured" log "UFW firewall configured (port 18790 is tailscale-only)"
elif command -v firewall-cmd &>/dev/null; then elif command -v firewall-cmd &>/dev/null; then
systemctl enable firewalld systemctl enable firewalld
systemctl start firewalld systemctl start firewalld
firewall-cmd --permanent --add-service=ssh firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-port=18790/tcp # Port 18790 is NOT opened publicly - accessible only via Tailscale
firewall-cmd --reload firewall-cmd --reload
log "firewalld configured" log "firewalld configured (port 18790 is tailscale-only)"
fi
# ── 6b. Install and configure Tailscale ──────────────
log "Installing Tailscale..."
if ! command -v tailscale &>/dev/null; then
curl -fsSL https://tailscale.com/install.sh | sh
log "Tailscale installed"
else
log "Tailscale already installed: $(tailscale version 2>/dev/null | head -1)"
fi
if [ -n "${TAILSCALE_AUTH_KEY:-}" ]; then
log "Authenticating Tailscale with auth key..."
tailscale up --authkey="${TAILSCALE_AUTH_KEY}" --hostname="picoclaw" --ssh
log "Tailscale authenticated. Configuring serve..."
tailscale serve --bg http://localhost:18790
log "Tailscale serve active: https://picoclaw.TAILNET.ts.net -> localhost:18790"
else
warn "TAILSCALE_AUTH_KEY not set. Run manually after setup:"
warn " tailscale up --hostname=picoclaw --ssh"
warn " tailscale serve --bg http://localhost:18790"
fi fi
# ── 7. Configure fail2ban ──────────────────────────── # ── 7. Configure fail2ban ────────────────────────────
@ -300,5 +319,5 @@ else
echo " 6. View logs: tail -f ${PICOCLAW_HOME}/logs/picoclaw.log" echo " 6. View logs: tail -f ${PICOCLAW_HOME}/logs/picoclaw.log"
fi fi
echo "" echo ""
log "Firewall ports open: SSH (22), PicoClaw Gateway (18790)" log "Firewall ports open: SSH (22) only. Port 18790 accessible via Tailscale only."
echo "" echo ""