mirror of
https://github.com/chatmail/relay.git
synced 2026-05-16 03:24:48 +00:00
Compare commits
5 Commits
fix-cmdepl
...
1.10.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16b00da373 | ||
|
|
75606f5eb8 | ||
|
|
d256538f81 | ||
|
|
fdf8e5e345 | ||
|
|
81a161d433 |
4
.github/workflows/ci.yaml
vendored
4
.github/workflows/ci.yaml
vendored
@@ -9,6 +9,8 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main" ]
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
# Newest push wins: Prevents multiple runs from clashing and wasting runner efforts
|
# Newest push wins: Prevents multiple runs from clashing and wasting runner efforts
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
@@ -25,6 +27,7 @@ jobs:
|
|||||||
# Otherwise `test_deployed_state` will be unhappy.
|
# Otherwise `test_deployed_state` will be unhappy.
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
persist-credentials: false
|
||||||
- name: download filtermail
|
- name: download filtermail
|
||||||
run: curl -L https://github.com/chatmail/filtermail/releases/download/v0.6.1/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.6.1/filtermail-x86_64 -o /usr/local/bin/filtermail && chmod +x /usr/local/bin/filtermail
|
||||||
- name: run chatmaild tests
|
- name: run chatmaild tests
|
||||||
@@ -38,6 +41,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: initenv
|
- name: initenv
|
||||||
run: scripts/initenv.sh
|
run: scripts/initenv.sh
|
||||||
|
|||||||
37
.github/workflows/docker-dispatch.yaml
vendored
Normal file
37
.github/workflows/docker-dispatch.yaml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Notify the docker repo to build and test a new image after relay CI passes.
|
||||||
|
#
|
||||||
|
# Sends a repository_dispatch event to chatmail/docker with the relay ref
|
||||||
|
# and short SHA, which triggers docker-ci.yaml to build, push to GHCR,
|
||||||
|
# and run integration tests via cmlxc.
|
||||||
|
|
||||||
|
name: Trigger Docker build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
dispatch:
|
||||||
|
name: Dispatch build to chatmail/docker
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'chatmail/relay'
|
||||||
|
steps:
|
||||||
|
- name: Compute short SHA
|
||||||
|
id: sha
|
||||||
|
run: echo "short=$(echo '${{ github.sha }}' | cut -c1-7)" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Send repository_dispatch
|
||||||
|
uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.CHATMAIL_DOCKER_DISPATCH_TOKEN }}
|
||||||
|
repository: chatmail/docker
|
||||||
|
event-type: relay-updated
|
||||||
|
client-payload: >-
|
||||||
|
{
|
||||||
|
"relay_ref": "${{ github.ref_name }}",
|
||||||
|
"relay_sha": "${{ github.sha }}",
|
||||||
|
"relay_sha_short": "${{ steps.sha.outputs.short }}"
|
||||||
|
}
|
||||||
14
.github/workflows/docs-preview.yaml
vendored
14
.github/workflows/docs-preview.yaml
vendored
@@ -7,6 +7,8 @@ on:
|
|||||||
- 'scripts/build-docs.sh'
|
- 'scripts/build-docs.sh'
|
||||||
- '.github/workflows/docs-preview.yaml'
|
- '.github/workflows/docs-preview.yaml'
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
scripts:
|
scripts:
|
||||||
name: build
|
name: build
|
||||||
@@ -16,6 +18,8 @@ jobs:
|
|||||||
url: https://staging.chatmail.at/doc/relay/${{ steps.prepare.outputs.prid }}
|
url: https://staging.chatmail.at/doc/relay/${{ steps.prepare.outputs.prid }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: initenv
|
- name: initenv
|
||||||
run: scripts/initenv.sh
|
run: scripts/initenv.sh
|
||||||
@@ -34,18 +38,22 @@ jobs:
|
|||||||
- name: Get Pullrequest ID
|
- name: Get Pullrequest ID
|
||||||
id: prepare
|
id: prepare
|
||||||
run: |
|
run: |
|
||||||
export PULLREQUEST_ID=$(echo "${{ github.ref }}" | cut -d "/" -f3)
|
export PULLREQUEST_ID=$(echo "${GITHUB_REF}" | cut -d "/" -f3)
|
||||||
echo "prid=$PULLREQUEST_ID" >> $GITHUB_OUTPUT
|
echo "prid=$PULLREQUEST_ID" >> $GITHUB_OUTPUT
|
||||||
if [ $(expr length "${{ secrets.USERNAME }}") -gt "1" ]; then echo "uploadtoserver=true" >> $GITHUB_OUTPUT; fi
|
if [ $(expr length "${{ secrets.USERNAME }}") -gt "1" ]; then echo "uploadtoserver=true" >> $GITHUB_OUTPUT; fi
|
||||||
- run: |
|
- run: |
|
||||||
echo "baseurl: /${{ steps.prepare.outputs.prid }}" >> _config.yml
|
echo "baseurl: /${STEPS_PREPARE_OUTPUTS_PRID}" >> _config.yml
|
||||||
|
env:
|
||||||
|
STEPS_PREPARE_OUTPUTS_PRID: ${{ steps.prepare.outputs.prid }}
|
||||||
|
|
||||||
- name: Upload preview
|
- name: Upload preview
|
||||||
run: |
|
run: |
|
||||||
mkdir -p "$HOME/.ssh"
|
mkdir -p "$HOME/.ssh"
|
||||||
echo "${{ secrets.CHATMAIL_STAGING_SSHKEY }}" > "$HOME/.ssh/key"
|
echo "${{ secrets.CHATMAIL_STAGING_SSHKEY }}" > "$HOME/.ssh/key"
|
||||||
chmod 600 "$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:/var/www/html/staging.chatmail.at/doc/relay/${{ steps.prepare.outputs.prid }}/"
|
rsync -rILvh -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no" $GITHUB_WORKSPACE/doc/build/ "${{ secrets.USERNAME }}@chatmail.at:/var/www/html/staging.chatmail.at/doc/relay/${STEPS_PREPARE_OUTPUTS_PRID}/"
|
||||||
|
env:
|
||||||
|
STEPS_PREPARE_OUTPUTS_PRID: ${{ steps.prepare.outputs.prid }}
|
||||||
|
|
||||||
- name: check links
|
- name: check links
|
||||||
working-directory: doc
|
working-directory: doc
|
||||||
|
|||||||
4
.github/workflows/docs.yaml
vendored
4
.github/workflows/docs.yaml
vendored
@@ -10,6 +10,8 @@ on:
|
|||||||
- 'scripts/build-docs.sh'
|
- 'scripts/build-docs.sh'
|
||||||
- '.github/workflows/docs.yaml'
|
- '.github/workflows/docs.yaml'
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
scripts:
|
scripts:
|
||||||
name: build
|
name: build
|
||||||
@@ -19,6 +21,8 @@ jobs:
|
|||||||
url: https://chatmail.at/doc/relay/
|
url: https://chatmail.at/doc/relay/
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: initenv
|
- name: initenv
|
||||||
run: scripts/initenv.sh
|
run: scripts/initenv.sh
|
||||||
|
|||||||
26
.github/workflows/zizmor-scan.yml
vendored
Normal file
26
.github/workflows/zizmor-scan.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
name: GitHub Actions Security Analysis with zizmor
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ["main"]
|
||||||
|
pull_request:
|
||||||
|
branches: ["**"]
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
zizmor:
|
||||||
|
name: Run zizmor
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
security-events: write # Required for upload-sarif (used by zizmor-action) to upload SARIF files.
|
||||||
|
contents: read
|
||||||
|
actions: read
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Run zizmor
|
||||||
|
uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3
|
||||||
7
.github/zizmor.yml
vendored
Normal file
7
.github/zizmor.yml
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
rules:
|
||||||
|
unpinned-uses:
|
||||||
|
config:
|
||||||
|
policies:
|
||||||
|
actions/*: ref-pin
|
||||||
|
dependabot/*: ref-pin
|
||||||
|
chatmail/*: ref-pin
|
||||||
84
CHANGELOG.md
84
CHANGELOG.md
@@ -1,5 +1,89 @@
|
|||||||
# Changelog for chatmail deployment
|
# Changelog for chatmail deployment
|
||||||
|
|
||||||
|
## 1.10.0 2026-04-30
|
||||||
|
|
||||||
|
* start mtail after networking is fully up <https://github.com/chatmail/relay/pull/942>
|
||||||
|
* support specifying custom filtermail binary through environment variable <https://github.com/chatmail/relay/pull/941>
|
||||||
|
* add automated zizmor scanning of github workflows <https://github.com/chatmail/relay/pull/938>
|
||||||
|
* added dispatch for *automated builds of chatmail relay docker images* <https://github.com/chatmail/relay/pull/934>
|
||||||
|
* do not bind SMTP client sockets to public addresses <https://github.com/chatmail/relay/pull/932>
|
||||||
|
* underline in docs that scripts/initenv.sh should be used for building the docs <https://github.com/chatmail/relay/pull/933>
|
||||||
|
* automatic oldest-first message removal from mailboxes to always stay under max_mailbox_size <https://github.com/chatmail/relay/pull/929>
|
||||||
|
* remove --slow from cmdeploy test <https://github.com/chatmail/relay/pull/931>
|
||||||
|
* handle missing inotify sysctl keys in containers <https://github.com/chatmail/relay/pull/930>
|
||||||
|
* replace resolvconf with static resolv.conf <https://github.com/chatmail/relay/pull/928>
|
||||||
|
* disable fsync for LMTP and IMAP services <https://github.com/chatmail/relay/pull/925>
|
||||||
|
* re-use cmlxc workflow, replacing CI with hetzner staging servers with local lxc containers <https://github.com/chatmail/relay/pull/917>
|
||||||
|
* explicitly install resolvconf <https://github.com/chatmail/relay/pull/924>
|
||||||
|
* detect stale dovecot binary and force restart in activate() <https://github.com/chatmail/relay/pull/922>
|
||||||
|
* Rename filtermail_http_port to filtermail_http_port_incoming <https://github.com/chatmail/relay/pull/921>
|
||||||
|
* consolidated is_in_container() check https://github.com/chatmail/relay/pull/920>
|
||||||
|
* restart dovecot after package replacement (rebase, test condense) <https://github.com/chatmail/relay/pull/913>
|
||||||
|
* Set permissions on dovecot pin prefs <https://github.com/chatmail/relay/pull/915>
|
||||||
|
* Route `/mxdeliv/` to configurable port <https://github.com/chatmail/relay/pull/901>
|
||||||
|
* fix VM detection, automated testing fixes, use newer chatmail-turn and move to standard BIND DNS zone format <https://github.com/chatmail/relay/pull/912>
|
||||||
|
* Upgrade to filtermail 0.6.1 <https://github.com/chatmail/relay/pull/910>
|
||||||
|
* pin dovecot packages to prevent apt upgrades <https://github.com/chatmail/relay/pull/908>
|
||||||
|
* add rpc server to cmdeploy along with client <https://github.com/chatmail/relay/pull/906>
|
||||||
|
* remove unused deps from chatmaild <https://github.com/chatmail/relay/pull/905>
|
||||||
|
* set default smtp_tls_security_level to "verify" unconditionally <https://github.com/chatmail/relay/pull/902>
|
||||||
|
* featprefer IPv4 in SMTP client <https://github.com/chatmail/relay/pull/900>
|
||||||
|
* Install dovecot .deb packages atomically <https://github.com/chatmail/relay/pull/899>
|
||||||
|
* stop installing cron package <https://github.com/chatmail/relay/pull/898>
|
||||||
|
* Rewrite dovecot install logic, update <https://github.com/chatmail/relay/pull/862>
|
||||||
|
* fix a test and some linting fixes <https://github.com/chatmail/relay/pull/897>
|
||||||
|
* Disable IP verification on domain-literal addresses <https://github.com/chatmail/relay/pull/895>
|
||||||
|
* disable installing recommended packages globally on the relay <https://github.com/chatmail/relay/pull/887>
|
||||||
|
* multiple bug fixes across chatmaild and cmdeploy <https://github.com/chatmail/relay/pull/883>
|
||||||
|
* remove /metrics from the website <https://github.com/chatmail/relay/pull/703>
|
||||||
|
* add Prometheus textfile output to fsreport <https://github.com/chatmail/relay/pull/881>
|
||||||
|
* chown opendkim: private key <https://github.com/chatmail/relay/pull/879>
|
||||||
|
* make sure chatmail-metadata was started <https://github.com/chatmail/relay/pull/882>
|
||||||
|
* dovecot update url <https://github.com/chatmail/relay/pull/880>
|
||||||
|
* upgrade to filtermail v0.5.2 <https://github.com/chatmail/relay/pull/876>
|
||||||
|
* download dovecot packages from github release <https://github.com/chatmail/relay/pull/875>
|
||||||
|
* replace DKIM verification with filtermail v0.5 <https://github.com/chatmail/relay/pull/831>
|
||||||
|
* remove CFFI deltachat bindings usage, and consolidate test support with rpc-bindings <https://github.com/chatmail/relay/pull/872>
|
||||||
|
* prepare chatmaild/cmdeploy changes for Docker support <https://github.com/chatmail/relay/pull/857>
|
||||||
|
* stabilize online benchmark timing adding rate-limit-aware cooldown between iterations <https://github.com/chatmail/relay/pull/867>
|
||||||
|
* move rate-limit cooldown to benchmark fixture <https://github.com/chatmail/relay/pull/868>
|
||||||
|
* reconfigure acmetool from redirector to proxy mode <https://github.com/chatmail/relay/pull/861>
|
||||||
|
* make tests work with `--ssh-host localhost` <https://github.com/chatmail/relay/pull/856>
|
||||||
|
* mark f-string with f prefix in test_expunged <https://github.com/chatmail/relay/pull/863>
|
||||||
|
* install also if dovecot.service=False in SystemdEnabled Fact <https://github.com/chatmail/relay/pull/841>
|
||||||
|
* Introduce support for self-signed chatmail relays <https://github.com/chatmail/relay/pull/855>
|
||||||
|
* Strip Received headers before delivery <https://github.com/chatmail/relay/pull/849>
|
||||||
|
* upgrade to filtermail v0.3 <https://github.com/chatmail/relay/pull/850>
|
||||||
|
* fix link to Maddy and update madmail URL <https://github.com/chatmail/relay/pull/847>
|
||||||
|
* accept self-signed certificates for IP-only relays <https://github.com/chatmail/relay/pull/846>
|
||||||
|
* enforce sending from public IP addresses <https://github.com/chatmail/relay/pull/845>
|
||||||
|
* port check: check addresses, fix single services <https://github.com/chatmail/relay/pull/844>
|
||||||
|
* remediates issue with improper concat on resolver injection <https://github.com/chatmail/relay/pull/834>
|
||||||
|
* ipv6 boolean not being respected during operations <https://github.com/chatmail/relay/pull/832>
|
||||||
|
* upgrade to filtermail v0.2 by <https://github.com/chatmail/relay/pull/825>
|
||||||
|
* fix link to filtermail <https://github.com/chatmail/relay/pull/824>
|
||||||
|
* print timestamps when sending messages <https://github.com/chatmail/relay/pull/823>
|
||||||
|
* fix flaky test_exceed_rate_limit <https://github.com/chatmail/relay/pull/822>
|
||||||
|
* Replace filtermail with rust reimplementation <https://github.com/chatmail/relay/pull/808>
|
||||||
|
* Set default internal SMTP ports in Config <https://github.com/chatmail/relay/pull/819>
|
||||||
|
* separate metrics for incoming and outgoing messages <https://github.com/chatmail/relay/pull/820>
|
||||||
|
* disable appending the Received header <https://github.com/chatmail/relay/pull/815>
|
||||||
|
* fail on errors in postfix/dovecot config <https://github.com/chatmail/relay/pull/813>
|
||||||
|
* tweak idle/hibernate metrics some more <https://github.com/chatmail/relay/pull/811>
|
||||||
|
* add config flag to export statistics <https://github.com/chatmail/relay/pull/806>
|
||||||
|
* add --website-only option to run subcommand <https://github.com/chatmail/relay/pull/768>
|
||||||
|
* Strip DKIM-Signature header before LMTP <https://github.com/chatmail/relay/pull/803>
|
||||||
|
* properly make sure that postfix gets restarted on failure <https://github.com/chatmail/relay/pull/802>
|
||||||
|
* expire.py: use absolute path to maildirsize <https://github.com/chatmail/relay/pull/807>
|
||||||
|
* pin Dovecot documentation URLs to version 2.3 <https://github.com/chatmail/relay/pull/800>
|
||||||
|
* try to use "build machine" and "deployment server" consistently <https://github.com/chatmail/relay/pull/797>
|
||||||
|
* adds instructions for migrating control machines <https://github.com/chatmail/relay/pull/795>
|
||||||
|
* use consistent naming schema in getting started <https://github.com/chatmail/relay/pull/793>
|
||||||
|
* remove jsok/serialize-workflow-action dependency <https://github.com/chatmail/relay/pull/790>
|
||||||
|
* streamline migration guide wording, provide titled steps <https://github.com/chatmail/relay/pull/789>
|
||||||
|
* increases default max mailbox size <https://github.com/chatmail/relay/pull/792>
|
||||||
|
* use daemon_name for OpenDKIM sign-verify decision instead of IP <https://github.com/chatmail/relay/pull/784>
|
||||||
|
|
||||||
## 1.9.0 2025-12-18
|
## 1.9.0 2025-12-18
|
||||||
|
|
||||||
### Documentation
|
### Documentation
|
||||||
|
|||||||
@@ -93,9 +93,7 @@ def run_cmd(args, out):
|
|||||||
strict_tls = args.config.tls_cert_mode == "acme"
|
strict_tls = args.config.tls_cert_mode == "acme"
|
||||||
if not args.dns_check_disabled:
|
if not args.dns_check_disabled:
|
||||||
remote_data = dns.get_initial_remote_data(sshexec, args.config.mail_domain)
|
remote_data = dns.get_initial_remote_data(sshexec, args.config.mail_domain)
|
||||||
if not dns.check_initial_remote_data(
|
if not dns.check_initial_remote_data(remote_data, strict_tls=strict_tls, print=out.red):
|
||||||
remote_data, strict_tls=strict_tls, print=out.red
|
|
||||||
):
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
@@ -118,11 +116,7 @@ def run_cmd(args, out):
|
|||||||
out.check_call(cmd, env=env)
|
out.check_call(cmd, env=env)
|
||||||
if args.website_only:
|
if args.website_only:
|
||||||
out.green("Website deployment completed.")
|
out.green("Website deployment completed.")
|
||||||
elif (
|
elif not args.dns_check_disabled and strict_tls and not remote_data["acme_account_url"]:
|
||||||
not args.dns_check_disabled
|
|
||||||
and strict_tls
|
|
||||||
and not remote_data["acme_account_url"]
|
|
||||||
):
|
|
||||||
out.red("Deploy completed but letsencrypt not configured")
|
out.red("Deploy completed but letsencrypt not configured")
|
||||||
out.red("Run 'cmdeploy run' again")
|
out.red("Run 'cmdeploy run' again")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -591,17 +591,11 @@ def deploy_chatmail(config_path: Path, disable_mail: bool, website_only: bool) -
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Check if mtail_address interface is available (if configured)
|
# Check if mtail_address interface is available (if configured)
|
||||||
if config.mtail_address and config.mtail_address not in (
|
if config.mtail_address and config.mtail_address not in ('127.0.0.1', '::1', 'localhost'):
|
||||||
"127.0.0.1",
|
|
||||||
"::1",
|
|
||||||
"localhost",
|
|
||||||
):
|
|
||||||
ipv4_addrs = host.get_fact(hardware.Ipv4Addrs)
|
ipv4_addrs = host.get_fact(hardware.Ipv4Addrs)
|
||||||
all_addresses = [addr for addrs in ipv4_addrs.values() for addr in addrs]
|
all_addresses = [addr for addrs in ipv4_addrs.values() for addr in addrs]
|
||||||
if config.mtail_address not in all_addresses:
|
if config.mtail_address not in all_addresses:
|
||||||
Out().red(
|
Out().red(f"Deploy failed: mtail_address {config.mtail_address} is not available (VPN up?).\n")
|
||||||
f"Deploy failed: mtail_address {config.mtail_address} is not available (VPN up?).\n"
|
|
||||||
)
|
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
if not is_in_container():
|
if not is_in_container():
|
||||||
|
|||||||
@@ -20,30 +20,12 @@ DOVECOT_ARCHIVE_VERSION = "2.3.21+dfsg1-3"
|
|||||||
DOVECOT_PACKAGE_VERSION = f"1:{DOVECOT_ARCHIVE_VERSION}"
|
DOVECOT_PACKAGE_VERSION = f"1:{DOVECOT_ARCHIVE_VERSION}"
|
||||||
|
|
||||||
DOVECOT_SHA256 = {
|
DOVECOT_SHA256 = {
|
||||||
(
|
("core", "amd64"): "dd060706f52a306fa863d874717210b9fe10536c824afe1790eec247ded5b27d",
|
||||||
"core",
|
("core", "arm64"): "e7548e8a82929722e973629ecc40fcfa886894cef3db88f23535149e7f730dc9",
|
||||||
"amd64",
|
("imapd", "amd64"): "8d8dc6fc00bbb6cdb25d345844f41ce2f1c53f764b79a838eb2a03103eebfa86",
|
||||||
): "dd060706f52a306fa863d874717210b9fe10536c824afe1790eec247ded5b27d",
|
("imapd", "arm64"): "178fa877ddd5df9930e8308b518f4b07df10e759050725f8217a0c1fb3fd707f",
|
||||||
(
|
("lmtpd", "amd64"): "2f69ba5e35363de50962d42cccbfe4ed8495265044e244007d7ccddad77513ab",
|
||||||
"core",
|
("lmtpd", "arm64"): "89f52fb36524f5877a177dff4a713ba771fd3f91f22ed0af7238d495e143b38f",
|
||||||
"arm64",
|
|
||||||
): "e7548e8a82929722e973629ecc40fcfa886894cef3db88f23535149e7f730dc9",
|
|
||||||
(
|
|
||||||
"imapd",
|
|
||||||
"amd64",
|
|
||||||
): "8d8dc6fc00bbb6cdb25d345844f41ce2f1c53f764b79a838eb2a03103eebfa86",
|
|
||||||
(
|
|
||||||
"imapd",
|
|
||||||
"arm64",
|
|
||||||
): "178fa877ddd5df9930e8308b518f4b07df10e759050725f8217a0c1fb3fd707f",
|
|
||||||
(
|
|
||||||
"lmtpd",
|
|
||||||
"amd64",
|
|
||||||
): "2f69ba5e35363de50962d42cccbfe4ed8495265044e244007d7ccddad77513ab",
|
|
||||||
(
|
|
||||||
"lmtpd",
|
|
||||||
"arm64",
|
|
||||||
): "89f52fb36524f5877a177dff4a713ba771fd3f91f22ed0af7238d495e143b38f",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -79,7 +61,11 @@ class DovecotDeployer(Deployer):
|
|||||||
self.need_restart = True
|
self.need_restart = True
|
||||||
files.put(
|
files.put(
|
||||||
name="Pin dovecot packages to block Debian dist-upgrades",
|
name="Pin dovecot packages to block Debian dist-upgrades",
|
||||||
src=io.StringIO("Package: dovecot-*\nPin: version *\nPin-Priority: -1\n"),
|
src=io.StringIO(
|
||||||
|
"Package: dovecot-*\n"
|
||||||
|
"Pin: version *\n"
|
||||||
|
"Pin-Priority: -1\n"
|
||||||
|
),
|
||||||
dest="/etc/apt/preferences.d/pin-dovecot",
|
dest="/etc/apt/preferences.d/pin-dovecot",
|
||||||
user="root",
|
user="root",
|
||||||
group="root",
|
group="root",
|
||||||
@@ -98,7 +84,7 @@ class DovecotDeployer(Deployer):
|
|||||||
if not self.disable_mail and not self.need_restart:
|
if not self.disable_mail and not self.need_restart:
|
||||||
stale = host.get_fact(
|
stale = host.get_fact(
|
||||||
Command,
|
Command,
|
||||||
"pid=$(systemctl show -p MainPID --value dovecot.service 2>/dev/null);"
|
'pid=$(systemctl show -p MainPID --value dovecot.service 2>/dev/null);'
|
||||||
' [ "${pid:-0}" != "0" ] && readlink "/proc/$pid/exe" 2>/dev/null | grep -q "(deleted)"'
|
' [ "${pid:-0}" != "0" ] && readlink "/proc/$pid/exe" 2>/dev/null | grep -q "(deleted)"'
|
||||||
" && echo STALE || true",
|
" && echo STALE || true",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
from pyinfra import facts, host
|
from pyinfra import facts, host
|
||||||
from pyinfra.operations import files, systemd
|
from pyinfra.operations import files, systemd
|
||||||
|
|
||||||
@@ -13,6 +15,16 @@ class FiltermailDeployer(Deployer):
|
|||||||
self.need_restart = False
|
self.need_restart = False
|
||||||
|
|
||||||
def install(self):
|
def install(self):
|
||||||
|
local_bin = os.environ.get("CHATMAIL_FILTERMAIL_BINARY")
|
||||||
|
if local_bin:
|
||||||
|
self.need_restart |= files.put(
|
||||||
|
name="Upload locally built filtermail",
|
||||||
|
src=local_bin,
|
||||||
|
dest=self.bin_path,
|
||||||
|
mode="755",
|
||||||
|
).changed
|
||||||
|
return
|
||||||
|
|
||||||
arch = host.get_fact(facts.server.Arch)
|
arch = host.get_fact(facts.server.Arch)
|
||||||
url = f"https://github.com/chatmail/filtermail/releases/download/v0.6.1/filtermail-{arch}"
|
url = f"https://github.com/chatmail/filtermail/releases/download/v0.6.1/filtermail-{arch}"
|
||||||
sha256sum = {
|
sha256sum = {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=mtail
|
Description=mtail
|
||||||
|
After=multi-user.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
|
|||||||
@@ -12,27 +12,15 @@ def openssl_selfsigned_args(domain, cert_path, key_path, days=36500):
|
|||||||
``www.<domain>`` and ``mta-sts.<domain>``.
|
``www.<domain>`` and ``mta-sts.<domain>``.
|
||||||
"""
|
"""
|
||||||
return [
|
return [
|
||||||
"openssl",
|
"openssl", "req", "-x509",
|
||||||
"req",
|
"-newkey", "ec", "-pkeyopt", "ec_paramgen_curve:P-256",
|
||||||
"-x509",
|
"-noenc", "-days", str(days),
|
||||||
"-newkey",
|
"-keyout", str(key_path),
|
||||||
"ec",
|
"-out", str(cert_path),
|
||||||
"-pkeyopt",
|
"-subj", f"/CN={domain}",
|
||||||
"ec_paramgen_curve:P-256",
|
|
||||||
"-noenc",
|
|
||||||
"-days",
|
|
||||||
str(days),
|
|
||||||
"-keyout",
|
|
||||||
str(key_path),
|
|
||||||
"-out",
|
|
||||||
str(cert_path),
|
|
||||||
"-subj",
|
|
||||||
f"/CN={domain}",
|
|
||||||
# Mark as end-entity cert so it cannot be used as a CA to sign others.
|
# Mark as end-entity cert so it cannot be used as a CA to sign others.
|
||||||
"-addext",
|
"-addext", "basicConstraints=critical,CA:FALSE",
|
||||||
"basicConstraints=critical,CA:FALSE",
|
"-addext", "extendedKeyUsage=serverAuth,clientAuth",
|
||||||
"-addext",
|
|
||||||
"extendedKeyUsage=serverAuth,clientAuth",
|
|
||||||
"-addext",
|
"-addext",
|
||||||
f"subjectAltName=DNS:{domain},DNS:www.{domain},DNS:mta-sts.{domain}",
|
f"subjectAltName=DNS:{domain},DNS:www.{domain},DNS:mta-sts.{domain}",
|
||||||
]
|
]
|
||||||
@@ -54,9 +42,7 @@ class SelfSignedTlsDeployer(Deployer):
|
|||||||
|
|
||||||
def configure(self):
|
def configure(self):
|
||||||
args = openssl_selfsigned_args(
|
args = openssl_selfsigned_args(
|
||||||
self.mail_domain,
|
self.mail_domain, self.cert_path, self.key_path,
|
||||||
self.cert_path,
|
|
||||||
self.key_path,
|
|
||||||
)
|
)
|
||||||
cmd = shlex.join(args)
|
cmd = shlex.join(args)
|
||||||
server.shell(
|
server.shell(
|
||||||
|
|||||||
@@ -30,15 +30,12 @@ def test_newemail_configure(maildomain, rpc, chatmail_config):
|
|||||||
# set_config_from_qr, so fetch credentials via requests instead
|
# set_config_from_qr, so fetch credentials via requests instead
|
||||||
res = requests.post(f"https://{maildomain}/new", verify=False)
|
res = requests.post(f"https://{maildomain}/new", verify=False)
|
||||||
data = res.json()
|
data = res.json()
|
||||||
rpc.add_or_update_transport(
|
rpc.add_or_update_transport(account_id, {
|
||||||
account_id,
|
"addr": data["email"],
|
||||||
{
|
"password": data["password"],
|
||||||
"addr": data["email"],
|
"imapServer": maildomain,
|
||||||
"password": data["password"],
|
"smtpServer": maildomain,
|
||||||
"imapServer": maildomain,
|
"certificateChecks": "acceptInvalidCertificates",
|
||||||
"smtpServer": maildomain,
|
})
|
||||||
"certificateChecks": "acceptInvalidCertificates",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
rpc.add_transport_from_qr(account_id, url)
|
rpc.add_transport_from_qr(account_id, url)
|
||||||
|
|||||||
@@ -417,12 +417,9 @@ class Remote:
|
|||||||
getjournal = "journalctl -f" if not logcmd else logcmd
|
getjournal = "journalctl -f" if not logcmd else logcmd
|
||||||
print(self.sshdomain)
|
print(self.sshdomain)
|
||||||
match self.sshdomain:
|
match self.sshdomain:
|
||||||
case "@local":
|
case "@local": command = []
|
||||||
command = []
|
case "localhost": command = []
|
||||||
case "localhost":
|
case _: command = ["ssh", f"root@{self.sshdomain}"]
|
||||||
command = []
|
|
||||||
case _:
|
|
||||||
command = ["ssh", f"root@{self.sshdomain}"]
|
|
||||||
[command.append(arg) for arg in getjournal.split()]
|
[command.append(arg) for arg in getjournal.split()]
|
||||||
popen = subprocess.Popen(
|
popen = subprocess.Popen(
|
||||||
command,
|
command,
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ def make_host(*fact_pairs):
|
|||||||
if cls not in facts:
|
if cls not in facts:
|
||||||
registered = ", ".join(c.__name__ for c in facts)
|
registered = ", ".join(c.__name__ for c in facts)
|
||||||
raise LookupError(
|
raise LookupError(
|
||||||
f"unexpected get_fact({cls.__name__}); only registered: {registered}"
|
f"unexpected get_fact({cls.__name__}); "
|
||||||
|
f"only registered: {registered}"
|
||||||
)
|
)
|
||||||
return facts[cls]
|
return facts[cls]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user