261 lines
12 KiB
TOML
261 lines
12 KiB
TOML
# RustBox 0.2.16
|
|
host = "127.0.0.1"
|
|
port = 3001
|
|
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"
|
|
# Global light/dark theme: system | dark | light
|
|
default_theme = "system"
|
|
# Global interface style used by the login screen and by accounts set to
|
|
# "Global default". Each user can additionally choose a style depth (colors only,
|
|
# standard or immersive) in Appearance. Available styles:
|
|
# rustbox, roundcube-classic, roundcube-larry, roundcube-elastic, clean, gmail,
|
|
# proton, zoho, outlook, minimal, graphite, high-contrast, fastmail, apple-mail,
|
|
# yahoo, hey, nord, github, gitlab, discord, slack, reddit, notion, dracula,
|
|
# catppuccin, solarized, gruvbox, tokyo-night, rose-pine, everforest, synthwave,
|
|
# paper, terminal, aqua, linear, material, retro, winxp, osx, ios6, win7,
|
|
# frutiger-aero, beos
|
|
default_interface_skin = "gmail"
|
|
data_dir = "/var/lib/rustbox"
|
|
log_dir = "/var/log/rustbox"
|
|
# trace | debug | info | warn | error | off. RUST_LOG still overrides this value.
|
|
log_level = "info"
|
|
session_timeout_hours = 24
|
|
|
|
# Application database. The selected engine stores all RustBox account data.
|
|
# With session_backend="database", it stores sessions as well.
|
|
database_backend = "sqlite" # sqlite | mysql | pgsql
|
|
# SQLite defaults to data_dir/rustbox.sqlite. MySQL/PostgreSQL require database_url.
|
|
# database_url = "postgres://rustbox:secret@db.example.com/rustbox"
|
|
session_backend = "database" # database | redis
|
|
cluster_mode = false
|
|
|
|
|
|
# For shared database sessions, Redis sessions, or cluster mode provide the same 32-byte key (base64) on all nodes.
|
|
# session_encryption_key = "..."
|
|
# Direct Redis session backend:
|
|
# redis_url = "redis://redis.example.com:6379/"
|
|
# Or Redis Sentinel:
|
|
# redis_sentinel_nodes = ["sentinel-a:26379", "sentinel-b:26379", "sentinel-c:26379"]
|
|
# redis_sentinel_master = "mymaster"
|
|
# redis_sentinel_password = "sentinel-secret"
|
|
# redis_password = "secret"
|
|
remember_me_enabled = true
|
|
remember_me_days = 30
|
|
|
|
# Mail profile. When hosts/ports are omitted RustBox defaults to:
|
|
# IMAP localhost:993 and SMTP localhost:587 with TLS enabled.
|
|
# SMTP host falls back to the IMAP host.
|
|
# imap_host = "localhost"
|
|
# imap_port = 993
|
|
# smtp_host = "localhost"
|
|
# smtp_port = 587
|
|
tls_enabled = true
|
|
# Certificate/hostname verification. If omitted, RustBox skips verification only
|
|
# for localhost/127.0.0.1/::1 and verifies certificates for remote hosts.
|
|
# tls_verify = true
|
|
|
|
# Maximum size of one raw uploaded attachment (MiB).
|
|
max_attachment_size_mb = 10
|
|
# Maximum size of the complete RFC822/MIME message submitted to the MTA (MiB).
|
|
max_message_size_mb = 50
|
|
# 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. A submitted message is held in memory (not
|
|
# persisted) for this long before it is actually dispatched to SMTP, so the
|
|
# sender can cancel it. 0 disables the feature and sends immediately. Must be
|
|
# <= 120; keep this short, since a server restart during the window loses the
|
|
# staged send.
|
|
undo_send_window_secs = 8
|
|
|
|
# Optional reverse-proxy subpath, e.g. "/mail".
|
|
# base_path = "/mail"
|
|
|
|
# Optional product features. Disabled features are not registered in the API/UI.
|
|
sieve_enabled = true
|
|
diagnostics_enabled = true
|
|
about_enabled = true
|
|
# Allow more than one signed-in account in the same browser session.
|
|
multi_account_enabled = true
|
|
# Adds content-type-aware browser security headers: document policies on HTML, private no-store/framing/CORP policy on /api, Referrer-Policy on HTML/CSS, and nosniff broadly.
|
|
security_headers_enabled = false
|
|
|
|
# ManageSieve. If sieve_host is omitted, imap_host from the authenticated
|
|
# session is used. Plaintext authentication stays blocked unless explicitly
|
|
# enabled.
|
|
# sieve_host = "mail.example.com"
|
|
sieve_port = 4190
|
|
sieve_tls_mode = "starttls" # starttls | implicit | none
|
|
sieve_allow_insecure_auth = false
|
|
sieve_timeout_secs = 10
|
|
|
|
trusted_proxies = "127.0.0.1,::1"
|
|
# Optional server-wide defaults for special IMAP folders. These are used when
|
|
# a mailbox has no per-account override and the named folder exists.
|
|
# default_sent_folder = "Sent"
|
|
# default_drafts_folder = "Drafts"
|
|
# default_trash_folder = "Trash"
|
|
# default_junk_folder = "Junk"
|
|
# default_archive_folder = "Archive"
|
|
|
|
# Optional headers added to every outgoing message. Use `Header-Name: value`.
|
|
# RustBox rejects structural/MIME header overrides and CR/LF injection.
|
|
outgoing_headers = []
|
|
# OpenPGP. Private keys are stored per user below data_dir with 0700/0600
|
|
# permissions. Passphrases are never persisted. WKD is enabled by default;
|
|
# HKP lookup is opt-in and HTTPS-only. Cluster mode requires pgp_enabled=false.
|
|
pgp_enabled = true
|
|
pgp_wkd_enabled = true
|
|
pgp_hkp_enabled = false
|
|
pgp_hkp_url = "https://keys.openpgp.org"
|
|
pgp_network_timeout_secs = 10
|
|
pgp_max_key_bytes = 1048576
|
|
# Private-key export is deliberately disabled unless the administrator opts in.
|
|
pgp_allow_private_export = false
|
|
|
|
# Login brute-force protection (POST /api/auth/login). Enabled by default.
|
|
# Environment overrides use a double underscore, e.g.
|
|
# 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.
|
|
# State is kept in memory on each node: behind a load balancer every node counts
|
|
# separately, so use sticky routing or lower thresholds in cluster mode.
|
|
[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]
|
|
backend = "filesystem" # filesystem | s3
|
|
# path = "/var/lib/rustbox/blobs" # defaults to data_dir for filesystem
|
|
shared = false # true only when every RustBox node sees the same filesystem
|
|
prefix = ""
|
|
# S3-compatible settings:
|
|
# bucket = "rustbox"
|
|
# region = "us-east-1"
|
|
# endpoint = "https://s3.example.com" # MinIO/Ceph RGW/etc. optional for AWS S3
|
|
# path_style = false
|
|
# allow_http = false
|
|
request_timeout_secs = 30
|
|
connect_timeout_secs = 5
|
|
max_retries = 3
|
|
retry_timeout_secs = 60
|
|
# access_key_id = "..." # AWS_* environment variables are also supported
|
|
# secret_access_key = "..."
|
|
# server_side_encryption = "AES256" # or "aws:kms"
|
|
# kms_key_id = "..."
|
|
|
|
# Periodic IMAP reconciliation. Active folders still use IMAP IDLE; this is the
|
|
# background/fallback cadence for folder counters, flags, new headers in other
|
|
# folders, and the automatic deep-index pass. Lower values improve convergence but
|
|
# increase IMAP traffic and mail-server load.
|
|
[sync]
|
|
interval_secs = 30
|
|
# Maximum full message bodies downloaded from IMAP per periodic pass when deep index
|
|
# is effective. Larger batches catch up faster at the cost of network traffic,
|
|
# application-database/search-storage usage and indexing CPU/I/O.
|
|
deep_index_batch_size = 10
|
|
|
|
# Search is independent from blob storage. Local Tantivy is single-node only.
|
|
[search]
|
|
backend = "local_tantivy" # disabled | local_tantivy | opensearch
|
|
# path = "/var/lib/rustbox/search" # defaults to data_dir for local_tantivy
|
|
# urls = ["https://opensearch.example.com:9200"]
|
|
index_prefix = "rustbox"
|
|
required = false
|
|
allow_insecure_http = false
|
|
request_timeout_secs = 10
|
|
# Server-wide automatic full-body cache/index switch. When true, RustBox proactively
|
|
# downloads message bodies from IMAP and indexes them for every account, up to
|
|
# sync.deep_index_batch_size per sync pass. This increases IMAP traffic,
|
|
# application-database/search-storage usage and indexing load. Production default
|
|
# is false. When false,
|
|
# the existing per-account deep_index preference may still opt an account in.
|
|
deep_index = false
|
|
# Search outbox worker cadence/batch; these do NOT control IMAP body downloads.
|
|
worker_interval_secs = 2
|
|
worker_batch_size = 100
|
|
worker_max_attempts = 8
|
|
# username = "rustbox"
|
|
# password = "..."
|
|
|
|
|
|
# RustBox 0.2 blob/search backends
|
|
# Blob storage is independent from the SQL database. PostgreSQL/MySQL can still use
|
|
# local filesystem storage in single-node mode. In cluster mode use S3-compatible
|
|
# storage or a genuinely shared POSIX filesystem (NFS/CephFS/GlusterFS).
|
|
|
|
# Built-in CalDAV / CardDAV server. Disabled by default.
|
|
# Every account gets one calendar and one address book, backed by the same tables
|
|
# as the webmail calendar and contacts:
|
|
# https://mail.example.com/dav/calendars/<login>/default/
|
|
# https://mail.example.com/dav/addressbooks/<login>/default/
|
|
# Clients may also start from https://mail.example.com/dav/ or rely on
|
|
# /.well-known/caldav and /.well-known/carddav. Authentication is HTTP Basic with
|
|
# the IMAP login and password (checked against imap_host, brute-force protected by
|
|
# [login_rate_limit]). Serve RustBox over HTTPS when this is enabled.
|
|
# Environment overrides: DAV__ENABLED=true, DAV__AUTH_CACHE_SECS=300, ...
|
|
[dav]
|
|
enabled = false
|
|
# Seconds a successful Basic login is remembered before IMAP is asked again
|
|
# (DAV clients authenticate on every request). 0 disables the cache.
|
|
auth_cache_secs = 300
|
|
# Largest accepted calendar object / vCard (bytes).
|
|
max_resource_size = 8388608
|
|
# Display names of the collections.
|
|
calendar_name = "Calendar"
|
|
addressbook_name = "Contacts"
|
|
|
|
# Administrator-only system diagnostics endpoint. Disabled by default.
|
|
# When enabled it exposes a redacted runtime/configuration report plus live probes
|
|
# for SQL, session persistence (database/Redis), blob storage (filesystem/S3),
|
|
# search (Tantivy/OpenSearch), IMAP IDLE counters and security telemetry.
|
|
# Access requires BOTH an allowed source network and the configured auth method.
|
|
# Secrets (passwords, tokens, S3 keys, session keys and URL credentials) are never returned.
|
|
[diagnostics_endpoint]
|
|
enabled = false
|
|
path = "/api/system/diagnostics"
|
|
# Default/fail-safe allowlist: only this host. Add trusted LAN/pod/monitoring CIDRs explicitly.
|
|
allowed_networks = ["127.0.0.1/32", "::1/128"]
|
|
# token | basic. Credentials should normally come from .env / secret manager, not TOML.
|
|
auth = "token"
|
|
# token = "replace-with-at-least-24-random-characters"
|
|
# basic_username = "rustbox-monitor"
|
|
# basic_password = "replace-with-a-long-random-password"
|
|
# E-mail addresses and stable user hashes are omitted by default; aggregate counts remain available.
|
|
include_user_identifiers = false
|
|
# Timeout applied independently to database/session/storage/search probes.
|
|
probe_timeout_secs = 5
|
|
# Rolling in-memory window used for login failures, 403, 429 and 5xx attack/problem signals.
|
|
security_window_secs = 900
|