mirror of
https://github.com/narrrl/narl-workspace.git
synced 2026-11-04 00:47:01 +01:00
The server no longer starts with WORKSPACE_SECRET or WORKSPACE_PASSWORD left at the value .env.example ships with. The secret was only checked for length, and the public placeholder passed: anyone who had read the repository could sign a session cookie for themselves. A secret under 32 characters is warned about. With WORKSPACE_SECURE_COOKIE=1 the cookie is named __Host-diary_session, which the browser keeps to this host and to HTTPS and which no sibling subdomain can plant; turning it on logs everyone out once. Responses then carry Strict-Transport-Security for a year. The traefik example turns it on. The password is compared as an HMAC under the secret, so the time a comparison takes no longer depends on the configured password's length. Every response also carries Cross-Origin-Opener-Policy and Cross-Origin-Resource-Policy same-origin and a Permissions-Policy that turns camera, microphone, location, payment and USB off; API answers are no-store unless they say otherwise.
52 lines
1.8 KiB
Plaintext
52 lines
1.8 KiB
Plaintext
# Copy to compose.override.yml on the host that runs traefik.
|
|
services:
|
|
workspace:
|
|
# Traefik only routes HTTP; SFTP (raw TCP) can't go through it, so its
|
|
# port is published straight to the host instead. Restrict to your IP,
|
|
# or leave it 127.0.0.1 and reach it over a VPN/SSH tunnel.
|
|
# Requires WORKSPACE_SFTP_BIND=0.0.0.0:2222 in .env to actually listen.
|
|
ports: !override
|
|
- "127.0.0.1:2222:2222"
|
|
# Traefik serves it over HTTPS, so the cookie can insist on it.
|
|
environment:
|
|
WORKSPACE_SECURE_COOKIE: "1"
|
|
networks:
|
|
- narl
|
|
- internal_net
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.docker.network=narl"
|
|
- "traefik.http.routers.workspace.rule=Host(`workspace.narl.io`)"
|
|
- "traefik.http.routers.workspace.entrypoints=websecure"
|
|
- "traefik.http.routers.workspace.tls.certresolver=https_resolver"
|
|
- "traefik.http.services.workspace.loadbalancer.server.port=4242"
|
|
# The key the Proton session is sealed under, mounted from the host at
|
|
# /run/secrets/session_key. Needs WORKSPACE_SESSION_KEY_FILE in .env.
|
|
secrets:
|
|
- session_key
|
|
|
|
# Mail, locally. Mailpit accepts everything on 1025 and shows it on 8025, so
|
|
# the reminders can be read before a real relay is ever involved:
|
|
#
|
|
# WORKSPACE_SMTP_URL=smtp://mailpit:1025
|
|
# WORKSPACE_MAIL_TO=you@example.org
|
|
#
|
|
# Nothing it receives leaves the host, which is the point of testing here.
|
|
mailpit:
|
|
image: axllent/mailpit:latest
|
|
restart: unless-stopped
|
|
networks:
|
|
- internal_net
|
|
ports:
|
|
- "127.0.0.1:8025:8025"
|
|
|
|
secrets:
|
|
# Outside compose is a plain bind mount, so the file must be readable by
|
|
# the container's user: `chown 10001 secrets/session.key`.
|
|
session_key:
|
|
file: ./secrets/session.key
|
|
|
|
networks:
|
|
narl:
|
|
external: true
|