Configure host base Postfix and send emails using a container

Thilina Viraj
4 min readJun 29, 2019

--

Hello there!

Let’s have a discussion on how we can send emails using host-based postfix instance, inside the docker container.

Beforehand let’s have a look at postfix. In the analog method, postfix can be the system that is used between postal offices to deliver the postal mails. This is called a Mail Transfer Agent in electronic terms.

Do we have any alternatives for postfix? Yes, we do. qmail, Exim and Sendmail are available.

Postfix and Sendmail are different implementations of Mail Transfer Agents which are using Simple Mail Transfer Protocol (SMTP) for email transport over the Internet. Postfix first released in 1998 intended to be an alternative to the widely used Sendmail MTA which was used widely since 1982.

To sum up the introduction, I’m putting below diagram which explains the differences between each of these approaches.

Source: http://shearer.org/MTA_Comparison

There are two approaches can be useful.

  1. Sendmail
  2. Connect directly to SMTP

Let’s move forward by indicating the difference between SMTP and Sendmail. SMTP is the protocol that is used by nearly all Internet hosts to send mail. This protocol is spoken by sendmail. Sendmail determines where to send your message and how.

“sendmail” means passing messages to the /usr/bin/sendmail binary. Sendmail is coming with all MTAs and letting binary to handle the rest (as opposed to directly connecting to an SMTP server using sockets). There are some mail programs connect directly to mail server and speak SMTP to it. But the traditional and better method is to let sendmail to handle it. But keep a note that Mutt email client for UNIX is one email client that still refuses to talk SMTP directly to a mail server.

There are two reasons for this:

1) nearly every program in UNIX that does what sendmail does is designed to be a drop-in replacement (this includes Postfix and Exim for instance)

2) sendmail or its replacement was designed to handle mail and nothing else. By using sendmail you don’t have to design an SMTP client.

Let’s install postfix inside host machine. I’ve done this in a virtual environment which has centos 7. Below commands will simply install postfix.

sudo yum install postfix

sudo systemctl start postfix

sudo systemctl enable postfix

In case if you want to make sure postfix is installed earlier, you can try out below commands

rpm -qa | grep postfix

systemctl status postfix

Let’s make postfix as default MTA for my OS

alternatives — set mta /usr/sbin/postfix

By any chance, if it didn’t work you will get the output as “/usr/sbin/postfix has not been configured as an alternative for mta“. In that case, you can use below command to do the same

alternatives — set mta /usr/sbin/sendmail.postfix

else skip it

Let’s configure postfix

myhostname = mail.blogspot.com //Change according to your domain

mydomain = blogspot.com //Change according to your domain

myorigin = $mydomain //Change according to your domain

inet_interfaces = all

mydestination = $myhostname, localhost, $mydomain //Change according to your domain

mynetworks = 127.0.0.0/8, /32 //Change according to your domain

relay_domains = $mydestination //Change according to your domain

home_mailbox = maildirectory/

Once configurations are done, restart the service and see whether configs are applied.

service postfix restart

chkconfig postfix on

Also, check whether your port 25 is opened to send emails

iptables -A INPUT -m state — state NEW -m tcp -p tcp — dport 25 -j ACCEPT

iptables -A INPUT -m state — state NEW -m udp -p udp — dport 25 -j ACCEPT

So we are done with host machine configurations. Let’s move into a docker container and see the configurations. We do run MTA on the host, because system (critical) errors can be sent to the admin’s mailbox. In other way around, MTA is not running in the container because that it is a duplicated process as the host system already runs an MTA.

You need to perform below two changes prior

  1. Accepting all incoming connections which come from any Docker containers.
  2. Exposing Postfix to the docker network. Postfix must be configured to bind to localhost as well as the docker network.

Now let’s change /etc/postfix/main.cf file. Before that, you need to find

echo $HOST_ADDR

and

echo $HOST_ADDR | awk -F. ‘{print $1 “.” $2 “.0.0/16”}’

vi /etc/postfix/main.cf

inet_interfaces = localhost, <echo $HOST_ADDR>

mynetworks = localhost, <echo $HOST_ADDR | awk -F. ‘{print $1 “.” $2 “.0.0/16”}’>

Save the configuration file and restart Postfix:

sudo systemctl restart postfix

Let’s run the docker container now.

Since we are going to use sendmail in the container, install ssmtp and set FromLineOverride to be permitted and mailhub to the IP address of the host in /etc/ssmtp/ssmtp.conf.

If you want you can set mailhub to be a symbol such as smtp-server. Then run the container with add-host option (run it with — add-host smtp-server:your-docker0-address). This would configure a usable sendmail in containers which would actually use the host MTA to send emails.

Here are the final steps. Run the commands below after replacing thilina@blogspot.com with your email address:

YOUR_EMAIL=thilina@blogspot.com

cat > sendmail.txt <<EOF

HELO x

MAIL FROM: admin@blogspot.com

RCPT TO: $YOUR_EMAIL

DATA

From: test@example.com

To: $YOUR_EMAIL

Subject: Test email

Successfully tested

.

quit

EOF

Run the following commands to connect to the Postfix server and send out the email:

apt-get update && apt-get install -y netcat

nc <echo $HOST_ADDR> 25 <sendmail.txt

Yay… That’s it for the day. Do post your thoughts below

--

--