Compare commits

..

1 Commits

Author SHA1 Message Date
link2xt 02c7d3da58 feat: setup websockify
This change makes it possible
to connect the client over WebSocket.
Running `websocat wss://example.org/imap`
connects to the IMAP
and running `websocat wss://example.org/smtp`
connects to SMTP (submission service, not port 25).

Connecting from a web client will still need a CORS policy
for clients not running on the same domain,
but for non-web clients this is already usable.
2026-07-29 22:10:14 +00:00
10 changed files with 72 additions and 62 deletions
+2
View File
@@ -20,6 +20,8 @@ concurrency:
jobs:
no-dns:
name: LXC deploy and test
permissions:
contents: read
uses: chatmail/cmlxc/.github/workflows/lxc-test.yml@main
with:
cmlxc_version: main
+2
View File
@@ -57,6 +57,8 @@ jobs:
lxc-test:
name: LXC deploy and test
permissions:
contents: read
uses: chatmail/cmlxc/.github/workflows/lxc-test.yml@main
with:
cmlxc_version: main
+1 -1
View File
@@ -47,5 +47,5 @@ jobs:
mkdir -p "$HOME/.ssh"
echo "${{ secrets.CHATMAIL_STAGING_SSHKEY }}" > "$HOME/.ssh/key"
chmod 600 "$HOME/.ssh/key"
rsync -rILvh -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no" $GITHUB_WORKSPACE/doc/build/ "${{ secrets.USERNAME }}@chatmail.at:"
rsync -rILvh -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no" $GITHUB_WORKSPACE/doc/build/ "${{ secrets.USERNAME }}@chatmail.at:/var/www/html/chatmail.at/doc/relay/"
-55
View File
@@ -1,60 +1,5 @@
# Changelog for chatmail deployment
## [1.12.0] - 2026-07-31
### Breaking Changes
- [**breaking**] Introduce configurable system limits to reject new address creation and limit imap/smtp connections.
Dovecot default connection limit lowered from 50k to 10k,
Postfix default connection limit lowered from 5k to 1k,
larger relays need to adjust their settings.
### Features
- Reduce maximal_queue_lifetime from 5d to 2d
- Disable negative cache in unbound (#992)
- *(mtail)* Add incoming_mailer_daemon_mail_count
- *(postfix)* Disable processing of MIME headers
- *(dovecot)* Advertise privacy_mail as admin contact, drop server comment
### Bug Fixes
- Set relay restrictions per smtpd service with default reject
- Reduce maxproc for filtermail-transport LMTP client to 500
- Core 2.50.0 does not have delete_server_after config anymore.
- Check if all required ports are available for filtermail (#983)
- Always deploy unbound.conf.d/chatmail.conf (#993)
- Expire empty directories (#994)
- Crypt-r dependency was declared for wrong Python version
- Always overwrite /etc/resolv.conf, even if it is a symbolic link
- Pass kwargs to files.put()
- List Iroh proxy endpoints used by 0.35 and 1.0, drop stale /relay/probe from earlier versions
- Fix port discovery when ss -tulpn shows dovecot before stats
### Documentation
- Add scripts/initenv.sh to upgrade instructions
- Update overview diagrams (#995)
- *(overview)* Remove mermaid styles from 'Accepting and delivering mail' (#1009)
- *(README.md)* Clarify security enforcement (#1011)
### Miscellaneous Tasks
- *(ci)* Auto-trigger docker build on release tag push
- *(acmetool)* Update let's encrypt ToS link to 1.8
- *(ci)* Update doc staging upload path
- *(ci)* Fix docs upload path
### Refactor
- *(postfix)* Remove unused "filter" lmtp service
- Install dns-root-data instead of using unbound-anchor
- *(deps)* Remove domain-validator dependency
### Testing
- Set socket security for IMAP and SMTP to "TLS" in "dclogin"
## [1.11.0] - 2026-05-15
### Breaking Changes
+6 -4
View File
@@ -1,13 +1,15 @@
# 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.9.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.9.0 --prepend CHANGELOG.md` or `git cliff -u -t 1.9.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`.
4. Open a PR with the new commit, merge it to main after review.
3. Tag the release: `git tag --annotate 1.9.0`.
5. In the web interface, create a GitHub release, tell it to create a new tag.
4. Push the release tag: `git push origin 1.9.0`.
5. Create a GitHub release: `gh release create 1.9.0`.
+4 -2
View File
@@ -32,6 +32,7 @@ from .external.deployer import ExternalTlsDeployer
from .filtermail.deployer import FiltermailDeployer
from .mtail.deployer import MtailDeployer
from .nginx.deployer import NginxDeployer
from .websockify.deployer import WebsockifyDeployer
from .opendkim.deployer import OpendkimDeployer
from .postfix.deployer import PostfixDeployer
from .selfsigned.deployer import SelfSignedTlsDeployer
@@ -520,10 +521,10 @@ def deploy_chatmail(config_path: Path, disable_mail: bool, website_only: bool) -
("nginx", 443),
(["master", "smtpd"], 465),
(["master", "smtpd"], 587),
(["dovecot", "imap-login"], 993),
(["imap-login", "dovecot"], 993),
("iroh-relay", 3340),
("mtail", 3903),
(["dovecot", "stats"], 3904),
("stats", 3904),
("nginx", 8443),
(["master", "smtpd"], config.postfix_reinject_port),
(["master", "smtpd"], config.postfix_reinject_port_incoming),
@@ -565,6 +566,7 @@ def deploy_chatmail(config_path: Path, disable_mail: bool, website_only: bool) -
PostfixDeployer(config, disable_mail),
FcgiwrapDeployer(),
NginxDeployer(config),
WebsockifyDeployer(config),
MtailDeployer(config.mtail_address),
GithashDeployer(),
]
+14
View File
@@ -140,6 +140,20 @@ http {
proxy_pass http://127.0.0.1:3340;
proxy_http_version 1.1;
}
location /imap {
proxy_pass http://127.0.0.1:8143;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /smtp {
proxy_pass http://127.0.0.1:8587;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
# Redirect www. to non-www
@@ -0,0 +1,19 @@
from pyinfra.operations import apt, server
from cmdeploy.basedeploy import Deployer
class WebsockifyDeployer(Deployer):
def __init__(self, config):
self.config = config
def install(self):
apt.packages(name="Install websockify", packages=["websockify"])
def configure(self):
self.ensure_systemd_unit("websockify/websockify-imap.service")
self.ensure_systemd_unit("websockify/websockify-submission.service")
def activate(self):
self.ensure_service("websockify-imap.service")
self.ensure_service("websockify-submission.service")
@@ -0,0 +1,12 @@
[Unit]
Description=WebSocket proxy for IMAP
After=network.target
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/websockify 127.0.0.1:8143 localhost:143
DynamicUser=true
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,12 @@
[Unit]
Description=WebSocket proxy for SMTP
After=network.target
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/websockify 127.0.0.1:8587 localhost:587
DynamicUser=true
[Install]
WantedBy=multi-user.target