Split README into sphinx doc structured sections (#711)

refactor README.rst and architecture file into sphinx doc project, automatically deploying on main merges and PRs.

* add FAQs from https://chatmail.at/relays landing page

* fix links, and streamline postfix/dovecot mentioning

* add linkcheck to CI, fix several links and streamlihne DKIM section while at it

* some streamlining, rename to "overview"

* ci: upload documentation to chatmail.at/doc/relay

* ci: main should be uploaded when docs.yaml changes

* ci: fix typo

* Update .github/workflows/docs-preview.yaml

Co-authored-by: missytake <missytake@systemli.org>
This commit is contained in:
holger krekel
2025-11-11 14:49:25 +01:00
committed by GitHub
parent f24bc99c6f
commit 50b986a265
19 changed files with 1005 additions and 604 deletions

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" id="svg4" width="145" height="145" version="1.1"><g id="text2" aria-label="@" style="font-size:144px;font-family:Arial" transform="matrix(1.0934997,0,0,1.0934997,-6.7787266,-6.7787281)"><path id="path347" d="m 79.927878,94.422406 c -2.704286,3.120332 -5.741407,5.637394 -9.111364,7.551194 -3.328352,1.87221 -6.677506,2.80831 -10.047463,2.80831 -3.702792,0 -7.301573,-1.08172 -10.796342,-3.24515 -3.49477,-2.163426 -6.344671,-5.491779 -8.549704,-9.985058 -2.163429,-4.493275 -3.245144,-9.423397 -3.245144,-14.790365 0,-6.615099 1.684978,-13.230199 5.054935,-19.845299 3.411561,-6.656705 7.634407,-11.649233 12.66854,-14.977585 5.034133,-3.328352 9.92265,-4.992528 14.665552,-4.992528 3.619583,0 7.072748,0.956901 10.359496,2.870704 3.286748,1.872198 6.115847,4.742902 8.487297,8.612111 l 2.121825,-9.673023 h 11.170784 l -8.986557,41.87483 c -1.248129,5.824616 -1.872194,9.048957 -1.872194,9.673023 0,1.123319 0.416044,2.101022 1.248132,2.93311 0.873692,0.790484 1.913802,1.185726 3.120332,1.185726 2.20503,0 5.096537,-1.268934 8.674517,-3.806803 4.7429,-3.328352 8.4873,-7.780023 11.23319,-13.355013 2.78749,-5.616594 4.18124,-11.399606 4.18124,-17.349035 0,-6.947935 -1.78899,-13.438222 -5.36697,-19.47086 -3.53637,-6.032638 -8.84094,-10.858749 -15.913687,-14.478332 -7.03114,-3.619583 -14.811161,-5.429374 -23.340064,-5.429374 -9.73543,0 -18.638772,2.288242 -26.710026,6.864726 -8.029649,4.534879 -14.27031,11.06677 -18.721981,19.595673 -4.410066,8.487298 -6.615099,17.598662 -6.615099,27.334092 0,10.193078 2.205033,18.971607 6.615099,26.33559 2.290454,3.78888 -7.136335,18.96983 -3.810585,21.73443 3.138096,2.60861 18.971963,-7.14297 23.031819,-5.44631 8.404089,3.53637 17.702673,5.30456 27.895752,5.30456 10.90035,0 20.032515,-1.83059 27.396492,-5.49178 7.36399,-3.66119 12.87657,-8.11286 16.53776,-13.35501 l 9.29559,4 c -2.12183,4.36846 -3.76221,4.82013 -8.92116,9.35501 -5.15895,4.53488 -11.2956,8.11286 -18.40995,10.73393 -7.114346,2.66268 -15.684851,3.99402 -25.711512,3.99402 -9.236177,0 -17.76508,-1.18572 -25.586707,-3.55717 -7.780023,-2.37145 -29.296198,9.26152 -34.78798,4.47701 -5.49178,-4.7429 5.248856,-25.42482 2.461361,-31.62388 -3.49477,-7.863231 -5.242155,-16.350531 -5.242155,-25.461894 0,-10.151474 2.08022,-19.824498 6.240661,-29.019071 5.075736,-11.274793 12.273297,-19.907706 21.592683,-25.898739 9.360991,-5.991034 20.69819,-8.986551 34.011599,-8.986551 10.317891,0 19.574873,2.121824 27.77093,6.365473 8.23767,4.202045 14.72796,10.484309 19.47086,18.846794 4.03563,7.197561 6.05344,15.019189 6.05344,23.464883 0,12.065277 -4.24365,22.77841 -12.73094,32.1394 -7.572,8.404095 -15.85128,12.606135 -24.837827,12.606135 -2.870704,0 -5.200551,-0.43684 -6.98954,-1.31053 -1.747385,-0.8737 -3.037121,-2.12183 -3.869209,-3.744402 -0.540857,-1.040114 -0.936099,-2.829105 -1.185726,-5.366972 z M 49.723082,77.510217 c 0,5.699803 1.352143,10.130671 4.05643,13.292606 2.704286,3.161935 5.803814,4.742902 9.298583,4.742902 2.329847,0 4.784506,-0.686473 7.363979,-2.059418 2.579473,-1.41455 5.034133,-3.49477 7.363979,-6.240661 2.371451,-2.74589 4.306056,-6.219857 5.803815,-10.421902 1.497759,-4.243649 2.246638,-8.487298 2.246638,-12.730947 0,-5.658198 -1.41455,-10.047462 -4.243649,-13.167793 -2.787495,-3.12033 -6.199056,-4.680495 -10.234683,-4.680495 -2.662682,0 -5.179749,0.686473 -7.5512,2.059418 -2.329846,1.331341 -4.597286,3.494769 -6.802319,6.490286 -2.205033,2.995517 -3.97322,6.635903 -5.304561,10.921156 -1.331341,4.285253 -1.997012,8.216869 -1.997012,11.794848 z" style="stroke-width:.887561"/></g></svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,21 @@
/* Tweak how the sidebar logo is presented */
.sidebar-logo {
width: 70%;
}
.sidebar-brand {
padding: 0;
}
/* The landing pages' sidebar-in-content highlights */
#features ul {
padding-left: 1rem;
list-style: none;
}
#features ul li {
margin-bottom: 0;
}
@media (min-width: 46em) {
#features {
width: 50%;
}
}

41
doc/source/conf.py Normal file
View File

@@ -0,0 +1,41 @@
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = 'chatmail relay documentation'
copyright = '2025, chatmail collective'
author = 'chatmail collective'
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
extensions = [
#'sphinx.ext.autodoc',
#'sphinx.ext.viewdoc',
'sphinxcontrib.mermaid',
]
templates_path = ['_templates']
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = 'furo'
html_static_path = ['_static']
html_css_files = [
"custom.css",
]
html_title = "chatmail relay documentation"
#html_short_title = f"chatmail-{release}"
html_logo = "_static/chatmail.svg"

61
doc/source/faq.rst Normal file
View File

@@ -0,0 +1,61 @@
Frequently asked questions
===========================
What is the difference between chatmail relays and classic email servers?
--------------------------------------------------------------------------
A chatmail relay is a minimal Mail Transport Agent (MTA) setup that
goes beyond what classic email servers offer:
- **Zero State:** no private data or metadata collected, messages are auto-deleted, low disk usage
- **Instant/Realtime:** sub-second message delivery, realtime P2P
streaming, privacy-preserving Push Notifications for Apple, Google, and `Ubuntu Touch <https://docs.ubports.com/en/latest/appdev/guides/pushnotifications.html>`_;
- **Security Enforcement**: only strict TLS, DKIM and OpenPGP with minimized metadata accepted
- **Reliable Federation and Decentralization:** No spam or IP reputation checks, federating
depends on established IETF standards and protocols.
How about interoperability with classic email servers?
-------------------------------------------------------
Generally, chatmail relays interoperate well with classic email servers.
However, some chatmail relays may be blocked by Big-Tech email
providers that use intransparent and proprietary techniques for scanning
and looking at cleartext email messages between users, or because they
use questionable IP-reputation systems that break interoperability.
**Chatmail relays instead use and require strong cryptography, allowing
anyone to participate, without having to submit to Big-Tech
restrictions.**
.. _selfhosted:
How are chatmail relays run? Can I run one myself?
--------------------------------------------------
Chatmail relays are designed to be very cheap to run, and are generally
self-funded by respective operators. All chatmail relays are
automatically deployed and updated using `the chatmail relay
repository <https://github.com/chatmail/relay>`__. Chatmail relays are
composed of proven standard email server components, Postfix and
Dovecot, and are configured to run unattended without much maintenance
effort. Chatmail relays happily run on low-end hardware like a Raspberry
Pi.
How trustable are chatmail relays?
----------------------------------
Chatmail relays enforce end-to-end encryption,
and chatmail clients like `Delta Chat <https://delta.chat>`_
enforce end-to-end encryption on their own.
The end-to-end encryption protection includes attached media, user
display names, avatars and group names. What is visible to operators is:
message date, sender and receiver addresses.
Please see the `Delta Chat FAQ on encryption and security <https://delta.chat/en/help#e2ee>`_ for further info.

View File

@@ -0,0 +1,169 @@
Setting up a chatmail relay
===========================
This section contains everything needed to setup a ready-to-use chatmail relay.
The automated setup is designed and optimized for providing chatmail
addresses for immediate permission-free onboarding through chat apps and bots.
Chatmail addresses are automatically created at first login,
after which the initially specified password is required
for sending and receiving messages through them.
Minimal requirements and prerequisites
--------------------------------------
You will need the following:
- Control over a domain through a DNS provider of your choice.
- A Debian 12 server with reachable SMTP/SUBMISSIONS/IMAPS/HTTPS ports.
IPv6 is encouraged if available. Chatmail relay servers only require
1GB RAM, one CPU, and perhaps 10GB storage for a few thousand active
chatmail addresses.
- Key-based SSH authentication to the root user. You must add a
passphrase-protected private key to your local ssh-agent because you
cant type in your passphrase during deployment. (An ed25519 private
key is required due to an `upstream bug in
paramiko <https://github.com/paramiko/paramiko/issues/2191>`_)
Setup with ``scripts/cmdeploy``
-------------------------------------
We use ``chat.example.org`` as the chatmail domain in the following
steps. Please substitute it with your own domain.
1. Setup the initial DNS records. The following is an example in the
familiar BIND zone file format with a TTL of 1 hour (3600 seconds).
Please substitute your domain and IP addresses.
::
chat.example.com. 3600 IN A 198.51.100.5
chat.example.com. 3600 IN AAAA 2001:db8::5
www.chat.example.com. 3600 IN CNAME chat.example.com.
mta-sts.chat.example.com. 3600 IN CNAME chat.example.com.
2. On your local PC, clone the repository and bootstrap the Python
virtualenv.
::
git clone https://github.com/chatmail/relay
cd relay
scripts/initenv.sh
3. On your local PC, create chatmail configuration file
``chatmail.ini``:
::
scripts/cmdeploy init chat.example.org # <-- use your domain
4. Verify that SSH root login to your remote server works:
::
ssh root@chat.example.org # <-- use your domain
5. From your local PC, deploy the remote chatmail relay server:
::
scripts/cmdeploy run
This script will also check that you have all necessary DNS records.
If DNS records are missing, it will recommend which you should
configure at your DNS provider (it can take some time until they are
public).
Other helpful commands
----------------------
To check the status of your remotely running chatmail service:
::
scripts/cmdeploy status
To display and check all recommended DNS records:
::
scripts/cmdeploy dns
To test whether your chatmail service is working correctly:
::
scripts/cmdeploy test
To measure the performance of your chatmail service:
::
scripts/cmdeploy bench
Modifying the home page
-----------------------
``cmdeploy run`` also creates default static web pages and deploys them
to a Nginx web server with:
- a default ``index.html`` along with a QR code that users can click to
create an address on your chatmail relay
- a default ``info.html`` that is linked from the home page
- a default ``policy.html`` that is linked from the home page
All ``.html`` files are generated by the according markdown ``.md`` file
in the ``www/src`` directory.
Refining the web pages
----------------------
::
scripts/cmdeploy webdev
This starts a local live development cycle for chatmail web pages:
- uses the ``www/src/page-layout.html`` file for producing static HTML
pages from ``www/src/*.md`` files
- continously builds the web presence reading files from ``www/src``
directory and generating HTML files and copying assets to the
``www/build`` directory.
- Starts a browser window automatically where you can “refresh” as
needed.
Custom web pages
----------------
You can skip uploading a web page by setting ``www_folder=disabled`` in
``chatmail.ini``.
If you want to manage your web pages outside this git repository, you
can set ``www_folder`` in ``chatmail.ini`` to a custom directory on your
computer. ``cmdeploy run`` will upload it as the servers home page, and
if it contains a ``src/index.md`` file, will build it with hugo.
Disable automatic address creation
--------------------------------------------------------
If you need to stop address creation, e.g. because some script is wildly
creating addresses, login with ssh and run:
::
touch /etc/chatmail-nocreate
Chatmail address creation will be denied while this file is present.

20
doc/source/index.rst Normal file
View File

@@ -0,0 +1,20 @@
*******************************************
chatmail relay documentation
*******************************************
.. image:: ../../www/src/collage-top.png
:target: https://testrun.org
This documentation details how to setup, maintain and understand `chatmail <https://chatmail.at>`_ relays.
Contributions and feedback welcome through the https://github.com/chatmail/relay repository.
.. toctree::
:maxdepth: 5
getting_started
proxy
migrate
overview
related
faq

73
doc/source/migrate.rst Normal file
View File

@@ -0,0 +1,73 @@
Migrating to a new host
-----------------------
If you want to migrate chatmail relay from an old machine to a new
machine, you can use these steps. They were tested with a Linux laptop;
you might need to adjust some of the steps to your environment.
Lets assume that your ``mail_domain`` is ``mail.example.org``, all
involved machines run Debian 12, your old sites IP address is
``13.37.13.37``, and your new sites IP address is ``13.12.23.42``.
Note, you should lower the TTLs of your DNS records to a value such as
300 (5 minutes) so the migration happens as smoothly as possible.
During the guide you might get a warning about changed SSH Host keys; in
this case, just run ``ssh-keygen -R "mail.example.org"`` as recommended.
1. First, disable mail services on the old site.
::
cmdeploy run --disable-mail --ssh-host 13.37.13.37
Now your users will notice the migration and will not be able to send
or receive messages until the migration is completed.
2. Now we want to copy ``/home/vmail``, ``/var/lib/acme``,
``/etc/dkimkeys``, ``/run/echobot``, and ``/var/spool/postfix`` to
the new site. Login to the old site while forwarding your SSH agent
so you can copy directly from the old to the new site with your SSH
key:
::
ssh -A root@13.37.13.37
tar c - /home/vmail/mail /var/lib/acme /etc/dkimkeys /run/echobot /var/spool/postfix | ssh root@13.12.23.42 "tar x -C /"
This transfers all addresses, the TLS certificate, DKIM keys (so DKIM
DNS record remains valid), and the echobots password so it continues
to function. It also preserves the Postfix mail spool so any messages
pending delivery will still be delivered.
3. Install chatmail on the new machine:
::
cmdeploy run --disable-mail --ssh-host 13.12.23.42
Postfix and Dovecot are disabled for now; we will enable them later.
We first need to make the new site fully operational.
4. On the new site, run the following to ensure the ownership is correct
in case UIDs/GIDs changed:
::
chown root: -R /var/lib/acme
chown opendkim: -R /etc/dkimkeys
chown vmail: -R /home/vmail/mail
chown echobot: -R /run/echobot
5. Now, update DNS entries.
If other MTAs try to deliver messages to your chatmail domain they
may fail intermittently, as DNS catches up with the new site settings
but normally will retry delivering messages for at least a week, so
messages will not be lost.
6. Finally, you can execute ``cmdeploy run --ssh-host 13.12.23.42`` to
turn on chatmail on the new relay. Your users will be able to use the
chatmail relay as soon as the DNS changes have propagated. Voilà!

299
doc/source/overview.rst Normal file
View File

@@ -0,0 +1,299 @@
Technical overview
======================
Directories of the relay repository
-----------------------------------
The `chatmail relay repository <https://github.com/chatmail/relay/tree/main/>`_
has four main directories.
``scripts/``
~~~~~~~~~~~~~
`scripts <https://github.com/chatmail/relay/tree/main/scripts>`_
offers two convenience tools for beginners:
- ``initenv.sh`` installs a local virtualenv Python environment and
installs necessary dependencies
- ``scripts/cmdeploy`` script enables you to run the ``cmdeploy``
command line tool in the local Python virtual environment.
``cmdeploy/``
~~~~~~~~~~~~~
The ``cmdeploy`` directory contains the Python package and command line tool
to setup a chatmail relay remotely via SSH:
- ``cmdeploy init`` creates the ``chatmail.ini`` config file locally.
- ``cmdeploy run`` under the hood uses pyinfra_
to automatically install or upgrade all chatmail components on a relay,
according to the local ``chatmail.ini`` config.
The deployed system components of a chatmail relay are:
- Postfix_ is the Mail Transport Agent (MTA) and
accepts messages from, and sends messages to, the wider email MTA network
- Dovecot_ is the Mail Delivery Agent (MDA) and
stores messages for users until they download them
- Nginx_ shows the web page with privacy policy and additional information
- `acmetool <https://hlandau.github.io/acmetool/>`_ manages TLS
certificates for Dovecot, Postfix, and Nginx
- `OpenDKIM <http://www.opendkim.org/>`_ for signing messages with
DKIM and rejecting inbound messages without DKIM
- `mtail <https://google.github.io/mtail/>`_ for collecting anonymized
metrics in case you have monitoring
- `Iroh relay <https://www.iroh.computer/docs/concepts/relay>`_ which
helps client devices to establish Peer-to-Peer connections
- `TURN <https://github.com/chatmail/chatmail-turn>`_ to enable relay
users to start webRTC calls even if a p2p connection cant be
established
- and the chatmaild services, explained in the next section:
``chatmaild/``
~~~~~~~~~~~~~~
`chatmaild <https://github.com/chatmail/relay/tree/main/chatmaild>`_
is a Python package containing several small services which handle
authentication, trigger push notifications on new messages, ensure
that outbound mails are encrypted, delete inactive users, and some
other minor things. chatmaild can also be installed as a stand-alone
Python package.
``chatmaild`` implements various systemd-controlled services
that integrate with Dovecot and Postfix to achieve instant-onboarding
and only relaying OpenPGP end-to-end messages encrypted messages. A
short overview of ``chatmaild`` services:
- `doveauth <https://github.com/chatmail/relay/blob/main/chatmaild/src/chatmaild/doveauth.py>`_
implements create-on-login address semantics and is used by Dovecot
during IMAP login and by Postfix during SMTP/SUBMISSION login which
in turn uses `Dovecot SASL
<https://doc.dovecot.org/2.3/configuration_manual/authentication/dict/#complete-example-for-authenticating-via-a-unix-socket>`_
to authenticate logins.
- `filtermail <https://github.com/chatmail/relay/blob/main/chatmaild/src/chatmaild/filtermail.py>`_
prevents unencrypted email from leaving or entering the chatmail
service and is integrated into Postfixs outbound and inbound mail
pipelines.
- `chatmail-metadata <https://github.com/chatmail/relay/blob/main/chatmaild/src/chatmaild/metadata.py>`_
is contacted by a `Dovecot lua
script <https://github.com/chatmail/relay/blob/main/cmdeploy/src/cmdeploy/dovecot/push_notification.lua>`_
to store user-specific relay-side config. On new messages, it `passes
the users push notification
token <https://github.com/chatmail/relay/blob/main/chatmaild/src/chatmaild/notifier.py>`_
to
`notifications.delta.chat <https://delta.chat/en/help#instant-delivery>`_
so the push notifications on the users phone can be triggered by
Apple/Google/Huawei.
- `chatmail-expire <https://github.com/chatmail/relay/blob/main/chatmaild/src/chatmaild/expire.py>`_
deletes users if they have not logged in for a longer while.
The timeframe can be configured in ``chatmail.ini``.
- `lastlogin <https://github.com/chatmail/relay/blob/main/chatmaild/src/chatmaild/lastlogin.py>`_
is contacted by Dovecot when a user logs in and stores the date of
the login.
- `echobot <https://github.com/chatmail/relay/blob/main/chatmaild/src/chatmaild/echo.py>`_
is a small bot for test purposes. It simply echoes back messages from
users.
- `metrics <https://github.com/chatmail/relay/blob/main/chatmaild/src/chatmaild/metrics.py>`_
collects some metrics and displays them at
``https://example.org/metrics``.
``www/``
~~~~~~~~~
`www <https://github.com/chatmail/relay/tree/main/www>`_ contains
the html, css, and markdown files which make up a chatmail relays
web page. Edit them before deploying to make your chatmail relay
stand out.
Component dependency diagram
--------------------------------------
.. mermaid::
:caption: This diagram shows relay components and dependencies/communication paths.
graph LR;
cmdeploy --- sshd;
letsencrypt --- |80|acmetool-redirector;
acmetool-redirector --- |443|nginx-right(["`nginx
(external)`"]);
nginx-external --- |465|postfix;
nginx-external(["`nginx
(external)`"]) --- |8443|nginx-internal["`nginx
(internal)`"];
nginx-internal --- website["`Website
/var/www/html`"];
nginx-internal --- newemail.py;
nginx-internal --- autoconfig.xml;
certs-nginx[("`TLS certs
/var/lib/acme`")] --> nginx-internal;
cron --- chatmail-metrics;
cron --- acmetool;
chatmail-metrics --- website;
acmetool --> certs[("`TLS certs
/var/lib/acme`")];
nginx-external --- |993|dovecot;
autoconfig.xml --- postfix;
autoconfig.xml --- dovecot;
postfix --- echobot;
postfix --- |10080,10081|filtermail;
postfix --- users["`User data
home/vmail/mail`"];
postfix --- |doveauth.socket|doveauth;
dovecot --- |doveauth.socket|doveauth;
dovecot --- users;
dovecot --- |metadata.socket|chatmail-metadata;
doveauth --- users;
chatmail-expire-daily --- users;
chatmail-fsreport-daily --- users;
chatmail-metadata --- iroh-relay;
certs-nginx --> postfix;
certs-nginx --> dovecot;
style certs fill:#ff6;
style certs-nginx fill:#ff6;
style nginx-external fill:#fc9;
style nginx-right fill:#fc9;
Operational details of a chatmail relay
----------------------------------------
Mailbox directory layout
~~~~~~~~~~~~~~~~~~~~~~~~
Fresh chatmail addresses have a mailbox directory that contains:
- a ``password`` file with the salted password required for
authenticating whether a login may use the address to send/receive
messages. If you modify the password file manually, you effectively
block the user.
- ``enforceE2EEincoming`` is a default-created file with each address.
If present the file indicates that this chatmail address rejects
incoming cleartext messages. If absent the address accepts incoming
cleartext messages.
- ``dovecot*``, ``cur``, ``new`` and ``tmp`` represent IMAP/mailbox
state. If the address is only used by one device, the Maildir
directories will typically be empty unless the user of that address
hasnt been online for a while.
Active ports
~~~~~~~~~~~~
Postfix_ listens on ports
- 25 (SMTP)
- 587 (SUBMISSION) and
- 465 (SUBMISSIONS)
Dovecot_ listens on ports
- 143 (IMAP) and
- 993 (IMAPS)
Nginx_ listens on port
- 8443 (HTTPS-ALT) and
- 443 (HTTPS) which multiplexes HTTPS, IMAP and SMTP using ALPN
to redirect connections to ports 8443, 465 or 993.
`acmetool <https://hlandau.github.io/acmetool/>`_ listens on port:
- 80 (HTTP).
`chatmail-turn <https://github.com/chatmail/chatmail-turn>`_ listens on port
- 3478 UDP (STUN/TURN), and temporarily opens further UDP ports
when users request them. UDP port range is not restricted, any free port
may be allocated.
chatmail-core based apps will, however, discover all ports and
configurations automatically by reading the `autoconfig XML
file <https://www.ietf.org/archive/id/draft-bucksch-autoconfig-00.html>`_
from the chatmail relay server.
Email domain authentication (DKIM)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Chatmail relays enforce :rfc:`DKIM <6376>` to authenticate incoming emails.
Incoming emails must have a valid DKIM signature with
Signing Domain Identifier (SDID, ``d=`` parameter in the DKIM-Signature
header) equal to the ``From:`` header domain. This property is checked
by OpenDKIM screen policy script before validating the signatures. This
correpsonds to strict :rfc:`DMARC <7489>` alignment (``adkim=s``).
If there is no valid DKIM signature on the incoming email, the
sender receives a “5.7.1 No valid DKIM signature found” error.
Note that chatmail relays
- do **not** rely on DMARC and do not consult the sender policy published in DMARC records;
- do **not** rely on legacy authentication mechanisms such as
:rfc:`iprev <8601#section-2.7.3>` and :rfc:`SPF <7208>`.
Any IP address is accepted if the DKIM signature was valid.
Outgoing emails must be sent over authenticated connection with envelope
``MAIL FROM`` (return path) corresponding to the login.
This is ensured by Postfix which maps login username to ``MAIL FROM`` with
`smtpd_sender_login_maps <https://www.postfix.org/postconf.5.html#smtpd_sender_login_maps>`_
and rejects incorrectly authenticated emails with
`reject_sender_login_mismatch <https://www.postfix.org/postconf.5.html#reject_sender_login_mismatch>`_ policy.
``From:`` header must correspond to envelope ``MAIL FROM``, this is
ensured by ``filtermail`` proxy.
TLS requirements
~~~~~~~~~~~~~~~~
Postfix is configured to require valid TLS by setting
`smtp_tls_security_level <https://www.postfix.org/postconf.5.html#smtp_tls_security_level>`_
to ``verify``. If emails dont arrive at your chatmail relay server, the
problem is likely that your relay does not have a valid TLS certificate.
You can test it by resolving ``MX`` records of your relay domain and
then connecting to MX relays (e.g ``mx.example.org``) with
``openssl s_client -connect mx.example.org:25 -verify_hostname mx.example.org -verify_return_error -starttls smtp``
from the host that has open port 25 to verify that certificate is valid.
When providing a TLS certificate to your chatmail relay server, make
sure to provide the full certificate chain and not just the last
certificate.
If you are running an Exim server and dont see incoming connections
from a chatmail relay server in the logs, make sure ``smtp_no_mail`` log
item is enabled in the config with ``log_selector = +smtp_no_mail``. By
default Exim does not log sessions that are closed before sending the
``MAIL`` command. This happens if certificate is not recognized as valid
by Postfix, so you might think that connection is not established while
actually it is a problem with your TLS certificate.
.. _dovecot: https://dovecot.org
.. _postfix: https://www.postfix.org
.. _nginx: https://nginx.org
.. _pyinfra: https://pyinfra.com

114
doc/source/proxy.rst Normal file
View File

@@ -0,0 +1,114 @@
Setting up a reverse proxy
--------------------------
A chatmail relay MTA does not track or depend on the client IP address
for its operation, so it can be run behind a reverse proxy. This will
not even affect incoming mail authentication as DKIM only checks the
cryptographic signature of the message and does not use the IP address
as the input.
For example, you may want to self-host your chatmail relay and only use
hosted VPS to provide a public IP address for client connections and
incoming mail. You can connect chatmail relay to VPS using a tunnel
protocol such as `WireGuard <https://www.wireguard.com/>`_ and setup a
reverse proxy on a VPS to forward connections to the chatmail relay over
the tunnel. You can also setup multiple reverse proxies for your
chatmail relay in different networks to ensure your relay is reachable
even when one of the IPs becomes inaccessible due to hosting or routing
problems.
Note that your chatmail relay still needs to be able to make outgoing
connections on port 25 to send messages outside.
To setup a reverse proxy (or rather Destination NAT, DNAT) for your
chatmail relay, put the following configuration in
``/etc/nftables.conf``:
::
#!/usr/sbin/nft -f
flush ruleset
define wan = eth0
# Which ports to proxy.
#
# Note that SSH is not proxied
# so it is possible to log into the proxy server
# and not the original one.
define ports = { smtp, http, https, imap, imaps, submission, submissions }
# The host we want to proxy to.
define ipv4_address = AAA.BBB.CCC.DDD
define ipv6_address = [XXX::1]
table ip nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
iif $wan tcp dport $ports dnat to $ipv4_address
}
chain postrouting {
type nat hook postrouting priority 0;
oifname $wan masquerade
}
}
table ip6 nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
iif $wan tcp dport $ports dnat to $ipv6_address
}
chain postrouting {
type nat hook postrouting priority 0;
oifname $wan masquerade
}
}
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
# Accept ICMP.
# It is especially important to accept ICMPv6 ND messages,
# otherwise IPv6 connectivity breaks.
icmp type { echo-request } accept
icmpv6 type { echo-request, nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
# Allow incoming SSH connections.
tcp dport { ssh } accept
ct state established accept
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established accept
ip daddr $ipv4_address counter accept
ip6 daddr $ipv6_address counter accept
}
chain output {
type filter hook output priority filter;
}
}
Run ``systemctl enable nftables.service`` to ensure configuration is
reloaded when the proxy relay reboots.
Uncomment in ``/etc/sysctl.conf`` the following two lines:
::
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
Then reboot the relay or do ``sysctl -p`` and
``nft -f /etc/nftables.conf``.
Once proxy relay is set up, you can add its IP address to the DNS.

20
doc/source/related.rst Normal file
View File

@@ -0,0 +1,20 @@
Community developments
======================
Active development takes place in the `chatmail/relay github repository <https://github.com/chatmail/relay>`_.
You can check out the `'chatmail' tag in the support.delta.chat forum <https://support.delta.chat/tag/chatmail>`_
and ask to get added to a non-public support chat for debugging issues.
We know of two work-in-progress alternative implementation efforts:
- `Mox <https://github.com/mjl-/mox>`_: A Golang email server. `Work
is in progress <https://github.com/mjl-/mox/issues/251>`_ to modify
it to support all of the features and configuration settings required
to operate as a chatmail relay.
- `Maddy-Chatmail <https://github.com/sadraiiali/maddy_chatmail>`_: a
plugin for the `Maddy email server <https://maddy.email/>`_ which
aims to implement the chatmail relay features and configuration
options.