mirror of
https://blitiri.com.ar/repos/chasquid
synced 2025-12-16 14:27:01 +00:00
dkim: Implement internal dkim signing and verification
This patch implements internal DKIM signing and verification.
This commit is contained in:
106
docs/dkim.md
106
docs/dkim.md
@@ -1,70 +1,90 @@
|
||||
|
||||
# DKIM integration
|
||||
|
||||
[chasquid] supports generating [DKIM] signatures via the [hooks](hooks.md)
|
||||
mechanism.
|
||||
[chasquid] supports verifying and generating [DKIM] signatures since version
|
||||
1.14.
|
||||
|
||||
All incoming email is verified, and *authenticated* emails for domains which
|
||||
have a private DKIM key set up will be signed.
|
||||
|
||||
In versions older than 1.13, support is possible via the [hooks] mechanism. In
|
||||
particular, the [example hook] included support for some command-line
|
||||
implementations. That continues to be an option, especially if customization
|
||||
is needed.
|
||||
|
||||
|
||||
## Signing
|
||||
## Easy setup
|
||||
|
||||
The [example hook] includes integration with [driusan/dkim] and [dkimpy], and
|
||||
assumes the following:
|
||||
- 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`.
|
||||
- Publish the DKIM DNS record which was shown by the
|
||||
previous command (e.g. by following
|
||||
[this guide](https://support.dnsimple.com/articles/dkim-record/)).
|
||||
- Change the key file's permissions, to ensure it is readable by chasquid (and
|
||||
nobody else).
|
||||
- Restart chasquid.
|
||||
|
||||
- The [selector](https://tools.ietf.org/html/rfc6376#section-3.1) for a domain
|
||||
can be found in the file `domains/$DOMAIN/dkim_selector`.
|
||||
- The private key to use for signing can be found in the file
|
||||
`certs/$DOMAIN/dkim_privkey.pem`.
|
||||
|
||||
Only authenticated email will be signed.
|
||||
It is highly recommended that you use a DKIM checker (like
|
||||
[Learn DMARC](https://www.learndmarc.com/)) to confirm that your setup is
|
||||
fully functional.
|
||||
|
||||
|
||||
### Setup with [driusan/dkim]
|
||||
## Advanced setup
|
||||
|
||||
1. Install the [driusan/dkim] tools with something like the following (adjust
|
||||
to your local environment):
|
||||
You need to place the PEM-encoded private key in the domain config directory,
|
||||
with a name like `dkim:SELECTOR.pem`, where `SELECTOR` is the selector string.
|
||||
|
||||
```
|
||||
for i in dkimsign dkimverify dkimkeygen; do
|
||||
go get github.com/driusan/dkim/cmd/$i
|
||||
go install github.com/driusan/dkim/cmd/$i
|
||||
done
|
||||
sudo cp ~/go/bin/{dkimsign,dkimverify,dkimkeygen} /usr/local/bin
|
||||
```
|
||||
It needs to be either RSA or Ed25519.
|
||||
|
||||
1. Generate the domain key for your domain using `dkimkeygen`.
|
||||
1. Publish the DNS record from `dns.txt`
|
||||
([guide](https://support.dnsimple.com/articles/dkim-record/)).
|
||||
1. Write the selector you chose to `domains/$DOMAIN/dkim_selector`.
|
||||
1. Copy `private.pem` to `/etc/chasquid/certs/$DOMAIN/dkim_privkey.pem`.
|
||||
1. Verify the setup using one of the publicly available tools, like
|
||||
[mail-tester](https://www.mail-tester.com/spf-dkim-check).
|
||||
### Key rotation
|
||||
|
||||
To rotate a key, you can remove the old key file, and generate a new one as
|
||||
per the previous step.
|
||||
|
||||
It is important to remove the old key from the directory, because chasquid
|
||||
will 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.
|
||||
|
||||
|
||||
### Setup with [dkimpy]
|
||||
### Multiple keys
|
||||
|
||||
1. Install [dkimpy] with `apt install python3-dkim` or the equivalent for your
|
||||
environment.
|
||||
1. Generate the domain key for your domain using `dknewkey dkim`.
|
||||
1. Publish the DNS record from `dkim.dns`
|
||||
([guide](https://support.dnsimple.com/articles/dkim-record/)).
|
||||
1. Write the selector you chose to `domains/$DOMAIN/dkim_selector`.
|
||||
1. Copy `dkim.key` to `/etc/chasquid/certs/$DOMAIN/dkim_privkey.pem`.
|
||||
1. Verify the setup using one of the publicly available tools, like
|
||||
[mail-tester](https://www.mail-tester.com/spf-dkim-check).
|
||||
Advanced users may want to sign outgoing mail with multiple keys (e.g. to
|
||||
support multiple signing algorithms).
|
||||
|
||||
This is well supported: chasquid will sign email with all keys it find that
|
||||
match `dkim:*.pem` in a domain directory.
|
||||
|
||||
|
||||
## Verification
|
||||
|
||||
Verifying signatures is technically supported as well, and can be done in the
|
||||
same hook. However, it's not recommended for SMTP servers to reject mail on
|
||||
verification failures
|
||||
[chasquid] will verify all DKIM signatures of incoming mail, and record the
|
||||
results in an [`Authentication-Results:`] header, as per [RFC 8601].
|
||||
|
||||
Note that emails will *not* be rejected even if they fail verification, as
|
||||
this is not recommended
|
||||
([source 1](https://tools.ietf.org/html/rfc6376#section-6.3),
|
||||
[source 2](https://tools.ietf.org/html/rfc7601#section-2.7.1)), so it is not
|
||||
included in the example.
|
||||
[source 2](https://tools.ietf.org/html/rfc7601#section-2.7.1)).
|
||||
|
||||
|
||||
## Other implementations
|
||||
|
||||
[chasquid] also supports [DKIM] via the [hooks] mechanism. This can be useful
|
||||
if more customization is needed.
|
||||
|
||||
Implementations that have been tried:
|
||||
|
||||
- [driusan/dkim]
|
||||
- [dkimpy]
|
||||
|
||||
|
||||
[chasquid]: https://blitiri.com.ar/p/chasquid
|
||||
[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/
|
||||
[RFC 8601]: https://datatracker.ietf.org/doc/html/rfc8601
|
||||
[`Authentication-Results:`]: https://en.wikipedia.org/wiki/Email_authentication#Authentication-Results
|
||||
|
||||
@@ -53,6 +53,18 @@ List of exported variables:
|
||||
- **chasquid/smtpIn/commandCount** (map of command -> count)
|
||||
count of SMTP commands received, by command. Note that for unknown commands
|
||||
we use `unknown<COMMAND>`.
|
||||
- **chasquid/smtpIn/dkimSignErrors** (counter)
|
||||
count of DKIM sign errors
|
||||
- **chasquid/smtpIn/dkimSigned** (counter)
|
||||
count of successful DKIM signs
|
||||
- **chasquid/smtpIn/dkimVerifyErrors** (counter)
|
||||
count of DKIM verification errors
|
||||
- **chasquid/smtpIn/dkimVerifyFound** (counter)
|
||||
count of messages with at least one DKIM signature
|
||||
- **chasquid/smtpIn/dkimVerifyNotFound** (counter)
|
||||
count of messages with no DKIM signatures
|
||||
- **chasquid/smtpIn/dkimVerifyValid** (counter)
|
||||
count of messages with at least one valid DKIM signature
|
||||
- **chasquid/smtpIn/hookResults** (result -> counter)
|
||||
count of hook invocations, by result.
|
||||
- **chasquid/smtpIn/loopsDetected** (counter)
|
||||
|
||||
Reference in New Issue
Block a user