Update packaging/rustbox.toml
This commit is contained in:
1 parent
fe2ad1590d
commit
56c35b00e6
1 file changed
+102
-143
+102
-143
@@ -10,6 +10,12 @@
|
|||||||
host = "0.0.0.0"
|
host = "0.0.0.0"
|
||||||
port = 3001
|
port = 3001
|
||||||
environment = "production"
|
environment = "production"
|
||||||
|
# Secure attribute of session cookies: auto | always | never.
|
||||||
|
# auto (default) sets Secure only when the browser reached RustBox over HTTPS:
|
||||||
|
# X-Forwarded-Proto / Forwarded: proto= / X-Forwarded-Ssl from a trusted proxy,
|
||||||
|
# otherwise the scheme of the browser's Origin/Referer. Plain-HTTP installations
|
||||||
|
# therefore keep working. Use "always" behind HTTPS if your proxy strips headers.
|
||||||
|
cookie_secure = "auto"
|
||||||
|
|
||||||
data_dir = "/var/lib/rustbox"
|
data_dir = "/var/lib/rustbox"
|
||||||
log_dir = "/var/log/rustbox"
|
log_dir = "/var/log/rustbox"
|
||||||
@@ -39,25 +45,8 @@ default_interface_skin = "apple-mail"
|
|||||||
sieve_enabled = true
|
sieve_enabled = true
|
||||||
diagnostics_enabled = true
|
diagnostics_enabled = true
|
||||||
about_enabled = true
|
about_enabled = true
|
||||||
|
# Content-type-aware browser security headers. Off by default for compatibility.
|
||||||
# Allow multiple IMAP accounts in one browser session.
|
|
||||||
# When disabled, RustBox hides multi-account UI, rejects adding another account,
|
|
||||||
# and realtime notifications/watchers are limited to the active account.
|
|
||||||
multi_account_enabled = true
|
|
||||||
|
|
||||||
# Security headers added by RustBox. Off by default for compatibility.
|
|
||||||
#
|
|
||||||
# When enabled:
|
|
||||||
# - HTML documents receive the full browser security policy
|
|
||||||
# (CSP, frame protection, referrer/permissions policy, COOP, nosniff).
|
|
||||||
# - CSS receives only headers that are meaningful for stylesheets.
|
|
||||||
# - JS/static/API responses receive only headers that are meaningful for
|
|
||||||
# non-document resources; private API responses use no-store.
|
|
||||||
# - HSTS is intentionally NOT emitted here. Configure HSTS at the HTTPS
|
|
||||||
# terminator/reverse proxy, which knows whether the request is really HTTPS.
|
|
||||||
security_headers_enabled = false
|
security_headers_enabled = false
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Database
|
# Database
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
@@ -144,6 +133,18 @@ max_attachment_size_mb = 50
|
|||||||
|
|
||||||
# Maximum complete RFC822/MIME message size in MiB.
|
# Maximum complete RFC822/MIME message size in MiB.
|
||||||
max_message_size_mb = 100
|
max_message_size_mb = 100
|
||||||
|
# Memory guard for messages with attachments. Sending a message or saving an IMAP
|
||||||
|
# draft snapshot loads every attachment into RAM and the MIME builder keeps several
|
||||||
|
# copies (about 3-4x the message size). Attachment sets that cannot fit
|
||||||
|
# max_message_size_mb are rejected with 413 before any file is read, and at most
|
||||||
|
# max_concurrent_message_builds requests may hold attachments in memory at once;
|
||||||
|
# the others wait up to message_build_wait_secs and then get 503.
|
||||||
|
# Rough peak RAM = max_concurrent_message_builds x 4 x max_message_size_mb.
|
||||||
|
max_concurrent_message_builds = 4
|
||||||
|
message_build_wait_secs = 30
|
||||||
|
|
||||||
|
# "Undo Send" window in seconds (0 disables; max 120). See config.example.toml.
|
||||||
|
undo_send_window_secs = 8
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
@@ -168,8 +169,6 @@ sieve_timeout_secs = 10
|
|||||||
# Reverse proxy
|
# Reverse proxy
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
# Also used by the administrative diagnostics endpoint to validate forwarded
|
|
||||||
# client addresses. Do not trust arbitrary Internet-facing proxy ranges.
|
|
||||||
trusted_proxies = "127.0.0.1,::1"
|
trusted_proxies = "127.0.0.1,::1"
|
||||||
|
|
||||||
|
|
||||||
@@ -231,17 +230,38 @@ pgp_allow_private_export = true
|
|||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Blob storage
|
# Login brute-force protection
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
#
|
|
||||||
# Blob storage is independent from database_backend.
|
# Login brute-force protection (POST /api/auth/login). Enabled by default.
|
||||||
#
|
# Environment overrides use a double underscore, e.g.
|
||||||
# PostgreSQL/MySQL can use a local filesystem in single-node mode.
|
# LOGIN_RATE_LIMIT__ACCOUNT_MAX_FAILURES=10 or LOGIN_RATE_LIMIT__ENABLED=false.
|
||||||
#
|
# Client IPs are taken from X-Forwarded-For only when the peer is in trusted_proxies.
|
||||||
# Cluster deployments must use:
|
# State is kept in memory on each node: behind a load balancer every node counts
|
||||||
# - S3-compatible object storage, or
|
# separately, so use sticky routing or lower thresholds in cluster mode.
|
||||||
# - a genuinely shared POSIX filesystem such as NFS/CephFS/GlusterFS.
|
[login_rate_limit]
|
||||||
#
|
enabled = true
|
||||||
|
# Per-IP token bucket: up to ip_burst attempts at once, then one new attempt
|
||||||
|
# every ip_replenish_secs seconds. Requests over the limit get HTTP 429.
|
||||||
|
ip_burst = 5
|
||||||
|
ip_replenish_secs = 12
|
||||||
|
# Failed logins counted inside failure_window_secs before a lockout.
|
||||||
|
# account_max_failures: per mailbox (case-insensitive), from any IP.
|
||||||
|
# ip_max_failures: per client IP, across all mailboxes (password spraying).
|
||||||
|
# 0 disables that lockout type.
|
||||||
|
account_max_failures = 5
|
||||||
|
ip_max_failures = 20
|
||||||
|
failure_window_secs = 900
|
||||||
|
# First lockout length; every consecutive lockout of the same key doubles it
|
||||||
|
# up to max_lockout_secs. Locked attempts are refused before contacting IMAP.
|
||||||
|
# Trade-off: an attacker can keep a known mailbox locked for webmail logins
|
||||||
|
# (IMAP/SMTP clients are unaffected), so keep max_lockout_secs moderate.
|
||||||
|
lockout_secs = 300
|
||||||
|
max_lockout_secs = 3600
|
||||||
|
# IPs/CIDRs exempt from the per-IP lockout (account lockouts still apply).
|
||||||
|
exempt_networks = []
|
||||||
|
# Memory cap per tracking table (accounts, IPs).
|
||||||
|
max_tracked_keys = 100000
|
||||||
|
|
||||||
[storage]
|
[storage]
|
||||||
|
|
||||||
@@ -302,23 +322,19 @@ retry_timeout_secs = 60
|
|||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# IMAP synchronization / body cache
|
# IMAP synchronization / automatic body cache
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
#
|
|
||||||
# Periodic synchronization complements IMAP IDLE. The currently watched folder
|
|
||||||
# can update immediately through IDLE, while this interval is used to reconcile
|
|
||||||
# counters/flags and to make progress on folders that are not actively open.
|
|
||||||
#
|
|
||||||
# Lower values make folder counters converge faster but increase IMAP traffic.
|
|
||||||
#
|
|
||||||
[sync]
|
[sync]
|
||||||
|
|
||||||
# Periodic synchronization interval in seconds.
|
# Periodic fallback/background IMAP reconciliation. Active folders use IMAP IDLE,
|
||||||
|
# while this pass refreshes counters/flags/headers in the rest of the mailbox and
|
||||||
|
# also runs automatic deep indexing when enabled. Lower values increase IMAP load.
|
||||||
interval_secs = 30
|
interval_secs = 30
|
||||||
|
|
||||||
# Maximum number of complete message bodies fetched from IMAP during one
|
# Maximum full message bodies fetched from IMAP per periodic pass when deep index is
|
||||||
# deep-cache/index pass. Increasing this speeds initial catch-up but increases
|
# effective. Larger batches catch up faster but increase bandwidth, application database/
|
||||||
# IMAP traffic, disk writes and indexing CPU usage.
|
# search-storage usage and indexing CPU/I/O bursts.
|
||||||
deep_index_batch_size = 10
|
deep_index_batch_size = 10
|
||||||
|
|
||||||
|
|
||||||
@@ -344,21 +360,6 @@ deep_index_batch_size = 10
|
|||||||
# disabled | local_tantivy | opensearch
|
# disabled | local_tantivy | opensearch
|
||||||
backend = "local_tantivy"
|
backend = "local_tantivy"
|
||||||
|
|
||||||
# Global deep body cache/index policy.
|
|
||||||
#
|
|
||||||
# false (recommended production default):
|
|
||||||
# - RustBox does not force full-message caching for every account.
|
|
||||||
# - An account may still opt in through its own deep_index setting.
|
|
||||||
#
|
|
||||||
# true:
|
|
||||||
# - RustBox automatically downloads complete message bodies from IMAP and keeps
|
|
||||||
# them in the local/shared cache so the search backend can fully index content.
|
|
||||||
# - This can significantly increase IMAP bandwidth, local/S3 storage usage,
|
|
||||||
# indexing CPU and initial synchronization time for large mailboxes.
|
|
||||||
#
|
|
||||||
# This does not control IMAP IDLE itself.
|
|
||||||
deep_index = false
|
|
||||||
|
|
||||||
# Local Tantivy path.
|
# Local Tantivy path.
|
||||||
path = "/var/lib/rustbox/search"
|
path = "/var/lib/rustbox/search"
|
||||||
|
|
||||||
@@ -380,6 +381,13 @@ allow_insecure_http = false
|
|||||||
|
|
||||||
request_timeout_secs = 10
|
request_timeout_secs = 10
|
||||||
|
|
||||||
|
# Server-wide automatic full-body cache/index switch. Production default is false
|
||||||
|
# because enabling it proactively downloads and stores full message bodies. When
|
||||||
|
# true, all accounts are deep-indexed; when false, an account may still opt in via
|
||||||
|
# its existing deep_index preference.
|
||||||
|
deep_index = false
|
||||||
|
|
||||||
|
# Search outbox worker cadence/batch; these do NOT control IMAP body downloads.
|
||||||
worker_interval_secs = 2
|
worker_interval_secs = 2
|
||||||
worker_batch_size = 100
|
worker_batch_size = 100
|
||||||
worker_max_attempts = 12
|
worker_max_attempts = 12
|
||||||
@@ -390,86 +398,6 @@ worker_max_attempts = 12
|
|||||||
# password = "change-me"
|
# password = "change-me"
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
# Administrative system diagnostics endpoint
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# This endpoint is intended for local/cluster troubleshooting and monitoring.
|
|
||||||
# It is independent from the normal signed-in-user diagnostics UI.
|
|
||||||
#
|
|
||||||
# Security model:
|
|
||||||
# - disabled by default;
|
|
||||||
# - source IP must match allowed_networks;
|
|
||||||
# - authentication is additionally required (token or Basic Auth);
|
|
||||||
# - untrusted source network -> HTTP 403;
|
|
||||||
# - missing/invalid endpoint credentials -> HTTP 401;
|
|
||||||
# - backend health can make the diagnostic response report degraded/error.
|
|
||||||
#
|
|
||||||
# Behind a reverse proxy, configure trusted_proxies correctly. If forwarded
|
|
||||||
# client-IP headers are present but the proxy is not trusted, access fails
|
|
||||||
# closed instead of treating the proxy connection as localhost.
|
|
||||||
#
|
|
||||||
# The endpoint NEVER returns configured passwords, access keys, session keys,
|
|
||||||
# bearer tokens or full credential-bearing DSNs. Secret fields are exposed only
|
|
||||||
# as configured/not-configured state.
|
|
||||||
#
|
|
||||||
# Runtime statistics are intentionally limited to the RustBox process and
|
|
||||||
# application state. RustBox does not inspect host CPU/RAM/load or /proc for
|
|
||||||
# this endpoint, keeping it lightweight and portable across supported systems.
|
|
||||||
#
|
|
||||||
[diagnostics_endpoint]
|
|
||||||
|
|
||||||
enabled = false
|
|
||||||
|
|
||||||
# Must start with "/api/".
|
|
||||||
path = "/api/system/diagnostics"
|
|
||||||
|
|
||||||
# Default: localhost only.
|
|
||||||
# Add explicit internal management networks when required, for example:
|
|
||||||
# allowed_networks = ["127.0.0.1/32", "::1/128", "10.20.30.0/24"]
|
|
||||||
allowed_networks = ["127.0.0.1/32", "::1/128"]
|
|
||||||
|
|
||||||
# token | basic
|
|
||||||
auth = "token"
|
|
||||||
|
|
||||||
# For token authentication uncomment and set a long random secret.
|
|
||||||
# Keep it outside source control in real deployments, preferably via environment
|
|
||||||
# configuration/secrets management.
|
|
||||||
#
|
|
||||||
# token = "minimum-24-random-characters"
|
|
||||||
|
|
||||||
# For Basic authentication:
|
|
||||||
#
|
|
||||||
# auth = "basic"
|
|
||||||
# basic_username = "rustbox-monitor"
|
|
||||||
# basic_password = "minimum-16-random-characters"
|
|
||||||
|
|
||||||
# When false, session/account diagnostics avoid exposing user identifiers.
|
|
||||||
include_user_identifiers = false
|
|
||||||
|
|
||||||
# Timeout used by lightweight dependency probes.
|
|
||||||
probe_timeout_secs = 5
|
|
||||||
|
|
||||||
# Sliding security-observation window used to aggregate login failures,
|
|
||||||
# 401/403/429 responses, 5xx responses and suspicious access patterns.
|
|
||||||
security_window_secs = 900
|
|
||||||
|
|
||||||
# The report can include:
|
|
||||||
# - RustBox version, PID, start time and uptime;
|
|
||||||
# - effective configuration with secrets redacted;
|
|
||||||
# - SQL backend/version/pool/schema migration state;
|
|
||||||
# - Redis/Valkey state when configured;
|
|
||||||
# - filesystem/S3 blob backend state;
|
|
||||||
# - Tantivy/OpenSearch state and index health;
|
|
||||||
# - active sessions and IMAP IDLE/synchronization state;
|
|
||||||
# - cache/index backlog and worker state;
|
|
||||||
# - aggregate security signals such as failed logins, 401/403/429/5xx,
|
|
||||||
# brute-force-like patterns and rejected diagnostic endpoint access.
|
|
||||||
#
|
|
||||||
# It intentionally does NOT expose message bodies, passwords, auth headers,
|
|
||||||
# session secrets, S3 credentials or host-wide resource statistics.
|
|
||||||
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# CLUSTER EXAMPLES
|
# CLUSTER EXAMPLES
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -491,10 +419,6 @@ security_window_secs = 900
|
|||||||
#
|
#
|
||||||
# pgp_enabled = false
|
# pgp_enabled = false
|
||||||
#
|
#
|
||||||
# [sync]
|
|
||||||
# interval_secs = 30
|
|
||||||
# deep_index_batch_size = 10
|
|
||||||
#
|
|
||||||
# [storage]
|
# [storage]
|
||||||
# backend = "s3"
|
# backend = "s3"
|
||||||
# bucket = "rustbox"
|
# bucket = "rustbox"
|
||||||
@@ -510,12 +434,12 @@ security_window_secs = 900
|
|||||||
#
|
#
|
||||||
# [search]
|
# [search]
|
||||||
# backend = "opensearch"
|
# backend = "opensearch"
|
||||||
# deep_index = false
|
|
||||||
# urls = ["https://opensearch.example.net:9200"]
|
# urls = ["https://opensearch.example.net:9200"]
|
||||||
# index_prefix = "rustbox"
|
# index_prefix = "rustbox"
|
||||||
# required = true
|
# required = true
|
||||||
# allow_insecure_http = false
|
# allow_insecure_http = false
|
||||||
# request_timeout_secs = 10
|
# request_timeout_secs = 10
|
||||||
|
# deep_index = false
|
||||||
# worker_interval_secs = 2
|
# worker_interval_secs = 2
|
||||||
# worker_batch_size = 100
|
# worker_batch_size = 100
|
||||||
# worker_max_attempts = 12
|
# worker_max_attempts = 12
|
||||||
@@ -545,7 +469,6 @@ security_window_secs = 900
|
|||||||
#
|
#
|
||||||
# [search]
|
# [search]
|
||||||
# backend = "opensearch"
|
# backend = "opensearch"
|
||||||
# deep_index = false
|
|
||||||
# urls = ["https://opensearch.example.net:9200"]
|
# urls = ["https://opensearch.example.net:9200"]
|
||||||
# index_prefix = "rustbox"
|
# index_prefix = "rustbox"
|
||||||
# required = true
|
# required = true
|
||||||
@@ -570,3 +493,39 @@ security_window_secs = 900
|
|||||||
# redis_sentinel_master = "mymaster"
|
# redis_sentinel_master = "mymaster"
|
||||||
# redis_sentinel_password = "sentinel-secret"
|
# redis_sentinel_password = "sentinel-secret"
|
||||||
# redis_password = "secret"
|
# redis_password = "secret"
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Blob storage
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Blob storage is independent from database_backend.
|
||||||
|
#
|
||||||
|
# PostgreSQL/MySQL can use a local filesystem in single-node mode.
|
||||||
|
#
|
||||||
|
# Cluster deployments must use:
|
||||||
|
# - S3-compatible object storage, or
|
||||||
|
# - a genuinely shared POSIX filesystem such as NFS/CephFS/GlusterFS.
|
||||||
|
#
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Administrator system diagnostics endpoint
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Disabled by default. When enabled, the endpoint performs live probes of SQL,
|
||||||
|
# session persistence/Redis, filesystem/S3, Tantivy/OpenSearch and reports
|
||||||
|
# process/runtime/IMAP-IDLE/security telemetry. Returned configuration is redacted:
|
||||||
|
# passwords, auth tokens, S3 secrets, session keys and URL credentials are never emitted.
|
||||||
|
# Access is an AND condition: source IP/CIDR must be allowed and token/basic auth must pass.
|
||||||
|
[diagnostics_endpoint]
|
||||||
|
enabled = false
|
||||||
|
path = "/api/system/diagnostics"
|
||||||
|
# Fail-safe default. Add only monitoring/admin networks that really need access.
|
||||||
|
allowed_networks = ["127.0.0.1/32", "::1/128"]
|
||||||
|
auth = "token" # token | basic
|
||||||
|
# Prefer injecting these with a secret manager/environment rather than storing here.
|
||||||
|
# token = "at-least-24-random-characters"
|
||||||
|
# basic_username = "rustbox-monitor"
|
||||||
|
# basic_password = "long-random-password"
|
||||||
|
include_user_identifiers = false
|
||||||
|
probe_timeout_secs = 5
|
||||||
|
security_window_secs = 900
|
||||||
Reference in new issue
Block a user