Skip to content

Commit

Permalink
Setup mtail
Browse files Browse the repository at this point in the history
  • Loading branch information
link2xt committed Oct 14, 2024
1 parent d0ed883 commit 7fac976
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 1 deletion.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

## untagged

There is a new required setting in `chatmail.ini`: `mtail_address`.
This defines the address on which [`mtail`](https://google.github.io/mtail/)
exposes its metrics collected from the logs.
If you want to collect the metrics with Prometheus,
setup a private network (e.g. WireGuard interface)
and assign an IP address from this network to the host.
If unsure, set this setting to `127.0.0.1`.

- add mtail
([#388](https://github.com/deltachat/chatmail/pull/388))

- fix checking for required DNS records
([#412](https://github.com/deltachat/chatmail/pull/412))

Expand Down
1 change: 1 addition & 0 deletions chatmaild/src/chatmaild/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def __init__(self, inipath, params):
self.passthrough_recipients = params["passthrough_recipients"].split()
self.filtermail_smtp_port = int(params["filtermail_smtp_port"])
self.postfix_reinject_port = int(params["postfix_reinject_port"])
self.mtail_address = params["mtail_address"]
self.disable_ipv6 = params.get("disable_ipv6", "false").lower() == "true"
self.imap_rawlog = params.get("imap_rawlog", "false").lower() == "true"
self.iroh_relay = params.get("iroh_relay")
Expand Down
8 changes: 7 additions & 1 deletion chatmaild/src/chatmaild/filtermail.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,15 +183,21 @@ def check_DATA(self, envelope):
mail_encrypted = check_encrypted(message)

_, from_addr = parseaddr(message.get("from").strip())
envelope_from_domain = from_addr.split("@").pop()

logging.info(f"mime-from: {from_addr} envelope-from: {envelope.mail_from!r}")
if envelope.mail_from.lower() != from_addr.lower():
return f"500 Invalid FROM <{from_addr!r}> for <{envelope.mail_from!r}>"

if mail_encrypted:
print("Filtering encrypted mail.", file=sys.stderr)
else:
print("Filtering unencrypted mail.", file=sys.stderr)

if envelope.mail_from in self.config.passthrough_senders:
return

passthrough_recipients = self.config.passthrough_recipients
envelope_from_domain = from_addr.split("@").pop()
for recipient in envelope.rcpt_tos:
if envelope.mail_from == recipient:
# Always allow sending emails to self.
Expand Down
13 changes: 13 additions & 0 deletions chatmaild/src/chatmaild/ini/chatmail.ini.f
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,19 @@
# if set to "True" IPv6 is disabled
disable_ipv6 = False

# Address on which `mtail` listens,
# e.g. 127.0.0.1 or some private network
# address like 192.168.10.1.
# You can point Prometheus
# or some other OpenMetrics-compatible
# collector to
# http://{{mtail_address}}:3903/metrics
# and display collected metrics with Grafana.
#
# WARNING: do not expose this service
# to the public IP address.
mtail_address = 127.0.0.1

#
# Debugging options
#
Expand Down
40 changes: 40 additions & 0 deletions cmdeploy/src/cmdeploy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,44 @@ def check_config(config):
return config


def deploy_mtail(config):
apt.packages(
name="Install mtail",
packages=["mtail"],
)

# Using our own systemd unit instead of `/usr/lib/systemd/system/mtail.service`.
# This allows to read from journalctl instead of log files.
files.template(
src=importlib.resources.files(__package__).joinpath("mtail/mtail.service.j2"),
dest="/etc/systemd/system/mtail.service",
user="root",
group="root",
mode="644",
address=config.mtail_address,
port=3903,
)

mtail_conf = files.put(
name="Mtail configuration",
src=importlib.resources.files(__package__).joinpath(
"mtail/delivered_mail.mtail"
),
dest="/etc/mtail/delivered_mail.mtail",
user="root",
group="root",
mode="644",
)

systemd.service(
name="Start and enable mtail",
service="mtail.service",
running=True,
enabled=True,
restarted=mtail_conf.changed,
)


def deploy_chatmail(config_path: Path) -> None:
"""Deploy a chat-mail instance.
Expand Down Expand Up @@ -636,3 +674,5 @@ def deploy_chatmail(config_path: Path) -> None:
name="Ensure cron is installed",
packages=["cron"],
)

deploy_mtail(config)
59 changes: 59 additions & 0 deletions cmdeploy/src/cmdeploy/mtail/delivered_mail.mtail
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
counter delivered_mail
/saved mail to INBOX$/ {
delivered_mail++
}

counter quota_exceeded
/Quota exceeded \(mailbox for user is full\)$/ {
quota_exceeded++
}

# Essentially the number of outgoing messages.
counter dkim_signed
/DKIM-Signature field added/ {
dkim_signed++
}

counter created_accounts
counter created_ci_accounts
counter created_nonci_accounts

/: Created address: (?P<addr>.*)$/ {
created_accounts++

$addr =~ /ci-/ {
created_ci_accounts++
} else {
created_nonci_accounts++
}
}

counter postfix_timeouts
/timeout after DATA/ {
postfix_timeouts++
}

counter postfix_noqueue
/postfix\/.*NOQUEUE/ {
postfix_noqueue++
}

counter warning_count
/warning/ {
warning_count++
}


counter filtered_mail_count

counter encrypted_mail_count
/Filtering encrypted mail\./ {
encrypted_mail_count++
filtered_mail_count++
}

counter unencrypted_mail_count
/Filtering unencrypted mail\./ {
unencrypted_mail_count++
filtered_mail_count++
}
10 changes: 10 additions & 0 deletions cmdeploy/src/cmdeploy/mtail/mtail.service.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=mtail

[Service]
Type=simple
ExecStart=/bin/sh -c "journalctl -f -o short-iso -n 0 | /usr/bin/mtail --address={{ address }} --port={{ port }} --progs /etc/mtail --logtostderr --logs -"
Restart=on-failure

[Install]
WantedBy=multi-user.target

0 comments on commit 7fac976

Please sign in to comment.