The current fail2ban regexp catches all SMTP connection errors.
This works fine, but includes connection errors, that can be caused by
transient external causes, and accidentally delay email delivery.
This patch changes the regexp to be more targeted towards specific SMTP
errors that are likely to be caused by deliberate actions.
The expression was cross-checked with a few month of errors to confirm
it should not have false positives, and that it correctly left
connection errors alone.
Thanks to pepperbob@github for reporting this in
https://github.com/albertito/chasquid/issues/77.
Today, the maximum number of items in the queue, as well as how long we
keep attempting to send each item, is hard-coded and not changed by end
users.
While they are totally adequate for chasquid's main use cases, it can
still be useful for some users to change them.
So this patch adds two new configuration options for those settings.
They're marked experimental for now, so we can adjust them if needed
after they get more exposure.
Thanks to Lewis Ross-Jones <lewis_r_j@hotmail.com> for suggesting this
improvement, and help with testing it.
This patch adds a fail2ban filter configuration example for chasquid.
It can be used to configure fail2ban to detect IPs causing connection
churn or high rate of errors.
Having systemd open sockets and pass them to chasquid is neat, but also
adds some complexity to the default config, for very little value in
practice.
This patch simplifies the default config by having chasquid open the
sockets instead.
Note that systemd file descriptor passing continues to be supported, and
existing installations will not be affected.
When running a diff for dkimpy's output, we expect that diff to exit with
non-zero code.
Unfortunately, the way we set that expectation (by prefixing the diff
invocation with `!` is incorrect.
Running `! diff ...` will not cause the hook to fail if diff exits with
0, instead `!` will cause the exit code to be ignored.
This patch fixes the problem by running `diff ... && exit 1` instead.
This was caught by shellcheck, https://www.shellcheck.net/wiki/SC2251.
This patch adds support in the default hook for using dkimpy for DKIM
signing.
Unfortunately, dkimpy binaries have the same name as driusan/dkim's, so
we need to use --help to disambiguate. It's not pretty but it should
work, and is quite self contained.
Also, for the integration tests, we still need driusan/dkim because
dkimpy lacks the features needed. Specifically, dkimpy's dkimverify
can't be made to use custom DNS, or override the TXT values in any way,
so we can't verify that the generated signature is reasonable.
Thanks to ne9z@github for suggesting this change and providing an
alternative patch in https://github.com/albertito/chasquid/pull/19.
The chasquid-rspamd utility (https://github.com/Thor77/chasquid-rspamd)
provides a better integration with rspamd, by taking envelope and
connection information from the environment variables, and communicating
with rspamd using its protocol.
So if it is available, use it instead of rspamc in the default hook.
This patch implements support for incoming connections wrapped in the
HAProxy protocol v1.
This is useful when running chasquid behind a HAProxy server, as it
needs the original source IP to perform SPF checks.
This patch is a reimplementation of one originally provided by Denys
Vitali in pull request #15, except the logic for the protocol handling
is moved to a new package, and the smtpsrv.Conn handling of the source
IP is simplified.
It is marked as experimental for now, since we want to give it a bit
more exposure just in case the option/api needs adjustment.
Thanks a lot to Denys Vitali (@denysvitali in github) for sending the
original patch for this, and helping test it!
The default hook will use rspamc (the command-line client of rspamd) if
it is installed. rspamc will emit one suggested action, and then the
hook will interpret it and return accordingly.
Because the possible actions returned by rspamc are user-configured,
this patch adds a comment to make it clear that the hook will need
adjustment if the configuration uses non-default actions.
In particular, the greylisting module (which usually handles the
"greylist" action) is not run when using rspamc. This can cause
unnecessary rejections and is quite misleading.
This patch removes the "greylist" action handling; now the default hook
will only reject mail once it reaches rspamd's configured threshold for
direct rejection.
In the future, a more custom integration with rspamd might be added to
allow for rspamd-based greylisting, but until then this is a more
reasonable default.
Thanks to Jonas Seydel (thor77) and Max Mazurov (fox.cpp@disroot.org)
for noticing this issue, helping investigate, and discussing the course
of action.
When checking if the dkimsign command exists, the default hook doesn't
redirect the output to /dev/null, so if the command is present it will
emit unwanted output (interpreted as message headers, as expected).
This patch adds the missing redirection.
Amended-by: Alberto Bertogli <albertito@blitiri.com.ar>
Extended commit message.
This patch adds support for writing maillog to stdout and stderr, which
can be desirable in certain environments.
Thanks to Denys Vitali <denys@denv.it> who sent an alternative patch for
this functionality.
The SMTP courier, which handles outgoing connections, uses the domain of
the envelope's from as the domain in the HELO/EHLO greeting.
This works fine in practice, but ideally the domain used in the greeting
should match the reverse DNS record. This used to be more relevant but
nowadays it is not really enforced; however, it sometimes comes up in
self checks, and might cause some confusion when troubleshooting.
So this patch makes it use the configured hostname instead, which is
under the users' control and more likely to be compliant. It also
simplifies the code.
The documentation of the hostname configuration option is also updated
to mention this behaviour.
Thanks to Jonas Seydel (thor77) for bringing this up.
The example post-data hook was missing a quote around a sub-shell
execution.
This is harmless because the content itself is admin-provided and not
related to user input, but this commit fixes the quote for defense in
depth and consistency.
Rspamd (https://rspamd.com/) is a popular open-source spam filtering
system.
This patch adds integration with it in the example hook, which uses the
rspamc client to get a veredict, similar to what it does for
Spamassassin.
This patch adds DKIM signing using https://github.com/driusan/dkim tools
to the example hook.
It also adds an optional integration test to exercise signing and
verification, and corresponding documentation.
This patch adds support for TLS-wrapped submission connections.
Instead of clients establishing a connection over plain text and then
using STARTTLS to switch over a TLS connection, this new mode allows the
clients to connect directly over TLS, like it's done in HTTPS.
This is not an official standard yet, but it's reasonably common in
practice, and provides some advantages over the traditional submission
port.
The default port is 465, commonly used for this; chasquid defaults to
systemd file descriptor passing as for the other protocols (for now).
The current default is "procmail" for historical reasons, but the
program has been unmaintained for years and its use is not generally
advisable.
This patch changes the default MDA binary to "maildrop", which is a more
modern and reasonable MDA to use.
We keep the courier.Procmail name for now, as that's internal, but it
may be changed later. Its documentation is updated to note that the
name is just for reference but it actually works with almost any binary.
chasquid needs at least one certificate in order to start, to prevent
accidental misconfigurations.
This patch documents this in etc/chasquid/README, and while at it fixes
a minor terminology issue.
Thanks to Martin Ferrari for the bug report!
Picking the domain used in the DSN message "From" header is more
complicated than it needs to be, causing confusing code paths and having
different uses for the hostname, which should be purely aesthetic.
This patch makes the queue pick the DSN "From" domain from the message
itself, by looking for a local domain in either the sender or the
original recipients. We should find at least one, otherwise it'd be
relaying.
This allows the code to be simplified, and we can narrow the scope of
the hostname option even further.