Files
microdao-daarion/docker-compose.web.secure.yml
Apple d77a4769c6 🔒 security(daarion-web): Hardening after crypto-mining incidents
## Root Cause Analysis
- Found CRITICAL RCE vulnerability in Next.js 15.0.3 (GHSA-9qr9-h5gf-34mp)
- 10 vulnerabilities total including SSRF, DoS, Auth Bypass
- Attack vector: exposed port 3000 + vulnerable Next.js → remote code execution

## Security Fixes
- Upgraded Next.js: 15.0.3 → 15.5.9 (0 vulnerabilities)
- Upgraded eslint-config-next: 15.0.3 → 15.5.9

## Hardening (New Files)
- apps/web/Dockerfile.secure: Multi-stage build, read-only FS, no shell
- docker-compose.web.secure.yml: Resource limits, cap_drop ALL, localhost bind
- scripts/rebuild-daarion-web-secure.sh: Local secure rebuild with Trivy scan
- scripts/deploy-daarion-web-node1.sh: Production deployment to NODE1
- SECURITY-REBUILD-REPORT.md: Full incident analysis and remediation report

## Key Security Measures
- restart: "no" (until verified)
- ports: 127.0.0.1:3000 (localhost only, use Nginx reverse proxy)
- read_only: true
- cap_drop: ALL
- resources.limits: 1 CPU, 512M RAM
- no-new-privileges: true

## Related Incidents
- Incident #1 (Jan 8): catcal, G4NQXBp miners
- Incident #2 (Jan 9): softirq, vrarhpb miners
- Hetzner AbuseID: 10F3971:2A

Co-authored-by: Cursor Agent <agent@cursor.sh>
2026-01-09 02:08:13 -08:00

122 lines
3.0 KiB
YAML

# DAARION Web Frontend - SECURE Docker Compose
# Hardened configuration post-security incident
# Version: 2.0.0
# Created: 2026-01-09
version: '3.8'
services:
web:
build:
context: ./apps/web
dockerfile: Dockerfile.secure
# Prevent cache from potentially compromised layers
no_cache: true
container_name: daarion-web
# ⚠️ SECURITY: Changed from "unless-stopped" to "no"
# Only enable after security verification
restart: "no"
# Port mapping - internal only via reverse proxy
ports:
- "127.0.0.1:3000:3000" # Bind to localhost only!
environment:
- NODE_ENV=production
- INTERNAL_API_URL=http://daarion-city-service:7001
- CITY_API_BASE_URL=http://daarion-city-service:7001
- AUTH_API_URL=http://daarion-auth:8080
- NEXT_PUBLIC_API_BASE_URL=
- NEXT_PUBLIC_CITY_API_BASE_URL=
# ============================================
# SECURITY HARDENING
# ============================================
# Read-only root filesystem
read_only: true
# Temporary filesystems for Next.js cache
tmpfs:
- /tmp:size=64M,mode=1777
- /app/.next/cache:size=128M,mode=1777
# Drop all Linux capabilities
cap_drop:
- ALL
# Add only necessary capabilities (none needed for Next.js)
# cap_add:
# - NET_BIND_SERVICE # Only if binding to port < 1024
# Security options
security_opt:
- no-new-privileges:true
# Resource limits to prevent crypto mining
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M
# Disable privileged mode
privileged: false
# User namespace
user: "1001:1001"
# Network configuration
networks:
- dagi-network
# Health check
healthcheck:
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000', (r) => process.exit(r.statusCode < 400 ? 0 : 1))"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
# Logging configuration
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# Labels for monitoring
labels:
- "security.hardened=true"
- "security.incident=post-recovery"
- "security.scan-required=true"
networks:
dagi-network:
external: true
# ============================================
# DEPLOYMENT NOTES
# ============================================
#
# 1. Build with no-cache:
# docker compose -f docker-compose.web.secure.yml build --no-cache
#
# 2. Scan image before deployment:
# trivy image daarion-web:latest
#
# 3. Test locally first:
# docker compose -f docker-compose.web.secure.yml up -d
# docker logs -f daarion-web
#
# 4. Monitor for 15+ minutes:
# docker stats daarion-web
# docker exec daarion-web ps aux
#
# 5. After verification, change restart to "unless-stopped"
# ============================================