mirror of
https://blitiri.com.ar/repos/chasquid
synced 2025-12-17 14:37:02 +00:00
docs: Add some documentation and a README
This commit is contained in:
161
README.md
Normal file
161
README.md
Normal file
@@ -0,0 +1,161 @@
|
||||
|
||||
# chasquid
|
||||
|
||||
[chasquid](https://blitiri.com.ar/p/chasquid) is an SMTP (email) server.
|
||||
|
||||
It aims to be easy to configure and maintain for a small mail server, at the
|
||||
expense of flexibility and functionality.
|
||||
|
||||
It's written in [Go](https://golang.org).
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
* Easy to configure, hard to mis-configure in ways that are harmful or
|
||||
insecure (e.g. no open relay, clear-text authentication, etc.).
|
||||
* Tracking of per-domain TLS support, prevents connection downgrading.
|
||||
* SMTP UTF8 (international usernames).
|
||||
* IDNA (international domain names).
|
||||
* Hooks for easy integration with greylisting, anti-virus and anti-spam.
|
||||
* Multiple domains, with per-domain user database and aliases.
|
||||
* Multiple TLS certificates.
|
||||
* Suffix dropping (user+something@domain -> user@domain).
|
||||
* Easy integration with letsencrypt.
|
||||
* SPF checking.
|
||||
* Monitoring HTTP server, with exported variables and tracing to help
|
||||
debugging.
|
||||
|
||||
|
||||
The following are intentionally *not* implemented:
|
||||
|
||||
* Custom email routing and transport.
|
||||
* DKIM/DMARC checking (although the post-data hook can be used for it).
|
||||
* Different backends for domain and user configuration (Dovecot authentication
|
||||
may be implemented in the future).
|
||||
|
||||
|
||||
## Status
|
||||
|
||||
chasquid is in beta.
|
||||
|
||||
It's functional and has had some production exposure, but some things may
|
||||
still change in backwards-incompatible way, including the configuration format.
|
||||
It should be rare and will be avoided if possible.
|
||||
|
||||
You should subscribe to the mailing list to get notifications of such changes.
|
||||
|
||||
|
||||
## Contact
|
||||
|
||||
If you have any questions, comments or patches please send them to the mailing
|
||||
list, chasquid@googlegroups.com.
|
||||
|
||||
To subscribe, send an email to chasquid+subscribe@googlegroups.com.
|
||||
|
||||
You can also browse the
|
||||
[archives](https://groups.google.com/forum/#!forum/chasquid).
|
||||
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
To get the code and build it, you will need a working [Go](http://golang.org)
|
||||
environment.
|
||||
|
||||
```shell
|
||||
# Get the code and build the binaries.
|
||||
go get blitiri.com.ar/go/chasquid
|
||||
cd "$GOPATH/src/blitiri.com.ar/go/chasquid"
|
||||
make
|
||||
|
||||
# Install the binaries to /usr/local/bin.
|
||||
sudo make install-binaries
|
||||
|
||||
# Copy the example configuration to /etc/chasquid and /etc/systemd, and create
|
||||
# the /var/lib/chasquid directory.
|
||||
sudo make install-config-skeleton
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The configuration is in `/etc/chasquid/` by default, and has the following
|
||||
structure:
|
||||
|
||||
```
|
||||
- chasquid.conf Main config file.
|
||||
|
||||
- domains/ Domains' data.
|
||||
- example.com/
|
||||
- users User and password database for the domain.
|
||||
- aliases Aliases for the domain.
|
||||
...
|
||||
|
||||
- certs/ Certificates to use, one dir per pair.
|
||||
- mx.example.com/
|
||||
- fullchain.pem Certificate (full chain).
|
||||
- privkey.pem Private key.
|
||||
...
|
||||
```
|
||||
|
||||
Note the certs/ directory matches certbot's structure, so if you use it you
|
||||
can just symlink to /etc/letsencrypt/live.
|
||||
|
||||
Make sure the user you use to run chasquid under ("mail" in the example
|
||||
config) can access the certificates and private keys.
|
||||
|
||||
|
||||
### Adding users
|
||||
|
||||
You can add users with:
|
||||
|
||||
```
|
||||
chasquid-util user-add user@domain
|
||||
```
|
||||
|
||||
This will also create the corresponding domain directory if it doesn't exist.
|
||||
|
||||
|
||||
### Checking your configuration
|
||||
|
||||
Run `chasquid-util print-config` to parse your configuration and display the
|
||||
resulting values.
|
||||
|
||||
|
||||
### Checking your setup
|
||||
|
||||
Run `smtp-check yourdomain.com`, it will check:
|
||||
|
||||
* MX DNS records.
|
||||
* SPF DNS records (will just warn if not present).
|
||||
* 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.
|
||||
|
||||
|
||||
### Greylisting, anti-spam and anti-virus
|
||||
|
||||
chasquid supports running a post-DATA hook, which can be used to perform
|
||||
greylisting, and run anti-spam and anti-virus filters.
|
||||
|
||||
The hook should be at `/etc/chasquid/hooks/post-data`.
|
||||
|
||||
|
||||
The one installed by default is a bash script supporting:
|
||||
|
||||
* greylisting using greylistd.
|
||||
* anti-spam using spamassassin.
|
||||
* anti-virus using clamav.
|
||||
|
||||
To use them, they just need to be available in your system.
|
||||
|
||||
For example, in Debian you can run the following to install all three:
|
||||
|
||||
apt install greylistd spamc clamdscan
|
||||
usermod -a -G greylist mail
|
||||
|
||||
|
||||
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
|
||||
needed.
|
||||
|
||||
48
docs/flow.md
Normal file
48
docs/flow.md
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
# Message flows
|
||||
|
||||
This document explains at a high level some parts of chasquid's message
|
||||
processing, in particular how messages flow through the system.
|
||||
|
||||
|
||||
## Message reception
|
||||
|
||||
- Client connects to chasquid on the smtp or submission ports, and issues
|
||||
HELO/EHLO.
|
||||
- Client optionally performs STARTTLS.
|
||||
- Client optionally performs AUTH.
|
||||
- Check that this is done over TLS.
|
||||
- Client sends MAIL FROM.
|
||||
- Check SPF.
|
||||
- Check connection security level.
|
||||
- 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 actual data, and ends it with '.'
|
||||
- Run the post-data hook. If the hook fails, return an error.
|
||||
- Parse the data contents to perform loop detection.
|
||||
- Add the required headers (Received, SPF results, post-data hook output).
|
||||
- Put it in the queue and reply success.
|
||||
|
||||
|
||||
## Queue processing
|
||||
|
||||
Before accepting a message:
|
||||
|
||||
- Create a (pseudo) random internal ID for it.
|
||||
- For each recipient, use the alias database to expand it, add the results to
|
||||
the list of final recipients (which may not be email).
|
||||
- Save the resulting envelope (with the final recipients) to disk.
|
||||
|
||||
Queue processing runs asynchronously, there's a goroutine for each message
|
||||
which does, in a loop:
|
||||
|
||||
- For each recipient which we have not delivered yet:
|
||||
- Attempt delivery.
|
||||
- Write to disk the results.
|
||||
- If there are mails still pending, wait for some time (incrementally).
|
||||
- When all the recipients have completed delivery, or enough time has passed:
|
||||
- If all were successful, remove from the queue.
|
||||
- If some failed, send a delivery status notification back to the sender.
|
||||
|
||||
45
docs/hooks.md
Normal file
45
docs/hooks.md
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
# Post-DATA hook
|
||||
|
||||
After completion of DATA, but before accepting the mail for queueing, chasquid
|
||||
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
|
||||
environment is detailed below.
|
||||
|
||||
If the exit status is 0, chasquid will move forward processing the command,
|
||||
and its stdout should contain headers which will be added to contents of
|
||||
the email (at the top).
|
||||
|
||||
Otherwise, chasquid will respond with an error, and the last line of stdout
|
||||
will be passed back to the client as the error message.
|
||||
If the exit status is 20 the error code will be permanent, otherwise it will
|
||||
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.
|
||||
|
||||
|
||||
## Environment
|
||||
|
||||
This hook will run as the chasquid user, so be careful about permissions and
|
||||
privileges.
|
||||
|
||||
The environment will contain the following variables:
|
||||
|
||||
- USER
|
||||
- SHELL
|
||||
- PATH
|
||||
- PWD
|
||||
- REMOTE_ADDR
|
||||
- MAIL_FROM
|
||||
- RCPT_TO (space separated)
|
||||
- AUTH_AS (empty if not completed AUTH)
|
||||
- ON_TLS (0 if not, 1 if yes)
|
||||
- FROM_LOCAL_DOMAIN (0 if not, 1 if yes)
|
||||
- SPF_PASS (0 if not, 1 if yes)
|
||||
|
||||
There is a 1 minute timeout for hook execution.
|
||||
It will be run at the config directory.
|
||||
|
||||
Reference in New Issue
Block a user