Skip to content

Dockerized SMTP relay solution using Postfix and Cyrus SASL

License

Notifications You must be signed in to change notification settings

mirawara/smtp-relay

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SMTP Relay

This repository provides a complete, Dockerized SMTP relay solution using Postfix and Cyrus SASL. It allows you to securely relay emails from client applications to an upstream SMTP server, with flexible authentication and TLS encryption options.

Overview

An SMTP relay forwards email messages from sending clients to another SMTP server. This is useful for:

  • Centralizing email delivery from multiple applications or services.
  • Securing authentication for client applications by offloading to a dedicated relay.
  • Enforcing transport security with TLS for both incoming client connections and outgoing relay connections.

Repository Contents

  • Dockerfile
    • Builds an Alpine-based image including Postfix (SMTP server) and Cyrus SASL (authentication).
    • Prepares Postfix directories, configures permissions, and exposes SMTP ports.
  • docker-entrypoint.sh
    • Validates and injects environment variables for relay and client authentication.
    • Generates SASL user databases, configures Postfix (main.cf and master.cf) dynamically based on variables.
    • Starts Postfix in the foreground, logging to stdout.
  • docker-compose.yml
    • Generic Docker Compose setup for running the SMTP relay container.
    • Exposes ports for plain/STARTTLS and SMTPS.
    • Defines environment variables, TLS volume mounts, and a persistent mail spool.
  • docker-compose-oauth2.yml

Detailed Features

Configurable Authentication Methods

  • Outgoing Relay (RELAY_AUTH_METHOD):
    • plain: No TLS enforced, simple authentication.
    • starttls: Opportunistic or required STARTTLS on port 587.
    • smtps: Implicit SSL/TLS on port 465.
  • Incoming Client (INCOMING_AUTH_METHOD):
    • plain: Allows unencrypted SMTP (port 25).
    • starttls: Clients must issue STARTTLS before authentication.
    • smtps: Implicit TLS on port 465 for maximum security.

TLS Encryption

  • Uses your provided fullchain.pem and privkey.pem certificates.
  • Ensures encrypted transport for client connections and/or relay connections.
  • Prevents eavesdropping and man-in-the-middle attacks.

SASL User Management

  • Automatically creates SASL user entries from INCOMING_USERNAME and INCOMING_PASSWORD.
  • Supports optional SASL realm (REALM) for multi-tenant setups.

Persistent Mail Queue

  • A Docker volume smtp-spool persists undelivered messages across container restarts.
  • Useful for handling temporary upstream outages without losing messages.

Why OAuth2 Integration Matters

email-oauth2-proxy is an excellent solution for integrating the new mandatory authentication systems from Google and Microsoft with legacy SMTP clients. However, in some cases, security can be compromised. For example, when using Google APIs to send emails with the secret.json (service account secret), any password is accepted as valid, which is not secure. This approach adds an extra layer but it does fully solve the problem.

Additionally, at the time of writing this README, email-oauth2-proxy has a bug where it fails if the client sends EHLO localhost during the SMTP protocol handshake. Many clients do this — Gatus, for instance - and with smtp-relay the problem is solved.

Usage

Prerequisites

  • Docker ≥ 20.10
  • Docker Compose ≥ 1.29
  • Valid TLS certificates (fullchain.pem, privkey.pem) for STARTTLS and SMTPS

Generic Relay

cp /path/to/fullchain.pem ./
cp /path/to/privkey.pem ./
docker-compose -f docker-compose.yml up -d

Clients connect to:

  • Port 2525 for plain or starttls.
  • Port 2465 for smtps.

Relay with OAuth2 Proxy

You can refer to this repo.

Environment Variables

Variable Description
RELAY_HOST Upstream SMTP host (e.g., smtp.gmail.com or your OAuth2 proxy).
RELAY_PORT Upstream SMTP port (587, 465, or 25).
RELAY_USERNAME Username for upstream authentication.
RELAY_PASSWORD Password for upstream authentication.
RELAY_AUTH_METHOD plain / starttls / smtps for relay.
INCOMING_AUTH_METHOD plain / starttls / smtps for client connections.
INCOMING_USERNAME SASL username for clients.
INCOMING_PASSWORD SASL password for clients.
REALM Optional SASL realm for multi-tenant services.

Volumes

  • smtp-spool: /var/spool/postfix persists the mail queue.
  • fullchain.pem, privkey.pem: Mounted read-only to /etc/ssl/certs & /etc/ssl/private.

Usage

Just treat it as a normal smtp server but the username must be INCOMING_USERNAME@REALM.

Extending & Troubleshooting

  • Modify SMTP parameters with postconf commands in docker-entrypoint.sh.
  • To enable additional SASL mechanisms, adjust /etc/sasl2/smtpd.conf.
  • Check logs via docker logs smtp_relay for runtime diagnostics.

TODO

  • Implement no password authentication for complete legacy smtp clients and servers compatibility.

📄 License

This project is licensed under the MIT License.

You are free to use, modify, and distribute this software, as long as the original copyright and license notice are included.

Buy me a coffee ☕

paypal.me/mirawara


© Lorenzo Mirabella - SMTP Relay

About

Dockerized SMTP relay solution using Postfix and Cyrus SASL

Resources

License

Stars

Watchers

Forks

Contributors