GURI SoftHouse
System Development,
Auditing and Consulting
Link to postfix site

My studies of Postfix and the unacceptable features.

I'm trying my best! This is not means that the result will be really the best!

POSTFIX FEATURES BY ULISSES GUEDES

NEXTBLINE and BYPASS are unofficial POSTFIX features developed by Ulisses Guedes. To build a postfix version with this features then download the patched postfix version and build it, following the instructions below.

Quick concept revision of Postfix capabilities:

Postfix reads and filters one line per time when it checks the header and body lines, by using (header|body|mime)_checks any (header+body) message part. No matter if it is destination email address.

Inside those *_checks you can create some condition and take some action if the conditions are at same line. For instance of headers:

if /From:/
/john@domain/ action1
/dude@domain/ action2
endif

But the following rule is invalid:

if /From: john@domain/
/To: dude@domain/ action1
endif

For that you must create an exclusive restriction class:

/From\: john\@domain/ restrclass1

at main.cf

restrclass1 = pcre:relatedjohn.pcre

and in relatedjohn.pcre file:

/To\: dude\@domain/ action1

So action1 rule requests dual condition at diferent physical lines, and that rule will not work if, and only if,the relatedjohn.pcre condition cames first.

Spammers know that because RFC allows it. For one effective solution (with the original Postfix code) is create a hook to procmail, by using thecnics of after-queue or before-queue filters.

unofficial POSTFIX features

The unofficial POSTFIX features attempt to the following scenarios:

NEXTBLINE

NEXTBLINE feature allows every postfix action (REJECT, WARN, BYPASS, HOLD, DISCARD, PREPEND, etc) according to 2 conditions that may occur both of them at header or at body, even those ones occur one at header and another at body message part.

For those, the action keys must be followed by tokens:

=
for same place - body or header
%
if the first condition occurs in header and the second one in body, separated by spaces or tabs from the action.

The token must be followed by a number from 0 upto the nearest small number defined by parameter "nextbline_index_limit" in main.cf. The token is an identification condition pair.

This takes precedences over the action. So the action may vary according to the winner sequential rule.

The default value of "nextbline_index_limit" is 10. With this value you are defining the rule to remember 10 dual conditions in header, 10 in body and 10 in header followed in body.

Examples:

Consider the following rules in header_checks=[regexp|pcre]:/etc/postfix/header_checks:

/To: anybody@somedomain\.com/  SOMEKEYS =1 text1
/Subject: .*marketing/    SOMEKEYS =1 text2
/From: marketingspam@/    SOMEKEYS %1 text3

Now, consider the following rules at body_checks:

/To be removed from this mailing/  SOMEKEYS =1 text4
/click here/        SOMEKEYS =1 text5
/this is restrictly confidential/  SOMEKEYS %1 text6

where SOMEKEYS may be any action provided by postfix: REJECT, OK, DUNNO, WARN, DISCARD, HOLD, REDIRECT, etc, including BYPASS.

At example, in header_checks, the conditions To: and Subject: are linked. So a message that has those conditions in header will be subjected to the verb SOMEKEYS, and it will be applied retunning a message defined by text1 (if To: is matched later) or text2 (it Subject is matched later). No matter what condition is the first one. Spammers do not follows any RFC.

Another two-lines condition was linked by body_checks file. Althought they have the same index (=1) defined in header but they are in different part of message and will not joined. If the line /To be removed .../ and /click here/ are matched then the message will be subjected to SOMEKEYS action.

At same example, we found:

"From: marketingspam@" in header and
/this is restrictly confidential/ in body.

These two conditions are joined by index "%1", and the text6 will be returned.

associated variables: nextbline_line_count

At some cases, spammers may change the positions and orders of headers, including some blank lines or lines with character space. If this is the case, it was defined a configurable variable "nextbline_line_count" in main.cf. So the matches occurs between 'nextbline_line_count' lines and the defined action will be applied. For instance: with nextbline_line_count = 2 then the following the dual condition may be separated upto 2 any other header lines.

BYPASS

WARNING: THIS ACTION WILL IMPLEMENT A SECURITY HOLE IF IT IS NOT PROPERLY CONFIGURED.

BYPASS disable all actions in smtpd rules, header or body checks for that message when a condition matches.

The sintaxe is:

/condition/ BYPASS[#nn] [(=|%)mm] text

where
nn
It is the number of recipients allowed. When the #nn is not defined the number of recipients valid is equal to 1.

= or %
They are the link condition flags (see nextbline)

mm
It is the number of this link.

The signature defined by sender must agree with that in local header or body_check files:

Example in body or header_checks:

/X-signature: XbYu19034Hd3Dsfgr/ BYPASS

This signature may be anything: a specific header contents or a phrase in message body.

Since it alone may implement a security hole, it MUST BE used following some rules defined by NEXTBLINE or by some rules that will verify the IP address of the client system and/or by a number os recipients (#nn)

/received: from .*[10\.1\.2\.3]/ BYPASS#1 =2
/X-signature: XbYu19034Hd3Dsfgr/ BYPASS#1 =2


When defined at check_{client|helo|sender|data|recient}_restriction the action analysis only the number of recipients.

BYPASS provides the same action of WARN, logging in syslog that action.

The SMTPD was changed to provide a special signature when a message was bounced to postmaster (only). The signature is defined by smtpd_bypass_rules_sign in main.cf. So you can forward the message to another system bypassing the remote rules easily.

When defined, a message header X-Postmaster-Signature: is inserted with the value defined by smtpd_bypass_rules_sign parameter. It is usefull when the postmaster of mailhub has an alias (usually to a normal and internal user) subject to internal filters.

Since this signature may be discovered, BYPASS is restricted to only one destination (one recipient) per default. So, for m(asshole) lists that rule will not be validated, even bypass signature was find out.

MATCHFROM

Although this feature did not attempts RFCs, it had showed usefull for some messages types.

At "normal" messages, those sent by "good users" that uses Outlook, Thunderbird, as should be configured, the message will always have the enevelop sender address (MAUL FROM) equals to the header sender address ("From:"). RFC 2282 and laters, shows that this can't happen at some well know conditions.

However, at malicious messages, or spam messages, the sender changes those e-mail address. Usually forging the header 'From:, attempting to bypass some procmail rule.

MATCHFROM matches the both fields (envelop and header senders). If they are different then its action is the same of HOLD. This action allows a delayed message analysis by other sofisticated filter.

Usage:

At some file of smtpd_data_restriction:
/From\:/ MATCHFROM

SPAMHOLD

Messages that fell on some blocking rule can not be just spam or malicious, especially when some rule was inserted to hold any event with urgency and that can interfere with normal messages.

One way around the problem is to retain the message for a future review by administrator and by recipient user.

The action SPAMHOLD modifies the destination address including the word 'spamming' in incício destination address, which may be aliased to the same recipient, but the message will be kept in HOLD queue. Thus, after review, a user and administrator could set the filters of your MUA without losing the message.

REDIRECT or REPLACE could be used, but they send the message and HOLD action only put the message on hold queue. Tunneling variables:
smtpd_bypass_rule_sign:
Define the signature to be inserted at smtp bounced messages sent to postmaster only.


hold_on_bypass
A logical variable to control if that message will be hold or delivered to recipient.

WHERE THE CHANGES WERE DONE

Resources NEXTBLINE, BYPASS, and SPAMHOLD MATCHFROM are implemented, specifically, in the archives:

  1. src/cleanup/cleanup.h
  2. src/cleanup/cleanup_message.c
  3. src/cleanup/cleanup_out.c
  4. src/cleanup/cleanup_state.c
  5. src/global/mail_params.h
  6. src/global/mail_version.h
  7. src/global/mail_params.c
  8. src/smtpd/smtpd.h
  9. src/smtpd/smtpd.c
  10. src/smtpd/smtpd_check.c
  11. src/util/mymalloc.h
  12. src/util/mymalloc.c
  13. makedefs

Compiling & Building

This unofficial Postfix source code must be compiled with -DHAS_NEXTBLINE and/or -DHAS_BYPASS in CCARGS.

Without those definitions the binaries generated are the same of official Postfix.

Comments About NETXTBLINE and BYPASS

Some NEXTBLINE action can be done by using RESTRICTION_CLASS.
Available docs and infos to configure restriction classes may be retrieved from http://www.arschkrebs.de/postfix/. Try as suggested there and conclude by yourself.

All these rules may be done using a procmail or a thirty-party software outside postfix.
That is a good and old news! We used those software for years too! The problem is that: they are THIRTY-PARTY software that also implements a system overhead but NEXTBLINE and BYPASS does not!

The mime_header feature may solve the same problem.
Yes! They can, but only for strictly same logical line, not physical ones.

The NEXTBLINE does the same action of OK.
Wrong! OK does nothing. It only verify that pattern. NEXTBLINE does much more than this. See the code... It is free!

This code is broken. It does hard what procmail does with the hand in back.
This code is a study! It is not a perfect code. You can improved it as you wish, including modification. The original postfix source code is "perfect". There is "none" bug there, neither error of logical implementation nor unusefull feature. The code changed was not accepted as contribution to postfix, so you use it "as is". I'm soo hear for comments, suggestions, fixes, and so far (good ones, of course!). These features have being used since postfix 2.0.10 (2003/May/21) without any problem. It works fine and, sorry, it is not broken!

BYPASS implements a serious security hole.
I already said this before. Administrators MUST change the signature every day. How long a man in middle of attack can guest the root password of your system, or intercept all communications between systems without backdoors, or internal colaboration? Take this signature as a mail-password key. Only postmaster will receive that. If you have some "bad opinion" about your postmaster the solution is to change him and the signature too.... of course.