2023-01-30 16:27:06 +03:00
|
|
|
/*
|
|
|
|
Package config holds the configuration file definitions for mox.conf (Static)
|
|
|
|
and domains.conf (Dynamic).
|
|
|
|
|
2023-03-10 13:42:50 +03:00
|
|
|
These config files are in "sconf" format. Summarized: Indent with tabs, "#" as
|
|
|
|
first non-whitespace character makes the line a comment (you cannot have a line
|
|
|
|
with both a value and a comment), strings are not quoted/escaped and can never
|
|
|
|
span multiple lines. See https://pkg.go.dev/github.com/mjl-/sconf for details.
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
Annotated empty/default configuration files you could use as a starting point
|
|
|
|
for your mox.conf and domains.conf, as generated by "mox config
|
|
|
|
describe-static" and "mox config describe-domains":
|
|
|
|
|
|
|
|
# mox.conf
|
|
|
|
|
2023-09-21 09:59:10 +03:00
|
|
|
# NOTE: This config file is in 'sconf' format. Indent with tabs. Comments must be
|
|
|
|
# on their own line, they don't end a line. Do not escape or quote strings.
|
|
|
|
# Details: https://pkg.go.dev/github.com/mjl-/sconf.
|
|
|
|
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# Directory where all data is stored, e.g. queue, accounts and messages, ACME TLS
|
|
|
|
# certs/keys. If this is a relative path, it is relative to the directory of
|
|
|
|
# mox.conf.
|
|
|
|
DataDir:
|
|
|
|
|
2023-02-03 22:33:19 +03:00
|
|
|
# Default log level, one of: error, info, debug, trace, traceauth, tracedata.
|
|
|
|
# Trace logs SMTP and IMAP protocol transcripts, with traceauth also messages with
|
|
|
|
# passwords, and tracedata on top of that also the full data exchanges (full
|
|
|
|
# messages), which can be a large amount of data.
|
2023-01-30 16:27:06 +03:00
|
|
|
LogLevel:
|
|
|
|
|
|
|
|
# Overrides of log level per package (e.g. queue, smtpclient, smtpserver,
|
|
|
|
# imapserver, spf, dkim, dmarc, dmarcdb, autotls, junk, mtasts, tlsrpt).
|
|
|
|
# (optional)
|
|
|
|
PackageLogLevels:
|
|
|
|
x:
|
|
|
|
|
change mox to start as root, bind to network sockets, then drop to regular unprivileged mox user
makes it easier to run on bsd's, where you cannot (easily?) let non-root users
bind to ports <1024. starting as root also paves the way for future improvements
with privilege separation.
unfortunately, this requires changes to how you start mox. though mox will help
by automatically fix up dir/file permissions/ownership.
if you start mox from the systemd unit file, you should update it so it starts
as root and adds a few additional capabilities:
# first update the mox binary, then, as root:
./mox config printservice >mox.service
systemctl daemon-reload
systemctl restart mox
journalctl -f -u mox &
# you should see mox start up, with messages about fixing permissions on dirs/files.
if you used the recommended config/ and data/ directory, in a directory just for
mox, and with the mox user called "mox", this should be enough.
if you don't want mox to modify dir/file permissions, set "NoFixPermissions:
true" in mox.conf.
if you named the mox user something else than mox, e.g. "_mox", add "User: _mox"
to mox.conf.
if you created a shared service user as originally suggested, you may want to
get rid of that as it is no longer useful and may get in the way. e.g. if you
had /home/service/mox with a "service" user, that service user can no longer
access any files: only mox and root can.
this also adds scripts for building mox docker images for alpine-supported
platforms.
the "restart" subcommand has been removed. it wasn't all that useful and got in
the way.
and another change: when adding a domain while mtasts isn't enabled, don't add
the per-domain mtasts config, as it would cause failure to add the domain.
based on report from setting up mox on openbsd from mteege.
and based on issue #3. thanks for the feedback!
2023-02-27 14:19:55 +03:00
|
|
|
# User to switch to after binding to all sockets as root. Default: mox. If the
|
|
|
|
# value is not a known user, it is parsed as integer and used as uid and gid.
|
|
|
|
# (optional)
|
|
|
|
User:
|
|
|
|
|
|
|
|
# If true, do not automatically fix file permissions when starting up. By default,
|
|
|
|
# mox will ensure reasonable owner/permissions on the working, data and config
|
|
|
|
# directories (and files), and mox binary (if present). (optional)
|
|
|
|
NoFixPermissions: false
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# Full hostname of system, e.g. mail.<domain>
|
|
|
|
Hostname:
|
|
|
|
|
|
|
|
# If enabled, a single DNS TXT lookup of _updates.xmox.nl is done every 24h to
|
|
|
|
# check for a new release. Each time a new release is found, a changelog is
|
2023-08-23 15:27:21 +03:00
|
|
|
# fetched from https://updates.xmox.nl/changelog and delivered to the postmaster
|
|
|
|
# mailbox. (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
CheckUpdates: false
|
|
|
|
|
2023-03-12 17:16:01 +03:00
|
|
|
# In pedantic mode protocol violations (that happen in the wild) for SMTP/IMAP/etc
|
|
|
|
# result in errors instead of accepting such behaviour. (optional)
|
|
|
|
Pedantic: false
|
|
|
|
|
2023-03-10 18:25:18 +03:00
|
|
|
# Global TLS configuration, e.g. for additional Certificate Authorities. Used for
|
|
|
|
# outgoing SMTP connections, HTTPS requests. (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
TLS:
|
|
|
|
|
|
|
|
# (optional)
|
|
|
|
CA:
|
|
|
|
|
|
|
|
# (optional)
|
|
|
|
AdditionalToSystem: false
|
|
|
|
|
|
|
|
# (optional)
|
|
|
|
CertFiles:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Automatic TLS configuration with ACME, e.g. through Let's Encrypt. The key is a
|
|
|
|
# name referenced in TLS configs, e.g. letsencrypt. (optional)
|
|
|
|
ACME:
|
|
|
|
x:
|
|
|
|
|
|
|
|
# For letsencrypt, use https://acme-v02.api.letsencrypt.org/directory.
|
|
|
|
DirectoryURL:
|
|
|
|
|
|
|
|
# How long before expiration to renew the certificate. Default is 30 days.
|
|
|
|
# (optional)
|
|
|
|
RenewBefore: 0s
|
|
|
|
|
|
|
|
# Email address to register at ACME provider. The provider can email you when
|
|
|
|
# certificates are about to expire. If you configure an address for which email is
|
|
|
|
# delivered by this server, keep in mind that TLS misconfigurations could result
|
|
|
|
# in such notification emails not arriving.
|
|
|
|
ContactEmail:
|
|
|
|
|
2023-02-18 18:53:06 +03:00
|
|
|
# TLS port for ACME validation, 443 by default. You should only override this if
|
|
|
|
# you cannot listen on port 443 directly. ACME will make requests to port 443, so
|
|
|
|
# you'll have to add an external mechanism to get the connection here, e.g. by
|
|
|
|
# configuring port forwarding. (optional)
|
|
|
|
Port: 0
|
|
|
|
|
2023-12-21 17:16:30 +03:00
|
|
|
# If set, used for suggested CAA DNS records, for restricting TLS certificate
|
|
|
|
# issuance to a Certificate Authority. If empty and DirectyURL is for Let's
|
|
|
|
# Encrypt, this value is set automatically to letsencrypt.org. (optional)
|
|
|
|
IssuerDomainName:
|
|
|
|
|
2023-12-22 12:34:55 +03:00
|
|
|
# ACME providers can require that a request for a new ACME account reference an
|
|
|
|
# existing non-ACME account known to the provider. External account binding
|
|
|
|
# references that account by a key id, and authorizes new ACME account requests by
|
|
|
|
# signing it with a key known both by the ACME client and ACME provider.
|
|
|
|
# (optional)
|
|
|
|
ExternalAccountBinding:
|
|
|
|
|
|
|
|
# Key identifier, from ACME provider.
|
|
|
|
KeyID:
|
|
|
|
|
|
|
|
# File containing the base64url-encoded key used to sign account requests with
|
|
|
|
# external account binding. The ACME provider will verify the account request is
|
|
|
|
# correctly signed by the key. File is evaluated relative to the directory of
|
|
|
|
# mox.conf.
|
|
|
|
KeyFile:
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# File containing hash of admin password, for authentication in the web admin
|
|
|
|
# pages (if enabled). (optional)
|
|
|
|
AdminPasswordFile:
|
|
|
|
|
|
|
|
# Listeners are groups of IP addresses and services enabled on those IP addresses,
|
|
|
|
# such as SMTP/IMAP or internal endpoints for administration or Prometheus
|
|
|
|
# metrics. All listeners with SMTP/IMAP services enabled will serve all configured
|
2023-03-05 18:22:23 +03:00
|
|
|
# domains. If the listener is named 'public', it will get a few helpful additional
|
|
|
|
# configuration checks, for acme automatic tls certificates and monitoring of ips
|
|
|
|
# in dnsbls if those are configured.
|
2023-01-30 16:27:06 +03:00
|
|
|
Listeners:
|
|
|
|
x:
|
|
|
|
|
2023-03-05 17:40:26 +03:00
|
|
|
# Use 0.0.0.0 to listen on all IPv4 and/or :: to listen on all IPv6 addresses, but
|
|
|
|
# it is better to explicitly specify the IPs you want to use for email, as mox
|
|
|
|
# will make sure outgoing connections will only be made from one of those IPs.
|
2023-01-30 16:27:06 +03:00
|
|
|
IPs:
|
|
|
|
-
|
|
|
|
|
2023-08-11 11:13:17 +03:00
|
|
|
# If set, the mail server is configured behind a NAT and field IPs are internal
|
|
|
|
# instead of the public IPs, while NATIPs lists the public IPs. Used during
|
|
|
|
# IP-related DNS self-checks, such as for iprev, mx, spf, autoconfig,
|
|
|
|
# autodiscover, and for autotls. (optional)
|
|
|
|
NATIPs:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Deprecated, use NATIPs instead. If set, IPs are not the public IPs, but are
|
|
|
|
# NATed. Skips IP-related DNS self-checks. (optional)
|
2023-03-09 17:24:06 +03:00
|
|
|
IPsNATed: false
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# If empty, the config global Hostname is used. (optional)
|
|
|
|
Hostname:
|
|
|
|
|
|
|
|
# For SMTP/IMAP STARTTLS, direct TLS and HTTPS connections. (optional)
|
|
|
|
TLS:
|
|
|
|
|
|
|
|
# Name of provider from top-level configuration to use for ACME, e.g. letsencrypt.
|
|
|
|
# (optional)
|
|
|
|
ACME:
|
|
|
|
|
implement dnssec-awareness throughout code, and dane for incoming/outgoing mail delivery
the vendored dns resolver code is a copy of the go stdlib dns resolver, with
awareness of the "authentic data" (i.e. dnssec secure) added, as well as support
for enhanced dns errors, and looking up tlsa records (for dane). ideally it
would be upstreamed, but the chances seem slim.
dnssec-awareness is added to all packages, e.g. spf, dkim, dmarc, iprev. their
dnssec status is added to the Received message headers for incoming email.
but the main reason to add dnssec was for implementing dane. with dane, the
verification of tls certificates can be done through certificates/public keys
published in dns (in the tlsa records). this only makes sense (is trustworthy)
if those dns records can be verified to be authentic.
mox now applies dane to delivering messages over smtp. mox already implemented
mta-sts for webpki/pkix-verification of certificates against the (large) pool
of CA's, and still enforces those policies when present. but it now also checks
for dane records, and will verify those if present. if dane and mta-sts are
both absent, the regular opportunistic tls with starttls is still done. and the
fallback to plaintext is also still done.
mox also makes it easy to setup dane for incoming deliveries, so other servers
can deliver with dane tls certificate verification. the quickstart now
generates private keys that are used when requesting certificates with acme.
the private keys are pre-generated because they must be static and known during
setup, because their public keys must be published in tlsa records in dns.
autocert would generate private keys on its own, so had to be forked to add the
option to provide the private key when requesting a new certificate. hopefully
upstream will accept the change and we can drop the fork.
with this change, using the quickstart to setup a new mox instance, the checks
at internet.nl result in a 100% score, provided the domain is dnssec-signed and
the network doesn't have any issues.
2023-10-10 13:09:35 +03:00
|
|
|
# Keys and certificates to use for this listener. The files are opened by the
|
|
|
|
# privileged root process and passed to the unprivileged mox process, so no
|
|
|
|
# special permissions are required on the files. If the private key will not be
|
|
|
|
# replaced when refreshing certificates, also consider adding the private key to
|
|
|
|
# HostPrivateKeyFiles and configuring DANE TLSA DNS records. (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
KeyCerts:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Certificate including intermediate CA certificates, in PEM format.
|
|
|
|
CertFile:
|
|
|
|
|
|
|
|
# Private key for certificate, in PEM format. PKCS8 is recommended, but PKCS1 and
|
|
|
|
# EC private keys are recognized as well.
|
|
|
|
KeyFile:
|
|
|
|
|
|
|
|
# Minimum TLS version. Default: TLSv1.2. (optional)
|
|
|
|
MinVersion:
|
|
|
|
|
implement dnssec-awareness throughout code, and dane for incoming/outgoing mail delivery
the vendored dns resolver code is a copy of the go stdlib dns resolver, with
awareness of the "authentic data" (i.e. dnssec secure) added, as well as support
for enhanced dns errors, and looking up tlsa records (for dane). ideally it
would be upstreamed, but the chances seem slim.
dnssec-awareness is added to all packages, e.g. spf, dkim, dmarc, iprev. their
dnssec status is added to the Received message headers for incoming email.
but the main reason to add dnssec was for implementing dane. with dane, the
verification of tls certificates can be done through certificates/public keys
published in dns (in the tlsa records). this only makes sense (is trustworthy)
if those dns records can be verified to be authentic.
mox now applies dane to delivering messages over smtp. mox already implemented
mta-sts for webpki/pkix-verification of certificates against the (large) pool
of CA's, and still enforces those policies when present. but it now also checks
for dane records, and will verify those if present. if dane and mta-sts are
both absent, the regular opportunistic tls with starttls is still done. and the
fallback to plaintext is also still done.
mox also makes it easy to setup dane for incoming deliveries, so other servers
can deliver with dane tls certificate verification. the quickstart now
generates private keys that are used when requesting certificates with acme.
the private keys are pre-generated because they must be static and known during
setup, because their public keys must be published in tlsa records in dns.
autocert would generate private keys on its own, so had to be forked to add the
option to provide the private key when requesting a new certificate. hopefully
upstream will accept the change and we can drop the fork.
with this change, using the quickstart to setup a new mox instance, the checks
at internet.nl result in a 100% score, provided the domain is dnssec-signed and
the network doesn't have any issues.
2023-10-10 13:09:35 +03:00
|
|
|
# Private keys used for ACME certificates. Specified explicitly so DANE TLSA DNS
|
|
|
|
# records can be generated, even before the certificates are requested. DANE is a
|
|
|
|
# mechanism to authenticate remote TLS certificates based on a public key or
|
|
|
|
# certificate specified in DNS, protected with DNSSEC. DANE is opportunistic and
|
|
|
|
# attempted when delivering SMTP with STARTTLS. The private key files must be in
|
|
|
|
# PEM format. PKCS8 is recommended, but PKCS1 and EC private keys are recognized
|
|
|
|
# as well. Only RSA 2048 bit and ECDSA P-256 keys are currently used. The first of
|
|
|
|
# each is used when requesting new certificates through ACME. (optional)
|
|
|
|
HostPrivateKeyFiles:
|
|
|
|
-
|
|
|
|
|
add webmail
it was far down on the roadmap, but implemented earlier, because it's
interesting, and to help prepare for a jmap implementation. for jmap we need to
implement more client-like functionality than with just imap. internal data
structures need to change. jmap has lots of other requirements, so it's already
a big project. by implementing a webmail now, some of the required data
structure changes become clear and can be made now, so the later jmap
implementation can do things similarly to the webmail code. the webmail
frontend and webmail are written together, making their interface/api much
smaller and simpler than jmap.
one of the internal changes is that we now keep track of per-mailbox
total/unread/unseen/deleted message counts and mailbox sizes. keeping this
data consistent after any change to the stored messages (through the code base)
is tricky, so mox now has a consistency check that verifies the counts are
correct, which runs only during tests, each time an internal account reference
is closed. we have a few more internal "changes" that are propagated for the
webmail frontend (that imap doesn't have a way to propagate on a connection),
like changes to the special-use flags on mailboxes, and used keywords in a
mailbox. more changes that will be required have revealed themselves while
implementing the webmail, and will be implemented next.
the webmail user interface is modeled after the mail clients i use or have
used: thunderbird, macos mail, mutt; and webmails i normally only use for
testing: gmail, proton, yahoo, outlook. a somewhat technical user is assumed,
but still the goal is to make this webmail client easy to use for everyone. the
user interface looks like most other mail clients: a list of mailboxes, a
search bar, a message list view, and message details. there is a top/bottom and
a left/right layout for the list/message view, default is automatic based on
screen size. the panes can be resized by the user. buttons for actions are just
text, not icons. clicking a button briefly shows the shortcut for the action in
the bottom right, helping with learning to operate quickly. any text that is
underdotted has a title attribute that causes more information to be displayed,
e.g. what a button does or a field is about. to highlight potential phishing
attempts, any text (anywhere in the webclient) that switches unicode "blocks"
(a rough approximation to (language) scripts) within a word is underlined
orange. multiple messages can be selected with familiar ui interaction:
clicking while holding control and/or shift keys. keyboard navigation works
with arrows/page up/down and home/end keys, and also with a few basic vi-like
keys for list/message navigation. we prefer showing the text instead of
html (with inlined images only) version of a message. html messages are shown
in an iframe served from an endpoint with CSP headers to prevent dangerous
resources (scripts, external images) from being loaded. the html is also
sanitized, with javascript removed. a user can choose to load external
resources (e.g. images for tracking purposes).
the frontend is just (strict) typescript, no external frameworks. all
incoming/outgoing data is typechecked, both the api request parameters and
response types, and the data coming in over SSE. the types and checking code
are generated with sherpats, which uses the api definitions generated by
sherpadoc based on the Go code. so types from the backend are automatically
propagated to the frontend. since there is no framework to automatically
propagate properties and rerender components, changes coming in over the SSE
connection are propagated explicitly with regular function calls. the ui is
separated into "views", each with a "root" dom element that is added to the
visible document. these views have additional functions for getting changes
propagated, often resulting in the view updating its (internal) ui state (dom).
we keep the frontend compilation simple, it's just a few typescript files that
get compiled (combined and types stripped) into a single js file, no additional
runtime code needed or complicated build processes used. the webmail is served
is served from a compressed, cachable html file that includes style and the
javascript, currently just over 225kb uncompressed, under 60kb compressed (not
minified, including comments). we include the generated js files in the
repository, to keep Go's easily buildable self-contained binaries.
authentication is basic http, as with the account and admin pages. most data
comes in over one long-term SSE connection to the backend. api requests signal
which mailbox/search/messages are requested over the SSE connection. fetching
individual messages, and making changes, are done through api calls. the
operations are similar to imap, so some code has been moved from package
imapserver to package store. the future jmap implementation will benefit from
these changes too. more functionality will probably be moved to the store
package in the future.
the quickstart enables webmail on the internal listener by default (for new
installs). users can enable it on the public listener if they want to. mox
localserve enables it too. to enable webmail on existing installs, add settings
like the following to the listeners in mox.conf, similar to AccountHTTP(S):
WebmailHTTP:
Enabled: true
WebmailHTTPS:
Enabled: true
special thanks to liesbeth, gerben, andrii for early user feedback.
there is plenty still to do, see the list at the top of webmail/webmail.ts.
feedback welcome as always.
2023-08-07 22:57:03 +03:00
|
|
|
# Maximum size in bytes for incoming and outgoing messages. Default is 100MB.
|
2023-01-30 16:27:06 +03:00
|
|
|
# (optional)
|
|
|
|
SMTPMaxMessageSize: 0
|
|
|
|
|
|
|
|
# (optional)
|
|
|
|
SMTP:
|
|
|
|
Enabled: false
|
|
|
|
|
|
|
|
# Default 25. (optional)
|
|
|
|
Port: 0
|
|
|
|
|
|
|
|
# Do not offer STARTTLS to secure the connection. Not recommended. (optional)
|
|
|
|
NoSTARTTLS: false
|
|
|
|
|
implement outgoing tls reports
we were already accepting, processing and displaying incoming tls reports. now
we start tracking TLS connection and security-policy-related errors for
outgoing message deliveries as well. we send reports once a day, to the
reporting addresses specified in TLSRPT records (rua) of a policy domain. these
reports are about MTA-STS policies and/or DANE policies, and about
STARTTLS-related failures.
sending reports is enabled by default, but can be disabled through setting
NoOutgoingTLSReports in mox.conf.
only at the end of the implementation process came the realization that the
TLSRPT policy domain for DANE (MX) hosts are separate from the TLSRPT policy
for the recipient domain, and that MTA-STS and DANE TLS/policy results are
typically delivered in separate reports. so MX hosts need their own TLSRPT
policies.
config for the per-host TLSRPT policy should be added to mox.conf for existing
installs, in field HostTLSRPT. it is automatically configured by quickstart for
new installs. with a HostTLSRPT config, the "dns records" and "dns check" admin
pages now suggest the per-host TLSRPT record. by creating that record, you're
requesting TLS reports about your MX host.
gathering all the TLS/policy results is somewhat tricky. the tentacles go
throughout the code. the positive result is that the TLS/policy-related code
had to be cleaned up a bit. for example, the smtpclient TLS modes now reflect
reality better, with independent settings about whether PKIX and/or DANE
verification has to be done, and/or whether verification errors have to be
ignored (e.g. for tls-required: no header). also, cached mtasts policies of
mode "none" are now cleaned up once the MTA-STS DNS record goes away.
2023-11-09 19:40:46 +03:00
|
|
|
# Do not accept incoming messages if STARTTLS is not active. Consider using in
|
|
|
|
# combination with an MTA-STS policy and/or DANE. A remote SMTP server may not
|
|
|
|
# support TLS and may not be able to deliver messages. Incoming messages for TLS
|
|
|
|
# reporting addresses ignore this setting and do not require TLS. (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
RequireSTARTTLS: false
|
|
|
|
|
implement "requiretls", rfc 8689
with requiretls, the tls verification mode/rules for email deliveries can be
changed by the sender/submitter. in two ways:
1. "requiretls" smtp extension to always enforce verified tls (with mta-sts or
dnssec+dane), along the entire delivery path until delivery into the final
destination mailbox (so entire transport is verified-tls-protected).
2. "tls-required: no" message header, to ignore any tls and tls verification
errors even if the recipient domain has a policy that requires tls verification
(mta-sts and/or dnssec+dane), allowing delivery of non-sensitive messages in
case of misconfiguration/interoperability issues (at least useful for sending
tls reports).
we enable requiretls by default (only when tls is active), for smtp and
submission. it can be disabled through the config.
for each delivery attempt, we now store (per recipient domain, in the account
of the sender) whether the smtp server supports starttls and requiretls. this
support is shown (after having sent a first message) in the webmail when
sending a message (the previous 3 bars under the address input field are now 5
bars, the first for starttls support, the last for requiretls support). when
all recipient domains for a message are known to implement requiretls,
requiretls is automatically selected for sending (instead of "default" tls
behaviour). users can also select the "fallback to insecure" to add the
"tls-required: no" header.
new metrics are added for insight into requiretls errors and (some, not yet
all) cases where tls-required-no ignored a tls/verification error.
the admin can change the requiretls status for messages in the queue. so with
default delivery attempts, when verified tls is required by failing, an admin
could potentially change the field to "tls-required: no"-behaviour.
messages received (over smtp) with the requiretls option, get a comment added
to their Received header line, just before "id", after "with".
2023-10-24 11:06:16 +03:00
|
|
|
# Do not announce the REQUIRETLS SMTP extension. Messages delivered using the
|
|
|
|
# REQUIRETLS extension should only be distributed onwards to servers also
|
|
|
|
# implementing the REQUIRETLS extension. In some situations, such as hosting
|
|
|
|
# mailing lists, this may not be feasible due to lack of support for the extension
|
|
|
|
# by mailing list subscribers. (optional)
|
|
|
|
NoRequireTLS: false
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# Addresses of DNS block lists for incoming messages. Block lists are only
|
|
|
|
# consulted for connections/messages without enough reputation to make an
|
|
|
|
# accept/reject decision. This prevents sending IPs of all communications to the
|
|
|
|
# block list provider. If any of the listed DNSBLs contains a requested IP
|
|
|
|
# address, the message is rejected as spam. The DNSBLs are checked for healthiness
|
|
|
|
# before use, at most once per 4 hours. Example DNSBLs: sbl.spamhaus.org,
|
2023-08-15 10:48:53 +03:00
|
|
|
# bl.spamcop.net. See https://www.spamhaus.org/sbl/ and https://www.spamcop.net/
|
|
|
|
# for more information and terms of use. (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
DNSBLs:
|
|
|
|
-
|
|
|
|
|
2023-07-01 15:24:28 +03:00
|
|
|
# Delay before accepting a message from a first-time sender for the destination
|
|
|
|
# account. Default: 15s. (optional)
|
|
|
|
FirstTimeSenderDelay: 0s
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# SMTP for submitting email, e.g. by email applications. Starts out in plain text,
|
|
|
|
# can be upgraded to TLS with the STARTTLS command. Prefer using Submissions which
|
|
|
|
# is always a TLS connection. (optional)
|
|
|
|
Submission:
|
|
|
|
Enabled: false
|
|
|
|
|
|
|
|
# Default 587. (optional)
|
|
|
|
Port: 0
|
|
|
|
|
|
|
|
# Do not require STARTTLS. Since users must login, this means password may be sent
|
|
|
|
# without encryption. Not recommended. (optional)
|
|
|
|
NoRequireSTARTTLS: false
|
|
|
|
|
|
|
|
# SMTP over TLS for submitting email, by email applications. Requires a TLS
|
|
|
|
# config. (optional)
|
|
|
|
Submissions:
|
|
|
|
Enabled: false
|
|
|
|
|
|
|
|
# Default 465. (optional)
|
|
|
|
Port: 0
|
|
|
|
|
|
|
|
# IMAP for reading email, by email applications. Starts out in plain text, can be
|
|
|
|
# upgraded to TLS with the STARTTLS command. Prefer using IMAPS instead which is
|
|
|
|
# always a TLS connection. (optional)
|
|
|
|
IMAP:
|
|
|
|
Enabled: false
|
|
|
|
|
|
|
|
# Default 143. (optional)
|
|
|
|
Port: 0
|
|
|
|
|
|
|
|
# Enable this only when the connection is otherwise encrypted (e.g. through a
|
|
|
|
# VPN). (optional)
|
|
|
|
NoRequireSTARTTLS: false
|
|
|
|
|
|
|
|
# IMAP over TLS for reading email, by email applications. Requires a TLS config.
|
|
|
|
# (optional)
|
|
|
|
IMAPS:
|
|
|
|
Enabled: false
|
|
|
|
|
|
|
|
# Default 993. (optional)
|
|
|
|
Port: 0
|
|
|
|
|
2023-02-13 15:53:47 +03:00
|
|
|
# Account web interface, for email users wanting to change their accounts, e.g.
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# set new password, set new delivery rulesets. Default path is /. (optional)
|
2023-02-13 15:53:47 +03:00
|
|
|
AccountHTTP:
|
|
|
|
Enabled: false
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# Default 80 for HTTP and 443 for HTTPS. (optional)
|
2023-02-13 15:53:47 +03:00
|
|
|
Port: 0
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# Path to serve requests on. (optional)
|
2023-03-12 13:52:15 +03:00
|
|
|
Path:
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# If set, X-Forwarded-* headers are used for the remote IP address for rate
|
|
|
|
# limiting and for the "secure" status of cookies. (optional)
|
|
|
|
Forwarded: false
|
|
|
|
|
|
|
|
# Account web interface listener like AccountHTTP, but for HTTPS. Requires a TLS
|
|
|
|
# config. (optional)
|
2023-02-13 15:53:47 +03:00
|
|
|
AccountHTTPS:
|
|
|
|
Enabled: false
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# Default 80 for HTTP and 443 for HTTPS. (optional)
|
2023-02-13 15:53:47 +03:00
|
|
|
Port: 0
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# Path to serve requests on. (optional)
|
2023-03-12 13:52:15 +03:00
|
|
|
Path:
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# If set, X-Forwarded-* headers are used for the remote IP address for rate
|
|
|
|
# limiting and for the "secure" status of cookies. (optional)
|
|
|
|
Forwarded: false
|
|
|
|
|
|
|
|
# Admin web interface, for managing domains, accounts, etc. Default path is
|
|
|
|
# /admin/. Preferably only enable on non-public IPs. Hint: use 'ssh -L
|
|
|
|
# 8080:localhost:80 you@yourmachine' and open http://localhost:8080/admin/, or set
|
|
|
|
# up a tunnel (e.g. WireGuard) and add its IP to the mox 'internal' listener.
|
|
|
|
# (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
AdminHTTP:
|
|
|
|
Enabled: false
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# Default 80 for HTTP and 443 for HTTPS. (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
Port: 0
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# Path to serve requests on. (optional)
|
2023-03-12 13:52:15 +03:00
|
|
|
Path:
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# If set, X-Forwarded-* headers are used for the remote IP address for rate
|
|
|
|
# limiting and for the "secure" status of cookies. (optional)
|
|
|
|
Forwarded: false
|
|
|
|
|
|
|
|
# Admin web interface listener like AdminHTTP, but for HTTPS. Requires a TLS
|
|
|
|
# config. (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
AdminHTTPS:
|
|
|
|
Enabled: false
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# Default 80 for HTTP and 443 for HTTPS. (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
Port: 0
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# Path to serve requests on. (optional)
|
2023-03-12 13:52:15 +03:00
|
|
|
Path:
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# If set, X-Forwarded-* headers are used for the remote IP address for rate
|
|
|
|
# limiting and for the "secure" status of cookies. (optional)
|
|
|
|
Forwarded: false
|
|
|
|
|
|
|
|
# Webmail client, for reading email. Default path is /webmail/. (optional)
|
add webmail
it was far down on the roadmap, but implemented earlier, because it's
interesting, and to help prepare for a jmap implementation. for jmap we need to
implement more client-like functionality than with just imap. internal data
structures need to change. jmap has lots of other requirements, so it's already
a big project. by implementing a webmail now, some of the required data
structure changes become clear and can be made now, so the later jmap
implementation can do things similarly to the webmail code. the webmail
frontend and webmail are written together, making their interface/api much
smaller and simpler than jmap.
one of the internal changes is that we now keep track of per-mailbox
total/unread/unseen/deleted message counts and mailbox sizes. keeping this
data consistent after any change to the stored messages (through the code base)
is tricky, so mox now has a consistency check that verifies the counts are
correct, which runs only during tests, each time an internal account reference
is closed. we have a few more internal "changes" that are propagated for the
webmail frontend (that imap doesn't have a way to propagate on a connection),
like changes to the special-use flags on mailboxes, and used keywords in a
mailbox. more changes that will be required have revealed themselves while
implementing the webmail, and will be implemented next.
the webmail user interface is modeled after the mail clients i use or have
used: thunderbird, macos mail, mutt; and webmails i normally only use for
testing: gmail, proton, yahoo, outlook. a somewhat technical user is assumed,
but still the goal is to make this webmail client easy to use for everyone. the
user interface looks like most other mail clients: a list of mailboxes, a
search bar, a message list view, and message details. there is a top/bottom and
a left/right layout for the list/message view, default is automatic based on
screen size. the panes can be resized by the user. buttons for actions are just
text, not icons. clicking a button briefly shows the shortcut for the action in
the bottom right, helping with learning to operate quickly. any text that is
underdotted has a title attribute that causes more information to be displayed,
e.g. what a button does or a field is about. to highlight potential phishing
attempts, any text (anywhere in the webclient) that switches unicode "blocks"
(a rough approximation to (language) scripts) within a word is underlined
orange. multiple messages can be selected with familiar ui interaction:
clicking while holding control and/or shift keys. keyboard navigation works
with arrows/page up/down and home/end keys, and also with a few basic vi-like
keys for list/message navigation. we prefer showing the text instead of
html (with inlined images only) version of a message. html messages are shown
in an iframe served from an endpoint with CSP headers to prevent dangerous
resources (scripts, external images) from being loaded. the html is also
sanitized, with javascript removed. a user can choose to load external
resources (e.g. images for tracking purposes).
the frontend is just (strict) typescript, no external frameworks. all
incoming/outgoing data is typechecked, both the api request parameters and
response types, and the data coming in over SSE. the types and checking code
are generated with sherpats, which uses the api definitions generated by
sherpadoc based on the Go code. so types from the backend are automatically
propagated to the frontend. since there is no framework to automatically
propagate properties and rerender components, changes coming in over the SSE
connection are propagated explicitly with regular function calls. the ui is
separated into "views", each with a "root" dom element that is added to the
visible document. these views have additional functions for getting changes
propagated, often resulting in the view updating its (internal) ui state (dom).
we keep the frontend compilation simple, it's just a few typescript files that
get compiled (combined and types stripped) into a single js file, no additional
runtime code needed or complicated build processes used. the webmail is served
is served from a compressed, cachable html file that includes style and the
javascript, currently just over 225kb uncompressed, under 60kb compressed (not
minified, including comments). we include the generated js files in the
repository, to keep Go's easily buildable self-contained binaries.
authentication is basic http, as with the account and admin pages. most data
comes in over one long-term SSE connection to the backend. api requests signal
which mailbox/search/messages are requested over the SSE connection. fetching
individual messages, and making changes, are done through api calls. the
operations are similar to imap, so some code has been moved from package
imapserver to package store. the future jmap implementation will benefit from
these changes too. more functionality will probably be moved to the store
package in the future.
the quickstart enables webmail on the internal listener by default (for new
installs). users can enable it on the public listener if they want to. mox
localserve enables it too. to enable webmail on existing installs, add settings
like the following to the listeners in mox.conf, similar to AccountHTTP(S):
WebmailHTTP:
Enabled: true
WebmailHTTPS:
Enabled: true
special thanks to liesbeth, gerben, andrii for early user feedback.
there is plenty still to do, see the list at the top of webmail/webmail.ts.
feedback welcome as always.
2023-08-07 22:57:03 +03:00
|
|
|
WebmailHTTP:
|
|
|
|
Enabled: false
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# Default 80 for HTTP and 443 for HTTPS. (optional)
|
add webmail
it was far down on the roadmap, but implemented earlier, because it's
interesting, and to help prepare for a jmap implementation. for jmap we need to
implement more client-like functionality than with just imap. internal data
structures need to change. jmap has lots of other requirements, so it's already
a big project. by implementing a webmail now, some of the required data
structure changes become clear and can be made now, so the later jmap
implementation can do things similarly to the webmail code. the webmail
frontend and webmail are written together, making their interface/api much
smaller and simpler than jmap.
one of the internal changes is that we now keep track of per-mailbox
total/unread/unseen/deleted message counts and mailbox sizes. keeping this
data consistent after any change to the stored messages (through the code base)
is tricky, so mox now has a consistency check that verifies the counts are
correct, which runs only during tests, each time an internal account reference
is closed. we have a few more internal "changes" that are propagated for the
webmail frontend (that imap doesn't have a way to propagate on a connection),
like changes to the special-use flags on mailboxes, and used keywords in a
mailbox. more changes that will be required have revealed themselves while
implementing the webmail, and will be implemented next.
the webmail user interface is modeled after the mail clients i use or have
used: thunderbird, macos mail, mutt; and webmails i normally only use for
testing: gmail, proton, yahoo, outlook. a somewhat technical user is assumed,
but still the goal is to make this webmail client easy to use for everyone. the
user interface looks like most other mail clients: a list of mailboxes, a
search bar, a message list view, and message details. there is a top/bottom and
a left/right layout for the list/message view, default is automatic based on
screen size. the panes can be resized by the user. buttons for actions are just
text, not icons. clicking a button briefly shows the shortcut for the action in
the bottom right, helping with learning to operate quickly. any text that is
underdotted has a title attribute that causes more information to be displayed,
e.g. what a button does or a field is about. to highlight potential phishing
attempts, any text (anywhere in the webclient) that switches unicode "blocks"
(a rough approximation to (language) scripts) within a word is underlined
orange. multiple messages can be selected with familiar ui interaction:
clicking while holding control and/or shift keys. keyboard navigation works
with arrows/page up/down and home/end keys, and also with a few basic vi-like
keys for list/message navigation. we prefer showing the text instead of
html (with inlined images only) version of a message. html messages are shown
in an iframe served from an endpoint with CSP headers to prevent dangerous
resources (scripts, external images) from being loaded. the html is also
sanitized, with javascript removed. a user can choose to load external
resources (e.g. images for tracking purposes).
the frontend is just (strict) typescript, no external frameworks. all
incoming/outgoing data is typechecked, both the api request parameters and
response types, and the data coming in over SSE. the types and checking code
are generated with sherpats, which uses the api definitions generated by
sherpadoc based on the Go code. so types from the backend are automatically
propagated to the frontend. since there is no framework to automatically
propagate properties and rerender components, changes coming in over the SSE
connection are propagated explicitly with regular function calls. the ui is
separated into "views", each with a "root" dom element that is added to the
visible document. these views have additional functions for getting changes
propagated, often resulting in the view updating its (internal) ui state (dom).
we keep the frontend compilation simple, it's just a few typescript files that
get compiled (combined and types stripped) into a single js file, no additional
runtime code needed or complicated build processes used. the webmail is served
is served from a compressed, cachable html file that includes style and the
javascript, currently just over 225kb uncompressed, under 60kb compressed (not
minified, including comments). we include the generated js files in the
repository, to keep Go's easily buildable self-contained binaries.
authentication is basic http, as with the account and admin pages. most data
comes in over one long-term SSE connection to the backend. api requests signal
which mailbox/search/messages are requested over the SSE connection. fetching
individual messages, and making changes, are done through api calls. the
operations are similar to imap, so some code has been moved from package
imapserver to package store. the future jmap implementation will benefit from
these changes too. more functionality will probably be moved to the store
package in the future.
the quickstart enables webmail on the internal listener by default (for new
installs). users can enable it on the public listener if they want to. mox
localserve enables it too. to enable webmail on existing installs, add settings
like the following to the listeners in mox.conf, similar to AccountHTTP(S):
WebmailHTTP:
Enabled: true
WebmailHTTPS:
Enabled: true
special thanks to liesbeth, gerben, andrii for early user feedback.
there is plenty still to do, see the list at the top of webmail/webmail.ts.
feedback welcome as always.
2023-08-07 22:57:03 +03:00
|
|
|
Port: 0
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# Path to serve requests on. (optional)
|
add webmail
it was far down on the roadmap, but implemented earlier, because it's
interesting, and to help prepare for a jmap implementation. for jmap we need to
implement more client-like functionality than with just imap. internal data
structures need to change. jmap has lots of other requirements, so it's already
a big project. by implementing a webmail now, some of the required data
structure changes become clear and can be made now, so the later jmap
implementation can do things similarly to the webmail code. the webmail
frontend and webmail are written together, making their interface/api much
smaller and simpler than jmap.
one of the internal changes is that we now keep track of per-mailbox
total/unread/unseen/deleted message counts and mailbox sizes. keeping this
data consistent after any change to the stored messages (through the code base)
is tricky, so mox now has a consistency check that verifies the counts are
correct, which runs only during tests, each time an internal account reference
is closed. we have a few more internal "changes" that are propagated for the
webmail frontend (that imap doesn't have a way to propagate on a connection),
like changes to the special-use flags on mailboxes, and used keywords in a
mailbox. more changes that will be required have revealed themselves while
implementing the webmail, and will be implemented next.
the webmail user interface is modeled after the mail clients i use or have
used: thunderbird, macos mail, mutt; and webmails i normally only use for
testing: gmail, proton, yahoo, outlook. a somewhat technical user is assumed,
but still the goal is to make this webmail client easy to use for everyone. the
user interface looks like most other mail clients: a list of mailboxes, a
search bar, a message list view, and message details. there is a top/bottom and
a left/right layout for the list/message view, default is automatic based on
screen size. the panes can be resized by the user. buttons for actions are just
text, not icons. clicking a button briefly shows the shortcut for the action in
the bottom right, helping with learning to operate quickly. any text that is
underdotted has a title attribute that causes more information to be displayed,
e.g. what a button does or a field is about. to highlight potential phishing
attempts, any text (anywhere in the webclient) that switches unicode "blocks"
(a rough approximation to (language) scripts) within a word is underlined
orange. multiple messages can be selected with familiar ui interaction:
clicking while holding control and/or shift keys. keyboard navigation works
with arrows/page up/down and home/end keys, and also with a few basic vi-like
keys for list/message navigation. we prefer showing the text instead of
html (with inlined images only) version of a message. html messages are shown
in an iframe served from an endpoint with CSP headers to prevent dangerous
resources (scripts, external images) from being loaded. the html is also
sanitized, with javascript removed. a user can choose to load external
resources (e.g. images for tracking purposes).
the frontend is just (strict) typescript, no external frameworks. all
incoming/outgoing data is typechecked, both the api request parameters and
response types, and the data coming in over SSE. the types and checking code
are generated with sherpats, which uses the api definitions generated by
sherpadoc based on the Go code. so types from the backend are automatically
propagated to the frontend. since there is no framework to automatically
propagate properties and rerender components, changes coming in over the SSE
connection are propagated explicitly with regular function calls. the ui is
separated into "views", each with a "root" dom element that is added to the
visible document. these views have additional functions for getting changes
propagated, often resulting in the view updating its (internal) ui state (dom).
we keep the frontend compilation simple, it's just a few typescript files that
get compiled (combined and types stripped) into a single js file, no additional
runtime code needed or complicated build processes used. the webmail is served
is served from a compressed, cachable html file that includes style and the
javascript, currently just over 225kb uncompressed, under 60kb compressed (not
minified, including comments). we include the generated js files in the
repository, to keep Go's easily buildable self-contained binaries.
authentication is basic http, as with the account and admin pages. most data
comes in over one long-term SSE connection to the backend. api requests signal
which mailbox/search/messages are requested over the SSE connection. fetching
individual messages, and making changes, are done through api calls. the
operations are similar to imap, so some code has been moved from package
imapserver to package store. the future jmap implementation will benefit from
these changes too. more functionality will probably be moved to the store
package in the future.
the quickstart enables webmail on the internal listener by default (for new
installs). users can enable it on the public listener if they want to. mox
localserve enables it too. to enable webmail on existing installs, add settings
like the following to the listeners in mox.conf, similar to AccountHTTP(S):
WebmailHTTP:
Enabled: true
WebmailHTTPS:
Enabled: true
special thanks to liesbeth, gerben, andrii for early user feedback.
there is plenty still to do, see the list at the top of webmail/webmail.ts.
feedback welcome as always.
2023-08-07 22:57:03 +03:00
|
|
|
Path:
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# If set, X-Forwarded-* headers are used for the remote IP address for rate
|
|
|
|
# limiting and for the "secure" status of cookies. (optional)
|
|
|
|
Forwarded: false
|
|
|
|
|
|
|
|
# Webmail client, like WebmailHTTP, but for HTTPS. Requires a TLS config.
|
|
|
|
# (optional)
|
add webmail
it was far down on the roadmap, but implemented earlier, because it's
interesting, and to help prepare for a jmap implementation. for jmap we need to
implement more client-like functionality than with just imap. internal data
structures need to change. jmap has lots of other requirements, so it's already
a big project. by implementing a webmail now, some of the required data
structure changes become clear and can be made now, so the later jmap
implementation can do things similarly to the webmail code. the webmail
frontend and webmail are written together, making their interface/api much
smaller and simpler than jmap.
one of the internal changes is that we now keep track of per-mailbox
total/unread/unseen/deleted message counts and mailbox sizes. keeping this
data consistent after any change to the stored messages (through the code base)
is tricky, so mox now has a consistency check that verifies the counts are
correct, which runs only during tests, each time an internal account reference
is closed. we have a few more internal "changes" that are propagated for the
webmail frontend (that imap doesn't have a way to propagate on a connection),
like changes to the special-use flags on mailboxes, and used keywords in a
mailbox. more changes that will be required have revealed themselves while
implementing the webmail, and will be implemented next.
the webmail user interface is modeled after the mail clients i use or have
used: thunderbird, macos mail, mutt; and webmails i normally only use for
testing: gmail, proton, yahoo, outlook. a somewhat technical user is assumed,
but still the goal is to make this webmail client easy to use for everyone. the
user interface looks like most other mail clients: a list of mailboxes, a
search bar, a message list view, and message details. there is a top/bottom and
a left/right layout for the list/message view, default is automatic based on
screen size. the panes can be resized by the user. buttons for actions are just
text, not icons. clicking a button briefly shows the shortcut for the action in
the bottom right, helping with learning to operate quickly. any text that is
underdotted has a title attribute that causes more information to be displayed,
e.g. what a button does or a field is about. to highlight potential phishing
attempts, any text (anywhere in the webclient) that switches unicode "blocks"
(a rough approximation to (language) scripts) within a word is underlined
orange. multiple messages can be selected with familiar ui interaction:
clicking while holding control and/or shift keys. keyboard navigation works
with arrows/page up/down and home/end keys, and also with a few basic vi-like
keys for list/message navigation. we prefer showing the text instead of
html (with inlined images only) version of a message. html messages are shown
in an iframe served from an endpoint with CSP headers to prevent dangerous
resources (scripts, external images) from being loaded. the html is also
sanitized, with javascript removed. a user can choose to load external
resources (e.g. images for tracking purposes).
the frontend is just (strict) typescript, no external frameworks. all
incoming/outgoing data is typechecked, both the api request parameters and
response types, and the data coming in over SSE. the types and checking code
are generated with sherpats, which uses the api definitions generated by
sherpadoc based on the Go code. so types from the backend are automatically
propagated to the frontend. since there is no framework to automatically
propagate properties and rerender components, changes coming in over the SSE
connection are propagated explicitly with regular function calls. the ui is
separated into "views", each with a "root" dom element that is added to the
visible document. these views have additional functions for getting changes
propagated, often resulting in the view updating its (internal) ui state (dom).
we keep the frontend compilation simple, it's just a few typescript files that
get compiled (combined and types stripped) into a single js file, no additional
runtime code needed or complicated build processes used. the webmail is served
is served from a compressed, cachable html file that includes style and the
javascript, currently just over 225kb uncompressed, under 60kb compressed (not
minified, including comments). we include the generated js files in the
repository, to keep Go's easily buildable self-contained binaries.
authentication is basic http, as with the account and admin pages. most data
comes in over one long-term SSE connection to the backend. api requests signal
which mailbox/search/messages are requested over the SSE connection. fetching
individual messages, and making changes, are done through api calls. the
operations are similar to imap, so some code has been moved from package
imapserver to package store. the future jmap implementation will benefit from
these changes too. more functionality will probably be moved to the store
package in the future.
the quickstart enables webmail on the internal listener by default (for new
installs). users can enable it on the public listener if they want to. mox
localserve enables it too. to enable webmail on existing installs, add settings
like the following to the listeners in mox.conf, similar to AccountHTTP(S):
WebmailHTTP:
Enabled: true
WebmailHTTPS:
Enabled: true
special thanks to liesbeth, gerben, andrii for early user feedback.
there is plenty still to do, see the list at the top of webmail/webmail.ts.
feedback welcome as always.
2023-08-07 22:57:03 +03:00
|
|
|
WebmailHTTPS:
|
|
|
|
Enabled: false
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# Default 80 for HTTP and 443 for HTTPS. (optional)
|
add webmail
it was far down on the roadmap, but implemented earlier, because it's
interesting, and to help prepare for a jmap implementation. for jmap we need to
implement more client-like functionality than with just imap. internal data
structures need to change. jmap has lots of other requirements, so it's already
a big project. by implementing a webmail now, some of the required data
structure changes become clear and can be made now, so the later jmap
implementation can do things similarly to the webmail code. the webmail
frontend and webmail are written together, making their interface/api much
smaller and simpler than jmap.
one of the internal changes is that we now keep track of per-mailbox
total/unread/unseen/deleted message counts and mailbox sizes. keeping this
data consistent after any change to the stored messages (through the code base)
is tricky, so mox now has a consistency check that verifies the counts are
correct, which runs only during tests, each time an internal account reference
is closed. we have a few more internal "changes" that are propagated for the
webmail frontend (that imap doesn't have a way to propagate on a connection),
like changes to the special-use flags on mailboxes, and used keywords in a
mailbox. more changes that will be required have revealed themselves while
implementing the webmail, and will be implemented next.
the webmail user interface is modeled after the mail clients i use or have
used: thunderbird, macos mail, mutt; and webmails i normally only use for
testing: gmail, proton, yahoo, outlook. a somewhat technical user is assumed,
but still the goal is to make this webmail client easy to use for everyone. the
user interface looks like most other mail clients: a list of mailboxes, a
search bar, a message list view, and message details. there is a top/bottom and
a left/right layout for the list/message view, default is automatic based on
screen size. the panes can be resized by the user. buttons for actions are just
text, not icons. clicking a button briefly shows the shortcut for the action in
the bottom right, helping with learning to operate quickly. any text that is
underdotted has a title attribute that causes more information to be displayed,
e.g. what a button does or a field is about. to highlight potential phishing
attempts, any text (anywhere in the webclient) that switches unicode "blocks"
(a rough approximation to (language) scripts) within a word is underlined
orange. multiple messages can be selected with familiar ui interaction:
clicking while holding control and/or shift keys. keyboard navigation works
with arrows/page up/down and home/end keys, and also with a few basic vi-like
keys for list/message navigation. we prefer showing the text instead of
html (with inlined images only) version of a message. html messages are shown
in an iframe served from an endpoint with CSP headers to prevent dangerous
resources (scripts, external images) from being loaded. the html is also
sanitized, with javascript removed. a user can choose to load external
resources (e.g. images for tracking purposes).
the frontend is just (strict) typescript, no external frameworks. all
incoming/outgoing data is typechecked, both the api request parameters and
response types, and the data coming in over SSE. the types and checking code
are generated with sherpats, which uses the api definitions generated by
sherpadoc based on the Go code. so types from the backend are automatically
propagated to the frontend. since there is no framework to automatically
propagate properties and rerender components, changes coming in over the SSE
connection are propagated explicitly with regular function calls. the ui is
separated into "views", each with a "root" dom element that is added to the
visible document. these views have additional functions for getting changes
propagated, often resulting in the view updating its (internal) ui state (dom).
we keep the frontend compilation simple, it's just a few typescript files that
get compiled (combined and types stripped) into a single js file, no additional
runtime code needed or complicated build processes used. the webmail is served
is served from a compressed, cachable html file that includes style and the
javascript, currently just over 225kb uncompressed, under 60kb compressed (not
minified, including comments). we include the generated js files in the
repository, to keep Go's easily buildable self-contained binaries.
authentication is basic http, as with the account and admin pages. most data
comes in over one long-term SSE connection to the backend. api requests signal
which mailbox/search/messages are requested over the SSE connection. fetching
individual messages, and making changes, are done through api calls. the
operations are similar to imap, so some code has been moved from package
imapserver to package store. the future jmap implementation will benefit from
these changes too. more functionality will probably be moved to the store
package in the future.
the quickstart enables webmail on the internal listener by default (for new
installs). users can enable it on the public listener if they want to. mox
localserve enables it too. to enable webmail on existing installs, add settings
like the following to the listeners in mox.conf, similar to AccountHTTP(S):
WebmailHTTP:
Enabled: true
WebmailHTTPS:
Enabled: true
special thanks to liesbeth, gerben, andrii for early user feedback.
there is plenty still to do, see the list at the top of webmail/webmail.ts.
feedback welcome as always.
2023-08-07 22:57:03 +03:00
|
|
|
Port: 0
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# Path to serve requests on. (optional)
|
add webmail
it was far down on the roadmap, but implemented earlier, because it's
interesting, and to help prepare for a jmap implementation. for jmap we need to
implement more client-like functionality than with just imap. internal data
structures need to change. jmap has lots of other requirements, so it's already
a big project. by implementing a webmail now, some of the required data
structure changes become clear and can be made now, so the later jmap
implementation can do things similarly to the webmail code. the webmail
frontend and webmail are written together, making their interface/api much
smaller and simpler than jmap.
one of the internal changes is that we now keep track of per-mailbox
total/unread/unseen/deleted message counts and mailbox sizes. keeping this
data consistent after any change to the stored messages (through the code base)
is tricky, so mox now has a consistency check that verifies the counts are
correct, which runs only during tests, each time an internal account reference
is closed. we have a few more internal "changes" that are propagated for the
webmail frontend (that imap doesn't have a way to propagate on a connection),
like changes to the special-use flags on mailboxes, and used keywords in a
mailbox. more changes that will be required have revealed themselves while
implementing the webmail, and will be implemented next.
the webmail user interface is modeled after the mail clients i use or have
used: thunderbird, macos mail, mutt; and webmails i normally only use for
testing: gmail, proton, yahoo, outlook. a somewhat technical user is assumed,
but still the goal is to make this webmail client easy to use for everyone. the
user interface looks like most other mail clients: a list of mailboxes, a
search bar, a message list view, and message details. there is a top/bottom and
a left/right layout for the list/message view, default is automatic based on
screen size. the panes can be resized by the user. buttons for actions are just
text, not icons. clicking a button briefly shows the shortcut for the action in
the bottom right, helping with learning to operate quickly. any text that is
underdotted has a title attribute that causes more information to be displayed,
e.g. what a button does or a field is about. to highlight potential phishing
attempts, any text (anywhere in the webclient) that switches unicode "blocks"
(a rough approximation to (language) scripts) within a word is underlined
orange. multiple messages can be selected with familiar ui interaction:
clicking while holding control and/or shift keys. keyboard navigation works
with arrows/page up/down and home/end keys, and also with a few basic vi-like
keys for list/message navigation. we prefer showing the text instead of
html (with inlined images only) version of a message. html messages are shown
in an iframe served from an endpoint with CSP headers to prevent dangerous
resources (scripts, external images) from being loaded. the html is also
sanitized, with javascript removed. a user can choose to load external
resources (e.g. images for tracking purposes).
the frontend is just (strict) typescript, no external frameworks. all
incoming/outgoing data is typechecked, both the api request parameters and
response types, and the data coming in over SSE. the types and checking code
are generated with sherpats, which uses the api definitions generated by
sherpadoc based on the Go code. so types from the backend are automatically
propagated to the frontend. since there is no framework to automatically
propagate properties and rerender components, changes coming in over the SSE
connection are propagated explicitly with regular function calls. the ui is
separated into "views", each with a "root" dom element that is added to the
visible document. these views have additional functions for getting changes
propagated, often resulting in the view updating its (internal) ui state (dom).
we keep the frontend compilation simple, it's just a few typescript files that
get compiled (combined and types stripped) into a single js file, no additional
runtime code needed or complicated build processes used. the webmail is served
is served from a compressed, cachable html file that includes style and the
javascript, currently just over 225kb uncompressed, under 60kb compressed (not
minified, including comments). we include the generated js files in the
repository, to keep Go's easily buildable self-contained binaries.
authentication is basic http, as with the account and admin pages. most data
comes in over one long-term SSE connection to the backend. api requests signal
which mailbox/search/messages are requested over the SSE connection. fetching
individual messages, and making changes, are done through api calls. the
operations are similar to imap, so some code has been moved from package
imapserver to package store. the future jmap implementation will benefit from
these changes too. more functionality will probably be moved to the store
package in the future.
the quickstart enables webmail on the internal listener by default (for new
installs). users can enable it on the public listener if they want to. mox
localserve enables it too. to enable webmail on existing installs, add settings
like the following to the listeners in mox.conf, similar to AccountHTTP(S):
WebmailHTTP:
Enabled: true
WebmailHTTPS:
Enabled: true
special thanks to liesbeth, gerben, andrii for early user feedback.
there is plenty still to do, see the list at the top of webmail/webmail.ts.
feedback welcome as always.
2023-08-07 22:57:03 +03:00
|
|
|
Path:
|
|
|
|
|
replace http basic auth for web interfaces with session cookie & csrf-based auth
the http basic auth we had was very simple to reason about, and to implement.
but it has a major downside:
there is no way to logout, browsers keep sending credentials. ideally, browsers
themselves would show a button to stop sending credentials.
a related downside: the http auth mechanism doesn't indicate for which server
paths the credentials are.
another downside: the original password is sent to the server with each
request. though sending original passwords to web servers seems to be
considered normal.
our new approach uses session cookies, along with csrf values when we can. the
sessions are server-side managed, automatically extended on each use. this
makes it easy to invalidate sessions and keeps the frontend simpler (than with
long- vs short-term sessions and refreshing). the cookies are httponly,
samesite=strict, scoped to the path of the web interface. cookies are set
"secure" when set over https. the cookie is set by a successful call to Login.
a call to Logout invalidates a session. changing a password invalidates all
sessions for a user, but keeps the session with which the password was changed
alive. the csrf value is also random, and associated with the session cookie.
the csrf must be sent as header for api calls, or as parameter for direct form
posts (where we cannot set a custom header). rest-like calls made directly by
the browser, e.g. for images, don't have a csrf protection. the csrf value is
returned by the Login api call and stored in localstorage.
api calls without credentials return code "user:noAuth", and with bad
credentials return "user:badAuth". the api client recognizes this and triggers
a login. after a login, all auth-failed api calls are automatically retried.
only for "user:badAuth" is an error message displayed in the login form (e.g.
session expired).
in an ideal world, browsers would take care of most session management. a
server would indicate authentication is needed (like http basic auth), and the
browsers uses trusted ui to request credentials for the server & path. the
browser could use safer mechanism than sending original passwords to the
server, such as scram, along with a standard way to create sessions. for now,
web developers have to do authentication themselves: from showing the login
prompt, ensuring the right session/csrf cookies/localstorage/headers/etc are
sent with each request.
webauthn is a newer way to do authentication, perhaps we'll implement it in the
future. though hardware tokens aren't an attractive option for many users, and
it may be overkill as long as we still do old-fashioned authentication in smtp
& imap where passwords can be sent to the server.
for issue #58
2024-01-04 15:10:48 +03:00
|
|
|
# If set, X-Forwarded-* headers are used for the remote IP address for rate
|
|
|
|
# limiting and for the "secure" status of cookies. (optional)
|
|
|
|
Forwarded: false
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# Serve prometheus metrics, for monitoring. You should not enable this on a public
|
|
|
|
# IP. (optional)
|
|
|
|
MetricsHTTP:
|
|
|
|
Enabled: false
|
|
|
|
|
|
|
|
# Default 8010. (optional)
|
|
|
|
Port: 0
|
|
|
|
|
|
|
|
# Serve /debug/pprof/ for profiling a running mox instance. Do not enable this on
|
|
|
|
# a public IP! (optional)
|
|
|
|
PprofHTTP:
|
|
|
|
Enabled: false
|
|
|
|
|
|
|
|
# Default 8011. (optional)
|
|
|
|
Port: 0
|
|
|
|
|
|
|
|
# Serve autoconfiguration/autodiscovery to simplify configuring email
|
|
|
|
# applications, will use port 443. Requires a TLS config. (optional)
|
|
|
|
AutoconfigHTTPS:
|
|
|
|
Enabled: false
|
|
|
|
|
2023-02-18 18:53:06 +03:00
|
|
|
# TLS port, 443 by default. You should only override this if you cannot listen on
|
|
|
|
# port 443 directly. Autoconfig requests will be made to port 443, so you'll have
|
|
|
|
# to add an external mechanism to get the connection here, e.g. by configuring
|
|
|
|
# port forwarding. (optional)
|
|
|
|
Port: 0
|
|
|
|
|
2023-02-25 13:28:15 +03:00
|
|
|
# If set, plain HTTP instead of HTTPS is spoken on the configured port. Can be
|
|
|
|
# useful when the autoconfig domain is reverse proxied. (optional)
|
|
|
|
NonTLS: false
|
|
|
|
|
2023-02-18 18:53:06 +03:00
|
|
|
# Serve MTA-STS policies describing SMTP TLS requirements. Requires a TLS config.
|
|
|
|
# (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
MTASTSHTTPS:
|
|
|
|
Enabled: false
|
|
|
|
|
2023-02-18 18:53:06 +03:00
|
|
|
# TLS port, 443 by default. You should only override this if you cannot listen on
|
|
|
|
# port 443 directly. MTA-STS requests will be made to port 443, so you'll have to
|
|
|
|
# add an external mechanism to get the connection here, e.g. by configuring port
|
|
|
|
# forwarding. (optional)
|
|
|
|
Port: 0
|
|
|
|
|
2023-02-25 13:28:15 +03:00
|
|
|
# If set, plain HTTP instead of HTTPS is spoken on the configured port. Can be
|
|
|
|
# useful when the mta-sts domain is reverse proxied. (optional)
|
|
|
|
NonTLS: false
|
|
|
|
|
2023-03-01 00:12:27 +03:00
|
|
|
# All configured WebHandlers will serve on an enabled listener. (optional)
|
|
|
|
WebserverHTTP:
|
|
|
|
Enabled: false
|
|
|
|
|
|
|
|
# Port for plain HTTP (non-TLS) webserver. (optional)
|
|
|
|
Port: 0
|
|
|
|
|
|
|
|
# All configured WebHandlers will serve on an enabled listener. Either ACME must
|
|
|
|
# be configured, or for each WebHandler domain a TLS certificate must be
|
|
|
|
# configured. (optional)
|
|
|
|
WebserverHTTPS:
|
|
|
|
Enabled: false
|
|
|
|
|
|
|
|
# Port for HTTPS webserver. (optional)
|
|
|
|
Port: 0
|
|
|
|
|
2023-04-24 13:04:46 +03:00
|
|
|
# Destination for emails delivered to postmaster addresses: a plain 'postmaster'
|
|
|
|
# without domain, 'postmaster@<hostname>' (also for each listener with SMTP
|
|
|
|
# enabled), and as fallback for each domain without explicitly configured
|
|
|
|
# postmaster destination.
|
2023-01-30 16:27:06 +03:00
|
|
|
Postmaster:
|
|
|
|
Account:
|
|
|
|
|
|
|
|
# E.g. Postmaster or Inbox.
|
|
|
|
Mailbox:
|
|
|
|
|
implement outgoing tls reports
we were already accepting, processing and displaying incoming tls reports. now
we start tracking TLS connection and security-policy-related errors for
outgoing message deliveries as well. we send reports once a day, to the
reporting addresses specified in TLSRPT records (rua) of a policy domain. these
reports are about MTA-STS policies and/or DANE policies, and about
STARTTLS-related failures.
sending reports is enabled by default, but can be disabled through setting
NoOutgoingTLSReports in mox.conf.
only at the end of the implementation process came the realization that the
TLSRPT policy domain for DANE (MX) hosts are separate from the TLSRPT policy
for the recipient domain, and that MTA-STS and DANE TLS/policy results are
typically delivered in separate reports. so MX hosts need their own TLSRPT
policies.
config for the per-host TLSRPT policy should be added to mox.conf for existing
installs, in field HostTLSRPT. it is automatically configured by quickstart for
new installs. with a HostTLSRPT config, the "dns records" and "dns check" admin
pages now suggest the per-host TLSRPT record. by creating that record, you're
requesting TLS reports about your MX host.
gathering all the TLS/policy results is somewhat tricky. the tentacles go
throughout the code. the positive result is that the TLS/policy-related code
had to be cleaned up a bit. for example, the smtpclient TLS modes now reflect
reality better, with independent settings about whether PKIX and/or DANE
verification has to be done, and/or whether verification errors have to be
ignored (e.g. for tls-required: no header). also, cached mtasts policies of
mode "none" are now cleaned up once the MTA-STS DNS record goes away.
2023-11-09 19:40:46 +03:00
|
|
|
# Destination for per-host TLS reports (TLSRPT). TLS reports can be per recipient
|
|
|
|
# domain (for MTA-STS), or per MX host (for DANE). The per-domain TLS reporting
|
|
|
|
# configuration is in domains.conf. This is the TLS reporting configuration for
|
|
|
|
# this host. If absent, no host-based TLSRPT address is configured, and no host
|
|
|
|
# TLSRPT DNS record is suggested. (optional)
|
|
|
|
HostTLSRPT:
|
|
|
|
|
|
|
|
# Account to deliver TLS reports to. Typically same account as for postmaster.
|
|
|
|
Account:
|
|
|
|
|
|
|
|
# Mailbox to deliver TLS reports to. Recommended value: TLSRPT.
|
|
|
|
Mailbox:
|
|
|
|
|
|
|
|
# Localpart at hostname to accept TLS reports at. Recommended value: tls-reports.
|
|
|
|
Localpart:
|
|
|
|
|
2023-08-09 10:31:23 +03:00
|
|
|
# Mailboxes to create for new accounts. Inbox is always created. Mailboxes can be
|
|
|
|
# given a 'special-use' role, which are understood by most mail clients. If
|
|
|
|
# absent/empty, the following mailboxes are created: Sent, Archive, Trash, Drafts
|
|
|
|
# and Junk. (optional)
|
|
|
|
InitialMailboxes:
|
|
|
|
|
|
|
|
# Special-use roles to mailbox to create. (optional)
|
|
|
|
SpecialUse:
|
|
|
|
|
|
|
|
# (optional)
|
|
|
|
Sent:
|
|
|
|
|
|
|
|
# (optional)
|
|
|
|
Archive:
|
|
|
|
|
|
|
|
# (optional)
|
|
|
|
Trash:
|
|
|
|
|
|
|
|
# (optional)
|
|
|
|
Draft:
|
|
|
|
|
|
|
|
# (optional)
|
|
|
|
Junk:
|
|
|
|
|
|
|
|
# Regular, non-special-use mailboxes to create. (optional)
|
|
|
|
Regular:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Deprecated in favor of InitialMailboxes. Mailboxes to create when adding an
|
|
|
|
# account. Inbox is always created. If no mailboxes are specified, the following
|
|
|
|
# are automatically created: Sent, Archive, Trash, Drafts and Junk. (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
DefaultMailboxes:
|
|
|
|
-
|
|
|
|
|
new feature: when delivering messages from the queue, make it possible to use a "transport"
the default transport is still just "direct delivery", where we connect to the
destination domain's MX servers.
other transports are:
- regular smtp without authentication, this is relaying to a smarthost.
- submission with authentication, e.g. to a third party email sending service.
- direct delivery, but with with connections going through a socks proxy. this
can be helpful if your ip is blocked, you need to get email out, and you have
another IP that isn't blocked.
keep in mind that for all of the above, appropriate SPF/DKIM settings have to
be configured. the "dnscheck" for a domain does a check for any SOCKS IP in the
SPF record. SPF for smtp/submission (ranges? includes?) and any DKIM
requirements cannot really be checked.
which transport is used can be configured through routes. routes can be set on
an account, a domain, or globally. the routes are evaluated in that order, with
the first match selecting the transport. these routes are evaluated for each
delivery attempt. common selection criteria are recipient domain and sender
domain, but also which delivery attempt this is. you could configured mox to
attempt sending through a 3rd party from the 4th attempt onwards.
routes and transports are optional. if no route matches, or an empty/zero
transport is selected, normal direct delivery is done.
we could already "submit" emails with 3rd party accounts with "sendmail". but
we now support more SASL authentication mechanisms with SMTP (not only PLAIN,
but also SCRAM-SHA-256, SCRAM-SHA-1 and CRAM-MD5), which sendmail now also
supports. sendmail will use the most secure mechanism supported by the server,
or the explicitly configured mechanism.
for issue #36 by dmikushin. also based on earlier discussion on hackernews.
2023-06-16 19:38:28 +03:00
|
|
|
# Transport are mechanisms for delivering messages. Transports can be referenced
|
|
|
|
# from Routes in accounts, domains and the global configuration. There is always
|
|
|
|
# an implicit/fallback delivery transport doing direct delivery with SMTP from the
|
|
|
|
# outgoing message queue. Transports are typically only configured when using
|
|
|
|
# smarthosts, i.e. when delivering through another SMTP server. Zero or one
|
|
|
|
# transport methods must be set in a transport, never multiple. When using an
|
|
|
|
# external party to send email for a domain, keep in mind you may have to add
|
|
|
|
# their IP address to your domain's SPF record, and possibly additional DKIM
|
|
|
|
# records. (optional)
|
|
|
|
Transports:
|
|
|
|
x:
|
|
|
|
|
|
|
|
# Submission SMTP over a TLS connection to submit email to a remote queue.
|
|
|
|
# (optional)
|
|
|
|
Submissions:
|
|
|
|
|
|
|
|
# Host name to connect to and for verifying its TLS certificate.
|
|
|
|
Host:
|
|
|
|
|
|
|
|
# If unset or 0, the default port for submission(s)/smtp is used: 25 for SMTP, 465
|
|
|
|
# for submissions (with TLS), 587 for submission (possibly with STARTTLS).
|
|
|
|
# (optional)
|
|
|
|
Port: 0
|
|
|
|
|
|
|
|
# If set an unverifiable remote TLS certificate during STARTTLS is accepted.
|
|
|
|
# (optional)
|
|
|
|
STARTTLSInsecureSkipVerify: false
|
|
|
|
|
|
|
|
# If set for submission or smtp transport, do not attempt STARTTLS on the
|
|
|
|
# connection. Authentication credentials and messages will be transferred in clear
|
|
|
|
# text. (optional)
|
|
|
|
NoSTARTTLS: false
|
|
|
|
|
|
|
|
# If set, authentication credentials for the remote server. (optional)
|
|
|
|
Auth:
|
|
|
|
Username:
|
|
|
|
Password:
|
|
|
|
|
2023-12-24 01:07:21 +03:00
|
|
|
# Allowed authentication mechanisms. Defaults to SCRAM-SHA-256-PLUS,
|
|
|
|
# SCRAM-SHA-256, SCRAM-SHA-1-PLUS, SCRAM-SHA-1, CRAM-MD5. Not included by default:
|
|
|
|
# PLAIN. Specify the strongest mechanism known to be implemented by the server to
|
|
|
|
# prevent mechanism downgrade attacks. (optional)
|
new feature: when delivering messages from the queue, make it possible to use a "transport"
the default transport is still just "direct delivery", where we connect to the
destination domain's MX servers.
other transports are:
- regular smtp without authentication, this is relaying to a smarthost.
- submission with authentication, e.g. to a third party email sending service.
- direct delivery, but with with connections going through a socks proxy. this
can be helpful if your ip is blocked, you need to get email out, and you have
another IP that isn't blocked.
keep in mind that for all of the above, appropriate SPF/DKIM settings have to
be configured. the "dnscheck" for a domain does a check for any SOCKS IP in the
SPF record. SPF for smtp/submission (ranges? includes?) and any DKIM
requirements cannot really be checked.
which transport is used can be configured through routes. routes can be set on
an account, a domain, or globally. the routes are evaluated in that order, with
the first match selecting the transport. these routes are evaluated for each
delivery attempt. common selection criteria are recipient domain and sender
domain, but also which delivery attempt this is. you could configured mox to
attempt sending through a 3rd party from the 4th attempt onwards.
routes and transports are optional. if no route matches, or an empty/zero
transport is selected, normal direct delivery is done.
we could already "submit" emails with 3rd party accounts with "sendmail". but
we now support more SASL authentication mechanisms with SMTP (not only PLAIN,
but also SCRAM-SHA-256, SCRAM-SHA-1 and CRAM-MD5), which sendmail now also
supports. sendmail will use the most secure mechanism supported by the server,
or the explicitly configured mechanism.
for issue #36 by dmikushin. also based on earlier discussion on hackernews.
2023-06-16 19:38:28 +03:00
|
|
|
Mechanisms:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Submission SMTP over a plain TCP connection (possibly with STARTTLS) to submit
|
|
|
|
# email to a remote queue. (optional)
|
|
|
|
Submission:
|
|
|
|
|
|
|
|
# Host name to connect to and for verifying its TLS certificate.
|
|
|
|
Host:
|
|
|
|
|
|
|
|
# If unset or 0, the default port for submission(s)/smtp is used: 25 for SMTP, 465
|
|
|
|
# for submissions (with TLS), 587 for submission (possibly with STARTTLS).
|
|
|
|
# (optional)
|
|
|
|
Port: 0
|
|
|
|
|
|
|
|
# If set an unverifiable remote TLS certificate during STARTTLS is accepted.
|
|
|
|
# (optional)
|
|
|
|
STARTTLSInsecureSkipVerify: false
|
|
|
|
|
|
|
|
# If set for submission or smtp transport, do not attempt STARTTLS on the
|
|
|
|
# connection. Authentication credentials and messages will be transferred in clear
|
|
|
|
# text. (optional)
|
|
|
|
NoSTARTTLS: false
|
|
|
|
|
|
|
|
# If set, authentication credentials for the remote server. (optional)
|
|
|
|
Auth:
|
|
|
|
Username:
|
|
|
|
Password:
|
|
|
|
|
2023-12-24 01:07:21 +03:00
|
|
|
# Allowed authentication mechanisms. Defaults to SCRAM-SHA-256-PLUS,
|
|
|
|
# SCRAM-SHA-256, SCRAM-SHA-1-PLUS, SCRAM-SHA-1, CRAM-MD5. Not included by default:
|
|
|
|
# PLAIN. Specify the strongest mechanism known to be implemented by the server to
|
|
|
|
# prevent mechanism downgrade attacks. (optional)
|
new feature: when delivering messages from the queue, make it possible to use a "transport"
the default transport is still just "direct delivery", where we connect to the
destination domain's MX servers.
other transports are:
- regular smtp without authentication, this is relaying to a smarthost.
- submission with authentication, e.g. to a third party email sending service.
- direct delivery, but with with connections going through a socks proxy. this
can be helpful if your ip is blocked, you need to get email out, and you have
another IP that isn't blocked.
keep in mind that for all of the above, appropriate SPF/DKIM settings have to
be configured. the "dnscheck" for a domain does a check for any SOCKS IP in the
SPF record. SPF for smtp/submission (ranges? includes?) and any DKIM
requirements cannot really be checked.
which transport is used can be configured through routes. routes can be set on
an account, a domain, or globally. the routes are evaluated in that order, with
the first match selecting the transport. these routes are evaluated for each
delivery attempt. common selection criteria are recipient domain and sender
domain, but also which delivery attempt this is. you could configured mox to
attempt sending through a 3rd party from the 4th attempt onwards.
routes and transports are optional. if no route matches, or an empty/zero
transport is selected, normal direct delivery is done.
we could already "submit" emails with 3rd party accounts with "sendmail". but
we now support more SASL authentication mechanisms with SMTP (not only PLAIN,
but also SCRAM-SHA-256, SCRAM-SHA-1 and CRAM-MD5), which sendmail now also
supports. sendmail will use the most secure mechanism supported by the server,
or the explicitly configured mechanism.
for issue #36 by dmikushin. also based on earlier discussion on hackernews.
2023-06-16 19:38:28 +03:00
|
|
|
Mechanisms:
|
|
|
|
-
|
|
|
|
|
|
|
|
# SMTP over a plain connection (possibly with STARTTLS), typically for
|
|
|
|
# old-fashioned unauthenticated relaying to a remote queue. (optional)
|
|
|
|
SMTP:
|
|
|
|
|
|
|
|
# Host name to connect to and for verifying its TLS certificate.
|
|
|
|
Host:
|
|
|
|
|
|
|
|
# If unset or 0, the default port for submission(s)/smtp is used: 25 for SMTP, 465
|
|
|
|
# for submissions (with TLS), 587 for submission (possibly with STARTTLS).
|
|
|
|
# (optional)
|
|
|
|
Port: 0
|
|
|
|
|
|
|
|
# If set an unverifiable remote TLS certificate during STARTTLS is accepted.
|
|
|
|
# (optional)
|
|
|
|
STARTTLSInsecureSkipVerify: false
|
|
|
|
|
|
|
|
# If set for submission or smtp transport, do not attempt STARTTLS on the
|
|
|
|
# connection. Authentication credentials and messages will be transferred in clear
|
|
|
|
# text. (optional)
|
|
|
|
NoSTARTTLS: false
|
|
|
|
|
|
|
|
# If set, authentication credentials for the remote server. (optional)
|
|
|
|
Auth:
|
|
|
|
Username:
|
|
|
|
Password:
|
|
|
|
|
2023-12-24 01:07:21 +03:00
|
|
|
# Allowed authentication mechanisms. Defaults to SCRAM-SHA-256-PLUS,
|
|
|
|
# SCRAM-SHA-256, SCRAM-SHA-1-PLUS, SCRAM-SHA-1, CRAM-MD5. Not included by default:
|
|
|
|
# PLAIN. Specify the strongest mechanism known to be implemented by the server to
|
|
|
|
# prevent mechanism downgrade attacks. (optional)
|
new feature: when delivering messages from the queue, make it possible to use a "transport"
the default transport is still just "direct delivery", where we connect to the
destination domain's MX servers.
other transports are:
- regular smtp without authentication, this is relaying to a smarthost.
- submission with authentication, e.g. to a third party email sending service.
- direct delivery, but with with connections going through a socks proxy. this
can be helpful if your ip is blocked, you need to get email out, and you have
another IP that isn't blocked.
keep in mind that for all of the above, appropriate SPF/DKIM settings have to
be configured. the "dnscheck" for a domain does a check for any SOCKS IP in the
SPF record. SPF for smtp/submission (ranges? includes?) and any DKIM
requirements cannot really be checked.
which transport is used can be configured through routes. routes can be set on
an account, a domain, or globally. the routes are evaluated in that order, with
the first match selecting the transport. these routes are evaluated for each
delivery attempt. common selection criteria are recipient domain and sender
domain, but also which delivery attempt this is. you could configured mox to
attempt sending through a 3rd party from the 4th attempt onwards.
routes and transports are optional. if no route matches, or an empty/zero
transport is selected, normal direct delivery is done.
we could already "submit" emails with 3rd party accounts with "sendmail". but
we now support more SASL authentication mechanisms with SMTP (not only PLAIN,
but also SCRAM-SHA-256, SCRAM-SHA-1 and CRAM-MD5), which sendmail now also
supports. sendmail will use the most secure mechanism supported by the server,
or the explicitly configured mechanism.
for issue #36 by dmikushin. also based on earlier discussion on hackernews.
2023-06-16 19:38:28 +03:00
|
|
|
Mechanisms:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Like regular direct delivery, but makes outgoing connections through a SOCKS
|
|
|
|
# proxy. (optional)
|
|
|
|
Socks:
|
|
|
|
|
|
|
|
# Address of SOCKS proxy, of the form host:port or ip:port.
|
|
|
|
Address:
|
|
|
|
|
|
|
|
# IP addresses connections from the SOCKS server will originate from. This IP
|
|
|
|
# addresses should be configured in the SPF record (keep in mind DNS record time
|
|
|
|
# to live (TTL) when adding a SOCKS proxy). Reverse DNS should be set up for these
|
|
|
|
# address, resolving to RemoteHostname. These are typically the IPv4 and IPv6
|
|
|
|
# address for the host in the Address field.
|
|
|
|
RemoteIPs:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Hostname belonging to RemoteIPs. This name is used during in SMTP EHLO. This is
|
|
|
|
# typically the hostname of the host in the Address field.
|
|
|
|
RemoteHostname:
|
|
|
|
|
2023-11-01 19:55:40 +03:00
|
|
|
# Do not send DMARC reports (aggregate only). By default, aggregate reports on
|
|
|
|
# DMARC evaluations are sent to domains if their DMARC policy requests them.
|
|
|
|
# Reports are sent at whole hours, with a minimum of 1 hour and maximum of 24
|
|
|
|
# hours, rounded up so a whole number of intervals cover 24 hours, aligned at
|
2023-11-20 13:31:46 +03:00
|
|
|
# whole days in UTC. Reports are sent from the postmaster@<mailhostname> address.
|
|
|
|
# (optional)
|
2023-11-01 19:55:40 +03:00
|
|
|
NoOutgoingDMARCReports: false
|
|
|
|
|
2023-11-20 13:31:46 +03:00
|
|
|
# Do not send TLS reports. By default, reports about failed SMTP STARTTLS
|
|
|
|
# connections and related MTA-STS/DANE policies are sent to domains if their
|
|
|
|
# TLSRPT DNS record requests them. Reports covering a 24 hour UTC interval are
|
|
|
|
# sent daily. Reports are sent from the postmaster address of the configured
|
|
|
|
# domain the mailhostname is in. If there is no such domain, or it does not have
|
|
|
|
# DKIM configured, no reports are sent. (optional)
|
implement outgoing tls reports
we were already accepting, processing and displaying incoming tls reports. now
we start tracking TLS connection and security-policy-related errors for
outgoing message deliveries as well. we send reports once a day, to the
reporting addresses specified in TLSRPT records (rua) of a policy domain. these
reports are about MTA-STS policies and/or DANE policies, and about
STARTTLS-related failures.
sending reports is enabled by default, but can be disabled through setting
NoOutgoingTLSReports in mox.conf.
only at the end of the implementation process came the realization that the
TLSRPT policy domain for DANE (MX) hosts are separate from the TLSRPT policy
for the recipient domain, and that MTA-STS and DANE TLS/policy results are
typically delivered in separate reports. so MX hosts need their own TLSRPT
policies.
config for the per-host TLSRPT policy should be added to mox.conf for existing
installs, in field HostTLSRPT. it is automatically configured by quickstart for
new installs. with a HostTLSRPT config, the "dns records" and "dns check" admin
pages now suggest the per-host TLSRPT record. by creating that record, you're
requesting TLS reports about your MX host.
gathering all the TLS/policy results is somewhat tricky. the tentacles go
throughout the code. the positive result is that the TLS/policy-related code
had to be cleaned up a bit. for example, the smtpclient TLS modes now reflect
reality better, with independent settings about whether PKIX and/or DANE
verification has to be done, and/or whether verification errors have to be
ignored (e.g. for tls-required: no header). also, cached mtasts policies of
mode "none" are now cleaned up once the MTA-STS DNS record goes away.
2023-11-09 19:40:46 +03:00
|
|
|
NoOutgoingTLSReports: false
|
|
|
|
|
2023-11-20 13:31:46 +03:00
|
|
|
# Also send TLS reports if there were no SMTP STARTTLS connection failures. By
|
|
|
|
# default, reports are only sent when at least one failure occurred. If a report
|
|
|
|
# is sent, it does always include the successful connection counts as well.
|
|
|
|
# (optional)
|
|
|
|
OutgoingTLSReportsForAllSuccess: false
|
|
|
|
|
2023-12-20 22:54:12 +03:00
|
|
|
# Default maximum total message size for accounts, only applicable if greater than
|
|
|
|
# zero. Can be overridden per account. Attempting to add new messages beyond the
|
|
|
|
# maximum size will result in an error. Useful to prevent a single account from
|
|
|
|
# filling storage. The quota only applies to the email message files, not to any
|
|
|
|
# file system overhead and also not the message index database file (account for
|
|
|
|
# approximately 15% overhead). (optional)
|
|
|
|
QuotaMessageSize: 0
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# domains.conf
|
|
|
|
|
2023-09-21 09:59:10 +03:00
|
|
|
# NOTE: This config file is in 'sconf' format. Indent with tabs. Comments must be
|
|
|
|
# on their own line, they don't end a line. Do not escape or quote strings.
|
|
|
|
# Details: https://pkg.go.dev/github.com/mjl-/sconf.
|
|
|
|
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# Domains for which email is accepted. For internationalized domains, use their
|
|
|
|
# IDNA names in UTF-8.
|
|
|
|
Domains:
|
|
|
|
x:
|
|
|
|
|
|
|
|
# Free-form description of domain. (optional)
|
|
|
|
Description:
|
|
|
|
|
assume a dns cname record mail.<domain>, pointing to the hostname of the mail server, for clients to connect to
the autoconfig/autodiscover endpoints, and the printed client settings (in
quickstart, in the admin interface) now all point to the cname record (called
"client settings domain"). it is configurable per domain, and set to
"mail.<domain>" by default. for existing mox installs, the domain can be added
by editing the config file.
this makes it easier for a domain to migrate to another server in the future.
client settings don't have to be updated, the cname can just be changed.
before, the hostname of the mail server was configured in email clients.
migrating away would require changing settings in all clients.
if a client settings domain is configured, a TLS certificate for the name will
be requested through ACME, or must be configured manually.
2023-12-24 13:01:16 +03:00
|
|
|
# Hostname for client settings instead of the mail server hostname. E.g.
|
|
|
|
# mail.<domain>. For future migration to another mail operator without requiring
|
|
|
|
# all clients to update their settings, it is convenient to have client settings
|
|
|
|
# that reference a subdomain of the hosted domain instead of the hostname of the
|
|
|
|
# server where the mail is currently hosted. If empty, the hostname of the mail
|
|
|
|
# server is used for client configurations. (optional)
|
|
|
|
ClientSettingsDomain:
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# If not empty, only the string before the separator is used to for email delivery
|
|
|
|
# decisions. For example, if set to "+", you+anything@example.com will be
|
|
|
|
# delivered to you@example.com. (optional)
|
|
|
|
LocalpartCatchallSeparator:
|
|
|
|
|
|
|
|
# If set, upper/lower case is relevant for email delivery. (optional)
|
|
|
|
LocalpartCaseSensitive: false
|
|
|
|
|
|
|
|
# With DKIM signing, a domain is taking responsibility for (content of) emails it
|
|
|
|
# sends, letting receiving mail servers build up a (hopefully positive) reputation
|
|
|
|
# of the domain, which can help with mail delivery. (optional)
|
|
|
|
DKIM:
|
|
|
|
|
|
|
|
# Emails can be DKIM signed. Config parameters are per selector. A DNS record must
|
|
|
|
# be created for each selector. Add the name to Sign to use the selector for
|
|
|
|
# signing messages.
|
|
|
|
Selectors:
|
|
|
|
x:
|
|
|
|
|
|
|
|
# sha256 (default) or (older, not recommended) sha1 (optional)
|
|
|
|
Hash:
|
|
|
|
|
|
|
|
# (optional)
|
|
|
|
Canonicalization:
|
|
|
|
|
|
|
|
# If set, some modifications to the headers (mostly whitespace) are allowed.
|
|
|
|
HeaderRelaxed: false
|
|
|
|
|
|
|
|
# If set, some whitespace modifications to the message body are allowed.
|
|
|
|
BodyRelaxed: false
|
|
|
|
|
|
|
|
# Headers to sign with DKIM. If empty, a reasonable default set of headers is
|
|
|
|
# selected. (optional)
|
|
|
|
Headers:
|
|
|
|
-
|
|
|
|
|
|
|
|
# If set, don't prevent duplicate headers from being added. Not recommended.
|
|
|
|
# (optional)
|
|
|
|
DontSealHeaders: false
|
|
|
|
|
|
|
|
# Period a signature is valid after signing, as duration, e.g. 72h. The period
|
|
|
|
# should be enough for delivery at the final destination, potentially with several
|
|
|
|
# hops/relays. In the order of days at least. (optional)
|
|
|
|
Expiration:
|
|
|
|
|
|
|
|
# Either an RSA or ed25519 private key file in PKCS8 PEM form.
|
|
|
|
PrivateKeyFile:
|
|
|
|
|
|
|
|
# List of selectors that emails will be signed with. (optional)
|
|
|
|
Sign:
|
|
|
|
-
|
|
|
|
|
|
|
|
# With DMARC, a domain publishes, in DNS, a policy on how other mail servers
|
|
|
|
# should handle incoming messages with the From-header matching this domain and/or
|
|
|
|
# subdomain (depending on the configured alignment). Receiving mail servers use
|
|
|
|
# this to build up a reputation of this domain, which can help with mail delivery.
|
|
|
|
# A domain can also publish an email address to which reports about DMARC
|
|
|
|
# verification results can be sent by verifying mail servers, useful for
|
|
|
|
# monitoring. Incoming DMARC reports are automatically parsed, validated, added to
|
|
|
|
# metrics and stored in the reporting database for later display in the admin web
|
|
|
|
# pages. (optional)
|
|
|
|
DMARC:
|
|
|
|
|
|
|
|
# Address-part before the @ that accepts DMARC reports. Must be
|
|
|
|
# non-internationalized. Recommended value: dmarc-reports.
|
|
|
|
Localpart:
|
|
|
|
|
2023-08-23 15:27:21 +03:00
|
|
|
# Alternative domain for report recipient address. Can be used to receive reports
|
|
|
|
# for other domains. Unicode name. (optional)
|
|
|
|
Domain:
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# Account to deliver to.
|
|
|
|
Account:
|
|
|
|
|
|
|
|
# Mailbox to deliver to, e.g. DMARC.
|
|
|
|
Mailbox:
|
|
|
|
|
|
|
|
# With MTA-STS a domain publishes, in DNS, presence of a policy for
|
|
|
|
# using/requiring TLS for SMTP connections. The policy is served over HTTPS.
|
|
|
|
# (optional)
|
|
|
|
MTASTS:
|
|
|
|
|
|
|
|
# Policies are versioned. The version must be specified in the DNS record. If you
|
|
|
|
# change a policy, first change it in mox, then update the DNS record.
|
|
|
|
PolicyID:
|
|
|
|
|
|
|
|
# testing, enforce or none. If set to enforce, a remote SMTP server will not
|
|
|
|
# deliver email to us if it cannot make a TLS connection.
|
|
|
|
Mode:
|
|
|
|
|
|
|
|
# How long a remote mail server is allowed to cache a policy. Typically 1 or
|
|
|
|
# several weeks.
|
|
|
|
MaxAge: 0s
|
|
|
|
|
|
|
|
# List of server names allowed for SMTP. If empty, the configured hostname is set.
|
|
|
|
# Host names can contain a wildcard (*) as a leading label (matching a single
|
|
|
|
# label, e.g. *.example matches host.example, not sub.host.example). (optional)
|
|
|
|
MX:
|
|
|
|
-
|
|
|
|
|
|
|
|
# With TLSRPT a domain specifies in DNS where reports about encountered SMTP TLS
|
|
|
|
# behaviour should be sent. Useful for monitoring. Incoming TLS reports are
|
|
|
|
# automatically parsed, validated, added to metrics and stored in the reporting
|
|
|
|
# database for later display in the admin web pages. (optional)
|
|
|
|
TLSRPT:
|
|
|
|
|
|
|
|
# Address-part before the @ that accepts TLSRPT reports. Recommended value:
|
|
|
|
# tls-reports.
|
|
|
|
Localpart:
|
|
|
|
|
2023-08-23 15:27:21 +03:00
|
|
|
# Alternative domain for report recipient address. Can be used to receive reports
|
|
|
|
# for other domains. Unicode name. (optional)
|
|
|
|
Domain:
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# Account to deliver to.
|
|
|
|
Account:
|
|
|
|
|
|
|
|
# Mailbox to deliver to, e.g. TLSRPT.
|
|
|
|
Mailbox:
|
|
|
|
|
new feature: when delivering messages from the queue, make it possible to use a "transport"
the default transport is still just "direct delivery", where we connect to the
destination domain's MX servers.
other transports are:
- regular smtp without authentication, this is relaying to a smarthost.
- submission with authentication, e.g. to a third party email sending service.
- direct delivery, but with with connections going through a socks proxy. this
can be helpful if your ip is blocked, you need to get email out, and you have
another IP that isn't blocked.
keep in mind that for all of the above, appropriate SPF/DKIM settings have to
be configured. the "dnscheck" for a domain does a check for any SOCKS IP in the
SPF record. SPF for smtp/submission (ranges? includes?) and any DKIM
requirements cannot really be checked.
which transport is used can be configured through routes. routes can be set on
an account, a domain, or globally. the routes are evaluated in that order, with
the first match selecting the transport. these routes are evaluated for each
delivery attempt. common selection criteria are recipient domain and sender
domain, but also which delivery attempt this is. you could configured mox to
attempt sending through a 3rd party from the 4th attempt onwards.
routes and transports are optional. if no route matches, or an empty/zero
transport is selected, normal direct delivery is done.
we could already "submit" emails with 3rd party accounts with "sendmail". but
we now support more SASL authentication mechanisms with SMTP (not only PLAIN,
but also SCRAM-SHA-256, SCRAM-SHA-1 and CRAM-MD5), which sendmail now also
supports. sendmail will use the most secure mechanism supported by the server,
or the explicitly configured mechanism.
for issue #36 by dmikushin. also based on earlier discussion on hackernews.
2023-06-16 19:38:28 +03:00
|
|
|
# Routes for delivering outgoing messages through the queue. Each delivery attempt
|
|
|
|
# evaluates account routes, these domain routes and finally global routes. The
|
|
|
|
# transport of the first matching route is used in the delivery attempt. If no
|
|
|
|
# routes match, which is the default with no configured routes, messages are
|
|
|
|
# delivered directly from the queue. (optional)
|
|
|
|
Routes:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Matches if the envelope from domain matches one of the configured domains, or if
|
|
|
|
# the list is empty. If a domain starts with a dot, prefixes of the domain also
|
|
|
|
# match. (optional)
|
|
|
|
FromDomain:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Like FromDomain, but matching against the envelope to domain. (optional)
|
|
|
|
ToDomain:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Matches if at least this many deliveries have already been attempted. This can
|
|
|
|
# be used to attempt sending through a smarthost when direct delivery has failed
|
|
|
|
# for several times. (optional)
|
|
|
|
MinimumAttempts: 0
|
|
|
|
Transport:
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# Accounts to which email can be delivered. An account can accept email for
|
|
|
|
# multiple domains, for multiple localparts, and deliver to multiple mailboxes.
|
|
|
|
Accounts:
|
|
|
|
x:
|
|
|
|
|
2023-03-10 00:07:37 +03:00
|
|
|
# Default domain for account. Deprecated behaviour: If a destination is not a full
|
|
|
|
# address but only a localpart, this domain is added to form a full address.
|
2023-01-30 16:27:06 +03:00
|
|
|
Domain:
|
|
|
|
|
|
|
|
# Free form description, e.g. full name or alternative contact info. (optional)
|
|
|
|
Description:
|
|
|
|
|
add webmail
it was far down on the roadmap, but implemented earlier, because it's
interesting, and to help prepare for a jmap implementation. for jmap we need to
implement more client-like functionality than with just imap. internal data
structures need to change. jmap has lots of other requirements, so it's already
a big project. by implementing a webmail now, some of the required data
structure changes become clear and can be made now, so the later jmap
implementation can do things similarly to the webmail code. the webmail
frontend and webmail are written together, making their interface/api much
smaller and simpler than jmap.
one of the internal changes is that we now keep track of per-mailbox
total/unread/unseen/deleted message counts and mailbox sizes. keeping this
data consistent after any change to the stored messages (through the code base)
is tricky, so mox now has a consistency check that verifies the counts are
correct, which runs only during tests, each time an internal account reference
is closed. we have a few more internal "changes" that are propagated for the
webmail frontend (that imap doesn't have a way to propagate on a connection),
like changes to the special-use flags on mailboxes, and used keywords in a
mailbox. more changes that will be required have revealed themselves while
implementing the webmail, and will be implemented next.
the webmail user interface is modeled after the mail clients i use or have
used: thunderbird, macos mail, mutt; and webmails i normally only use for
testing: gmail, proton, yahoo, outlook. a somewhat technical user is assumed,
but still the goal is to make this webmail client easy to use for everyone. the
user interface looks like most other mail clients: a list of mailboxes, a
search bar, a message list view, and message details. there is a top/bottom and
a left/right layout for the list/message view, default is automatic based on
screen size. the panes can be resized by the user. buttons for actions are just
text, not icons. clicking a button briefly shows the shortcut for the action in
the bottom right, helping with learning to operate quickly. any text that is
underdotted has a title attribute that causes more information to be displayed,
e.g. what a button does or a field is about. to highlight potential phishing
attempts, any text (anywhere in the webclient) that switches unicode "blocks"
(a rough approximation to (language) scripts) within a word is underlined
orange. multiple messages can be selected with familiar ui interaction:
clicking while holding control and/or shift keys. keyboard navigation works
with arrows/page up/down and home/end keys, and also with a few basic vi-like
keys for list/message navigation. we prefer showing the text instead of
html (with inlined images only) version of a message. html messages are shown
in an iframe served from an endpoint with CSP headers to prevent dangerous
resources (scripts, external images) from being loaded. the html is also
sanitized, with javascript removed. a user can choose to load external
resources (e.g. images for tracking purposes).
the frontend is just (strict) typescript, no external frameworks. all
incoming/outgoing data is typechecked, both the api request parameters and
response types, and the data coming in over SSE. the types and checking code
are generated with sherpats, which uses the api definitions generated by
sherpadoc based on the Go code. so types from the backend are automatically
propagated to the frontend. since there is no framework to automatically
propagate properties and rerender components, changes coming in over the SSE
connection are propagated explicitly with regular function calls. the ui is
separated into "views", each with a "root" dom element that is added to the
visible document. these views have additional functions for getting changes
propagated, often resulting in the view updating its (internal) ui state (dom).
we keep the frontend compilation simple, it's just a few typescript files that
get compiled (combined and types stripped) into a single js file, no additional
runtime code needed or complicated build processes used. the webmail is served
is served from a compressed, cachable html file that includes style and the
javascript, currently just over 225kb uncompressed, under 60kb compressed (not
minified, including comments). we include the generated js files in the
repository, to keep Go's easily buildable self-contained binaries.
authentication is basic http, as with the account and admin pages. most data
comes in over one long-term SSE connection to the backend. api requests signal
which mailbox/search/messages are requested over the SSE connection. fetching
individual messages, and making changes, are done through api calls. the
operations are similar to imap, so some code has been moved from package
imapserver to package store. the future jmap implementation will benefit from
these changes too. more functionality will probably be moved to the store
package in the future.
the quickstart enables webmail on the internal listener by default (for new
installs). users can enable it on the public listener if they want to. mox
localserve enables it too. to enable webmail on existing installs, add settings
like the following to the listeners in mox.conf, similar to AccountHTTP(S):
WebmailHTTP:
Enabled: true
WebmailHTTPS:
Enabled: true
special thanks to liesbeth, gerben, andrii for early user feedback.
there is plenty still to do, see the list at the top of webmail/webmail.ts.
feedback welcome as always.
2023-08-07 22:57:03 +03:00
|
|
|
# Full name, to use in message From header when composing messages in webmail. Can
|
|
|
|
# be overridden per destination. (optional)
|
|
|
|
FullName:
|
|
|
|
|
2023-03-29 22:11:43 +03:00
|
|
|
# Destinations, keys are email addresses (with IDNA domains). If the address is of
|
|
|
|
# the form '@domain', i.e. with localpart missing, it serves as a catchall for the
|
|
|
|
# domain, matching all messages that are not explicitly configured. Deprecated
|
2023-03-10 00:07:37 +03:00
|
|
|
# behaviour: If the address is not a full address but a localpart, it is combined
|
|
|
|
# with Domain to form a full address.
|
2023-01-30 16:27:06 +03:00
|
|
|
Destinations:
|
|
|
|
x:
|
|
|
|
|
|
|
|
# Mailbox to deliver to if none of Rulesets match. Default: Inbox. (optional)
|
|
|
|
Mailbox:
|
|
|
|
|
|
|
|
# Delivery rules based on message and SMTP transaction. You may want to match each
|
|
|
|
# mailing list by SMTP MailFrom address, VerifiedDomain and/or List-ID header
|
|
|
|
# (typically <listname.example.org> if the list address is listname@example.org),
|
|
|
|
# delivering them to their own mailbox. (optional)
|
|
|
|
Rulesets:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Matches if this regular expression matches (a substring of) the SMTP MAIL FROM
|
2023-08-09 23:31:37 +03:00
|
|
|
# address (not the message From-header). E.g. '^user@example\.org$'. (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
SMTPMailFromRegexp:
|
|
|
|
|
2023-02-11 01:47:19 +03:00
|
|
|
# Matches if this domain matches an SPF- and/or DKIM-verified (sub)domain.
|
|
|
|
# (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
VerifiedDomain:
|
|
|
|
|
|
|
|
# Matches if these header field/value regular expressions all match (substrings
|
|
|
|
# of) the message headers. Header fields and valuees are converted to lower case
|
|
|
|
# before matching. Whitespace is trimmed from the value before matching. A header
|
2023-02-11 01:47:19 +03:00
|
|
|
# field can occur multiple times in a message, only one instance has to match. For
|
|
|
|
# mailing lists, you could match on ^list-id$ with the value typically the mailing
|
|
|
|
# list address in angled brackets with @ replaced with a dot, e.g.
|
|
|
|
# <name\.lists\.example\.org>. (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
HeadersRegexp:
|
|
|
|
x:
|
|
|
|
|
2023-08-09 23:31:37 +03:00
|
|
|
# Influences spam filtering only, this option does not change whether a message
|
|
|
|
# matches this ruleset. Can only be used together with SMTPMailFromRegexp and
|
|
|
|
# VerifiedDomain. SMTPMailFromRegexp must be set to the address used to deliver
|
|
|
|
# the forwarded message, e.g. '^user(|\+.*)@forward\.example$'. Changes to junk
|
|
|
|
# analysis: 1. Messages are not rejects for failing a DMARC policy, because a
|
|
|
|
# legitimate forwarded message without valid/intact/aligned DKIM signature would
|
|
|
|
# be rejected because any verified SPF domain will be 'unaligned', of the
|
|
|
|
# forwarding mail server. 2. The sending mail server IP address, and sending EHLO
|
|
|
|
# and MAIL FROM domains and matching DKIM domain aren't used in future
|
|
|
|
# reputation-based spam classifications (but other verified DKIM domains are)
|
|
|
|
# because the forwarding server is not a useful spam signal for future messages.
|
|
|
|
# (optional)
|
|
|
|
IsForward: false
|
|
|
|
|
|
|
|
# Influences spam filtering only, this option does not change whether a message
|
2023-08-09 19:03:29 +03:00
|
|
|
# matches this ruleset. If this domain matches an SPF- and/or DKIM-verified
|
|
|
|
# (sub)domain, the message is accepted without further spam checks, such as a junk
|
|
|
|
# filter or DMARC reject evaluation. DMARC rejects should not apply for mailing
|
|
|
|
# lists that are not configured to rewrite the From-header of messages that don't
|
|
|
|
# have a passing DKIM signature of the From-domain. Otherwise, by rejecting
|
|
|
|
# messages, you may be automatically unsubscribed from the mailing list. The
|
|
|
|
# assumption is that mailing lists do their own spam filtering/moderation.
|
|
|
|
# (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
ListAllowDomain:
|
|
|
|
|
2023-08-09 23:31:37 +03:00
|
|
|
# Influences spam filtering only, this option does not change whether a message
|
2023-08-09 19:03:29 +03:00
|
|
|
# matches this ruleset. If a message is classified as spam, it isn't rejected
|
|
|
|
# during the SMTP transaction (the normal behaviour), but accepted during the SMTP
|
|
|
|
# transaction and delivered to the specified mailbox. The specified mailbox is not
|
|
|
|
# automatically cleaned up like the account global Rejects mailbox, unless set to
|
|
|
|
# that Rejects mailbox. (optional)
|
|
|
|
AcceptRejectsToMailbox:
|
|
|
|
|
2023-02-11 01:47:19 +03:00
|
|
|
# Mailbox to deliver to if this ruleset matches.
|
2023-01-30 16:27:06 +03:00
|
|
|
Mailbox:
|
|
|
|
|
add webmail
it was far down on the roadmap, but implemented earlier, because it's
interesting, and to help prepare for a jmap implementation. for jmap we need to
implement more client-like functionality than with just imap. internal data
structures need to change. jmap has lots of other requirements, so it's already
a big project. by implementing a webmail now, some of the required data
structure changes become clear and can be made now, so the later jmap
implementation can do things similarly to the webmail code. the webmail
frontend and webmail are written together, making their interface/api much
smaller and simpler than jmap.
one of the internal changes is that we now keep track of per-mailbox
total/unread/unseen/deleted message counts and mailbox sizes. keeping this
data consistent after any change to the stored messages (through the code base)
is tricky, so mox now has a consistency check that verifies the counts are
correct, which runs only during tests, each time an internal account reference
is closed. we have a few more internal "changes" that are propagated for the
webmail frontend (that imap doesn't have a way to propagate on a connection),
like changes to the special-use flags on mailboxes, and used keywords in a
mailbox. more changes that will be required have revealed themselves while
implementing the webmail, and will be implemented next.
the webmail user interface is modeled after the mail clients i use or have
used: thunderbird, macos mail, mutt; and webmails i normally only use for
testing: gmail, proton, yahoo, outlook. a somewhat technical user is assumed,
but still the goal is to make this webmail client easy to use for everyone. the
user interface looks like most other mail clients: a list of mailboxes, a
search bar, a message list view, and message details. there is a top/bottom and
a left/right layout for the list/message view, default is automatic based on
screen size. the panes can be resized by the user. buttons for actions are just
text, not icons. clicking a button briefly shows the shortcut for the action in
the bottom right, helping with learning to operate quickly. any text that is
underdotted has a title attribute that causes more information to be displayed,
e.g. what a button does or a field is about. to highlight potential phishing
attempts, any text (anywhere in the webclient) that switches unicode "blocks"
(a rough approximation to (language) scripts) within a word is underlined
orange. multiple messages can be selected with familiar ui interaction:
clicking while holding control and/or shift keys. keyboard navigation works
with arrows/page up/down and home/end keys, and also with a few basic vi-like
keys for list/message navigation. we prefer showing the text instead of
html (with inlined images only) version of a message. html messages are shown
in an iframe served from an endpoint with CSP headers to prevent dangerous
resources (scripts, external images) from being loaded. the html is also
sanitized, with javascript removed. a user can choose to load external
resources (e.g. images for tracking purposes).
the frontend is just (strict) typescript, no external frameworks. all
incoming/outgoing data is typechecked, both the api request parameters and
response types, and the data coming in over SSE. the types and checking code
are generated with sherpats, which uses the api definitions generated by
sherpadoc based on the Go code. so types from the backend are automatically
propagated to the frontend. since there is no framework to automatically
propagate properties and rerender components, changes coming in over the SSE
connection are propagated explicitly with regular function calls. the ui is
separated into "views", each with a "root" dom element that is added to the
visible document. these views have additional functions for getting changes
propagated, often resulting in the view updating its (internal) ui state (dom).
we keep the frontend compilation simple, it's just a few typescript files that
get compiled (combined and types stripped) into a single js file, no additional
runtime code needed or complicated build processes used. the webmail is served
is served from a compressed, cachable html file that includes style and the
javascript, currently just over 225kb uncompressed, under 60kb compressed (not
minified, including comments). we include the generated js files in the
repository, to keep Go's easily buildable self-contained binaries.
authentication is basic http, as with the account and admin pages. most data
comes in over one long-term SSE connection to the backend. api requests signal
which mailbox/search/messages are requested over the SSE connection. fetching
individual messages, and making changes, are done through api calls. the
operations are similar to imap, so some code has been moved from package
imapserver to package store. the future jmap implementation will benefit from
these changes too. more functionality will probably be moved to the store
package in the future.
the quickstart enables webmail on the internal listener by default (for new
installs). users can enable it on the public listener if they want to. mox
localserve enables it too. to enable webmail on existing installs, add settings
like the following to the listeners in mox.conf, similar to AccountHTTP(S):
WebmailHTTP:
Enabled: true
WebmailHTTPS:
Enabled: true
special thanks to liesbeth, gerben, andrii for early user feedback.
there is plenty still to do, see the list at the top of webmail/webmail.ts.
feedback welcome as always.
2023-08-07 22:57:03 +03:00
|
|
|
# Full name to use in message From header when composing messages coming from this
|
|
|
|
# address with webmail. (optional)
|
|
|
|
FullName:
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# If configured, messages classified as weakly spam are rejected with instructions
|
|
|
|
# to retry delivery, but this time with a signed token added to the subject.
|
|
|
|
# During the next delivery attempt, the signed token will bypass the spam filter.
|
|
|
|
# Messages with a clear spam signal, such as a known bad reputation, are
|
|
|
|
# rejected/delayed without a signed token. (optional)
|
|
|
|
SubjectPass:
|
|
|
|
|
|
|
|
# How long unique values are accepted after generating, e.g. 12h.
|
|
|
|
Period: 0s
|
|
|
|
|
2023-12-20 22:54:12 +03:00
|
|
|
# Default maximum total message size for the account, overriding any globally
|
|
|
|
# configured maximum size if non-zero. A negative value can be used to have no
|
|
|
|
# limit in case there is a limit by default. Attempting to add new messages beyond
|
|
|
|
# the maximum size will result in an error. Useful to prevent a single account
|
|
|
|
# from filling storage. (optional)
|
|
|
|
QuotaMessageSize: 0
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# Mail that looks like spam will be rejected, but a copy can be stored temporarily
|
|
|
|
# in a mailbox, e.g. Rejects. If mail isn't coming in when you expect, you can
|
|
|
|
# look there. The mail still isn't accepted, so the remote mail server may retry
|
|
|
|
# (hopefully, if legitimate), or give up (hopefully, if indeed a spammer).
|
improve training of junk filter
before, we used heuristics to decide when to train/untrain a message as junk or
nonjunk: the message had to be seen, be in certain mailboxes. then if a message
was marked as junk, it was junk. and otherwise it was nonjunk. this wasn't good
enough: you may want to keep some messages around as neither junk or nonjunk.
and that wasn't possible.
ideally, we would just look at the imap $Junk and $NotJunk flags. the problem
is that mail clients don't set these flags, or don't make it easy. thunderbird
can set the flags based on its own bayesian filter. it has a shortcut for
marking Junk and moving it to the junk folder (good), but the counterpart of
notjunk only marks a message as notjunk without showing in the UI that it was
marked as notjunk. there is also no "move and mark as notjunk" mechanism. e.g.
"archive" does not mark a message as notjunk. ios mail and mutt don't appear to
have any way to see or change the $Junk and $NotJunk flags.
what email clients do have is the ability to move messages to other
mailboxes/folders. so mox now has a mechanism that allows you to configure
mailboxes that automatically set $Junk or $NotJunk (or clear both) when a
message is moved/copied/delivered to that folder. e.g. a mailbox called junk or
spam or rejects marks its messags as junk. inbox, postmaster, dmarc, tlsrpt,
neutral* mark their messages as neither junk or notjunk. other folders mark
their messages as notjunk. e.g. list/*, archive. this functionality is
optional, but enabled with the quickstart and for new accounts.
also, mox now keeps track of the previous training of a message and will only
untrain/train if needed. before, there probably have been duplicate or missing
(un)trainings.
this also includes a new subcommand "retrain" to recreate the junkfilter for an
account. you should run it after updating to this version. and you should
probably also modify your account config to include the AutomaticJunkFlags.
2023-02-12 01:00:12 +03:00
|
|
|
# Messages are automatically removed from this mailbox, so do not set it to a
|
|
|
|
# mailbox that has messages you want to keep. (optional)
|
2023-01-30 16:27:06 +03:00
|
|
|
RejectsMailbox:
|
|
|
|
|
2023-07-23 18:08:39 +03:00
|
|
|
# Don't automatically delete mail in the RejectsMailbox listed above. This can be
|
|
|
|
# useful, e.g. for future spam training. (optional)
|
|
|
|
KeepRejects: false
|
2023-07-23 18:03:09 +03:00
|
|
|
|
improve training of junk filter
before, we used heuristics to decide when to train/untrain a message as junk or
nonjunk: the message had to be seen, be in certain mailboxes. then if a message
was marked as junk, it was junk. and otherwise it was nonjunk. this wasn't good
enough: you may want to keep some messages around as neither junk or nonjunk.
and that wasn't possible.
ideally, we would just look at the imap $Junk and $NotJunk flags. the problem
is that mail clients don't set these flags, or don't make it easy. thunderbird
can set the flags based on its own bayesian filter. it has a shortcut for
marking Junk and moving it to the junk folder (good), but the counterpart of
notjunk only marks a message as notjunk without showing in the UI that it was
marked as notjunk. there is also no "move and mark as notjunk" mechanism. e.g.
"archive" does not mark a message as notjunk. ios mail and mutt don't appear to
have any way to see or change the $Junk and $NotJunk flags.
what email clients do have is the ability to move messages to other
mailboxes/folders. so mox now has a mechanism that allows you to configure
mailboxes that automatically set $Junk or $NotJunk (or clear both) when a
message is moved/copied/delivered to that folder. e.g. a mailbox called junk or
spam or rejects marks its messags as junk. inbox, postmaster, dmarc, tlsrpt,
neutral* mark their messages as neither junk or notjunk. other folders mark
their messages as notjunk. e.g. list/*, archive. this functionality is
optional, but enabled with the quickstart and for new accounts.
also, mox now keeps track of the previous training of a message and will only
untrain/train if needed. before, there probably have been duplicate or missing
(un)trainings.
this also includes a new subcommand "retrain" to recreate the junkfilter for an
account. you should run it after updating to this version. and you should
probably also modify your account config to include the AutomaticJunkFlags.
2023-02-12 01:00:12 +03:00
|
|
|
# Automatically set $Junk and $NotJunk flags based on mailbox messages are
|
|
|
|
# delivered/moved/copied to. Email clients typically have too limited
|
|
|
|
# functionality to conveniently set these flags, especially $NonJunk, but they can
|
|
|
|
# all move messages to a different mailbox, so this helps them. (optional)
|
|
|
|
AutomaticJunkFlags:
|
|
|
|
|
|
|
|
# If enabled, flags will be set automatically if they match a regular expression
|
2023-02-13 12:47:20 +03:00
|
|
|
# below. When two of the three mailbox regular expressions are set, the remaining
|
|
|
|
# one will match all unmatched messages. Messages are matched in the order
|
|
|
|
# specified and the search stops on the first match. Mailboxes are lowercased
|
|
|
|
# before matching.
|
improve training of junk filter
before, we used heuristics to decide when to train/untrain a message as junk or
nonjunk: the message had to be seen, be in certain mailboxes. then if a message
was marked as junk, it was junk. and otherwise it was nonjunk. this wasn't good
enough: you may want to keep some messages around as neither junk or nonjunk.
and that wasn't possible.
ideally, we would just look at the imap $Junk and $NotJunk flags. the problem
is that mail clients don't set these flags, or don't make it easy. thunderbird
can set the flags based on its own bayesian filter. it has a shortcut for
marking Junk and moving it to the junk folder (good), but the counterpart of
notjunk only marks a message as notjunk without showing in the UI that it was
marked as notjunk. there is also no "move and mark as notjunk" mechanism. e.g.
"archive" does not mark a message as notjunk. ios mail and mutt don't appear to
have any way to see or change the $Junk and $NotJunk flags.
what email clients do have is the ability to move messages to other
mailboxes/folders. so mox now has a mechanism that allows you to configure
mailboxes that automatically set $Junk or $NotJunk (or clear both) when a
message is moved/copied/delivered to that folder. e.g. a mailbox called junk or
spam or rejects marks its messags as junk. inbox, postmaster, dmarc, tlsrpt,
neutral* mark their messages as neither junk or notjunk. other folders mark
their messages as notjunk. e.g. list/*, archive. this functionality is
optional, but enabled with the quickstart and for new accounts.
also, mox now keeps track of the previous training of a message and will only
untrain/train if needed. before, there probably have been duplicate or missing
(un)trainings.
this also includes a new subcommand "retrain" to recreate the junkfilter for an
account. you should run it after updating to this version. and you should
probably also modify your account config to include the AutomaticJunkFlags.
2023-02-12 01:00:12 +03:00
|
|
|
Enabled: false
|
|
|
|
|
2023-02-13 12:47:20 +03:00
|
|
|
# Example: ^(junk|spam). (optional)
|
improve training of junk filter
before, we used heuristics to decide when to train/untrain a message as junk or
nonjunk: the message had to be seen, be in certain mailboxes. then if a message
was marked as junk, it was junk. and otherwise it was nonjunk. this wasn't good
enough: you may want to keep some messages around as neither junk or nonjunk.
and that wasn't possible.
ideally, we would just look at the imap $Junk and $NotJunk flags. the problem
is that mail clients don't set these flags, or don't make it easy. thunderbird
can set the flags based on its own bayesian filter. it has a shortcut for
marking Junk and moving it to the junk folder (good), but the counterpart of
notjunk only marks a message as notjunk without showing in the UI that it was
marked as notjunk. there is also no "move and mark as notjunk" mechanism. e.g.
"archive" does not mark a message as notjunk. ios mail and mutt don't appear to
have any way to see or change the $Junk and $NotJunk flags.
what email clients do have is the ability to move messages to other
mailboxes/folders. so mox now has a mechanism that allows you to configure
mailboxes that automatically set $Junk or $NotJunk (or clear both) when a
message is moved/copied/delivered to that folder. e.g. a mailbox called junk or
spam or rejects marks its messags as junk. inbox, postmaster, dmarc, tlsrpt,
neutral* mark their messages as neither junk or notjunk. other folders mark
their messages as notjunk. e.g. list/*, archive. this functionality is
optional, but enabled with the quickstart and for new accounts.
also, mox now keeps track of the previous training of a message and will only
untrain/train if needed. before, there probably have been duplicate or missing
(un)trainings.
this also includes a new subcommand "retrain" to recreate the junkfilter for an
account. you should run it after updating to this version. and you should
probably also modify your account config to include the AutomaticJunkFlags.
2023-02-12 01:00:12 +03:00
|
|
|
JunkMailboxRegexp:
|
|
|
|
|
2023-02-13 12:47:20 +03:00
|
|
|
# Example: ^(inbox|neutral|postmaster|dmarc|tlsrpt|rejects), and you may wish to
|
|
|
|
# add trash depending on how you use it, or leave this empty. (optional)
|
improve training of junk filter
before, we used heuristics to decide when to train/untrain a message as junk or
nonjunk: the message had to be seen, be in certain mailboxes. then if a message
was marked as junk, it was junk. and otherwise it was nonjunk. this wasn't good
enough: you may want to keep some messages around as neither junk or nonjunk.
and that wasn't possible.
ideally, we would just look at the imap $Junk and $NotJunk flags. the problem
is that mail clients don't set these flags, or don't make it easy. thunderbird
can set the flags based on its own bayesian filter. it has a shortcut for
marking Junk and moving it to the junk folder (good), but the counterpart of
notjunk only marks a message as notjunk without showing in the UI that it was
marked as notjunk. there is also no "move and mark as notjunk" mechanism. e.g.
"archive" does not mark a message as notjunk. ios mail and mutt don't appear to
have any way to see or change the $Junk and $NotJunk flags.
what email clients do have is the ability to move messages to other
mailboxes/folders. so mox now has a mechanism that allows you to configure
mailboxes that automatically set $Junk or $NotJunk (or clear both) when a
message is moved/copied/delivered to that folder. e.g. a mailbox called junk or
spam or rejects marks its messags as junk. inbox, postmaster, dmarc, tlsrpt,
neutral* mark their messages as neither junk or notjunk. other folders mark
their messages as notjunk. e.g. list/*, archive. this functionality is
optional, but enabled with the quickstart and for new accounts.
also, mox now keeps track of the previous training of a message and will only
untrain/train if needed. before, there probably have been duplicate or missing
(un)trainings.
this also includes a new subcommand "retrain" to recreate the junkfilter for an
account. you should run it after updating to this version. and you should
probably also modify your account config to include the AutomaticJunkFlags.
2023-02-12 01:00:12 +03:00
|
|
|
NeutralMailboxRegexp:
|
|
|
|
|
|
|
|
# Example: .* or an empty string. (optional)
|
|
|
|
NotJunkMailboxRegexp:
|
|
|
|
|
2023-01-30 16:27:06 +03:00
|
|
|
# Content-based filtering, using the junk-status of individual messages to rank
|
|
|
|
# words in such messages as spam or ham. It is recommended you always set the
|
|
|
|
# applicable (non)-junk status on messages, and that you do not empty your Trash
|
|
|
|
# because those messages contain valuable ham/spam training information.
|
|
|
|
# (optional)
|
|
|
|
JunkFilter:
|
|
|
|
|
|
|
|
# Approximate spaminess score between 0 and 1 above which emails are rejected as
|
|
|
|
# spam. Each delivery attempt adds a little noise to make it slightly harder for
|
|
|
|
# spammers to identify words that strongly indicate non-spaminess and use it to
|
|
|
|
# bypass the filter. E.g. 0.95.
|
|
|
|
Threshold: 0.000000
|
|
|
|
Params:
|
|
|
|
|
|
|
|
# Track ham/spam ranking for single words. (optional)
|
|
|
|
Onegrams: false
|
|
|
|
|
|
|
|
# Track ham/spam ranking for each two consecutive words. (optional)
|
|
|
|
Twograms: false
|
|
|
|
|
|
|
|
# Track ham/spam ranking for each three consecutive words. (optional)
|
|
|
|
Threegrams: false
|
|
|
|
|
|
|
|
# Maximum power a word (combination) can have. If spaminess is 0.99, and max power
|
|
|
|
# is 0.1, spaminess of the word will be set to 0.9. Similar for ham words.
|
|
|
|
MaxPower: 0.000000
|
|
|
|
|
|
|
|
# Number of most spammy/hammy words to use for calculating probability. E.g. 10.
|
|
|
|
TopWords: 0
|
|
|
|
|
|
|
|
# Ignore words that are this much away from 0.5 haminess/spaminess. E.g. 0.1,
|
|
|
|
# causing word (combinations) of 0.4 to 0.6 to be ignored. (optional)
|
|
|
|
IgnoreWords: 0.000000
|
|
|
|
|
|
|
|
# Occurrences in word database until a word is considered rare and its influence
|
|
|
|
# in calculating probability reduced. E.g. 1 or 2. (optional)
|
|
|
|
RareWords: 0
|
2023-03-01 00:12:27 +03:00
|
|
|
|
2023-03-28 21:50:36 +03:00
|
|
|
# Maximum number of outgoing messages for this account in a 24 hour window. This
|
|
|
|
# limits the damage to recipients and the reputation of this mail server in case
|
|
|
|
# of account compromise. Default 1000. (optional)
|
|
|
|
MaxOutgoingMessagesPerDay: 0
|
|
|
|
|
|
|
|
# Maximum number of first-time recipients in outgoing messages for this account in
|
|
|
|
# a 24 hour window. This limits the damage to recipients and the reputation of
|
|
|
|
# this mail server in case of account compromise. Default 200. (optional)
|
|
|
|
MaxFirstTimeRecipientsPerDay: 0
|
|
|
|
|
new feature: when delivering messages from the queue, make it possible to use a "transport"
the default transport is still just "direct delivery", where we connect to the
destination domain's MX servers.
other transports are:
- regular smtp without authentication, this is relaying to a smarthost.
- submission with authentication, e.g. to a third party email sending service.
- direct delivery, but with with connections going through a socks proxy. this
can be helpful if your ip is blocked, you need to get email out, and you have
another IP that isn't blocked.
keep in mind that for all of the above, appropriate SPF/DKIM settings have to
be configured. the "dnscheck" for a domain does a check for any SOCKS IP in the
SPF record. SPF for smtp/submission (ranges? includes?) and any DKIM
requirements cannot really be checked.
which transport is used can be configured through routes. routes can be set on
an account, a domain, or globally. the routes are evaluated in that order, with
the first match selecting the transport. these routes are evaluated for each
delivery attempt. common selection criteria are recipient domain and sender
domain, but also which delivery attempt this is. you could configured mox to
attempt sending through a 3rd party from the 4th attempt onwards.
routes and transports are optional. if no route matches, or an empty/zero
transport is selected, normal direct delivery is done.
we could already "submit" emails with 3rd party accounts with "sendmail". but
we now support more SASL authentication mechanisms with SMTP (not only PLAIN,
but also SCRAM-SHA-256, SCRAM-SHA-1 and CRAM-MD5), which sendmail now also
supports. sendmail will use the most secure mechanism supported by the server,
or the explicitly configured mechanism.
for issue #36 by dmikushin. also based on earlier discussion on hackernews.
2023-06-16 19:38:28 +03:00
|
|
|
# Routes for delivering outgoing messages through the queue. Each delivery attempt
|
|
|
|
# evaluates these account routes, domain routes and finally global routes. The
|
|
|
|
# transport of the first matching route is used in the delivery attempt. If no
|
|
|
|
# routes match, which is the default with no configured routes, messages are
|
|
|
|
# delivered directly from the queue. (optional)
|
|
|
|
Routes:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Matches if the envelope from domain matches one of the configured domains, or if
|
|
|
|
# the list is empty. If a domain starts with a dot, prefixes of the domain also
|
|
|
|
# match. (optional)
|
|
|
|
FromDomain:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Like FromDomain, but matching against the envelope to domain. (optional)
|
|
|
|
ToDomain:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Matches if at least this many deliveries have already been attempted. This can
|
|
|
|
# be used to attempt sending through a smarthost when direct delivery has failed
|
|
|
|
# for several times. (optional)
|
|
|
|
MinimumAttempts: 0
|
|
|
|
Transport:
|
|
|
|
|
improve webserver, add domain redirects (aliases), add tests and admin page ui to manage the config
- make builtin http handlers serve on specific domains, such as for mta-sts, so
e.g. /.well-known/mta-sts.txt isn't served on all domains.
- add logging of a few more fields in access logging.
- small tweaks/bug fixes in webserver request handling.
- add config option for redirecting entire domains to another (common enough).
- split httpserver metric into two: one for duration until writing header (i.e.
performance of server), another for duration until full response is sent to
client (i.e. performance as perceived by users).
- add admin ui, a new page for managing the configs. after making changes
and hitting "save", the changes take effect immediately. the page itself
doesn't look very well-designed (many input fields, makes it look messy). i
have an idea to improve it (explained in admin.html as todo) by making the
layout look just like the config file. not urgent though.
i've already changed my websites/webapps over.
the idea of adding a webserver is to take away a (the) reason for folks to want
to complicate their mox setup by running an other webserver on the same machine.
i think the current webserver implementation can already serve most common use
cases. with a few more tweaks (feedback needed!) we should be able to get to 95%
of the use cases. the reverse proxy can take care of the remaining 5%.
nevertheless, a next step is still to change the quickstart to make it easier
for folks to run with an existing webserver, with existing tls certs/keys.
that's how this relates to issue #5.
2023-03-02 20:15:54 +03:00
|
|
|
# Redirect all requests from domain (key) to domain (value). Always redirects to
|
|
|
|
# HTTPS. For plain HTTP redirects, use a WebHandler with a WebRedirect. (optional)
|
|
|
|
WebDomainRedirects:
|
|
|
|
x:
|
|
|
|
|
2023-03-01 00:12:27 +03:00
|
|
|
# Handle webserver requests by serving static files, redirecting or
|
|
|
|
# reverse-proxying HTTP(s). The first matching WebHandler will handle the request.
|
2023-03-09 01:29:44 +03:00
|
|
|
# Built-in handlers, e.g. for account, admin, autoconfig and mta-sts always run
|
|
|
|
# first. If no handler matches, the response status code is file not found (404).
|
|
|
|
# If functionality you need is missng, simply forward the requests to an
|
|
|
|
# application that can provide the needed functionality. (optional)
|
2023-03-01 00:12:27 +03:00
|
|
|
WebHandlers:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Name to use in logging and metrics. (optional)
|
|
|
|
LogName:
|
|
|
|
|
|
|
|
# Both Domain and PathRegexp must match for this WebHandler to match a request.
|
|
|
|
# Exactly one of WebStatic, WebRedirect, WebForward must be set.
|
|
|
|
Domain:
|
|
|
|
|
|
|
|
# Regular expression matched against request path, must always start with ^ to
|
|
|
|
# ensure matching from the start of the path. The matching prefix can optionally
|
|
|
|
# be stripped by WebForward. The regular expression does not have to end with $.
|
|
|
|
PathRegexp:
|
|
|
|
|
|
|
|
# If set, plain HTTP requests are not automatically permanently redirected (308)
|
|
|
|
# to HTTPS. If you don't have a HTTPS webserver configured, set this to true.
|
|
|
|
# (optional)
|
|
|
|
DontRedirectPlainHTTP: false
|
|
|
|
|
2023-08-21 22:52:35 +03:00
|
|
|
# Transparently compress responses (currently with gzip) if the client supports
|
|
|
|
# it, the status is 200 OK, no Content-Encoding is set on the response yet and the
|
|
|
|
# Content-Type of the response hints that the data is compressible (text/...,
|
|
|
|
# specific application/... and .../...+json and .../...+xml). For static files
|
|
|
|
# only, a cache with compressed files is kept. (optional)
|
|
|
|
Compress: false
|
|
|
|
|
2023-03-01 00:12:27 +03:00
|
|
|
# Serve static files. (optional)
|
|
|
|
WebStatic:
|
|
|
|
|
|
|
|
# Path to strip from the request URL before evaluating to a local path. If the
|
|
|
|
# requested URL path does not start with this prefix and ContinueNotFound it is
|
|
|
|
# considered non-matching and next WebHandlers are tried. If ContinueNotFound is
|
|
|
|
# not set, a file not found (404) is returned in that case. (optional)
|
|
|
|
StripPrefix:
|
|
|
|
|
|
|
|
# Directory to serve files from for this handler. Keep in mind that relative paths
|
|
|
|
# are relative to the working directory of mox.
|
|
|
|
Root:
|
|
|
|
|
|
|
|
# If set, and a directory is requested, and no index.html is present that can be
|
|
|
|
# served, a file listing is returned. Results in 403 if ListFiles is not set. If a
|
|
|
|
# directory is requested and the URL does not end with a slash, the response is a
|
|
|
|
# redirect to the path with trailing slash. (optional)
|
|
|
|
ListFiles: false
|
|
|
|
|
|
|
|
# If a requested URL does not exist, don't return a file not found (404) response,
|
|
|
|
# but consider this handler non-matching and continue attempts to serve with later
|
|
|
|
# WebHandlers, which may be a reverse proxy generating dynamic content, possibly
|
|
|
|
# even writing a static file for a next request to serve statically. If
|
|
|
|
# ContinueNotFound is set, HTTP requests other than GET and HEAD do not match.
|
|
|
|
# This mechanism can be used to implement the equivalent of 'try_files' in other
|
|
|
|
# webservers. (optional)
|
|
|
|
ContinueNotFound: false
|
|
|
|
|
|
|
|
# Headers to add to the response. Useful for cache-control, content-type, etc. By
|
|
|
|
# default, Content-Type headers are automatically added for recognized file types,
|
|
|
|
# unless added explicitly through this setting. For directory listings, a
|
|
|
|
# content-type header is skipped. (optional)
|
|
|
|
ResponseHeaders:
|
|
|
|
x:
|
|
|
|
|
|
|
|
# Redirect requests to configured URL. (optional)
|
|
|
|
WebRedirect:
|
|
|
|
|
|
|
|
# Base URL to redirect to. The path must be empty and will be replaced, either by
|
improve webserver, add domain redirects (aliases), add tests and admin page ui to manage the config
- make builtin http handlers serve on specific domains, such as for mta-sts, so
e.g. /.well-known/mta-sts.txt isn't served on all domains.
- add logging of a few more fields in access logging.
- small tweaks/bug fixes in webserver request handling.
- add config option for redirecting entire domains to another (common enough).
- split httpserver metric into two: one for duration until writing header (i.e.
performance of server), another for duration until full response is sent to
client (i.e. performance as perceived by users).
- add admin ui, a new page for managing the configs. after making changes
and hitting "save", the changes take effect immediately. the page itself
doesn't look very well-designed (many input fields, makes it look messy). i
have an idea to improve it (explained in admin.html as todo) by making the
layout look just like the config file. not urgent though.
i've already changed my websites/webapps over.
the idea of adding a webserver is to take away a (the) reason for folks to want
to complicate their mox setup by running an other webserver on the same machine.
i think the current webserver implementation can already serve most common use
cases. with a few more tweaks (feedback needed!) we should be able to get to 95%
of the use cases. the reverse proxy can take care of the remaining 5%.
nevertheless, a next step is still to change the quickstart to make it easier
for folks to run with an existing webserver, with existing tls certs/keys.
that's how this relates to issue #5.
2023-03-02 20:15:54 +03:00
|
|
|
# the request URL path, or by OrigPathRegexp/ReplacePath. Scheme, host, port and
|
2023-03-01 00:12:27 +03:00
|
|
|
# fragment stay intact, and query strings are combined. If empty, the response
|
|
|
|
# redirects to a different path through OrigPathRegexp and ReplacePath, which must
|
|
|
|
# then be set. Use a URL without scheme to redirect without changing the protocol,
|
2023-03-09 01:29:44 +03:00
|
|
|
# e.g. //newdomain/. If a redirect would send a request to a URL with the same
|
|
|
|
# scheme, host and path, the WebRedirect does not match so a next WebHandler can
|
|
|
|
# be tried. This can be used to redirect all plain http traffic to https.
|
|
|
|
# (optional)
|
2023-03-01 00:12:27 +03:00
|
|
|
BaseURL:
|
|
|
|
|
|
|
|
# Regular expression for matching path. If set and path does not match, a 404 is
|
|
|
|
# returned. The HTTP path used for matching always starts with a slash. (optional)
|
|
|
|
OrigPathRegexp:
|
|
|
|
|
|
|
|
# Replacement path for destination URL based on OrigPathRegexp. Implemented with
|
|
|
|
# Go's Regexp.ReplaceAllString: $1 is replaced with the text of the first
|
|
|
|
# submatch, etc. If both OrigPathRegexp and ReplacePath are empty, BaseURL must be
|
|
|
|
# set and all paths are redirected unaltered. (optional)
|
|
|
|
ReplacePath:
|
|
|
|
|
|
|
|
# Status code to use in redirect, e.g. 307. By default, a permanent redirect (308)
|
|
|
|
# is returned. (optional)
|
|
|
|
StatusCode: 0
|
|
|
|
|
|
|
|
# Forward requests to another webserver, i.e. reverse proxy. (optional)
|
|
|
|
WebForward:
|
|
|
|
|
|
|
|
# Strip the matching WebHandler path from the WebHandler before forwarding the
|
|
|
|
# request. (optional)
|
|
|
|
StripPath: false
|
|
|
|
|
|
|
|
# URL to forward HTTP requests to, e.g. http://127.0.0.1:8123/base. If StripPath
|
|
|
|
# is false the full request path is added to the URL. Host headers are sent
|
|
|
|
# unmodified. New X-Forwarded-{For,Host,Proto} headers are set. Any query string
|
|
|
|
# in the URL is ignored. Requests are made using Go's net/http.DefaultTransport
|
|
|
|
# that takes environment variables HTTP_PROXY and HTTPS_PROXY into account.
|
2023-05-30 23:11:31 +03:00
|
|
|
# Websocket connections are forwarded and data is copied between client and
|
|
|
|
# backend without looking at the framing. The websocket 'version' and
|
|
|
|
# 'key'/'accept' headers are verified during the handshake, but other websocket
|
|
|
|
# headers, including 'origin', 'protocol' and 'extensions' headers, are not
|
|
|
|
# inspected and the backend is responsible for verifying/interpreting them.
|
2023-03-01 00:12:27 +03:00
|
|
|
URL:
|
|
|
|
|
|
|
|
# Headers to add to the response. Useful for adding security- and cache-related
|
|
|
|
# headers. (optional)
|
|
|
|
ResponseHeaders:
|
|
|
|
x:
|
|
|
|
|
new feature: when delivering messages from the queue, make it possible to use a "transport"
the default transport is still just "direct delivery", where we connect to the
destination domain's MX servers.
other transports are:
- regular smtp without authentication, this is relaying to a smarthost.
- submission with authentication, e.g. to a third party email sending service.
- direct delivery, but with with connections going through a socks proxy. this
can be helpful if your ip is blocked, you need to get email out, and you have
another IP that isn't blocked.
keep in mind that for all of the above, appropriate SPF/DKIM settings have to
be configured. the "dnscheck" for a domain does a check for any SOCKS IP in the
SPF record. SPF for smtp/submission (ranges? includes?) and any DKIM
requirements cannot really be checked.
which transport is used can be configured through routes. routes can be set on
an account, a domain, or globally. the routes are evaluated in that order, with
the first match selecting the transport. these routes are evaluated for each
delivery attempt. common selection criteria are recipient domain and sender
domain, but also which delivery attempt this is. you could configured mox to
attempt sending through a 3rd party from the 4th attempt onwards.
routes and transports are optional. if no route matches, or an empty/zero
transport is selected, normal direct delivery is done.
we could already "submit" emails with 3rd party accounts with "sendmail". but
we now support more SASL authentication mechanisms with SMTP (not only PLAIN,
but also SCRAM-SHA-256, SCRAM-SHA-1 and CRAM-MD5), which sendmail now also
supports. sendmail will use the most secure mechanism supported by the server,
or the explicitly configured mechanism.
for issue #36 by dmikushin. also based on earlier discussion on hackernews.
2023-06-16 19:38:28 +03:00
|
|
|
# Routes for delivering outgoing messages through the queue. Each delivery attempt
|
|
|
|
# evaluates account routes, domain routes and finally these global routes. The
|
|
|
|
# transport of the first matching route is used in the delivery attempt. If no
|
|
|
|
# routes match, which is the default with no configured routes, messages are
|
|
|
|
# delivered directly from the queue. (optional)
|
|
|
|
Routes:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Matches if the envelope from domain matches one of the configured domains, or if
|
|
|
|
# the list is empty. If a domain starts with a dot, prefixes of the domain also
|
|
|
|
# match. (optional)
|
|
|
|
FromDomain:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Like FromDomain, but matching against the envelope to domain. (optional)
|
|
|
|
ToDomain:
|
|
|
|
-
|
|
|
|
|
|
|
|
# Matches if at least this many deliveries have already been attempted. This can
|
|
|
|
# be used to attempt sending through a smarthost when direct delivery has failed
|
|
|
|
# for several times. (optional)
|
|
|
|
MinimumAttempts: 0
|
|
|
|
Transport:
|
|
|
|
|
2023-03-01 00:12:27 +03:00
|
|
|
# Examples
|
|
|
|
|
|
|
|
Mox includes configuration files to illustrate common setups. You can see these
|
2023-03-04 02:49:02 +03:00
|
|
|
examples with "mox example", and print a specific example with "mox example
|
2023-03-01 00:12:27 +03:00
|
|
|
<name>". Below are all examples included in mox.
|
|
|
|
|
|
|
|
# Example webhandlers
|
|
|
|
|
improve webserver, add domain redirects (aliases), add tests and admin page ui to manage the config
- make builtin http handlers serve on specific domains, such as for mta-sts, so
e.g. /.well-known/mta-sts.txt isn't served on all domains.
- add logging of a few more fields in access logging.
- small tweaks/bug fixes in webserver request handling.
- add config option for redirecting entire domains to another (common enough).
- split httpserver metric into two: one for duration until writing header (i.e.
performance of server), another for duration until full response is sent to
client (i.e. performance as perceived by users).
- add admin ui, a new page for managing the configs. after making changes
and hitting "save", the changes take effect immediately. the page itself
doesn't look very well-designed (many input fields, makes it look messy). i
have an idea to improve it (explained in admin.html as todo) by making the
layout look just like the config file. not urgent though.
i've already changed my websites/webapps over.
the idea of adding a webserver is to take away a (the) reason for folks to want
to complicate their mox setup by running an other webserver on the same machine.
i think the current webserver implementation can already serve most common use
cases. with a few more tweaks (feedback needed!) we should be able to get to 95%
of the use cases. the reverse proxy can take care of the remaining 5%.
nevertheless, a next step is still to change the quickstart to make it easier
for folks to run with an existing webserver, with existing tls certs/keys.
that's how this relates to issue #5.
2023-03-02 20:15:54 +03:00
|
|
|
# Snippet of domains.conf to configure WebDomainRedirects and WebHandlers.
|
|
|
|
|
|
|
|
# Redirect all requests for mox.example to https://www.mox.example.
|
|
|
|
WebDomainRedirects:
|
|
|
|
mox.example: www.mox.example
|
|
|
|
|
|
|
|
# Each request is matched against these handlers until one matches and serves it.
|
2023-03-01 00:12:27 +03:00
|
|
|
WebHandlers:
|
2023-03-09 01:29:44 +03:00
|
|
|
-
|
|
|
|
# Redirect all plain http requests to https, leaving path, query strings, etc
|
|
|
|
# intact. When the request is already to https, the destination URL would have the
|
|
|
|
# same scheme, host and path, causing this redirect handler to not match the
|
|
|
|
# request (and not cause a redirect loop) and the webserver to serve the request
|
|
|
|
# with a later handler.
|
|
|
|
LogName: redirhttps
|
|
|
|
Domain: www.mox.example
|
|
|
|
PathRegexp: ^/
|
|
|
|
# Could leave DontRedirectPlainHTTP at false if it wasn't for this being an
|
|
|
|
# example for doing this redirect.
|
|
|
|
DontRedirectPlainHTTP: true
|
|
|
|
WebRedirect:
|
|
|
|
BaseURL: https://www.mox.example
|
2023-03-01 00:12:27 +03:00
|
|
|
-
|
|
|
|
# The name of the handler, used in logging and metrics.
|
|
|
|
LogName: staticmjl
|
|
|
|
# With ACME configured, each configured domain will automatically get a TLS
|
|
|
|
# certificate on first request.
|
improve webserver, add domain redirects (aliases), add tests and admin page ui to manage the config
- make builtin http handlers serve on specific domains, such as for mta-sts, so
e.g. /.well-known/mta-sts.txt isn't served on all domains.
- add logging of a few more fields in access logging.
- small tweaks/bug fixes in webserver request handling.
- add config option for redirecting entire domains to another (common enough).
- split httpserver metric into two: one for duration until writing header (i.e.
performance of server), another for duration until full response is sent to
client (i.e. performance as perceived by users).
- add admin ui, a new page for managing the configs. after making changes
and hitting "save", the changes take effect immediately. the page itself
doesn't look very well-designed (many input fields, makes it look messy). i
have an idea to improve it (explained in admin.html as todo) by making the
layout look just like the config file. not urgent though.
i've already changed my websites/webapps over.
the idea of adding a webserver is to take away a (the) reason for folks to want
to complicate their mox setup by running an other webserver on the same machine.
i think the current webserver implementation can already serve most common use
cases. with a few more tweaks (feedback needed!) we should be able to get to 95%
of the use cases. the reverse proxy can take care of the remaining 5%.
nevertheless, a next step is still to change the quickstart to make it easier
for folks to run with an existing webserver, with existing tls certs/keys.
that's how this relates to issue #5.
2023-03-02 20:15:54 +03:00
|
|
|
Domain: www.mox.example
|
2023-03-01 00:12:27 +03:00
|
|
|
PathRegexp: ^/who/mjl/
|
|
|
|
WebStatic:
|
|
|
|
StripPrefix: /who/mjl
|
|
|
|
# Requested path /who/mjl/inferno/ resolves to local web/mjl/inferno.
|
|
|
|
# If a directory contains an index.html, it is served when a directory is requested.
|
|
|
|
Root: web/mjl
|
|
|
|
# With ListFiles true, if a directory does not contain an index.html, the contents are listed.
|
|
|
|
ListFiles: true
|
|
|
|
ResponseHeaders:
|
|
|
|
X-Mox: hi
|
|
|
|
-
|
|
|
|
LogName: redir
|
improve webserver, add domain redirects (aliases), add tests and admin page ui to manage the config
- make builtin http handlers serve on specific domains, such as for mta-sts, so
e.g. /.well-known/mta-sts.txt isn't served on all domains.
- add logging of a few more fields in access logging.
- small tweaks/bug fixes in webserver request handling.
- add config option for redirecting entire domains to another (common enough).
- split httpserver metric into two: one for duration until writing header (i.e.
performance of server), another for duration until full response is sent to
client (i.e. performance as perceived by users).
- add admin ui, a new page for managing the configs. after making changes
and hitting "save", the changes take effect immediately. the page itself
doesn't look very well-designed (many input fields, makes it look messy). i
have an idea to improve it (explained in admin.html as todo) by making the
layout look just like the config file. not urgent though.
i've already changed my websites/webapps over.
the idea of adding a webserver is to take away a (the) reason for folks to want
to complicate their mox setup by running an other webserver on the same machine.
i think the current webserver implementation can already serve most common use
cases. with a few more tweaks (feedback needed!) we should be able to get to 95%
of the use cases. the reverse proxy can take care of the remaining 5%.
nevertheless, a next step is still to change the quickstart to make it easier
for folks to run with an existing webserver, with existing tls certs/keys.
that's how this relates to issue #5.
2023-03-02 20:15:54 +03:00
|
|
|
Domain: www.mox.example
|
2023-03-01 00:12:27 +03:00
|
|
|
PathRegexp: ^/redir/a/b/c
|
|
|
|
# Don't redirect from plain HTTP to HTTPS.
|
|
|
|
DontRedirectPlainHTTP: true
|
|
|
|
WebRedirect:
|
|
|
|
# Just change the domain and add query string set fragment. No change to scheme.
|
|
|
|
# Path will start with /redir/a/b/c (and whathever came after) because no
|
|
|
|
# OrigPathRegexp+ReplacePath is set.
|
|
|
|
BaseURL: //moxest.example?q=1#frag
|
|
|
|
# Default redirection is 308 - Permanent Redirect.
|
|
|
|
StatusCode: 307
|
|
|
|
-
|
|
|
|
LogName: oldnew
|
improve webserver, add domain redirects (aliases), add tests and admin page ui to manage the config
- make builtin http handlers serve on specific domains, such as for mta-sts, so
e.g. /.well-known/mta-sts.txt isn't served on all domains.
- add logging of a few more fields in access logging.
- small tweaks/bug fixes in webserver request handling.
- add config option for redirecting entire domains to another (common enough).
- split httpserver metric into two: one for duration until writing header (i.e.
performance of server), another for duration until full response is sent to
client (i.e. performance as perceived by users).
- add admin ui, a new page for managing the configs. after making changes
and hitting "save", the changes take effect immediately. the page itself
doesn't look very well-designed (many input fields, makes it look messy). i
have an idea to improve it (explained in admin.html as todo) by making the
layout look just like the config file. not urgent though.
i've already changed my websites/webapps over.
the idea of adding a webserver is to take away a (the) reason for folks to want
to complicate their mox setup by running an other webserver on the same machine.
i think the current webserver implementation can already serve most common use
cases. with a few more tweaks (feedback needed!) we should be able to get to 95%
of the use cases. the reverse proxy can take care of the remaining 5%.
nevertheless, a next step is still to change the quickstart to make it easier
for folks to run with an existing webserver, with existing tls certs/keys.
that's how this relates to issue #5.
2023-03-02 20:15:54 +03:00
|
|
|
Domain: www.mox.example
|
2023-03-01 00:12:27 +03:00
|
|
|
PathRegexp: ^/old/
|
|
|
|
WebRedirect:
|
|
|
|
# Replace path, leaving rest of URL intact.
|
|
|
|
OrigPathRegexp: ^/old/(.*)
|
|
|
|
ReplacePath: /new/$1
|
|
|
|
-
|
|
|
|
LogName: app
|
improve webserver, add domain redirects (aliases), add tests and admin page ui to manage the config
- make builtin http handlers serve on specific domains, such as for mta-sts, so
e.g. /.well-known/mta-sts.txt isn't served on all domains.
- add logging of a few more fields in access logging.
- small tweaks/bug fixes in webserver request handling.
- add config option for redirecting entire domains to another (common enough).
- split httpserver metric into two: one for duration until writing header (i.e.
performance of server), another for duration until full response is sent to
client (i.e. performance as perceived by users).
- add admin ui, a new page for managing the configs. after making changes
and hitting "save", the changes take effect immediately. the page itself
doesn't look very well-designed (many input fields, makes it look messy). i
have an idea to improve it (explained in admin.html as todo) by making the
layout look just like the config file. not urgent though.
i've already changed my websites/webapps over.
the idea of adding a webserver is to take away a (the) reason for folks to want
to complicate their mox setup by running an other webserver on the same machine.
i think the current webserver implementation can already serve most common use
cases. with a few more tweaks (feedback needed!) we should be able to get to 95%
of the use cases. the reverse proxy can take care of the remaining 5%.
nevertheless, a next step is still to change the quickstart to make it easier
for folks to run with an existing webserver, with existing tls certs/keys.
that's how this relates to issue #5.
2023-03-02 20:15:54 +03:00
|
|
|
Domain: www.mox.example
|
2023-03-01 00:12:27 +03:00
|
|
|
PathRegexp: ^/app/
|
|
|
|
WebForward:
|
|
|
|
# Strip the path matched by PathRegexp before forwarding the request. So original
|
|
|
|
# request /app/api become just /api.
|
|
|
|
StripPath: true
|
|
|
|
# URL of backend, where requests are forwarded to. The path in the URL is kept,
|
|
|
|
# so for incoming request URL /app/api, the outgoing request URL has path /app-v2/api.
|
|
|
|
# Requests are made with Go's net/http DefaultTransporter, including using
|
|
|
|
# HTTP_PROXY and HTTPS_PROXY environment variables.
|
|
|
|
URL: http://127.0.0.1:8900/app-v2/
|
|
|
|
# Add headers to response.
|
|
|
|
ResponseHeaders:
|
|
|
|
X-Frame-Options: deny
|
|
|
|
X-Content-Type-Options: nosniff
|
2024-01-01 17:12:40 +03:00
|
|
|
|
|
|
|
# Example transport
|
|
|
|
|
|
|
|
# Snippet for mox.conf, defining a transport called Example that connects on the
|
|
|
|
# SMTP submission with TLS port 465 ("submissions), authenticating with
|
|
|
|
# SCRAM-SHA-256-PLUS (other providers may not support SCRAM-SHA-256-PLUS, but they
|
|
|
|
# typically do support the older CRAM-MD5).:
|
|
|
|
|
|
|
|
# Transport are mechanisms for delivering messages. Transports can be referenced
|
|
|
|
# from Routes in accounts, domains and the global configuration. There is always
|
|
|
|
# an implicit/fallback delivery transport doing direct delivery with SMTP from the
|
|
|
|
# outgoing message queue. Transports are typically only configured when using
|
|
|
|
# smarthosts, i.e. when delivering through another SMTP server. Zero or one
|
|
|
|
# transport methods must be set in a transport, never multiple. When using an
|
|
|
|
# external party to send email for a domain, keep in mind you may have to add
|
|
|
|
# their IP address to your domain's SPF record, and possibly additional DKIM
|
|
|
|
# records. (optional)
|
|
|
|
Transports:
|
|
|
|
Example:
|
|
|
|
# Submission SMTP over a TLS connection to submit email to a remote queue.
|
|
|
|
# (optional)
|
|
|
|
Submissions:
|
|
|
|
# Host name to connect to and for verifying its TLS certificate.
|
|
|
|
Host: smtp.example.com
|
|
|
|
|
|
|
|
# If set, authentication credentials for the remote server. (optional)
|
|
|
|
Auth:
|
|
|
|
Username: user@example.com
|
|
|
|
Password: test1234
|
|
|
|
Mechanisms:
|
|
|
|
# Allowed authentication mechanisms. Defaults to SCRAM-SHA-256-PLUS,
|
|
|
|
# SCRAM-SHA-256, SCRAM-SHA-1-PLUS, SCRAM-SHA-1, CRAM-MD5. Not included by default:
|
|
|
|
# PLAIN. Specify the strongest mechanism known to be implemented by the server to
|
|
|
|
# prevent mechanism downgrade attacks. (optional)
|
|
|
|
|
|
|
|
- SCRAM-SHA-256-PLUS
|
|
|
|
|
|
|
|
|
|
|
|
# Snippet for domains.conf, specifying a route that sends through the transport:
|
|
|
|
|
|
|
|
# Routes for delivering outgoing messages through the queue. Each delivery attempt
|
|
|
|
# evaluates account routes, domain routes and finally these global routes. The
|
|
|
|
# transport of the first matching route is used in the delivery attempt. If no
|
|
|
|
# routes match, which is the default with no configured routes, messages are
|
|
|
|
# delivered directly from the queue. (optional)
|
|
|
|
Routes:
|
|
|
|
-
|
|
|
|
Transport: Example
|
2023-01-30 16:27:06 +03:00
|
|
|
*/
|
|
|
|
package config
|
|
|
|
|
|
|
|
// NOTE: DO NOT EDIT, this file is generated by ../gendoc.sh.
|