This is a rough design for the postscreen policy callout.

        Wietse

High-level description
======================

After checking the postscreen_access_list, postscreen will call out
to an optional policy service before making DNS queries or sending
the PREGREET banner to the client.

The policy test is just another test that the client must pass
before it can talk to a real Postfix SMTP server.  Just like all
other postscreen tests, a successful policy test is remembered for
some amount of time so that a good client does not have to be tested
with every connection that it makes.

Configuration parameters:

    postscreen_policy_service = inet:host:port | unix:pathname
    postscreen_policy_timeout = time in seconds
    postscreen_policy_default_ttl = time in seconds
    postscreen_policy_default_action = pass | ignore | enforce | drop

The host and port may be numeric or symbolic. If the policy server
is local, specify 127.0.0.1 or ::1 for maximal robustness.

Actions:

    pass: Skip this test for this client, for the amount of time
    specified with postscreen_policy_default_ttl.

    ignore, enforce, drop: These actions have the exact same meaning
    as with other postscreen tests (specifically, "enforce" allows
    other tests to complete, rejects attempts to deliver mail with
    a 550 SMTP reply, and logs the helo/sender/recipient information).
    The postscreen_policy_default_ttl value is ignored.

Protocol
========

postscreen sends a request over a policy service connection and
expects a reply over that same connection. Once the reply is received,
that connection may be reused for another policy request. It is an
error for a policy server to close a connection after sending a
response.

postscreen will use parallel connections when multiple policy queries
are in progress.

Each policy request contains name=value attributes with the local
and remote address and port.

Request format:
    client_address "=" <IPv4 address> | <IPv6 address> <newline>
    server_address "=" <IPv4 address> | <IPv6 address> <newline>
    client_port "=" <numerical port> <newline>
    server_port "=" <numerical port> <newline>
    <newline>

The order of the attributes is unspecified; the order shown above
is just an example for readability. A policy server must ignore
attribute names that it does not know.

Each policy response must contain an action and may contain a ttl
value that indicates how long postscreen will skip a policy test
that returns a "pass" result.

Reply format:
    action "=" "pass" | "ignore" | "enforce" | "drop" <newline>
    ttl "=" <time in seconds> <newline>
    <newline>

See "Configuration parameters" above for a description of actions.
With actions other than "pass", postscreen ignores the ttl attribute.

If a "pass" action specifies no ttl, postscreen_policy_default_ttl
is used instead.

Error handling
==============

When postscreen cannot complete a policy service request, it will
use the postscreen_policy_default_action and postscreen_policy_default_ttl.

Examples of errors:

- The policy server connection is not ready to write (write would block).

- The policy server does not respond to a connection request or
  policy request within the postscreen_policy_timeout.

- The policy server response is malformed.

Alternatives considered
=======================

Instead of doing the policy check before DNSBL and PREGREET checks,
they could be done in parallel, at least some of the time. Then, 
the policy timeouts could be more relaxed. Unfortunately that
requires that the PREGREET or DNSBL checks expire at the same time 
as the policy check ttl, which is hard to guarantee.

Reply via email to