SMTP Authentication

 Published on 16 Feb 2025 .  Filed in Projects .  1164 words

Postfix Delegates Authentication to Dovecot

We have already configured Dovecot to know everything about users from the SQL database. So let's tell Postfix to use the Dovecot server as an authentication server to verify the username and password. Run these commands on the shell:

  sudo postconf smtpd_sasl_type=dovecot
  sudo postconf smtpd_sasl_path=private/auth
  sudo postconf smtpd_sasl_auth_enable=yes

Postfix can send authentication request to Dovecot through a socket file located at chroot directory — /var/spool/postfix/private/auth. (Postfix cannot access any file outside /var/spool/postfix directory.

In a previous section we edited the /etc/dovecot/conf.d/10-master.conf file and made Dovecot place a socket file into /var/spool/postfix/private/auth to allow communication from Postfix.

The following settings enable encryption, set the key and certificate paths for Postfix:

  sudo postconf smtpd_tls_security_level=may
  sudo postconf smtpd_tls_auth_only=yes
  sudo postconf smtpd_tls_cert_file=/etc/letsencrypt/live/example1.com/fullchain.pem
  sudo postconf smtpd_tls_key_file=/etc/letsencrypt/live/example1.com/privkey.pem

  sudo postconf smtp_tls_security_level=may

NOTE: Here we have two types of configuration directives, one starting with smtp_ and the second with smtpd_. The smtp_ refers to the SMTP client (do not confuse with MUA such as Thunderbird, mutt, etc), the component that sends mail from Postfix to other SMTP servers. smtpd_ refers to the SMTP server. This is the component that receives mail from other systems, either from other SMTP server or from one of your SMTP users.

The above settings allow encrypted incoming (smtpd_) and outgoing (smtp_) connections. But they do not enforce it. So if a remote mail server does not have encryption enabled, we will still accept its emails, otherwise the emails will be rejected.

However the smtpd_tls_auth_only=yes setting makes sure that the user’s authentication information (email address and password) are always encrypted between the user and your mail server.

How SMTP Authentication Works ?

Unencrypted SMTP Communication

Let's connect to TCP port 25 on localhost using Telnet:

  telnet localhost 25

The server will let you in:

Trying 127.0.0.1…
Connected to localhost.
Escape character is '^]'.
220 webmail ESMTP Postfix (Debian/GNU)

Start the communication by introducing yourself to the SMTP server or in other words specifying the domain name or IP address of the SMTP client:

ehlo example.com

Postfix will present a list of features that are available for you:

250-mailtest
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING
  • PIPELINING This is a feature to speed up SMTP communication. Usually the remote system (who initiate a SMTP connection) has to wait for a response to every command it sends. Pipelining allows the remote server to send several commands in a batch without waiting for a response. Our Postfix will just store these commands and execute them one by one. If you told Postfix to forbid pipelining it would disconnect the remote server when it tries to send bulks of commands without waiting for the proper reply. It is mainly a feature against rogue senders.
  • SIZE 10240000 The remote server is allowed to send emails up to 10 MB large. This has long been a common maximum size for emails. However nowadays 40 MB or even more are more common sizes because emails have grown larger. Some mail servers even allow 100 MB.
  • VRFY Allows remote servers to verify a given name or email address. For example the remote server could send VRFY user1 and your server might respond 250 User1 <user1@example1.com>. It can be used to verify that a certain recipient email address is deliverable
  • ETRN A command that a remote system can send to flush the Postfix queue of mails for a certain domain. It can be used if the remote system had technical problems and failed to receive email for a while. Then it could send an ETRN command to make your server start sending outstanding emails for that domain. It is rarely used.
  • STARTTLS This tells the remote system that it might start switching from this unencrypted to an encrypted connection by sending the STARTTLS command. It will then start negotiating a TLS-encrypted connection. You could compare it to an HTTP connection that suddenly switches over to an encrypted HTTPS connection. The advantage is that you can start talking SMTP on TCP port 25 and don’t have to open up a second TCP port like 465 which is the "SSMTP" (secure SMTP) port and which only accepts encrypted connections.
  • ENHANCEDSTATUSCODES

This enables more three-digit return codes for various conditions. See the RFC2034 1 for more details.

  • 8BITMIME In ancient times SMTP only processed 7-bit characters. You couldn’t transfer special characters like Ä or ß without special encoding. The 8BITMIME allows a transmission of emails using 8-bit characters. Still many emails are specially encoded using ISO8859-1 or UTF-8.
  • DSN It enables DSNs (delivery status notofications) that allows the sender to control the messages that Postfix creates when an email could not be delivered as intended.
  • SMTPUTF8 In addition to 8BITMIME you can use UTF8 encoded characters in header fields.
  • CHUNKING This feature (described in RFC 3030) makes sending of large emails more efficient.

However one important line is missing here that would allow us to send our username and password:

250-AUTH PLAIN LOGIN

We told Postfix to only allow authentication when the connection is encrypted. So we are not offered authentication over this plain text connection. So we need an encrypted connection using TLS. Using the STARTTLS feature we can switch over from unencrypted to encrypted without having to reconnect. So enter:

STARTTLS

And the server replies:

220 2.0.0 Ready to start TLS

However now it’s getting weird because you would have to speak TLS encryption which is not a language that humans speak. So let’s quit this using the QUIT command and do that differently.

Ecrypted SMTP Communication

So we use OpenSSL to help us with the ecryption:

openssl s_client -connect localhost:25 -starttls smtp

You will see a lot of output. OpenSSL has connected to TCP port 25 and issued a STARTTLS command to switch to an encrypted connection. So whatever you type now will get encrypted. Enter:

EHLO example.com

And Postfix will send a list of capabilities that will look like this:

250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN

And now that we are using an encrypted connection Postfix offers us to authenticate. So let us send the authentication string with a Base64-encoded password:

AUTH PLAIN AGpvaG5AZXhhbXBsZS5vcmcAc3VtbWVyc3Vu
  • We use an encoded string because, in general, SMTP can only transfer ASCII characters. But the email address may contain special characters that are not covered by ASCII. So, in the PLAIN method, we encode the foloowing information in Base64 — NULL-BYTE + USERNAME + NULL-BYTE + PASSWORD.

    So for user1’s case you can easily create the Base64 string using:

      printf '\0user1@example1.com\0SecurePass' | base64

Unless you have changed user1's password to something else than SecurePass the server should accept that authentication:

235 2.7.0 Authentication successful

Excellent. You are logged in through SMTP. You could now send an email to be forwarded to another mail server. Here I just wanted to show that authentication works if you use an encrypted connection.

Disconnect from Postfix:

QUIT

Footnotes


1

SMTP Service Extension for Returning Enhanced Error Codes - https://datatracker.ietf.org/doc/html/rfc2034