Skip to content

scanner/as_email_service

Repository files navigation

Build Status Code style: black Code style: prettier

Apricot Systematic Email Service (as_email_service)

A Django app and smtp relay service for working with 3rd party email services (well, just Postmark initially. Also supports delivery to an MH email box on the same machine (for use with asimap hosted on the same machine).

Table of Contents

Setup

  1. Linux host running docker with at least 2gb of RAM to run all of the services. More if you have a lot of email servers at postmark that this is handling email for.

Configuration

The docker-compose.yml file in this repo has all that is necessary to run the system services. Most configuration for dealing with postmark and users is handled directly within the django-admin. For setting up the service itself you will need a .env file with the necessary values filled in.

Here is a minimal set of env. vars you will need to set in the .env for your services:

# This project uses a .env file for basic configuration and passing secrets to
# the AS Email Service.
#
# Naturally due to the sensitive nature of this file access to it must be
# carefully controlled.
#
# This is a get-the-thing-off-the-ground setup.
#
# The following env. vars are required for the service to function.
#
DJANGO_SECRET_KEY=<your sites secret key here>
EMAIL_BACKEND=<backend to use>
ANYMAIL="key1=value1,key2=value2"
SITE_NAME=your_email_server.your.domain
DEFAULT_FROM_EMAIL = "you@example.com"
SERVER_EMAIL = "your-server@example.com"

# JSON mapping of provider name to its API keys. Each provider has an
# "account_api_key" plus per-domain sending keys.
# Must be compact single-line JSON (docker-compose does not support multiline
# .env values). Tip: keep a readable JSON file and generate this with:
#   jq -c '.' email_server_tokens.json >> .env
#
EMAIL_SERVER_TOKENS={"forwardemail":{"account_api_key":"<forwardemail-account-api-key>","example.com":"<forwardemail-account-api-key>"},"postmark":{"account_api_key":"<postmark-account-api-token>","example.com":"<postmark-server-api-token>","example.org":"<postmark-server-api-token>"}}

# The container-internal paths where volumes are mounted. These rarely
# need to change.
#
DATABASE_URL=sqlite:////mnt/db/as_email_service.db
EMAIL_SPOOL_DIR=/mnt/spool
MAIL_DIRS=/mnt/mail_dirs

# External (host) directories mounted into the containers. Set these to
# wherever you want data stored on the host.
#
HOST_SPOOL_ROOT=/home/mailapps/spool
HOST_MAIL_ROOT=/home/mailapps/mail_dirs
HOST_DB_DIR=/home/mailapps/dbs
HOST_SPAMA_DIR=/home/mailapps/spama

# as_email expects to find ssl_crt.pem and ssl_key.pem in this directory.
#
HOST_SSL_DIR=/home/mailapps/ssl

# Email addresses users forward misclassified messages to for SpamAssassin
# training. Both must be set to enable user-driven training. See
# docs/sa-training.md for setup instructions.
#
# SPAM_TRAINING_ADDRESS=spam@mail.example.com
# NOT_SPAM_TRAINING_ADDRESS=not-spam@mail.example.com

# What docker tag to pull and run
#
RELEASE_VERSION=latest

API Documentation

The REST API is documented via OpenAPI 3.0. The full reference is available in docs/api.md and the machine-readable spec in docs/openapi.yaml.

When the development server is running you can also browse the interactive docs:

  • Swagger UI: /as_email/api/schema/swagger-ui/
  • ReDoc: /as_email/api/schema/redoc/

To regenerate the docs after making API changes:

make api-docs

Administration

SpamAssassin Training

The service supports both initial corpus training (running sa-learn directly against a spam/ham directory) and ongoing user-driven training (users forward misclassified messages to dedicated addresses, which a management command processes and stages for sa-learn).

See docs/sa-training.md for full setup and operational instructions.

fail2ban Integration

The SMTP daemon writes structured security log lines that fail2ban can monitor to automatically ban IPs performing brute-force attacks, flooding connections, or using nonexistent accounts. Six jails cover different attack patterns with configurable thresholds and ban durations.

See docs/fail2ban-integration.md for setup instructions and configuration details.

Design

Local Development

NOTE: This project uses mkcert to generate and use SSL certificates for development. See https://github.com/FiloSottile/mkcert for details. The Makefile and supporting scripts assume that you have already run mkcert -install to setup the local trusted CA for development.

Python Version Management

The canonical Python version is defined in .python-version at the project root. uv and make build read it automatically.

To bump the Python version:

  1. Update requires-python in pyproject.toml to the new x.y.z version
  2. Update the image: field in .drone.yml to python:<x.y.z>
  3. Run make uv-sync to rebuild the local venv

Required Installed Packages

Even if you are not going to download new python and node modules you need at least these packages installed for local development:

  • python (3.13 or greater)
  • npm
  • docker

Contributing

License

[./LICENSE](BSD 3-Clause License)

Favicon

This favicon was generated using the following graphics from Twitter Twemoji:

About

A Django app and smtp relay service for working with 3rd party email services and asimap

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors