LINUXOR.SK ... open source notes ...

Email system on Postfix - encrypted mail for a management infrastructure

category: solutionz · date: 2019-01-01 · updated: 2026-10-02 · author: LALA

Between 2017 and 2019 I designed, built and ran the email system of the management infrastructure of a network service provider. Its users were mostly not people. Servers, applications and appliances sent alerts and notifications through it, and what they sent described the inside of the infrastructure, so a message was not allowed to leave unless the sender was known, was allowed to write to that destination, and the content was encrypted for the person who would read it.

This Solution is the whole of that system. In each of two sites: a pair of Postfix servers behind one Keepalived address, Dovecot as their authentication back end, senders authorized by Active Directory groups over LDAPS, a content filter written in Bash that encrypts every message with S/MIME or PGP/MIME, two relay servers that deliver to the internet through NAT, and a third internal server with the mailboxes and Roundcube webmail. It started in 2017 as one internal server and one relay; the highly available design is from 2019.

noteBuilt on RHEL 7 with Postfix 2.10 and Dovecot 2.2. Every configuration file and script is shown as it ran and then checked against the releases current on 2026-10-02: Postfix 3.11, Dovecot 2.4, Keepalived 2.4, Roundcube 1.7, RHEL 10. The system is anonymized: sites, names, domains, addresses, people and organisations are replaced, and every secret is a placeholder. The configuration contains mistakes; they are reported where they were found, not corrected.

The system in one picture

mermaid
flowchart TB
  clients["Mail clients: servers, applications, appliances"]
  users["Administrators and operators"]
  subgraph site["Site 2, DC2"]
    vip["VIP DC2-S-XCMSX001, SMTP 25 with STARTTLS and SMTPS 465"]
    subgraph pair["Internal pair, Keepalived"]
      x1["DC2-A-VCMSX001: Postfix, Dovecot SASL, encryption filter"]
      x2["DC2-B-VCMSX001: Postfix, Dovecot SASL, encryption filter"]
      x1 <-. "keys and certificates, rsync" .-> x2
    end
    ad["Active Directory, LDAPS"]
    x3["DC2-A-VCMSX002: mailboxes, Dovecot, Roundcube"]
    r1["DC2-A-VCMSR001: relay, primary"]
    r2["DC2-B-VCMSR001: relay, fallback"]
  end
  inet["Mail servers on the internet"]
  clients --> vip
  vip --> x1
  vip -.-> x2
  x1 --> ad
  x1 -- "own domain" --> x3
  x1 -- "other domains" --> r1
  x1 -.-> r2
  r1 -- "NAT" --> inet
  r2 -- "NAT" --> inet
  users -- "HTTPS" --> x3

The fictional environment

Every Article and every Config document uses the same names and addresses.

ThingSite 1, productionSite 2, pre-production
Internal pairDC1-A-VCMSX001, DC1-B-VCMSX001DC2-A-VCMSX001, DC2-B-VCMSX001
Virtual address of the pairDC1-S-XCMSX001, 10.11.19.33DC2-S-XCMSX001, 10.12.19.33
Mailbox and webmail serverDC1-A-VCMSX002DC2-A-VCMSX002
Relay serversDC1-A-VCMSR001, DC1-B-VCMSR001DC2-A-VCMSR001, DC2-B-VCMSR001
Mail domain, also the directory domainad.example.netad-dc2.example.net
Internal mail network, VLAN 116810.11.19.32/2810.12.19.32/28
Relay network, VLAN 117210.11.19.64/2810.12.19.64/28
Public addresses of the relays198.51.100.44, 198.51.100.48203.0.113.44, 203.0.113.48
Host namesadm.example.netadm.example.net

Site 2 is the worked example throughout, because the archived configuration is that of its five servers. Site 1 is described from the design. People in mail addresses are user01 and up, partner organisations in group names are PARTNER1 and PARTNER2, and the marks CFG-ON and CFG-OFF in the comments of a file are mine: this setting was turned on, or off, by me.

Articles

Read in this order; it goes from why, through how it was built, to how it was run.

#ArticleWhat it covers
1Requirements and conceptWhat the system had to do, the first concept of 2017, and what the highly available one changed
2Logical designNaming, components and their jobs, service accounts, the four kinds of clients, the path of a message
3Network, DNS and firewallTwo VLANs, NAT, the public records, the flows, and design tables that disagree with the servers
4Virtual machines and OS buildPlacement, sizing, file systems, packages, local accounts, three SELinux modules
5Internal servers: PostfixListeners, routing, the restriction lists step by step, and a check that port 465 skips
6Active Directory integrationAccounts, groups and roles, and the five LDAP maps filter by filter
7Dovecot authenticationDovecot as the SASL back end of Postfix, two LDAP password databases, what is stock and what is local
8TLS and certificatesThe internal CA, a certificate per server, which hops are encrypted and which are not
9Automatic email encryptionThe Bash content filter: S/MIME, PGP/MIME, exception lists, and where the script differs from its design
10High availability and key synchronizationThe Keepalived address, what fails over and what does not, two rsync services that can undo each other
11Relay serversTwo interfaces, static routes, NAT, header cleaning, and names that do not match the DNS
12Mailbox serverVirtual mailboxes, Dovecot delivery into Maildir, IMAP for the webmail
13WebmailRoundcube on a hardened Apache with PHP and MariaDB
14Accounts, clients and operationsGiving an account mail, client settings, monitoring, logging, known issues, what I would do differently

Configuration

Each document holds one file as it ran, with comments, the differences between the hosts that carry it, and a check against the current release. Files that are mostly the distribution's own comments are shown with every active line and without those comments.

Postfix, internal pair

Postfix, LDAP maps against Active Directory

Dovecot

Encryption filter

High availability and synchronization

Relay servers

Mailbox server

Webmail

Operating system

What the write-up found

Reading the archived configuration against the design, seven years later, turned up things the design does not say. Each is told in its Article.

FindingWhere
The listener on port 465 replaces the recipient restrictions, so the group check for sending to external domains does not apply there5
The sender-login check stands behind a rule that has already accepted the sender5
Clients with neither TLS nor authentication, which the requirements promised to serve, cannot send through the pair14
The relays offer no STARTTLS, so the hop from the pair to the relay is not encrypted8
The filter encrypts S/MIME with the default cipher of openssl smime, which was triple DES at the time9
Two synchronization services with --delete push in both directions10
The relays introduce themselves with names that the public DNS of the design does not hold11
IMAP listens on every IPv4 address of the mailbox server, without TLS, where the design says localhost12
← solutionz