Postal Mail Server

repository·main·Indexed 12 days ago

https://github.com/postalserver/postal

An open-source, self-hosted mail server providing transactional and marketing email capabilities as an alternative to managed services like Sendgrid, Mailgun, or Postmark. It includes a full SMTP server with STARTTLS and PROXY protocol support, a background worker process for job and task management, and integrated Prometheus metrics for monitoring server performance and message throughput.

Tokens
13.1K
Snippets
20
Records
41
Agent score
89%

What's inside Postal

  1. Overview of Postal mail server

    main
    Postal is a complete, fully featured, open-source mail server designed for use by websites and web servers. It serves as a self-hosted alternative to managed services like Sendgrid, Mailgun, or Postmark, allowing you to manage transactional and marketing email directly on your own infrastructure.
  2. Configure Postal using a YAML file or environment variables

    main

    Postal supports two configuration methods:

    1. YAML Configuration File: Use a YAML file to define settings. To use a file, set the POSTAL_CONFIG_FILE_PATH environment variable to the path of your configuration file. Important: Your YAML file must include version: 2.
    2. Environment Variables: You can configure Postal entirely via environment variables without providing a configuration file.

    For a complete list of available environment variables, refer to environment-variables.md in the configuration directory.

    version: 2
    # ... other configuration keys
  3. Configure Postal for local development

    main

    When developing locally, you can use one of the following methods:

    • YAML File: Place your configuration file at config/postal/postal.yml.
    • Environment Variables: Place your configuration in a .env file located in the root of the application.

    Running tests

    By default, the test suite uses:

    • Configuration file: config/postal/postal.test.yml
    • Environment file: .env.test
  4. Identify clients using the PROXY protocol

    main

    If the client connection starts in the :preauth state, the SMTPServer::Client can use the PROXY command to identify the actual client IP address. This is useful when the SMTP server is behind a load balancer or proxy.

    The expected format is: PROXY <inet-protocol> <client-ip> <proxy-ip> <client-port> <proxy-port>

    Upon receiving a valid PROXY command, the client updates its @ip_address, transitions to the :welcome state, and returns a 220 response.

    PROXY TCP 192.168.1.1 10.0.0.1 54321 25
  5. Process the DATA command and message termination

    main

    When the DATA command is received, the client enters a state where it collects headers and the message body.

    • Header Parsing: The client parses headers until it encounters an empty line.
    • Message Termination: The end of the data stream is signaled by a single dot (.) on a line by itself, provided it is preceded by a carriage return (\r).
    • Completion: Once the dot is received, the client calls finished, which validates the message (size, loop detection, sender validity) and persists the message to the database as either incoming, outgoing, or a bounce depending on the transaction state and credentials.
  6. Configure DNS and Domain Verification

    main

    Set up the DNS records and settings required for Postal to function correctly with email domains.

    • DNS_MX_RECORDS: Default MX records (default: ["mx1.postal.example.com", "mx2.postal.example.com"]).
    • DNS_SPF_INCLUDE: Location of the SPF record.
    • DNS_RETURN_PATH_DOMAIN: The return path hostname.
    • DNS_ROUTE_DOMAIN: Domain for hosting route-specific addresses.
    • DNS_TRACK_DOMAIN: CNAME for tracking domains.
    • DNS_DKIM_IDENTIFIER: Identifier for DKIM keys (default: postal).
    • DNS_DOMAIN_VERIFY_PREFIX: Prefix for TXT record verification (default: postal-verification).
    • DNS_CUSTOM_RETURN_PATH_PREFIX: Prefix for external domains pointing to the Postal return path (default: psrp).
    • DNS_TIMEOUT: DNS resolution timeout in seconds (default: 5).
  7. Configure SMTP Server TLS and Security

    main

    Configure how the SMTP server handles encryption and security settings.

    • SMTP_SERVER_TLS_ENABLED: Enable TLS for the SMTP server (requires certificate).
    • SMTP_SERVER_TLS_CERTIFICATE_PATH: Path to the TLS certificate (default: $config-file-root/smtp.cert).
    • SMTP_SERVER_TLS_PRIVATE_KEY_PATH: Path to the TLS private key (default: $config-file-root/smtp.key).
    • SMTP_SERVER_TLS_CIPHERS: Override ciphers to use for SSL.
    • SMTP_SERVER_SSL_VERSION: Supported SSL versions (default: SSLv23).
    • SMTP_SERVER_PROXY_PROTOCOL: Enable proxy protocol v1 for use behind load balancers.
  8. Configure Message Inspection (Rspamd, SpamAssassin, ClamAV)

    main

    Enable and configure external services for scanning messages for spam or viruses.

    Rspamd

    • RSPAMD_ENABLED: Enable rspamd.
    • RSPAMD_HOST: Rspamd hostname (default: 127.0.0.1).
    • RSPAMD_PORT: Rspamd port (default: 11334).
    • RSPAMD_SSL: Enable SSL for Rspamd.
    • RSPAMD_PASSWORD: Rspamd password.

    SpamAssassin

    • SPAMD_ENABLED: Enable SpamAssassin.
    • SPAMD_HOST: SpamAssassin hostname (default: 127.0.0.1).
    • SPAMD_PORT: SpamAssassin port (default: 783).

    ClamAV

    • CLAMAV_ENABLED: Enable ClamAV.
    • CLAMAV_HOST: ClamAV host (default: 127.0.0.1).
    • CLAMAV_PORT: ClamAV port (default: 2000).
  9. How the Postal Worker process works

    main

    The Postal Worker process handles all background tasks, including messages, webhooks, and administrative tasks. It manages two distinct types of work:

    1. Jobs: Continuous monitoring of a database table or queue for new items. Jobs poll every 5 seconds by default and can run across multiple threads to process work concurrently.
    2. Scheduled Tasks: Administrative tasks executed on a rough schedule. A single thread within the worker process attempts to acquire the tasks role. If successful, it runs all due tasks and reschedules them. Workers that fail to acquire the role still attempt to acquire a lock to ensure continuity if the current holder disappears.

    Graceful Shutdown: The worker process runs until it receives a TERM or INT signal. Upon receiving these signals, it attempts to shut down gracefully by completing any currently in-flight jobs before exiting.

  10. Configure Proxy Protocol for SMTP

    main

    If your SMTP server is running behind a load balancer or proxy (like HAProxy) that supports the PROXY protocol, you must enable this setting in Postal::Config.smtp_server.proxy_protocol?.

    When enabled, the server delays the SMTP welcome process (220 ...) until the proxy protocol header is parsed, ensuring the correct client IP address is identified for logging and security purposes.

  11. Configure OIDC Authentication

    main

    Enable OpenID Connect (OIDC) for user authentication.

    • OIDC_ENABLED: Enable OIDC authentication.
    • OIDC_LOCAL_AUTHENTICATION_ENABLED: If true, users can still login with passwords. If false, only OIDC is available.
    • OIDC_NAME: Name of the provider in the UI.
    • OIDC_ISSUER: The OIDC issuer URL.
    • OIDC_IDENTIFIER: Client ID.
    • OIDC_SECRET: Client secret.
    • OIDC_SCOPES: Scopes to request (default: ["openid", "email"]).
    • OIDC_UID_FIELD: Field used for UID (default: sub).
    • OIDC_EMAIL_ADDRESS_FIELD: Field used for email (default: email).
    • OIDC_NAME_FIELD: Field used for name (default: name).
    • OIDC_DISCOVERY: Enable discovery via .well-known/openid-configuration (default: true).