mirror of
https://blitiri.com.ar/repos/chasquid
synced 2026-10-28 15:02:28 +00:00
docs: Auto-format markdown documentation
This patch uses mdformat to auto-format markdown documentation. To support \ for line breaks (which is what mdformat uses), mkdocs now requires the pymdownx.escapeall extension. Because of incompatibilities between mdformat (which formats to CommonMark) and mkdocs (which expects Python-Markdown), there are now some limitations: no nested lists, multi-paragraph list items, or admonitions support. These limitations are acceptable for now, although some of the docs had to be adjusted to meet them.
This commit is contained in:
@@ -14,6 +14,8 @@ markdown_extensions:
|
|||||||
guess_lang: false
|
guess_lang: false
|
||||||
- attr_list
|
- attr_list
|
||||||
- admonition
|
- admonition
|
||||||
|
- pymdownx.escapeall:
|
||||||
|
hardbreak: true
|
||||||
|
|
||||||
theme: readthedocs
|
theme: readthedocs
|
||||||
|
|
||||||
|
|||||||
@@ -60,10 +60,13 @@ fmt:
|
|||||||
gofmt -s -w .
|
gofmt -s -w .
|
||||||
go fix ./...
|
go fix ./...
|
||||||
clang-format -i $(shell find . -iname '*.proto')
|
clang-format -i $(shell find . -iname '*.proto')
|
||||||
black -l 79 \
|
black -l 79 --quiet \
|
||||||
test/util/check-hostaliases \
|
test/util/check-hostaliases \
|
||||||
test/util/chamuyero \
|
test/util/chamuyero \
|
||||||
test/util/mail_diff
|
test/util/mail_diff
|
||||||
|
mdformat --wrap 79 --number \
|
||||||
|
--exclude 'docs/man/*.[15].md' \
|
||||||
|
README.md docs/
|
||||||
|
|
||||||
.PHONY: chasquid test \
|
.PHONY: chasquid test \
|
||||||
chasquid-util smtp-check mda-lmtp dovecot-auth-cli \
|
chasquid-util smtp-check mda-lmtp dovecot-auth-cli \
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# chasquid
|
# chasquid
|
||||||
|
|
||||||
[chasquid](https://blitiri.com.ar/p/chasquid) is an SMTP (email) server with a
|
[chasquid](https://blitiri.com.ar/p/chasquid) is an SMTP (email) server with a
|
||||||
@@ -11,64 +10,45 @@ It's written in [Go](https://golang.org), and distributed under the
|
|||||||
|
|
||||||
[](https://github.com/albertito/chasquid/actions)
|
[](https://github.com/albertito/chasquid/actions)
|
||||||
[](https://goreportcard.com/report/github.com/albertito/chasquid)
|
[](https://goreportcard.com/report/github.com/albertito/chasquid)
|
||||||
[](https://coveralls.io/github/albertito/chasquid?branch=next)
|
[](https://coveralls.io/github/albertito/chasquid?branch=next)\
|
||||||
[](https://blitiri.com.ar/p/chasquid/)
|
[](https://blitiri.com.ar/p/chasquid/)
|
||||||
[](https://webchat.oftc.net/?channels=%23chasquid)
|
[](https://webchat.oftc.net/?channels=%23chasquid)
|
||||||
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* Easy
|
- Easy
|
||||||
* Easy to configure.
|
- Easy to configure.
|
||||||
* Hard to mis-configure in ways that are harmful or insecure (e.g. no open
|
- Hard to mis-configure in ways that are harmful or insecure (e.g. no open
|
||||||
relay, or clear-text authentication).
|
relay, or clear-text authentication).
|
||||||
* [Monitoring] HTTP server, with exported variables and tracing to help
|
- [Monitoring] HTTP server, with exported variables and tracing to help
|
||||||
debugging.
|
debugging.
|
||||||
* Integrated with [Debian], [Ubuntu], [Arch], and [Alpine].
|
- Integrated with [Debian], [Ubuntu], [Arch], and [Alpine].
|
||||||
* Supports using [Dovecot] for authentication.
|
- Supports using [Dovecot] for authentication.
|
||||||
* Useful
|
- Useful
|
||||||
* Multiple/virtual domains, with per-domain users and aliases.
|
- Multiple/virtual domains, with per-domain users and aliases.
|
||||||
* Suffix dropping (`user+something@domain` → `user@domain`).
|
- Suffix dropping (`user+something@domain` → `user@domain`).
|
||||||
* [Hooks] for integration with greylisting, anti-virus, and anti-spam.
|
- [Hooks] for integration with greylisting, anti-virus, and anti-spam.
|
||||||
* International usernames ([SMTPUTF8]) and domain names ([IDNA]).
|
- International usernames ([SMTPUTF8]) and domain names ([IDNA]).
|
||||||
* Secure
|
- Secure
|
||||||
* [Tracking] of per-domain TLS support, prevents connection downgrading.
|
- [Tracking] of per-domain TLS support, prevents connection downgrading.
|
||||||
* Multiple TLS certificates.
|
- Multiple TLS certificates.
|
||||||
* Easy integration with [Let's Encrypt].
|
- Easy integration with [Let's Encrypt].
|
||||||
* [SPF] and [MTA-STS] checking.
|
- [SPF] and [MTA-STS] checking.
|
||||||
* [DKIM] support (signing and verification).
|
- [DKIM] support (signing and verification).
|
||||||
|
|
||||||
|
|
||||||
[Arch]: https://blitiri.com.ar/p/chasquid/install/#arch
|
|
||||||
[Alpine]: https://blitiri.com.ar/p/chasquid/install/#alpine
|
|
||||||
[DKIM]: https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail
|
|
||||||
[Debian]: https://blitiri.com.ar/p/chasquid/install/#debianubuntu
|
|
||||||
[Dovecot]: https://blitiri.com.ar/p/chasquid/dovecot/
|
|
||||||
[Hooks]: https://blitiri.com.ar/p/chasquid/hooks/
|
|
||||||
[IDNA]: https://en.wikipedia.org/wiki/Internationalized_domain_name
|
|
||||||
[Let's Encrypt]: https://letsencrypt.org
|
|
||||||
[MTA-STS]: https://tools.ietf.org/html/rfc8461
|
|
||||||
[Monitoring]: https://blitiri.com.ar/p/chasquid/monitoring/
|
|
||||||
[SMTPUTF8]: https://en.wikipedia.org/wiki/Extended_SMTP#SMTPUTF8
|
|
||||||
[SPF]: https://en.wikipedia.org/wiki/Sender_Policy_Framework
|
|
||||||
[Tracking]: https://blitiri.com.ar/p/chasquid/sec-levels/
|
|
||||||
[Ubuntu]: https://blitiri.com.ar/p/chasquid/install/#debianubuntu
|
|
||||||
|
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
The [how-to guide](https://blitiri.com.ar/p/chasquid/howto/) and the
|
The [how-to guide](https://blitiri.com.ar/p/chasquid/howto/) and the
|
||||||
[installation guide](https://blitiri.com.ar/p/chasquid/install/) are the
|
[installation guide](https://blitiri.com.ar/p/chasquid/install/) are the best
|
||||||
best starting points on how to install, configure and run chasquid.
|
starting points on how to install, configure and run chasquid.
|
||||||
|
|
||||||
You will find [all documentation here](https://blitiri.com.ar/p/chasquid/).
|
You will find [all documentation here](https://blitiri.com.ar/p/chasquid/).
|
||||||
|
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
|
|
||||||
If you have any questions, comments or patches, please send them to the [mailing
|
If you have any questions, comments or patches, please send them to the
|
||||||
list](https://groups.google.com/forum/#!forum/chasquid),
|
[mailing list](https://groups.google.com/forum/#!forum/chasquid),
|
||||||
chasquid@googlegroups.com.
|
chasquid@googlegroups.com.\
|
||||||
To subscribe, send an email to chasquid+subscribe@googlegroups.com.
|
To subscribe, send an email to chasquid+subscribe@googlegroups.com.
|
||||||
|
|
||||||
Security issues can be reported privately to albertito@blitiri.com.ar.
|
Security issues can be reported privately to albertito@blitiri.com.ar.
|
||||||
@@ -78,3 +58,17 @@ Bug reports and pull requests on
|
|||||||
|
|
||||||
You can also reach out via IRC, `#chasquid` on [OFTC](https://oftc.net/).
|
You can also reach out via IRC, `#chasquid` on [OFTC](https://oftc.net/).
|
||||||
|
|
||||||
|
[alpine]: https://blitiri.com.ar/p/chasquid/install/#alpine
|
||||||
|
[arch]: https://blitiri.com.ar/p/chasquid/install/#arch
|
||||||
|
[debian]: https://blitiri.com.ar/p/chasquid/install/#debianubuntu
|
||||||
|
[dkim]: https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail
|
||||||
|
[dovecot]: https://blitiri.com.ar/p/chasquid/dovecot/
|
||||||
|
[hooks]: https://blitiri.com.ar/p/chasquid/hooks/
|
||||||
|
[idna]: https://en.wikipedia.org/wiki/Internationalized_domain_name
|
||||||
|
[let's encrypt]: https://letsencrypt.org
|
||||||
|
[monitoring]: https://blitiri.com.ar/p/chasquid/monitoring/
|
||||||
|
[mta-sts]: https://tools.ietf.org/html/rfc8461
|
||||||
|
[smtputf8]: https://en.wikipedia.org/wiki/Extended_SMTP#SMTPUTF8
|
||||||
|
[spf]: https://en.wikipedia.org/wiki/Sender_Policy_Framework
|
||||||
|
[tracking]: https://blitiri.com.ar/p/chasquid/sec-levels/
|
||||||
|
[ubuntu]: https://blitiri.com.ar/p/chasquid/install/#debianubuntu
|
||||||
|
|||||||
+12
-16
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# Docker
|
# Docker
|
||||||
|
|
||||||
chasquid comes with a Dockerfile to create a container running [chasquid],
|
chasquid comes with a Dockerfile to create a container running [chasquid],
|
||||||
@@ -7,18 +6,13 @@ chasquid comes with a Dockerfile to create a container running [chasquid],
|
|||||||
Note these are less thoroughly tested than the [traditional setup](howto.md),
|
Note these are less thoroughly tested than the [traditional setup](howto.md),
|
||||||
which is the recommended way to use chasquid.
|
which is the recommended way to use chasquid.
|
||||||
|
|
||||||
[chasquid]: https://blitiri.com.ar/p/chasquid
|
|
||||||
[dovecot]: https://dovecot.org
|
|
||||||
[Let's Encrypt]: https://letsencrypt.org
|
|
||||||
|
|
||||||
|
|
||||||
## Images
|
## Images
|
||||||
|
|
||||||
There are pre-built images at the
|
There are pre-built images at the
|
||||||
[gitlab registry](https://gitlab.com/albertito/chasquid/container_registry)
|
[gitlab registry](https://gitlab.com/albertito/chasquid/container_registry) and
|
||||||
and [dockerhub](https://hub.docker.com/r/albertito/chasquid).
|
[dockerhub](https://hub.docker.com/r/albertito/chasquid). They are
|
||||||
They are automatically built, and tagged with the corresponding branch name.
|
automatically built, and tagged with the corresponding branch name. Use the
|
||||||
Use the *main* tag for a stable version.
|
*main* tag for a stable version.
|
||||||
|
|
||||||
If, instead, you want to build the image yourself, just run:
|
If, instead, you want to build the image yourself, just run:
|
||||||
|
|
||||||
@@ -59,12 +53,12 @@ Password:
|
|||||||
pepe@example.com added to /data/dovecot/users
|
pepe@example.com added to /data/dovecot/users
|
||||||
```
|
```
|
||||||
|
|
||||||
Upon startup, the image will obtain a TLS certificate for you using [Let's
|
Upon startup, the image will obtain a TLS certificate for you using
|
||||||
Encrypt](https://letsencrypt.com/). You need to tell it the domain(s) to get a
|
[Let's Encrypt](https://letsencrypt.com/). You need to tell it the domain(s) to
|
||||||
certificate from by setting the `AUTO_CERTS` variable.
|
get a certificate from by setting the `AUTO_CERTS` variable.
|
||||||
|
|
||||||
Because certificates expire, you should restart the container every week or
|
Because certificates expire, you should restart the container every week or so.
|
||||||
so. Certificates will be renewed automatically upon startup if needed.
|
Certificates will be renewed automatically upon startup if needed.
|
||||||
|
|
||||||
In order for chasquid to get access to the source IP address, you will need to
|
In order for chasquid to get access to the source IP address, you will need to
|
||||||
use host networking, or create a custom docker network that does IP forwarding
|
use host networking, or create a custom docker network that does IP forwarding
|
||||||
@@ -79,10 +73,12 @@ $ docker run -e AUTO_CERTS=mail.yourdomain.com \
|
|||||||
registry.gitlab.com/albertito/chasquid:main
|
registry.gitlab.com/albertito/chasquid:main
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Debugging
|
## Debugging
|
||||||
|
|
||||||
To get a shell on the running container for debugging, you can use `docker ps`
|
To get a shell on the running container for debugging, you can use `docker ps`
|
||||||
to find the container ID, and then `docker exec -it CONTAINERID /bin/bash` to
|
to find the container ID, and then `docker exec -it CONTAINERID /bin/bash` to
|
||||||
open a shell on the running container.
|
open a shell on the running container.
|
||||||
|
|
||||||
|
[chasquid]: https://blitiri.com.ar/p/chasquid
|
||||||
|
[dovecot]: https://dovecot.org
|
||||||
|
[let's encrypt]: https://letsencrypt.org
|
||||||
|
|||||||
+16
-23
@@ -1,9 +1,7 @@
|
|||||||
|
|
||||||
# Aliases
|
# Aliases
|
||||||
|
|
||||||
[chasquid] supports [email aliases], which is a mechanism to redirect mail
|
[chasquid] supports [email aliases], which is a mechanism to redirect mail from
|
||||||
from one account to others.
|
one account to others.
|
||||||
|
|
||||||
|
|
||||||
## File format
|
## File format
|
||||||
|
|
||||||
@@ -42,8 +40,8 @@ email will be forwarded using
|
|||||||
While the content of the message will not be changed, the envelope sender will
|
While the content of the message will not be changed, the envelope sender will
|
||||||
be the constructed from the alias user.
|
be the constructed from the alias user.
|
||||||
|
|
||||||
User names cannot contain spaces, ":" or commas, for parsing reasons. This is
|
User names cannot contain spaces, ":" or commas, for parsing reasons. This is a
|
||||||
a tradeoff between flexibility and keeping the file format easy to edit for
|
tradeoff between flexibility and keeping the file format easy to edit for
|
||||||
people. User names will be normalized internally to lower-case. UTF-8 is
|
people. User names will be normalized internally to lower-case. UTF-8 is
|
||||||
allowed and fully supported.
|
allowed and fully supported.
|
||||||
|
|
||||||
@@ -52,8 +50,8 @@ allowed and fully supported.
|
|||||||
A pipe alias is of the form `user: | command`, and causes mail to be sent as
|
A pipe alias is of the form `user: | command`, and causes mail to be sent as
|
||||||
standard input to the given command.
|
standard input to the given command.
|
||||||
|
|
||||||
The command can have space-separated arguments (no quotes or escaping
|
The command can have space-separated arguments (no quotes or escaping expansion
|
||||||
expansion will be performed).
|
will be performed).
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
@@ -76,13 +74,12 @@ pepe: jose
|
|||||||
*: pepe, rose@backgarden
|
*: pepe, rose@backgarden
|
||||||
```
|
```
|
||||||
|
|
||||||
If the destination address has `*` as its user, then it will be replaced
|
If the destination address has `*` as its user, then it will be replaced by the
|
||||||
by the sender user. Note that in this case, the user is copied as-is, no
|
sender user. Note that in this case, the user is copied as-is, no characters or
|
||||||
characters or suffixes will be dropped.
|
suffixes will be dropped.
|
||||||
|
|
||||||
For example, `*: *@pond` will redirect `lilly@domain` to `lilly@pond`.
|
For example, `*: *@pond` will redirect `lilly@domain` to `lilly@pond`.
|
||||||
|
|
||||||
|
|
||||||
### "Via" aliases {#via}
|
### "Via" aliases {#via}
|
||||||
|
|
||||||
A "via" alias is like an email alias, but it explicitly specifies which
|
A "via" alias is like an email alias, but it explicitly specifies which
|
||||||
@@ -111,7 +108,6 @@ flowers: lilly@pond via mail1.pond/mail2.pond
|
|||||||
*: * via mail1.example.com
|
*: * via mail1.example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Overrides
|
### Overrides
|
||||||
|
|
||||||
If the same left-side address appears more than once, the last one will take
|
If the same left-side address appears more than once, the last one will take
|
||||||
@@ -156,31 +152,29 @@ juana.perez+fruta -> fruta
|
|||||||
juanaperez+fruta -> fruta
|
juanaperez+fruta -> fruta
|
||||||
```
|
```
|
||||||
|
|
||||||
This allows addresses with suffixes to have specific aliases, without having
|
This allows addresses with suffixes to have specific aliases, without having to
|
||||||
to worry about drop characters, which is the most common use case.
|
worry about drop characters, which is the most common use case.
|
||||||
|
|
||||||
If different semantics are needed, they can be implemented using the
|
If different semantics are needed, they can be implemented using the
|
||||||
[hook](#hooks).
|
[hook](#hooks).
|
||||||
|
|
||||||
|
|
||||||
## Processing
|
## Processing
|
||||||
|
|
||||||
Aliases files are read upon start-up and refreshed every 30 seconds, so
|
Aliases files are read upon start-up and refreshed every 30 seconds, so changes
|
||||||
changes to them don't require a daemon restart.
|
to them don't require a daemon restart.
|
||||||
|
|
||||||
The resolver will perform lookups recursively, until it finds all the final
|
The resolver will perform lookups recursively, until it finds all the final
|
||||||
recipients. There are recursion limits to avoid alias loops. If the limit (10
|
recipients. There are recursion limits to avoid alias loops. If the limit (10
|
||||||
levels) is reached, the entire resolution will fail.
|
levels) is reached, the entire resolution will fail.
|
||||||
|
|
||||||
Commands are given 30s to run, after which it will be killed and the execution
|
Commands are given 30s to run, after which it will be killed and the execution
|
||||||
will fail. If the command exits with an error (non-0 exit code), the delivery
|
will fail. If the command exits with an error (non-0 exit code), the delivery
|
||||||
will be considered failed.
|
will be considered failed.
|
||||||
|
|
||||||
The `chasquid-util` command-line tool can be used to check and resolve
|
The `chasquid-util` command-line tool can be used to check and resolve aliases
|
||||||
aliases manually. It talks to the running server, so the response is fully
|
manually. It talks to the running server, so the response is fully
|
||||||
authoritative.
|
authoritative.
|
||||||
|
|
||||||
|
|
||||||
## Hooks
|
## Hooks
|
||||||
|
|
||||||
There is a hook that allows more sophisticated aliases resolution:
|
There is a hook that allows more sophisticated aliases resolution:
|
||||||
@@ -191,6 +185,5 @@ are merged with the file-based resolution results.
|
|||||||
|
|
||||||
See the [hooks](hooks.md) documentation for more details.
|
See the [hooks](hooks.md) documentation for more details.
|
||||||
|
|
||||||
|
|
||||||
[chasquid]: https://blitiri.com.ar/p/chasquid
|
[chasquid]: https://blitiri.com.ar/p/chasquid
|
||||||
[email aliases]: https://en.wikipedia.org/wiki/Email_alias
|
[email aliases]: https://en.wikipedia.org/wiki/Email_alias
|
||||||
|
|||||||
+4
-10
@@ -1,18 +1,15 @@
|
|||||||
|
|
||||||
# Clients
|
# Clients
|
||||||
|
|
||||||
chasquid supports most SMTP clients, but requires them to have some features:
|
chasquid supports most SMTP clients, but requires them to have some features:
|
||||||
|
|
||||||
- Support TLS (either
|
- Support TLS (either [STARTTLS](https://datatracker.ietf.org/doc/html/rfc3207)
|
||||||
[STARTTLS](https://datatracker.ietf.org/doc/html/rfc3207) or
|
or [implicit TLS](https://datatracker.ietf.org/doc/html/rfc8314#section-3.3))
|
||||||
[implicit TLS](https://datatracker.ietf.org/doc/html/rfc8314#section-3.3))
|
|
||||||
- Support the
|
- Support the
|
||||||
[PLAIN authentication method](https://datatracker.ietf.org/doc/html/rfc4954#section-4).
|
[PLAIN authentication method](https://datatracker.ietf.org/doc/html/rfc4954#section-4).
|
||||||
|
|
||||||
All modern clients should support both, and thus have no problems talking to
|
All modern clients should support both, and thus have no problems talking to
|
||||||
chasquid.
|
chasquid.
|
||||||
|
|
||||||
|
|
||||||
## Configuration examples
|
## Configuration examples
|
||||||
|
|
||||||
### [msmtp](https://marlam.de/msmtp/)
|
### [msmtp](https://marlam.de/msmtp/)
|
||||||
@@ -42,13 +39,10 @@ password SECRET
|
|||||||
Replace the `SERVER`, `USER@DOMAIN` and `SECRET` strings with the appropriate
|
Replace the `SERVER`, `USER@DOMAIN` and `SECRET` strings with the appropriate
|
||||||
values.
|
values.
|
||||||
|
|
||||||
|
|
||||||
## Problematic clients
|
## Problematic clients
|
||||||
|
|
||||||
These clients are known to have issues talking to chasquid:
|
These clients are known to have issues talking to chasquid:
|
||||||
|
|
||||||
- [ssmtp](https://packages.debian.org/source/unstable/ssmtp): does not
|
- [ssmtp](https://packages.debian.org/source/unstable/ssmtp): does not support
|
||||||
support the PLAIN authentication method. It is also unmaintained.
|
the PLAIN authentication method. It is also unmaintained.\
|
||||||
Please use [msmtp](https://marlam.de/msmtp/) instead.
|
Please use [msmtp](https://marlam.de/msmtp/) instead.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+14
-20
@@ -1,19 +1,17 @@
|
|||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
## Questions and bug reports
|
## Questions and bug reports
|
||||||
|
|
||||||
Please send questions and bug reports via [Github Issues], or to the [mailing
|
Please send questions and bug reports via [Github Issues], or to the
|
||||||
list], chasquid@googlegroups.com.
|
[mailing list], chasquid@googlegroups.com.\
|
||||||
To subscribe to the [mailing list], send an email to
|
To subscribe to the [mailing list], send an email to
|
||||||
`chasquid+subscribe@googlegroups.com`.
|
`chasquid+subscribe@googlegroups.com`.
|
||||||
|
|
||||||
To privately report a suspected security issue, please see [Reporting a
|
To privately report a suspected security issue, please see
|
||||||
security issue](security.md).
|
[Reporting a security issue](security.md).
|
||||||
|
|
||||||
<a name="irc"></a>
|
|
||||||
You can also reach out via IRC, `#chasquid` on [OFTC](https://oftc.net/).
|
|
||||||
|
|
||||||
|
<a name="irc"></a> You can also reach out via IRC, `#chasquid` on
|
||||||
|
[OFTC](https://oftc.net/).
|
||||||
|
|
||||||
## Patches and pull requests
|
## Patches and pull requests
|
||||||
|
|
||||||
@@ -24,12 +22,11 @@ Before sending any non-trivial change, it's ideal to discuss the proposal (via
|
|||||||
[Github Issues], [mailing list], or [IRC](#irc)). This helps make the most out
|
[Github Issues], [mailing list], or [IRC](#irc)). This helps make the most out
|
||||||
of the contribution, and minimize friction frustration during code reviews.
|
of the contribution, and minimize friction frustration during code reviews.
|
||||||
|
|
||||||
|
|
||||||
### Commit message, coding style, tests
|
### Commit message, coding style, tests
|
||||||
|
|
||||||
Ideally, patches would have descriptive commit messages, adhere to Go's coding
|
Ideally, patches would have descriptive commit messages, adhere to Go's coding
|
||||||
style, and include comprehensive tests. However, that is a lot to ask, and
|
style, and include comprehensive tests. However, that is a lot to ask, and very
|
||||||
very subjective.
|
subjective.
|
||||||
|
|
||||||
It is okay to propose patches without those things. In those cases, the
|
It is okay to propose patches without those things. In those cases, the
|
||||||
maintainer will usually amend the patches to add them.
|
maintainer will usually amend the patches to add them.
|
||||||
@@ -39,22 +36,19 @@ For how to write commit messages,
|
|||||||
[this](https://git-scm.com/docs/SubmittingPatches#describe-changes) articles
|
[this](https://git-scm.com/docs/SubmittingPatches#describe-changes) articles
|
||||||
contain great advise.
|
contain great advise.
|
||||||
|
|
||||||
|
|
||||||
### Workflow
|
### Workflow
|
||||||
|
|
||||||
Patches will be cherry-picked, and are typically first incorporated into the
|
Patches will be cherry-picked, and are typically first incorporated into the
|
||||||
`next` branch.
|
`next` branch.
|
||||||
|
|
||||||
The `next` branch is where patches are staged, tested and reviewed. This
|
The `next` branch is where patches are staged, tested and reviewed. This branch
|
||||||
branch is rebased frequently, to make adjustments and fixes as needed.
|
is rebased frequently, to make adjustments and fixes as needed. Once patches
|
||||||
Once patches have received enough testing (usually after a couple of weeks),
|
have received enough testing (usually after a couple of weeks), they are moved
|
||||||
they are moved to the `main` branch.
|
to the `main` branch.
|
||||||
|
|
||||||
The `main` branch is the stable branch and where releases are cut from. It is
|
The `main` branch is the stable branch and where releases are cut from. It is
|
||||||
never rebased.
|
never rebased.
|
||||||
|
|
||||||
|
[github issues]: https://github.com/albertito/chasquid/issues
|
||||||
[Github Issues]: https://github.com/albertito/chasquid/issues
|
[github pull requests]: https://github.com/albertito/chasquid/pulls
|
||||||
[mailing list]: https://groups.google.com/forum/#!forum/chasquid
|
[mailing list]: https://groups.google.com/forum/#!forum/chasquid
|
||||||
[GitHub's Security tab]: https://github.com/albertito/chasquid/security
|
|
||||||
[Github Pull requests]: https://github.com/albertito/chasquid/pulls
|
|
||||||
|
|||||||
+21
-29
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# DKIM integration
|
# DKIM integration
|
||||||
|
|
||||||
[chasquid] supports verifying and generating [DKIM] signatures since version
|
[chasquid] supports verifying and generating [DKIM] signatures since version
|
||||||
@@ -9,25 +8,22 @@ have a private DKIM key set up will be signed.
|
|||||||
|
|
||||||
In versions older than 1.13, support is possible via the [hooks] mechanism. In
|
In versions older than 1.13, support is possible via the [hooks] mechanism. In
|
||||||
particular, the [example hook] included support for some command-line
|
particular, the [example hook] included support for some command-line
|
||||||
implementations. That continues to be an option, especially if customization
|
implementations. That continues to be an option, especially if customization is
|
||||||
is needed.
|
needed.
|
||||||
|
|
||||||
|
|
||||||
## Easy setup
|
## Easy setup
|
||||||
|
|
||||||
- Run `chasquid-util dkim-keygen DOMAIN` to generate a DKIM private key for
|
- Run `chasquid-util dkim-keygen DOMAIN` to generate a DKIM private key for
|
||||||
your domain. The file will be in `/etc/chasquid/domains/DOMAIN/dkim:*.pem`.
|
your domain. The file will be in `/etc/chasquid/domains/DOMAIN/dkim:*.pem`.
|
||||||
- Publish the DKIM DNS record which was shown by the
|
- Publish the DKIM DNS record which was shown by the previous command (e.g. by
|
||||||
previous command (e.g. by following
|
following [this guide](https://support.dnsimple.com/articles/dkim-record/)).
|
||||||
[this guide](https://support.dnsimple.com/articles/dkim-record/)).
|
|
||||||
- Change the key file's permissions, to ensure it is readable by chasquid (and
|
- Change the key file's permissions, to ensure it is readable by chasquid (and
|
||||||
nobody else).
|
nobody else).
|
||||||
- Restart chasquid.
|
- Restart chasquid.
|
||||||
|
|
||||||
It is highly recommended that you use a DKIM checker (like
|
It is highly recommended that you use a DKIM checker (like
|
||||||
[Learn DMARC](https://www.learndmarc.com/)) to confirm that your setup is
|
[Learn DMARC](https://www.learndmarc.com/)) to confirm that your setup is fully
|
||||||
fully functional.
|
functional.
|
||||||
|
|
||||||
|
|
||||||
## Advanced setup
|
## Advanced setup
|
||||||
|
|
||||||
@@ -38,16 +34,15 @@ It needs to be either RSA or Ed25519.
|
|||||||
|
|
||||||
### Key rotation
|
### Key rotation
|
||||||
|
|
||||||
To rotate a key, you can remove the old key file, and generate a new one as
|
To rotate a key, you can remove the old key file, and generate a new one as per
|
||||||
per the previous step.
|
the previous step.
|
||||||
|
|
||||||
It is important to remove the old key from the directory, because chasquid
|
It is important to remove the old key from the directory, because chasquid will
|
||||||
will use *all* the keys in it.
|
use *all* the keys in it.
|
||||||
|
|
||||||
You should use a different selector each time. If you don't specify a
|
|
||||||
selector when using `chasquid-util dkim-keygen`, the current date will be
|
|
||||||
used, which is a safe default to prevent accidental reuse.
|
|
||||||
|
|
||||||
|
You should use a different selector each time. If you don't specify a selector
|
||||||
|
when using `chasquid-util dkim-keygen`, the current date will be used, which is
|
||||||
|
a safe default to prevent accidental reuse.
|
||||||
|
|
||||||
### Multiple keys
|
### Multiple keys
|
||||||
|
|
||||||
@@ -57,18 +52,16 @@ support multiple signing algorithms).
|
|||||||
This is well supported: chasquid will sign email with all keys it find that
|
This is well supported: chasquid will sign email with all keys it find that
|
||||||
match `dkim:*.pem` in a domain directory.
|
match `dkim:*.pem` in a domain directory.
|
||||||
|
|
||||||
|
|
||||||
## Verification
|
## Verification
|
||||||
|
|
||||||
[chasquid] will verify all DKIM signatures of incoming mail, and record the
|
[chasquid] will verify all DKIM signatures of incoming mail, and record the
|
||||||
results in an [`Authentication-Results:`] header, as per [RFC 8601].
|
results in an [`Authentication-Results:`] header, as per [RFC 8601].
|
||||||
|
|
||||||
Note that emails will *not* be rejected even if they fail verification, as
|
Note that emails will *not* be rejected even if they fail verification, as this
|
||||||
this is not recommended
|
is not recommended
|
||||||
([source 1](https://tools.ietf.org/html/rfc6376#section-6.3),
|
([source 1](https://tools.ietf.org/html/rfc6376#section-6.3),
|
||||||
[source 2](https://tools.ietf.org/html/rfc7601#section-2.7.1)).
|
[source 2](https://tools.ietf.org/html/rfc7601#section-2.7.1)).
|
||||||
|
|
||||||
|
|
||||||
## Other implementations
|
## Other implementations
|
||||||
|
|
||||||
[chasquid] also supports [DKIM] via the [hooks] mechanism. This can be useful
|
[chasquid] also supports [DKIM] via the [hooks] mechanism. This can be useful
|
||||||
@@ -79,12 +72,11 @@ Implementations that have been tried:
|
|||||||
- [driusan/dkim]
|
- [driusan/dkim]
|
||||||
- [dkimpy]
|
- [dkimpy]
|
||||||
|
|
||||||
|
|
||||||
[chasquid]: https://blitiri.com.ar/p/chasquid
|
[chasquid]: https://blitiri.com.ar/p/chasquid
|
||||||
[DKIM]: https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail
|
[dkim]: https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail
|
||||||
[hooks]: hooks.md
|
|
||||||
[example hook]: https://blitiri.com.ar/git/r/chasquid/b/next/t/etc/chasquid/hooks/f=post-data.html
|
|
||||||
[driusan/dkim]: https://github.com/driusan/dkim
|
|
||||||
[dkimpy]: https://launchpad.net/dkimpy/
|
[dkimpy]: https://launchpad.net/dkimpy/
|
||||||
[RFC 8601]: https://datatracker.ietf.org/doc/html/rfc8601
|
[driusan/dkim]: https://github.com/driusan/dkim
|
||||||
[`Authentication-Results:`]: https://en.wikipedia.org/wiki/Email_authentication#Authentication-Results
|
[example hook]: https://blitiri.com.ar/git/r/chasquid/b/next/t/etc/chasquid/hooks/f=post-data.html
|
||||||
|
[hooks]: hooks.md
|
||||||
|
[rfc 8601]: https://datatracker.ietf.org/doc/html/rfc8601
|
||||||
|
[`authentication-results:`]: https://en.wikipedia.org/wiki/Email_authentication#Authentication-Results
|
||||||
|
|||||||
+3
-8
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# Dovecot integration
|
# Dovecot integration
|
||||||
|
|
||||||
As of version 0.04 (2018-02), [chasquid] has integration with [dovecot] for
|
As of version 0.04 (2018-02), [chasquid] has integration with [dovecot] for
|
||||||
@@ -7,7 +6,6 @@ authenticating users.
|
|||||||
This means that chasquid can ask dovecot to authenticate users, instead/in
|
This means that chasquid can ask dovecot to authenticate users, instead/in
|
||||||
addition to having its own per-domain user databases.
|
addition to having its own per-domain user databases.
|
||||||
|
|
||||||
|
|
||||||
## Configuring dovecot
|
## Configuring dovecot
|
||||||
|
|
||||||
The following needs to be added to the Dovecot configuration, usually in
|
The following needs to be added to the Dovecot configuration, usually in
|
||||||
@@ -35,7 +33,6 @@ Authentication requests sent by chasquid to dovecot will pass on the username
|
|||||||
as specified by the client. This will usually be either `user@domain`, or just
|
as specified by the client. This will usually be either `user@domain`, or just
|
||||||
`user`.
|
`user`.
|
||||||
|
|
||||||
|
|
||||||
## Configuring chasquid
|
## Configuring chasquid
|
||||||
|
|
||||||
Add the following line to `/etc/chasquid/chasquid.conf`:
|
Add the following line to `/etc/chasquid/chasquid.conf`:
|
||||||
@@ -51,14 +48,13 @@ CentOS, and NixOS).
|
|||||||
If chasquid can't find them, the paths can be set with the
|
If chasquid can't find them, the paths can be set with the
|
||||||
`dovecot_userdb_path` and `dovecot_client_path` options.
|
`dovecot_userdb_path` and `dovecot_client_path` options.
|
||||||
|
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
Dovecot authentication can be tricky to troubleshoot.
|
Dovecot authentication can be tricky to troubleshoot.
|
||||||
|
|
||||||
If you think it is not working as it should, or chasquid isn't correctly
|
If you think it is not working as it should, or chasquid isn't correctly
|
||||||
talking with it, the easiest way to check is to [increase dovecot auth logging
|
talking with it, the easiest way to check is to
|
||||||
verbosity](https://doc.dovecot.org/admin_manual/logging/?highlight=logging#logging-verbosity):
|
[increase dovecot auth logging verbosity](https://doc.dovecot.org/admin_manual/logging/?highlight=logging#logging-verbosity):
|
||||||
|
|
||||||
```
|
```
|
||||||
auth_verbose = yes
|
auth_verbose = yes
|
||||||
@@ -69,6 +65,5 @@ One common gotcha is when dovecot is set up to use `user` instead of
|
|||||||
`user@domain`. In that case you can try setting `auth_username_format = %n` to
|
`user@domain`. In that case you can try setting `auth_username_format = %n` to
|
||||||
make it ignore the domain if present.
|
make it ignore the domain if present.
|
||||||
|
|
||||||
|
|
||||||
[dovecot]: https://dovecot.org
|
|
||||||
[chasquid]: https://blitiri.com.ar/p/chasquid
|
[chasquid]: https://blitiri.com.ar/p/chasquid
|
||||||
|
[dovecot]: https://dovecot.org
|
||||||
|
|||||||
+22
-27
@@ -1,34 +1,31 @@
|
|||||||
|
|
||||||
# Message flows
|
# Message flows
|
||||||
|
|
||||||
This document explains at a high level some parts of chasquid's message
|
This document explains at a high level some parts of chasquid's message
|
||||||
processing, in particular how messages flow through the system.
|
processing, in particular how messages flow through the system.
|
||||||
|
|
||||||
|
|
||||||
## Message reception
|
## Message reception
|
||||||
|
|
||||||
- Client connects to chasquid on the smtp or submission ports, and issues
|
- Client connects to chasquid on the smtp or submission ports, and issues
|
||||||
HELO/EHLO.
|
HELO/EHLO.
|
||||||
- Client optionally performs STARTTLS.
|
- Client optionally performs STARTTLS.
|
||||||
- Client optionally performs AUTH.
|
- Client optionally performs AUTH, which must be done over TLS.
|
||||||
- Check that this is done over TLS.
|
- Client sends MAIL FROM, and we check SPF and the connection security level.
|
||||||
- Client sends MAIL FROM.
|
- Client sends one or more RCPT TO. If the destination is remote, then the user
|
||||||
- Check SPF.
|
must have authenticated. If the destination is local, check that the user
|
||||||
- Check connection security level.
|
exists.
|
||||||
- Client sends one or more RCPT TO.
|
|
||||||
- If the destination is remote, then the user must have authenticated.
|
|
||||||
- If the destination is local, check that the user exists.
|
|
||||||
- Client sends DATA.
|
- Client sends DATA.
|
||||||
- Client sends actual data, and ends it with '.'
|
- Client sends actual data, and ends it with '.'
|
||||||
- Parse the data contents to perform loop detection.
|
|
||||||
- If the sender is authenticated, DKIM-sign the email with the
|
|
||||||
corresponding key.
|
|
||||||
- If the sender is not authenticated, verify the DKIM signature (if the
|
|
||||||
email has one).
|
|
||||||
- Add the required headers (Received, SPF results, post-data hook output).
|
|
||||||
- Run the post-data hook. If the hook fails, return an error.
|
|
||||||
- Put it in the queue and reply success.
|
|
||||||
|
|
||||||
|
Then, to process the data:
|
||||||
|
|
||||||
|
- Parse the data contents to perform loop detection.
|
||||||
|
- If the sender is authenticated, DKIM-sign the email with the corresponding
|
||||||
|
key.
|
||||||
|
- If the sender is not authenticated, verify the DKIM signature (if the email
|
||||||
|
has one).
|
||||||
|
- Add the required headers (Received, SPF results, post-data hook output).
|
||||||
|
- Run the post-data hook. If the hook fails, return an error.
|
||||||
|
- Put it in the queue and reply success.
|
||||||
|
|
||||||
### Authenticated mail, and email spoofing
|
### Authenticated mail, and email spoofing
|
||||||
|
|
||||||
@@ -41,9 +38,9 @@ Users who want to be strict about "MAIL FROM" or even "From:" validation can
|
|||||||
add additional checks in the [post-DATA hook](hooks.md).
|
add additional checks in the [post-DATA hook](hooks.md).
|
||||||
|
|
||||||
In the future, chasquid may get some option to be strict about it by default,
|
In the future, chasquid may get some option to be strict about it by default,
|
||||||
or on a per-domain or per-user basis. But for now, using a [post-DATA
|
or on a per-domain or per-user basis. But for now, using a
|
||||||
hook](hooks.md) is the best way to make chasquid more strict about this.
|
[post-DATA hook](hooks.md) is the best way to make chasquid more strict about
|
||||||
|
this.
|
||||||
|
|
||||||
## Queue processing
|
## Queue processing
|
||||||
|
|
||||||
@@ -57,11 +54,9 @@ Before accepting a message:
|
|||||||
Queue processing runs asynchronously, there's a goroutine for each message
|
Queue processing runs asynchronously, there's a goroutine for each message
|
||||||
which does, in a loop:
|
which does, in a loop:
|
||||||
|
|
||||||
- For each recipient which we have not delivered yet:
|
- For each recipient which we have not delivered yet, attempt delivery, and
|
||||||
- Attempt delivery.
|
write the results to disk.
|
||||||
- Write to disk the results.
|
|
||||||
- If there are mails still pending, wait for some time (incrementally).
|
- If there are mails still pending, wait for some time (incrementally).
|
||||||
- When all the recipients have completed delivery, or enough time has passed:
|
- When all the recipients have completed delivery, or enough time has passed:
|
||||||
- If all were successful, remove from the queue.
|
if all were successful, remove from the queue; if some failed, send a
|
||||||
- If some failed, send a delivery status notification back to the sender.
|
delivery status notification back to the sender.
|
||||||
|
|
||||||
|
|||||||
+1
-5
@@ -1,10 +1,8 @@
|
|||||||
|
|
||||||
# HAProxy integration
|
# HAProxy integration
|
||||||
|
|
||||||
As of version 1.6, [chasquid] supports being deployed behind a [HAProxy]
|
As of version 1.6, [chasquid] supports being deployed behind a [HAProxy]
|
||||||
instance.
|
instance.
|
||||||
|
|
||||||
|
|
||||||
## Configuring HAProxy
|
## Configuring HAProxy
|
||||||
|
|
||||||
In the backend server line, set the [send-proxy] parameter to turn on the use
|
In the backend server line, set the [send-proxy] parameter to turn on the use
|
||||||
@@ -14,7 +12,6 @@ You need to set this for each of the ports that are forwarded.
|
|||||||
|
|
||||||
Only PROXY protocol v1 is supported for now.
|
Only PROXY protocol v1 is supported for now.
|
||||||
|
|
||||||
|
|
||||||
## Configuring chasquid
|
## Configuring chasquid
|
||||||
|
|
||||||
Add the following line to `/etc/chasquid/chasquid.conf`:
|
Add the following line to `/etc/chasquid/chasquid.conf`:
|
||||||
@@ -25,7 +22,6 @@ haproxy_incoming: true
|
|||||||
|
|
||||||
That turns HAProxy support on for all incoming SMTP connections.
|
That turns HAProxy support on for all incoming SMTP connections.
|
||||||
|
|
||||||
|
|
||||||
[chasquid]: https://blitiri.com.ar/p/chasquid
|
[chasquid]: https://blitiri.com.ar/p/chasquid
|
||||||
[HAProxy]: https://www.haproxy.org/
|
[haproxy]: https://www.haproxy.org/
|
||||||
[send-proxy]: http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#5.2-send-proxy
|
[send-proxy]: http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#5.2-send-proxy
|
||||||
|
|||||||
+26
-32
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# Hooks
|
# Hooks
|
||||||
|
|
||||||
chasquid supports some functionality via hooks, which are binaries that get
|
chasquid supports some functionality via hooks, which are binaries that get
|
||||||
@@ -6,7 +5,6 @@ executed at specific points in time during delivery.
|
|||||||
|
|
||||||
They are optional, and will be skipped if they don't exist.
|
They are optional, and will be skipped if they don't exist.
|
||||||
|
|
||||||
|
|
||||||
## Post-DATA hook
|
## Post-DATA hook
|
||||||
|
|
||||||
After completion of DATA, but before accepting the mail for queueing, chasquid
|
After completion of DATA, but before accepting the mail for queueing, chasquid
|
||||||
@@ -15,19 +13,16 @@ will run the command at `$config_dir/hooks/post-data`.
|
|||||||
The contents of the mail will be written to the command's stdin, and the
|
The contents of the mail will be written to the command's stdin, and the
|
||||||
environment is detailed below.
|
environment is detailed below.
|
||||||
|
|
||||||
If the exit status is 0, chasquid will move forward processing the command,
|
If the exit status is 0, chasquid will move forward processing the command, and
|
||||||
and its stdout should contain headers which will be added to contents of
|
its stdout should contain headers which will be added to contents of the email
|
||||||
the email (at the top).
|
(at the top).
|
||||||
|
|
||||||
Otherwise, chasquid will respond with an error, and the last line of stdout
|
Otherwise, chasquid will respond with an error, and the last line of stdout
|
||||||
will be passed back to the client as the error message.
|
will be passed back to the client as the error message. If the exit status is
|
||||||
If the exit status is 20 the error code will be permanent, otherwise it will
|
20 the error code will be permanent, otherwise it will be temporary.
|
||||||
be temporary.
|
|
||||||
|
|
||||||
|
|
||||||
This hook can be used to block based on contents, for example to check for
|
|
||||||
spam or virus. See `etc/hooks/post-data` for an example.
|
|
||||||
|
|
||||||
|
This hook can be used to block based on contents, for example to check for spam
|
||||||
|
or virus. See `etc/hooks/post-data` for an example.
|
||||||
|
|
||||||
### Environment
|
### Environment
|
||||||
|
|
||||||
@@ -36,27 +31,26 @@ privileges.
|
|||||||
|
|
||||||
The environment will contain the following variables:
|
The environment will contain the following variables:
|
||||||
|
|
||||||
- `$USER`: The server's `$USER` env variable.
|
- `$USER`: The server's `$USER` env variable.
|
||||||
- `$SHELL`: The server's `$SHELL` env variable.
|
- `$SHELL`: The server's `$SHELL` env variable.
|
||||||
- `$PATH`: The server's `$PATH` env variable.
|
- `$PATH`: The server's `$PATH` env variable.
|
||||||
- `$PWD`: The working directory, which will be the config directory.
|
- `$PWD`: The working directory, which will be the config directory.
|
||||||
- `$REMOTE_ADDR`: IP address of the remote side of the connection.
|
- `$REMOTE_ADDR`: IP address of the remote side of the connection.
|
||||||
- `$EHLO_DOMAIN`: EHLO/HELO domain, as given by the client; sanitized for
|
- `$EHLO_DOMAIN`: EHLO/HELO domain, as given by the client; sanitized for
|
||||||
safety (only letters, digits, and `-.[]:` are kept). If there are no valid
|
safety (only letters, digits, and `-.[]:` are kept). If there are no valid
|
||||||
characters, it is `no-valid-characters.invalid`.
|
characters, it is `no-valid-characters.invalid`.
|
||||||
- `$EHLO_DOMAIN_RAW`: Same as `$EHLO_DOMAIN`. Kept for backwards
|
- `$EHLO_DOMAIN_RAW`: Same as `$EHLO_DOMAIN`. Kept for backwards compatibility;
|
||||||
compatibility; it used to be the unsanitized value.
|
it used to be the unsanitized value.
|
||||||
- `$MAIL_FROM`: MAIL FROM address.
|
- `$MAIL_FROM`: MAIL FROM address.
|
||||||
- `$RCPT_TO`: RCPT TO addresses, space separated.
|
- `$RCPT_TO`: RCPT TO addresses, space separated.
|
||||||
- `$AUTH_AS`: Authenticated user; empty if the connection has not
|
- `$AUTH_AS`: Authenticated user; empty if the connection has not authenticated
|
||||||
authenticated successfully.
|
successfully.
|
||||||
- `$ON_TLS`: 1 if using TLS, 0 if not.
|
- `$ON_TLS`: 1 if using TLS, 0 if not.
|
||||||
- `$FROM_LOCAL_DOMAIN`: 1 if the mail comes from a local domain, 0 if not.
|
- `$FROM_LOCAL_DOMAIN`: 1 if the mail comes from a local domain, 0 if not.
|
||||||
- `$SPF_PASS`: 1 if it passed SPF, 0 if not.
|
- `$SPF_PASS`: 1 if it passed SPF, 0 if not.
|
||||||
|
|
||||||
There is a 1 minute timeout for hook execution.
|
|
||||||
It will be run at the config directory.
|
|
||||||
|
|
||||||
|
There is a 1 minute timeout for hook execution. It will be run at the config
|
||||||
|
directory.
|
||||||
|
|
||||||
## Alias resolve hook
|
## Alias resolve hook
|
||||||
|
|
||||||
|
|||||||
+50
-65
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# chasquid how-to guide
|
# chasquid how-to guide
|
||||||
|
|
||||||
This is a practical guide for setting up an email server for personal or small
|
This is a practical guide for setting up an email server for personal or small
|
||||||
@@ -7,34 +6,22 @@ detailed references where possible.
|
|||||||
|
|
||||||
While a lot of the contents are generic, for simplicity it will use:
|
While a lot of the contents are generic, for simplicity it will use:
|
||||||
|
|
||||||
- [Debian] as base operating system ([Ubuntu] also works)
|
- [Debian] as base operating system ([Ubuntu] also works)
|
||||||
- [Dovecot] for [POP3]+[IMAP]
|
- [Dovecot] for [POP3]+[IMAP]
|
||||||
- [chasquid] for [SMTP]
|
- [chasquid] for [SMTP]
|
||||||
- [Let's Encrypt] for [TLS] certificates
|
- [Let's Encrypt] for [TLS] certificates
|
||||||
|
|
||||||
[Debian]: https://debian.org
|
|
||||||
[Ubuntu]: https://ubuntu.com
|
|
||||||
[Dovecot]: https://dovecot.org
|
|
||||||
[chasquid]: https://blitiri.com.ar/p/chasquid
|
|
||||||
[Let's Encrypt]: https://letsencrypt.org
|
|
||||||
[POP3]: https://en.wikipedia.org/wiki/Post_Office_Protocol
|
|
||||||
[IMAP]: https://en.wikipedia.org/wiki/Internet_Message_Access_Protocol
|
|
||||||
[SMTP]: https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol
|
|
||||||
[TLS]: https://en.wikipedia.org/wiki/Transport_Layer_Security
|
|
||||||
|
|
||||||
|
|
||||||
## Example data
|
## Example data
|
||||||
|
|
||||||
This guide will use the following data for illustration purposes, replace them
|
This guide will use the following data for illustration purposes, replace them
|
||||||
with your own where appropriate.
|
with your own where appropriate.
|
||||||
|
|
||||||
- Domain name: `example.com`.
|
- Domain name: `example.com`.
|
||||||
- IPv4 address of your mail server: `198.51.100.7`.
|
- IPv4 address of your mail server: `198.51.100.7`.
|
||||||
- IPv6 address of your mail server: `2001:db8::7`.
|
- IPv6 address of your mail server: `2001:db8::7`.
|
||||||
|
|
||||||
Note IPv6 is optional but highly encouraged, and supported by most providers.
|
Note IPv6 is optional but highly encouraged, and supported by most providers.
|
||||||
|
|
||||||
|
|
||||||
## Getting a server
|
## Getting a server
|
||||||
|
|
||||||
You first need to have a server to use. This could be an existing one (for
|
You first need to have a server to use. This could be an existing one (for
|
||||||
@@ -43,33 +30,26 @@ exclusive for email.
|
|||||||
|
|
||||||
In this guide we will use a separate server, mostly for clarity.
|
In this guide we will use a separate server, mostly for clarity.
|
||||||
|
|
||||||
For small groups the size of the server does not matter, any small VPS
|
For small groups the size of the server does not matter, any small VPS (virtual
|
||||||
(virtual private server) will do just fine.
|
private server) will do just fine.
|
||||||
|
|
||||||
Specifically for hosting email servers, there are some things to check when
|
Specifically for hosting email servers, there are some things to check when
|
||||||
selecting a provider:
|
selecting a provider:
|
||||||
|
|
||||||
- Make sure they allow traffic on TCP port 25 (SMTP). While almost all VPS
|
- Make sure they allow traffic on TCP port 25 (SMTP). While almost all VPS and
|
||||||
and dedicated server providers are fine, some "cloud" providers (like
|
dedicated server providers are fine, some "cloud" providers (like Google
|
||||||
Google Cloud) block port 25, which is used for sending and receiving mails.
|
Cloud) block port 25, which is used for sending and receiving mails.
|
||||||
- Once you get a server, make sure the IP addresses are not listed in any
|
- Once you get a server, make sure the IP addresses are not listed in any
|
||||||
[blackhole lists].
|
[blackhole lists]. There are many services to check them, for example
|
||||||
There are many services to check them, for example [the
|
[the Anti-Abuse project] or [multirbl.valli.org].
|
||||||
Anti-Abuse project] or [multirbl.valli.org].
|
|
||||||
|
|
||||||
Remember to update your server regularly, setting up [unattended upgrades] is
|
Remember to update your server regularly, setting up [unattended upgrades] is
|
||||||
highly recommended.
|
highly recommended.
|
||||||
|
|
||||||
[the Anti-Abuse project]: http://www.anti-abuse.org/multi-rbl-check/
|
|
||||||
[blackhole lists]: https://en.wikipedia.org/wiki/DNSBL
|
|
||||||
[unattended upgrades]: https://wiki.debian.org/UnattendedUpgrades
|
|
||||||
[multirbl.valli.org]: http://multirbl.valli.org/
|
|
||||||
|
|
||||||
|
|
||||||
## DNS
|
## DNS
|
||||||
|
|
||||||
Set up the following DNS records for `example.com`. This is usually done
|
Set up the following DNS records for `example.com`. This is usually done either
|
||||||
either in your DNS server, or in the user interface of your DNS provider.
|
in your DNS server, or in the user interface of your DNS provider.
|
||||||
|
|
||||||
```
|
```
|
||||||
; Assign "mail.example.com" to the server's IP addresses.
|
; Assign "mail.example.com" to the server's IP addresses.
|
||||||
@@ -86,20 +66,18 @@ mail AAAA 2001:db8::7
|
|||||||
```
|
```
|
||||||
|
|
||||||
Finally, you should go to your server provider and configure the "reverse DNS"
|
Finally, you should go to your server provider and configure the "reverse DNS"
|
||||||
(also known as "PTR") for the IP addresses to be to "mail.example.com". This
|
(also known as "PTR") for the IP addresses to be to "mail.example.com". This is
|
||||||
is important, as some spam checkers will consider it a factor.
|
important, as some spam checkers will consider it a factor.
|
||||||
|
|
||||||
*References:
|
*References: [A record](https://en.wikipedia.org/wiki/A_record),
|
||||||
[A record](https://en.wikipedia.org/wiki/A_record),
|
|
||||||
[MX record](https://en.wikipedia.org/wiki/MX_record),
|
[MX record](https://en.wikipedia.org/wiki/MX_record),
|
||||||
[Sender Policy Framework (SPF)](https://en.wikipedia.org/wiki/Sender_Policy_Framework).*
|
[Sender Policy Framework (SPF)](https://en.wikipedia.org/wiki/Sender_Policy_Framework).*
|
||||||
|
|
||||||
|
|
||||||
## TLS certificate
|
## TLS certificate
|
||||||
|
|
||||||
[TLS] certificates are needed to send and receive email securely.
|
[TLS] certificates are needed to send and receive email securely. [letsencrypt]
|
||||||
[letsencrypt] will provide us with a free certificate, which needs to be
|
will provide us with a free certificate, which needs to be renewed every 90
|
||||||
renewed every 90 days, so the following relies on automatic renewal.
|
days, so the following relies on automatic renewal.
|
||||||
|
|
||||||
Note `certbot` is the recommended letsencrypt command line client.
|
Note `certbot` is the recommended letsencrypt command line client.
|
||||||
|
|
||||||
@@ -124,10 +102,6 @@ EOF
|
|||||||
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/restart
|
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/restart
|
||||||
```
|
```
|
||||||
|
|
||||||
[TLS]: https://en.wikipedia.org/wiki/Transport_Layer_Security
|
|
||||||
[letsencrypt]: https://letsencrypt.org
|
|
||||||
|
|
||||||
|
|
||||||
## Configure dovecot
|
## Configure dovecot
|
||||||
|
|
||||||
First, install dovecot, and let chasquid use it for authorizing users. That
|
First, install dovecot, and let chasquid use it for authorizing users. That
|
||||||
@@ -151,12 +125,11 @@ service auth {
|
|||||||
EOF
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
You will need to configure dovecot authentication depending on your needs.
|
You will need to configure dovecot authentication depending on your needs. For
|
||||||
For example, if you want to use only system users, or virtual users.
|
example, if you want to use only system users, or virtual users. See the
|
||||||
See the `/etc/dovecot/conf.d/10-auth.conf` file, and the [dovecot
|
`/etc/dovecot/conf.d/10-auth.conf` file, and the
|
||||||
documentation](https://wiki.dovecot.org/HowTo/SimpleVirtualInstall) for more
|
[dovecot documentation](https://wiki.dovecot.org/HowTo/SimpleVirtualInstall)
|
||||||
details.
|
for more details.
|
||||||
|
|
||||||
|
|
||||||
## Configure chasquid
|
## Configure chasquid
|
||||||
|
|
||||||
@@ -191,13 +164,12 @@ EOF
|
|||||||
|
|
||||||
## Add users
|
## Add users
|
||||||
|
|
||||||
With this configuration, chasquid will use dovecot to manage users, so refer
|
With this configuration, chasquid will use dovecot to manage users, so refer to
|
||||||
to the [dovecot documentation](https://wiki.dovecot.org/BasicConfiguration)
|
the [dovecot documentation](https://wiki.dovecot.org/BasicConfiguration) for
|
||||||
for the details.
|
the details.
|
||||||
|
|
||||||
You can also add chasquid-specific users with `chasquid-util user-add`.
|
You can also add chasquid-specific users with `chasquid-util user-add`.
|
||||||
|
|
||||||
|
|
||||||
## Additional domains
|
## Additional domains
|
||||||
|
|
||||||
To make chasquid manage an additional domain `otherdomain.com`, first add the
|
To make chasquid manage an additional domain `otherdomain.com`, first add the
|
||||||
@@ -208,13 +180,13 @@ following records to `otherdomain.com`:
|
|||||||
@ TXT "v=spf1 mx -all"
|
@ TXT "v=spf1 mx -all"
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, tell chasquid about it by running `mkdir
|
Then, tell chasquid about it by running
|
||||||
/etc/chasquid/domains/otherdomain.com`. Don't forget to restart it afterwards.
|
`mkdir /etc/chasquid/domains/otherdomain.com`. Don't forget to restart it
|
||||||
|
afterwards.
|
||||||
|
|
||||||
Alternatively, you can use a different MX record, as long as you can get
|
Alternatively, you can use a different MX record, as long as you can get
|
||||||
chasquid a certificate for it.
|
chasquid a certificate for it.
|
||||||
|
|
||||||
|
|
||||||
## Optional software
|
## Optional software
|
||||||
|
|
||||||
- To use [SpamAssassin] to filter spam, run `apt install spamassassin spamc`.
|
- To use [SpamAssassin] to filter spam, run `apt install spamassassin spamc`.
|
||||||
@@ -223,6 +195,19 @@ chasquid a certificate for it.
|
|||||||
That's all it takes. chasquid default hooks will pass incoming mail through
|
That's all it takes. chasquid default hooks will pass incoming mail through
|
||||||
both if (and only if) they are installed.
|
both if (and only if) they are installed.
|
||||||
|
|
||||||
[SpamAssassin]: https://spamassassin.apache.org/
|
[blackhole lists]: https://en.wikipedia.org/wiki/DNSBL
|
||||||
[ClamAV]: https://www.clamav.net/
|
[chasquid]: https://blitiri.com.ar/p/chasquid
|
||||||
|
[clamav]: https://www.clamav.net/
|
||||||
|
[debian]: https://debian.org
|
||||||
|
[dovecot]: https://dovecot.org
|
||||||
|
[imap]: https://en.wikipedia.org/wiki/Internet_Message_Access_Protocol
|
||||||
|
[let's encrypt]: https://letsencrypt.org
|
||||||
|
[letsencrypt]: https://letsencrypt.org
|
||||||
|
[multirbl.valli.org]: http://multirbl.valli.org/
|
||||||
|
[pop3]: https://en.wikipedia.org/wiki/Post_Office_Protocol
|
||||||
|
[smtp]: https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol
|
||||||
|
[spamassassin]: https://spamassassin.apache.org/
|
||||||
|
[the anti-abuse project]: http://www.anti-abuse.org/multi-rbl-check/
|
||||||
|
[tls]: https://en.wikipedia.org/wiki/Transport_Layer_Security
|
||||||
|
[ubuntu]: https://ubuntu.com
|
||||||
|
[unattended upgrades]: https://wiki.debian.org/UnattendedUpgrades
|
||||||
|
|||||||
+3
-8
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# chasquid
|
# chasquid
|
||||||
|
|
||||||
[chasquid](https://blitiri.com.ar/p/chasquid) is an SMTP (email) server with a
|
[chasquid](https://blitiri.com.ar/p/chasquid) is an SMTP (email) server with a
|
||||||
@@ -9,16 +8,12 @@ This is the documentation index.
|
|||||||
Please see the [project page](https://blitiri.com.ar/p/chasquid) for more
|
Please see the [project page](https://blitiri.com.ar/p/chasquid) for more
|
||||||
details.
|
details.
|
||||||
|
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
|
|
||||||
If you have any questions, comments or patches please send them to the [mailing
|
If you have any questions, comments or patches please send them to the
|
||||||
list](https://groups.google.com/forum/#!forum/chasquid),
|
[mailing list](https://groups.google.com/forum/#!forum/chasquid),
|
||||||
chasquid@googlegroups.com.
|
chasquid@googlegroups.com.
|
||||||
|
|
||||||
To subscribe, send an email to chasquid+subscribe@googlegroups.com.
|
To subscribe, send an email to chasquid+subscribe@googlegroups.com.
|
||||||
|
|
||||||
You can also reach out via IRC, `#chasquid` on
|
You can also reach out via IRC, `#chasquid` on [OFTC](https://oftc.net/).
|
||||||
[OFTC](https://oftc.net/).
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+21
-33
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# Installing and configuring [chasquid](https://blitiri.com.ar/p/chasquid)
|
# Installing and configuring [chasquid](https://blitiri.com.ar/p/chasquid)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
@@ -17,9 +16,9 @@ sudo apt install chasquid
|
|||||||
|
|
||||||
If you're using Arch, there is a
|
If you're using Arch, there is a
|
||||||
[chasquid AUR package](https://aur.archlinux.org/packages/chasquid/) you can
|
[chasquid AUR package](https://aur.archlinux.org/packages/chasquid/) you can
|
||||||
use. See the [official Arch
|
use. See the
|
||||||
documentation](https://wiki.archlinux.org/index.php/Arch_User_Repository) for
|
[official Arch documentation](https://wiki.archlinux.org/index.php/Arch_User_Repository)
|
||||||
how to install it. If you use the [pacaur](https://github.com/E5ten/pacaur)
|
for how to install it. If you use the [pacaur](https://github.com/E5ten/pacaur)
|
||||||
[helper](https://wiki.archlinux.org/index.php/AUR_helpers), you can just run:
|
[helper](https://wiki.archlinux.org/index.php/AUR_helpers), you can just run:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
@@ -29,7 +28,6 @@ pacaur -S chasquid
|
|||||||
[Binary packages](https://maddy.email/archlinux/README.txt) are also available,
|
[Binary packages](https://maddy.email/archlinux/README.txt) are also available,
|
||||||
courtesy of [foxcpp](https://github.com/foxcpp/).
|
courtesy of [foxcpp](https://github.com/foxcpp/).
|
||||||
|
|
||||||
|
|
||||||
### Alpine
|
### Alpine
|
||||||
|
|
||||||
If you're using
|
If you're using
|
||||||
@@ -43,7 +41,6 @@ apk add chasquid
|
|||||||
Thanks to [raspbeguy](https://github.com/raspbeguy) for maintaining the Alpine
|
Thanks to [raspbeguy](https://github.com/raspbeguy) for maintaining the Alpine
|
||||||
package.
|
package.
|
||||||
|
|
||||||
|
|
||||||
### From source
|
### From source
|
||||||
|
|
||||||
To get, build and install from source, you will need a working
|
To get, build and install from source, you will need a working
|
||||||
@@ -63,7 +60,6 @@ sudo make install-binaries
|
|||||||
sudo make install-config-skeleton
|
sudo make install-config-skeleton
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The configuration is in `/etc/chasquid/` by default, and has the following
|
The configuration is in `/etc/chasquid/` by default, and has the following
|
||||||
@@ -88,28 +84,24 @@ structure:
|
|||||||
### Certificates
|
### Certificates
|
||||||
|
|
||||||
The certs/ directory layout matches the one from
|
The certs/ directory layout matches the one from
|
||||||
[certbot](https://certbot.eff.org/),
|
[certbot](https://certbot.eff.org/), [letsencrypt](https://letsencrypt.org)'s
|
||||||
[letsencrypt](https://letsencrypt.org)'s
|
default client, to make it easier to integrate. The layout from the
|
||||||
default client, to make it easier to integrate.
|
[NixOS ACME module](https://wiki.nixos.org/wiki/ACME) (`/var/lib/acme`) is also
|
||||||
The layout from the [NixOS ACME module](https://wiki.nixos.org/wiki/ACME)
|
supported.
|
||||||
(`/var/lib/acme`) is also supported.
|
|
||||||
|
|
||||||
A convenient way to set this up is:
|
A convenient way to set this up is:
|
||||||
|
|
||||||
1) Obtain TLS certificates using `certbot` as needed.
|
1. Obtain TLS certificates using `certbot` as needed.
|
||||||
2) Symlink chasquid's `certs/` to `/etc/letsencrypt/live`:\
|
2. Symlink chasquid's `certs/` to `/etc/letsencrypt/live`:\
|
||||||
`sudo ln -s /etc/letsencrypt/live/ /etc/chasquid/certs`
|
`sudo ln -s /etc/letsencrypt/live/ /etc/chasquid/certs`
|
||||||
3) Give chasquid permissions to read the certificates:\
|
3. Give chasquid permissions to read the certificates:\
|
||||||
`sudo setfacl -R -m u:chasquid:rX /etc/letsencrypt/{live,archive}`
|
`sudo setfacl -R -m u:chasquid:rX /etc/letsencrypt/{live,archive}`
|
||||||
4) Set up [automatic renewal] to restart chasquid when certificates are
|
4. Set up [automatic renewal] to restart chasquid when certificates are
|
||||||
renewed.
|
renewed.
|
||||||
|
|
||||||
Please see the [how-to guide](howto.md#tls-certificate) for more detailed
|
Please see the [how-to guide](howto.md#tls-certificate) for more detailed
|
||||||
examples.
|
examples.
|
||||||
|
|
||||||
[automatic renewal]: https://eff-certbot.readthedocs.io/en/stable/using.html#setting-up-automated-renewal
|
|
||||||
|
|
||||||
|
|
||||||
### Adding users
|
### Adding users
|
||||||
|
|
||||||
You can add users with:
|
You can add users with:
|
||||||
@@ -120,24 +112,21 @@ chasquid-util user-add user@domain
|
|||||||
|
|
||||||
This will also create the corresponding domain directory if it doesn't exist.
|
This will also create the corresponding domain directory if it doesn't exist.
|
||||||
|
|
||||||
|
|
||||||
### Checking your configuration
|
### Checking your configuration
|
||||||
|
|
||||||
Run `chasquid-util print-config` to parse your configuration and display the
|
Run `chasquid-util print-config` to parse your configuration and display the
|
||||||
resulting values.
|
resulting values.
|
||||||
|
|
||||||
|
|
||||||
### Checking your setup
|
### Checking your setup
|
||||||
|
|
||||||
Run `smtp-check yourdomain.com`, it will check:
|
Run `smtp-check yourdomain.com`, it will check:
|
||||||
|
|
||||||
* MX DNS records.
|
- MX DNS records.
|
||||||
* SPF DNS records (will just warn if not present).
|
- SPF DNS records (will just warn if not present).
|
||||||
* TLS certificates.
|
- TLS certificates.
|
||||||
|
|
||||||
It needs to access port 25, which is often blocked by ISPs, so it's likely
|
|
||||||
that you need to run it from your server.
|
|
||||||
|
|
||||||
|
It needs to access port 25, which is often blocked by ISPs, so it's likely that
|
||||||
|
you need to run it from your server.
|
||||||
|
|
||||||
### Greylisting, anti-spam and anti-virus
|
### Greylisting, anti-spam and anti-virus
|
||||||
|
|
||||||
@@ -146,12 +135,11 @@ greylisting, and run anti-spam and anti-virus filters.
|
|||||||
|
|
||||||
The hook should be at `/etc/chasquid/hooks/post-data`.
|
The hook should be at `/etc/chasquid/hooks/post-data`.
|
||||||
|
|
||||||
|
|
||||||
The one installed by default is a bash script supporting:
|
The one installed by default is a bash script supporting:
|
||||||
|
|
||||||
* greylisting using greylistd.
|
- greylisting using greylistd.
|
||||||
* anti-spam using spamassassin or rspamd.
|
- anti-spam using spamassassin or rspamd.
|
||||||
* anti-virus using clamav.
|
- anti-virus using clamav.
|
||||||
|
|
||||||
To use them, they just need to be available in your system.
|
To use them, they just need to be available in your system.
|
||||||
|
|
||||||
@@ -163,6 +151,6 @@ usermod -a -G greylist mail
|
|||||||
```
|
```
|
||||||
|
|
||||||
Note that the default hook may not work in all cases, it is provided as a
|
Note that the default hook may not work in all cases, it is provided as a
|
||||||
practical example but you should adjust it to your particular system if
|
practical example but you should adjust it to your particular system if needed.
|
||||||
needed.
|
|
||||||
|
|
||||||
|
[automatic renewal]: https://eff-certbot.readthedocs.io/en/stable/using.html#setting-up-automated-renewal
|
||||||
|
|||||||
+2
-5
@@ -1,14 +1,12 @@
|
|||||||
|
|
||||||
# Known issues
|
# Known issues
|
||||||
|
|
||||||
This file contains a list of the most common known issues, and the release
|
This file contains a list of the most common known issues, and the release
|
||||||
range affected. It can be useful for people running older versions, to
|
range affected. It can be useful for people running older versions, to identify
|
||||||
identify problems (and workarounds) faster.
|
problems (and workarounds) faster.
|
||||||
|
|
||||||
Entries are eventually be purged once their affected versions become uncommon,
|
Entries are eventually be purged once their affected versions become uncommon,
|
||||||
to prevent confusion.
|
to prevent confusion.
|
||||||
|
|
||||||
|
|
||||||
## Dovecot auth occasionally not functional after a reboot (0.04 to 1.6)
|
## Dovecot auth occasionally not functional after a reboot (0.04 to 1.6)
|
||||||
|
|
||||||
After a reboot, if chasquid starts *before* dovecot, it's possible that
|
After a reboot, if chasquid starts *before* dovecot, it's possible that
|
||||||
@@ -30,7 +28,6 @@ After=dovecot.service
|
|||||||
|
|
||||||
The issue is fixed in 1.7.
|
The issue is fixed in 1.7.
|
||||||
|
|
||||||
|
|
||||||
## `dkimsign` causes parsing errors in post-data hook (0.07 to 1.5)
|
## `dkimsign` causes parsing errors in post-data hook (0.07 to 1.5)
|
||||||
|
|
||||||
The default post-data hook in versions 0.07 to 1.5 has a bug where if the
|
The default post-data hook in versions 0.07 to 1.5 has a bug where if the
|
||||||
|
|||||||
+3
-5
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
From the latest Debian package:
|
From the latest Debian package:
|
||||||
|
|
||||||
- [chasquid(1)](https://manpages.debian.org/unstable/chasquid/chasquid.1):
|
- [chasquid(1)](https://manpages.debian.org/unstable/chasquid/chasquid.1): the
|
||||||
the main binary.
|
main binary.
|
||||||
- [chasquid.conf(5)](https://manpages.debian.org/unstable/chasquid/chasquid.conf.5):
|
- [chasquid.conf(5)](https://manpages.debian.org/unstable/chasquid/chasquid.conf.5):
|
||||||
the configuration file and structure.
|
the configuration file and structure.
|
||||||
- [chasquid-util(1)](https://manpages.debian.org/unstable/chasquid/chasquid-util.1):
|
- [chasquid-util(1)](https://manpages.debian.org/unstable/chasquid/chasquid-util.1):
|
||||||
@@ -17,9 +17,7 @@ From the current branch (more likely to change, but useful when doing
|
|||||||
development or running experimental versions):
|
development or running experimental versions):
|
||||||
|
|
||||||
- [chasquid(1)](chasquid.1.md): the main binary.
|
- [chasquid(1)](chasquid.1.md): the main binary.
|
||||||
- [chasquid.conf(5)](chasquid.conf.5.md): the configuration file and
|
- [chasquid.conf(5)](chasquid.conf.5.md): the configuration file and structure.
|
||||||
structure.
|
|
||||||
- [chasquid-util(1)](chasquid-util.1.md): the command-line utility helper.
|
- [chasquid-util(1)](chasquid-util.1.md): the command-line utility helper.
|
||||||
- [mda-lmtp(1)](mda-lmtp.1.md): helper to integrate with LMTP delivery.
|
- [mda-lmtp(1)](mda-lmtp.1.md): helper to integrate with LMTP delivery.
|
||||||
- [smtp-check(1)](smtp-check.1.md): SMTP setup checker.
|
- [smtp-check(1)](smtp-check.1.md): SMTP setup checker.
|
||||||
|
|
||||||
|
|||||||
+45
-48
@@ -1,13 +1,12 @@
|
|||||||
|
|
||||||
# Monitoring
|
# Monitoring
|
||||||
|
|
||||||
chasquid includes an HTTP server for monitoring purposes, which for security
|
chasquid includes an HTTP server for monitoring purposes, which for security it
|
||||||
it is not enabled by default.
|
is not enabled by default.
|
||||||
|
|
||||||
You can use the `monitoring_address` configuration option to enable it.
|
You can use the `monitoring_address` configuration option to enable it.
|
||||||
|
|
||||||
Then just browse the address and human-friendly links to various monitoring
|
Then just browse the address and human-friendly links to various monitoring and
|
||||||
and debugging tools should appear.
|
debugging tools should appear.
|
||||||
|
|
||||||
These include:
|
These include:
|
||||||
|
|
||||||
@@ -19,7 +18,6 @@ These include:
|
|||||||
- [Exported variables](#variables) for whitebox monitoring.
|
- [Exported variables](#variables) for whitebox monitoring.
|
||||||
- Profiling endpoints, for use with `go tool pprof` or similar tools.
|
- Profiling endpoints, for use with `go tool pprof` or similar tools.
|
||||||
|
|
||||||
|
|
||||||
## Variables
|
## Variables
|
||||||
|
|
||||||
chasquid exports some variables for monitoring, via the standard
|
chasquid exports some variables for monitoring, via the standard
|
||||||
@@ -30,8 +28,7 @@ whitebox monitoring.
|
|||||||
They're accessible on the monitoring HTTP server, at `/debug/vars` (default
|
They're accessible on the monitoring HTTP server, at `/debug/vars` (default
|
||||||
endpoint for expvars) and `/metrics` (common endpoint for openmetrics).
|
endpoint for expvars) and `/metrics` (common endpoint for openmetrics).
|
||||||
|
|
||||||
<a name="prometheus"></a>
|
<a name="prometheus"></a> The `/metrics` endpoint is also compatible with
|
||||||
The `/metrics` endpoint is also compatible with
|
|
||||||
[Prometheus](https://prometheus.io/).
|
[Prometheus](https://prometheus.io/).
|
||||||
|
|
||||||
*Note these are still subject to change, although breaking changes will be
|
*Note these are still subject to change, although breaking changes will be
|
||||||
@@ -40,86 +37,86 @@ avoided whenever possible, and will be noted in the
|
|||||||
|
|
||||||
List of exported variables:
|
List of exported variables:
|
||||||
|
|
||||||
- **chasquid/aliases/hookResults** (hook result -> counter)
|
- **chasquid/aliases/hookResults** (hook result -> counter)\
|
||||||
count of aliases hook results, by hook and result.
|
count of aliases hook results, by hook and result.
|
||||||
- **chasquid/queue/deliverAttempts** (recipient type -> counter)
|
- **chasquid/queue/deliverAttempts** (recipient type -> counter)\
|
||||||
attempts to deliver mail, by recipient type (pipe/local email/remote email).
|
attempts to deliver mail, by recipient type (pipe/local email/remote email).
|
||||||
- **chasquid/queue/dsnQueued** (counter)
|
- **chasquid/queue/dsnQueued** (counter)\
|
||||||
count of DSNs that we generated (queued).
|
count of DSNs that we generated (queued).
|
||||||
- **chasquid/queue/itemsWritten** (counter)
|
- **chasquid/queue/itemsWritten** (counter)\
|
||||||
count of items the queue wrote to disk.
|
count of items the queue wrote to disk.
|
||||||
- **chasquid/queue/putCount** (counter)
|
- **chasquid/queue/putCount** (counter)\
|
||||||
number of envelopes put in the queue.
|
number of envelopes put in the queue.
|
||||||
- **chasquid/smtpIn/acceptErrors** (counter)
|
- **chasquid/smtpIn/acceptErrors** (counter)\
|
||||||
count of errors accepting incoming connections.
|
count of errors accepting incoming connections.
|
||||||
- **chasquid/smtpIn/activeConnections** (gauge)
|
- **chasquid/smtpIn/activeConnections** (gauge)\
|
||||||
number of active incoming connections.
|
number of active incoming connections.
|
||||||
- **chasquid/smtpIn/commandCount** (map of command -> count)
|
- **chasquid/smtpIn/commandCount** (map of command -> count)\
|
||||||
count of SMTP commands received, by command. Note that for unknown commands
|
count of SMTP commands received, by command. Note that for unknown commands
|
||||||
we use `unknown<COMMAND>`.
|
we use `unknown<COMMAND>`.
|
||||||
- **chasquid/smtpIn/connectionsOverLimit** (counter)
|
- **chasquid/smtpIn/connectionsOverLimit** (counter)\
|
||||||
count of incoming connections closed due to the connection limit, which is
|
count of incoming connections closed due to the connection limit, which is
|
||||||
half of the file descriptor limit.
|
half of the file descriptor limit.
|
||||||
- **chasquid/smtpIn/dkimSignErrors** (counter)
|
- **chasquid/smtpIn/dkimSignErrors** (counter)\
|
||||||
count of DKIM sign errors
|
count of DKIM sign errors
|
||||||
- **chasquid/smtpIn/dkimSigned** (counter)
|
- **chasquid/smtpIn/dkimSigned** (counter)\
|
||||||
count of successful DKIM signs
|
count of successful DKIM signs
|
||||||
- **chasquid/smtpIn/dkimVerifyErrors** (counter)
|
- **chasquid/smtpIn/dkimVerifyErrors** (counter)\
|
||||||
count of DKIM verification errors
|
count of DKIM verification errors
|
||||||
- **chasquid/smtpIn/dkimVerifyFound** (counter)
|
- **chasquid/smtpIn/dkimVerifyFound** (counter)\
|
||||||
count of messages with at least one DKIM signature
|
count of messages with at least one DKIM signature
|
||||||
- **chasquid/smtpIn/dkimVerifyNotFound** (counter)
|
- **chasquid/smtpIn/dkimVerifyNotFound** (counter)\
|
||||||
count of messages with no DKIM signatures
|
count of messages with no DKIM signatures
|
||||||
- **chasquid/smtpIn/dkimVerifyValid** (counter)
|
- **chasquid/smtpIn/dkimVerifyValid** (counter)\
|
||||||
count of messages with at least one valid DKIM signature
|
count of messages with at least one valid DKIM signature
|
||||||
- **chasquid/smtpIn/hookResults** (result -> counter)
|
- **chasquid/smtpIn/hookResults** (result -> counter)\
|
||||||
count of hook invocations, by result.
|
count of hook invocations, by result.
|
||||||
- **chasquid/smtpIn/loopsDetected** (counter)
|
- **chasquid/smtpIn/loopsDetected** (counter)\
|
||||||
count of email loops detected.
|
count of email loops detected.
|
||||||
- **chasquid/smtpIn/responseCodeCount** (code -> counter)
|
- **chasquid/smtpIn/responseCodeCount** (code -> counter)\
|
||||||
count of response codes returned to incoming SMTP connections, by result
|
count of response codes returned to incoming SMTP connections, by result
|
||||||
code.
|
code.
|
||||||
- **chasquid/smtpIn/securityLevelChecks** (result -> counter)
|
- **chasquid/smtpIn/securityLevelChecks** (result -> counter)\
|
||||||
count of security level checks on incoming connections, by result.
|
count of security level checks on incoming connections, by result.
|
||||||
- **chasquid/smtpIn/spfResultCount** (result -> counter)
|
- **chasquid/smtpIn/spfResultCount** (result -> counter)\
|
||||||
count of SPF checks, by result.
|
count of SPF checks, by result.
|
||||||
- **chasquid/smtpIn/tlsCount** (tls status -> counter)
|
- **chasquid/smtpIn/tlsCount** (tls status -> counter)\
|
||||||
count of TLS statuses (plain/tls) for incoming SMTP connections.
|
count of TLS statuses (plain/tls) for incoming SMTP connections.
|
||||||
- **chasquid/smtpIn/wrongProtoCount** (command -> counter)
|
- **chasquid/smtpIn/wrongProtoCount** (command -> counter)\
|
||||||
count of commands for other protocols (e.g. HTTP commands).
|
count of commands for other protocols (e.g. HTTP commands).
|
||||||
- **chasquid/smtpOut/securityLevelChecks** (result -> counter)
|
- **chasquid/smtpOut/securityLevelChecks** (result -> counter)\
|
||||||
count of security level checks on outgoing connections, by result.
|
count of security level checks on outgoing connections, by result.
|
||||||
- **chasquid/smtpOut/sts/mode** (mode -> counter)
|
- **chasquid/smtpOut/sts/mode** (mode -> counter)\
|
||||||
count of STS checks on outgoing connections, by mode (enforce/testing).
|
count of STS checks on outgoing connections, by mode (enforce/testing).
|
||||||
- **chasquid/smtpOut/sts/security** (result -> counter)
|
- **chasquid/smtpOut/sts/security** (result -> counter)\
|
||||||
count of STS security checks on outgoing connections, by result (pass/fail).
|
count of STS security checks on outgoing connections, by result (pass/fail).
|
||||||
- **chasquid/smtpOut/tlsCount** (status -> counter)
|
- **chasquid/smtpOut/tlsCount** (status -> counter)\
|
||||||
count of TLS status (insecure TLS/secure TLS/plain) on outgoing connections.
|
count of TLS status (insecure TLS/secure TLS/plain) on outgoing connections.
|
||||||
- **chasquid/sourceDateStr** (string)
|
- **chasquid/sourceDateStr** (string)\
|
||||||
timestamp when the binary was built, in human readable format.
|
timestamp when the binary was built, in human readable format.
|
||||||
- **chasquid/sourceDateTimestamp** (int)
|
- **chasquid/sourceDateTimestamp** (int)\
|
||||||
timestamp when the binary was built, in seconds since epoch.
|
timestamp when the binary was built, in seconds since epoch.
|
||||||
- **chasquid/sts/cache/expired** (counter)
|
- **chasquid/sts/cache/expired** (counter)\
|
||||||
count of expired entries in the STS cache.
|
count of expired entries in the STS cache.
|
||||||
- **chasquid/sts/cache/failedFetch** (counter)
|
- **chasquid/sts/cache/failedFetch** (counter)\
|
||||||
count of failed fetches in the STS cache.
|
count of failed fetches in the STS cache.
|
||||||
- **chasquid/sts/cache/fetches** (counter)
|
- **chasquid/sts/cache/fetches** (counter)\
|
||||||
count of total fetches in the STS cache.
|
count of total fetches in the STS cache.
|
||||||
- **chasquid/sts/cache/hits** (counter)
|
- **chasquid/sts/cache/hits** (counter)\
|
||||||
count of hits in the STS cache.
|
count of hits in the STS cache.
|
||||||
- **chasquid/sts/cache/invalid** (counter)
|
- **chasquid/sts/cache/invalid** (counter)\
|
||||||
count of invalid policies in the STS cache.
|
count of invalid policies in the STS cache.
|
||||||
- **chasquid/sts/cache/ioErrors** (counter)
|
- **chasquid/sts/cache/ioErrors** (counter)\
|
||||||
count of I/O errors when maintaining the STS cache.
|
count of I/O errors when maintaining the STS cache.
|
||||||
- **chasquid/sts/cache/marshalErrors** (counter)
|
- **chasquid/sts/cache/marshalErrors** (counter)\
|
||||||
count of marshaling errors when maintaining the STS cache.
|
count of marshaling errors when maintaining the STS cache.
|
||||||
- **chasquid/sts/cache/refreshCycles** (counter)
|
- **chasquid/sts/cache/refreshCycles** (counter)\
|
||||||
count of STS cache refresh cycles.
|
count of STS cache refresh cycles.
|
||||||
- **chasquid/sts/cache/refreshErrors** (counter)
|
- **chasquid/sts/cache/refreshErrors** (counter)\
|
||||||
count of STS cache refresh errors.
|
count of STS cache refresh errors.
|
||||||
- **chasquid/sts/cache/refreshes** (counter)
|
- **chasquid/sts/cache/refreshes** (counter)\
|
||||||
count of STS cache refreshes.
|
count of STS cache refreshes.
|
||||||
- **chasquid/sts/cache/unmarshalErrors** (counter)
|
- **chasquid/sts/cache/unmarshalErrors** (counter)\
|
||||||
count of unmarshaling errors in the STS cache.
|
count of unmarshaling errors in the STS cache.
|
||||||
- **chasquid/version** (string)
|
- **chasquid/version** (string)\
|
||||||
version string.
|
version string.
|
||||||
|
|||||||
+19
-47
@@ -1,10 +1,8 @@
|
|||||||
|
|
||||||
# Release notes
|
# Release notes
|
||||||
|
|
||||||
This file contains notes for each release, summarizing changes and explicitly
|
This file contains notes for each release, summarizing changes and explicitly
|
||||||
noting backward-incompatible changes or known security issues.
|
noting backward-incompatible changes or known security issues.
|
||||||
|
|
||||||
|
|
||||||
## 1.18.0 (2026-06-07)
|
## 1.18.0 (2026-06-07)
|
||||||
|
|
||||||
- Conform to the stricter OpenMetrics format in the monitoring exporter, which
|
- Conform to the stricter OpenMetrics format in the monitoring exporter, which
|
||||||
@@ -12,7 +10,6 @@ noting backward-incompatible changes or known security issues.
|
|||||||
- Fix extra newlines in the authentication log entries.
|
- Fix extra newlines in the authentication log entries.
|
||||||
- Docker image improvements, including updating the Dovecot config to 2.4.
|
- Docker image improvements, including updating the Dovecot config to 2.4.
|
||||||
|
|
||||||
|
|
||||||
## 1.17.0 (2025-11-30)
|
## 1.17.0 (2025-11-30)
|
||||||
|
|
||||||
- Fix `Received` header format when including the IP address.
|
- Fix `Received` header format when including the IP address.
|
||||||
@@ -20,7 +17,6 @@ noting backward-incompatible changes or known security issues.
|
|||||||
- Docker image improvements and bug fixes.
|
- Docker image improvements and bug fixes.
|
||||||
- Minor fixes for systems without /bin.
|
- Minor fixes for systems without /bin.
|
||||||
|
|
||||||
|
|
||||||
## 1.16.0 (2025-06-08)
|
## 1.16.0 (2025-06-08)
|
||||||
|
|
||||||
- Minor bug fixes to `chasquid-util`.
|
- Minor bug fixes to `chasquid-util`.
|
||||||
@@ -31,7 +27,6 @@ noting backward-incompatible changes or known security issues.
|
|||||||
- Make the max queue size and give up time
|
- Make the max queue size and give up time
|
||||||
[configurable](man/chasquid.conf.5.md) *(experimental)*.
|
[configurable](man/chasquid.conf.5.md) *(experimental)*.
|
||||||
|
|
||||||
|
|
||||||
## 1.15.0 (2025-01-17)
|
## 1.15.0 (2025-01-17)
|
||||||
|
|
||||||
- Exit if there's an error reading users/aliases files on startup.
|
- Exit if there's an error reading users/aliases files on startup.
|
||||||
@@ -40,15 +35,14 @@ noting backward-incompatible changes or known security issues.
|
|||||||
|
|
||||||
### 1.15.1 (2025-03-30)
|
### 1.15.1 (2025-03-30)
|
||||||
|
|
||||||
Implement a workaround for a Microsoft bug in TLS session ticket handling,
|
Implement a workaround for a Microsoft bug in TLS session ticket handling, that
|
||||||
that is causing deliverability issues, and they are being too slow at fixing.
|
is causing deliverability issues, and they are being too slow at fixing.
|
||||||
|
|
||||||
See this [chasquid issue](https://github.com/albertito/chasquid/issues/64),
|
See this [chasquid issue](https://github.com/albertito/chasquid/issues/64),
|
||||||
this [Go issue](https://github.com/golang/go/issues/70232) and this
|
this [Go issue](https://github.com/golang/go/issues/70232) and this
|
||||||
[Postfix thread](https://www.mail-archive.com/postfix-users@postfix.org/msg104308.html)
|
[Postfix thread](https://www.mail-archive.com/postfix-users@postfix.org/msg104308.html)
|
||||||
for more details.
|
for more details.
|
||||||
|
|
||||||
|
|
||||||
## 1.14.0 (2024-04-21)
|
## 1.14.0 (2024-04-21)
|
||||||
|
|
||||||
- Add built-in [DKIM](dkim.md) signing and verification.
|
- Add built-in [DKIM](dkim.md) signing and verification.
|
||||||
@@ -59,17 +53,16 @@ for more details.
|
|||||||
[SemVer](https://semver.org/)-compatible, to help integration with other
|
[SemVer](https://semver.org/)-compatible, to help integration with other
|
||||||
software that expects it (e.g. [pkg.go.dev](https://pkg.go.dev/)).
|
software that expects it (e.g. [pkg.go.dev](https://pkg.go.dev/)).
|
||||||
|
|
||||||
|
|
||||||
## 1.13 (2023-12-24)
|
## 1.13 (2023-12-24)
|
||||||
|
|
||||||
Security fixes:
|
Security fixes:
|
||||||
|
|
||||||
- Strict CRLF enforcement in DATA contents, to prevent [SMTP smuggling
|
- Strict CRLF enforcement in DATA contents, to prevent
|
||||||
attacks](https://www.postfix.org/smtp-smuggling.html)
|
[SMTP smuggling attacks](https://www.postfix.org/smtp-smuggling.html)
|
||||||
([CVE-2023-52354](https://nvd.nist.gov/vuln/detail/CVE-2023-52354)). \
|
([CVE-2023-52354](https://nvd.nist.gov/vuln/detail/CVE-2023-52354)). \
|
||||||
[RFC5322](https://www.rfc-editor.org/rfc/rfc5322#section-2.3) and
|
[RFC5322](https://www.rfc-editor.org/rfc/rfc5322#section-2.3) and
|
||||||
[RFC5321](https://www.rfc-editor.org/rfc/rfc5321#section-2.3.8) say
|
[RFC5321](https://www.rfc-editor.org/rfc/rfc5321#section-2.3.8) say that the
|
||||||
that the only valid newline terminator in SMTP is CRLF. \
|
only valid newline terminator in SMTP is CRLF. \
|
||||||
When an invalid newline terminator is found in an incoming message, the
|
When an invalid newline terminator is found in an incoming message, the
|
||||||
connection is now aborted immediately (previous releases also accepted
|
connection is now aborted immediately (previous releases also accepted
|
||||||
LF-terminated lines). \
|
LF-terminated lines). \
|
||||||
@@ -84,11 +77,10 @@ Other changes:
|
|||||||
entry in the config.
|
entry in the config.
|
||||||
- `docker/add-user.sh`: Support getting email and password from env variables.
|
- `docker/add-user.sh`: Support getting email and password from env variables.
|
||||||
|
|
||||||
|
|
||||||
## 1.12 (2023-10-07)
|
## 1.12 (2023-10-07)
|
||||||
|
|
||||||
- Support [aliases with drop characters and
|
- Support
|
||||||
suffix separators](aliases.md#drop-characters-and-suffix-separators).
|
[aliases with drop characters and suffix separators](aliases.md#drop-characters-and-suffix-separators).
|
||||||
- Improved delivery on some low-level TLS negotiation errors.
|
- Improved delivery on some low-level TLS negotiation errors.
|
||||||
- `smtp-check`: Add flag to specify local name.
|
- `smtp-check`: Add flag to specify local name.
|
||||||
- `chasquid-util`: `aliases-resolve` and `domaininfo-remove` subcommands now
|
- `chasquid-util`: `aliases-resolve` and `domaininfo-remove` subcommands now
|
||||||
@@ -98,7 +90,6 @@ Other changes:
|
|||||||
command that was added a while ago, and there is no need for it anymore.
|
command that was added a while ago, and there is no need for it anymore.
|
||||||
- Handle symlinks under the `certs/` directory.
|
- Handle symlinks under the `certs/` directory.
|
||||||
|
|
||||||
|
|
||||||
## 1.11 (2023-02-19)
|
## 1.11 (2023-02-19)
|
||||||
|
|
||||||
- New tracing library for improved observability.
|
- New tracing library for improved observability.
|
||||||
@@ -110,14 +101,12 @@ Backport the security fixes from 1.13 (*Strict CRLF enforcement in DATA
|
|||||||
contents*, fixes
|
contents*, fixes
|
||||||
[CVE-2023-52354](https://nvd.nist.gov/vuln/detail/CVE-2023-52354)).
|
[CVE-2023-52354](https://nvd.nist.gov/vuln/detail/CVE-2023-52354)).
|
||||||
|
|
||||||
|
|
||||||
## 1.10 (2022-09-01)
|
## 1.10 (2022-09-01)
|
||||||
|
|
||||||
- Support [catch-all aliases](aliases.md#catch-all).
|
- Support [catch-all aliases](aliases.md#catch-all).
|
||||||
- Fix bug in Docker image with user-provided certificates.
|
- Fix bug in Docker image with user-provided certificates.
|
||||||
- Miscellaneous test improvements.
|
- Miscellaneous test improvements.
|
||||||
|
|
||||||
|
|
||||||
## 1.9 (2022-03-05)
|
## 1.9 (2022-03-05)
|
||||||
|
|
||||||
- Improve certificate validation logic in the SMTP courier.
|
- Improve certificate validation logic in the SMTP courier.
|
||||||
@@ -125,11 +114,10 @@ contents*, fixes
|
|||||||
- Support `""` values for `drop_characters` and `suffix_separators` in the
|
- Support `""` values for `drop_characters` and `suffix_separators` in the
|
||||||
configuration file.
|
configuration file.
|
||||||
|
|
||||||
|
|
||||||
## 1.8 (2021-07-30)
|
## 1.8 (2021-07-30)
|
||||||
|
|
||||||
- Stricter error checking to help prevent cross-protocol attacks
|
- Stricter error checking to help prevent cross-protocol attacks (like
|
||||||
(like [ALPACA](https://alpaca-attack.com/)).
|
[ALPACA](https://alpaca-attack.com/)).
|
||||||
- Allow authenticating users without an `@domain` part.
|
- Allow authenticating users without an `@domain` part.
|
||||||
- Add integration for
|
- Add integration for
|
||||||
[chasquid-rspamd](https://github.com/Thor77/chasquid-rspamd) and
|
[chasquid-rspamd](https://github.com/Thor77/chasquid-rspamd) and
|
||||||
@@ -138,18 +126,16 @@ contents*, fixes
|
|||||||
- Use `application/openmetrics-text` as content type in the openmetrics
|
- Use `application/openmetrics-text` as content type in the openmetrics
|
||||||
exporter.
|
exporter.
|
||||||
|
|
||||||
|
|
||||||
## 1.7 (2021-05-31)
|
## 1.7 (2021-05-31)
|
||||||
|
|
||||||
- chasquid-util no longer depends on the unmaintained docopt-go.
|
- chasquid-util no longer depends on the unmaintained docopt-go. If you relied
|
||||||
If you relied on undocumented parsing behaviour before, your invocations may
|
on undocumented parsing behaviour before, your invocations may need
|
||||||
need adjustment. In particular, `--a b` is no longer supported, and `--a=b`
|
adjustment. In particular, `--a b` is no longer supported, and `--a=b` must
|
||||||
must be used instead.
|
be used instead.
|
||||||
- Improve handling of errors when talking to Dovecot for authentication.
|
- Improve handling of errors when talking to Dovecot for authentication.
|
||||||
- Fix handling of `hostname` option in the Docker image.
|
- Fix handling of `hostname` option in the Docker image.
|
||||||
- Miscellaneous documentation and test improvements.
|
- Miscellaneous documentation and test improvements.
|
||||||
|
|
||||||
|
|
||||||
## 1.6 (2020-11-22)
|
## 1.6 (2020-11-22)
|
||||||
|
|
||||||
- Pass the EHLO domain to the post-data hook.
|
- Pass the EHLO domain to the post-data hook.
|
||||||
@@ -157,7 +143,6 @@ contents*, fixes
|
|||||||
- Implement HAProxy protocol support (experimental).
|
- Implement HAProxy protocol support (experimental).
|
||||||
- Documentation updates.
|
- Documentation updates.
|
||||||
|
|
||||||
|
|
||||||
## 1.5 (2020-09-12)
|
## 1.5 (2020-09-12)
|
||||||
|
|
||||||
- Add OpenMetrics exporter (compatible with Prometheus).
|
- Add OpenMetrics exporter (compatible with Prometheus).
|
||||||
@@ -166,14 +151,12 @@ contents*, fixes
|
|||||||
- Fix rspamd greylist action handling in the default hook.
|
- Fix rspamd greylist action handling in the default hook.
|
||||||
- Miscellaneous monitoring server improvements.
|
- Miscellaneous monitoring server improvements.
|
||||||
|
|
||||||
|
|
||||||
## 1.4 (2020-05-22)
|
## 1.4 (2020-05-22)
|
||||||
|
|
||||||
- Use the configured hostname in outgoing SMTP HELO/EHLO.
|
- Use the configured hostname in outgoing SMTP HELO/EHLO.
|
||||||
- Allow config overrides from the command line.
|
- Allow config overrides from the command line.
|
||||||
- Miscellaneous test improvements and code cleanups.
|
- Miscellaneous test improvements and code cleanups.
|
||||||
|
|
||||||
|
|
||||||
## 1.3 (2020-04-12)
|
## 1.3 (2020-04-12)
|
||||||
|
|
||||||
- Improved handling of DNS temporary errors.
|
- Improved handling of DNS temporary errors.
|
||||||
@@ -181,7 +164,6 @@ contents*, fixes
|
|||||||
Arch installation instructions).
|
Arch installation instructions).
|
||||||
- Miscellaneous test improvements and cleanups.
|
- Miscellaneous test improvements and cleanups.
|
||||||
|
|
||||||
|
|
||||||
## 1.2 (2019-12-06)
|
## 1.2 (2019-12-06)
|
||||||
|
|
||||||
Security fixes:
|
Security fixes:
|
||||||
@@ -197,7 +179,6 @@ Release notes:
|
|||||||
- New documentation sections (monitoring, release notes).
|
- New documentation sections (monitoring, release notes).
|
||||||
- Many miscellaneous test improvements.
|
- Many miscellaneous test improvements.
|
||||||
|
|
||||||
|
|
||||||
## 1.1 (2019-10-26)
|
## 1.1 (2019-10-26)
|
||||||
|
|
||||||
- Added hooks for aliases resolution.
|
- Added hooks for aliases resolution.
|
||||||
@@ -207,7 +188,6 @@ Release notes:
|
|||||||
- Documentation and test improvements.
|
- Documentation and test improvements.
|
||||||
- Minor bug fixes.
|
- Minor bug fixes.
|
||||||
|
|
||||||
|
|
||||||
## 1.0 (2019-07-15)
|
## 1.0 (2019-07-15)
|
||||||
|
|
||||||
No backwards-incompatible changes. No more are expected within this major
|
No backwards-incompatible changes. No more are expected within this major
|
||||||
@@ -217,7 +197,6 @@ version.
|
|||||||
- Make DSN tidier, especially in handling multi-line errors.
|
- Make DSN tidier, especially in handling multi-line errors.
|
||||||
- Miscellaneous test improvements.
|
- Miscellaneous test improvements.
|
||||||
|
|
||||||
|
|
||||||
## 0.07 (2019-01-19)
|
## 0.07 (2019-01-19)
|
||||||
|
|
||||||
No backwards-incompatible changes.
|
No backwards-incompatible changes.
|
||||||
@@ -227,14 +206,12 @@ No backwards-incompatible changes.
|
|||||||
- Miscellaneous test improvements.
|
- Miscellaneous test improvements.
|
||||||
- DKIM integration examples and test.
|
- DKIM integration examples and test.
|
||||||
|
|
||||||
|
|
||||||
## 0.06 (2018-07-22)
|
## 0.06 (2018-07-22)
|
||||||
|
|
||||||
No backwards-incompatible changes.
|
No backwards-incompatible changes.
|
||||||
|
|
||||||
- New MTA-STS (Strict Transport Security) checking.
|
- New MTA-STS (Strict Transport Security) checking.
|
||||||
|
|
||||||
|
|
||||||
## 0.05 (2018-06-05)
|
## 0.05 (2018-06-05)
|
||||||
|
|
||||||
No backwards-incompatible changes.
|
No backwards-incompatible changes.
|
||||||
@@ -244,7 +221,6 @@ No backwards-incompatible changes.
|
|||||||
- Periodic reload of domaininfo, support removing entries manually.
|
- Periodic reload of domaininfo, support removing entries manually.
|
||||||
- Dovecot auth support no longer considered experimental.
|
- Dovecot auth support no longer considered experimental.
|
||||||
|
|
||||||
|
|
||||||
## 0.04 (2018-02-10)
|
## 0.04 (2018-02-10)
|
||||||
|
|
||||||
No backwards-incompatible changes.
|
No backwards-incompatible changes.
|
||||||
@@ -252,18 +228,16 @@ No backwards-incompatible changes.
|
|||||||
- Add Dovecot authentication support (experimental).
|
- Add Dovecot authentication support (experimental).
|
||||||
- Miscellaneous bug fixes to mda-lmtp and tests.
|
- Miscellaneous bug fixes to mda-lmtp and tests.
|
||||||
|
|
||||||
|
|
||||||
## 0.03 (2017-07-15)
|
## 0.03 (2017-07-15)
|
||||||
|
|
||||||
**Backwards-incompatible changes:**
|
**Backwards-incompatible changes:**
|
||||||
|
|
||||||
- The default MTA binary has changed. It's now maildrop by default.
|
- The default MTA binary has changed. It's now maildrop by default. If you
|
||||||
If you relied on procmail being the default, add the following to
|
relied on procmail being the default, add the following to
|
||||||
`/etc/chasquid/chasquid.conf`: `mail_delivery_agent_bin: "procmail"`.
|
`/etc/chasquid/chasquid.conf`: `mail_delivery_agent_bin: "procmail"`.
|
||||||
- chasquid now listens on a third port, submission-on-TLS.
|
- chasquid now listens on a third port, submission-on-TLS. If using systemd,
|
||||||
If using systemd, copy the `etc/systemd/system/chasquid-submission_tls.socket`
|
copy the `etc/systemd/system/chasquid-submission_tls.socket` file to
|
||||||
file to `/etc/systemd/system/`, and start it.
|
`/etc/systemd/system/`, and start it.
|
||||||
|
|
||||||
|
|
||||||
Release notes:
|
Release notes:
|
||||||
|
|
||||||
@@ -271,7 +245,6 @@ Release notes:
|
|||||||
- Change the default MDA binary to `maildrop`.
|
- Change the default MDA binary to `maildrop`.
|
||||||
- Add a very basic MDA that uses LMTP to do the mail delivery.
|
- Add a very basic MDA that uses LMTP to do the mail delivery.
|
||||||
|
|
||||||
|
|
||||||
## 0.02 (2017-03-03)
|
## 0.02 (2017-03-03)
|
||||||
|
|
||||||
No backwards-incompatible changes.
|
No backwards-incompatible changes.
|
||||||
@@ -280,7 +253,6 @@ No backwards-incompatible changes.
|
|||||||
- Fall back through the MX list on errors.
|
- Fall back through the MX list on errors.
|
||||||
- Experimental MTA-STS implementation (disabled by default).
|
- Experimental MTA-STS implementation (disabled by default).
|
||||||
|
|
||||||
|
|
||||||
## 0.01 (2016-11-03)
|
## 0.01 (2016-11-03)
|
||||||
|
|
||||||
Initial release.
|
Initial release.
|
||||||
|
|||||||
+26
-33
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# Security level checks
|
# Security level checks
|
||||||
|
|
||||||
chasquid tracks per-domain TLS support, and uses it to prevent connection
|
chasquid tracks per-domain TLS support, and uses it to prevent connection
|
||||||
@@ -11,28 +10,26 @@ servers.
|
|||||||
|
|
||||||
This is very different from other MTAs, and has some tradeoffs.
|
This is very different from other MTAs, and has some tradeoffs.
|
||||||
|
|
||||||
|
|
||||||
## Outgoing connections
|
## Outgoing connections
|
||||||
|
|
||||||
An outgoing connection has one of 3 security levels, which are (in order):
|
An outgoing connection has one of 3 security levels, which are (in order):
|
||||||
|
|
||||||
1. Plain: connection is plain-text (the server does not support TLS).
|
1. Plain: connection is plain-text (the server does not support TLS).
|
||||||
2. TLS insecure: TLS connection established, but the certificate itself was
|
2. TLS insecure: TLS connection established, but the certificate itself was not
|
||||||
not valid.
|
valid.
|
||||||
3. TLS secure: TLS connection established, with a valid certificate.
|
3. TLS secure: TLS connection established, with a valid certificate.
|
||||||
|
|
||||||
When establishing an outgoing connection, chasquid will always attempt to
|
When establishing an outgoing connection, chasquid will always attempt to
|
||||||
negotiate up to the *TLS secure* level. After the negotiation, it will
|
negotiate up to the *TLS secure* level. After the negotiation, it will compare
|
||||||
compare which level it got, with the previously recorded value for this
|
which level it got, with the previously recorded value for this domain:
|
||||||
domain:
|
|
||||||
|
|
||||||
* If the connection level is lower than the recorded value, then the
|
- If the connection level is lower than the recorded value, then the connection
|
||||||
connection will be dropped, and the delivery will fail (with a transient
|
will be dropped, and the delivery will fail (with a transient failure). The
|
||||||
failure). The delivery will be retried as usual (using other MXs if
|
delivery will be retried as usual (using other MXs if available, and repeat
|
||||||
available, and repeat after some delay).
|
after some delay).
|
||||||
* If the connection level is the same as the recorded value, then the
|
- If the connection level is the same as the recorded value, then the
|
||||||
connection will proceed.
|
connection will proceed.
|
||||||
* If the connection level is higher, chasquid will record this new value, and
|
- If the connection level is higher, chasquid will record this new value, and
|
||||||
proceed.
|
proceed.
|
||||||
|
|
||||||
If there is no previously recorded value for this domain, a *plain* level is
|
If there is no previously recorded value for this domain, a *plain* level is
|
||||||
@@ -55,25 +52,24 @@ with MTA-STS and HTTPS, but it is not universally agreed upon. It's also why
|
|||||||
the "TLS insecure" state exists, instead of the connection being rejected
|
the "TLS insecure" state exists, instead of the connection being rejected
|
||||||
directly.
|
directly.
|
||||||
|
|
||||||
|
|
||||||
### Tradeoffs
|
### Tradeoffs
|
||||||
|
|
||||||
Almost all other MTAs do TLS negotiation but accept *all* certificates, even
|
Almost all other MTAs do TLS negotiation but accept *all* certificates, even
|
||||||
self-signed or expired ones. chasquid operates differently, as described
|
self-signed or expired ones. chasquid operates differently, as described above.
|
||||||
above.
|
|
||||||
|
|
||||||
The main advantage is that, *with domains where secure connections were
|
The main advantage is that, *with domains where secure connections were
|
||||||
previously established*, chasquid will detect connection downgrading (caused
|
previously established*, chasquid will detect connection downgrading (caused by
|
||||||
by malicious interception such as STARTTLS blocking, as well as
|
malicious interception such as STARTTLS blocking, as well as misconfiguration
|
||||||
misconfiguration such as incorrectly configured or expired certificates), and
|
such as incorrectly configured or expired certificates), and avoid
|
||||||
avoid communicating insecurely.
|
communicating insecurely.
|
||||||
|
|
||||||
The main disadvantage is that if a domain changes the configuration to a lower
|
The main disadvantage is that if a domain changes the configuration to a lower
|
||||||
security level, chasquid will fail the delivery (returning a message to the
|
security level, chasquid will fail the delivery (returning a message to the
|
||||||
sender explaining why). Because there is no formal standard for TLS
|
sender explaining why). Because there is no formal standard for TLS certificate
|
||||||
certificate validation, and most MTAs will deliver email in this situation,
|
validation, and most MTAs will deliver email in this situation, the domain
|
||||||
the domain owners might not see this as a problem and thus require [manual
|
owners might not see this as a problem and thus require
|
||||||
intervention](#manual-override) on the chasquid side to explicitly allow it.
|
[manual intervention](#manual-override) on the chasquid side to explicitly
|
||||||
|
allow it.
|
||||||
|
|
||||||
### MTA-STS
|
### MTA-STS
|
||||||
|
|
||||||
@@ -85,7 +81,6 @@ It is supported by chasquid, out of the box, and in practice it means that for
|
|||||||
domains that advertise MTA-STS support, the *secure* level will be enforced
|
domains that advertise MTA-STS support, the *secure* level will be enforced
|
||||||
even if the domain was previously unknown.
|
even if the domain was previously unknown.
|
||||||
|
|
||||||
|
|
||||||
## Incoming connections
|
## Incoming connections
|
||||||
|
|
||||||
Incoming connections from authenticated users are always done over TLS
|
Incoming connections from authenticated users are always done over TLS
|
||||||
@@ -107,11 +102,11 @@ security levels, which are (in order):
|
|||||||
At this point, chasquid will compare the level with the previously recorded
|
At this point, chasquid will compare the level with the previously recorded
|
||||||
value for this domain:
|
value for this domain:
|
||||||
|
|
||||||
* If the connection level is lower than the recorded value, then the
|
- If the connection level is lower than the recorded value, then the connection
|
||||||
connection is rejected with an SMTP error.
|
is rejected with an SMTP error.
|
||||||
* If the connection level is the same as the recorded value, then the
|
- If the connection level is the same as the recorded value, then the
|
||||||
connection is allowed.
|
connection is allowed.
|
||||||
* If the connection level is higher, chasquid will record this new value, and
|
- If the connection level is higher, chasquid will record this new value, and
|
||||||
the connection is allowed.
|
the connection is allowed.
|
||||||
|
|
||||||
If there is no previously recorded value for this domain, a *plain* level is
|
If there is no previously recorded value for this domain, a *plain* level is
|
||||||
@@ -136,14 +131,12 @@ MTAs will accept the connection anyway, domain owners might not even notice
|
|||||||
there is a problem, and might require [manual intervention](#manual-override)
|
there is a problem, and might require [manual intervention](#manual-override)
|
||||||
on the chasquid side to explicitly allow it.
|
on the chasquid side to explicitly allow it.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Accepting lower security levels {#manual-override}
|
## Accepting lower security levels {#manual-override}
|
||||||
|
|
||||||
If a domain changes its configuration to a lower security level and is causing
|
If a domain changes its configuration to a lower security level and is causing
|
||||||
chasquid to fail delivery, you can use
|
chasquid to fail delivery, you can use
|
||||||
`chasquid-util domaininfo-remove <domain>` to make the server forget about
|
`chasquid-util domaininfo-remove <domain>` to make the server forget about that
|
||||||
that domain.
|
domain.
|
||||||
|
|
||||||
Then, the next time there is a connection, there is no high security
|
Then, the next time there is a connection, there is no high security
|
||||||
expectation so it will proceed just fine, regardless of the level that was
|
expectation so it will proceed just fine, regardless of the level that was
|
||||||
|
|||||||
+1
-2
@@ -5,5 +5,4 @@ albertito@blitiri.com.ar, or do it via [GitHub's Security tab].
|
|||||||
|
|
||||||
Thank you!
|
Thank you!
|
||||||
|
|
||||||
|
[github's security tab]: https://github.com/albertito/chasquid/security
|
||||||
[GitHub's Security tab]: https://github.com/albertito/chasquid/security
|
|
||||||
|
|||||||
+21
-31
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# Testing
|
# Testing
|
||||||
|
|
||||||
## Go tests
|
## Go tests
|
||||||
@@ -6,46 +5,43 @@
|
|||||||
All Go packages have their own test suite, which provides easy and portable
|
All Go packages have their own test suite, which provides easy and portable
|
||||||
tests with decent enough coverage.
|
tests with decent enough coverage.
|
||||||
|
|
||||||
|
|
||||||
## Integration tests
|
## Integration tests
|
||||||
|
|
||||||
In the `test/` directory there is a set of end to end integration tests,
|
In the `test/` directory there is a set of end to end integration tests,
|
||||||
written usually in a combination of bash and Python 3.
|
written usually in a combination of bash and Python 3.
|
||||||
|
|
||||||
They're not expected to be portable, as that gets impractical very quickly,
|
They're not expected to be portable, as that gets impractical very quickly, but
|
||||||
but should be usable in most Linux environments.
|
should be usable in most Linux environments.
|
||||||
|
|
||||||
They provide critical coverage and integration tests for real life scenarios,
|
They provide critical coverage and integration tests for real life scenarios,
|
||||||
as well as interactions with other software (like Exim or Dovecot).
|
as well as interactions with other software (like Exim or Dovecot).
|
||||||
|
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
The tests depend on the following things being installed on the system (listed
|
The tests depend on the following things being installed on the system (listed
|
||||||
as Debian package, for consistency):
|
as Debian package, for consistency):
|
||||||
|
|
||||||
- `msmtp`
|
- `msmtp`
|
||||||
- `util-linux` (for `/usr/bin/setsid`)
|
- `util-linux` (for `/usr/bin/setsid`)
|
||||||
|
|
||||||
Some individual tests have additional dependencies, and the tests are skipped
|
Some individual tests have additional dependencies, and the tests are skipped
|
||||||
if the dependencies are not found:
|
if the dependencies are not found:
|
||||||
|
|
||||||
- `t-02-exim` [Exim](https://www.exim.org/) interaction tests:
|
- `t-02-exim` [Exim](https://www.exim.org/) interaction tests: `gettext-base`
|
||||||
- `gettext-base` (for `/usr/bin/envsubst`)
|
(for `/usr/bin/envsubst`), and the `exim` binary available somewhere, but it
|
||||||
- The `exim` binary available somewhere, but it doesn't have to be
|
doesn't have to be installed. There's a script `get-exim4-debian.sh` to get
|
||||||
installed. There's a script `get-exim4-debian.sh` to get it from the
|
it from the archives.
|
||||||
archives.
|
|
||||||
- `t-11-dovecot` [Dovecot](https://www.dovecot.org/) interaction tests:
|
- `t-11-dovecot` [Dovecot](https://www.dovecot.org/) interaction tests:
|
||||||
- `dovecot`
|
`dovecot`.
|
||||||
- `t-15-driusan_dkim` DKIM integration tests:
|
- `t-15-driusan_dkim` DKIM integration tests: the
|
||||||
- The `dkimsign dkimverify dkimkeygen` binaries, from
|
`dkimsign dkimverify dkimkeygen` binaries, from
|
||||||
[driusan/dkim](https://github.com/driusan/dkim) (no Debian package yet).
|
[driusan/dkim](https://github.com/driusan/dkim) (no Debian package yet).
|
||||||
- `t-18-haproxy` [HAProxy](https://www.haproxy.org/) integration tests:
|
- `t-18-haproxy` [HAProxy](https://www.haproxy.org/) integration tests:
|
||||||
- `haproxy`
|
`haproxy`.
|
||||||
- `t-19-dkimpy`: [dkimpy](https://pypi.org/project/dkimpy/) integration tests:
|
- `t-19-dkimpy`: [dkimpy](https://pypi.org/project/dkimpy/) integration tests:
|
||||||
- `python3-dkim`
|
`python3-dkim`.
|
||||||
- `t-23-prometheus`: [Prometheus](https://prometheus.io/) integration tests:
|
- `t-23-prometheus`: [Prometheus](https://prometheus.io/) integration tests:
|
||||||
- `prometheus promtool`
|
`prometheus promtool`.
|
||||||
|
|
||||||
For some tests, python >= 3.5 is required; they will be skipped if it's not
|
For some tests, python >= 3.5 is required; they will be skipped if it's not
|
||||||
available.
|
available.
|
||||||
@@ -56,7 +52,6 @@ environment variable being functional, and will be skipped if it isn't. This
|
|||||||
works by default in most Linux systems, but note that the use of
|
works by default in most Linux systems, but note that the use of
|
||||||
`systemd-resolved` can prevent it from working properly.
|
`systemd-resolved` can prevent it from working properly.
|
||||||
|
|
||||||
|
|
||||||
## Stress tests
|
## Stress tests
|
||||||
|
|
||||||
Also in the `test/` directory there is a set of stress tests, which generate
|
Also in the `test/` directory there is a set of stress tests, which generate
|
||||||
@@ -65,7 +60,6 @@ load against chasquid to measure performance and resource consumption.
|
|||||||
While they are not exhaustive, they are useful to catch regressions and track
|
While they are not exhaustive, they are useful to catch regressions and track
|
||||||
improvements on the main code paths.
|
improvements on the main code paths.
|
||||||
|
|
||||||
|
|
||||||
## Fuzz tests
|
## Fuzz tests
|
||||||
|
|
||||||
Some Go packages also have instrumentation to run fuzz testing against them,
|
Some Go packages also have instrumentation to run fuzz testing against them,
|
||||||
@@ -74,13 +68,11 @@ using the [Go native fuzzing support](https://go.dev/security/fuzz/).
|
|||||||
This is critical for packages that handle sensitive user input, such as
|
This is critical for packages that handle sensitive user input, such as
|
||||||
authentication encoding, aliases files, or username normalization.
|
authentication encoding, aliases files, or username normalization.
|
||||||
|
|
||||||
|
|
||||||
## Command-line tool tests
|
## Command-line tool tests
|
||||||
|
|
||||||
Each command-line tool has their own set of tests, see the `test.sh` file on
|
Each command-line tool has their own set of tests, see the `test.sh` file on
|
||||||
their corresponding directories.
|
their corresponding directories.
|
||||||
|
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
The `test/Dockerfile` can be used to set up a suitable isolated environment to
|
The `test/Dockerfile` can be used to set up a suitable isolated environment to
|
||||||
@@ -89,20 +81,18 @@ run the integration and stress tests.
|
|||||||
This is very useful for automated tests, or running the integration tests in
|
This is very useful for automated tests, or running the integration tests in
|
||||||
constrained or non supported environments.
|
constrained or non supported environments.
|
||||||
|
|
||||||
|
|
||||||
## Automated tests
|
## Automated tests
|
||||||
|
|
||||||
There are two sets of automated tests which are run on every commit to
|
There are two sets of automated tests which are run on every commit to
|
||||||
upstream, and also weekly:
|
upstream, and also weekly:
|
||||||
|
|
||||||
* [Github Actions](https://github.com/albertito/chasquid/actions),
|
- [Github Actions](https://github.com/albertito/chasquid/actions), configured
|
||||||
configured in the `.github` directory, runs the Go tests, the integration
|
in the `.github` directory, runs the Go tests, the integration tests, checks
|
||||||
tests, checks for vulnerabilities, and finally
|
for vulnerabilities, and finally also builds the
|
||||||
also builds the [public Docker images](docker.md).
|
[public Docker images](docker.md).
|
||||||
|
|
||||||
* [Cirrus CI](https://cirrus-ci.com/github/albertito/chasquid),
|
|
||||||
configured in the `.cirrus.yml` file, runs Go tests on FreeBSD.
|
|
||||||
|
|
||||||
|
- [Cirrus CI](https://cirrus-ci.com/github/albertito/chasquid), configured in
|
||||||
|
the `.cirrus.yml` file, runs Go tests on FreeBSD.
|
||||||
|
|
||||||
## Coverage
|
## Coverage
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user