Based on Debian 10 "Buster" environment.

SMTP Auth

Now Postfix accepts relaying the mails only from the localhost (cronjob or other systems). Set up authorization to make the mailbox users can send out the mail.

Postfix can be integrated with Dovecot regarding SMTP Auth, and Dovecot is already set up. Just adding some configurations enables this function and you don't have to care about multiple user lists.

In addition, many internet providers are blocking Outbound port 25 to prevent spam mails from the infected computers. Postfix should listen to the port 587 (submission port) to wait for the mailbox users sending out their mails.

SMTP TLS

Before setting up authentication, let Postfix use proper server certificate to encrypt the connection between Postfix and MUA.
The test certificate is set in /etc/postfix/main.cf by default, so swap them to the valid certificate from Let's Encrypt (or anything else you have).

# TLS parameters
smtpd_tls_cert_file=/etc/letsencrypt/live/example.jp/fullchain.pem  # Change this line to valid certificate
smtpd_tls_key_file=/etc/letsencrypt/live/example.jp/privkey.pem     # Change this line to valid private key file
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

There is another connection that should be encrypted - among other mail servers. For example, Gmail will show you the non-encrypted alert if the mail comes from the server without encrypting the connection when sending the mail. To send and receive mails via encrypted connections, add configurations in /etc/postfix/main.cf.

# TLS parameters for connection between other mail servers
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtp_tls_security_level = may
smtp_tls_loglevel = 1   # Delete this line after testing

Test

Send out a mail to Gmail and check if the alert still appears after the following auth configuration completed. If you want to check if the incoming mails are also encrypted, send a mail from Gmail and check /var/log/mail.log for "TLS connection".


SMTP Auth Configuration

Dovecot

Uncomment configurations in /etc/dovecot/conf.d/10-master.conf to enable smtp-auth for Postfix.

service auth {
  # auth_socket_path points to this userdb socket by default. It's typically
  # used by dovecot-lda, doveadm, possibly imap process, etc. Users that have
  # full permissions to this socket are able to get a list of all usernames and
  # get the results of everyone's userdb lookups.
  #
  # The default 0666 mode allows anyone to connect to the socket, but the
  # userdb lookups will succeed only if the userdb returns an "uid" field that
  # matches the caller process's UID. Also if caller's uid or gid matches the
  # socket's uid or gid the lookup succeeds. Anything else causes a failure.
  #
  # To give the caller full permissions to lookup all users, set the mode to
  # something else than 0666 and Dovecot lets the kernel enforce the
  # permissions (e.g. 0777 allows everyone full permissions).
  unix_listener auth-userdb {
    #mode = 0666
    #user = 
    #group = 
  }

  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
  }

Restart dovecot.

# systemctl restart dovecot

Postfix

Add SASL configuration to /etc/postfix/main.cf.

# SASL
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_tls_auth_only = yes
  • This authentication can be done through the tls connection only.

Reload Postfix

# systemctl reload postfix

Test if possible

If your provider doesn't block Outbound 25 connection, you can check what happens when sending out the mail.
If succeeded, the mail should reach Gmail account and the following log will show up in /var/log/mail.log.

postfix/smtpd[xxxx]: AFXXXXXXXX: client=xxx.ne.jp[000.000.000.000], sasl_method=PLAIN, sasl_username=info@mail.example.jp

Submission Port

For the mailbox users, port 587 is reserved for the use of sending out the mails.
Enable submission section in /etc/postfix/master.cf

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
  • As submission port is not for the normal mail transfer from other servers, so...
    • the connection is limited to tls connection.
    • no relaying permitted unless authenticated.
  • There are $mua_xxx_restrictions parameters, which don't exist. These will be defined later.

Reload Postfix

# systemctl reload postfix

Test

Like port 25 case above, the successful log will appear in /etc/log/mail.log. The difference is, log will show you it's connected via submission port. (See what wrote the log in the beginning part.)

postfix/submission/smtpd[xxxx]: AFXXXXXXXX: client=xxx.ne.jp[000.000.000.000], sasl_method=PLAIN, sasl_username=info@mail.example.jp

fail2ban

After opening the submission port, the attackers continue to try intruding. The fail2ban has Postfix preset for this kind of attacks.
Here I tweaked (included the latest version) to take countermeasures for the brute-force attack.

Enable postfix preset

Create /etc/fail2ban/jail.d/postfix.conf with the contents below.

[postfix]
enabled = true
mode = aggressive
findtime = 60m
  • The "aggressive" mode will enable all presets for postfix. If you need a softer version, this option can be "more" or specific mode described in the presets.
  • The default findtime is 10 minutes, which may be too short for the postfix attacks.

Only with this configuration, login attempts will be blocked.
To include this recent enhancement, tweak the preset file: /etc/fail2ban/filter.d/postfix.conf.

# Comment out (or delete) following original line
#mdpr-ddos = lost connection after(?! DATA) [A-Z]+
# Add following line
mdpr-ddos = (?:lost connection after(?! DATA) [A-Z]+|disconnect(?= from \S+(?: \S+=\d+)* auth=0/(?:[1-9]|\d\d+)))

Enable this configuration.

# systemctl restart fail2ban

You can check the result in the fail2ban logs: /var/log/fail2ban.log


Update History

2020-03-28

  • Add fail2ban configuration