Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Postfix Documentation
Previous Page Home Next Page

Advanced content filter example

The second example is more complex, but can give better performance, and is less likely to bounce mail when the machine runs into some resource problem. This content filter receives unfiltered mail with SMTP on localhost port 10025, and sends filtered mail back into Postfix with SMTP on localhost port 10026.

For non-SMTP capable content filtering software, Bennett Todd's SMTP proxy implements a nice PERL/SMTP content filtering framework. See: https://bent.latency.net/smtpprox/.

In the figure below, names followed by a number represent Postfix commands or daemon programs. See the OVERVIEW document for an introduction to the Postfix architecture.

Unfiltered

Unfiltered
->

->
smtpd(8)

pickup(8)
>- cleanup(8) -> qmgr(8)
Postfix
queue
-< smtp(8)

local(8)
->

->
Filtered

Filtered
^
|
|
v
smtpd(8)
10026
smtp(8)
^
|
|
v
content filter 10025

The example given here filters all mail, including mail that arrives via SMTP and mail that is locally submitted via the Postfix sendmail command. See examples near the end of this document for how to exclude local users from filtering, or how to configure a destination dependent content filter.

You can expect to lose about a factor of two in Postfix performance for mail that arrives and leaves via SMTP, provided that the content filter creates no temporary files. Each temporary file created by the content filter adds another factor to the performance loss.

Advanced content filter: requesting that all mail is filtered

To enable the advanced content filter method for all mail, specify in main.cf:

/etc/postfix/
main.cf:
    
content_filter = scan:localhost:10025
    
receive_override_options = 
no_address_mappings
  • The " content_filter" line causes Postfix to add one content filter request record to each incoming mail message, with content "scan:localhost:10025". The content filter request records are added by the smtpd(8) and pickup(8) servers (and qmqpd(8) if you decide to enable this service).

  • Content filter requests are stored in queue files; this is how Postfix keeps track of what mail needs filtering. When a queue file contains a content filter request, the queue manager will deliver the mail to the specified content filter regardless of its final destination.

  • The " receive_override_options" line disables address manipulation before the content filter, so that the content filter sees the original mail addresses instead of the result of virtual alias expansion, canonical mapping, automatic bcc, address masquerading, etc.

Advanced content filter: sending unfiltered mail to the content filter

In this example, "scan" is an instance of the Postfix SMTP client with slightly different configuration parameters. This is how one would set up the service in the Postfix master.cf file:

/etc/postfix/
master.cf:
    # =============================================================
    # service type  private unpriv  chroot  wakeup  maxproc command
    #               (yes)   (yes)   (yes)   (never) (100)
    # =============================================================
    scan      unix  -       -       n       -       10      smtp
        -o 
smtp_send_xforward_command=yes
        -o 
disable_mime_output_conversion=yes
  • This runs up to 10 content filters in parallel. Instead of a limit of 10 concurrent processes, use whatever process limit is feasible for your machine. Content inspection software can gobble up a lot of system resources, so you don't want to have too much of it running at the same time.

  • With "-o smtp_send_xforward_command=yes", the scan transport will try to forward the original client name and IP address through the content filter to the after-filter smtpd process, so that filtered mail is logged with the real client name IP address. See smtp(8) and XFORWARD_README for more information.

  • The "-o disable_mime_output_conversion=yes" is a workaround that prevents the breaking of domainkeys and other digital signatures. This is needed because some SMTP-based content filters don't announce 8BITMIME support, even though they can handle it just fine.

Advanced content filter: running the content filter

The content filter can be set up with the Postfix spawn service, which is the Postfix equivalent of inetd. For example, to instantiate up to 10 content filtering processes on localhost port 10025:

/etc/postfix/
master.cf:
    # ===================================================================
    # service       type  private unpriv  chroot  wakeup  maxproc command
    #                     (yes)   (yes)   (yes)   (never) (100)
    # ===================================================================
    localhost:10025 inet  n       n       n       -       10      spawn
        user=filter argv=/path/to/filter localhost 10026
  • "filter" is a dedicated local user account. The user will never log in, and can be given a "*" password and non-existent shell and home directory. This user handles all potentially dangerous mail content - that is why it should be a separate account.

If you want to have your filter listening on port localhost:10025 instead of Postfix, then you must run your filter as a stand-alone program, and must not use the Postfix spawn service.

Advanced filter: injecting mail back into Postfix

The job of the content filter is to either bounce mail with a suitable diagnostic, or to feed the mail back into Postfix through a dedicated listener on port localhost 10026.

The simplest content filter just copies SMTP commands and data between its inputs and outputs. If it has a problem, all it has to do is to reply to an input of `.' from Postfix with `550 content rejected', and to disconnect without sending `.' on the connection that injects mail back into Postfix.

/etc/postfix/
master.cf:
    # ===================================================================
    # service       type  private unpriv  chroot  wakeup  maxproc command
    #                     (yes)   (yes)   (yes)   (never) (100)
    # ===================================================================
    localhost:10026 inet  n       -       n       -       10      smtpd
        -o 
content_filter= 
        -o 
receive_override_options=
no_unknown_recipient_checks,
no_header_body_checks,
no_milters
        -o 
smtpd_helo_restrictions=
        -o 
smtpd_client_restrictions=
        -o 
smtpd_sender_restrictions=
        -o 
smtpd_recipient_restrictions=
permit_mynetworks,reject
        -o 
mynetworks=127.0.0.0/8
        -o 
smtpd_authorized_xforward_hosts=127.0.0.0/8
  • Note: do not use spaces around the "=" or "," characters.

  • Note: the SMTP server must not have a smaller process limit than the "filter" master.cf entry.

  • The "-o content_filter=" overrides main.cf settings, and requests no content filtering for mail from the content filter. This is required or else mail will stay in the content filtering loop.

  • The "-o receive_override_options" overrides main.cf settings to avoid duplicating work that was already done before the content filter. These options are complementary to the options that are specified in main.cf:

    • We specify " no_unknown_recipient_checks" to disable attempts to find out if a recipient is unknown.

    • We specify " no_header_body_checks" to disable header/body checks.

    • We specify " no_milters" to disable Milter applications (this option is available only in Postfix 2.3 and later).

    • We don't specify "no_address_mapping" here. This enables virtual alias expansion, canonical mappings, address masquerading, and other address mappings after the content filter. The main.cf setting of " receive_override_options" disables these mappings before the content filter.

    These receive override options are either implemented by the SMTP server itself, or they are passed on to the cleanup server.

  • The "-o smtpd_xxx_restrictions" and "-o mynetworks=127.0.0.0/8" override main.cf settings. They turn off junk mail controls that would only waste time here.

  • With "-o smtpd_authorized_xforward_hosts=127.0.0.0/8", the scan transport will try to forward the original client name and IP address to the after-filter smtpd process, so that filtered mail is logged with the real client name and IP address. See XFORWARD_README and smtpd(8).

Postfix Documentation
Previous Page Home Next Page