Postfix Null Client
A desktop running Kubuntu generates mail. Cron jobs send output. System tools send alerts. Package managers notify of security updates. By default, all of this goes into a local mailbox that nobody reads, or gets dropped entirely because there is no mail transport configured. Neither is useful.
A null client solves this cleanly. Postfix is configured in its simplest possible mode: listen only on localhost, accept no incoming mail, deliver nothing locally, and relay everything to your mail server. System mail from the desktop lands in your inbox alongside everything else.
The name comes from the fact that the client has no mail of its own to receive. It is a zero-configuration mail relay for system-generated messages only.
Installation
Postfix is available in the standard Ubuntu repositories. When the package manager asks about mail server configuration during installation, choose No configuration. The null client configuration is minimal enough that starting from scratch is cleaner than modifying the defaults the installer would apply.
sudo apt install postfix libsasl2-modules
If Postfix is already installed with a different configuration, that is fine. The postconf commands below will overwrite whatever is currently set.
Configuration
All configuration is done via postconf, which modifies /etc/postfix/main.cf directly and handles escaping correctly. Do not edit main.cf by hand unless you know what you are doing.
Core null client settings
# Disable backwards compatibility warnings
sudo postconf compatibility_level=3.6
# Set the fully qualified hostname of this machine
sudo postconf myhostname=$(hostname -f)
# Listen only on localhost
sudo postconf inet_interfaces=loopback-only
# Deliver no mail locally
sudo postconf mydestination=
# Map all local addresses to your mail account
sudo postconf "virtual_alias_maps=regexp:/etc/postfix/virtual_alias"
# Relay all mail to your internal mail server on the submission port
sudo postconf "relayhost=[mail.yourdomain.net]:submission"
Authentication
Your mail server requires authenticated connections on the submission port. Configure SASL authentication so Postfix can log in:
sudo postconf smtp_sasl_auth_enable=yes
sudo postconf smtp_sasl_security_options=noanonymous
sudo postconf "smtp_sasl_password_maps=hash:/etc/postfix/smtp_password"
TLS
The connection to the mail server must be encrypted. Use secure level, which requires a valid certificate and refuses to deliver if TLS is unavailable:
sudo postconf smtp_tls_security_level=secure
sudo postconf smtp_tls_CAfile=/etc/ssl/certs/ca-certificates.crt
sudo postconf smtp_tls_loglevel=1
If your mail server uses a certificate signed by your internal CA (which it should, once the CA section of this series is complete), you need to trust that CA. Add it to the system trust store:
sudo cp /path/to/your-root-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
Verify the CA is now trusted:
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt \
/path/to/mail.yourdomain.net.cert.pem
Virtual alias map
The virtual alias map redirects all locally addressed mail to your actual mail account. Without this, mail sent to root@yourhostname would have nowhere to go.
Create /etc/postfix/virtual_alias:
#
# Postfix virtual alias map - regular expression database
# Redirect all local mail to a real mail account
#
# Run: sudo postmap /etc/postfix/virtual_alias
# after making changes to this file.
#
/.+@.+/ you@yourdomain.net
This regex matches any address of the form user@anything and redirects it to your mail account. Build the database:
sudo postmap /etc/postfix/virtual_alias
SMTP password
Create /etc/postfix/smtp_password with the credentials for your mail account on the mail server. The format is [relay]:port username:password:
[mail.yourdomain.net]:submission you@yourdomain.net:yourpassword
Lock down the file permissions and build the hash database:
sudo chmod 600 /etc/postfix/smtp_password
sudo chown root:root /etc/postfix/smtp_password
sudo postmap /etc/postfix/smtp_password
The password database is stored in /etc/postfix/smtp_password.db. The plaintext file can be deleted after hashing if you prefer, but keeping it makes future password changes easier to manage.
System aliases
The /etc/aliases file maps system accounts to real addresses. This ensures mail sent directly to root or other system accounts reaches your inbox rather than a local mailbox:
sudo tee -a /etc/aliases << 'EOF'
root: you@yourdomain.net
postmaster: you@yourdomain.net
EOF
sudo newaliases
Verifying the configuration
Check the current settings:
sudo postconf -n
The output should show only the settings you have configured. A correctly set up null client will have inet_interfaces = loopback-only, mydestination = (empty), and a relayhost pointing at your mail server.
Check for configuration errors:
sudo postfix check
No output means no errors.
Starting and enabling Postfix
sudo systemctl enable --now postfix
Testing
Send a test message to yourself:
echo "Test from $(hostname -f) at $(date)" | mail -s "Postfix null client test" you@yourdomain.net
Check the mail queue immediately after sending:
mailq
An empty queue means the message was delivered. A message sitting in the queue means delivery failed. Check the Postfix log for details:
sudo journalctl -u postfix -f
Common failure reasons:
- The mail server is unreachable (check the VPN or local network)
- TLS certificate validation failed (check the CA trust store)
- Authentication failed (check the SMTP password file and that
postmapwas run) - The relayhost address or port is wrong
Testing with a cron job
Cron sends its output via mail. A quick test: create a cron job that always produces output and verify you receive it:
crontab -e
Add:
# Test: runs every minute, generates mail output
* * * * * echo "Cron test from $(hostname -f)"
Wait a minute or two and check your inbox. Remove the test entry once confirmed. If the cron output arrives, the null client is working correctly for its primary purpose.
What the configuration file looks like
After all the postconf commands above, /etc/postfix/main.cf should contain something like this. Verify with sudo postconf -n:
compatibility_level = 3.6
inet_interfaces = loopback-only
myhostname = desktop.yourdomain.net
mydestination =
relayhost = [mail.yourdomain.net]:submission
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/smtp_password
smtp_sasl_security_options = noanonymous
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtp_tls_loglevel = 1
smtp_tls_security_level = secure
virtual_alias_maps = regexp:/etc/postfix/virtual_alias
Twelve lines. That is the entire configuration. Anything more than this for a null client is unnecessary complexity.
The SMTP password in
/etc/postfix/smtp_passwordis stored as plaintext before hashing. Ensure the file permissions are600and the file is owned byroot. The hashed.dbfile carries the same sensitivity. Both should be excluded from any backup that is not encrypted.