Ulrich Kautz

NAME

Mail::Decency::ContentFilter

SYNOPSIS

    use Mail::Decency::ContentFilter;
    
    my $content_filter = Mail::Decency::ContentFilter->new( {
        config => '/etc/decency/content-filter.yml'
    } );
    
    $content_filter->run;

DESCRIPTION

Postfix:Decency::ContentFilter implements multiple content filter

POSTFIX

You have to edit two files: master.cf and main.cf in /etc/postfix

master.cf

Add the following to the end of your master.cf file:

    # the decency server itself
    decency     unix  -       -       n       -       4        smtp
        -o smtp_send_xforward_command=yes
        -o disable_dns_lookups=yes
        -o max_use=20
        -o smtp_send_xforward_command=yes
        -o disable_mime_output_conversion=yes
        -o smtp_destination_recipient_limit=1
    
    # re-inject mails from decency for delivery
    127.0.0.1:10250      inet  n       -       -       -       -       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_unauth_destination,permit
        -o mynetworks=127.0.0.0/8
        -o smtpd_authorized_xforward_hosts=127.0.0.0/8

main.cf

There are two possible ways you can include this content filter into postfix. The first is via content_filter, the second via check_*_access, eg check_client_access.

  • content_filter

    The advantage: it is easy. The disadvantage: all mails (incoming, outgoing) will be filtered. In a one-mailserver-for-all configuration this might be ugly.

        # main.cf
        content_filter = decency:127.0.0.1:16000
  • Via check_*_access

    And example using pcre on all mails would be:

        # main.cf
        smtpd_client_restrictions =
            # ...
            check_client_access = pcre:/etc/postfix/decency-filter, reject
            # ...

    Then in the /etc/postfix/decency-filter file:

        # /path/to/access
        /./ FILTER decency:127.0.0.1:16000

CONFIG

Provide either a hashref or a YAML file.

Example:

    ---
    
    spool_dir: /var/spool/decency
    
    accept_scoring: 1
    policy_verify_key: sign.pub
    
    notification_from: 'Postmaster <postmaster@localhost>'
    
    enable_stats: 1
    
    
    include:
        - logging.yml
        - database.yml
        - cache.yml
    
    server:
        host: 127.0.0.1
        port: 16000
        instances: 3
    
    reinject:
        host: 127.0.0.1
        port: 10250
    
    spam:
        behavior: scoring
        threshold: -50
        handle: tag
        noisy_headers: 1
        spam_subject_prefix: "SPAM:"
        
        # for handle: bounce or delete:
        #notify_recipient: 1
        #recipient_template: 'templates/spam-recipient-notify.tmpl'
        #recipient_subject: 'Spam detection notification'
    
    virus:
        handle: bounce
        
        # for handle: bounce, delete or quarantine
        notify_sender: 1
        notify_recipient: 1
        sender_template: 'templates/virus-sender-notify.tmpl'
        sender_subject: 'Virus detection notification'
        recipient_template: 'templates/virus-recipient-notify.tmpl'
        recipient_subject: 'Virus detection notification'
    
    
    filters:
        #- MimeAttribs: "content-filter/mime-attribs.yml"
        - DKIM: "content-filter/dkim.yml"
        # - ClamAV: content-filter/clamav.yml
        - Bogofilter: content-filter/bogofilter.yml
        #- DSPAM: content-filter/dspam.yml
        - CRM114: content-filter/crm114.yml
        - Razor: content-filter/razor.yml
        - HoneyCollector: content-filter/honey-collector.yml
        # -
        #     SpamAssassin:
        #         disable: 0
        #         default_user:
        #         weight_translate:
        #             1: -100
        #             -2: 0
        #             -3: 100
        - Archive: content-filter/archive.yml
    

CLASS ATTRIBUTES

spool_dir : Str

The directory where to save received mails before filtering

temp_dir : Str

Holds temp files for modules

queue_dir : Str

Holds queued mails (currently working on)

mime_output_dir : Str

Directory for temporary mime output .. required by MIME::Parser

Defaults to spool_dir/mime

reinject_failure_dir : Str

Directory for reinjection failures

Defaults to spool_dir/failure

quarantine_dir : Str

Directory for quarantined mails (virus, spam)

Defaults to spool_dir/quarantine

spam_*

There is either spam scoring, strict or keep.

Keep account on positive or negative score per file. Each filter module may increment or decrement score on handling the file. The overall score determines in the end wheter to bounce or re-inject the mail.

spam_behavior : Str

How to determine what is spam. Either scoring, strict or ignore

Default: scoring

spam_handle : Str

What to do with recognized spam. Either tag, bounce or delete

Default: tag

spam_subject_prefix : Str

If spam_handle is tag: "Subject"-Attribute prefix for recognized SPAM mails.

spam_threshold : Int

For spam_behavior: scoring. Each cann add/remove a score for the filtered mail. SPAM scores are negative, HAM scores positive. If this threshold is reached, the mail is considered SPAM.

Default: -100

spam_notify_recipient : Bool

If enabled -> send recipient notification if SPAM is recognized.

Default: 0

spam_recipient_template : Str

Path to template used for SPAM notification.

spam_recipient_subject : Str

Subject of the recipient's SPAM notification mail

Default: Spam detected

spam_noisy_headers : Bool

Wheter X-Decency headers in mail should contain detailed information.

Default: 0

virus_*

Virus handling

virus_handle : Str

What to do with infected mails ? Either: bounce, delete or quarantine

Default: ignore

virus_notify_recipient : Bool

Wheter to notofy the recipient about infected mails.

Default: 0

virus_recipient_template : Str

Path to template used for recipient notification

virus_recipient_subject : Str

Subject of the recipient's notification mail

Default: Virus detected

virus_notify_sender : Str

Wheter to notify the sender of an infected mail (NOT A GOOD IDEA: BACKSCATTER!)

Default: 0

virus_sender_template : Str

Path to sender notification template

virus_sender_subject : Str

Subject of the sender notification

Default: Virus detected

accept_scoring : Bool

Wheter to accept scoring from (external) policy server.

Default: 0

policy_verify_key : Str

Path to public (verification) key for scoring verification

Default: 0

policy_verify_key_rsa : Crypt::OpenSSL::RSA

Instance of verification key (Crypt::OpenSSL::RSA)

session_data : Mail::Decency::Core::SessionItem::ContentFilter

SessionItem (Mail::Decency::Core::SessionItem::ContentFilter) of the current handle file

notification_from : Str

Notification sender (from address)

Default: Postmaster <postmaster@localhost>

METHODS

init

Init cache, database, logger, dirs and content filter

init_dirs

Inits the queue, checks spool dir for existing files -> read them

init_content_filters

Reads all content filters, creates instance and add to list of filters

start

Starts all POE servers without calling the POE::Kernel->run

run

Start and run the server via POE::Kernel->run

train

Train spam/ham into modules

get_handlers

Returns code ref to handlers

    my $handlers_ref = $content_filter->get_handlers();
    $handlers_ref->( {
        file => '/tmp/somefile',
        size => -s '/tmp/somefile',
        from => 'sender@domain.tld',
        to   => 'recipient@domain.tld',
    } );

handle

Calls the handle method of all registered filters.

Will be called from the job queue

finish_spam

Called after modules have filtered the mail. Will perform according to spam_handle directive.

  • delete

    Remvoe mail silently

  • bounce

    Bounce mail back to sender

  • ignore

    Ignore mail, simply forward

  • tag

    Tag mail, insert X-Decency-Status and X-Decency-Score headers. If detailed: also X-Decency-Details header.

finish_virus

Mail has been recognized as infected. Handle it according to virus_handle

  • bounce

    Send back to sender

  • delete

    Silently remove

  • quarantine

    Do not deliver mail, move it into quarantine directory.

  • ignore

    Deliver to recipient

finish_ok

Called after mails has not been recognized as virus nor SPAM. Do deliver to recipient. With noisy_headers, include spam X-Decency-(Result|Score|Details) into header.

reinject

Reinject mails to postfix queue, or archive in send-queue

send_notify

Send either spam or virus notification

    $content_filter->send_notify( virus => recipient => 'recipient@domain.tld' );

session_init

Inits the Mail::Decency::Core::SessionItem::ContentFilter session object for the current handled mail.

session_write_cache

Write session to cache. Called at the end of the session.

add_spam_score

Add spam score (positive/negative). If threshold is reached -> throw Mail::Decency::Core::Exception::Spam exception.

virus_info

Virus is found. Throw Mail::Decency::Core::Exception::Virus exception.

_save_mail_to_dir

Save a mail to some dir. Called from quarantine or reinjection failures

AUTHOR

Ulrich Kautz <uk@fortrabbit.de>

COPYRIGHT

Copyright (c) 2010 the "AUTHOR" as listed above

LICENCSE

This library is free software and may be distributed under the same terms as perl itself.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 115:

You forgot a '=back' before '=head1'