Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
slapos slapos
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Labels
    • Labels
  • Merge requests 122
    • Merge requests 122
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Environments
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value Stream
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Jobs
  • Commits
Collapse sidebar
  • nexedi
  • slaposslapos
  • Merge requests
  • !1726

Open
Created Feb 03, 2025 by Tom Niget@zdimensionDeveloper
  • Report abuse
Report abuse

Draft: Full mail server

  • Overview 102
  • Commits 17
  • Changes 53

This MR extends the existing mail-server SR to a full mail server bundle, including:

  • a user database (including aliases) backing both Postfix and Dovecot, that can be populated using shared instances (previously using Postgres, now using plain text per JP request)
  • a preconfigured Snappymail webmail (using the apache-php component)
  • the configuration needed to interact with the outside world

The last point revolves around two facts:

  • that we can't assume the machine hosting the instance to have a public IPv4 address, which is unfortunately still a requirement for receiving and sending mail since numerous providers can't handle IPv6 yet.
  • even if the machine had an IPv4 address, we can't rely on it to send mail: most providers use proprietary IP range lists for spam management, so reliable mail posting must be done through some kind of trusted relay. This can be done using third-party services such as Scaleway, Sendinblue or Rapidmail. Currently, SMTP2GO free tier is used.

A second SR is also included: mail-server-relay which only contains a Postfix server that acts as the middleman between the mail backends and a third-party mail delivery service. This allows using a single delivery service for multiple domains hosted on different servers, all handled in SlapOS.

State of things

Currently:

  • relay and mail domains are configurable
  • accounts are configured as shared instances (passwords are set through a link + token. this is unfinished and the way tokens are generated an updated will be redone)
  • network components (Postfix, Dovecot, Apache) are monitored and configurable
  • aliases are not implemented yet. They will be handled as shared instances too, but the exact details have not yet been decided

On the relay side, backends and domains are set in the instance configuration. Ultimately this will be done with shared instances too: the mail backends will request slaves from the relay. DNS configuration (MX records), however, will probably remain manual.

MR is WIP draft. Commits have been squashed multiple times, will squash and reorder ultimately.

Questions:

  • is a domain-per-backend setup what we want? This would mean that when requesting an account (as a shared instance) we need to choose which node this instance will live in (the one hosting the mail server). Otherwise we'd get accounts in the wrong servers.
  • receiving mails from the outside requires port 25 to be open on the mail-server-relay instance. This can be complicated if it's living on a Rapid.space instance. On the current testing setup this is on an OVH VPS

Example setup

  • two domains: mail1.example.com and mail2.example.com, each with a MX pointing to the IPv4 of mailrelay.lan
  • a third-party relay: 3rdpartyrelay.com configured with the IP (4 or 6) of mailrelay.lan
  • two mail-server instances: maildemo1.lan and maildemo2.lan (handling their respective domain)
  • one mail-server-relay instance: mailrelay.lan configured with both domains and their server's domain name, and the relay's domain name
flowchart LR;
  Dom1["mail1.example.com (MX)"]:::mxDomain;
  Dom2["mail2.example.com (MX)"]:::mxDomain;
  Relay["mailrelay.lan"]:::relay;
  Gmail["gmail.com"]:::remoteAddr;
  Hotmail["gmail.com"]:::remoteAddr;
  Third["3rdpartyrelay.com"]:::extRelay;
  Demo1["maildemo1.lan"]:::backendServer;
  Demo2["maildemo2.lan"]:::backendServer;

  Hotmail -->|sends mail to| Dom1;
  Hotmail -->|sends mail to| Dom2;
  Dom1 -->|MX points to| Relay;
  Dom2 -->|MX points to| Relay;
  Relay -->|forwards outbound to 3rd party| Third;
  Third -->|delivers to external server| Gmail;
  Relay <-->|handles mail1.example.com| Demo1;
  Relay <-->|handles mail2.example.com| Demo2;

  classDef localAddr     fill:#e0f7fa,stroke:#006064;
  classDef remoteAddr    fill:#f1f8e9,stroke:#33691e;
  classDef backendServer fill:#fff3e0,stroke:#e65100;
  classDef relay         fill:#fce4ec,stroke:#880e4f;
  classDef extRelay      fill:#ede7f6,stroke:#311b92;
  classDef mxDomain    fill:#e8eaf6,stroke:#3f51b5;

Example mail paths

From alice@mail1.example.com to bob@mail1.example.com:

flowchart LR;
  A["alice@mail1.example.com"]:::localAddr;
  B["maildemo1.lan"]:::backendServer;
  C["bob@mail1.example.com"]:::localAddr;

  A -->|SMTP submission| B;
  B -->|Local delivery| C;

  classDef localAddr     fill:#e0f7fa,stroke:#006064;
  classDef remoteAddr    fill:#f1f8e9,stroke:#33691e;
  classDef backendServer fill:#fff3e0,stroke:#e65100;
  classDef relay         fill:#fce4ec,stroke:#880e4f;
  classDef extRelay      fill:#ede7f6,stroke:#311b92;

From alice@mail1.example.com to charlie@mail2.example.com:

flowchart LR;
  A["alice@mail1.example.com"]:::localAddr;
  B["maildemo1.lan"]:::backendServer;
  C["mailrelay.lan"]:::relay;
  D["maildemo2.lan"]:::backendServer;
  E["charlie@mail2.example.com"]:::localAddr;

  A -->|SMTP submission| B;
  B -->|Relay to mailrelay| C;
  C -->|Delivery to backend| D;
  D -->|Local delivery| E;

  classDef localAddr     fill:#e0f7fa,stroke:#006064;
  classDef remoteAddr    fill:#f1f8e9,stroke:#33691e;
  classDef backendServer fill:#fff3e0,stroke:#e65100;
  classDef relay         fill:#fce4ec,stroke:#880e4f;
  classDef extRelay      fill:#ede7f6,stroke:#311b92;

From alice@mail1.example.com to david@gmail.com (outbound mail):

flowchart LR;
  A["alice@mail1.example.com"]:::localAddr;
  B["maildemo1.lan"]:::backendServer;
  C["mailrelay.lan"]:::relay;
  D["3rdpartyrelay.com"]:::extRelay;
  E["david@gmail.com"]:::remoteAddr;

  A -->|SMTP submission| B;
  B -->|Relay to mailrelay| C;
  C -->|Outbound relay| D;
  D -->|Delivery to recipient SMTP| E;

  classDef localAddr     fill:#e0f7fa,stroke:#006064;
  classDef remoteAddr    fill:#f1f8e9,stroke:#33691e;
  classDef backendServer fill:#fff3e0,stroke:#e65100;
  classDef relay         fill:#fce4ec,stroke:#880e4f;
  classDef extRelay      fill:#ede7f6,stroke:#311b92;

From etienne@hotmail.com to alice@mail1.example.com (inbound mail):

flowchart LR;
  A["etienne@hotmail.com"]:::remoteAddr;
  B["mailrelay.lan"]:::relay;
  C["maildemo1.lan"]:::backendServer;
  D["alice@mail1.example.com"]:::localAddr;

  A -->|SMTP connect| B;
  B -->|Routing by recipient domain| C;
  C -->|Local delivery| D;

  classDef localAddr     fill:#e0f7fa,stroke:#006064;
  classDef remoteAddr    fill:#f1f8e9,stroke:#33691e;
  classDef backendServer fill:#fff3e0,stroke:#e65100;
  classDef relay         fill:#fce4ec,stroke:#880e4f;
  classDef extRelay      fill:#ede7f6,stroke:#311b92;
Edited Apr 28, 2025 by Tom Niget
Assignee
Assign to
Reviewer
Request review from
None
Milestone
None
Assign milestone
Time tracking
Source branch: full-mail-server
GitLab Nexedi Edition | About GitLab | About Nexedi | 沪ICP备2021021310号-2 | 沪ICP备2021021310号-7