115 Commits

Author SHA1 Message Date
Timmy Welch
8e9ea901e9 Merge remote-tracking branch 'gh/main' 2025-12-12 01:49:12 -08:00
Alberto Bertogli
d0afe102de chasquid: Exit with code 0 on SIGINT/SIGTERM
When we get SIGINT or SIGTERM, today chasquid exits with code 1. This
can confuse some of the supervision tools.

In particular, Docker and Kubernetes expect exit 0 upon an intentional
stop.

And systemd, the Restart= semantics make a difference with 0 and non-0,
and exiting with 1 prevents users from making that distinction.

This patch changes the SIGINT/SIGTERM exit code to 0, to make it easier
for users to set up things as desired in those environments.

Thanks to [Guiorgy@github](https://github.com/Guiorgy) for reporting
this problem in https://github.com/albertito/chasquid/pull/70.
2025-08-03 17:56:43 +01:00
Alberto Bertogli
24c2c4f5fd Make the max queue size and give up time configurable
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.
2025-06-07 11:00:00 +01:00
Alberto Bertogli
8e4d31c74c Fix minor typos found by codespell
This patch fixes some minor typos in comments and strings found by
codespell.

While at it, also expand some variable names that were not typos, but
caused false positives, and end up being more readable anyway.
2025-04-06 14:02:56 +01:00
Alberto Bertogli
45580dae46 Update to math/rand/v2
This commit updates the uses of math/rand to math/rand/v2, which was
released in Go 1.22 (2024-02).

The new package is generally safer, see https://go.dev/blog/randv2 for
the details.

There are no user-visible changes, it is only adjusting the name of
functions, simplify some code thanks to v2 having a better API, etc.
2025-02-16 20:18:16 +00:00
Alberto Bertogli
aae0367c60 Log how many things were loaded for each domain
This patch makes chasquid log how many users, aliases and DKIM keys were
loaded for each domain.

This makes it easier to confirm changes, and troubleshoot problems
related to these per-domain configuration files.
2024-05-10 12:19:49 +01:00
Alberto Bertogli
e6a9410377 Exit if there's an error reading users/aliases files on startup
Today, when starting up, if there's an error reading the users or
aliases files, we only log but do not exit. And then those files will
not be attempted to be read on the periodic reload.

We also treat "file does not exist" as an error for users file, but not
aliases file, resulting in inconsistent behaviour between the two.

All of this makes some classes of problems (like permission errors) more
difficult to spot and troubleshoot. For example,
https://github.com/albertito/chasquid/issues/55.

So this patch makes errors reading users/aliases files on startup a
fatal error, and also unifies the "file does not exist" behaviour to
make it not an error in both cases.

Note that the behaviour on the periodic reload is unchanged: treat these
errors as fatal too. This may be changed in future patches.
2024-05-10 12:09:53 +01:00
Alberto Bertogli
76a72367ae dkim: Implement internal dkim signing and verification
This patch implements internal DKIM signing and verification.
2024-03-12 20:43:21 +00:00
Ernesto Alfonso
36c5139da4 Skip non-directories in the domains/ directory
This prevents chasquid from attempting to look for certs under a
non-directory, e.g. `/etc/chasquid/domains/.gitignore/certs`.

Amended-by: Alberto Bertogli <albertito@blitiri.com.ar>
  Adjusted commit message, applied `go fmt`.
2024-02-05 00:04:37 +00:00
Alberto Bertogli
dbff2f0455 Reject empty listening addresses
Using an empty listening address will result in chasquid listening on a
random port, which is a dangerous misconfiguration.

That is most likely done to prevent it from listening at all.

To prevent this misconfiguration, explicitly reject empty listening
addresses early and with a warning, so there is no ambiguity.

Users can still prevent chasquid from listening by just commenting out
the entry in the config (and not passing any systemd file descriptors).

See https://github.com/albertito/chasquid/issues/45 for more details and
discussion, including alternatives considered.

Thanks to xavierg who reported this via IRC.
2023-12-02 15:08:09 +00:00
Alberto Bertogli
f51b449c69 chasquid: Move the certificate loading logic in a separate function
This patch moves the top-level certificate loading logic out of main and
into a separate function.

This is only for readability and consistency with how we handle domains
(which have a similar structure already). There are no logic changes.
2023-09-17 10:58:25 +01:00
Alberto Bertogli
b9e222f6eb chasquid: Remove unnecessary logging on loading aliases and users on startup
When starting up, for each domain we parse aliases and users files (if
they exist).

Today we print a line for each, which gets quite verbose and doesn't
offer much useful information.

This patch adjusts that logic so that we only print errors (unless a
file does not exist, which is a normal case).

This also improves the scenario where chasquid does not have permissions
to access the users file: before this patch, that would fail silently,
but with this patch we show the correct error.

While at it, make the "Loading" messages consistent with each other, for
readability.
2023-09-17 10:54:49 +01:00
Alberto Bertogli
888b2df4c1 Handle symlinks under the certs/ directory
Currently, if the `certs/` directory has a symlink inside, we skip it.
That is not really intended, it's an unfortunate side-effect of skipping
regular files.

To fix this, this patch adjusts the logic to only ignore regular files
instead. It also adds a message when a directory is skipped, to make it
easier to debug permission issues.

Thanks to @erjoalgo for reporting this in
https://github.com/albertito/chasquid/pull/39, and providing an
alternative patch!
2023-09-02 13:58:24 +01:00
Alberto Bertogli
ddd1b6d96e chasquid: Run a localrpc server
This patch makes chasquid run a localrpc server, exporting two methods:
alias resolve, and domaininfo clear.

They will be used by chasquid-util in later patches.
2023-07-30 13:21:07 +01:00
Alberto Bertogli
2b7e33a615 domaininfo: Do not reload the database periodically
It is not expected that the user modifies the domaininfo database behind
chasquid's back, and reloading it can be somewhat expensive.

So this patch removes the periodic reload, and instead makes it triggered
by SIGHUP so the user can trigger a reload manually if needed.
2023-07-28 10:05:15 +01:00
Alberto Bertogli
a54d81f406 monitoring: Get build information from Go's runtime
Currently, chasquid gets version information from build-time flags that
have to be passed by the user.

This patch extends this logic so, if no flags are given, Go's build
information will be used to construct a synthetic version string.
2023-02-05 11:01:36 +00:00
Alberto Bertogli
7d6a59ba77 test: Update coverage tests to Go 1.20
Go 1.20 finally includes proper support for instrumenting binaries for
coverage. This allows us to drop quite a few hacks and workarounds that
we used for it, and we can now also test exiting cases.

The downside is that coverage tests now require Go 1.20, but it is an
acceptable price to pay for the more accurate results.

Normal integration tests are unchanged.

This patch updates the coverage testing infrastructure to make use of
the new Go 1.20 features.
2023-02-01 23:43:12 +00:00
Alberto Bertogli
3ebe5c5173 Replace uses of ioutil
ioutil package was deprecated in Go 1.16, replace all uses with their
respective replacements.

This patch was generated with a combination of `gofmt -r`, `eg`, and
manually (for `ioutil.ReadDir`).
2022-11-12 20:06:35 +00:00
Alberto Bertogli
fa1db7d81a config: Support "" values for drop_characters and suffix_separators
If the `drop_characters` or `suffix_separators` options are set to "",
currently instead of the empty string, their default value is used instead.

This is a bug, and it also happens on other config options, but because
the others have to be set in order for chasquid to function, it's not a
problem in practice.

Thanks Björn Busse (bbusse@github) for finding and reporting this
problem, on irc and in https://github.com/albertito/chasquid/issues/25.

This patch fixes the problem by marking these fields explicitly
optional, which enables presence testing, as described in the protobuf
documentation:
https://github.com/protocolbuffers/protobuf/blob/master/docs/field_presence.md.
2022-01-21 12:07:34 +00:00
Alberto Bertogli
fa651e74e3 dovecot: Retry auto-detect until we find a usable socket pair
Currently, chasquid attempts to auto-detect dovecot sockets when
starting up (if needed). If autodetection fails, chasquid emits an
error, continues serving, and never tries again.

This can be problematic if chasquid starts up before dovecot, and at the
time the dovecot sockets are not present (e.g. after a reboot). In that
case, chasquid will not use dovecot for authentication even after
dovecot has started.

This patch changes the autodetect logic, by doing autodetection at
startup and on each request, until we find a working pair of sockets.
Once we do, they're used consistently.

That way, if dovecot is not ready when chasquid starts, it's not a
problem and chasquid will start using dovecot once it becomes available.

Thanks to Thor77 (thor77@thor77.org) for reporting and helping
troubleshoot this issue.
2021-05-24 10:21:33 +01:00
lordwelch
660da4a85b Allow multiple authentications for the same relay based on from domain
Allow dovecot auth paths to use tcp
Add any domains of authenticated users to localDomains
2021-01-29 14:19:19 -08:00
lordwelch
e685366a28 Add support for sending mail to a specific relay
Update go-cmp and protobuf
Add support for dovecot auth over tcp
2021-01-24 13:27:07 -08:00
Alberto Bertogli
e79586a014 Implement HAProxy protocol support
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!
2020-11-13 20:49:42 +00:00
ThinkChaos
bb1b921e3c Add /exit endpoint to monitoring server
Allows terminating chasquid via the network. Useful to trigger a restart
(if there is an init system to relaunch chasquid) and thus reload certificates.

Amended-by: Alberto Bertogli <albertito@blitiri.com.ar>
  Added tests, and adjusted shutdown sequence.
2020-11-12 23:24:21 +00:00
Alberto Bertogli
025cb2d96a courier: Rename Procmail to MDA
This patch renames courier.Procmail to courier.MDA, to make it more
obvious that the functionality is not tied to that particular MDA.

It's just for readability, there are no functional changes.
2020-09-17 02:47:42 +01:00
Alberto Bertogli
7fe42a368a monitoring: Add OpenMetrics exporter
This patch makes chasquid's monitoring server expose an OpenMetrics
metrics endpoint.

It adds a new package "expvarom" which implements an HTTP handler that
exports expvar variables in the OpenMetrics text format.

Then, the handler is registered by the monitoring server at /metrics
(where most things expect it to be).

The existing exported variables are also extended with descriptions,
which is optional, but improves the readability of the metrics.
2020-08-21 12:07:33 +01:00
Alberto Bertogli
33446fd565 monitoring: Reorganize index structure
This patch improves the organization of the monitoring index page:

- Include the hostname (both OS and configured) for convenience.
- Round the uptime presentation for readability.
- Add a tiny CSS for consistency with the traces.
- Re-arrange the list of links for readability.
2020-07-08 23:23:17 +01:00
Alberto Bertogli
a08b86a663 Move monitoring HTTP server code to a separate file
This patch moves the monitoring HTTP server code to its own file, for
readability purposes only.
2020-07-08 22:15:37 +01:00
Alberto Bertogli
d9d56552f3 maillog: Support logging to stdout and stderr
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.
2020-05-24 02:26:18 +01:00
ThinkChaos
db810084a0 Reopen logs on SIGHUP
This makes it possible to manage chasquid logs using logrotate.

Amended-by: Alberto Bertogli <albertito@blitiri.com.ar>
  Added tests, minor style and comment changes.
2020-05-22 20:34:42 +01:00
ThinkChaos
ade107f62e maillog: Use blitiri.com.ar/go/log for mail log
In preparation for supporting log rotation, this patch makes the maillog
package to use blitiri.com.ar/go/log instead of its own writer.

Some of the tests are made more strict, to better test the log format.

Amended-by: Alberto Bertogli <albertito@blitiri.com.ar>
  Fixed build, extended commit message, adjusted to the log options
  API, and added tests.
2020-05-22 20:09:19 +01:00
Alberto Bertogli
4c28efcb20 config: Allow overrides from the command line
This patch allows the configuration values to be overridden from the
command-line, with a new -config_overrides flag.

There is a fairly specific use case for this, when editing the
configuration file is not feasible or convenient (e.g. running an
user-supplied configuration in a managed environment).
2020-05-17 00:10:06 +01:00
Alberto Bertogli
b1fe4f81f9 config: Improve logging of errors
Currently, the config package logs errors itself, in addition to
returning them.

That is confusing and results in some duplication of logging.

This patch makes config just return errors, and adjusts the callers
to log them properly.
2020-05-16 23:46:43 +01:00
Alberto Bertogli
13ee3ba482 courier: Use the hostname in SMTP HELO
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.
2020-05-13 20:27:17 +01:00
Alberto Bertogli
d6b512166b Make it explicit when we are intentionally not checking errors
The linter complains that we're not checking for errors, but on some
cases it's on code paths were it is reasonable to do so (e.g. we're
closing the connection and it's a best-effort write).

This patch adjusts the code to make those cases explicit.
2020-04-14 12:01:01 +01:00
Alberto Bertogli
aed0156579 chasquid: Check result of initial os.Chdir
The daemon attempts to change to the config directory on startup, for
security and convenience.

We currently don't check if this works, which is not a big deal since it
will just fail later on when it can't find the files. However, it makes
things more awkward to debug, so this patch adds an explicit check.
2020-04-14 12:01:01 +01:00
Alberto Bertogli
f399fe3e84 aliases: Implement aliases hooks
This patch implements two new hooks: alias-resolve and alias-exists.

They are called during the aliases resolution process, to allow for more
complex integration with other systems, such as storing the aliases in a
database.

See the included documentation for more details.
2019-10-24 21:37:09 +01:00
Alberto Bertogli
dbd8bd7699 chasquid: Update docstring to match the README file 2018-07-14 10:45:10 +01:00
Alberto Bertogli
23deaf1f88 Reinstate the MTA-STS (Strict Transport Security) implementation
This commit brings back the experimental MTA-STS (Strict Transport
Security) implementation, removed in commit
7f5bedf4aa.

We will continue development in the "sts" branch, subject to rebase,
until it is ready to be integrated into "next" again.
2018-07-01 12:19:02 +01:00
Alberto Bertogli
d39d3aaff4 chasquid: Dovecot support (experimental)
This patch adds dovecot support to the chasquid daemon, using the
internal dovecot library added in previous patches.

Dovecot support is still considered EXPERIMENTAL and may be reverted, or
changed in backwards-incompatible ways.

The patch also adds the corresponding integration test, which brings up
a dovecot server with a custom configuration, and tests chasquid's
authentication against it.  If dovecot is not installed, the test is
skipped.
2018-02-10 23:18:31 +00:00
Alberto Bertogli
b3592b7bf9 chasquid: Add package-level documentation 2017-11-19 13:49:54 +00:00
Alberto Bertogli
033a5d657b Use the external log, spf and systemd packages
The log, spf and systemd packages have been externalized; use them
instead of the internal version to avoid having two versions of the same
thing.
2017-09-17 22:17:14 +01:00
Alberto Bertogli
17eff21279 Only fail if there is no address to listen on at all, regardless of mode
Currently, chasquid exits if any mode (SMTP/submission/submission+tls)
has no addresses to listen on. This means that chasquid must be given
addresses for all three.

While that's generally the expected configuration, there are cases where
users may not want to have all three.

So this patch replaces that fatal error with a warning, and only makes
chasquid exit if there are no addresses to listen on at all.
2017-04-12 10:32:41 +01:00
Alberto Bertogli
7f5bedf4aa Remove the MTA-STS (Strict Transport Security) implementation
This commit removes the experimental MTA-STS (Strict Transport Security)
implementation for now, as it's not up to date with the latest draft.

Development will continue on the "sts" branch, but this way it won't
block releases until it is ready.

Commits reverted:
 - cb6500b993
 - 0eeb964534
 - e66288e4b4
 - 216cf47ffa
 - d66b06de51
 - fe00750e39
 - 933ab54cd8
2017-04-11 00:58:59 +01:00
Alberto Bertogli
213bc63a95 Support submission (directly) over TLS (submissions/smtps/port 465)
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).
2017-04-10 19:59:04 +01:00
Alberto Bertogli
216cf47ffa courier: Add STS policy checking to the SMTP courier
This patch extends the SMTP courier to (optionally) do STS policy
checking when delivering mail.

As STS support is currently experimental, we gate this behind a flag and
is disabled by default.
2017-02-28 22:27:15 +00:00
Alberto Bertogli
7b51ce725b chasquid: Ignore non-directories in certs/
We only care about directories within the certs/, but the code as-is
complains if there are files.

This patch makes the iteration skip non-directories entirely.

Thanks to Martin Ferrari for the bug report!
2016-11-22 20:39:19 +00:00
Alberto Bertogli
60a7932bd3 log: Replace glog with a new logging module
glog works fine and has great features, but it does not play along well
with systemd or standard log rotators (as it does the rotation itself).

So this patch replaces glog with a new logging module "log", which by
default logs to stderr, in a systemd-friendly manner.

Logging to files or syslog is still supported.
2016-11-01 23:56:04 +00:00
Alberto Bertogli
c87c5ec1bc chasquid: Include build and version information
This patch adds the possibility of setting build and version
information, which will be exported and displayed in the monitoring http
server.
2016-10-26 22:25:12 +01:00
Alberto Bertogli
febe96697a maillog: Introduce a special-purpose mail logging package
The default INFO logs are more oriented towards debugging and can be
a bit too verbose when looking for high-level information.

This patch introduces a new "maillog" package, used to log messages of
particular relevance to mail transmission at a higher level.
2016-10-21 22:20:47 +01:00