Overview

This article documents a practical pattern for reliable outbound mail in a small network:

  • A dedicated mail relay host (hl-mail) running Postfix
  • Workstations using msmtp (via msmtp-mta) as a lightweight sendmail-compatible client
  • Postfix relays mail to an upstream provider (a “smart host”) using SASL authentication and (typically) STARTTLS

All hostnames, IP addresses, and email addresses are anonymised. Replace placeholders like:

  • hl-mail.lan (mail relay host)
  • mail.example.com (upstream SMTP provider / smart host)
  • user@example.com (mailbox)
  • 192.168.x.x (LAN IPs)

Architecture

Workstation(s)
sendmailmsmtp → SMTP to hl-mail.lan:25

Mail relay (hl-mail)
Postfix receives mail from LAN → relays upstream to mail.example.com:587 (or 465, depending on provider)


Part 1: Build the Mail Relay (hl-mail) with Postfix

Install Postfix

On hl-mail:

sudo apt update
sudo apt install postfix libsasl2-modules ca-certificates

During install, choose “Internet Site” or “Satellite system” depending on preference. We’ll explicitly configure next.

Set a stable hostname

sudo hostnamectl set-hostname hl-mail

Make sure DNS or /etc/hosts resolves hl-mail.lan correctly on your LAN.


Postfix configuration

Postfix’s main config is:

  • /etc/postfix/main.cf
# Identity
myhostname = hl-mail.lan
mydomain = lan
myorigin = $myhostname

# Listen on all interfaces (LAN relay)
inet_interfaces = all
inet_protocols = ipv4

# Accept mail for localhost and this host only (adjust if you host local mailboxes)
mydestination = $myhostname, localhost.$mydomain, localhost

# Define which networks can relay through this box (YOUR LAN)
mynetworks = 127.0.0.0/8, 192.168.0.0/16

# Don’t be an open relay
smtpd_recipient_restrictions =
    permit_mynetworks,
    reject_unauth_destination

# Upstream smart host (provider)
relayhost = [mail.example.com]:587

# --- TLS for outbound SMTP (modern settings) ---
smtp_tls_security_level = encrypt
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtp_tls_loglevel = 1

# --- SASL auth for outbound SMTP ---
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous

# Compatibility note:
# If you see warnings about legacy smtp_use_tls, replace with smtp_tls_security_level as above.

SASL credentials file

Create /etc/postfix/sasl_passwd:

sudo nano /etc/postfix/sasl_passwd

Add:

[mail.example.com]:587 user@example.com:APP_PASSWORD_OR_SMTP_PASSWORD

Secure it and build the hash DB:

sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd

Reload Postfix:

sudo systemctl restart postfix

Confirm Postfix is listening on port 25 (LAN)

sudo ss -lntp | grep ':25'

You should see master / smtpd bound to 0.0.0.0:25 (or your LAN interface).


Testing relayhost connectivity

From hl-mail:

nc -vz mail.example.com 587

If you can’t reach your provider, fix firewall/DNS first.


Common Postfix queue troubleshooting

Check the queue:

sudo postqueue -p

Flush the queue (retry delivery):

sudo postqueue -f

Watch logs:

sudo tail -f /var/log/mail.log

Typical failure: SASL authentication failed (535)

A classic symptom looks like:

SASL authentication failed; server mail.example.com[...] said: 535 5.7.8 Authentication failed.

Fixes usually are:

  • Wrong username (typo)
  • Wrong password (use an app password if your provider requires it)
  • Wrong port / TLS mode (587 STARTTLS vs 465 implicit TLS)

Part 2: Configure Workstations with msmtp (sendmail-compatible)

The workstation goal is simple:

  • Apps/scripts write to sendmail
  • sendmail is provided by msmtp-mta
  • msmtp forwards mail to hl-mail.lan:25

Install msmtp

On each workstation:

sudo apt update
sudo apt install msmtp msmtp-mta

Confirm sendmail exists:

ls -l /usr/sbin/sendmail
/usr/sbin/sendmail --version

It should report msmtp version ....


Per-user config: ~/.msmtprc

Create:

nano ~/.msmtprc
chmod 600 ~/.msmtprc

Example config (LAN relay, no auth, no TLS on LAN):

defaults
auth           off
tls            off
tls_starttls   off
logfile        ~/.msmtp.log

account default
host           hl-mail.lan
port           25
from           user@example.com

Test:

echo -e "Subject: msmtp test\n\nHello" | sendmail user@example.com

Or:

echo -e "Subject: msmtp test\n\nHello" | msmtp --debug user@example.com

File permissions gotchas (msmtp logging)

If you see:

cannot log to /var/log/msmtp.log: Permission denied

Use a per-user logfile (recommended):

logfile ~/.msmtp.log

Or remove logging if you prefer.


System-wide config: /etc/msmtprc (optional)

If you want a single config for all users, use /etc/msmtprc. For LAN relay with no auth, it’s safe:

defaults
auth off
tls off
tls_starttls off

account default
host hl-mail.lan
port 25
from user@example.com

Debugging “mail never arrived” cases

1) Confirm workstation can reach hl-mail port 25

nc -vz hl-mail.lan 25

2) Use msmtp debug to see SMTP dialogue

echo -e "Subject: debug\n\nHello" | msmtp --debug user@example.com

3) Check Postfix logs on hl-mail

sudo tail -f /var/log/mail.log

SMTP size limits (552 “message file too big”)

If you hit:

552 5.3.4 Error: message file too big

You’re exceeding the upstream provider’s message size limit.

Fixes:

  • Email a summary + last N lines
  • Store full logs locally
  • (Optional) compress and attach (still counts toward size)

Generate a short report and pipe to sendmail:

{
  echo "To: user@example.com"
  echo "Subject: Backup report [OK]"
  echo
  echo "Summary..."
  tail -n 200 /path/to/full.log
} | /usr/sbin/sendmail -t

Security Notes

  • Keep mynetworks tight (only your LAN ranges)
  • Prefer app-passwords for upstream auth
  • Use STARTTLS upstream (smtp_tls_security_level=encrypt)
  • Don’t expose unauthenticated port 25 to the internet

Wrap-up

With Postfix as a local smart host and msmtp on workstations, you get:

  • Reliable outbound delivery
  • “sendmail” compatibility for scripts and tooling
  • Centralised relay configuration
  • Easier troubleshooting (single mail-log source)

Next steps could include SPF/DKIM/DMARC (if sending as your own domain) and alerting on repeated delivery failures.