Home // Postfix Guides // Header Checks

Header Checks

The first thing that needs to be done is to enable header checks in the Postfix main.cf configuration file. This will tell postfix where to look for the header checks file.

To do this, add the following lines to main.cf:
header_checks = regexp:/etc/postfix/maps/header_checks
mime_header_checks = regexp:/etc/postfix/maps/mime_header_checks

If you are using pcre instead of regexp, you will use:
header_checks = pcre:/etc/postfix/header_checks
mime_header_checks = pcre:/etc/postfix/mime_header_checks

The format for each line in the header_checks file is as follows:
/^HEADER: .*content_to_act_on/ ACTION

The HEADER listed can be any header available in an email. The Subject header is the most popular to reject on for key words or phrases in spam filtering, but others can be very useful as well. The X-Mailer header can be used to identify some software or mail clients that are used almost exclusively for spam. Please see the last version of the header checks file for more examples of header checks.

The content to act on is preceded by a .* which specifies that it doesn’t matter what characters were before the content to act on.

The ACTION that will be taken has a number of options available:

REJECT is the most common, and this will cause the email to be rejected by Postfix. In this case, the incoming email will be blocked before it can enter your server. As an option, you can add text after the work REJECT, whereas that text will appear in both your log and the bounce message to the sender of the email. It is a good practice to number your lines in any checks file, as you may sometimes have difficulty identifying which rule caused a particular email to be rejected. A sample reject is as follows:

/^Subject .*Free Money/ REJECT Spam Header Rule #42
This will cause any email that has the words “Free Money” in the subject line to be rejected. The bounce message to the sender and your mail log will both have the text “Spam Header Rule #42” in them. This will allow you to more efficiently find what rule is causing problems or false rejects.

IGNORE will cause that particular header to be removed from the email, and will continue to process the email as normal. This can be useful in some situations. Please seethe Header Removal Guide for more information.

WARN can be very useful when testing new spam filters. An entry will be made in your mail log with a warning on the header, as well as any text that you place after the word “WARN” like with REJECT. It is often advisable to test new filters for a day or two with WARN before implementing them in production. This especially applies to complex rules that could easily have errors.

HOLD will hold the email in a hold queue, so that the system administrator can later take action (delete or release the email).

DISCARD will cause the sending server to think that the email was sent properly, but your Postfix server will silently discard (delete) the email. This option is for instances where you don’t want the remote person or server to know that the email was deleted.

FILTER will allow you to specify another instance of postfix, filter, or server where to send the email. After the word FILTER, you will add an entry like in the transport map file of transport:nexthop. Please see the transport map documentation for more information.

As spammers have become a lot more devious in finding ways to slip their emails past filters, header_checks has become a lot more useful in defining complex filtering schemes. Following are a few examples.

/^Subject: .*        / REJECT Spam Header Many Spaces 1
In this example, any subject with more than eight spaces will be rejected. In normal circumstances, there are very few reasons for someone to put eight spaces in a subject. Many automates spam sending tools and systems will add spaces at the end of a subject, and then place a code identifying the message or some other details.

/^Date: .* 200[0-2]/ REJECT Spam Header Past Date 1
/^Date: .* 19[0-9][0-9]/ REJECT Spam Header Past Date 2

These two examples will reject emails that appear to have been sent in the past (it is currently 2003 as of the time of this writing). Many spammers use dates far in the past (or the future) to make their emails appear at the top of your list.

/^Subject: .*f[ _\.\*\-]+r[ _\.\*\-]+e[ _\.\*\-]+e/ REJECT Hidden Word 1
This example shows how some spammers use different characters in between words to slip their messages past filters. In this example, the word “free” can be disguised with various characters in between the letters, and the header check will still reject it.

In the mime_header_checks file, you will place a restriction for any file extentsons that you do not want to have passing through your system. For example:

/name=[^>]*\.(bat|com|exe)/ REJECT
This will reject any messages that have attachments whose files end in .bat, .com, or .exe. There are many more file extensions that can be considered dangerous. Please see the latest mime_header_checks file for more information.

You will have to deal with false rejects now and again. Either when users complain that they are not getting email, or when in looking at the mail logs you find that there are apparently valid emails being rejected. In this case, it should not be difficult to find the culprit rule, as you’ve added a rule number to the end of the reject string.

As you can see, header checks are not just about the words in the subject. They can be detailed and granular enough to catch even the strangest spam headers.