postfix - different header checks for incoming and outgoing mail

How can I apply different header_checks for incoming and outoing mail using postfix?

By default, all header_checks are applied to both incoming and outgoing.


Solution 1:

header_checks is done by cleanup so I don't think you can apply it only for incoming or outgoing.

smtp_header_checks is applied only for outgoing mail (smtp client)

Solution 2:

If there is a mail header which you can use to identify which is incoming and which is outgoing mail, with postfix 3.2 or newer you can short-circuit the header_checks, like:

/^Received: .*detect_outgoing_mails/ PASS
/^X-Something: this rule will only match on incoming mails/ HOLD

(but it still gives you only option to match ALL (as before) or to match only incoming or only outgoing mail, and requires relatively new postfix version)

As a better alternative, if you can always receive "outgoing" mail (mail from clients for whom you act as mail relay server) on one port (submission: tcp/587) and incoming mail on tcp/25, you should be able to use master.cf to override header_checks for each one, like this:

submission inet n       -       n       -       -       smtpd
  -o smtpd_enforce_tls=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o header_checks=pcre:/etc/postfix/header_checks.relay

smtp      inet  n       -       -       -       200     smtpd
  -o strict_rfc821_envelopes=yes
  -o header_checks=pcre:/etc/postfix/header_checks.mx

but that won't work if your clients for whom you relay also use tcp/25 as rest of the world. If they do, you could setup alternative port for them and it would work, but feasibility of that depends on your ability to persuade all your users to change their settings.

If you have extra IP to spare, you could also make it mostly transparent for users: let's say you had smtp.example.org as both relay server for users and as your MX with IP a.a.a.a, you could change domain's MX to IP b.b.b.b, and then use one smtpd server at a.a.a.a with one set of header checks, and another smtpd server at b.b.b.b with another set of header checks. This is even easier if you relay only for users from say 192.168.x.x/24 when you could even keep same DNS name and use DNS views to present internal IP for internal clients, and external IP for rest of the world.

And third way is so to use postfix FILTER capability instead of header_check - instead of simple regexp matching, it will forward whole message to your custom script for processing, which can then easily distinguish between incoming and outgoing mail by inspecting headers, and then do any postprocessing as wanted.