First off I want to mention that this configuration is simply to get outgoing mail working, little else. I’ll be presenting the postfix configuration I use on 3 of my servers which are all internet connected. All 3 systems have identical master.cf and main.cf configuration files which of course live in /etc/postfix directory. Because the configuration files are identical, other than relevant lines in main.cf updated to reflect the host it’s on, this is a very portable configuration and I actually keep copies of these particular main.cf and master.cf files in a configuration directory on my home sandbox so that I can easily push them out to new hosts as needed. I’ll also mentioned my home sandbox is a WSL (Windows Subsystem for Linux) installation and I send out emails out from there as well so the configuration is used there as well.
postfix should already be installed if your using one of the Ubuntu LTS distributions named in the title but you could be using any Linux distribution, not limited to Ubuntu of course to use this configuration. The 3 Linux distributions I mentioned above are Ubuntu 20, 22, and 24 installations and it’s a real boon to have identical postfix configuration and installations as it seriously minimizes the administrative burden. There is a dependency on saslauthd so we’ll need to install the sasl2-bin package which by default is NOT part of a standard Ubuntu LTS distribution. You may install either or both packages required with the following commands:
apt install postfix
apt install sasl2-bin
Relay Host
You may have noticed in the title something about a mail relay. This is especially important if say you just purchased a VPS (Virtual Private Server) or other hosting product, which is the audience this article is mostly aimed at and you simply want to send the occasional mail from the command line and maybe even receive some mail. Maybe you want to be able to mail yourself some file, or more importantly, maybe you have some subsystem which generates some email and you want it to go to your internet email address. For example many of the plugins I utilize on my various WordPress based sites send out informational mail to alert me of various goings on that are occuring within my WordPress installations. Maybe it’s the summary mail WP Mail SMTP sends out weekly. Maybe it’s the various reports Wordfence sends out to alert me on status. Maybe I have auto-updates enabled for my WordPress plugins and want to be notified when automatic updates or upgrades occur. By default these mails would go to the root, www-data, or nobody user configured on the Ubuntu host and are easy to miss unless you religiously monitor your mail spool.
The reason the host relay is important is because configuring a full service mail server encompasses much more than this short article details. So I’ll say it now. This configuration I’m presenting is NOT for the purposes of setting up a complete fully featured internet email subsystem with complete send and receive functionality, or with IMAP, pop3, and Dovecot configurations. I’m not going into the subtleties of postscreen and definitely not entertaining spamassassin. There are more considerations such as DKIM, DMARC, and SPF1. Additionally many mail servers on the internet will not process mail unless forward, and sometimes, reverse name resolution records are resolvable. MX (mail exchanger) DNS records also will not be discussed. These are all expert (not advanced, expert) related matters for hardcore mail administrators that do nothing but handle email issues on a daily basis. If you were looking for some sendmail information, I charge an exorbitant consulting fee for handling the intricacies of sendmail so that also will not be discussed.
The final note about host relay is this. One of my email addresses is on the Comcast/Xfinity network. It’s their mail servers I’m ultimately relying on to distribute the email because they, unlike my servers, are already trusted internet wide but it could be any of Gmail, Yahoo, or your home ISP (internet service provider), whoever. I just use the smtp servers at Comcast/Xfinity because I have unrestricted access to smtp.comcast.net (the relay host) as I am a customer and have a username and password to authenticate against it. There are some restrictions, but not for responsible users. What would an irresponsible situation look like? If I tried to send 100 emails a second to 5 million email addresses, I would quickly discover I no longer have that unrestricted access.
Comcast/Xfinity of course is not the only choice choice for relaying mail. If you have a Google Gmail account, they offer access to their smtp servers through the very nature of having an email address with them. In fact, Google publishes a document which includes the names of their email servers (smtp server) and to authenticate against them requires nothing more than a Gmail email address and password.
So if you don’t have Comcast or Xfinity and you also do not use Gmail as your email provider there’s a high degree of likelihood that’s there’s an smtp server on your ISP’s (internet service provider) network and you simply need to find out what that is. It’s pretty standard for all the various ISP’s to have an smtp server and it might be named smtp.{ISP}.{com, net, org, whatever}, but it might not. Because you’re already an authenticated user on your ISP’s network you might not even have to authenticate against the smtp server, but chances of this are slim. Your username and password more likely than not are the authentication details you’ll need to authenticate against the smtp (mail) server of your ISP and these items are the prerequisites you’ll need to carry out the steps coming up.
With that said, this document assumes you have the name of an smtp (mail) server that you can use which you can authenticate against with your username and password. The username and password of course will have been provided to you when you signed up for whoever services your internet connectivity. Alternatively, you can use the free mail servers Google/Gmail provide and use the username and password you use to get your email (Gmail) as the authentication details that server needs and use that as the relay.
Setup sasl
sasl (Simple Authentication and Security Layer) will need to be setup so that you can provide the detail and syntax for inclusion in the main.cf postfix configuration file. Once you have those details you’ll need to perform the following steps to get it ready for saslauthd and postfix. At the very beginning of this document are the details to install the saslauthd package on Ubuntu so make sure that is available.
Steps:
- vi /etc/postfix/sasl_passwd (this file more likely than not won’t exist yet)
- Enter the Following single line into the sasl_password file
- **Syntax: [{mail server}.{mail relay}.{net, com, org}]:{port} {username:password} into that file
- **Example: [smtp.comcast.net]:587 username:password (my personal setup)
- Save the sasl_passwd file
- chown root:root /etc/postfix/sasl_passwd
- chmod 0600 /etc/postfix/sasl_passwd
- postmap /etc/postfix/sasl_passwd
So you need to edit or create the /etc/postfix/sasl_passwd file. The single line which comprises the name of the server, the port, username, and password all fit on a single line following the syntax as provided in the above list. Your mail port might not be 587 (though there’s a big chance it is). It might be port 25 in which case you don’t have to provide the port number, but do it anyways. It’s a self documenting feature and doesn’t hurt.
Once the sasl_passwd file is created we need to secure it, as it might contain the username and password of your respective mail user. chown and chmod as provided above so no one but root and the mail subsystem are the only ones that have access to the file.
Finally, the postmap command creates a secure hash of the sasl_passwd file in the format postfix requires.
Configuration
Before I present the main.cf and master.cf configuration files I want to make sure some prerequisite files are configured and contain the proper information. Those prerequisite files are:
/etc/hostname
/etc/mailname
These files should contain the hostname of the system your configuring the outgoing and/or incoming mail for. It’s up to you whether you want to use the short hostname or FQDN (fully qualified domain name). I personally use the short host name for /etc/hostname and the FQDN for /etc/mailname, but that’s a personal preference. You can do as I do or use short hostnames or FQDN for either or both files.
Okay let’s get to the meat of the situation and talk about what you’ll need to update in the main.cf configuration file. As a reminder the main.cf and master.cf configuration files live in the /etc/postfix directory. No changes will need to be made to the master.cf config file I’ll be providing unless you absolutely don’t want to start up the mail server/s. The lines you’ll want to change in the provided main.cf file are as follows:
myhostname = {short or FQDN goes here}
mydestination = {FQDN}, {short hostname}, localhost
relayhost = [{relay.host}]:{mail server port}
The braces used above are simply to delimit what’s contained in them. DO NOT recreate those braces in the actual /etc/postfix/main.cf file. The brackets however on the relayhost portion are not optional. You’ll get a better look at the entries when the actual main.cf is presented below. Braces and brackets are different. Braces are the curly looking ones, brackets are the squared looking ones.
The /etc/postfix/main.cf and /etc/postfix/master.cf files in question are located at the end of this article. Don’t just immediately copy and paste those files into place just yet. Do this first:
mv /etc/postfix/main.cf /etc/postfix/main.old
mv /etc/postfix/master.cf /etc/postfix/master.old
That creates a saved copy of those files and can be used as templated in the future as your needs change. They will be replaced with the main.cf and master.cf files below. Once you’ve set up the sasl parameters, and made the necessary changes to the main.cf config file we’ll need to restart postfix to get it to read the new information.
service postfix restart
Okay that will just about do it for this article. Below are the main.cf and master.cf configuration files I use. This configuration starts up the smtp server on port 25 and the more secure submission server on port 587. That has nothing to do with outgoing mail, but the configuration is setup to receive mail on those two ports. I have them setup because I do want the servers up as I pass email among my firewalled hosts. This is optional and you can simply comment out the smtp and submission lines in master.cf if you don’t want the servers started up. Of course having them firewalled accomplishes the same thing. If you’re using a host based firewall (ufw for example) don’t forget to open those ports as needed. Additionally, make sure to open up the ports on the network firewall choke point or have the ports forwarded to it if that’s your network configuration. I have both host based firewall as well as network firewall in front of all my internet facing servers. Sure, it might be redundant, but redundancy not only settles the mind, it settles security as well.
Thanks for taking the time to read this article. It was supposed to be short and I suppose it’s relatively short. If this setup helps you or you need some clarification don’t hesitate to send an email to support@zettabytes.org or leave a reply/comment below.
—
/etc/postfix/main.cf
# Debian specific: Specifying a file name will cause the first
# line of that file to be used as the name. The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
readme_directory = no
# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on
# fresh installs.
compatibility_level = 2
# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_security_level=may
smtp_tls_CApath=/etc/ssl/certs
smtp_tls_security_level=may
smtp_tls_session_cache_database = hash:/etc/postfix/sasl_passwd
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = lite.zettabytes.org
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = lite.zettabytes.org, localhost.org, localhost
relayhost = [smtp.comcast.net]:587
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_use_tls = yes
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
/etc/postfix/master.cf
#
# Postfix master process configuration file. For details on the format
# of the file, see the master(5) manual page (command: "man 5 master" or
# on-line: http://www.postfix.org/master.5.html).
#
# Do not forget to execute "postfix reload" after editing this file.
#
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (no) (never) (100)
# ==========================================================================
#587 inet n - y - - smtpd
#smtp inet n - y - 1 postscreen
smtp inet n - y - 1 smtpd
#smtpd pass - - y - - smtpd
#dnsblog unix - - y - 0 dnsblog
#tlsproxy unix - - y - 0 tlsproxy
submission inet n - y - - smtpd
# -o syslog_name=postfix/submission
# -o smtpd_tls_security_level=encrypt
# -o smtpd_sasl_auth_enable=yes
# -o smtpd_tls_auth_only=yes
# -o smtpd_reject_unlisted_recipient=no
# -o smtpd_client_restrictions=$mua_client_restrictions
# -o smtpd_helo_restrictions=$mua_helo_restrictions
# -o smtpd_sender_restrictions=$mua_sender_restrictions
# -o smtpd_recipient_restrictions=
# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING
#smtps inet n - y - - smtpd
# -o syslog_name=postfix/smtps
# -o smtpd_tls_wrappermode=yes
# -o smtpd_sasl_auth_enable=yes
# -o smtpd_reject_unlisted_recipient=no
# -o smtpd_client_restrictions=$mua_client_restrictions
# -o smtpd_helo_restrictions=$mua_helo_restrictions
# -o smtpd_sender_restrictions=$mua_sender_restrictions
# -o smtpd_recipient_restrictions=
# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING
#628 inet n - y - - qmqpd
pickup unix n - y 60 1 pickup
cleanup unix n - y - 0 cleanup
qmgr unix n - n 300 1 qmgr
#qmgr unix n - n 300 1 oqmgr
tlsmgr unix - - y 1000? 1 tlsmgr
rewrite unix - - y - - trivial-rewrite
bounce unix - - y - 0 bounce
defer unix - - y - 0 bounce
trace unix - - y - 0 bounce
verify unix - - y - 1 verify
flush unix n - y 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - y - - smtp
relay unix - - y - - smtp
-o syslog_name=postfix/$service_name
# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq unix n - y - - showq
error unix - - y - - error
retry unix - - y - - error
discard unix - - y - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - y - - lmtp
anvil unix - - y - 1 anvil
scache unix - - y - 1 scache
postlog unix-dgram n - n - 1 postlogd
#
# ====================================================================
# Interfaces to non-Postfix software. Be sure to examine the manual
# pages of the non-Postfix software to find out what options it wants.
#
# Many of the following services use the Postfix pipe(8) delivery
# agent. See the pipe(8) man page for information about ${recipient}
# and other message envelope options.
# ====================================================================
#
# maildrop. See the Postfix MAILDROP_README file for details.
# Also specify in main.cf: maildrop_destination_recipient_limit=1
#
maildrop unix - n n - - pipe
flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
#
# ====================================================================
#
# Recent Cyrus versions can use the existing "lmtp" master.cf entry.
#
# Specify in cyrus.conf:
# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4
#
# Specify in main.cf one or more of the following:
# mailbox_transport = lmtp:inet:localhost
# virtual_transport = lmtp:inet:localhost
#
# ====================================================================
#
# Cyrus 2.1.5 (Amos Gouaux)
# Also specify in main.cf: cyrus_destination_recipient_limit=1
#
#cyrus unix - n n - - pipe
# user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
#
# ====================================================================
# Old example of delivery via Cyrus.
#
#old-cyrus unix - n n - - pipe
# flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
#
# ====================================================================
#
# See the Postfix UUCP_README file for configuration details.
#
uucp unix - n n - - pipe
flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
#
# Other external delivery methods.
#
ifmail unix - n n - - pipe
flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp unix - n n - - pipe
flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix - n n - 2 pipe
flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman unix - n n - - pipe
flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
${nexthop} ${user}
BUON WEEK-END