In Part 8 of the Mailserver Configuration series, we are going to go over setting up restrictions in Postfix. Right now our mailserver does very little to verify the sender of a message. We are going to tell Postfix to see what IP address a message is coming from before accepting it, and if that IP is on a RBL (Realtime Blackhole List) Postfix will be told to reject it. Postifx will also check to make sure that the domain the message is being sent to even exists on the system.
Open up “/etc/postfix/main.cf” using:
Scroll to the bottom of the file and add the following lines:
# HELO restrictions: smtpd_delay_reject = yes smtpd_helo_required = yes #smtpd_helo_restrictions = # permit_mynetworks, # reject_non_fqdn_helo_hostname, # reject_invalid_helo_hostname, # reject_unknown_helo_hostname, # permit
The smtpd_delay_reject line seems a bit strange because one would think that we would want to reject the message immediately. The reasons behind delaying the reject are; when the server receives the message it gets logged to the maillog, and it is required to usesmtpd_hello_restrictions. Before we get to that line, the smtpd_helo_required line tells Postfix to reject servers that do not identify themselves.
Now the restrictions, permit_mynetworks is used to define our trusted connections so that Postfix will bypass the remaining checks. The reject_non-fqdn_helo_hostname line expands upon the smtpd_helo_required line by not only requiring that the server identify itself, but now it also must use a fully qualified domain name for mail to be accepted. The next line, reject_invalid_helo_hostname, will tell Postfix to check the syntax during HELO.
Another common entry to put in this section is the reject_unknown_helo_hostname line. This tells Postfix that it should check the sender’s DNS for an A or MX record and if it is unable to find one, reject the message. I’m leaving it commented out for now because it can cause a lot of false positives, but depending on how much spam your server receives it may be something to consider.
Finally the permit line will let all messages continue to the next part of the filtering process.
Put this section after the HELO Restriction in your “main.cf” file that should still be open. Sender Restrictions will only be processed if the server makes it through the checks we just defined for the HELO Restrictions.
# Sender restrictions: smtpd_sender_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_non_fqdn_sender, reject_unknown_sender_domain, permit
Edit: Added “permit_sasl_authenticated,” to the file so that email sent by a logged in user will always get allowed.
First of all we want to make sure that any of our known-safe hosts don’t have to go through the filtering process, so the first line permit_mynetworks works in much of the same way as the previous section. Next we want to check if the sender is using a valid email address, reject_non_fqdn_sender**checks the FROM field in the email and makes sure its defined and valid in the way of syntax. Provided the syntax is correct, the FROM domain will be checked for a valid A or MX record in DNS, this is defined by the reject_unknown_sender_domain. This line responds to the sending server saying that it should try again later just in case there is a temporary DNS problem. Again the permit line behaves the same way as the HELO restrictions above, it will allow the message to the next step in the filtering process.
If the sending client makes it this far through the process, we at least know that the message might possibly be valid, however there is still more checking that can be done to make sure the message is valid. Make sure this step is after the previous two restrictions, these checks use sources other than Postifx’s built-in functions and therefore require more CPU cycles to process. The vast majority of spam will be filtered out by the previous filters, so there should be very little mail getting this far, and again we have a permit_mynetworks line to bypass some of the more CPU-intensive checks in this step. Add the following to the end of main.cf:
# Recipient restrictions: smtpd_recipient_restrictions = reject_unauth_pipelining, permit_sasl_authenticated, reject_non_fqdn_recipient, reject_unknown_recipient_domain, permit_mynetworks, # check_sender_access # hash:/etc/postfix/sender_access, reject_rbl_client zen.spamhaus.org, reject_rbl_client bl.spamcop.net, # check_policy_service unix:postgrey/socket, permit
These checks start out by blocking pipelining, this is when a client sends a bunch of commands without waiting for authorization, they do this to get messages out as fast as they can. This will block senders that use this function improperly to send bulk mail.
The next couple lines might look familiar because they resemble some of the commands in the previous sections. These differ however, because they are now used to check the recipient field instead of the sender. If the field is invalid or not on this mailserver, it is rejected. The permit_mynetworks should be familiar by now.
If you have prior knowledge of older versions of Postfix, you might notice that the reject_unauth_destination line is missing. This line tells Posfix that it is to reject any email that is not hosted on this machine or that this machine isn’t a backup for, in other words it keeps the server from forwarding spam from a source to anywhere other than a mailbox it manages. The settings for this changed in the newer version of Postfix, I documented the updated setting in Part 2 of the series under “Postfix Configuration” in the “master.cf” file. The updated line is: (The line below is for reference purposes only, it was configured in part 2. Don’t add it to your main.cf file or stuff will break.)
Now the next line provides a link to a file: “/etc/postfix/sender_access” this file defines a list of full or partial email addresses along with a “REJECT” or “OK” entry to tell Postfix what to do with the matching emails. Below is an example of this file, you will need to create it and configure it specifically for your environment, and can go back and make changes to it as time goes on. I am going to leave this portion commented out for now and will determine whether it is needed based on how much spam is getting through.
# /etc/postfix/sender_access # # Black/Whitelist for senders matching the 'MAIL FROM' field. Examples... # email@example.com OK firstname.lastname@example.org REJECT marketing@ REJECT theboss@ OK deals.marketing.com REJECT somedomain.com OK
Anytime you modify this file, you will need to run the following command to tell Postfix to update it’s configuration.
Generally you don’t want to add your own domain to this list because spammers could spoof your domain as the sender list, meaning they would skip the Blackhole List check configured next.
The next lines check the sender’s IP address against a list of known spammers, and rejects the message immediately. A quick internet search for RBLs can give you more, I have only included the common ones. Just be aware that each list you add increases the time and CPU cycles required to process a message.
The final line that I have commented out is for postgrey checking, configuring postgrey is recommended, but takes a lot of tweaking, trial, and error to make it work effectively and not block too much. Postgrey could easily take an entire blog post to configure, therefore I am going to leave it for another time.
The final permit line marks the end of our Restrictions. If the mail makes it through all these checks, it is probably a valid message and will be delivered to the user’s Inbox.
Configuring the restrictions concludes the Mailerver Configuration series. I hope I was able to help at least a few people get their own Open-Source mailserver configured. At some point I want to do a post on configuring Rainloop mail client because of it’s better mobile support compared to Roundcube. Rainloop would be run parallel with Roundcube, giving users the option of using either mail client to get their mail. With that, I wish you good luck as a mailserver administrator.
If you missed any part of the series, you can select it from the Index below: