Mailgun is an awesome free service for sending email safely from your WordPress server. They have a WordPress plugin that uses the Mailgun HTTP API so you can conceal your web server’s IP address – you should never host email on your web server for security reasons like spam, exploitation and risk your server IPs getting blacklisted as a result.
If you are using Monit, CSF ConfigServer Firewall or Linux Malware Detect and would like email reports, then this guide is for you. CSF Firewall’s lfd (login failure daemon) needs postfix or sendmail to send your alerts about system load, login attempt failures and so on. With this guide you will be able to configure Postfix to use Mailgun as an SMTP relay. We will also be setting up postfix forwarding so any local email address (e.g. root@localhost) is automatically forwarded to your gmail account – or any email address you choose.
You will need a Mailgun account to complete this tutorial and the ability to change your postfix settings.
This tutorial was tested on Debian 7, 8 and Ubuntu 16.04.
Configure Postfix to use Mailgun SMTP Relay on Ubuntu
Installation overview
- Install Postfix
- Configure Postfix SMTP Relay
- Set all emails to be forwarded
- Test Postfix SMTP relay
- Configure Firewall Exceptions
Install Postfix on Ubuntu
First install postfix and the necessary SASL modules for authenticating with the Mailgun server
sudo apt-get update
sudo apt-get install postfix libsasl2-modules -y
Choose inetd when prompted, you do not need to use your full domain name and it can actually cause issues (relay=local in logs) if you do.
Configure Postfix Mailgun SMTP Relay
Open the postfix config
sudo nano /etc/postfix/main.cf
Your configuration should look something like this, the #comments explain what the lines do.
You will want to make sure you are using your Mailgun postmaster password in the smtp_sasl_password_maps
line.
# See /usr/share/postfix/main.cf.dist for a commented, more complete version
# 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 (Debian/GNU)
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
# 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_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.
myhostname = wp-bullet.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = wp-bullet.com, mail.wp-bullet.com, localhost.localdomain, localhost
relayhost = [smtp.mailgun.org]:587
#limit to loopback address
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
#limit to loopback address
inet_interfaces = loopback-only
local_recipient_maps = proxy:unix:passwd.byname $alias_maps
#where we specify the forwarding address to e.g. google
virtual_maps = regexp:/etc/postfix/virtual-regexp
#allow inet interfaces for SMTP - also allow submission inet in master.conf
smtpd_client_restrictions = permit_inet_interfaces
smtp_sasl_auth_enable = yes
#set to your mailgun credentials
smtp_sasl_password_maps = static:postmaster@mg.wp-bullet.com:3de4626206c0cbecea409fde2f49147e4
#this is required for authentication to prevent the FROMTO error
smtp_sasl_security_options = noanonymous
Now open the postfix master configuration
sudo nano /etc/postfix/master.cf
Enable the submission line by removing the #
submission inet n - - - - smtpd
Ctrl+X, Y and Enter to Save and Exit.
Make sure your mailname is set to your domain
sudo nano /etc/mailname
Paste your domain name
wp-bullet.com
Ctrl+X, Y and Enter to Save.
Test your Postfix configuration syntax to make sure there are no errors
sudo postfix check
Then restart postfix
sudo service postfix restart
Now you can verify postfix is listening on the loopback adapter 127.0.0.1 only
sudo netstat -lntp | grep master
You should see this output that ports 25, 465 and 587 are only running on the loopback adapter which means no external users can access it from its internet IP address.
This is the safest way to send mail from your VPS or dedicated server as an SMTP send only server.
tcp 0 0 127.0.0.1:465 0.0.0.0:* LISTEN 3458/master
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 3458/master
tcp 0 0 127.0.0.1:587 0.0.0.0:* LISTEN 3458/master
tcp6 0 0 ::1:465 :::* LISTEN 3458/master
tcp6 0 0 ::1:25 :::* LISTEN 3458/master
tcp6 0 0 ::1:587 :::* LISTEN
Configure Postfix Email Forwarding
Many programs will send email alerts to root@localhost by default. In this section we will configure postfix to forward all emails on the system to your desired email address at gmail or wherever you like
sudo nano /etc/postfix/virtual-regexp
The most common use case is to have emails that are being sent to root@localhost to be forwarded to your gmail address.
This regular expression will match any user at localhost and forward it to test@wp-bullet.com
/.+@localhost/ test@wp-bullet.com
If you want to match any email user at any email domain and forward it to test@wp-bullet.com use the regular expression below.
Warning this will forward all email users and domains to test@wp-bullet.com
/.+@.+/ test@wp-bullet.com
Now we need to postmap it so postfix is aware of forwarding rules
postmap /etc/postfix/virtual-regexp
Reload postfix service
sudo service postfix reload
Testing Postfix Mailgun SMTP Relay
In this section we are going to test that the Mailgun SMTP relay is working. First we will send an email to your desired email address (e.g. test@wp-bullet.com). Afterwards we will send an email to root@localhost to make sure it is forwarded to our desired email address (e.g. test@wp-bullet.com).
Install mail utilities
sudo apt-get install mailutils -y
This will send a an email to test@wp-bullet.com with the subject Postfix Mailgun and the body text ‘This is testing SMTP Relay’
echo "This is testing SMTP Relay." | mail -s "Postfix Mailgun" test@wp-bullet.com
You should get the email immediately, you can check the last 100 lines of your postfix mail logs
tail -n 100 /var/log/mail.log
You should see these logs indicating the Mailgun successfully delivered it (250 Great success).
Aug 4 19:50:58 wp-bullet postfix/pickup[9265]: D83B480985: uid=0 from=
Aug 4 19:50:58 wp-bullet postfix/cleanup[9804]: D83B480985: message-id=<20160804195058.D83B480985@wp-bullet.com>
Aug 4 19:50:58 wp-bullet postfix/qmgr[9266]: D83B480985: from=<root@wp-bullet.com>, size=472, nrcpt=1 (queue active)
Aug 4 19:50:59 wp-bullet postfix/smtp[9799]: D83B480985: to=<test@wp-bullet.com>, relay=smtp.mailgun.org[173.203.37.114]:587, delay=1, delays=0.04/0/0.43/0.53, dsn=2.0.0, status=sent (250 Great success)
Aug 4 19:50:59 wp-bullet postfix/qmgr[9266]: D83B480985: removed
Now you can send an email to root@localhost and see if it is automatically forwarded to your desired email address test@wp-bullet.com
echo "This is testing forwarding." | mail -s "Postfix Mailgun Forward" root@localhost
Check your logs again and you can see the email is being forwarded. Here the orig_to is being forwarded to test@wp-bullet.com
Aug 9 13:34:23 htpcguides postfix/pickup[6103]: B719B81163: uid=0 from=
Aug 9 13:34:23 htpcguides postfix/cleanup[8799]: B719B81163: message-id=<20160809113423.B719B81163@htpcguides.com>
Aug 9 13:34:23 htpcguides postfix/qmgr[3466]: B719B81163: from=<root@wp-bullet.com>, size=461, nrcpt=1 (queue active)
Aug 9 13:34:24 htpcguides postfix/smtp[8801]: B719B81163: to=<test@wp-bullet.com>, orig_to=<root@localhost>, relay=smtp.mailgun.org[104.130.177.23]:587, delay=0.83, delays=0.06/0.03/0.36/0.38, dsn=2.0.0, status=sent (250 Great success)
Aug 9 13:34:24 htpcguides postfix/qmgr[3466]: B719B81163: removed
Troubleshooting Postfix Mailgun SMTP Relay Errors
If you see this error can be fixed with the smtp inetd submssion line in master.conf set in the previous section
Aug 4 19:45:53 wp-bullet postfix/qmgr[9266]: BB9FB80B6B: from=<>, size=2332, nrcpt=1 (queue active)
Aug 4 19:45:53 wp-bullet postfix/submission/smtpd[9284]: connect from wp-bullet.com[178.62.198.10]
Aug 4 19:45:53 wp-bullet postfix/smtp[9280]: BB9FB80B6B: to=<test@wp-bullet.com>, orig_to=<root@wp-bullet.com>, relay=smtp.mailgun.org[104.130.177.23]:587, delay=0.01, delays=0/0/0.01/0, dsn=5.7.0, status=bounced (host smtp.mailgun.org[104.130.177.23] said: 530 5.7.0 Must issue a STARTT LS command first (in reply to MAIL FROM command))
Aug 4 19:45:53 wp-bullet postfix/submission/smtpd[9284]: disconnect from wp-bullet.com[173.62.198.10]
Aug 4 19:45:53 wp-bullet postfix/qmgr[9266]: BB9FB80B6B: removed
This error is because of a firewall blocking the connection (some fixes are below in the Firewall Exceptions section)
Aug 4 18:01:49 wp-bullet postfix/error[4861]: D926D80BA1: to=<htpcguidez@gmail.com>, orig_to=<root@wp-bullet.com>, relay=none, delay=27839, delays=27839/0.05/0/0.02, dsn=4.4.1, status=deferred (delivery temporarily suspended: connect to smtp.mailgun.org[104.130.177.23]:587: Connection timed out)
This error is because smtp_sasl_security_options = noanonymous
isn’t set in main.cf enabling plain text SASL authentication.
warning: SASL authentication failure: No worthy mechs found
Aug 4 19:22:30 wp-bullet postfix/smtp[7719]: 8821B81A11: to=<blindpet@gmail.com>, relay=smtp.mailgun.org[173.203.37.114]:587, delay=0.68, delays=0.03/0.02/0.63/0, dsn=4.7.0, status=deferred (SASL authentication failed; cannot authenticate to server smtp.mailgun.org[173.203.37.114]: no mechanism available)
If you see this error
Aug 11 07:11:00 wp-bullet postfix/local[29226]: 2B3E75FACF: to=<webmaster@wp-bullet.com>, orig_to=<root@wp-bullet.com>, relay=local, delay=0.01, delays=0/0/0/0, dsn=5.1.1, status=bounced (unknown user: "webmaster")
Aug 11 07:11:00 wp-bullet postfix/qmgr[2609]: 2B3E75FACF: removed
then remove the domain name (e.g. wp-bullet.com is missing now) from the mydestination
line in /etc/postfix/main.cf
mydestination = guides.wp-bullet.com, localhost.wp-bullet.com, localhost
Configure Firewall Exceptions for Postfix
In this section I show how to prevent the timeout errors if you are using CSF ConfigServer Firewall or ufw firewall.
CSF ConfigServer Firewall Exception
Open your CSF ConfigServer Firewall configuration
sudo nano /etc/csf/csf.conf
Make sure port 587 is in TCP_IN
and TCP_OUT
# Allow incoming TCP ports
TCP_IN = "20,21,25,53,80,110,143,443,465,587,993,995"
# Allow outgoing TCP ports
TCP_OUT = "20,21,25,53,80,110,113,443,587,993,995,3005"
Use Ctrl+W and enter SMTP_BLOCK to find this section.
Make your configuration match the one below to fix timeout errors.
If you have SMTP_PORTS
include 587 it will be blocking the attempt causing the timeout
###############################################################################
# SECTION:SMTP Settings
###############################################################################
# Block outgoing SMTP except for root, exim and mailman (forces scripts/users
# to use the exim/sendmail binary instead of sockets access). This replaces the
# protection as WHM > Tweak Settings > SMTP Tweaks
#
# This option uses the iptables ipt_owner/xt_owner module and must be loaded
# for it to work. It may not be available on some VPS platforms
#
# Note: Run /etc/csf/csftest.pl to check whether this option will function on
# this server
SMTP_BLOCK = "1"
# If SMTP_BLOCK is enabled but you want to allow local connections to port 25
# on the server (e.g. for webmail or web scripts) then enable this option to
# allow outgoing SMTP connections to the loopback device
SMTP_ALLOWLOCAL = "1"
# This option redirects outgoing SMTP connections destined for remote servers
# for non-bypass users to the local SMTP server to force local relaying of
# email. Such email may require authentication (SMTP AUTH)
SMTP_REDIRECT = "0"
# This is a comma separated list of the ports to block. You should list all
# ports that exim is configured to listen on
SMTP_PORTS = "25,465"
# Always allow the following comma separated users and groups to bypass
# SMTP_BLOCK
#
# Note: root (UID:0) is always allowed
SMTP_ALLOWUSER = ""
SMTP_ALLOWGROUP = "mail,mailman"
Ctrl+X, Y and Enter to Save and Exit.
Restart CSF
sudo csf -r
sudo service csf restart
UFW Firewall Exception
If you are using ufw (Universal Firewall) you can create an exception for the postfix SMTP relay like this
sudo ufw allow 587/tcp
Sources
Postfix SMTP relay setup for Mailgun
Configure Postfix + Mailgun on a Cloud VPS
How to Install and Configure Postfix as a Send-Only SMTP Server on Ubuntu 16.04
SASL authentication failure: No worthy mechs found
Problem with outgoing mail from server
Must issue a STARTTLS command first when RECEIVING email