SMTP Email Server With Postfix

This article will detail the installation and configuration of an SMTP email server using Postfix 3.6.0.

postfix-sasl will be used for inbound Internet email delivery as well as for encrypted outbound email via submission and smtps.

cyrus-sasl2-saslauthd will handle plaintext authentication requests on behalf of the SASL library and will authenticate against local system users via PAM.

Outbound Internet email will be relayed through a Gmail account to workaround ISP blocked outbound port 25.

 

Additional Requirements

For this setup there are some additional requirements that should be met. However, the exact implementations are beyond the scope of this article.

- DNS

The domain name you are going to provide email for needs to be a valid Internet registered domain. In the provided examples this will be example.org and should be changed accordingly.

An MX record pointing to the mail server's host record i.e. MX 10 mail.example.org.

A host A record and optionally an AAAA record for mail.example.org that resolves to the Internet IP address(es) of the server

- Firewall

The firewall should be configured to allow SMTP port 25 ingress to the Postfix mail server. Mail submission and smtps ports 587 and 645 will be permitted from LAN connected hosts only.

- TLS

A valid server certificate associated with the mail server's FQDN is required to enable and use TLS encryption. To support TLS 1.3 encryption, ensure openssl 1.1.1 is installed, use openssl version to check.

- Gmail Relay

If outbound port 25 is blocked by your ISP and you would like to relay all outbound mail through Gmail's submission server, then ensure that Less secure app access is turned On for the account you will be using. Login to your Gmail account at https://myaccount.google.com/security to verify if it is turned on.

 

Install Postfix and saslauthd

Install postfix-sasl and cyrus-sasl2-saslauthd via your preferred method pkg, portmaster, synth etc.
pkg install mail/postfix-sasl security/cyrus-sasl2-saslauthd


Follow the (former) post install instructions for postfix-sasl:

To use postfix instead of sendmail:
- clear sendmail queue and stop the sendmail daemons
service sendmail stop

Run the following commands to enable postfix during startup:
sysrc postfix_enable="YES"

- sysrc sendmail_enable="NONE"
According to rc.sendmail(8) sendmail_enable="NONE" is deprecated, therefore we will disable sendmail correctly with:
sysrc sendmail_enable="NO"
sysrc sendmail_submit_enable="NO"
sysrc sendmail_outbound_enable="NO"
sysrc sendmail_msp_queue_enable="NO"

If postfix is *not* already activated in /usr/local/etc/mail/mailer.conf
mv /usr/local/etc/mail/mailer.conf /usr/local/etc/mail/mailer.conf.old
install -m 0644 /usr/local/share/postfix/mailer.conf.postfix /usr/local/etc/mail/mailer.conf

Disable sendmail specific tasks,
add the following lines to /etc/periodic.conf

daily_clean_hoststat_enable="NO"
daily_status_mail_rejects_enable="NO"
daily_status_include_submit_mailq="NO"
daily_submit_queuerun="NO"

 

Configure Postfix

Postfix uses two files for configuration /usr/local/etc/postfix/main.cf and /usr/local/etc/postfix/master.cf

main.cf contains the majority of the configuration parameters for the server. It is used to configure in/outbound mail delivery SMTP port 25, and forms the base configuration of all other Postfix SMTP daemons. It is only necessary to specify parameters if they differ from the defaults. Refer to main.cf.default to see Postfix default values for all parameters.

master.cf is used to enable and configure additional SMTP daemons for outbound submission port 587 and smtps port 465 as well as any overrides to main.cf configuration parameters.

Edit /usr/local/etc/postfix/main.cf
Modify myhostname and mydomain accordingly.
Modify mynetworks replacing 192.0.2.0/24 [2001:DB8::]/32 with your IPv4 and IPv6 network adresses.

myhostname = mail.example.org
mydomain = example.org
myorigin = $mydomain
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.0.2.0/24 [2001:DB8::]/32
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain alias_maps = hash:/etc/aliases compatibility_level = 3.6 # Outbound Internet Relay host relayhost = [smtp.gmail.com]:587 # smtp smtp_use_tls = yes smtp_tls_security_level = encrypt smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:${config_directory}/sasl_passwd smtp_sasl_security_options = noanonymous # smtpd smtpd_banner = $myhostname smtpd_use_tls = yes smtpd_tls_security_level = may smtpd_sasl_auth_enable = no smtpd_tls_chain_files = /your/path/to/postfix-chain.pem smtpd_tls_protocols = >=TLSv1.2, <=TLSv1.3 smtpd_tls_mandatory_protocols = >=TLSv1.2, <=TLSv1.3 smtpd_tls_session_cache_database = btree:/var/db/postfix/smtpd_tls_session_cache smtpd_tls_received_header = yes smtpd_tls_loglevel = 1 disable_vrfy_command = yes smtpd_helo_required = yes smtpd_relay_restrictions = permit_mynetworks, permit_auth_destination, reject smtpd_data_restrictions = reject_unauth_pipelining smtpd_client_connection_count_limit = 10

 

Edit /usr/local/etc/postfix/master.cf and uncomment either submission, smtps, or both and respective override lines:

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (no)    (never) (100)
# ==========================================================================
smtp      inet  n       -       n       -       -       smtpd
#smtp      inet  n       -       n       -       1       postscreen
#smtpd     pass  -       -       n       -       -       smtpd
#dnsblog   unix  -       -       n       -       0       dnsblog
#tlsproxy  unix  -       -       n       -       0       tlsproxy
# Choose one: enable submission for loopback clients only, or for any client.
#127.0.0.1:submission inet n -   n       -       -       smtpd
submission inet n - n - - 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
# Choose one: enable smtps for loopback clients only, or for any client. #127.0.0.1:smtps inet n - n - - smtpd smtps inet n - n - - 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

 

Create a Mail Local User Account

When creating a new user for email access:

- Add the new user to the mail group. Any existing users that require email access should also be added to the mail group.

- You do not need to configure a shell for email only users, and should specify nologin if one is not specifically required.

- Create the user's default home directory.

 

Configure cyrus-sasl2-saslauthd

Cyrus SASL is used to authenticate clients against local system users to allow sending / relaying email.

Create and edit the authentication mechanism file /usr/local/lib/sasl2/smtpd.conf

pwcheck_method: saslauthd
mech_list: PLAIN LOGIN

saslauthd only supports PLAIN and LOGIN authentication mechanisms and should be the only ones specified.

 

Create an All-in-one Certificate Chain File

With newer versions of Postfix there is support for using an all-in-one key/cert/chain file which is the recommended method.

Use cat to combine the private key, server certificate, and CA issuer certificate into an all-in-one chain file.
cat rsa-privkey.pem cert.pem chain.pem > postfix-chain.pem

Set the file to be read/writable only by root:
chmod 600 postfix-chain.pem

 

Configure Gmail Authentication

Create and edit /usr/local/etc/postfix/sasl_passwd

smtp.gmail.com    username@gmail.com:password

Set the file to be read/writable only by root:
chmod 600 /usr/local/etc/postfix/sasl_passwd

Use postmap to compile and hash the contents of sasl_passwd:
postmap /usr/local/etc/postfix/sasl_passwd

Optionally, if you'd like to also forward root's incoming mail to your Gmail mailbox:
Edit /etc/aliases adding your Gmail email address as an alias to root.

# Pretty much everything else in this file points to "root", so
# you would do well in either reading root's mailbox or forwarding
# root's email from here.

# root:	This email address is being protected from spambots. You need JavaScript enabled to view it.
root: This email address is being protected from spambots. You need JavaScript enabled to view it.

 

Rebuild Aliases Database

Use newaliases to (re)generate the /etc/aliases.db database:
newaliases

 

Enable and Start the Services

Enable Postfix and saslauthd in /etc/rc.conf
sysrc saslauthd_enable="YES"
sysrc postfix_enable="YES"

Start the services
service saslauthd start
service postfix start

 

Test the Postfix Server

Test the server using a configured email client or via command line to ensure that it can send emails to your email domain, as well as send to and receive from the Internet.

To send a test email from the command line:
mail -vs "Postfix Test" destination-email-address
Type your message and then use Ctrl-D to send it.

To test if TLS encryption is configured and working correctly via ports 587 and 465:
openssl s_client -connect mail.example.org:587 -starttls smtp
openssl s_client -connect mail.example.org:465

To view mail that has been delivered to a local user's mailbox
mail -u username

 

Configure an Email Client

To configure an email client i.e. Thunderbird, Outlook etc., use the following settings to configure outgoing SMTP server settings:

Server Name: mail.example.org
Port: 587 or 465
Connection security: STARTTLS for port 587 or SSL/TLS for port 465
Authentication method: Normal password (plaintext)
User Name: username

 

Logging

Postfix logs all successful and failed deliveries to /var/log/maillog

saslauthd logs authentication failures to /var/log/auth

 

Additional Information

For additional information refer to postconf(5) and master(5) man pages for Postfix main.cf and master.cf file syntax. The postfix(1) man page provides names of many other man pages related to configuring and running Postfix.

Postfix also provides extensive documentation with examples at http://www.postfix.org/documentation.html