diff --git a/.env.example b/.env.example deleted file mode 100644 index e79ec665..00000000 --- a/.env.example +++ /dev/null @@ -1,16 +0,0 @@ -# Copy to `.env` next to docker-compose.yml; `docker compose up -d` reads it automatically. -# Local default needs none of this — it's only for a public/HTTPS deployment. - -BASE_URL=https://archive.example.com -SERVER_SECURITY_MODE=safe-subdomains-fullreplay -REVERSE_PROXY_TRUST_FORWARDED_PROTO=True - -# Pick ONE ingress (see docker-compose.yml). Activates its profile with no extra flags: -# tunnel = Cloudflare Tunnel (no public IP needed) https = Caddy + Let's Encrypt (public IP) -COMPOSE_PROFILES=tunnel - -# Cloudflare API token. For `tunnel`: Account:Cloudflare Tunnel:Edit + Zone:DNS:Edit + Zone:Read. -# For `https` (lego DNS-01): Zone:DNS:Edit + Zone:Read. Everything else is provisioned for you. -CLOUDFLARE_DNS_API_TOKEN= -# CLOUDFLARE_ACCOUNT_ID= # optional (tunnel only); first account is used if unset -# ARCHIVEBOX_ACME_EMAIL=admin@example.com # https profile: ACME contact email diff --git a/archivebox/core/settings.py b/archivebox/core/settings.py index 0e3f4a6b..5332ba75 100644 --- a/archivebox/core/settings.py +++ b/archivebox/core/settings.py @@ -432,8 +432,11 @@ SECURE_REFERRER_POLICY = "strict-origin-when-cross-origin" if CONFIG.REVERSE_PROXY_TRUST_FORWARDED_PROTO: SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") -CSRF_COOKIE_SECURE = False -SESSION_COOKIE_SECURE = False +# When the proxy is trusted the deployment is HTTPS end-to-end, so also mark the +# admin session + CSRF cookies Secure (never sent over plain HTTP). Scoped to the +# same flag so the default http://localhost:8000 setup keeps working unchanged. +CSRF_COOKIE_SECURE = CONFIG.REVERSE_PROXY_TRUST_FORWARDED_PROTO +SESSION_COOKIE_SECURE = CONFIG.REVERSE_PROXY_TRUST_FORWARDED_PROTO SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_NAME = f"archivebox_sessionid_{CONSTANTS.COLLECTION_ID}" CSRF_COOKIE_NAME = f"archivebox_csrftoken_{CONSTANTS.COLLECTION_ID}" diff --git a/docker-compose.yml b/docker-compose.yml index fad628fa..d931d06e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -127,7 +127,11 @@ services: except urllib.error.HTTPError as e: return json.load(e) assert DOMAIN and TOKEN, "set BASE_URL (https://archive.example.com) + CLOUDFLARE_DNS_API_TOKEN" acct = os.environ.get("CLOUDFLARE_ACCOUNT_ID", "").strip() or call("GET", "/accounts")["result"][0]["id"] - zone = call("GET", f"/zones?name={DOMAIN}")["result"][0]["id"] + labels = DOMAIN.split("."); zone = None # DOMAIN may be a subdomain; find its registrable zone + for i in range(len(labels) - 1): + res = call("GET", f"/zones?name={'.'.join(labels[i:])}")["result"] + if res: zone = res[0]["id"]; break + assert zone, f"no Cloudflare zone found for {DOMAIN}" NAME = "archivebox-" + DOMAIN.replace(".", "-") ts = call("GET", f"/accounts/{acct}/cfd_tunnel?name={NAME}&is_deleted=false")["result"] tid = ts[0]["id"] if ts else call("POST", f"/accounts/{acct}/cfd_tunnel", {"name": NAME, @@ -144,7 +148,7 @@ services: desired = {"type": "CNAME", "name": name, "content": target, "proxied": True, "ttl": 1} call("PUT", f"/zones/{zone}/dns_records/{cname[0]['id']}", desired) if cname else call("POST", f"/zones/{zone}/dns_records", desired) tok = call("GET", f"/accounts/{acct}/cfd_tunnel/{tid}/token")["result"] - os.makedirs(os.path.dirname(OUT) or ".", exist_ok=True); open(OUT, "w").write(tok) + os.makedirs(os.path.dirname(OUT) or ".", exist_ok=True); open(OUT, "w").write(tok); os.chmod(OUT, 0o600) print(f"[tunnel-init] {NAME} ({tid}): *.{DOMAIN} + {DOMAIN} -> {SERVICE}; connector token -> {OUT}") cloudflared: diff --git a/etc/README.md b/etc/README.md index 2a6368a5..b45a4b60 100644 --- a/etc/README.md +++ b/etc/README.md @@ -6,7 +6,8 @@ E.g. see `nginx.conf` for an example nginx config to serve your archive with SSL For the recommended, batteries-included reverse proxy and TLS, you don't need a file here at all — it's built into the main `../docker-compose.yml` as two opt-in, env-var -driven profiles (no extra files, Dockerfiles, or scripts). See `../.env.example`: +driven profiles (no extra files, Dockerfiles, or scripts) — set the documented env +vars in a `.env` next to `../docker-compose.yml`: - `https` — Caddy + a `goacme/lego` DNS-01 sidecar fetch a single `*.` wildcard cert (covering unlimited `snap-*` subdomains, ~150 DNS providers, no