Compare commits

..
Author SHA1 Message Date
holger krekel 33f925caa7 refactor: un-hardcode filesystem paths in configuration templates
Drive all file system paths from templating variables,
useful e.g. for FreeBSD which keeps debian's `/etc` hiearchy rather in `/usr/local/etc`.
Also support static nginx builds which have the stream module compiled in
and thus don't need dynamic linking to a stream module.
2026-09-26 23:27:55 +02:00
maren-bunkandmissytake 4435864779 Update faq.rst to clarify how to deploy tagged releases 2026-09-24 12:18:00 +02:00
missytake 4ffb501c5e chore(release): prepare for 1.13.0 2026-09-22 15:18:38 +02:00
Jagoda Ślązakandmissytake b5f0d5f268 chore(deps): Upgrade filtermail to v0.7.7
## 0.7.7 - 2026-09-11

### Performance

- Don't convert Bytes to Vec

## 0.7.6 - 2026-09-11

### Miscellaneous Tasks

- Always use --locked flag in CI

### Performance

- Don't keep multiple copies of the same mail data in memory

## 0.7.5 - 2026-09-10

### Performance

- Pass HttpsClient by reference instead of cloning it
- Remove connection pool

### Refactor

- Do not evaluate smtp_write! argument twice
- Do not clone the Config unnecessarily

Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-09-22 14:04:26 +02:00
16 changed files with 95 additions and 32 deletions
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}
persist-credentials: false
- name: download filtermail
run: curl -L https://github.com/chatmail/filtermail/releases/download/v0.7.4/filtermail-x86_64 -o /usr/local/bin/filtermail && chmod +x /usr/local/bin/filtermail
run: curl -L https://github.com/chatmail/filtermail/releases/download/v0.7.7/filtermail-x86_64 -o /usr/local/bin/filtermail && chmod +x /usr/local/bin/filtermail
- name: run chatmaild tests
working-directory: chatmaild
run: pipx run tox
+33
View File
@@ -1,5 +1,38 @@
# Changelog for chatmail deployment
## [1.13.0] - 2026-09-22
### Bug Fixes
- Actually use UTC time instead of just seemingly using it
### Documentation
- Describe Madmail v2 as a Rust chatmail relay
### Features
- Serve an APPVERSIONS.json index file to clients via IMAP metadata
- *(mtail)* Deploy filtermail.mtail and gate mtail rule copy on mtail_address
- *(mtail)* Validate programs during deploy
- Move doveauth from dictproxy to lua/http
- Distinguish AUTHENTICATION_FAILED/UNAVAILABLE login failures
### Miscellaneous Tasks
- Try to fix lack of RFC822 item support in madmail and make CI pass
- Un-hardcode executable paths in some systemd service files
- Follow the new mtail release source, upgrade 3.0.8 to 3.4.9
- *(cmdeploy)* Refactor all pins into pins.py
- *(doc)* Use sphinx roles for referencing repository files and dirs
- update deltachat-android link to 2.59.1
### Testing
- Integrate lua testing into regular pytest run for push notifications
- Cleanup and allow a repo-root level "pytest -n6" to succeed.
- [**breaking**] Remove global registration of pytest plugins
## [1.12.0] - 2026-07-31
### Breaking Changes
+3 -3
View File
@@ -1,12 +1,12 @@
# Releasing a new version of chatmail relay
For example, to release version 1.13.0 of chatmail relay, do the following steps.
For example, to release version 1.14.0 of chatmail relay, do the following steps.
1. Update the changelog: `git cliff --unreleased --tag 1.13.0 --prepend CHANGELOG.md` or `git cliff -u -t 1.13.0 -p CHANGELOG.md`.
1. Update the changelog: `git cliff --unreleased --tag 1.14.0 --prepend CHANGELOG.md` or `git cliff -u -t 1.14.0 -p CHANGELOG.md`.
2. Open the changelog in the editor, edit it if required.
3. Commit the changes to the changelog with a commit message `chore(release): prepare for 1.9.0`.
3. Commit the changes to the changelog with a commit message `chore(release): prepare for 1.14.0`.
4. Open a PR with the new commit, merge it to main after review.
@@ -133,6 +133,9 @@ def _configure_dovecot(deployer, config: Config, debug: bool = False):
config=config,
debug=debug,
disable_ipv6=config.disable_ipv6,
config_dir="/etc/dovecot",
dh_path="/usr/share/dovecot/dh.pem",
quota_expire_bin="/usr/local/lib/chatmaild/venv/bin/chatmail-quota-expire",
)
deployer.put_template("dovecot/auth.lua.j2", "/etc/dovecot/auth.lua", config=config)
deployer.remove_file("/etc/dovecot/auth.conf")
@@ -56,15 +56,17 @@ mail_server_admin = mailto:{{ config.privacy_mail }}
# <https://doc.dovecot.org/2.3/configuration_manual/quota_plugin/>
mail_plugins = zlib quota
imap_capability = +XDELTAPUSH XCHATMAIL
# Authentication for system users.
passdb {
driver = lua
args = file=/etc/dovecot/auth.lua blocking=yes
args = file={{ config_dir }}/auth.lua blocking=yes
}
userdb {
driver = lua
args = file=/etc/dovecot/auth.lua blocking=yes
args = file={{ config_dir }}/auth.lua blocking=yes
}
##
## Mailbox locations and namespaces
@@ -166,7 +168,7 @@ plugin {
}
service quota-warning {
executable = script /usr/local/lib/chatmaild/venv/bin/chatmail-quota-expire
executable = script {{ quota_expire_bin }}
user = vmail
unix_listener quota-warning {
user = vmail
@@ -177,7 +179,7 @@ service quota-warning {
# push_notification configuration
plugin {
# <https://doc.dovecot.org/2.3/configuration_manual/push_notification/#lua-lua>
push_notification_driver = lua:file=/etc/dovecot/push_notification.lua
push_notification_driver = lua:file={{ config_dir }}/push_notification.lua
}
service lmtp {
@@ -252,7 +254,7 @@ service anvil {
ssl = required
ssl_cert = <{{ config.tls_cert_path }}
ssl_key = <{{ config.tls_key_path }}
ssl_dh = </usr/share/dovecot/dh.pem
ssl_dh = <{{ dh_path }}
ssl_min_protocol = TLSv1.3
ssl_prefer_server_ciphers = yes
+4
View File
@@ -55,6 +55,10 @@ def _configure_nginx(deployer, config: Config, debug: bool = False):
"/etc/nginx/nginx.conf",
config=config,
disable_ipv6=config.disable_ipv6,
config_dir="/etc/nginx",
stream_module="modules/ngx_stream_module.so",
www_root="/var/www/html",
cgi_dir="/usr/lib/cgi-bin",
)
deployer.put_template(
+7 -7
View File
@@ -1,4 +1,4 @@
load_module modules/ngx_stream_module.so;
{% if stream_module %}load_module {{ stream_module }};{% endif %}
user www-data;
worker_processes auto;
@@ -54,7 +54,7 @@ http {
# Do not emit nginx version on error pages.
server_tokens off;
include /etc/nginx/mime.types;
include {{ config_dir }}/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1.2 TLSv1.3;
@@ -68,7 +68,7 @@ http {
listen 127.0.0.1:8443 ssl default_server;
root /var/www/html;
root {{ www_root }};
index index.html index.htm;
@@ -96,8 +96,8 @@ http {
{% endif %}
fastcgi_pass unix:/run/fcgiwrap.socket;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /usr/lib/cgi-bin/newemail.py;
include {{ config_dir }}/fastcgi_params;
fastcgi_param SCRIPT_FILENAME {{ cgi_dir }}/newemail.py;
}
# Old URL for compatibility with e.g. printed QR codes.
@@ -114,8 +114,8 @@ http {
{% endif %}
fastcgi_pass unix:/run/fcgiwrap.socket;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /usr/lib/cgi-bin/newemail.py;
include {{ config_dir }}/fastcgi_params;
fastcgi_param SCRIPT_FILENAME {{ cgi_dir }}/newemail.py;
}
# Proxy to iroh-relay service.
+1 -1
View File
@@ -1 +1 @@
{{ config.opendkim_selector }}._domainkey.{{ config.domain_name }} {{ config.domain_name }}:{{ config.opendkim_selector }}:/etc/dkimkeys/{{ config.opendkim_selector }}.private
{{ config.opendkim_selector }}._domainkey.{{ config.domain_name }} {{ config.domain_name }}:{{ config.opendkim_selector }}:{{ keys_dir }}/{{ config.opendkim_selector }}.private
@@ -30,6 +30,8 @@ class OpendkimDeployer(Deployer):
"opendkim/opendkim.conf",
"/etc/opendkim.conf",
config={"domain_name": domain, "opendkim_selector": dkim_selector},
keys_dir="/etc/dkimkeys",
trust_anchor="/usr/share/dns/root.key",
)
self.remove_file("/etc/opendkim/screen.lua")
@@ -46,6 +48,7 @@ class OpendkimDeployer(Deployer):
"/etc/dkimkeys/KeyTable",
owner="opendkim",
config={"domain_name": domain, "opendkim_selector": dkim_selector},
keys_dir="/etc/dkimkeys",
)
self.put_template(
+4 -4
View File
@@ -21,9 +21,9 @@ DNSTimeout 60
# setup options can be found in /usr/share/doc/opendkim/README.opendkim.
Domain {{ config.domain_name }}
Selector {{ config.opendkim_selector }}
KeyFile /etc/dkimkeys/{{ config.opendkim_selector }}.private
KeyTable /etc/dkimkeys/KeyTable
SigningTable refile:/etc/dkimkeys/SigningTable
KeyFile {{ keys_dir }}/{{ config.opendkim_selector }}.private
KeyTable {{ keys_dir }}/KeyTable
SigningTable refile:{{ keys_dir }}/SigningTable
# Sign Autocrypt header in addition to the default specified in RFC 6376.
#
@@ -58,7 +58,7 @@ PidFile /run/opendkim/opendkim.pid
# The trust anchor enables DNSSEC. In Debian, the trust anchor file is provided
# by the package dns-root-data.
TrustAnchorFile /usr/share/dns/root.key
TrustAnchorFile {{ trust_anchor }}
# Sign messages when `-o milter_macro_daemon_name=ORIGINATING` is set.
MTA ORIGINATING
+3 -3
View File
@@ -1,14 +1,14 @@
"""Versions, hashes, and download URLs for pre-built artifacts fetched during deploy."""
FILTERMAIL_VERSION = "v0.7.4"
FILTERMAIL_VERSION = "v0.7.7"
FILTERMAIL_ARTIFACTS = {
"x86_64": (
f"https://github.com/chatmail/filtermail/releases/download/{FILTERMAIL_VERSION}/filtermail-x86_64",
"484cb8dff083134aefba9fce4a6b7ef4784a0f0e28e5108ecf8bb9e58a44fd2c",
"0691debf501f854f4e6a9dd6516f3a0ef03d95721a9b540309014bfe1a1f52b1",
),
"aarch64": (
f"https://github.com/chatmail/filtermail/releases/download/{FILTERMAIL_VERSION}/filtermail-aarch64",
"66aa0ca2ca9add7a12d92883d76f8786384092adfde24a3d3a1d0b1f30d23a9e",
"964f85df8b65b812666113f968cbfdd8da88ce16d218284deb359c1e2400d2da",
),
"mtail": (
f"https://raw.githubusercontent.com/chatmail/filtermail/{FILTERMAIL_VERSION}/contrib/filtermail.mtail",
@@ -24,6 +24,8 @@ class PostfixDeployer(Deployer):
"/etc/postfix/main.cf",
config=config,
disable_ipv6=config.disable_ipv6,
config_dir="/etc/postfix",
ca_path="/etc/ssl/certs",
)
self.put_template(
@@ -31,6 +33,7 @@ class PostfixDeployer(Deployer):
"/etc/postfix/master.cf",
debug=False,
config=config,
config_dir="/etc/postfix",
)
self.put_file(
+4 -4
View File
@@ -19,13 +19,13 @@ smtpd_tls_cert_file={{ config.tls_cert_path }}
smtpd_tls_key_file={{ config.tls_key_path }}
smtpd_tls_security_level=may
smtp_tls_CApath=/etc/ssl/certs
smtp_tls_CApath={{ ca_path }}
smtp_tls_security_level=verify
# Send SNI extension when connecting to other servers.
# <https://www.postfix.org/postconf.5.html#smtp_tls_servername>
smtp_tls_servername = hostname
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_policy_maps = regexp:/etc/postfix/smtp_tls_policy_map
smtp_tls_policy_maps = regexp:{{ config_dir }}/smtp_tls_policy_map
smtp_tls_protocols = >=TLSv1.2
smtp_tls_mandatory_protocols = >=TLSv1.2
@@ -83,7 +83,7 @@ inet_protocols = ipv4
inet_protocols = all
{% endif %}
lmtp_header_checks = regexp:/etc/postfix/lmtp_header_cleanup
lmtp_header_checks = regexp:{{ config_dir }}/lmtp_header_cleanup
# Do not apply header checks to MIME headers
# and other headers that are actually part of the message body.
@@ -98,7 +98,7 @@ mua_sender_restrictions = reject_sender_login_mismatch, permit_sasl_authenticate
mua_helo_restrictions = permit_mynetworks, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, permit
# 1:1 map MAIL FROM to SASL login name.
smtpd_sender_login_maps = regexp:/etc/postfix/login_map
smtpd_sender_login_maps = regexp:{{ config_dir }}/login_map
# Do not lookup SMTP client hostnames to reduce delays
# and avoid unnecessary DNS requests.
+1 -1
View File
@@ -102,7 +102,7 @@ postlog unix-dgram n - n - 1 postlogd
# to make sure the users
# cannot send unprotected Subject.
authclean unix n - - - 0 cleanup
-o header_checks=regexp:/etc/postfix/submission_header_cleanup
-o header_checks=regexp:{{ config_dir }}/submission_header_cleanup
# Reducing `maxproc` here may result in a head of line blocking
# when there are many messages sent to unreachable destinations
@@ -15,6 +15,13 @@ def test_init(tmp_path, maildomain):
assert config.mail_domain_bare == maildomain
def test_capabilities(imap):
imap.connect()
capas = imap.conn.capabilities
assert "XCHATMAIL" in capas
assert "XDELTAPUSH" in capas
def test_login_basic_functioning(imap_or_smtp, gencreds, lp):
"""Test a) that an initial login creates a user automatically
and b) verify we can also login a second time with the same password
+11 -3
View File
@@ -63,9 +63,17 @@ and run the following commands:
scripts/initenv.sh
scripts/cmdeploy run
If you don't want the latest development version,
but a specific tagged release like `1.10.0 <https://github.com/chatmail/relay/releases/tag/1.10.0>`_,
run ``git pull origin 1.10.0`` instead.
To upgrade to the latest tag,
``cd`` into your local checkout of https://github.com/chatmail/relay/
and run the following commands:
::
git fetch --tags
latestTag=$(git describe --tags "$(git rev-list --tags --max-count=1)")
git checkout $latestTag
scripts/initenv.sh
scripts/cmdeploy run
If you made local changes for your setup,
they will be reapplied as long as they don't conflict with the upgrade.