- Create server/src/utils/ssrfGuard.ts with checkSsrf() and createPinnedAgent()
- Resolves DNS before allowing outbound requests to catch hostnames that
map to private IPs (closes the TOCTOU gap in the old inline checks)
- Always blocks loopback (127.x, ::1) and link-local/metadata (169.254.x)
- RFC-1918, CGNAT (100.64/10), and IPv6 ULA ranges blocked by default;
opt-in via ALLOW_INTERNAL_NETWORK=true for self-hosters running Immich
on a local network
- createPinnedAgent() pins node-fetch to the validated IP, preventing
DNS rebinding between the check and the actual connection
- Replace isValidImmichUrl() (hostname-string check, no DNS resolution)
with checkSsrf(); make PUT /integrations/immich/settings async
- Audit log entry (immich.private_ip_configured) written when a user
saves an Immich URL that resolves to a private IP
- Response includes a warning field surfaced as a toast in the UI
- Replace ~20 lines of duplicated inline SSRF logic in the link-preview
handler with a single checkSsrf() call + pinned agent
- Document ALLOW_INTERNAL_NETWORK in README, docker-compose.yml,
server/.env.example, chart/values.yaml, chart/templates/configmap.yaml,
and chart/README.md
43 lines
1.8 KiB
YAML
43 lines
1.8 KiB
YAML
services:
|
|
app:
|
|
image: mauriceboe/trek:latest
|
|
container_name: trek
|
|
read_only: true
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
cap_drop:
|
|
- ALL
|
|
cap_add:
|
|
- CHOWN
|
|
- SETUID
|
|
- SETGID
|
|
tmpfs:
|
|
- /tmp:noexec,nosuid,size=64m
|
|
ports:
|
|
- "3000:3000"
|
|
environment:
|
|
- NODE_ENV=production
|
|
- PORT=3000
|
|
- ENCRYPTION_KEY=${ENCRYPTION_KEY:-} # Auto-generated if not set. If upgrading, set to your old JWT_SECRET value to keep existing encrypted secrets readable.
|
|
- TZ=${TZ:-UTC} # Timezone for logs, reminders and scheduled tasks (e.g. Europe/Berlin)
|
|
- LOG_LEVEL=${LOG_LEVEL:-info} # info = concise user actions; debug = verbose admin-level details
|
|
- ALLOWED_ORIGINS=${ALLOWED_ORIGINS:-} # Comma-separated origins for CORS and email notification links
|
|
- FORCE_HTTPS=true # Redirect HTTP to HTTPS when behind a TLS-terminating proxy
|
|
- TRUST_PROXY=1 # Number of trusted proxies (for X-Forwarded-For / real client IP)
|
|
- ALLOW_INTERNAL_NETWORK=false # Set to true if Immich or other services are hosted on your local network (RFC-1918 IPs). Loopback and link-local addresses remain blocked regardless.
|
|
- OIDC_ISSUER=https://auth.example.com # OpenID Connect provider URL
|
|
- OIDC_CLIENT_ID=trek # OpenID Connect client ID
|
|
- OIDC_CLIENT_SECRET=supersecret # OpenID Connect client secret
|
|
- OIDC_DISPLAY_NAME=SSO # Label shown on the SSO login button
|
|
- OIDC_ONLY=false # Set true to disable local password auth entirely (SSO only)
|
|
volumes:
|
|
- ./data:/app/data
|
|
- ./uploads:/app/uploads
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 15s
|