A Tour Of main.cf (Postfix) In Your Email Server | Carbonio CE

MTA is the integral part of a linux based email system. In this article, we will shed some lights on main.cf that will help you to configure postfix as per your requirement.

Understanding main.cf

We have setup a Carbonio CE server. We can find the main.cf file on /opt/zextras/common/conf location. It has more than 500 lines but don’t worry we will pick those lines that are most useful for the system admins. So let’s start.

queue_directory = /opt/zextras/data/postfix/spool

All postfix queues are stored in this directories. If you further look into this spool directory then you will be able to notice then but you can not read them as they can only be accessible by postfix user.

zextras@mail:~/data/postfix/spool$ ls -ll
total 56
drwx------ 2 postfix postfix  4096 Sep 26 17:26 active
drwx------ 2 postfix postfix  4096 Jul 25 14:01 bounce
drwx------ 2 postfix postfix  4096 Jul 25 14:01 corrupt
drwx------ 2 postfix postfix  4096 Jul 25 14:01 defer
drwx------ 2 postfix postfix  4096 Jul 25 14:01 deferred
drwx------ 2 postfix postfix  4096 Jul 25 14:01 flush
drwx------ 2 postfix postfix  4096 Jul 25 14:01 hold
drwx------ 2 postfix postfix  4096 Sep 26 17:26 incoming
drwx-wx--- 2 postfix postdrop 4096 Jul 25 14:01 maildrop
drwxr-xr-x 2 postfix root     4096 Sep 26 17:17 pid
drwx------ 2 postfix postfix  4096 Sep 27 05:17 private
drwx--x--- 2 postfix postdrop 4096 Sep 27 05:17 public
drwx------ 2 postfix postfix  4096 Jul 25 14:01 saved
drwx------ 2 postfix postfix  4096 Jul 25 14:01 trace

What if local recipient is rejected by postfix. Sometimes it can happen that the recipient of an email is a local user but the postfix could not find it in the lookup table. Now this lookup table is constructed by local_recipient_maps. A recipient is local or not is identified when its domain matches mydestination, inet_interfaces or proxy_interfaces.

unknown_local_recipient_reject_code = 550

The default setting is 550 (with the message: reject mail) but it is safer to initially use 450 (with the message: try again later) so you have time to find out if your local_recipient_maps settings are OK.

On many occasions, users get emails with a deformed header. By the very first look, you can tell that this email is a spam/phishing/unsolicited email and still your server accepts it. With header_checks you can enforce policy for deformed/unwanted headers. The format for this enforcement is:

header_checks = pcre:/etc/postfix/header_checks.pcre

vi /etc/postfix/header_checks.pcre:
               REJECT Attachment name "$2" may not end with ".$4"

You can also enforce policy for different format of headers. Check out this article.

As a system admin, you don’t want to establish connection with any remote SMTP server that does not provide it’s clear identification. That’s why we need HELO/EHLO from remote SMTP server before it can submit email to your server. To enforce this policy, you have to set followings:

smtpd_helo_required = yes

You also enforce some level of protections through restriction lists. Top 6 of them are: smtpd_client_restrictions,
Unless you have anything specific about any sender, we would advice you to use smtpd_recipient_restrictions.

smtpd_client_restrictions = reject_unauth_pipelining
smtpd_recipient_restrictions = reject_non_fqdn_recipient, permit_sasl_authenticated, permit_mynetworks, reject_unlisted_recipient, reject_invalid_helo_hostname, reject_non_fqdn_sender, reject_unknown_sender_domain, permit

You can check this article to find the details about the parameters that are being used in these restrictions.

Imagine, your remote end SMTP client implemented an obsolete version of AUTH, then you can allow/reject this such request from it. But to keep your email transaction smooth you can set this parameter yes to allow those SMTP clients who uses older version of AUTH.

broken_sasl_auth_clients = yes

It is very important to use properly set smtpd_banner. Because When your server sends an email, the remote end server takes close look at your server’s identity (Hostname, rDNS) and greetings (smtpd_banner). If they are not aligned properly, there is a high chance that your mail may get rejected. So set a proper smtpd_banner that aligns with your server identity.

smtpd_banner = $myhostname ESMTP $mail_name

In some cases, you may need to use this smtpd_banner to troubleshoot your email communication with your remote end.

Imagine there is an upcoming Christmas vacation and you are suspecting that your remote end world wide recipient’s server may not be reachable during this time. You can set policy in your server that how long it should keep a message in it’s queue if your server failed to deliver the message in several attempts. You can adjust the queue lifetime as per your convenience.

bounce_queue_lifetime = 5d

What address format you would like for your users. Let me give you an example:

myhostname = mail.example.com
mydomain = example.com

#So if you set,
myorigin = $myhostname 
#Your server will send mail as "user@$myhostname" or the from address will be flaminia@mail.example.com

#But if you set,
myorigin = $mydomain
#Your server will send mail as "user@$mydomain" or the from address will be flaminia@example.com  

So make sure this has been set properly.

It would be great if you can allow/block any SMTP connection to connect with your server at the very beginning. This is where postscreen works. By default it allows your trusted network only, but if you want you can add external list of remote SMTP server’s IP address to be blocked or allowed during postscreen and before being able to deliver email to your SMTP server.

postscreen_access_list = permit_mynetworks

#For custom address list:
postscreen_access_list = permit_mynetworks, cidr:/etc/postfix/postscreen_access.cidr

    # Rules are evaluated in the order as specified.
    # Denylist 192.168.* except        permit     reject

Postscreen listens on port 25 only, so authenticated users from port 587 or 465 won’t be affected by Postscreen. You can also modify the postscreen_greet_action to strengthen the security.

You should not use any range of IPs in mynetworks unless you are sure about their activity. If you want any remote SMTP server relay emails through your server you can add it’s IP to the mynetworks section. For best practice, you should not add your local IP block to mynetworks as it will allow and pass unauthenticated and unsolicited emails generated from your local network.

mynetworks = [::1]/128 your_server_IP/32 any_external_smtp_that_relays_via_this_server/32

#Some other formats of mynetworks:
mynetworks =
mynetworks = !,
mynetworks = [::1]/128 [2001:240:587::]/64
mynetworks = $config_directory/mynetworks
mynetworks = hash:/etc/postfix/network_table
mynetworks = cidr:/etc/postfix/network_table.cidr

When your server exchanges greetings with other SMTP server it greets with smtp_helo_name. So set it properly to avoid any inconvenience.

smtp_helo_name = $myhostname

This information can be specified in the main.cf file for all SMTP clients, or it can be specified in the master.cf file for a specific client, for example:

        mysmtp ... smtp -o smtp_helo_name=remotedomain1.com

SASL authentication should be enabled in SMTP.

smtpd_sasl_auth_enable = yes

#To reject all SMTP connections from unauthenticated clients, set followings:

smtpd_delay_reject = yes
smtpd_client_restrictions = permit_sasl_authenticated, reject

If you have any external gateway/relay device that delivers your non local emails then you could specify them in relayhost segment.

relayhost =
By default it is empty. But you can modify it as follows:

relayhost = [gateway.example.com]
relayhost = [ip_address]

You can enforce policy for sender restriction in SMTP. The default is to permit everything. But you can specify a list of restrictions.

smtpd_sender_restrictions = check_sender_access regexp:/opt/zextras/common/conf/tag_as_originating.re, permit_mynetworks, permit_sasl_authenticated, permit_tls_clientcerts, check_sender_access regexp:/opt/zextras/common/conf/tag_as_foreign.re

A main.cf file can consist of thousands of lines. But if you understand them well it can be your best friend to manage your server and troubleshot email related issues.

We have only mentioned a few policies here. But you can find a whole lot of them in the official website of postfix.

So that’s it for today.


Post your comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Migrate Zimbra From One Server To Another Server | Method-3 | Zimbra
DMARC Alignment Test and How It Helps You Prevent Spoofing on Your E-mail Servers in Carbonio Community Edition | Carbonio CE