WEB WORKBENCH

My Postfix SMTP Relay Build

A collection of systems, experiments, and builds

Introduction

This guide documents the build of an outbound SMTP relay server using Ubuntu and Postfix. The purpose of this server is to allow websites and applications to send email through an authenticated SMTP connection.

This is not a mailbox server.
It does not provide:
IMAP mailboxes
POP3 services
Email storage
The mail flow is:
Websites / Applications > Postfix SMTP Relay > Internet Mail Servers

Install Postfix

Update Ubuntu:
sudo apt update

Install Postfix:
sudo apt install postfix -y

During installation choose:
Internet Site

Set the mail name:
Example:
mail.webworkbench.co.uk

Configure Postfix

Edit:
sudo nano /etc/postfix/main.cf

Set the hostname:
myhostname = mail.webworkbench.co.uk

Set the origin:
myorigin = /etc/mailname

Listen on all interfaces:
inet_interfaces = all

Use IPv4 only:
inet_protocols = ipv4

Because this is a relay server and not a mailbox server, do not accept local mail domains:
mydestination =

Relay Security

The server must not become an open relay.
Add:
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination

This allows:
Trusted networks
Authenticated SMTP users
and rejects unauthorised relay attempts.

TLS Certificate

Using Let's Encrypt:
smtpd_tls_cert_file=/etc/letsencrypt/live/mail.webworkbench.co.uk/fullchain.pem

smtpd_tls_key_file=/etc/letsencrypt/live/mail.webworkbench.co.uk/privkey.pem

smtpd_tls_security_level=encrypt

Restart Postfix

Restart:
sudo systemctl restart postfix

Check status:
sudo systemctl status postfix

Check SMTP listener:
sudo ss -ltnp | grep :25

Sender Rewriting (Optional)

Some applications send email using incorrect local usernames.
Example:
Instead of:
wordpress@server

you may want:
no-reply@webworkbench.co.uk

Create the sender map:
sudo nano /etc/postfix/sender_canonical

Example:
@webworkbench.co.uk no-reply@webworkbench.co.uk

Create the database:
sudo postmap /etc/postfix/sender_canonical

Enable in:
/etc/postfix/main.cf

Add:
sender_canonical_maps = hash:/etc/postfix/sender_canonical

Restart:
sudo systemctl restart postfix

Enable SMTP Submission Port 587 and 465

Edit:
sudo nano /etc/postfix/master.cf

Find:
#submission inet n - y - - smtpd (port 587)
Find:
#submissions inet n - y - - smtpd (port 465)

Enable: in both eg
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject

Trusted Relay Networks

Set trusted networks:
mynetworks = 127.0.0.0/8, SERVER_IP

Example:
mynetworks = 127.0.0.0/8, 51.xxx.xxx.xxx

Restart:
sudo systemctl restart postfix

DKIM Signing

Install OpenDKIM:
sudo apt install opendkim opendkim-tools -y

Create a key directory:
sudo mkdir -p /etc/opendkim/keys/webworkbench.co.uk

Generate a DKIM key:
cd /etc/opendkim/keys/webworkbench.co.uk

sudo opendkim-genkey -s mail -d webworkbench.co.uk

This creates:
mail.private
mail.txt

The TXT record from mail.txt is added to DNS.

OpenDKIM Configuration

OpenDKIM uses:
/etc/opendkim/KeyTable

/etc/opendkim/SigningTable

/etc/opendkim/TrustedHosts

Example KeyTable:
mail._domainkey.webworkbench.co.uk webworkbench.co.uk:mail:/etc/opendkim/keys/webworkbench.co.uk/mail.private

Example SigningTable:
*@webworkbench.co.uk mail._domainkey.webworkbench.co.uk

Trusted hosts:
127.0.0.1

localhost

mail.webworkbench.co.uk

Connect OpenDKIM to Postfix

Add:
smtpd_milters = local:/run/opendkim/opendkim.sock

non_smtpd_milters = local:/run/opendkim/opendkim.sock

Allow Postfix access:
sudo usermod -aG opendkim postfix

Secure keys:
sudo chmod 600 /etc/opendkim/keys/*/*.private

sudo chown -R opendkim:opendkim /etc/opendkim/keys

Restart:
sudo systemctl restart opendkim

sudo systemctl restart postfix

Check socket:
sudo ls -l /run/opendkim/opendkim.sock

Adding Additional Sending Domains

For each additional domain:
Create directory:
sudo mkdir -p /etc/opendkim/keys/domain.com

Generate key:
sudo opendkim-genkey -s mail -d domain.com

Add:
Private key path to KeyTable
Sender rule to SigningTable
DKIM TXT record to DNS

Final Working Postfix Configuration

After completing the setup and troubleshooting, this was the final working configuration. To view the active Postfix configuration: postconf -n

Example output:
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
biff = no
broken_sasl_auth_clients = yes
compatibility_level = 3.9
inet_interfaces = all
inet_protocols = ipv4
mailbox_command =
mailbox_size_limit = 0
mydestination =
myhostname = mail.webworkbench.co.uk
mynetworks = 127.0.0.0/8, SERVER_IP (eg 1.2.3.4)
myorigin = /etc/mailname
non_smtpd_milters = local:/run/opendkim/opendkim.sock
relayhost =
sender_canonical_maps = hash:/etc/postfix/sender_canonical
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtp_tls_security_level = may
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
smtpd_milters = local:/run/opendkim/opendkim.sock
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination
smtpd_relay_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
defer_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_sasl_path = smtpd
smtpd_sasl_security_options = noanonymous
smtpd_sasl_type = cyrus
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.webworkbench.co.uk/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.webworkbench.co.uk/privkey.pem
smtpd_tls_security_level = encrypt

Reminder

This configuration provides:
✓ SMTP relay
✓ SMTP authentication
✓ TLS encryption
✓ DKIM signing
✓ SPF/DKIM/DMARC compatibility
It does not provide:
✗ Mailboxes
✗ IMAP
✗ POP3
Those are separate services.

This configuration is the final working state from my own server build. Your environment may differ depending on Ubuntu version, Postfix version, authentication method, DNS setup and whether a control panel such as Virtualmin is managing parts of the configuration.

Found This Useful?

If you found this useful, please consider sharing it.

InfoAbout Cookie infoContactFAQsTermsDisclosure