Configuration File
rmail reads config.json from the working directory on startup. Generate a default file with all options:
python run.py init
An alternative path can be passed directly:
python run.py /etc/rmail/config.json
All values have defaults. Missing keys fall back to the default silently. Invalid values (wrong type or out of range) emit a warning and fall back to the default.
Top-Level
| Key | Default | Description |
|---|---|---|
hostname | mail.example.com | Server FQDN. Used in SMTP banners, EHLO, DSN bounces, autoconfig. |
mail_root | ./mailstore | Root directory for all mail storage. |
domains | ["example.com"] | List of locally hosted domains. SMTP accepts recipients in these domains. |
log_level | INFO | Logging verbosity: DEBUG, INFO, WARNING, ERROR, CRITICAL. |
SMTP
| Key | Default | Description |
|---|---|---|
smtp.host | 0.0.0.0 | Bind address for all SMTP ports. |
smtp.port | 25 | Standard SMTP port (inbound from other mail servers). |
smtp.submission_port | 587 | Authenticated submission port. |
smtp.smtps_port | 465 | SMTPS port (implicit TLS). |
smtp.max_recipients | 50 | Maximum RCPT TO per message. |
smtp.max_connections | 100 | Maximum simultaneous SMTP connections across all ports. |
smtp.max_messages_per_connection | 50 | Maximum messages sent per persistent connection. |
smtp.max_message_size | 52428800 | Maximum message size in bytes (50 MiB). |
IMAP
| Key | Default | Description |
|---|---|---|
imap.host | 0.0.0.0 | Bind address. |
imap.port | 143 | IMAP port. |
imap.imaps_port | 993 | IMAPS port (implicit TLS). |
imap.max_connections | 100 | Maximum simultaneous IMAP connections. |
Exchange API
| Key | Default | Description |
|---|---|---|
exchange_api.host | 0.0.0.0 | Bind address. |
exchange_api.port | 9002 | HTTP API port. |
exchange_api.secure_port | 9003 | HTTPS API port (implicit TLS). |
exchange_api.token_secret | auto-generated | HMAC-SHA256 key for JWT tokens. Auto-generated and written to config on first start if null. |
Delivery
| Key | Default | Description |
|---|---|---|
delivery.workers | 4 | Async worker count for the local delivery queue. |
delivery.max_queue_size | 1000 | Maximum messages in the local delivery queue. 0 = unlimited. |
Outbound Relay
Relay only applies to authenticated users. Unauthenticated senders to external domains are always rejected regardless of this configuration.
| Key | Default | Description |
|---|---|---|
relay.enabled | true | Allow authenticated users to send to external domains. |
relay.workers | 2 | Async worker count for the relay queue. |
relay.max_queue_size | 500 | Maximum messages in the relay queue. 0 = unlimited. |
relay.connect_timeout | 30 | TCP connect timeout in seconds for outbound connections. |
relay.command_timeout | 60 | Timeout in seconds for individual SMTP commands. |
relay.data_timeout | 300 | Timeout in seconds for DATA transmission. |
relay.max_retries | 8 | Total delivery attempts before generating a DSN bounce. |
relay.smarthost | "" | Smarthost address. Empty string = direct MX delivery. |
relay.smarthost_port | 587 | Smarthost port. |
relay.smarthost_username | "" | AUTH PLAIN username for smarthost. Empty = no authentication. |
relay.smarthost_password | "" | AUTH PLAIN password for smarthost. |
Retry schedule (delays between attempts): 1m, 5m, 15m, 30m, 1h, 4h, 8h, 24h. Total window approximately 37.5 hours.
TLS
| Key | Default | Description |
|---|---|---|
tls.cert_file | null | Path to PEM certificate. If null, a self-signed cert is auto-generated at {mail_root}/tls/cert.pem. |
tls.key_file | null | Path to PEM private key. If null, auto-generated at {mail_root}/tls/key.pem. |
When TLS is configured, AUTH mechanisms are hidden from cleartext EHLO/CAPABILITY responses. Clients must perform STARTTLS before credentials are accepted. Auto-generated certificates are self-signed and will trigger warnings in strict clients.
Rate Limiting
| Key | Default | Description |
|---|---|---|
rate_limit.enabled | true | Enable per-IP rate limiting. |
rate_limit.connection_rate | 20 | New connections allowed per IP per connection_period. |
rate_limit.connection_period | 60 | Window in seconds for connection rate tracking. |
rate_limit.message_rate | 30 | Messages allowed per IP per message_period. |
rate_limit.message_period | 60 | Window in seconds for message rate tracking. |
rate_limit.recipient_rate | 100 | RCPT TO commands allowed per IP per recipient_period. |
rate_limit.recipient_period | 60 | Window in seconds for recipient rate tracking. |
rate_limit.auth_failure_limit | 5 | Auth failures before IP lockout. |
rate_limit.auth_failure_lockout | 600 | Lockout duration in seconds after exceeding auth failure limit. |
rate_limit.max_concurrent_per_ip | 10 | Maximum simultaneous connections per IP. |
rate_limit.whitelist | ["127.0.0.1","::1"] | IPs exempt from all rate limiting. |
rate_limit.max_tracked_ips | 10000 | Maximum IPs tracked in memory. |
rate_limit.cleanup_interval | 300 | Seconds between cleanup sweeps of expired tracking entries. |
Minimal Production Example
{
"hostname": "mail.yourdomain.com",
"mail_root": "/var/mail/rmail",
"domains": ["yourdomain.com"],
"log_level": "INFO",
"smtp": {
"max_message_size": 52428800
},
"relay": {
"enabled": true,
"workers": 2
},
"tls": {
"cert_file": "/etc/ssl/certs/mail.pem",
"key_file": "/etc/ssl/private/mail.key"
},
"rate_limit": {
"enabled": true,
"whitelist": ["127.0.0.1", "::1"]
}
}