diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:18:56 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:18:56 +0000 |
commit | b7c15c31519dc44c1f691e0466badd556ffe9423 (patch) | |
tree | f944572f288bab482a615e09af627d9a2b6727d8 /proto | |
parent | Initial commit. (diff) | |
download | postfix-b7c15c31519dc44c1f691e0466badd556ffe9423.tar.xz postfix-b7c15c31519dc44c1f691e0466badd556ffe9423.zip |
Adding upstream version 3.7.10.upstream/3.7.10
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'proto')
95 files changed, 65046 insertions, 0 deletions
diff --git a/proto/ADDRESS_CLASS_README.html b/proto/ADDRESS_CLASS_README.html new file mode 100644 index 0000000..ca4bb67 --- /dev/null +++ b/proto/ADDRESS_CLASS_README.html @@ -0,0 +1,279 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Address Classes </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Address Classes </h1> + +<hr> + +<h2>Introduction</h2> + +<p> Postfix version 2.0 introduces the concept of address classes. +This is a way of grouping recipient addresses by their delivery +method. The idea comes from discussions with Victor Duchovni. +Although address classes introduced a few incompatibilities they +also made it possible to improve the handling of hosted domains +and of unknown recipients. </p> + +<p> This document provides information on the following topics: </p> + +<ul> + +<li><a href="#wtf">What are address classes good for?</a> + +<li><a href="#classes">What address classes does Postfix implement?</a> + +<li><a href="#improvements">Improvements compared to Postfix 1.1</a> + +<li><a href="#incompatibility">Incompatibilities with Postfix 1.1</a> + +</ul> + +<h2><a name="wtf">What are address classes good for?</a></h2> + +<p> Why should you care about address classes? This is how Postfix +decides what mail to accept, and how to deliver it. In other words, +address classes are very important for the operation of Postfix. </p> + +<p> An address class is defined by three items. </p> + +<ul> + +<li> <p> The list of domains that are a member of the class: for +example, all local domains, or all relay domains. </p> + +<li> <p> The default delivery transport. For example, the local, +virtual or relay delivery transport (delivery transports are defined +in master.cf). This helps to keep Postfix configurations simple, +by avoiding the need for explicit routing information in transport +maps. </p> + +<li> <p> The list of valid recipient addresses for that address +class. The Postfix SMTP server rejects invalid recipients with +"User unknown in <name of address class here> table". This +helps to keep the Postfix queue free of undeliverable MAILER-DAEMON +messages. </p> + +</ul> + +<h2><a name="classes">What address classes does Postfix implement?</a></h2> + +<p> Initially the list of address classes is hard coded, but this +is meant to become extensible. The summary below describes the main +purpose of each class, and what the relevant configuration parameters +are. </p> + +<p> The <a name="local_domain_class">local </a> domain class. </p> + +<ul> + +<li> <p> Purpose: final delivery for traditional UNIX system accounts +and traditional Sendmail-style aliases. This is typically used for +the canonical domains of the machine. For a discussion of the +difference between canonical domains, hosted domains and other +domains, see the VIRTUAL_README file. </p> + +<li> <p> Domain names are listed with the mydestination parameter. +This domain class also includes mail for <i>user@[ipaddress]</i> +when the IP address is listed with the inet_interfaces or +proxy_interfaces parameters. </p> + +<li> <p> Valid recipient addresses are listed with the local_recipient_maps +parameter, as described in LOCAL_RECIPIENT_README. The Postfix SMTP +server rejects invalid recipients with "User unknown in local +recipient table". If the local_recipient_maps parameter value is +empty, then the Postfix SMTP server accepts any address in the +local domain class. </p> + +<li> <p> The mail delivery transport is specified with the +local_transport parameter. The default value is <b>local:$myhostname</b> +for delivery with the local(8) delivery agent. </p> + +</ul> + +<p> The <a name="virtual_alias_class">virtual alias </a> domain +class. </p> + +<ul> + +<li> <p> Purpose: hosted domains where each recipient address is +aliased to a local UNIX system account or to a remote address. A +virtual alias example is given in the VIRTUAL_README file. </p> + +<li> <p> Domain names are listed in virtual_alias_domains. The +default value is $virtual_alias_maps for Postfix 1.1 compatibility. +</p> + +<li> <p> Valid recipient addresses are listed with the virtual_alias_maps +parameter. The Postfix SMTP server rejects invalid recipients with +"User unknown in virtual alias table". The default value is +$virtual_maps for Postfix 1.1 compatibility. </p> + +<li> <p> There is no mail delivery transport parameter. Every +address must be aliased to some other address. </p> + +</ul> + +<p> The <a name="virtual_mailbox_class">virtual mailbox </a> domain +class. </p> + +<ul> + +<li> <p> Purpose: final delivery for hosted domains where each +recipient address can have its own mailbox, and where users do not +need to have a UNIX system account. A virtual mailbox example is +given in the VIRTUAL_README file. </p> + +<li> <p> Domain names are listed with the virtual_mailbox_domains +parameter. The default value is $virtual_mailbox_maps for Postfix +1.1 compatibility. </p> + +<li> <p> Valid recipient addresses are listed with the virtual_mailbox_maps +parameter. The Postfix SMTP server rejects invalid recipients with +"User unknown in virtual mailbox table". If this parameter value +is empty, the Postfix SMTP server accepts all recipients for domains +listed in $virtual_mailbox_domains. </p> + +<li> <p> The mail delivery transport is specified with the +virtual_transport parameter. The default value is <b>virtual</b> +for delivery with the virtual(8) delivery agent. </p> + +</ul> + +<p> The <a name="relay_domain_class">relay </a> domain class. </p> + +<ul> + +<li> <p> Purpose: mail forwarding to remote destinations that list +your system as primary or backup MX host. For a discussion of the +basic configuration details, see the BASIC_CONFIGURATION_README +document. For a discussion of the difference between canonical +domains, hosted domains and other domains, see the VIRTUAL_README +file. </p> + +<li> <p> Domain names are listed with the relay_domains parameter. +</p> + +<li> <p> Valid recipient addresses are listed with the relay_recipient_maps +parameter. The Postfix SMTP server rejects invalid recipients with +"User unknown in relay recipient table". If this parameter value +is empty, the Postfix SMTP server accepts all recipients for domains +listed with the relay_domains parameter. </p> + +<li> <p> The mail delivery transport is specified with the +relay_transport parameter. The default value is <b>relay</b> which +is a clone of the smtp(8) delivery agent. </p> + +</ul> + +<p> The <a name="default_domain_class">default </a> domain class. +</p> + +<ul> + +<li> <p> Purpose: mail forwarding to the Internet on behalf of +authorized clients. For a discussion of the basic configuration +details, see the BASIC_CONFIGURATION_README file. For a discussion +of the difference between canonical domains, hosted domains and +other domains, see the VIRTUAL_README file. </p> + +<li> <p> This class has no destination domain table. </p> + +<li> <p> This class has no valid recipient address table. </p> + +<li> <p> The mail delivery transport is specified with the +default_transport parameter. The default value is <b>smtp</b> for +delivery with the smtp(8) delivery agent. </p> + +</ul> + +<h2><a name="improvements">Improvements compared to Postfix +1.1</a></h2> + +<p> Postfix 2.0 address classes made the following improvements +possible over earlier Postfix versions: </p> + +<ul> + +<li> <p> You no longer need to specify all the virtual(8) mailbox +domains in the Postfix transport map. The virtual(8) delivery agent +has become a first-class citizen just like local(8) or smtp(8). +</p> + +<li> <p> On mail gateway systems, address classes provide separation +of inbound mail relay traffic ($relay_transport) from outbound +traffic ($default_transport). This eliminates a problem where +inbound mail deliveries could become resource starved in the presence +of a high volume of outbound mail. </p> + +<li> <p> The SMTP server rejects unknown recipients in a more +consistent manner than was possible with Postfix version 1. This +is needed to keep undeliverable mail (and bounced undeliverable +mail) out of the mail queue. This is controlled by the +smtpd_reject_unlisted_recipient configuration parameter. </p> + +<li> <p> As of Postfix version 2.1, the SMTP server also rejects +unknown sender addresses (i.e. addresses that it would reject as +unknown recipient addresses). Sender "egress filtering" can help +to slow down an email worm explosion. This is controlled by the +smtpd_reject_unlisted_sender configuration parameter. </p> + +</ul> + +<h2><a name="incompatibility">Incompatibilities with Postfix 1.1</a></h2> + +<p> Postfix 2.0 address classes introduce a few incompatible changes +in documented behavior. In order to ease the transitions, new +parameters have default values that are backwards compatible. </p> + +<ul> + +<li> <p> The virtual_maps parameter is replaced by virtual_alias_maps +(for address lookups) and by virtual_alias_domains (for the names +of what were formerly called "Postfix-style virtual domains"). </p> + +<p> For backwards compatibility with Postfix version 1.1, the new +virtual_alias_maps parameter defaults to $virtual_maps, and the +new virtual_alias_domains parameter defaults to $virtual_alias_maps. +</p> + +<li> <p> The virtual_mailbox_maps parameter now has a companion +parameter called virtual_mailbox_domains (for the names of domains +served by the virtual delivery agent). The virtual_mailbox_maps +parameter is now used for address lookups only. </p> + +<p> For backwards compatibility with Postfix version 1.1, the new +virtual_mailbox_domains parameter defaults to $virtual_mailbox_maps. +</p> + +<li> <p> Introduction of the relay_recipient_maps parameter. The +Postfix SMTP server can use this to block mail for relay recipients +that don't exist. This list is empty by default, which means accept +any recipient. </p> + +<li> <p> The local_recipient_maps feature is now turned on by +default. The Postfix SMTP server uses this to reject mail for +unknown local recipients. See the LOCAL_RECIPIENT_README file hints +and tips. </p> + +<li> <p> Introduction of the relay delivery transport in master.cf. +This helps to avoid mail delivery scheduling problems on inbound +mail relays when there is a lot of outbound mail, but may require +that you update your "defer_transports" setting. </p> + +</ul> + +</body> + +</html> diff --git a/proto/ADDRESS_REWRITING_README.html b/proto/ADDRESS_REWRITING_README.html new file mode 100644 index 0000000..8c60b76 --- /dev/null +++ b/proto/ADDRESS_REWRITING_README.html @@ -0,0 +1,1246 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Address Rewriting </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +Address Rewriting </h1> + +<hr> + +<h2> <a name="purpose"> Postfix address rewriting purpose </a> </h2> + +<p> Address rewriting is at the heart of the Postfix mail system. +Postfix rewrites addresses for many different purposes. Some are +merely cosmetic, and some are necessary to deliver correctly +formatted mail to the correct destination. Examples of +address rewriting in Postfix are: </p> + +<ul> + +<li> <p> Transform an incomplete address into a complete address. +For example, transform "username" into "username@example.com", or +transform "username@hostname" into "username@hostname.example.com". +</p> + +<li> <p> Replace an address by an equivalent address. For example, +replace "username@example.com" by "firstname.lastname@example.com" +when sending mail, and do the reverse transformation when receiving +mail. </p> + +<li> <p> Replace an internal address by an external address. For +example, replace "username@localdomain.local" by "isp-account@isp.example" +when sending mail from a home computer to the Internet. +</p> + +<li> <p> Replace an address by multiple addresses. For example, +replace the address of an alias by the addresses listed under that +alias. </p> + +<li> <p> Determine how and where to deliver mail for a specific +address. For example, deliver mail for "username@example.com" with +the smtp(8) delivery agent, to the hosts that are listed in the +DNS as the mail servers for the domain "example.com". </p> + +</ul> + +<p> Although Postfix currently has no address rewriting language, +it can do surprisingly powerful address manipulation via table +lookup. Postfix typically uses lookup tables with fixed strings +to map one address to one or multiple addresses, and typically uses +regular expressions to map multiple addresses to one or multiple +addresses. Fixed-string lookup tables may be in the form of local +files, or in the form of NIS, LDAP or SQL databases. The +DATABASE_README document gives an introduction to Postfix lookup +tables. </p> + +<p> Topics covered in this document: </p> + +<ul> + +<li> <a href="#william"> To rewrite message headers or not, or to label +as invalid </a> + +<li> <a href="#overview"> Postfix address rewriting overview </a> + +<li> <a href="#receiving"> Address rewriting when mail is received</a> + +<ul> + +<li> <a href="#standard"> Rewrite addresses to standard form</a> + +<li> <a href="#canonical"> Canonical address mapping </a> + +<li> <a href="#masquerade"> Address masquerading </a> + +<li> <a href="#auto_bcc"> Automatic BCC recipients</a> + +<li> <a href="#virtual"> Virtual aliasing </a> + +</ul> + +<li> <a href="#delivering"> Address rewriting when mail is delivered</a> + +<ul> + +<li> <a href="#resolve"> Resolve address to destination </a> + +<li> <a href="#transport"> Mail transport switch </a> + +<li> <a href="#relocated"> Relocated users table </a> + +</ul> + +<li> <a href="#remote"> Address rewriting with remote delivery </a> + +<ul> + +<li> <a href="#generic"> Generic mapping for outgoing SMTP mail </a> + +</ul> + +<li> <a href="#local"> Address rewriting with local delivery </a> + +<ul> + +<li> <a href="#aliases"> Local alias database </a> + +<li> <a href="#forward"> Local per-user .forward files </a> + +<li> <a href="#luser_relay"> Local catch-all address </a> + +</ul> + +<li> <a href="#debugging"> Debugging your address manipulations </a> + +</ul> + +<h2> <a name="william"> To rewrite message headers or not, or to label +as invalid </a> </h2> + +<p> Postfix versions 2.1 and earlier always rewrite message header +addresses, and append Postfix's own domain information to addresses +that Postfix considers incomplete. While rewriting message header +addresses is OK for mail with a local origin, it is undesirable +for remote mail: </p> + +<ul> + +<li> Message header address rewriting is frowned upon by mail standards, + +<li> Appending Postfix's own domain produces incorrect results with +some incomplete addresses, + +<li> Appending Postfix's own domain sometimes creates the appearance +that spam is sent by local users. + +</ul> + +<p> Postfix versions 2.2 give you the option to either not rewrite +message headers from remote SMTP clients at all, or to label +incomplete addresses in such message headers as invalid. Here is +how it works: </p> + +<ul> + +<li> Postfix always rewrites message headers from local SMTP clients +and from the Postfix sendmail command, and appends its own domain +to incomplete addresses. The local_header_rewrite_clients parameter +controls what SMTP clients Postfix considers local (by default, +only local network interface addresses). + +<li> Postfix never rewrites message header addresses from remote +SMTP clients when the remote_header_rewrite_domain parameter value +is empty (the default setting). + +<li> Otherwise, Postfix rewrites message headers from remote SMTP +clients, and appends the remote_header_rewrite_domain value to +incomplete addresses. This feature can be used to append a reserved +domain such as "domain.invalid", so that incomplete addresses cannot +be mistaken for local addresses. + +</ul> + +<h2> <a name="overview"> Postfix address rewriting overview </a> </h2> + +<p> The figure below zooms in on those parts of Postfix that are most +involved with address rewriting activity. See the OVERVIEW document +for an overview of the complete Postfix architecture. Names followed +by a number are Postfix daemon programs, while unnumbered names +represent Postfix queues or internal sources of mail messages. </p> + +<blockquote> + +<table> + +<tr> + +<td colspan="2"> </td> + +<td bgcolor="#f0f0ff" align="center"> trivial-<br>rewrite(8)<br>(std +form) </td> + +<td colspan="5"> </td> + +<td bgcolor="#f0f0ff" align="center"> trivial-<br>rewrite(8)<br>(resolve) +</td> + +</tr> + +<tr> + +<td colspan="2"> </td> + +<td align="center"><table><tr><td align="center"> ^<br> <tt> | +</tt> </td><td align="center"> <tt> |<br>v </tt> </td></tr></table> + +<td colspan="5"> </td> + +<td align="center"><table><tr><td align="center"> ^<br> <tt> | +</tt> </td><td align="center"> <tt> |<br>v </tt> </td></tr></table> + +<td colspan="2"> </td> + +</tr> + +<tr> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> smtpd(8) +</td> + +<td rowspan="3" align="center" valign="middle"> <tt> >- </tt> +</td> + +<td rowspan="3" bgcolor="#f0f0ff" align="center"> cleanup(8) </td> + +<td rowspan="3" align="center" valign="middle"> <tt> -> </tt> +</td> + +<td rowspan="3" bgcolor="#f0f0ff" align="center"> <a +href="QSHAPE_README.html#incoming_queue"> incoming </a> </td> + +<td rowspan="3" align="center" valign="middle"> <tt> -> </tt> +</td> + +<td rowspan="3" bgcolor="#f0f0ff" align="center"> <a +href="QSHAPE_README.html#active_queue"> active </a> </td> + +<td rowspan="3" align="center" valign="middle"> <tt> -> </tt> +</td> + +<td rowspan="3" bgcolor="#f0f0ff" align="center"> qmgr(8) </td> + +<td rowspan="3" align="center" valign="middle"> <tt> -< </tt> +</td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> +smtp(8) </td> + +</tr> + +<tr> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> +qmqpd(8) </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> lmtp(8) </td> + +</tr> + +<tr> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> pickup(8) +</td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> local(8) +</td> + +</tr> + +<tr> + +<td colspan="2"> </td> + +<td align="center"> ^<br> <tt> | </tt> </td> + +<td colspan="3"> </td> + +<td align="center"><table><tr><td align="center"> ^<br> <tt> | +</tt> </td><td align="center"> <tt> |<br>v </tt> </td></tr></table> + +<td colspan="4"> </td> + +</tr> + +<tr> + +<td colspan="2"> </td> + +<td align="center"> bounces<br> forwarding<br> notices</td> + +<td colspan="3"> </td> + +<td bgcolor="#f0f0ff" align="center"> <a +href="QSHAPE_README.html#deferred_queue"> deferred </a> + +<td colspan="2"> </td> + +</table> + +</blockquote> + +<p> The table below summarizes all Postfix address manipulations. +If you're reading this document for the first time, skip forward +to "<a href="ADDRESS_REWRITING_README.html#receiving">Address +rewriting when mail is received</a>". Once you've finished reading +the remainder of this document, the table will help you to quickly +find what you need. </p> + +<blockquote> + +<table border="1"> + +<tr> <th nowrap> Address manipulation </th> <th nowrap> Scope </th> +<th> Daemon </th> <th nowrap> Global turn-on control </th> <th nowrap> Selective +turn-off control </th> </tr> + +<tr> <td> <a href="#standard"> Rewrite addresses to standard form</a> +</td> <td nowrap> all mail </td> <td> trivial-<br>rewrite(8) </td> +<td> append_at_myorigin, append_dot_mydomain, swap_bangpath, +allow_percent_hack </td> <td> local_header_rewrite_clients, +remote_header_rewrite_domain </td> </tr> + +<tr> <td> <a href="#canonical"> Canonical address mapping </a> </td> +<td nowrap> all mail </td> <td> cleanup(8) </td> <td> canonical_maps +</td> <td> receive_override_options, local_header_rewrite_clients, +remote_header_rewrite_domain </td> </tr> + +<tr> <td> <a href="#masquerade"> Address masquerading </a> </td> <td +nowrap> all mail </td> <td> cleanup(8) </td> <td> masquerade_domains +</td> <td> receive_override_options, local_header_rewrite_clients, +remote_header_rewrite_domain </td> </tr> + +<tr> <td> <a href="#auto_bcc"> Automatic BCC recipients </a> </td> +<td nowrap> new mail </td> <td> cleanup(8) </td> <td> always_bcc, +sender_bcc_maps, recipient_bcc_maps </td> <td> receive_override_options +</td> </tr> + +<tr> <td> <a href="#virtual"> Virtual aliasing </a> </td> <td +nowrap> all mail </td> <td> cleanup(8) </td> <td> virtual_alias_maps +</td> <td> receive_override_options </td> </tr> + +<tr> <td> <a href="#resolve"> Resolve address to destination </a> +</td> <td nowrap> all mail </td> <td> trivial-<br>rewrite(8) </td> +<td> none </td> <td> none </td> </tr> + +<tr> <td> <a href="#transport"> Mail transport switch</a> </td> +<td nowrap> all mail </td> <td> trivial-<br>rewrite(8) </td> <td> +transport_maps </td> <td> none </td> </tr> + +<tr> <td> <a href="#relocated"> Relocated users table</a> </td> +<td nowrap> all mail </td> <td> trivial-<br>rewrite(8) </td> <td> +relocated_maps </td> <td> none </td> </tr> + +<tr> <td> <a href="#generic"> Generic mapping table </a> </td> <td> +outgoing SMTP mail </td> <td> smtp(8) </td> <td> smtp_generic_maps +</td> <td> none </td> </tr> + +<tr> <td> <a href="#aliases"> Local alias database</a> </td> <td> +local mail only </td> <td> local(8) </td> <td> alias_maps </td> <td> none +</td> </tr> + +<tr> <td> <a href="#forward"> Local per-user .forward files</a> +</td> <td> local mail only </td> <td> local(8) </td> <td> forward_path +</td> <td> none </td> </tr> + +<tr> <td> <a href="#luser_relay"> Local catch-all address</a> </td> +<td> local mail only </td> <td> local(8) </td> <td> luser_relay </td> <td> +none </td> </tr> + +</table> + +</blockquote> + +<h2> <a name="receiving"> Address rewriting when mail is received</a> +</h2> + +<p> The cleanup(8) server receives mail from outside of Postfix as +well as mail from internal sources such as forwarded mail, +undeliverable mail that is bounced to the sender, and postmaster +notifications about problems with the mail system. </p> + +<p> The cleanup(8) server transforms the sender, recipients and +message content into a standard form before writing it to an incoming +queue file. The server cleans up sender and recipient addresses in +message headers and in the envelope, adds missing message headers +such as From: or Date: that are required by mail standards, and +removes message headers such as Bcc: that should not be present. +The cleanup(8) server delegates the more complex address manipulations +to the trivial-rewrite(8) server as described later in this document. +</p> + +<p> Address manipulations at this stage are: </p> + +<ul> + +<li> <a href="#standard"> Rewrite addresses to standard form</a> + +<li> <a href="#canonical"> Canonical address mapping</a> + +<li> <a href="#masquerade"> Address masquerading</a> + +<li> <a href="#auto_bcc"> Automatic BCC recipients</a> + +<li> <a href="#virtual"> Virtual aliasing </a> + +</ul> + +<h3> <a name="standard"> Rewrite addresses to standard form</a> </h3> + +<p> Before the cleanup(8) daemon runs an address through any address +mapping lookup table, it first rewrites the address to the standard +"user@fully.qualified.domain" form, by sending the address to the +trivial-rewrite(8) daemon. The purpose of rewriting to standard +form is to reduce the number of entries needed in lookup tables. +</p> + +<p> The Postfix trivial-rewrite(8) daemon implements the following +hard-coded address manipulations: </p> + +<blockquote> + +<dl> + +<dt>Rewrite "@hosta,@hostb:user@site" to "user@site"</dt> + +<dd> <p> In case you wonder what this is, the address form above +is called a route address, and specifies that mail for "user@site" +be delivered via "hosta" and "hostb". Usage of this form has been +deprecated for a long time. Postfix has no ability to handle route +addresses, other than to strip off the route part. </p> + +<p> NOTE: Postfix versions 2.2 and later rewrite message headers +from remote SMTP clients only if the client matches the +local_header_rewrite_clients parameter, or if the +remote_header_rewrite_domain configuration parameter specifies a +non-empty value. To get the behavior before Postfix 2.2, specify +"local_header_rewrite_clients = static:all". </p> </dd> + +<dt>Rewrite "site!user" to "user@site" </dt> + +<dd> <p> This feature is controlled by the boolean swap_bangpath +parameter (default: yes). The purpose is to rewrite UUCP-style +addresses to domain style. This is useful only when you receive +mail via UUCP, but it probably does not hurt otherwise. </p> + +<p> NOTE: Postfix versions 2.2 and later rewrite message headers +from remote SMTP clients only if the client matches the +local_header_rewrite_clients parameter, or if the +remote_header_rewrite_domain configuration parameter specifies a +non-empty value. To get the behavior before Postfix 2.2, specify +"local_header_rewrite_clients = static:all". </p> </dd> + +<dt>Rewrite "user%domain" to "user@domain"</dt> + +<dd> <p> This feature is controlled by the boolean allow_percent_hack +parameter (default: yes). Typically, this is used in order to deal +with monstrosities such as "user%domain@otherdomain". </p> + +<p> NOTE: Postfix versions 2.2 and later rewrite message headers +from remote SMTP clients only if the client matches the +local_header_rewrite_clients parameter, or if the +remote_header_rewrite_domain configuration parameter specifies a +non-empty value. To get the behavior before Postfix 2.2, specify +"local_header_rewrite_clients = static:all". </p> </dd> + +<dt> + +Rewrite "user" to "user@$myorigin" </dt> + +<dd> <p> This feature is controlled by the boolean append_at_myorigin +parameter (default: yes). You should never turn off this feature, +because a lot of Postfix components expect that all addresses have +the form "user@domain". </p> + +<p> NOTE: Postfix versions 2.2 and later rewrite message headers +from remote SMTP clients only if the client matches the +local_header_rewrite_clients parameter; otherwise they append the +domain name specified with the remote_header_rewrite_domain +configuration parameter, if one is specified. To get the behavior +before Postfix 2.2, specify "local_header_rewrite_clients = +static:all". </p> + +<p> If your machine is not the main machine for $myorigin and you +wish to have some users delivered locally without going via that +main machine, make an entry in the <a href="#virtual">virtual +alias</a> table that redirects "user@$myorigin" to +"user@$myhostname". See also the "delivering some +users locally" section in the STANDARD_CONFIGURATION_README +document. </p> </dd> + +<dt> + +Rewrite "user@host" to "user@host.$mydomain" </dt> + +<dd> <p> This feature is controlled by the boolean append_dot_mydomain +parameter (default: Postfix ≥ 3.0: no, Postfix < 3.0: yes). The purpose +is to get consistent treatment of different forms of the same hostname. </p> + +<p> NOTE: Postfix versions 2.2 and later rewrite message headers +from remote SMTP clients only if the client matches the +local_header_rewrite_clients parameter; otherwise they append the +domain name specified with the remote_header_rewrite_domain +configuration parameter, if one is specified. To get the behavior +before Postfix 2.2, specify "local_header_rewrite_clients = +static:all". </p> + +<p> Some will argue that rewriting "host" to "host.domain" +is bad. That is why it can be turned off. Others like the convenience +of having Postfix's own domain appended automatically. </p> </dd> + +<dt>Rewrite "user@site." to "user@site" (without the trailing dot).</dt> + +<dd> <p> A single trailing dot is silently removed. However, an +address that ends in multiple dots will be rejected as an invalid +address. </p> + +<p> NOTE: Postfix versions 2.2 and later rewrite message headers +from remote SMTP clients only if the client matches the +local_header_rewrite_clients parameter, or if the +remote_header_rewrite_domain configuration parameter specifies a +non-empty value. To get the behavior before Postfix 2.2, specify +"local_header_rewrite_clients = static:all". </p> </dd> + +</dl> + +</blockquote> + +<h3> <a name="canonical"> Canonical address mapping </a> </h3> + +<p> The cleanup(8) daemon uses the canonical(5) tables to rewrite +addresses in message envelopes and in message headers. By default +all header and envelope addresses are rewritten; this is controlled +with the canonical_classes configuration parameter. </p> + +<p> NOTE: Postfix versions 2.2 and later rewrite message headers +from remote SMTP clients only if the client matches the +local_header_rewrite_clients parameter, or if the +remote_header_rewrite_domain configuration parameter specifies a +non-empty value. To get the behavior before Postfix 2.2, specify +"local_header_rewrite_clients = static:all". </p> + +<p> Address rewriting is +done for local and remote addresses. The mapping is useful to +replace login names by "Firstname.Lastname" style addresses, or to +clean up invalid domains in mail addresses produced by legacy mail +systems. </p> + +<p> Canonical mapping is disabled by default. To enable, edit the +canonical_maps parameter in the main.cf file and specify one or +more lookup tables, separated by whitespace or commas. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + canonical_maps = hash:/etc/postfix/canonical + +/etc/postfix/canonical: + wietse Wietse.Venema +</pre> +</blockquote> + +<p> For static mappings as shown above, lookup tables such as hash:, +ldap:, mysql: or pgsql: are sufficient. For dynamic mappings you +can use regular expression tables. This requires that you become +intimately familiar with the ideas expressed in regexp_table(5), +pcre_table(5) and canonical(5). </p> + +<p> In addition to the canonical maps which are applied to both sender +and recipient addresses, you can specify canonical maps that are +applied only to sender addresses or to recipient addresses. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + sender_canonical_maps = hash:/etc/postfix/sender_canonical + recipient_canonical_maps = hash:/etc/postfix/recipient_canonical +</pre> +</blockquote> + +<p> The sender and recipient canonical maps are applied before the +common canonical maps. The sender_canonical_classes and +recipient_canonical_classes parameters control what addresses are +subject to sender_canonical_maps and recipient_canonical_maps +mappings, respectively. </p> + +<p> Sender-specific rewriting is useful when you want to rewrite +ugly sender addresses to pretty ones, and still want to be able to +send mail to the those ugly address without creating a mailer loop. +</p> + +<p> Canonical mapping can be turned off selectively for mail received +by smtpd(8), qmqpd(8), or pickup(8), by overriding main.cf settings +in the master.cf file. This feature is available in Postfix version +2.1 and later. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + 127.0.0.1:10026 inet n - n - - smtpd + -o receive_override_options=no_address_mappings +</pre> +</blockquote> + +<p> Note: do not specify whitespace around the "=" here. </p> + +<h3> <a name="masquerade"> Address masquerading </a> </h3> + +<p> Address masquerading is a method to hide hosts inside a domain +behind their mail gateway, and to make it appear as if the mail +comes from the gateway itself, instead of from individual machines. +</p> + +<p> NOTE: Postfix versions 2.2 and later rewrite message headers +from remote SMTP clients only if the client matches the +local_header_rewrite_clients parameter, or if the +remote_header_rewrite_domain configuration parameter specifies a +non-empty value. To get the behavior before Postfix 2.2, specify +"local_header_rewrite_clients = static:all". </p> + +<p> Address masquerading is disabled by default, and is implemented +by the cleanup(8) server. To enable, edit the masquerade_domains +parameter in the main.cf file and specify one or more domain names +separated by whitespace or commas. When Postfix tries to masquerade +a domain, it processes the list from left to right, and processing +stops at the first match. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + masquerade_domains = foo.example.com example.com +</pre> +</blockquote> + +<p> strips "any.thing.foo.example.com" to "foo.example.com", but +strips "any.thing.else.example.com" to "example.com". </p> + +<p> A domain name prefixed with "<tt>!</tt>" means do not masquerade +this domain or its subdomains: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + masquerade_domains = !foo.example.com example.com +</pre> +</blockquote> + +<p> does not change "any.thing.foo.example.com" and "foo.example.com", +but strips "any.thing.else.example.com" to "example.com". </p> + +<p> The masquerade_exceptions configuration parameter specifies +what user names should not be subjected to address masquerading. +Specify one or more user names separated by whitespace or commas. +</p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + masquerade_exceptions = root +</pre> +</blockquote> + +<p> By default, Postfix makes no exceptions. </p> + +<p> Subtle point: by default, address masquerading is applied only to +message headers and to envelope sender addresses, but not to envelope +recipients. This allows you to use address masquerading on a mail +gateway machine, while still being able to forward mail from outside +to users on individual machines. </p> + +<p> In order to subject envelope recipient addresses to masquerading, +too, specify (Postfix version 1.1 and later):</p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + masquerade_classes = envelope_sender, envelope_recipient, + header_sender, header_recipient +</pre> +</blockquote> + +<p> If you rewrite the envelope recipient like this, Postfix will +no longer be able to send mail to individual machines. </p> + +<p> Address masquerading can be turned off selectively for mail +received by smtpd(8), qmqpd(8), or pickup(8), by overriding main.cf +settings in the master.cf file. This feature is available in +Postfix version 2.1 and later. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + 127.0.0.1:10026 inet n - n - - smtpd + -o receive_override_options=no_address_mappings +</pre> +</blockquote> + +<p> Note: do not specify whitespace around the "=" here. </p> + +<h3> <a name="auto_bcc"> Automatic BCC recipients</a> </h3> + +<p> After applying the canonical and masquerade mappings, the +cleanup(8) daemon can generate optional BCC (blind carbon-copy) +recipients. Postfix provides three mechanisms: </p> + +<blockquote> + +<dl> + +<dt> always_bcc = address </dt> <dd> Deliver a copy of all mail to +the specified address. In Postfix versions before 2.1, this feature +is implemented by smtpd(8), qmqpd(8), or pickup(8). </dd> + +<dt> sender_bcc_maps = type:table </dt> <dd> Search the specified +"type:table" lookup table with the envelope sender address for an +automatic BCC address. This feature is available in Postfix 2.1 +and later. </dd> + +<dt> recipient_bcc_maps = type:table </dt> <dd> Search the specified +"type:table" lookup table with the envelope recipient address for +an automatic BCC address. This feature is available in Postfix 2.1 +and later. </dd> + +</dl> + +</blockquote> + +<p> Note: automatic BCC recipients are produced only for new mail. +To avoid mailer loops, automatic BCC recipients are not generated +for mail that Postfix forwards internally, nor for mail that Postfix +generates itself. </p> + +<p> Automatic BCC recipients (including always_bcc) can be turned +off selectively for mail received by smtpd(8), qmqpd(8), or pickup(8), +by overriding main.cf settings in the master.cf file. This feature +is available in Postfix version 2.1 and later. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + 127.0.0.1:10026 inet n - n - - smtpd + -o receive_override_options=no_address_mappings +</pre> +</blockquote> + +<p> Note: do not specify whitespace around the "=" here. </p> + +<h3> <a name="virtual"> Virtual aliasing </a> </h3> + +<p> Before writing the recipients to the queue file, the cleanup(8) +daemon uses the optional virtual(5) alias tables to redirect mail +for recipients. The mapping affects only envelope recipient +addresses; it has no effect on message headers or envelope sender +addresses. Virtual alias lookups are useful to redirect mail for +virtual alias domains to real user mailboxes, and to redirect mail +for domains that no longer exist. Virtual alias lookups can also +be used to transform " Firstname.Lastname " back into UNIX login +names, although it seems that local <a href="#aliases">aliases</a> +may be a more appropriate vehicle. See the VIRTUAL_README document +for an overview of methods to host virtual domains with Postfix. +</p> + +<p> Virtual aliasing is disabled by default. To enable, edit the +virtual_alias_maps parameter in the main.cf file and +specify one or more lookup tables, separated by whitespace or +commas. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + virtual_alias_maps = hash:/etc/postfix/virtual + +/etc/postfix/virtual: + Wietse.Venema wietse +</pre> +</blockquote> + +<p> Addresses found in virtual alias maps are subjected to another +iteration of virtual aliasing, but are not subjected to canonical +mapping, in order to avoid loops. </p> + +<p> For static mappings as shown above, lookup tables such as hash:, +ldap:, mysql: or pgsql: are sufficient. For dynamic mappings you +can use regular expression tables. This requires that you become +intimately familiar with the ideas expressed in regexp_table(5), +pcre_table(5) and virtual(5). </p> + +<p> Virtual aliasing can be turned off selectively for mail received +by smtpd(8), qmqpd(8), or pickup(8), by overriding main.cf settings +in the master.cf file. This feature is available in Postfix version +2.1 and later. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + 127.0.0.1:10026 inet n - n - - smtpd + -o receive_override_options=no_address_mappings +</pre> +</blockquote> + +<p> Note: do not specify whitespace around the "=" here. </p> + +<p> At this point the message is ready to be stored into the +Postfix incoming queue. </p> + +<h2> <a name="delivering"> Address rewriting when mail is delivered</a> </h2> + +<p> The Postfix queue manager sorts mail according to its destination +and gives it to Postfix delivery agents such as local(8), smtp(8), +or lmtp(8). Just like the cleanup(8) server, the Postfix queue +manager delegates the more complex address manipulations to the +trivial-rewrite(8) server. </p> + +<p> Address manipulations at this stage are: </p> + +<ul> + +<li> <a href="#resolve"> Resolve address to destination </a> + +<li> <a href="#transport"> Mail transport switch</a> + +<li> <a href="#relocated"> Relocated users table</a> + +</ul> + +<p> Each Postfix delivery agent tries to deliver the mail to its +destination, while encapsulating the sender, recipients, and message +content according to the rules of the SMTP, LMTP, etc. protocol. +When mail cannot be delivered, it is either returned to the sender +or moved to the deferred queue and tried again later. </p> + +<p> <a name="remote">Address</a> manipulations when mail is delivered +via the smtp(8) delivery agent: </p> + +<ul> + +<li> <a href="#generic"> Generic mapping for outgoing SMTP mail </a> + +</ul> + +<p> <a name="local">Address</a> manipulations when mail is delivered +via the local(8) delivery agent: </p> + +<ul> + +<li> <a href="#aliases"> Local alias database</a> + +<li> <a href="#forward"> Local per-user .forward files</a> + +<li> <a href="#luser_relay"> Local catch-all address</a> + +</ul> + +<p> The remainder of this document presents each address manipulation +step in more detail, with specific examples or with pointers to +documentation with examples. </p> + +<h3> <a name="resolve"> Resolve address to destination </a> </h3> + +<p> The Postfix qmgr(8) queue manager selects new mail from the +incoming queue or old mail from the deferred queue, and asks the +trivial-rewrite(8) address rewriting and resolving daemon where it +should be delivered. </p> + +<p> As of version 2.0, Postfix distinguishes four major address +classes. Each class has its own list of domain names, and each +class has its own default delivery method, as shown in the table +below. See the ADDRESS_CLASS_README document for the fine details. +Postfix versions before 2.0 only distinguish between local delivery +and everything else. </p> + +<blockquote> + +<table border="1"> + +<tr><th align="left">Destination domain list </th> <th +align="left">Default delivery method </th> <th>Availability +</th> </tr> + +<tr><td>$mydestination, $inet_interfaces, $proxy_interfaces </td> +<td>$local_transport </td> <td>Postfix 1.0</td></tr> + +<tr><td>$virtual_mailbox_domains </td> <td>$virtual_transport </td> +<td>Postfix 2.0</td> </tr> + +<tr><td>$relay_domains </td> <td>$relay_transport </td> <td>Postfix +2.0</td> </tr> + +<tr><td>none </td> <td>$default_transport </td> <td>Postfix 1.0</td> +</tr> + +</table> + +</blockquote> + +<h3> <a name="transport"> Mail transport switch </a> </h3> + +<p> Once the trivial-rewrite(8) daemon has determined a default +delivery method it searches the optional transport(5) table for +information that overrides the message destination and/or delivery +method. Typical use of the transport(5) table is to send mail to +a system +that is not connected to the Internet, or to use a special SMTP +client configuration for destinations that have special requirements. +See, for example, the STANDARD_CONFIGURATION_README and UUCP_README +documents, and the examples in the transport(5) manual page. </p> + +<p> Transport table lookups are disabled by default. To enable, +edit the transport_maps parameter in the main.cf file and specify +one or more lookup tables, separated by whitespace or commas. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + transport_maps = hash:/etc/postfix/transport +</pre> +</blockquote> + +<h3> <a name="relocated"> Relocated users table </a> </h3> + +<p> Next, the trivial-rewrite(8) address rewriting and resolving +daemon runs each recipient through the relocated(5) database. This +table provides information on how to reach users that no longer +have an account, or what to do with mail for entire domains that +no longer exist. When mail is sent to an address that is listed +in this table, the message is returned to the sender with an +informative message. </p> + +<p> The relocated(5) database is searched after transport(5) +table lookups, in anticipation of transport(5) tables that +can replace one recipient address by a different one. </p> + +<p> Lookups of relocated users are disabled by default. To enable, +edit the relocated_maps parameter in the main.cf file and specify +one or more lookup tables, separated by whitespace or commas. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + relocated_maps = hash:/etc/postfix/relocated + +/etc/postfix/relocated: + username@example.com otheruser@elsewhere.tld +</pre> +</blockquote> + +<p> As of Postfix version 2, mail for a relocated user will be +rejected by the SMTP server with the reason "user has moved to +otheruser@elsewhere.tld". Older Postfix versions will receive the +mail first, and then return it to the sender as undeliverable, with +the same reason. </p> + +<h3> <a name="generic"> Generic mapping for outgoing SMTP mail </a> </h3> + +<p> Some hosts have no valid Internet domain name, and instead use +a name such as <i>localdomain.local</i>. This can be a problem when +you want to send mail over the Internet, because many mail servers +reject mail addresses with invalid domain names. </p> + +<p> With the smtp_generic_maps parameter you can specify generic(5) +lookup tables that replace local mail addresses by valid Internet +addresses when mail leaves the machine via SMTP. The generic(5) +mapping replaces envelope and header addresses, and is non-recursive. +It does not happen when you send mail between addresses on the +local machine. </p> + +<p> This feature is available in Postfix version 2.2 and later.</p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_generic_maps = hash:/etc/postfix/generic + +/etc/postfix/generic: + his@localdomain.local hisaccount@hisisp.example + her@localdomain.local heraccount@herisp.example + @localdomain.local hisaccount+local@hisisp.example +</pre> +</blockquote> + +<p> When mail is sent to a remote host via SMTP, this replaces +<i>his@localdomain.local</i> by his ISP mail address, replaces +<i>her@localdomain.local</i> by her ISP mail address, and replaces +other local addresses by his ISP account, with an address extension +of +<i>local</i> (this example assumes that the ISP supports "+" +style address extensions). </p> + +<h3> <a name="aliases"> Local alias database </a> </h3> + +<p> When mail is to be delivered locally, the local(8) delivery +agent runs each local recipient name through the aliases(5) database. +The mapping does not affect addresses in message headers. Local +aliases are typically used to implement distribution lists, or to +direct mail for standard aliases such as postmaster to real people. +The table can also be used to map "Firstname.Lastname" addresses +to login names. </p> + +<p> Alias lookups are enabled by default. The default configuration +depends on the operating system environment, but it is typically +one of the following: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + alias_maps = hash:/etc/aliases + alias_maps = dbm:/etc/aliases, nis:mail.aliases +</pre> +</blockquote> + +<p> The pathname of the alias database file is controlled with the +alias_database configuration parameter. The value is system dependent. +Usually it is one of the following: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + alias_database = hash:/etc/aliases (4.4BSD, LINUX) + alias_database = dbm:/etc/aliases (4.3BSD, SYSV<4) + alias_database = dbm:/etc/mail/aliases (SYSV4) +</pre> +</blockquote> + +<p> An aliases(5) file can specify that mail should be delivered +to a local file, or to a command that receives the message in the +standard input stream. For security reasons, deliveries to command +and file destinations are performed with the rights of the alias +database owner. A default userid, default_privs, is used for +deliveries to commands or files in "root"-owned aliases. </p> + +<h3> <a name="forward"> Local per-user .forward files </a> </h3> + +<p> With delivery via the local(8) delivery agent, users can control +their own mail delivery by specifying destinations in a file called +.forward in their home directories. The syntax of these files is +the same as with the local aliases(5) file, except that the left-hand +side of the alias (lookup key and colon) are not present. </p> + +<h3> <a name="luser_relay"> Local catch-all address </a> </h3> + +<p> When the local(8) delivery agent finds that a message recipient +does not exist, the message is normally returned to the sender ("user +unknown"). Sometimes it is desirable to forward mail for non-existing +recipients to another machine. For this purpose you can specify +an alternative destination with the luser_relay configuration +parameter. </p> + +<p> Alternatively, mail for non-existent recipients can be delegated +to an entirely different message transport, as specified with the +fallback_transport configuration parameter. For details, see the +local(8) delivery agent documentation. </p> + +<p> Note: if you use the luser_relay feature in order to receive +mail for non-UNIX accounts, then you must specify: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + local_recipient_maps = +</pre> +</blockquote> + +<p> (i.e. empty) in the main.cf file, otherwise the Postfix SMTP +server will reject mail for non-UNIX accounts with "User unknown +in local recipient table". See the LOCAL_RECIPIENT_README file +for more information on this. +</p> + +<p> luser_relay can specify one address. It is subjected to "$name" +expansions. Examples: </p> + +<blockquote> + +<dl> + +<dt>$user@other.host </dt> + +<dd> <p> The bare username, without address extension, is prepended +to "@other.host". For example, mail for "username+foo" is sent to +"username@other.host". </p> </dd> + +<dt>$local@other.host </dt> + +<dd> <p> The entire original recipient localpart, including address +extension, is prepended to "@other.host". For example, mail for +"username+foo" is sent to "username+foo@other.host". </p> </dd> + +<dt>sysadmin+$user </dt> + +<dd> <p> The bare username, without address extension, is appended +to "sysadmin". For example, mail for "username+foo" is sent to +"sysadmin+username". </p> </dd> + +<dt>sysadmin+$local </dt> + +<dd> <p> The entire original recipient localpart, including address +extension, is appended to "sysadmin". For example, mail for +"username+foo" is sent to "sysadmin+username+foo". </p> </dd> + +</dl> + +</blockquote> + +<h2> <a name="debugging"> Debugging your address manipulations </a> </h2> + +<p> Postfix version 2.1 and later can +produce mail delivery reports for debugging purposes. These reports +not only show sender/recipient addresses after address rewriting +and alias expansion or forwarding, they also show information about +delivery to mailbox, delivery to non-Postfix command, responses +from remote SMTP servers, and so on. </p> + +<p> Postfix can produce two types of mail delivery reports for +debugging: </p> + +<ul> + +<li> <p> What-if: report what would happen, but do not actually +deliver mail. This mode of operation is requested with: </p> + +<pre> +$ <b>/usr/sbin/sendmail -bv address...</b> +Mail Delivery Status Report will be mailed to <your login name>. +</pre> + +<li> <p> What happened: deliver mail and report successes and/or +failures, including replies from remote SMTP servers. This mode +of operation is requested with: </p> + +<pre> +$ <b>/usr/sbin/sendmail -v address...</b> +Mail Delivery Status Report will be mailed to <your login name>. +</pre> + +</ul> + +<p> These reports contain information that is generated by Postfix +delivery agents. Since these run as daemon processes and do not +interact with users directly, the result is sent as mail to the +sender of the test message. The format of these reports is practically +identical to that of ordinary non-delivery notifications. </p> + +<p> As an example, below is the delivery report that is produced +with the command "sendmail -bv postfix-users@postfix.org". The +first part of the report contains human-readable text. In this +case, mail would be delivered via mail.cloud9.net, and the SMTP +server replies with "250 Ok". Other reports may show delivery +to mailbox, or delivery to non-Postfix command. </p> + +<blockquote> +<pre> +Content-Description: Notification +Content-Type: text/plain + +This is the mail system at host spike.porcupine.org. + +Enclosed is the mail delivery report that you requested. + + The mail system + +<postfix-users@postfix.org>: delivery via mail.cloud9.net[168.100.1.4]: 250 2.1.5 Ok +</pre> +</blockquote> + +<p> The second part of the report is in machine-readable form, and +includes the following information: </p> + +<ul> + +<li> The envelope sender address (wietse@porcupine.org). + +<li> The envelope recipient address (postfix-users@postfix.org). +If the recipient address was changed by Postfix then Postfix also +includes the original recipient address. + +<li> The delivery status. + +</ul> + +<p> Some details depend on Postfix version. The example below is +for Postfix version 2.3 and later. </p> + +<blockquote> +<pre> +Content-Description: Delivery report +Content-Type: message/delivery-status + +Reporting-MTA: dns; spike.porcupine.org +X-Postfix-Queue-ID: 84863BC0E5 +X-Postfix-Sender: rfc822; wietse@porcupine.org +Arrival-Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST) + +Final-Recipient: rfc822; postfix-users@postfix.org +Action: deliverable +Status: 2.1.5 +Remote-MTA: dns; mail.cloud9.net +Diagnostic-Code: smtp; 250 2.1.5 Ok +</pre> +</blockquote> + +<p> The third part of the report contains the message that Postfix +would have delivered, including From: and To: message headers, so +that you can see any effects of address rewriting on those. Mail +submitted with "sendmail -bv" has no body content so none is shown +in the example below. </p> + +<blockquote> +<pre> +Content-Description: Message +Content-Type: message/rfc822 + +Received: by spike.porcupine.org (Postfix, from userid 1001) + id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST) +Subject: probe +To: postfix-users@postfix.org +Message-Id: <20061126220101.84863BC0E5@spike.porcupine.org> +Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST) +From: wietse@porcupine.org (Wietse Venema) +</pre> +</blockquote> + +</body> + +</html> diff --git a/proto/ADDRESS_VERIFICATION_README.html b/proto/ADDRESS_VERIFICATION_README.html new file mode 100644 index 0000000..aaaf24d --- /dev/null +++ b/proto/ADDRESS_VERIFICATION_README.html @@ -0,0 +1,658 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Address Verification </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Address Verification Howto</h1> + +<hr> + +<h2>WARNING </h2> + +<p> Recipient address verification may cause an increased load on +down-stream servers in the case of a dictionary attack or a flood +of backscatter bounces. Sender address verification may cause your +site to be denylisted by some providers. See also the "<a +href="#limitations">Limitations</a>" section below for more. </p> + +<h2><a name="summary">What Postfix address verification can do for you</a></h2> + +<p> Address verification is a feature that allows the Postfix SMTP +server to block a sender (MAIL FROM) or recipient (RCPT TO) address +until the address has been verified to be deliverable. </p> + +<p> The technique has obvious uses to reject junk mail +with an unreplyable sender address. </p> + +<p> The technique is also useful to block mail for undeliverable +recipients, for example on a mail relay host that does not have a +list of all the valid recipient addresses. This prevents undeliverable +junk mail from entering the queue, so that Postfix doesn't have to +waste resources trying to send MAILER-DAEMON messages back. </p> + +<p> This feature is available in Postfix version 2.1 and later. </p> + +<p> Topics covered in this document: </p> + +<ul> + +<li><a href="#how"> How address verification works</a> + +<li><a href="#limitations">Limitations of address verification</a> + +<li><a href="#recipient">Recipient address verification</a> + +<li><a href="#forged_sender">Sender address verification for mail +from frequently forged domains</a> + +<li><a href="#sender_always">Sender address verification for all +email</a> + +<li><a href="#caching">Address verification database</a> + +<li><a href="#dirty_secret">Managing the address verification +database</a> + +<li><a href="#probe_routing">Controlling the routing of address +verification probes</a> + +<li><a href="#forced_examples">Forced probe routing examples</a> + +<li><a href="#forced_limitations">Limitations of forced probe routing</a> + +</ul> + +<h2><a name="how">How address verification works</a></h2> + +<p> A Postfix MTA verifies a sender or recipient address by probing +the preferred MTAs +for that address, without actually delivering mail. The preferred +MTAs could include the Postfix MTA itself, or some remote MTAs +(SMTP +interruptus). Probe messages are like normal mail, except that +they are never delivered, deferred or bounced; probe messages are +always discarded. </p> + +<blockquote> + +<table border="0"> + +<tr> + + <td rowspan="2" colspan="5" align="center" valign="middle"> + </td> + + <td rowspan="3" align="center" valign="bottom"> <tt> -> </tt> + </td> + + <td rowspan="3" align="center" valign="middle"> probe<br> + message </td> + + <td rowspan="3" align="center" valign="middle"> <tt> -> </tt> + </td> + + <td rowspan="3" bgcolor="#f0f0ff" align="center" valign="middle"> + Postfix<br> mail<br> queue </td> + +</tr> + +<tr> <td> </td> </tr> + +<tr> + + <td rowspan="3" align="center" valign="middle"> Internet </td> + + <td rowspan="3" align="center" valign="middle"> <tt> -> </tt> + </td> + + <td rowspan="3" bgcolor="#f0f0ff" align="center" valign="middle"> + <a href="smtpd.8.html">Postfix<br> SMTP<br> server</a> </td> + + <td rowspan="3" align="center" valign="middle"> <tt> <-> + </tt> </td> + + <td rowspan="3" bgcolor="#f0f0ff" align="center" valign="middle"> + <a href="verify.8.html">Postfix<br> verify<br> server</a> + </td> + +</tr> + +<tr> + + <td rowspan="1" colspan="3"> </td> + + <td rowspan="1" align="center" valign="middle"> <tt> |</tt><br> + <tt> v</tt> </td> + +</tr> + +<tr> + + <td rowspan="3" align="center" valign="top"> <tt> <- </tt> + </td> + + <td rowspan="3" align="center" valign="middle"> probe<br> + status </td> + + <td rowspan="3" align="center" valign="middle"> <tt> <- </tt> + </td> + + <td rowspan="3" bgcolor="#f0f0ff" align="center" valign="middle"> + Postfix<br> delivery<br> agents </td> + + <td rowspan="3" align="left" valign="middle"> <tt>-></tt> + Local<br> <tt>-></tt> Remote</td> + +</tr> + +<tr> + + <td rowspan="3" colspan="4" align="center" valign="middle"> + </td> + + <td rowspan="3" align="center" valign="middle"> <tt> + ^</tt><br> <tt> |</tt><br> <tt> v</tt> </td> + +</tr> + +<tr> <td> </td> </tr> + +<tr> <td colspan="4"> </td> </tr> + +<tr> + + <td colspan="4" align="center" valign="middle"> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + Address<br> verification<br> database </td> + +</tr> + +</table> + +</blockquote> + +<p> With Postfix address verification turned on, normal mail will +suffer only a short delay of up to 6 seconds while an address is +being verified for the first time. Once an address status is known, +the status is cached and Postfix replies immediately. </p> + +<p> When verification takes too long the Postfix SMTP server defers +the sender or recipient address with a 450 reply. Normal mail +clients will connect again after some delay. The address verification +delay is configurable with the main.cf address_verify_poll_count +and address_verify_poll_delay parameters. See postconf(5) for +details. </p> + +<h2><a name="limitations">Limitations of address verification</a></h2> + +<ul> + +<li> <p> Postfix assumes that a remote SMTP server will reject +unknown addresses in reply to the RCPT TO command. However, some +sites report this in reply to the DATA command. For such sites +you may configure a workaround with the smtp_address_verify_target +parameter (Postfix 3.0 and later). </p> + +<li> <p> When verifying a remote address, Postfix probes the preferred +MTAs for that address, without actually delivering mail. If +a preferred MTA accepts the address, then Postfix assumes that the +address is deliverable. In reality, mail for a remote address can +bounce AFTER a preferred MTA accepts the recipient address, or AFTER +a preferred MTA accepts the message content. </p> + +<li> <p> Some sites may denylist you when you are probing them +too often (a probe is an SMTP session that does not deliver mail), +or when you are probing them too often for a non-existent address. +This is one reason why you should use sender address verification +sparingly, if at all, when your site receives lots of email. </p> + +<li> <p> Normally, address verification probe messages follow the +same path as regular mail. However, some sites send mail to the +Internet via an intermediate relayhost; this breaks address +verification. See below, section <a href="#probe_routing">"Controlling +the routing of address verification probes"</a>, for how to override +mail routing and for possible limitations when you have to do this. +</p> + +<li> <p> Postfix assumes that an address is undeliverable when a +preferred MTA for the address rejects the probe, regardless of the +reason for rejection (client rejected, HELO rejected, MAIL FROM +rejected, etc.). Thus, Postfix rejects an address when a preferred +MTA for that address rejects mail from your machine for any reason. +This is not a limitation, but it is mentioned here just in case +people believe that it is a limitation. </p> + +<li> <p> Unfortunately, some sites do not reject unknown addresses +in reply to the RCPT TO or DATA command, but instead report a +delivery failure in response to end of DATA after a message is +transferred. Postfix address verification does not work with such +sites. </p> + +<li> <p> By default, Postfix probe messages have a sender address +"double-bounce@$myorigin" (with Postfix versions before 2.5, the +default +is "postmaster@$myorigin"). This is SAFE because the Postfix SMTP +server does not reject mail for this address. </p> + +<p> You can change the probe sender address into the null address +("address_verify_sender +="). This is UNSAFE because address probes will fail with +mis-configured sites that reject MAIL FROM: <>, while +probes from "double-bounce@$myorigin" would succeed. </p> + +<li> <p> The downside of using a non-empty sender address is that +the address may end up on spammer mailing lists. Although Postfix +always discards mail to the double-bounce address, this still results +in wasted network bandwidth and server capacity. To defeat +address harvesting, Postfix 2.9 and later support time-dependent +sender addresses when you specify a non-zero address_verify_sender_ttl +value. </p> + +</ul> + +<h2><a name="recipient">Recipient address verification</a></h2> + +<p> As mentioned earlier, recipient address verification is +useful to block mail for undeliverable recipients on a mail relay +host that does not have a list of all valid recipient addresses. +This can help to prevent the mail queue from filling up with +MAILER-DAEMON messages. </p> + +<p> Recipient address verification is relatively straightforward +and there are no surprises. If a recipient probe fails, then Postfix +rejects mail for the recipient address. If a recipient probe +succeeds, then Postfix accepts mail for the recipient address. +However, recipient address verification probes can increase the +load on down-stream MTAs when you're being flooded by backscatter +bounces, or when some spammer is mounting a dictionary attack. </p> + +<p> By default, address verification results are saved in a <a +href="#caching">persistent database</a> (Postfix version 2.7 and +later; with earlier versions, specify the database in main.cf as +described later). The persistent database helps to avoid probing +the same address repeatedly. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_recipient_restrictions = + permit_mynetworks + # reject_unauth_destination is not needed here if the mail + # relay policy is specified under smtpd_relay_restrictions + # (available with Postfix 2.10 and later). + reject_unauth_destination + ... + reject_unknown_recipient_domain + reject_unverified_recipient + ... + # Postfix 2.6 and later privacy feature. + # unverified_recipient_reject_reason = Address lookup failed + + # Postfix 3.2 and earlier workaround. + # Do not set enable_original_recipient=no. This prevents Postfix + # from saving the recipient address verification result under + # the original address, when the address verification probe + # message goes through address aliasing or canonical mapping. +</pre> +</blockquote> + +<p> The "reject_unknown_recipient_domain" restriction blocks mail +for non-existent domains. Putting this before "reject_unverified_recipient" +avoids the overhead of generating unnecessary probe messages. </p> + +<p> The unverified_recipient_reject_code parameter (default 450) +specifies the numerical Postfix SMTP server reply code when a +recipient address is known to +bounce. Change this setting into 550 when you trust Postfix's +judgments. </p> + +<p> The following features are available in Postfix 2.6 and later. +</p> + +<p> The unverified_recipient_defer_code parameter (default 450) +specifies the numerical Postfix SMTP server reply code when a +recipient address probe fails with some temporary error. Some sites +insist on changing this into 250. NOTE: This change turns MX servers +into backscatter sources when the load is high. </p> + +<p> The unverified_recipient_reject_reason parameter (default: +empty) specifies fixed text that Postfix will send to remote SMTP +clients, instead of sending actual address verification details. +Do not specify the SMTP status code or enhanced status code. </p> + +<p> The unverified_recipient_tempfail_action parameter (default: +defer_if_permit) specifies the Postfix SMTP server action when a +recipient address verification probe fails with some temporary +error. </p> + +<h2><a name="forged_sender">Sender address verification for mail from frequently forged domains</a></h2> + +<p> Only for very small sites, it is relatively safe to turn on +sender address verification for specific domains that often appear +in forged email. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_sender_restrictions = hash:/etc/postfix/sender_access + unverified_sender_reject_code = 550 + # Postfix 2.6 and later. + # unverified_sender_defer_code = 250 + + # Default setting for Postfix 2.7 and later. + # Note 1: Be sure to read the "<a href="#caching">Caching</a>" section below! + # Note 2: Avoid hash files here. Use btree or lmdb instead. + address_verify_map = btree:/var/lib/postfix/verify + + # Postfix 3.2 and earlier workaround. + # Do not set enable_original_recipient=no. This prevents Postfix + # from saving the sender address verification result under the + # original address, when the address verification probe message + # goes through address aliasing or canonical mapping. + +/etc/postfix/sender_access: + # Don't do this when you handle lots of email. + aol.com reject_unverified_sender + hotmail.com reject_unverified_sender + bigfoot.com reject_unverified_sender + ... etcetera ... +</pre> +</blockquote> + +<p> At some point in cyberspace/time, a list of frequently forged +MAIL FROM domains could be found at +http://www.monkeys.com/anti-spam/filtering/sender-domain-validate.in. </p> + +<p> NOTE: One of the first things you might want to do is to turn +on sender address verification for all your own domains. </p> + +<h2><a name="sender_always">Sender address verification for all +email</a></h2> + +<p> Unfortunately, sender address verification cannot simply be +turned on for all email - you are likely to lose legitimate mail +from mis-configured systems. You almost certainly will have to set +up allow lists for specific addresses, or even for entire domains. +</p> + +<p> To find out how sender address verification would affect your +mail, specify "warn_if_reject reject_unverified_sender" so that +you can see what mail would be blocked: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_sender_restrictions = + permit_mynetworks + ... + check_sender_access hash:/etc/postfix/sender_access + reject_unknown_sender_domain + warn_if_reject reject_unverified_sender + ... + # Postfix 2.6 and later. + # unverified_sender_reject_reason = Address verification failed + + # Default setting for Postfix 2.7 and later. + # Note 1: Be sure to read the "<a href="#caching">Caching</a>" section below! + # Note 2: Avoid hash files here. Use btree or lmdb instead. + address_verify_map = btree:/var/lib/postfix/verify +</pre> +</blockquote> + +<p> This is also a good way to populate your cache with address +verification results before you start to actually reject mail. </p> + +<p> The sender_access restriction is needed to allowlist domains +or addresses that are known to be OK. Although Postfix will not +mark a known-to-be-good address as bad after a probe fails, it is +better to be safe than sorry. </p> + +<p> NOTE: You will have to allowlist sites such as securityfocus.com +and other sites that operate mailing lists that use a different +sender address for each posting (VERP). Such addresses pollute +the address verification cache quickly, and generate unnecessary +sender verification probes. </p> + +<blockquote> +<pre> +/etc/postfix/sender_access + securityfocus.com OK + ... +</pre> +</blockquote> + +<p> The "reject_unknown_sender_domain" restriction blocks mail from +non-existent domains. Putting this before "reject_unverified_sender" +avoids the overhead of generating unnecessary probe messages. </p> + +<p> The unverified_sender_reject_code parameter (default 450) +specifies the numerical Postfix server reply code when a sender +address is known to +bounce. Change this setting into 550 when you trust Postfix's +judgments. </p> + +<p> The following features are available in Postfix 2.6 and later. +</p> + +<p> The unverified_sender_defer_code parameter (default 450) specifies +the numerical Postfix SMTP server reply code when a sender address +verification probe fails with some temporary error. Specify a valid +2xx or 4xx code. </p> + +<p> The unverified_sender_reject_reason parameter (default: +empty) specifies fixed text that Postfix will send to remote SMTP +clients, instead of sending actual address verification details. +Do not specify the SMTP status code or enhanced status code. </p> + +<p> The unverified_sender_tempfail_action parameter (default: +defer_if_permit) specifies the Postfix SMTP server action when a +sender address verification probe fails with some temporary error. +</p> + +<h2><a name="caching">Address verification database</a></h2> + +<p> To improve performance, the Postfix verify(8) daemon can save +address verification results to a persistent database. This is +enabled by default with Postfix 2.7 and later. The +address_verify_map (NOTE: singular) configuration parameter specifies +persistent storage for sender or recipient address verification +results. If you specify an empty value, all address verification +results are lost after "postfix reload" or "postfix stop". </p> + +<blockquote> +<pre> +# Example 1: Default setting for Postfix 2.7 and later. +# Note: avoid hash files here. Use btree or lmdb instead. +/etc/postfix/main.cf: + address_verify_map = btree:$data_directory/verify_cache + +# Example 2: Shared persistent lmdb: cache (Postfix 2.11 or later). +# Disable automatic cache cleanup in all Postfix instances except +# for one instance that will be responsible for cache cleanup. +/etc/postfix/main.cf: + address_verify_map = lmdb:$data_directory/verify_cache + # address_verify_cache_cleanup_interval = 0 + +# Example 3: Shared persistent btree: cache (Postfix 2.9 or later). +# Disable automatic cache cleanup in all Postfix instances except +# for one instance that will be responsible for cache cleanup. +/etc/postfix/main.cf: + address_verify_map = proxy:btree:$data_directory/verify_cache + # address_verify_cache_cleanup_interval = 0 + +# Example 4: Shared memory cache (requires Postfix 2.9 or later). +# Disable automatic cache cleanup in all Postfix instances. +# See memcache_table(5) for details. +/etc/postfix/main.cf: + address_verify_map = memcache:/etc/postfix/verify-memcache.cf + address_verify_cache_cleanup_interval = 0 + +# Example 5: Default setting for Postfix 2.6 and earlier. +# This uses non-persistent storage only. +/etc/postfix/main.cf: + address_verify_map = +</pre> +</blockquote> + +<p> NOTE 1: The database file should be stored under a Postfix-owned +directory, such as $data_directory. </p> + +<blockquote> As of version 2.5, Postfix no longer uses root privileges +when opening this file. To maintain backwards compatibility, an +attempt to open the file under a non-Postfix directory is redirected +to the Postfix-owned data_directory, and a warning is logged. If +you wish to continue using a pre-existing database file, change its +file ownership to the account specified with the mail_owner parameter, +and either move the file to the data_directory, or move it to some +other Postfix-owned directory. </blockquote> + +<p> NOTE 2: Do not put this file in a file system that may run out +of space. When the address verification table gets corrupted the +world comes to an end and YOU will have to MANUALLY fix things as +described in the next section. Meanwhile, you will not receive mail +via SMTP. </p> + +<p> NOTE 3: The verify(8) daemon will create a new database when +none exists. It will open or create the file before entering the +chroot jail. </p> + +<h2><a name="dirty_secret">Managing the address verification +database</a></h2> + +<p> The verify(8) manual page describes parameters that control how +long address verification results are cached before they need to +be refreshed, and how long results can remain "unrefreshed" before +they expire. Postfix uses different controls for positive results +(address was accepted) and for negative results (address was rejected, +or address verification failed for some other reason). </p> + +<p> The verify(8) daemon will periodically remove expired entries +from the address verification database, and log the number of entries +retained and dropped (Postfix versions 2.7 and later). A cleanup +run is logged as "partial" when the daemon terminates early because +of "postfix reload, "postfix stop", or because the daemon received +no requests for $max_idle seconds. Postfix versions 2.6 and earlier +do not implement automatic address verification database cleanup. +There, the database is managed manually as described next. </p> + +<p> When the address verification database file becomes too big, +or when it becomes corrupted, the solution is to manually rename +or delete (NOT: truncate) the file and run "postfix reload". The +verify(8) daemon will then create a new database file. </p> + +<h2><a name="probe_routing">Controlling the routing of address +verification probes</a></h2> + +<p> By default, Postfix sends address verification probe messages +via the same route as regular mail, because that normally produces +the most accurate result. It's no good to verify a local address +by connecting to your own SMTP port; that just triggers all kinds +of mailer loop alarms. The same is true for any destination that +your machine is best MX host for: hidden domains, virtual domains, +etc. </p> + +<p> However, some sites have a complex infrastructure where mail +is not sent directly to the Internet, but is instead given to an +intermediate relayhost. This is a problem for address verification, +because remote Internet addresses can be verified only when Postfix +can access remote destinations directly. </p> + +<p> For this reason, Postfix allows you to override the routing +parameters when it delivers an address verification probe message. +</p> + +<p> First, the address_verify_relayhost parameter allows you to +override the relayhost setting, and the address_verify_transport_maps +parameter allows you to override the transport_maps setting. +The address_verify_sender_dependent_relayhost_maps parameter +does the same for sender-dependent relayhost selection. </p> + +<p> Second, each address class is given its own address verification +version of the message delivery transport, as shown in the table +below. Address classes are defined in the ADDRESS_CLASS_README +file. </p> + +<blockquote> + +<table border="1"> + +<tr> <th> Domain list </th> <th> Regular transport</th> <th> Verify +transport </th> </tr> + +<tr> <td> mydestination </td> <td> local_transport </td> <td> +address_verify_local_transport </td> </tr> + +<tr> <td> virtual_alias_domains </td> <td> (not applicable) </td> +<td> (not applicable) </td> </tr> + +<tr> <td> virtual_mailbox_domains </td> <td> virtual_transport +</td> <td> address_verify_virtual_transport </td> </tr> + +<tr> <td> relay_domains </td> <td> relay_transport </td> <td> +address_verify_relay_transport </td> </tr> + +<tr> <td> (not applicable) </td> <td> default_transport </td> <td> +address_verify_default_transport </td> </tr> + +</table> + +</blockquote> + +<p> By default, the parameters that control delivery of address +probes have the same value as the parameters that control normal +mail delivery. </p> + +<h2><a name="forced_examples">Forced probe routing examples</a></h2> + +<p> In a typical scenario one would override the relayhost setting +for address verification probes and leave everything else alone: +</p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + relayhost = $mydomain + address_verify_relayhost = + ... +</pre> +</blockquote> + +<p> Sites behind a network address translation box might have to +use a different SMTP client that sends the correct hostname +information: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + relayhost = $mydomain + address_verify_relayhost = + address_verify_default_transport = direct_smtp + +/etc/postfix/master.cf: + direct_smtp .. .. .. .. .. .. .. .. .. smtp + -o smtp_helo_name=nat.box.tld +</pre> +</blockquote> + +<h2><a name="forced_limitations">Limitations of forced probe routing</a></h2> + +<p> Inconsistencies can happen when probe messages don't follow +the same path as regular mail. For example, a message can be +accepted when it follows the regular route while an otherwise +identical probe message is rejected when it follows the forced +route. The opposite can happen, too, but is less likely. </p> + +</body> + +</html> diff --git a/proto/BACKSCATTER_README.html b/proto/BACKSCATTER_README.html new file mode 100644 index 0000000..aae9430 --- /dev/null +++ b/proto/BACKSCATTER_README.html @@ -0,0 +1,410 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Backscatter Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +Backscatter Howto</h1> + +<hr> + +<h2>Overview </h2> + +<p> This document describes features that require Postfix version +2.0 or later. </p> + +<p> Topics covered in this document: </p> + +<ul> + +<li><a href="#wtf">What is backscatter mail?</a> + +<li><a href="#random">How do I block backscatter mail to random +recipient addresses?</a> + +<li><a href="#real">How do I block backscatter mail to real +recipient addresses?</a> + +<ul> + +<li><a href="#forged_helo">Blocking backscatter mail with forged +mail server information</a> + +<li><a href="#forged_sender">Blocking backscatter mail with forged +sender information</a> + +<li><a href="#forged_other">Blocking backscatter mail with other +forged information</a> + +<li><a href="#scanner">Blocking backscatter mail from virus +scanners</a> + +</ul> + +</ul> + +<p> The examples use Perl Compatible Regular Expressions (Postfix +pcre: tables), but also provide a translation to POSIX regular +expressions (Postfix regexp: tables). PCRE is preferred primarily +because the implementation is often faster.</p> + +<h2><a name="wtf">What is backscatter mail?</a></h2> + +<p> When a spammer or worm sends mail with forged sender addresses, +innocent sites are flooded with undeliverable mail notifications. +This is called backscatter mail. With Postfix, you know that you're +a backscatter victim when your logfile goes on and on like this: +</p> + +<blockquote> +<pre> +Dec 4 04:30:09 hostname postfix/smtpd[58549]: NOQUEUE: reject: +RCPT from xxxxxxx[x.x.x.x]: 550 5.1.1 <yyyyyy@your.domain.here>: +Recipient address rejected: User unknown; from=<> +to=<yyyyyy@your.domain.here> proto=ESMTP helo=<zzzzzz> +</pre> +</blockquote> + +<p> What you see are lots of "user unknown" errors with "from=<>". +These are error reports from MAILER-DAEMONs elsewhere on the Internet, +about email that was sent with a false sender address in your domain. +</p> + +<h2><a name="random">How do I block backscatter mail to random +recipient addresses?</a></h2> + +<p> If your machine receives backscatter mail to random addresses, +configure Postfix to reject all mail for non-existent recipients +as described in the LOCAL_RECIPIENT_README and +STANDARD_CONFIGURATION_README documentation. </p> + +<p> If your machine runs Postfix 2.0 and earlier, disable the "pause +before reject" feature in the SMTP server. If your system is under +stress then it should not waste time. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # Not needed with Postfix 2.1 and later. + smtpd_error_sleep_time = 0 + + # Not needed with Postfix 2.4 and later. + unknown_local_recipient_reject_code = 550 +</pre> +</blockquote> + +<h2><a name="real">How do I block backscatter mail to real +recipient addresses?</a></h2> + +<p> When backscatter mail passes the "unknown recipient" barrier, +there still is no need to despair. Many mail systems are kind +enough to attach the message headers of the undeliverable mail in +the non-delivery notification. These message headers contain +information that you can use to recognize and block forged mail. +</p> + +<h3><a name="forged_helo">Blocking backscatter mail with forged +mail server information</a></h3> + +<p> Although my email address is "wietse@porcupine.org", all my +mail systems announce themselves with the SMTP HELO command as +"hostname.porcupine.org". Thus, if returned mail has a Received: +message header like this: </p> + +<blockquote> +<pre> +Received: from porcupine.org ... +</pre> +</blockquote> + +<p> Then I know that this is almost certainly forged mail (almost; +see <a href="#caveats">next section</a> for the fly in the ointment). +Mail that is really +sent by my systems looks like this: </p> + +<blockquote> +<pre> +Received: from hostname.porcupine.org ... +</pre> +</blockquote> + +<p> For the same reason the following message headers are very likely +to be the result of forgery:</p> + +<blockquote> +<pre> +Received: from host.example.com ([1.2.3.4] helo=porcupine.org) ... +Received: from [1.2.3.4] (port=12345 helo=porcupine.org) ... +Received: from host.example.com (HELO porcupine.org) ... +Received: from host.example.com (EHLO porcupine.org) ... +</pre> +</blockquote> + +<p> Some forgeries show up in the way that a mail server reports +itself in Received: message headers. Keeping in mind that all my +systems have a mail server name of <i>hostname</i>.porcupine.org, +the following is definitely a forgery:</p> + +<blockquote> +<pre> +Received: by porcupine.org ... +Received: from host.example.com ( ... ) by porcupine.org ... +</pre> +</blockquote> + +<p> Another frequent sign of forgery is the Message-ID: header. My +systems produce a Message-ID: of +<<i>stuff</i>@<i>hostname</i>.porcupine.org>. The following +are forgeries, especially the first one: + +<blockquote> +<pre> +Message-ID: <1cb479435d8eb9.2beb1.qmail@porcupine.org> +Message-ID: <yulszqocfzsficvzzju@porcupine.org> +</pre> +</blockquote> + +<p> To block such backscatter I use header_checks and body_checks +patterns like this: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + header_checks = pcre:/etc/postfix/header_checks + body_checks = pcre:/etc/postfix/body_checks + +/etc/postfix/header_checks: + # Do not indent the patterns between "if" and "endif". + if /^Received:/ + /^Received: +from +(porcupine\.org) +/ + reject forged client name in Received: header: $1 + /^Received: +from +[^ ]+ +\(([^ ]+ +[he]+lo=|[he]+lo +)(porcupine\.org)\)/ + reject forged client name in Received: header: $2 + /^Received:.* +by +(porcupine\.org)\b/ + reject forged mail server name in Received: header: $1 + endif + /^Message-ID:.* <!&!/ DUNNO + /^Message-ID:.*@(porcupine\.org)/ + reject forged domain name in Message-ID: header: $1 + +/etc/postfix/body_checks: + # Do not indent the patterns between "if" and "endif". + if /^[> ]*Received:/ + /^[> ]*Received: +from +(porcupine\.org) / + reject forged client name in Received: header: $1 + /^[> ]*Received: +from +[^ ]+ +\(([^ ]+ +[he]+lo=|[he]+lo +)(porcupine\.org)\)/ + reject forged client name in Received: header: $2 + /^[> ]*Received:.* +by +(porcupine\.org)\b/ + reject forged mail server name in Received: header: $1 + endif + /^[> ]*Message-ID:.* <!&!/ DUNNO + /^[> ]*Message-ID:.*@(porcupine\.org)/ + reject forged domain name in Message-ID: header: $1 +</pre> +</blockquote> + +<p> Notes: </p> + +<ul> + +<li> <p> The example uses pcre: tables mainly for speed; with minor +modifications, you can use regexp: tables as explained below. </p> + +<li> <p> The example is simplified for educational purposes. In +reality my patterns list multiple domain names, as +"<tt>(domain|domain|...)</tt>". </p> + +<li> <p> The "<tt>\.</tt>" matches "<tt>.</tt>" literally. Without +the "<tt>\</tt>", the "<tt>.</tt>" would match any character. </p> + +<li> <p> The "<tt>\(</tt>" and "<tt>\)</tt>" match "<tt>(</tt>" +and "<tt>)</tt>" literally. Without the "<tt>\</tt>", the "<tt>(</tt>" +and "<tt>)</tt>" would be grouping operators. </p> + +<li> <p> The "<tt>\b</tt>" is used here to match the end of a word. +If you use regexp: tables, specify "<tt>[[:>:]]</tt>" (on some +systems you should specify "<tt>\></tt>" instead; for details +see your system documentation). + +<li> <p> The "if /pattern/" and "endif" eliminate unnecessary +matching attempts. DO NOT indent lines starting with /pattern/ +between the "if" and "endif"! </p> + +<li> <p> The two "<tt>Message-ID:.* <!&!</tt>" rules are +workarounds for some versions of Outlook express, as described in +the <a href="#caveats"> caveats </a> section below. + +</ul> + +<p><a name="caveats"><strong>Caveats</strong></a></p> + +<ul> + +<li> + +<p> Netscape Messenger (and reportedly, Mozilla) sends a HELO name +that is identical to the sender address domain part. If you have +such clients then the above patterns would block legitimate email. +</p> + +<p> My network has only one such machine, and to prevent its mail +from being blocked I have configured it to send mail as +user@hostname.porcupine.org. On the Postfix server, a canonical +mapping translates this temporary address into user@porcupine.org. +</p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + canonical_maps = hash:/etc/postfix/canonical + +/etc/postfix/canonical: + @hostname.porcupine.org @porcupine.org +</pre> +</blockquote> + +<p> This is of course practical only when you have very few systems +that send HELO commands like this, and when you never have to send +mail to a user on such a host. </p> + +<p> An alternative would be to remove the hostname from +"hostname.porcupine.org" with address +masquerading, as described in the ADDRESS_REWRITING_README document. +</p> + +<li> <p> Reportedly, Outlook 2003 (perhaps Outlook Express, and +other versions as well) present substantially different Message-ID +headers depending upon whether or not a DSN is requested (via Options +"Request a delivery receipt for this message"). </p> + +<p> When a DSN is requested, Outlook 2003 uses a Message-ID string +that ends in the sender's domain name: </p> + +<blockquote> +<pre> +Message-ID: <!&! ...very long string... ==@example.com> +</pre> +</blockquote> + +<p> where <i>example.com</i> is the domain name part of the email +address specified in Outlook's account settings for the user. Since +many users configure their email addresses as <i>username@example.com</i>, +messages with DSN turned on will trigger the REJECT action in the +previous section. </p> + +<p> If you have such clients then you can exclude their Message-ID +strings with the two "<tt>Message-ID:.* <!&!</tt>" patterns +that are shown in the previous section. Otherwise you will not be +able to use the two backscatter rules to stop forged Message ID +strings. Of course this workaround may break the next time Outlook +is changed. </p> + +</ul> + +<h3><a name="forged_sender">Blocking backscatter mail with forged +sender information</a></h3> + +Like many people I still have a few email addresses in domains that +I used in the past. Mail for those addresses is forwarded to my +current address. Most of the backscatter mail that I get claims +to be sent from these addresses. Such mail is obviously forged +and is very easy to stop. + +<blockquote> +<pre> +/etc/postfix/main.cf: + header_checks = pcre:/etc/postfix/header_checks + body_checks = pcre:/etc/postfix/body_checks + +/etc/postfix/header_checks: + /^(From|Return-Path):.*\b(user@domain\.tld)\b/ + reject forged sender address in $1: header: $2 + +/etc/postfix/body_checks: + /^[> ]*(From|Return-Path):.*\b(user@domain\.tld)\b/ + reject forged sender address in $1: header: $2 +</pre> +</blockquote> + +<p> Notes: </p> + +<ul> + +<li> <p> The example uses pcre: tables mainly for speed; with minor +modifications, you can use regexp: tables as explained below. </p> + +<li> <p> The example is simplified for educational purposes. In +reality, my patterns list multiple email addresses as +"<tt>(user1@domain1\.tld|user2@domain2\.tld)</tt>". </p> + +<li> <p> The two "<tt>\b</tt>" as used in "<tt>\b(user@domain\.tld)\b</tt>" +match the beginning and end of a word, respectively. If you use +regexp: tables, specify "<tt>[[:<:]]</tt> and <tt>[[:>:]]</tt>" +(on some systems you should specify "<tt>\<</tt> and <tt>\></tt>" +instead; for details see your system documentation). </p> + +<li> <p> The "<tt>\.</tt>" matches "<tt>.</tt>" literally. Without +the "<tt>\</tt>", the "<tt>.</tt>" would match any character. </p> + +</ul> + +<h3><a name="forged_other">Blocking backscatter mail with other +forged information</a></h3> + +<p> Another sign of forgery can be found in the IP address that is +recorded in Received: headers next to your HELO host or domain name. +This information must be used with care, though. Some mail servers +are behind a network address translator and never see the true +client IP address. </p> + +<h3><a name="scanner">Blocking backscatter mail from virus +scanners</a></h3> + +<p> With all the easily recognizable forgeries eliminated, there +is one category of backscatter mail that remains, and that is +notifications from virus scanner software. Unfortunately, some +virus scanning software doesn't know that viruses forge sender +addresses. To make matters worse, the software also doesn't know +how to report a mail delivery problem, so that we cannot use the +above techniques to recognize forgeries. </p> + +<p> Recognizing virus scanner mail is an error prone process, +because there is a lot of variation in report formats. The following +is only a small example of message header patterns. For a large +collection of header and body patterns that recognize virus +notification email, see +https://web.archive.org/web/20100317123907/http://std.dkuug.dk/keld/virus/ +or http://www.t29.dk/antiantivirus.txt. </p> + +<blockquote> +<pre> +/etc/postfix/header_checks: + /^Subject: *Your email contains VIRUSES/ DISCARD virus notification + /^Content-Disposition:.*VIRUS1_DETECTED_AND_REMOVED/ + DISCARD virus notification + /^Content-Disposition:.*VirusWarning.txt/ DISCARD virus notification +</pre> +</blockquote> + +<p> Note: these documents haven't been updated since 2004, so they +are useful only as a starting point. </p> + +<p> A plea to virus or spam scanner operators: please do not make +the problem worse by sending return mail to forged sender addresses. +You're only harassing innocent people. If you must return mail to +the purported sender, please return the full message headers, so +that the sender can filter out the obvious forgeries. </p> + +</body> + +</html> diff --git a/proto/BASIC_CONFIGURATION_README.html b/proto/BASIC_CONFIGURATION_README.html new file mode 100644 index 0000000..531dbf9 --- /dev/null +++ b/proto/BASIC_CONFIGURATION_README.html @@ -0,0 +1,684 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title> Postfix Basic Configuration </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Basic Configuration </h1> + +<hr> + +<h2> Introduction </h2> + +<p> Postfix has several hundred configuration parameters that are +controlled via the main.cf file. Fortunately, all parameters have +sensible default values. In many cases, you need to configure only +two or three parameters before you can start to play with the mail +system. Here's a quick introduction to the syntax: </p> + +<ul> + +<li> <p> <a href="#syntax">Postfix configuration files</a></p> + +</ul> + +<p> The text below assumes that you already have Postfix installed +on the system, either by compiling the source code yourself (as +described in the INSTALL file) or by installing an already compiled +version. </p> + +<p> This document covers basic Postfix configuration. Information +about how to configure Postfix for specific applications such as +mailhub, firewall or dial-up client can be found in the +STANDARD_CONFIGURATION_README file. But don't go there until you +already have covered the material presented below. </p> + +<p> The first parameters of interest specify the machine's identity +and role in the network. </p> + +<ul> + +<li> <p> <a href="#myorigin"> What domain name to use in outbound mail </a> </p> + +<li> <p> <a href="#mydestination"> What domains to receive mail for </a> </p> + +<li> <p> <a href="#relay_from"> What clients to relay mail from </a> </p> + +<li> <p> <a href="#relay_to"> What destinations to relay mail to </a> </p> + +<li> <p> <a href="#relayhost"> What delivery method: direct or +indirect </a> </p> + +</ul> + +<p> The default values for many other configuration parameters are +derived from just these. </p> + +<p> The next parameter of interest controls the amount of mail sent +to the local postmaster: </p> + +<ul> + +<li> <p> <a href="#notify"> What trouble to report to the postmaster +</a> </p> + +</ul> + +<p> Be sure to set the following correctly if you're behind a proxy or +network address translator, and you are running a backup MX host +for some other domain: </p> + +<ul> + +<li> <p> <a href="#proxy_interfaces"> Proxy/NAT external network +addresses </a> </p> + +</ul> + +<p> Postfix daemon processes run in the background, and log problems +and normal activity to the syslog daemon. Here are a few things +that you need to be aware of: </p> + +<ul> + +<li> <p> <a href="#syslog_howto"> What you need to know about +Postfix logging </a> </p> + +</ul> + +<p> If your machine has unusual security requirements you may +want to run Postfix daemon processes inside a chroot environment. </p> + +<ul> + +<li> <p> <a href="#chroot_setup"> Running Postfix daemon processes +chrooted </a> </p> + +</ul> +<p> If you run Postfix on a virtual network interface, or if your +machine runs other mailers on virtual interfaces, you'll have to +look at the other parameters listed here as well: </p> + +<ul> + +<li> <p> <a href="#myhostname"> My own hostname </a> </p> + +<li> <p> <a href="#mydomain"> My own domain name </a> </p> + +<li> <p> <a href="#inet_interfaces"> My own network addresses </a> </p> + +</ul> + +<h2> <a name="syntax">Postfix configuration files</a></h2> + +<p> By default, Postfix configuration files are in /etc/postfix. +The two most important files are main.cf and master.cf; these files +must be owned by root. Giving someone else write permission to +main.cf or master.cf (or to their parent directories) means giving +root privileges to that person. </p> + +<p> In /etc/postfix/main.cf you will have to set up a minimal number +of configuration parameters. Postfix configuration parameters +resemble shell variables, with two important differences: the first +one is that Postfix does not know about quotes like the UNIX shell +does.</p> + +<p> You specify a configuration parameter as: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + parameter = value +</pre> +</blockquote> + +<p> and you use it by putting a "$" character in front of its name: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + other_parameter = $parameter +</pre> +</blockquote> + +<p> You can use $parameter before it is given a value (that is the +second main difference with UNIX shell variables). The Postfix +configuration language uses lazy evaluation, and does not look at +a parameter value until it is needed at runtime. </p> + +<p> Postfix uses database files for access control, address rewriting +and other purposes. The DATABASE_README file gives an introduction +to how Postfix works with Berkeley DB, LDAP or SQL and other types. +Here is a common example of how Postfix invokes a database: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + virtual_alias_maps = hash:/etc/postfix/virtual +</pre> +</blockquote> + +<p> Whenever you make a change to the main.cf or master.cf file, +execute the following command as root in order to refresh a running +mail system: </p> + +<blockquote> +<pre> +# postfix reload +</pre> +</blockquote> + +<h2> <a name="myorigin"> What domain name to use in outbound mail </a> </h2> + +<p> The myorigin parameter specifies the domain that appears in +mail that is posted on this machine. The default is to use the +local machine name, $myhostname, which defaults to the name of the +machine. Unless you are running a really small site, you probably +want to change that into $mydomain, which defaults to the parent +domain of the machine name. </p> + +<p> For the sake of consistency between sender and recipient addresses, +myorigin also specifies the domain name that is appended +to an unqualified recipient address. </p> + +<p> Examples (specify only one of the following): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + myorigin = $myhostname (default: send mail as "user@$myhostname") + myorigin = $mydomain (probably desirable: "user@$mydomain") +</pre> +</blockquote> + +<h2><a name="mydestination"> What domains to receive mail for </a> +</h2> + +<p> The mydestination parameter specifies what domains this +machine will deliver locally, instead of forwarding to another +machine. The default is to receive mail for the machine itself. +See the VIRTUAL_README file for how to configure Postfix for +hosted domains. </p> + +<p> You can specify zero or more domain names, "/file/name" patterns +and/or "type:table" lookup tables (such as hash:, btree:, nis:, ldap:, +or mysql:), separated by whitespace and/or commas. A "/file/name" +pattern is replaced by its contents; "type:table" requests that a +table lookup is done and merely tests for existence: the lookup +result is ignored. </p> + +<p> IMPORTANT: If your machine is a mail server for its entire +domain, you must list $mydomain as well. </p> + +<p> Example 1: default setting. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + mydestination = $myhostname localhost.$mydomain localhost +</pre> +</blockquote> + +<p> Example 2: domain-wide mail server. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + mydestination = $myhostname localhost.$mydomain localhost $mydomain +</pre> +</blockquote> + +<p> Example 3: host with multiple DNS A records. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + mydestination = $myhostname localhost.$mydomain localhost + www.$mydomain ftp.$mydomain +</pre> +</blockquote> + +<p> Caution: in order to avoid mail delivery loops, you must list all +hostnames of the machine, including $myhostname, and localhost.$mydomain. </p> + +<h2> <a name="relay_from"> What clients to relay mail from </a> </h2> + +<p> By default, Postfix will forward mail from clients in authorized +network blocks to any destination. Authorized networks are defined +with the mynetworks configuration parameter. The current default is to +authorize the local machine only. Prior to Postfix 3.0, the default +was to authorize all clients in the IP subnetworks that the local +machine is attached to. </p> + +<p> Postfix can also be configured to relay mail from "mobile" +clients that send mail from outside an authorized network block. +This is explained in the SASL_README and TLS_README documents. </p> + +<p> IMPORTANT: If your machine is connected to a wide area network +then the "mynetworks_style = subnet" setting may be too friendly. </p> + +<p> Examples (specify only one of the following): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + mynetworks_style = subnet (not safe on a wide area network) + mynetworks_style = host (authorize local machine only) + mynetworks = 127.0.0.0/8 (authorize local machine only) + mynetworks = 127.0.0.0/8 168.100.189.2/32 (authorize local machine) + mynetworks = 127.0.0.0/8 168.100.189.2/28 (authorize local networks) +</pre> +</blockquote> + +<p> You can specify the trusted networks in the main.cf file, or +you can let Postfix do the work for you. The default is to let +Postfix do the work. The result depends on the mynetworks_style +parameter value. + +<ul> + +<li> <p> Specify "mynetworks_style = host" (the default when +compatibility_level ≥ 2) when Postfix should forward mail from +only the local machine. </p> + +<li> <p> Specify "mynetworks_style = subnet" (the default when +compatibility_level < 2) when Postfix should forward mail from +SMTP clients in the same IP subnetworks as the local machine. +On Linux, this works correctly only with interfaces specified +with the "ifconfig" or "ip" command. </p> + +<li> <p> Specify "mynetworks_style = class" when Postfix should +forward mail from SMTP clients in the same IP class A/B/C networks +as the local machine. Don't do this with a dialup site - it would +cause Postfix to "trust" your entire provider's network. Instead, +specify an explicit mynetworks list by hand, as described below. +</p> + +</ul> + +<p> Alternatively, you can specify the mynetworks list by hand, +in which case Postfix ignores the mynetworks_style setting. +To specify the list of trusted networks by hand, specify network +blocks in CIDR (network/mask) notation, for example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + mynetworks = 168.100.189.0/28, 127.0.0.0/8 +</pre> +</blockquote> + +<p> You can also specify the absolute pathname of a pattern file instead +of listing the patterns in the main.cf file. </p> + +<h2> <a name="relay_to"> What destinations to relay mail to </a> </h2> + +<p> By default, Postfix will forward mail from strangers (clients outside +authorized networks) to authorized remote destinations only. +Authorized remote +destinations are defined with the relay_domains configuration +parameter. The default is to authorize all domains (and subdomains) +of the domains listed with the mydestination parameter. </p> + +<p> Examples (specify only one of the following): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + relay_domains = $mydestination (default) + relay_domains = (safe: never forward mail from strangers) + relay_domains = $mydomain (forward mail to my domain and subdomains) +</pre> +</blockquote> + +<h2> <a name="relayhost"> What delivery method: direct or +indirect </a> </h2> + +<p> By default, Postfix tries to deliver mail directly to the +Internet. Depending on your local conditions this may not be possible +or desirable. For example, your system may be turned off outside +office hours, it may be behind a firewall, or it may be connected +via a provider who does not allow direct mail to the Internet. In +those cases you need to configure Postfix to deliver mail indirectly +via a relay host. </p> + +<p> Examples (specify only one of the following): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + relayhost = (default: direct delivery to Internet) + relayhost = $mydomain (deliver via local mailhub) + relayhost = [mail.$mydomain] (deliver via local mailhub) + relayhost = [mail.isp.tld] (deliver via provider mailhub) +</pre> +</blockquote> + +<p> The form enclosed with <tt>[]</tt> eliminates DNS MX lookups. +Don't worry if you don't know what that means. Just be sure to +specify the <tt>[]</tt> around the mailhub hostname that your ISP +gave to you, otherwise mail may be mis-delivered. </p> + +<p> The STANDARD_CONFIGURATION_README file has more hints and tips +for firewalled and/or dial-up networks. </p> + +<h2> <a name="notify"> What trouble to report to the postmaster</a> </h2> + +<p> You should set up a postmaster alias in the aliases(5) table +that directs mail to a human person. The postmaster address is +required to exist, so that people can report mail delivery problems. +While you're updating the aliases(5) table, be sure to direct mail +for the super-user to a human person too. </p> + +<blockquote> +<pre> +/etc/aliases: + postmaster: you + root: you +</pre> +</blockquote> + +<p> Execute the command "newaliases" after changing the aliases +file. Instead of /etc/aliases, your alias file may be located +elsewhere. Use the command "postconf alias_maps" to find out.</p> + +<p> The Postfix system reports problems to the postmaster alias. +You may not be interested in all types of trouble reports, so this +reporting mechanism is configurable. The default is to report only +serious problems (resource, software) to postmaster: </p> + +<p> Default setting: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + notify_classes = resource, software +</pre> +</blockquote> + +<p> The meaning of the classes is as follows: </p> + +<blockquote> + +<dl> + +<dt> bounce </dt> <dd> Inform the postmaster of undeliverable +mail. Either send the postmaster a copy of undeliverable mail that +is returned to the sender, or send a transcript of the SMTP session +when Postfix rejected mail. For privacy reasons, the postmaster +copy of undeliverable mail is truncated after the original message +headers. This implies "2bounce" (see below). See also the +luser_relay feature. The notification is sent to the address +specified with the bounce_notice_recipient configuration parameter +(default: postmaster). </dd> + +<dt> 2bounce </dt> <dd> When Postfix is unable to return undeliverable +mail to the sender, send it to the postmaster instead (without +truncating the message after the primary headers). The notification +is sent to the address specified with the 2bounce_notice_recipient +configuration parameter (default: postmaster). </dd> + +<dt> delay </dt> <dd> Inform the postmaster of delayed mail. In +this case, the postmaster receives message headers only. The +notification is sent to the address specified with the +delay_notice_recipient configuration parameter (default: postmaster). +</dd> + +<dt> policy </dt> <dd> Inform the postmaster of client requests +that were rejected because of (UCE) policy restrictions. The +postmaster receives a transcript of the SMTP session. The notification +is sent to the address specified with the error_notice_recipient +configuration parameter (default: postmaster). </dd> + +<dt> protocol </dt> <dd> Inform the postmaster of protocol errors +(client or server side) or attempts by a client to execute +unimplemented commands. The postmaster receives a transcript of +the SMTP session. The notification is sent to the address specified +with the error_notice_recipient configuration parameter (default: +postmaster). </dd> + +<dt> resource </dt> <dd> Inform the postmaster of mail not delivered +due to resource problems (for example, queue file write errors). +The notification is sent to the address specified with the +error_notice_recipient configuration parameter (default: postmaster). +</dd> + +<dt> software </dt> <dd> Inform the postmaster of mail not delivered +due to software problems. The notification is sent to the address +specified with the error_notice_recipient configuration parameter +(default: postmaster). </dd> + +</dl> + +</blockquote> + +<h2><a name="proxy_interfaces"> Proxy/NAT external network +addresses</a> </h2> + +<p> Some mail servers are connected to the Internet via a network +address translator (NAT) or proxy. This means that systems on the +Internet connect to the address of the NAT or proxy, instead of +connecting to the network address of the mail server. The NAT or +proxy forwards the connection to the network address of the mail +server, but Postfix does not know this. </p> + +<p> If you run a Postfix server behind a proxy or NAT, you need to +configure the proxy_interfaces parameter and specify all the external +proxy or NAT addresses that Postfix receives mail on. You may +specify symbolic hostnames instead of network addresses. </p> + +<p> IMPORTANT: You must specify your proxy/NAT external addresses +when your system is a backup MX host for other domains, otherwise +mail delivery loops will happen when the primary MX host is down. +</p> + +<p> Example: host behind NAT box running a backup MX host. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + proxy_interfaces = 1.2.3.4 (the proxy/NAT external network address) +</pre> +</blockquote> + +<h2> <a name="syslog_howto"> What you need to know about +Postfix logging </a> </h2> + +<p> Postfix daemon processes run in the background, and log problems +and normal activity to the syslog daemon. The syslogd process sorts +events by class and severity, and appends them to logfiles. The +logging classes, levels and logfile names are usually specified in +/etc/syslog.conf. At the very least you need something like: </p> + +<blockquote> +<pre> +/etc/syslog.conf: + mail.err /dev/console + mail.debug /var/log/maillog +</pre> +</blockquote> + +<p> After changing the syslog.conf file, send a "HUP" signal to +the syslogd process. </p> + +<p> IMPORTANT: many syslogd implementations will not create files. +You must create files before (re)starting syslogd. </p> + +<p> IMPORTANT: on Linux you need to put a "-" character before the +pathname, e.g., -/var/log/maillog, otherwise the syslogd process +will use more system resources than Postfix. </p> + +<p> Hopefully, the number of problems will be small, but it is a good +idea to run every night before the syslog files are rotated: </p> + +<blockquote> +<pre> +# postfix check +# egrep '(reject|warning|error|fatal|panic):' /some/log/file +</pre> +</blockquote> + +<ul> + +<li> <p> The first line (postfix check) causes Postfix to report +file permission/ownership discrepancies. </p> + +<li> <p> The second line looks for problem reports from the mail +software, and reports how effective the relay and junk mail access +blocks are. This may produce a lot of output. You will want to +apply some postprocessing to eliminate uninteresting information. +</p> + +</ul> + +<p> The <a href="DEBUG_README.html#logging"> DEBUG_README </a> +document describes the meaning of the "warning" etc. labels in +Postfix logging. </p> + +<h2> <a name="chroot_setup"> Running Postfix daemon processes +chrooted </a> </h2> + +<p> Postfix daemon processes can be configured (via the master.cf +file) to run in a chroot jail. The processes run at a fixed low +privilege and with file system access limited to the Postfix queue +directories (/var/spool/postfix). This provides a significant +barrier against intrusion. The barrier is not impenetrable (chroot +limits file system access only), but every little bit helps.</p> + +<p>With the exception of Postfix daemons that deliver mail locally +and/or that execute non-Postfix commands, every Postfix daemon can +run chrooted.</p> + +<p>Sites with high security requirements should consider to chroot +all daemons that talk to the network: the smtp(8) and smtpd(8) +processes, and perhaps also the lmtp(8) client. The author's own +porcupine.org mail server runs all daemons chrooted that can be +chrooted. </p> + +<p>The default /etc/postfix/master.cf file specifies that no Postfix +daemon runs chrooted. In order to enable chroot operation, edit +the file /etc/postfix/master.cf, and follow instructions in the +file. When you're finished, execute "postfix reload" to make the +change effective. </p> + +<p>Note that a chrooted daemon resolves all filenames relative to +the Postfix queue directory (/var/spool/postfix). For successful +use of a chroot jail, most UNIX systems require you to bring in +some files or device nodes. The examples/chroot-setup directory in +the source code distribution has a collection of scripts that help +you set up Postfix chroot environments on different operating +systems.</p> + +<p> Additionally, you almost certainly need to configure syslogd +so that it listens on a socket inside the Postfix queue directory. +Examples of syslogd command line options that achieve this for +specific systems: </p> + +<p> FreeBSD: <tt>syslogd -l /var/spool/postfix/var/run/log</tt> </p> + +<p> Linux, OpenBSD: <tt>syslogd -a /var/spool/postfix/dev/log</tt> </p> + +<h2><a name="myhostname"> My own hostname </a> </h2> + +<p> The myhostname parameter specifies the fully-qualified domain +name of the machine running the Postfix system. $myhostname +appears as the default value in many other Postfix configuration +parameters. </p> + +<p> By default, myhostname is set to the local machine name. If +your local machine name is not in fully-qualified domain name form, +or if you run Postfix on a virtual interface, you will have to +specify the fully-qualified domain name that the mail system should +use. </p> + +<p> Alternatively, if you specify mydomain in main.cf, then Postfix +will use its value to generate a fully-qualified default value +for the myhostname parameter. </p> + +<p> Examples (specify only one of the following): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + myhostname = host.local.domain (machine name is not FQDN) + myhostname = host.virtual.domain (virtual interface) + myhostname = virtual.domain (virtual interface) +</pre> +</blockquote> + +<h2><a name="mydomain"> My own domain name</a> </h2> + +<p> The mydomain parameter specifies the parent domain of +$myhostname. By default, it is derived from $myhostname +by stripping off the first part (unless the result would be a +top-level domain). </p> + +<p> Conversely, if you specify mydomain in main.cf, then Postfix +will use its value to generate a fully-qualified default value +for the myhostname parameter. </p> + +<p> Examples (specify only one of the following): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + mydomain = local.domain + mydomain = virtual.domain (virtual interface) +</pre> +</blockquote> + +<h2><a name="inet_interfaces">My own network addresses</a> </h2> + +<p>The inet_interfaces parameter specifies all network interface +addresses that the Postfix system should listen on; mail addressed +to "user@[network address]" will be delivered locally, +as if it is addressed to a domain listed in $mydestination.</p> + +<p> You can override the inet_interfaces setting in the Postfix +master.cf file by prepending an IP address to a server name. </p> + +<p> The default is to listen on all active interfaces. If you run +mailers on virtual interfaces, you will have to specify what +interfaces to listen on. </p> + +<p> IMPORTANT: If you run MTAs on virtual interfaces you must +specify explicit inet_interfaces values for the MTA that receives +mail for the machine itself: this MTA should never listen on the +virtual interfaces or you would have a mailer loop when a virtual +MTA is down. </p> + +<p> Example: default setting. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + inet_interfaces = all +</pre> +</blockquote> + +<p> Example: host running one or more virtual mailers. For +each Postfix instance, specify only one of the following. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + inet_interfaces = virtual.host.tld (virtual Postfix) + inet_interfaces = $myhostname localhost... (non-virtual Postfix) +</pre> +</blockquote> + +<p> Note: you need to stop and start Postfix after changing this +parameter. </p> + +</body> + +</html> diff --git a/proto/BDAT_README.html b/proto/BDAT_README.html new file mode 100644 index 0000000..1891c7b --- /dev/null +++ b/proto/BDAT_README.html @@ -0,0 +1,178 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix BDAT (CHUNKING) support</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +BDAT (CHUNKING) support</h1> + +<hr> + +<h2>Overview </h2> + +<p> Postfix SMTP server supports RFC 3030 CHUNKING (the BDAT command) +without BINARYMIME, in both smtpd(8) and postscreen(8). It is enabled +by default. </p> + +<p> Topics covered in this document: </p> + +<ul> + +<li><a href="#disable"> Disabling BDAT support</a> + +<li><a href="#impact"> Impact on existing configurations</a> + +<li><a href="#example"> Example SMTP session</a> + +<li> <a href="#benefits">Benefits of CHUNKING (BDAT) support without BINARYMIME</a> + +<li> <a href="#downsides">Downsides of CHUNKING (BDAT) support</a> + +</ul> + +<h2> <a name="disable"> Disabling BDAT support </a> </h2> + +<p> BDAT support is enabled by default. To disable BDAT support +globally: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # The logging alternative: + smtpd_discard_ehlo_keywords = chunking + # The non-logging alternative: + smtpd_discard_ehlo_keywords = chunking, silent-discard +</pre> +</blockquote> + +<p> Specify '-o smtpd_discard_ehlo_keywords=' in master.cf +for the submission and smtps services, if you have clients +that benefit from CHUNKING support. </p> + +<h2> <a name="impact"> Impact on existing configurations </a> </h2> + +<ul> + +<li> <p> There are no changes for smtpd_mumble_restrictions, +smtpd_proxy_filter, smtpd_milters, or for postscreen settings, +except for the above mentioned option to suppress the SMTP server's +CHUNKING service announcement. </p> + +<li> <p> There are no changes in the Postfix queue file content, +no changes for down-stream SMTP servers or after-queue content +filters, and no changes in the envelope or message content that +Milters will receive. </p> + +</ul> + +<h2> <a name="example"> Example SMTP session</a> </h2> + +<p> The main differences are that the Postfix SMTP server announces +"CHUNKING" support in the EHLO response, and that instead of sending +one DATA request, the remote SMTP client may send one or more BDAT +requests. In the example below, "S:" indicates server responses, +and "C:" indicates client requests (bold font). </p> + +<blockquote> +<pre> + S: 220 server.example.com + C: <b>EHLO client.example.com</b> + S: 250-server.example.com + S: 250-PIPELINING + S: 250-SIZE 153600000 + S: 250-VRFY + S: 250-ETRN + S: 250-STARTTLS + S: 250-AUTH PLAIN LOGIN + S: 250-ENHANCEDSTATUSCODES + S: 250-8BITMIME + S: 250-DSN + S: 250-SMTPUTF8 + S: 250 CHUNKING + C: <b>MAIL FROM:<sender@example.com></b> + S: 250 2.1.0 Ok + C: <b>RCPT TO:<recipient@example.com></b> + S: 250 2.1.5 Ok + C: <b>BDAT 10000</b> + C: <b>..followed by 10000 bytes...</b> + S: 250 2.0.0 Ok: 10000 bytes + C: <b>BDAT 123</b> + C: <b>..followed by 123 bytes...</b> + S: 250 2.0.0 Ok: 123 bytes + C: <b>BDAT 0 LAST</b> + S: 250 2.0.0 Ok: 10123 bytes queued as 41yYhh41qmznjbD + C: <b>QUIT</b> + S: 221 2.0.0 Bye +</pre> +</blockquote> + +<p> Internally in Postfix, there is no difference between mail that +was received with BDAT or with DATA. Postfix smtpd_mumble_restrictions, +policy delegation queries, smtpd_proxy_filter and Milters all behave +as if Postfix received (MAIL + RCPT + DATA + end-of-data). However, +Postfix will log BDAT-related failures as "xxx after BDAT" to avoid +complicating troubleshooting (xxx = 'lost connection' or 'timeout'), +and will log a warning when a client sends a malformed BDAT command. +</p> + +<h2> <a name="benefits">Benefits of CHUNKING (BDAT) support without +BINARYMIME</a> </h2> + +<p> Support for CHUNKING (BDAT) was added to improve interoperability +with some clients, a benefit that would reportedly exist even without +Postfix support for BINARYMIME. Since June 2018, Wietse's mail +server has received BDAT commands from a variety of systems. </p> + +<p> Postfix does not support BINARYMIME at this time because: </p> + +<ul> + +<li> <p> BINARYMIME support would require moderately invasive +changes to Postfix, to support email content that is not line-oriented. +With BINARYMIME, the Content-Length: message header specifies the +length of content that may or may not have line boundaries. Without +BINARYMIME support, email RFCs require that binary content is +base64-encoded, and formatted as lines of text. </p> + +<li> <p> For delivery to non-BINARYMIME systems including UNIX mbox, +the available options are to convert binary content into 8bit text, +one of the 7bit forms (base64 or quoted-printable), or to return +email as undeliverable. Any conversion would obviously break digital +signatures, so conversion would have to happen before signing. </p> + +</ul> + +<h2> <a name="downsides">Downsides of CHUNKING (BDAT) support</a> +</h2> + +<p> The RFC 3030 authors did not specify any limitations on how +clients may pipeline commands (i.e. send commands without waiting +for a server response). If a server announces PIPELINING support, +like Postfix does, then a remote SMTP client can pipeline all +commands following EHLO, for example, MAIL/RCPT/BDAT/BDAT/MAIL/RCPT/BDAT, +without ever having to wait for a server response. This means that +with BDAT, the Postfix SMTP server cannot distinguish between a +well-behaved client and a spambot, based on their command pipelining +behavior. If you require "reject_unauth_pipelining" to block spambots, +then turn off Postfix's CHUNKING announcement as described above. +</p> + +<p> In RFC 4468, the authors write that a client may pipeline +commands, and that after sending BURL LAST or BDAT LAST, a client +must wait for the server's response. But as this text does not +appear in RFC 3030 which defines BDAT, it is a useless restriction +that Postfix will not enforce. </p> + +</body> + +</html> diff --git a/proto/BUILTIN_FILTER_README.html b/proto/BUILTIN_FILTER_README.html new file mode 100644 index 0000000..939fafb --- /dev/null +++ b/proto/BUILTIN_FILTER_README.html @@ -0,0 +1,488 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Built-in Content Inspection</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" alt=""> +Postfix Built-in Content Inspection</h1> + +<hr> + +<h2>Built-in content inspection introduction </h2> + +<p> Postfix supports a built-in filter mechanism that examines +message header and message body content, one line at a time, before +it is stored in the Postfix queue. The filter is usually implemented +with POSIX or PCRE regular expressions, as described in the +header_checks(5) manual page. </p> + +<p> The original purpose of the built-in filter is to stop an +outbreak of specific email worms or viruses, and it does this job +well. The filter has also helped to block bounced junk email, +bounced email from worms or viruses, and notifications from virus +detection systems. Information about this secondary application +is given in the BACKSCATTER_README document. </p> + +<p> Because the built-in filter is optimized for stopping specific +worms and virus outbreaks, it has <a href="#limitations">limitations</a> +that make it NOT suitable for general junk email and virus detection. +For that, you should use one of the external content inspection +methods that are described in the FILTER_README, SMTPD_PROXY_README +and MILTER_README documents. </p> + +<p> The following diagram gives an over-all picture of how Postfix +built-in content inspection works: </p> + +<blockquote> + +<table> + +<tr> + + <td colspan="4"> <td bgcolor="#f0f0ff" align="center" + valign="middle"> Postmaster<br> notifications </td> + +</tr> + +<tr> + + <td colspan="4"> <td align="center"> <tt> |<br>v </tt></td> + +</tr> + +<tr> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + Network or<br> local users </td> + + <td align="center" valign="middle"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + + <b> Built-in<br> filter</b> </td> + + <td align="center" valign="middle"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + Postfix<br> queue </td> + + <td align="center" valign="middle"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + Delivery<br> agents </td> + + <td align="center" valign="middle"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + Network or<br> local mailbox </td> + +</tr> + +<tr> + + <td colspan="4"> <td align="center"> ^<br> <tt> | </tt> </td> + <td> </td> <td align="center"> <tt> |<br>v </tt> </td> + +</tr> + +<tr> + + <td colspan="4"> <td colspan="3" bgcolor="#f0f0ff" align="center" + valign="middle"> Undeliverable mail<br> Forwarded mail</td> + +</tr> + +</table> + +</blockquote> + +<p> The picture makes clear that the filter works while Postfix is +receiving new mail. This means that Postfix can reject mail from +the network without having to return undeliverable mail to the +originator address (which is often spoofed anyway). However, this +ability comes at a price: if mail inspection takes too much time, +then the remote client will time out, and the client may send the +same message repeatedly. </p> + +<p>Topics covered by this document: </p> + +<ul> + +<li><a href="#what">What mail is subjected to header/body checks </a> + +<li><a href="#limitations">Limitations of Postfix header/body checks </a> + +<li><a href="#daily">Preventing daily mail status reports from being blocked </a> + +<li><a href="#remote_only">Configuring header/body checks for mail from outside users only</a> + +<li><a href="#mx_submission">Configuring different header/body checks for MX service and submission service</a> + +<li><a href="#domain_except">Configuring header/body checks for mail to some domains only</a> + +</ul> + +<h2><a name="what">What mail is subjected to header/body checks </a></h2> + +<p> Postfix header/body checks are implemented by the cleanup(8) +server before it injects mail into the incoming queue. The diagram +below zooms in on the cleanup(8) server, and shows that this server +handles mail from many different sources. In order to keep the +diagram readable, the sources of postmaster notifications are not +shown, because they can be produced by many Postfix daemon processes. +</p> + +<blockquote> + +<table> + +<tr> <td colspan="2"> </td> <td bgcolor="#f0f0ff" align="center" +valign="middle"> bounce(8)<br> (undeliverable) </td> </tr> + +<tr> <td bgcolor="#f0f0ff" align="center" valign="middle"> <b> +smtpd(8)<br> (network)</b> </td> <td align="left" valign="bottom"> +<tt> \ </tt> </td> <td align="center" valign="middle"> <tt> |<br>v +</tt> </td> </tr> + +<tr> <td> </td> <td> </td> </tr> + +<tr> <td bgcolor="#f0f0ff" align="center" valign="middle"> <b> +qmqpd(8)<br> (network)</b> </td> <td align="center" valign="middle"> +<tt> -\<br>-/ </tt> </td> <td bgcolor="#f0f0ff" align="center" +valign="middle"> cleanup(8) </td> <td align="center" valign="middle"> +<tt> -> </tt> </td> <td bgcolor="#f0f0ff" align="center" +valign="middle"> <a href="QSHAPE_README.html#incoming_queue"> +incoming<br> queue </a> </td> </tr> + +<tr> <td bgcolor="#f0f0ff" align="center" valign="middle"> <b> +pickup(8)<br> (local)</b> </td> <td align="left" valign="top"> <tt> +/ </tt> </td> <td align="center" valign="middle"> ^<br> <tt> | +</tt> </td> </tr> + +<tr> <td colspan="2"> </td> <td bgcolor="#f0f0ff" align="center" +valign="middle"> local(8)<br> (forwarded) </td> </tr> + +</table> + +</blockquote> + +<p> For efficiency reasons, only mail that enters from outside of +Postfix is inspected with header/body checks. It would be inefficient +to filter already filtered mail again, and it would be undesirable +to block postmaster notifications. The table below summarizes what +mail is and is not subject to header/body checks. </p> + +<blockquote> + +<table border="1"> + +<tr> <th> Message type </th> <th> Source </th> <th> Header/body checks? </th> </tr> + +<tr> <td> Undeliverable mail </td> <td> bounce(8) </td> <td> No </td> </tr> + +<tr> <td> Network mail </td> <td> smtpd(8) </td> <td> Configurable </td> </tr> + +<tr> <td> Network mail </td> <td> qmqpd(8) </td> <td> Configurable </td> </tr> + +<tr> <td> Local submission </td> <td> pickup(8) </td> <td> Configurable </td> </tr> + +<tr> <td> Local forwarding </td> <td> local(8) </td> <td> No </td> </tr> + +<tr> <td> Postmaster notice </td> <td> many </td> <td> No </td> </tr> + +</table> + +</blockquote> + +<p> How does Postfix decide what mail needs to be filtered? It +would be clumsy to make the decision in the cleanup(8) server, as +this program receives mail from so many different sources. Instead, +header/body checks are requested by the source. Examples of how +to turn off header/body checks for mail received with smtpd(8), +qmqpd(8) or pickup(8) are given below under "<a +href="#remote_only">Configuring header/body checks for mail from +outside users only</a>", "<a href="#mx_submission">Configuring +different header/body checks for MX service and submission +service</a>", and "<a href="#domain_except">Configuring +header/body checks for mail to some domains only</a>". </p> + +<h2><a name="limitations">Limitations of Postfix header/body checks </a></h2> + +<ul> + +<li> <p> Header/body checks do not decode message headers or message +body content. For example, if text in the message body is BASE64 +encoded (RFC 2045) then your regular expressions will have to match +the BASE64 encoded form. Likewise, message headers with encoded +non-ASCII characters (RFC 2047) need to be matched in their encoded +form. </p> + +<li> <p> Header/body checks cannot filter on a combination of +message headers or body lines. Header/body checks examine content +one message header at a time, or one message body line at a time, +and cannot carry a decision over to the next message header or body +line. </p> + +<li> <p> Header/body checks cannot depend on the recipient of a +message. </p> + +<ul> + +<li> <p> One message can have multiple recipients, and all recipients +of a message receive the same treatment. Workarounds have been +proposed that involve selectively deferring some recipients of +multi-recipient mail, but that results in poor SMTP performance +and does not work for non-SMTP mail. </p> + +<li> <p> Some sources of mail send the headers and content ahead +of the recipient information. It would be inefficient to buffer up +an entire message before deciding if it needs to be filtered, and +it would be clumsy to filter mail and to buffer up all the actions +until it is known whether those actions need to be executed. </p> + +</ul> + +<li> <p> Despite warnings, some people try to use the built-in +filter feature for general junk email and/or virus blocking, using +hundreds or even thousands of regular expressions. This can result +in catastrophic performance failure. The symptoms are as follows: +</p> + +<ul> + +<li> <p> The cleanup(8) processes use up all available CPU time in +order to process the regular expressions, and/or they use up all +available memory so that the system begins to swap. This slows down +all incoming mail deliveries. </p> + +<li> <p> As Postfix needs more and more time to receive an email +message, the number of simultaneous SMTP sessions increases to the +point that the SMTP server process limit is reached. </p> + +<li> <p> While all SMTP server processes are waiting for the +cleanup(8) servers to finish, new SMTP clients have to wait until +an SMTP server process becomes available. This causes mail deliveries +to time out before they have even begun. </p> + +</ul> + +<p> The remedy for this type of performance problem is simple: +don't use header/body checks for general junk email and/or virus +blocking, and don't filter mail before it is queued. When performance +is a concern, use an external content filter that runs after mail +is queued, as described in the FILTER_README document. </p> + +</ul> + +<h2><a name="daily">Preventing daily mail status reports from being blocked </a></h2> + +<p>The following is quoted from Jim Seymour's Pflogsumm FAQ at +http://jimsun.linxnet.com/downloads/pflogsumm-faq.txt. Pflogsumm +is a program that analyzes Postfix logs, including the logging from +rejected mail. If these logs contain text that was rejected by +Postfix body_checks patterns, then the logging is also likely to +be rejected by those same body_checks patterns. This problem does +not exist with header_checks patterns, because those are not applied +to the text that is part of the mail status report. </p> + +<blockquote> + +<p>You configure Postfix to do body checks, Postfix does its thing, +Pflogsumm reports it and Postfix catches the same string in the +Pflogsumm report. There are several solutions to this. </p> + +<p> Wolfgang Zeikat contributed this: </p> + +<blockquote> +<pre> +#!/usr/bin/perl +use MIME::Lite; + +### Create a new message: +$msg = MIME::Lite->new( + From => 'your@send.er', + To => 'your@recipie.nt', + # Cc => 'some@other.com, some@more.com', + Subject => 'pflogsumm', + Date => `date`, + Type => 'text/plain', + Encoding => 'base64', + Path => '/tmp/pflogg', +); + +$msg->send; +</pre> +</blockquote> + +<p> Where "/tmp/pflogg" is the output of Pflogsumm. This puts Pflogsumm's +output in a base64 MIME attachment. </p> + +</blockquote> + +<p> Note by Wietse: if you run this on a machine that is accessible +by untrusted users, it is safer to store the Pflogsumm report in +a directory that is not world writable. </p> + +<blockquote> + +<p> In a follow-up to a thread in the postfix-users mailing list, Ralf +Hildebrandt noted: </p> + +<blockquote> <p> "mpack does the same thing." </p> </blockquote> + +</blockquote> + +<p> And it does. Which tool one should use is a matter of preference. +</p> + +<p> Other solutions involve additional body_checks rules that make +exceptions for daily mail status reports, but this is not recommended. +Such rules slow down all mail and complicate Postfix maintenance. +</p> + +<h2><a name="remote_only">Configuring header/body checks for mail from outside users only</a></h2> + +<p> The following information applies to Postfix 2.1 and later. +Earlier +Postfix versions do not support the receive_override_options feature. +</p> + +<p> The easiest approach is to configure ONE Postfix instance with +multiple SMTP server IP addresses in master.cf: </p> + +<ul> + +<li> <p> Two SMTP server IP addresses for mail from inside users +only, with header/body filtering turned off, and a local mail pickup +service with header/body filtering turned off. </p> + +<pre> +/etc/postfix.master.cf: + # ================================================================== + # service type private unpriv chroot wakeup maxproc command + # (yes) (yes) (yes) (never) (100) + # ================================================================== + 1.2.3.4:smtp inet n - n - - smtpd + -o receive_override_options=no_header_body_checks + 127.0.0.1:smtp inet n - n - - smtpd + -o receive_override_options=no_header_body_checks + pickup fifo n - n 60 1 pickup + -o receive_override_options=no_header_body_checks +</pre> + +<li> <p> Add some firewall rule to prevent access to 1.2.3.4:smtp +from the outside world. </p> + +<li> <p> One SMTP server address for mail from outside users with +header/body filtering turned on via main.cf. </p> + +<pre> +/etc/postfix.master.cf: + # ================================================================= + # service type private unpriv chroot wakeup maxproc command + # (yes) (yes) (yes) (never) (100) + # ================================================================= + 1.2.3.5:smtp inet n - n - - smtpd +</pre> + +</ul> + +<h2><a name="mx_submission">Configuring different header/body checks for MX service and submission service</a></h2> + +<p> If authorized user submissions require different header/body +checks than mail from remote MTAs, then this is possible as long +as you have separate mail streams for authorized users and for MX +service. </p> + +<p> The example below assumes that authorized users connect to TCP +port 587 (submission) or 465 (smtps), and that remote MTAs connect +to TCP port 25 (smtp). </p> + +<p> First, we define a few "user-defined" parameters that will +override settings for the submission and smtps services. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + msa_cleanup_service_name = msa_cleanup + msa_header_checks = pcre:/etc/postfix/msa_header_checks + msa_body_checks = pcre:/etc/postfix/msa_body_checks +</pre> +</blockquote> + +<p> Next, we define msa_cleanup as a dedicated cleanup service that +will be used only by the submission and smtps services. This service +uses the header_checks and body_checks overrides that were defined +above. </p> + +<blockquote> +<pre> +/etc/postfix.master.cf: + # ================================================================= + # service type private unpriv chroot wakeup maxproc command + # (yes) (yes) (yes) (never) (100) + # ================================================================= + smtp inet n - n - - smtpd + msa_cleanup unix n - n - 0 cleanup + -o header_checks=$msa_header_checks + -o body_checks=$msa_body_checks + submission inet n - n - - smtpd + -o cleanup_service_name=$msa_cleanup_service_name + -o syslog_name=postfix/submission + <i>...[see sample master.cf file for more]...</i> + smtps inet n - n - - smtpd + -o cleanup_service_name=$msa_cleanup_service_name + -o syslog_name=postfix/smtps + -o smtpd_tls_wrappermode=yes + <i>...[see sample master.cf file for more]...</i> +</pre> +</blockquote> + +<p> By keeping the "msa_xxx" parameter settings in main.cf, you +keep your master.cf file simple, and you minimize the amount +of duplication. </p> + +<h2><a name="domain_except">Configuring header/body checks for mail to some domains only</a></h2> + +<p> The following information applies to Postfix 2.1. Earlier +Postfix versions do not support the receive_override_options feature. +</p> + +<p> If you are an MX service provider and want to enable header/body +checks only for some domains, you can configure ONE Postfix +instance with multiple SMTP server IP addresses in master.cf. Each +address provides a different service. </p> + +<blockquote> + +<pre> +/etc/postfix.master.cf: + # ================================================================= + # service type private unpriv chroot wakeup maxproc command + # (yes) (yes) (yes) (never) (100) + # ================================================================= + # SMTP service for domains with header/body checks turned on. + 1.2.3.4:smtp inet n - n - - smtpd + + # SMTP service for domains with header/body checks turned off. + 1.2.3.5:smtp inet n - n - - smtpd + -o receive_override_options=no_header_body_checks +</pre> +</blockquote> + +<p> Once this is set up you can configure MX records in the DNS +that route each domain to the proper SMTP server instance. </p> + +</body> + +</html> diff --git a/proto/CDB_README.html b/proto/CDB_README.html new file mode 100644 index 0000000..3fd0973 --- /dev/null +++ b/proto/CDB_README.html @@ -0,0 +1,109 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix CDB Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix CDB Howto</h1> + +<hr> + +<h2>Introduction</h2> + +<p> CDB (Constant DataBase) is an indexed file format designed by +Daniel Bernstein. CDB is optimized exclusively for read access +and guarantees that each record will be read in at most two disk +accesses. This is achieved by forgoing support for incremental +updates: no single-record inserts or deletes are supported. CDB +databases can be modified only by rebuilding them completely from +scratch, hence the "constant" qualifier in the name. </p> + +<p> Postfix CDB databases are specified as "cdb:<i>name</i>", where +<i>name</i> specifies the CDB file name without the ".cdb" suffix +(another suffix, ".tmp", is used temporarily while a CDB file is +under construction). CDB databases are maintained with the postmap(1) +or postalias(1) command. The DATABASE_README document has general +information about Postfix databases. </p> + +<p> CDB support is available with Postfix 2.2 and later releases. +This document describes how to build Postfix with CDB support. </p> + +<h2>Building Postfix with CDB support</h2> + +<p> These instructions assume that you build Postfix from source +code as described in the INSTALL document. Some modification may +be required if you build Postfix from a vendor-specific source +package. </p> + +<p> Postfix is compatible with two CDB implementations: </p> + +<ul> + +<li> <p> The original cdb library from Daniel Bernstein, available +from http://cr.yp.to/cdb.html, and </p> + +<li> <p> tinycdb (version 0.5 and later) from Michael Tokarev, +available from http://www.corpit.ru/mjt/tinycdb.html. </p> + +</ul> + +<p> Tinycdb is preferred, since it is a bit faster, has additional +useful functionality and is much simpler to use. </p> + +<p>To build Postfix after you have installed tinycdb, use something +like: </p> + +<blockquote> +<pre> +% make tidy +% CDB=../../../tinycdb-0.5 +% make -f Makefile.init makefiles "CCARGS=-DHAS_CDB -I$CDB" \ + "AUXLIBS_CDB=$CDB/libcdb.a" +% make +</pre> +</blockquote> + +<p> Alternatively, for the D.J.B. version of CDB:<p> + +<blockquote> +<pre> +% make tidy +% CDB=../../../cdb-0.75 +% make -f Makefile.init makefiles "CCARGS=-DHAS_CDB -I$CDB" \ + "AUXLIBS_CDB=$CDB/cdb.a $CDB/alloc.a $CDB/buffer.a $CDB/unix.a $CDB/byte.a" +% make +</pre> +</blockquote> + +<p> Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_CDB. +With Postfix 3.0 and later, the old AUXLIBS variable still supports +building a statically-loaded CDB database client, but only the new +AUXLIBS_CDB variable supports building a dynamically-loaded or +statically-loaded CDB database client. </p> + +<blockquote> + +<p> Failure to use the AUXLIBS_CDB variable will defeat the purpose +of dynamic database client loading. Every Postfix executable file +will have CDB database library dependencies. And that was exactly +what dynamic database client loading was meant to avoid. </p> + +</blockquote> + +<p> After Postfix has been built with cdb support, you can use +"cdb" tables wherever you can use read-only "hash", "btree" or +"dbm" tables. However, the "<b>postmap -i</b>" (incremental record +insertion) and "<b>postmap -d</b>" (incremental record deletion) +command-line options are not available. For the same reason the +"cdb" map type cannot be used to store the persistent address +verification cache for the verify(8) service, or to store +TLS session information for the tlsmgr(8) service. </p> diff --git a/proto/COMPATIBILITY_README.html b/proto/COMPATIBILITY_README.html new file mode 100644 index 0000000..7020dbe --- /dev/null +++ b/proto/COMPATIBILITY_README.html @@ -0,0 +1,594 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Backwards-Compatibility Safety Net</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +Backwards-Compatibility Safety Net</h1> + +<hr> + +<h2>Purpose of this document </h2> + +<p> Postfix 3.0 introduces a safety net that runs Postfix programs +with backwards-compatible default settings after an upgrade. The +safety net will log a warning whenever a "new" default setting could +have an negative effect on your mail flow. </p> + +<p>This document provides information on the following topics: </p> + +<ul> + +<li> <p> <a href="#overview">Detailed descriptions</a> of Postfix +backwards-compatibility warnings. + +<li> <p> What backwards-compatible settings you may have to make +permanent in main.cf or master.cf. </p> + +<li> <p> <a href="#turnoff">How to turn off</a> Postfix +backwards-compatibility warnings. </p> + +</ul> + +<h2> <a name="overview"> Overview </a> </h2> + +<p> With backwards compatibility turned on, Postfix logs a message +whenever a backwards-compatible default setting may be required for +continuity of service. Based on this logging the system administrator +can decide if any backwards-compatible settings need to be made +permanent in main.cf or master.cf, before <a href="#turnoff">turning +off the backwards-compatibility safety net</a> as described at the +end of this document. </p> + +<p> Logged with compatibility_level < 1: </p> + +<ul> + +<li> <p> <a href="#append_dot_mydomain"> Using backwards-compatible +default setting append_dot_mydomain=yes </a> </p> + +<li> <p> <a href="#chroot"> Using backwards-compatible default setting +chroot=y</a> </p> + +</ul> + +<p> Logged with compatibility_level < 2: </p> + +<ul> + +<li><p> <a href="#relay_restrictions"> Using backwards-compatible +default setting "smtpd_relay_restrictions = (empty)"</a> </p> + +<li> <p> <a href="#mynetworks_style"> Using backwards-compatible +default setting mynetworks_style=subnet </a> </p> + +<li> <p> <a href="#relay_domains"> Using backwards-compatible default +setting relay_domains=$mydestination </a> </p> + +<li> <p> <a href="#smtputf8_enable"> Using backwards-compatible +default setting smtputf8_enable=no</a> </p> + +</ul> + +<p> Logged with compatibility_level < 3.6: </p> + +<ul> + +<li> <p> <a href="#smtpd_digest"> Using backwards-compatible +default setting smtpd_tls_fingerprint_digest=md5</a> </p> + +<li> <p> <a href="#smtp_digest"> Using backwards-compatible +default setting smtp_tls_fingerprint_digest=md5</a> </p> + +<li> <p> <a href="#smtp_digest"> Using backwards-compatible +default setting lmtp_tls_fingerprint_digest=md5</a> </p> + +<li> <p> <a href="#relay_before_rcpt"> Using backwards-compatible +default setting smtpd_relay_before_recipient_restrictions=no</a> </p> + +<li> <p> <a href="#respectful_logging"> Using backwards-compatible +default setting respectful_logging=no</a> </p> + +</ul> + +<p> If such a message is logged in the context of a legitimate +request, the system administrator should make the backwards-compatible +setting permanent in main.cf or master.cf, as detailed in the +sections that follow. </p> + +<p> When no more backwards-compatible settings need to be made +permanent, the system administrator should <a href="#turnoff">turn +off the backwards-compatibility safety net</a> as described at the +end of this document. </p> + +<h2> <a name="append_dot_mydomain"> Using backwards-compatible default +setting append_dot_mydomain=yes</a> </h2> + +<p> The append_dot_mydomain default value has changed from "yes" +to "no". This could result in unexpected non-delivery of email after +Postfix is updated from an older version. The backwards-compatibility +safety net is designed to prevent such surprises. </p> + +<p> As long as the append_dot_mydomain parameter is left at +its implicit default value, and the compatibility_level setting is +less than 1, Postfix may log one of the following messages:</p> + +<ul> + +<li> <p> Messages about missing "localhost" in mydestination or +other address class: </p> + +<blockquote> +<pre> +postfix/trivial-rewrite[14777]: using backwards-compatible + default setting append_dot_mydomain=yes to rewrite + "localhost" to "localhost.example.com"; please add + "localhost" to mydestination or other address class +</pre> +</blockquote> + +<p> If Postfix logs the above message, add "localhost" to +mydestination (or virtual_alias_domains, virtual_mailbox_domains, +or relay_domains) and execute the command "<b>postfix reload</b>". + +<li> <p> Messages about incomplete domains in email addresses: </p> + +<blockquote> +<pre> +postfix/trivial-rewrite[25835]: using backwards-compatible + default setting append_dot_mydomain=yes to rewrite "foo" to + "foo.example.com" +</pre> +</blockquote> + +<p> If Postfix logs the above message for domains different from +"localhost", and the sender cannot be changed to use complete domain +names in email addresses, then the system administrator should make +the backwards-compatible setting "append_dot_mydomain = yes" permanent +in main.cf: </p> + +<blockquote> +<pre> +# <b>postconf append_dot_mydomain=yes</b> +# <b>postfix reload</b> +</pre> +</blockquote> + +</ul> + +<h2> <a name="chroot"> Using backwards-compatible default +setting chroot=y</a> </h2> + +<p> The master.cf chroot default value has changed from "y" (yes) +to "n" (no). The new default avoids the need for copies of system +files under the Postfix queue directory. However, sites with strict +security requirements may want to keep the chroot feature enabled +after updating Postfix from an older version. The backwards-compatibility +safety net is designed allow the administrator to choose if they +want to keep the old behavior. </p> + +<p> As long as a master.cf chroot field is left at its +implicit default value, and the compatibility_level setting +is less than 1, Postfix may log the following message while it +reads the master.cf file: </p> + +<blockquote> +<pre> +postfix/master[27664]: /etc/postfix/master.cf: line 72: using + backwards-compatible default setting chroot=y +</pre> +</blockquote> + +<p> If this service should remain chrooted, then the system +administrator should make the backwards-compatible setting "chroot += y" permanent in master.cf. For example, to update the chroot +setting for the "smtp inet" service: </p> + +<blockquote> +<pre> +# <b>postconf -F smtp/inet/chroot=y</b> +# <b>postfix reload</b> +</pre> +</blockquote> + +<h2> <a name="relay_restrictions"> Using backwards-compatible default +setting smtpd_relay_restrictions = (empty)</a> </h2> + +<p> The smtpd_relay_restrictions feature was introduced with Postfix +version 2.10, as a safety mechanism for configuration errors in +smtpd_recipient_restrictions that could make Postfix an open relay. +</p> + +<p> The smtpd_relay_restrictions implicit default setting forbids +mail to remote destinations from clients that don't match +permit_mynetworks or permit_sasl_authenticated. This could result +in unexpected 'Relay access denied' errors after Postfix is updated +from an older Postfix version. The backwards-compatibility safety +net is designed to prevent such surprises. </p> + +<p> When the compatibility_level less than 1, and the +smtpd_relay_restrictions parameter is left at its implicit default +setting, Postfix may log the following message: </p> + +<blockquote> +<pre> +postfix/smtpd[38463]: using backwards-compatible default setting + "smtpd_relay_restrictions = (empty)" to avoid "Relay access + denied" error for recipient "user@example.com" from client + "host.example.net[10.0.0.2]" +</pre> +</blockquote> + +<p> If this request should not be blocked, then the system +administrator should make the backwards-compatible setting +"smtpd_relay_restrictions=" (i.e. empty) permanent in main.cf: + +<blockquote> +<pre> +# <b>postconf smtpd_relay_restrictions=</b> +# <b>postfix reload</b> +</pre> +</blockquote> + +<h2> <a name="mynetworks_style"> Using backwards-compatible default +setting mynetworks_style=subnet</a> </h2> + +<p> The mynetworks_style default value has changed from "subnet" +to "host". This parameter is used to implement the "permit_mynetworks" +feature. The change could cause unexpected 'access denied' errors after +Postfix is updated from an older version. The backwards-compatibility +safety net is designed to prevent such surprises. </p> + +<p> As long as the mynetworks and mynetworks_style parameters are +left at their implicit default values, and the compatibility_level +setting is less than 2, the Postfix SMTP server may log one of the +following messages: </p> + +<blockquote> +<pre> +postfix/smtpd[17375]: using backwards-compatible default setting + mynetworks_style=subnet to permit request from client + "foo.example.com[10.1.1.1]" +</pre> +</blockquote> + +<blockquote> +<pre> +postfix/postscreen[24982]: using backwards-compatible default + setting mynetworks_style=subnet to permit request from client + "10.1.1.1" +</pre> +</blockquote> + +<p> If the client request should not be rejected, then the system +administrator should make the backwards-compatible setting +"mynetworks_style = subnet" permanent in main.cf: </p> + +<blockquote> +<pre> +# <b>postconf mynetworks_style=subnet</b> +# <b>postfix reload</b> +</pre> +</blockquote> + +<h2><a name="relay_domains"> Using backwards-compatible default +setting relay_domains=$mydestination </a> </h2> + +<p> The relay_domains default value has changed from "$mydestination" +to the empty value. This could result in unexpected 'Relay access +denied' errors or ETRN errors after Postfix is updated from an older +version. The backwards-compatibility safety net is designed to +prevent such surprises. </p> + +<p> As long as the relay_domains parameter is left at its implicit +default value, and the compatibility_level setting is less than 2, +Postfix may log one of the following messages. </p> + +<ul> + +<li> <p> Messages about accepting mail for a remote domain:</p> + +<blockquote> +<pre> +postfix/smtpd[19052]: using backwards-compatible default setting + relay_domains=$mydestination to accept mail for domain + "foo.example.com" +</pre> +</blockquote> + +<blockquote> +<pre> +postfix/smtpd[19052]: using backwards-compatible default setting + relay_domains=$mydestination to accept mail for address + "user@foo.example.com" +</pre> +</blockquote> + +<li> <p> Messages about providing ETRN service for a remote domain:</p> + +<blockquote> +<pre> +postfix/smtpd[19138]: using backwards-compatible default setting + relay_domains=$mydestination to flush mail for domain + "bar.example.com" +</pre> +</blockquote> + +<blockquote> +<pre> +postfix/smtp[13945]: using backwards-compatible default setting + relay_domains=$mydestination to update fast-flush logfile for + domain "bar.example.com" +</pre> +</blockquote> + +</ul> + +<p> If Postfix should continue to accept mail for that domain or +continue to provide ETRN service for that domain, then the system +administrator should make the backwards-compatible setting +"relay_domains = $mydestination" permanent in main.cf: </p> + +<blockquote> +<pre> +# <b>postconf 'relay_domains=$mydestination'</b> +# <b>postfix reload</b> +</pre> +</blockquote> + +<p> Note: quotes are required as indicated above. </p> + +<p> Instead of $mydestination, it may be better to specify an +explicit list of domain names. </p> + +<h2> <a name="smtputf8_enable"> Using backwards-compatible default +setting smtputf8_enable=no</a> </h2> + +<p> The smtputf8_enable default value has changed from "no" to "yes". +With the new "yes" setting, the Postfix SMTP server rejects non-ASCII +addresses from clients that don't request SMTPUTF8 support, after +Postfix is updated from an older version. The backwards-compatibility +safety net is designed to prevent such surprises. </p> + +<p> As long as the smtputf8_enable parameter is left at its implicit +default value, and the compatibility_level setting is +less than 1, Postfix logs a warning each time an SMTP command uses a +non-ASCII address localpart without requesting SMTPUTF8 support: </p> + +<blockquote> +<pre> +postfix/smtpd[27560]: using backwards-compatible default setting + smtputf8_enable=no to accept non-ASCII sender address + "??@example.org" from localhost[127.0.0.1] +</pre> +</blockquote> + +<blockquote> +<pre> +postfix/smtpd[27560]: using backwards-compatible default setting + smtputf8_enable=no to accept non-ASCII recipient address + "??@example.com" from localhost[127.0.0.1] +</pre> +</blockquote> + +<p> If the address should not be rejected, and the client cannot +be updated to use SMTPUTF8, then the system administrator should +make the backwards-compatible setting "smtputf8_enable = no" permanent +in main.cf: + +<blockquote> +<pre> +# <b>postconf smtputf8_enable=no</b> +# <b>postfix reload</b> +</pre> +</blockquote> + +<h2> <a name="smtpd_digest"> Using backwards-compatible +default setting smtpd_tls_fingerprint_digest=md5</a> </h2> + +<p> The smtpd_tls_fingerprint_digest default value has changed from +"md5" to "sha256". With the new "sha256" setting, the Postfix SMTP +server avoids using the deprecated "md5" algorithm and computes a more +secure digest of the client certificate. </p> + +<p> If you're using the default "md5" setting, or even an explicit +"sha1" (also deprecated) setting, you should consider switching to +"sha256". This will require updating any associated lookup table keys +with the "sha256" digests of the expected client certificate or public +key. </p> + +<p> As long as the smtpd_tls_fingerprint_digest parameter is left at its +implicit default value, and the compatibility_level setting is less than +3.6, Postfix logs a warning each time a client certificate or public key +fingerprint is (potentially) used for access control: </p> + +<blockquote> +<pre> +postfix/smtpd[27560]: using backwards-compatible default setting + smtpd_tls_fingerprint_digest=md5 to compute certificate fingerprints +</pre> +</blockquote> + +<p> Since any client certificate fingerprints are passed in policy service +lookups, and Postfix doesn't know whether the fingerprint will be used, the +warning may also be logged when policy lookups are performed for connections +that used a client certificate, even if the policy service does not in fact +examine the client certificate. To reduce the noise somewhat, such warnings +are issued at most once per smtpd(8) process instance. </p> + +<p> If you prefer to stick with "md5", you can suppress the warnings by +making that setting explicit. After addressing any other compatibility +warnings, you can <a href="#turnoff">update</a> your compatibility level. +</p> + +<blockquote> +<pre> +# <b>postconf smtpd_tls_fingerprint_digest=md5</b> +# <b>postfix reload</b> +</pre> +</blockquote> + +<h2> <a name="smtp_digest"> Using backwards-compatible +default setting smtp_tls_fingerprint_digest=md5</a> </h2> + +<p> The smtp_tls_fingerprint_digest and lmtp_tls_fingerprint_digest +default values have changed from "md5" to "sha256". With the new +"sha256" setting, the Postfix SMTP and LMTP client avoids using the +deprecated "md5" algorithm and computes a more secure digest of the +server certificate. </p> + +<p> If you're using the default "md5" setting, or even an explicit +"sha1" (also deprecated) setting, you should consider switching to +"sha256". This will require updating any "fingerprint" security level +policies in the TLS policy table to specify matching "sha256" digests of +the expected server certificates or public keys. </p> + +<p> As long as the smtp_tls_fingerprint_digest (or LMTP equivalent) +parameter is left at its implicit default value, and the +compatibility_level setting is less than 3.6, Postfix logs a warning each +time the "fingerprint" security level is used to specify matching "md5" +digests of trusted server certificates or public keys: </p> + +<blockquote> +<pre> +postfix/smtp[27560]: using backwards-compatible default setting + smtp_tls_fingerprint_digest=md5 to compute certificate fingerprints +</pre> +</blockquote> + +<p> If you prefer to stick with "md5", you can suppress the warnings by +making that setting explicit. After addressing any other compatibility +warnings, you can <a href="#turnoff">update</a> your compatibility level. +</p> + +<blockquote> +<pre> +# <b>postconf 'smtp_tls_fingerprint_digest = md5' \ + 'lmtp_tls_fingerprint_digest = md5' </b> +# <b>postfix reload</b> +</pre> +</blockquote> + +<h2> <a name="relay_before_rcpt"> Using backwards-compatible +default setting smtpd_relay_before_recipient_restrictions=no</a> </h2> + +<p> The smtpd_relay_before_recipient_restrictions feature was +introduced in Postfix version 3.6, to evaluate smtpd_relay_restrictions +before smtpd_recipient_restrictions. Historically, smtpd_relay_restrictions +was evaluated after smtpd_recipient_restrictions, contradicting +documented behavior. </p> + +<blockquote> <p> Background: smtpd_relay_restrictions is +primarily designed to enforce a mail relaying policy, while +smtpd_recipient_restrictions is primarily designed to enforce spam +blocking policy. Both are evaluated while replying to the RCPT TO +command, and both support the same features. </p> </blockquote> + +<p> To maintain compatibility with earlier versions, Postfix will +keep evaluating smtpd_recipient_restrictions before +smtpd_relay_restrictions, as long as the compatibility_level is +less than 3.6, and the smtpd_relay_before_recipient_restrictions +parameter is left at its implicit default setting. As a reminder, +Postfix may log the following message: </p> + +<blockquote> +<pre> +postfix/smtpd[54696]: using backwards-compatible default setting + smtpd_relay_before_recipient_restrictions=no to reject recipient + "user@example.com" from client "host.example.net[10.0.0.2]" +</pre> +</blockquote> + +<p> If Postfix should keep evaluating smtpd_recipient_restrictions +before smtpd_relay_restrictions, then the system +administrator should make the backwards-compatible setting +"smtpd_relay_before_recipient_restrictions=no" permanent in main.cf: </p> + +<blockquote> +<pre> +# <b> postconf smtpd_relay_before_recipient_restrictions=no </b> +# <b> postfix reload </b> +</pre> +</blockquote> + +<h2> <a name="respectful_logging"> Using backwards-compatible +default setting respectful_logging=no</a> </h2> + +<p> Postfix version 3.6 deprecates configuration parameter names and +logging that suggest white is better than black. Instead it prefers +'allowlist, 'denylist', and variations of those words. While the renamed +configuration parameters have backwards-compatible default values, +the changes in logging could affect logfile analysis tools. </p> + +<p> To avoid breaking existing logfile analysis tools, Postfix will keep +logging the deprecated form, as long as the respectful_logging parameter +is left at its implicit default value, and the compatibility_level +setting is less than 3.6. As a reminder, Postfix may log the following +when a remote SMTP client is allowlisted or denylisted: </p> + +<blockquote> +<pre> +postfix/postscreen[22642]: Using backwards-compatible default setting + respectful_logging=no for client [<i>address</i>]:<i>port</i> +</pre> +</blockquote> + +<p> If Postfix should keep logging the deprecated form, then the +system administrator should make the backwards-compatible setting +"respectful_logging = no" permanent in main.cf. + +<blockquote> +<pre> +# <b>postconf "respectful_logging = no"</b> +# <b>postfix reload</b> +</pre> +</blockquote> + +<h2> <a name="turnoff">Turning off the backwards-compatibility safety net</a> </h2> + +<p> Backwards compatibility is turned off by updating the +compatibility_level setting in main.cf. </p> + +<blockquote> +<pre> +# <b>postconf compatibility_level=<i>N</i></b> +# <b>postfix reload</b> +</pre> +</blockquote> + +<p> For <i>N</i> specify the number that is logged in your postfix(1) +warning message: </p> + +<blockquote> +<pre> +warning: To disable backwards compatibility use "postconf compatibility_level=<i>N</i>" and "postfix reload" +</pre> +</blockquote> + +<p> Sites that don't care about backwards compatibility may set +"compatibility_level = 9999" at their own risk. </p> + +<p> Starting with Postfix version 3.6, the compatibility level in +the above warning message is the Postfix version that introduced +the last incompatible change. The level is formatted as +<i>major.minor.patch</i>, where <i>patch</i> is usually omitted and +defaults to zero. Earlier compatibility levels are 0, 1 and 2. </p> + +<p> NOTE: Postfix 3.6 also introduces support for the "<level", +"<=level", and other operators to compare compatibility levels. +With the standard operators "<", "<=", etc., compatibility +level "3.10" would be smaller than "3.9" which is undesirable. </p> + +</body> + +</html> diff --git a/proto/CONNECTION_CACHE_README.html b/proto/CONNECTION_CACHE_README.html new file mode 100644 index 0000000..bc2e34e --- /dev/null +++ b/proto/CONNECTION_CACHE_README.html @@ -0,0 +1,350 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Connection Cache </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Connection Cache </h1> + +<hr> + +<h2>Introduction</h2> + +<p> This document describes the Postfix connection cache implementation, +which is available with Postfix version 2.2 and later. </p> + +<p> Topics covered in this document: </p> + +<ul> + +<li><a href="#summary"> What SMTP connection caching can do for you</a> + +<li><a href="#implementation"> Connection cache implementation</a> + +<li><a href="#configuration"> Connection cache configuration</a> + +<li><a href="#safety">Connection cache safety mechanisms </a> + +<li><a href="#limitations">Connection cache limitations</a> + +<li><a href="#statistics">Connection cache statistics</a> + +</ul> + +<h2><a name="summary">What SMTP connection caching can do for +you</a></h2> + +<p> With SMTP connection caching, Postfix can deliver multiple +messages over the same SMTP connection. By default, Postfix 2.2 +reuses a plaintext SMTP connection automatically when a destination has +high volume of mail in the active queue. </p> + +<p> SMTP Connection caching is a performance feature. Whether or not +it actually improves performance depends on the conditions: </p> + +<ul> + +<li> <p> SMTP Connection caching can greatly improve performance +when delivering mail to a destination with multiple mail servers, +because it can help Postfix to skip over a non-responding server. +</p> + +<li> <p> SMTP Connection caching can also help with receivers that +impose rate limits on new connections. </p> + +<li> <p> Otherwise, the benefits of SMTP connection caching are +minor: it eliminates the latency of the TCP handshake (SYN, SYN+ACK, +ACK), plus the latency of the SMTP initial handshake (220 greeting, +EHLO command, EHLO response). With TLS-encrypted connections, this +can save an additional two roundtrips that would otherwise be needed +to send STARTTLS and to resume a TLS session. </p> + +<li> <p> SMTP Connection caching gives no gains with respect to +SMTP session tear-down. The Postfix smtp(8) client normally does +not wait for the server's reply to the QUIT command, and it never +waits for the TCP final handshake to complete. </p> + +<li> <p> SMTP Connection caching introduces some overhead: the +client needs to send an RSET command to find out if a connection +is still usable, before it can send the next MAIL FROM command. +This introduces one additional round-trip delay. </p> + +</ul> + +<p> For other potential issues with SMTP connection caching, see +the discussion of <a href="#limitations">limitations</a> at the end +of this document. </p> + +<h2><a name="implementation">Connection cache implementation</a></h2> + +<p> For an overview of how Postfix delivers mail, see the Postfix +architecture OVERVIEW document. </p> + +<p> The Postfix connection cache is shared among Postfix mail +delivering processes. This maximizes the opportunity to reuse an +open connection. Some MTAs such as Sendmail have a +non-shared connection cache. Here, a connection can be reused only +by the mail delivering process that creates the connection. To get +the same performance improvement as with a shared connection cache, +non-shared connections need to be kept open for a longer time. </p> + +<p> The scache(8) server, introduced with Postfix version 2.2, +maintains the shared connection cache. With Postfix version 2.2, +only the smtp(8) client has support to access this cache. </p> + +<p> When SMTP connection caching is enabled (see next section), the +smtp(8) client does not disconnect after a mail transaction, but +gives the connection to the scache(8) server which keeps the +connection open for a limited amount of time. </p> + +<p> After handing over the open connection to the scache(8) server, +the smtp(8) client continues with some other mail delivery request. +Meanwhile, any smtp(8) client process can ask the scache(8) server +for that cached connection and reuse it for mail delivery. </p> + +<blockquote> + +<table> + +<tr> <td> </td> <td> <tt> /-- </tt> </td> <td align="center" +colspan="3" bgcolor="#f0f0ff"> smtp(8) </td> <td colspan="2"> <tt> +--> </tt> </td> <td> Internet </td> </tr> + +<tr> <td align="center" bgcolor="#f0f0ff"> qmgr(8) </td> <td> </td> +<td align="center" rowspan="3"><tt>|<br>|<br>|<br>|<br>v</tt></td> +</tr> + +<tr> <td> </td> <td> <tt> \-- </tt> </td> <td align="center" +colspan="4" bgcolor="#f0f0ff"> smtp(8) </td> <td align="left"> + </td> </tr> + +<tr> <td colspan="2"> </td> <td> </td> <td +align="center"><tt>^<br>|</tt></td> </tr> + +<tr> <td colspan="2"> </td> <td align="center" colspan="3" +bgcolor="#f0f0ff"> scache(8) </td> </tr> + +</table> + +</blockquote> + +<p> With TLS connection reuse (Postfix 3.4 and later), the Postfix +smtp(8) client connects to a remote SMTP server and sends plaintext +EHLO and STARTTLS commands, then inserts a tlsproxy(8) process into +the connection as shown below. </p> + +<p> After delivering mail, the smtp(8) client hands over the open +smtp(8)-to-tlsproxy(8) connection to the scache(8) server, and +continues with some other mail delivery request. Meanwhile, any +smtp(8) client process can ask the scache(8) server for that cached +connection and reuse it for mail delivery. </p> + +<blockquote> + +<table> + +<tr> <td> </td> <td> <tt> /-- </tt> </td> <td align="center" +colspan="3" bgcolor="#f0f0ff"> smtp(8) </td> <td colspan="2"> <tt> +--> </tt> </td> <td align="center"bgcolor="#f0f0ff"> tlsproxy(8) +</td> <td> <tt> --> </tt> </td> <td> Internet </td> </tr> + +<tr> <td align="center" bgcolor="#f0f0ff"> qmgr(8) </td> <td> </td> +<td align="center" rowspan="3"><tt>|<br>|<br>|<br>|<br>v</tt></td> +</tr> + +<tr> <td> </td> <td> <tt> \-- </tt> </td> <td align="center" +colspan="4" bgcolor="#f0f0ff"> smtp(8) </td> <td align="left"> + </td> </tr> + +<tr> <td colspan="2"> </td> <td> </td> <td +align="center"><tt>^<br>|</tt></td> </tr> + +<tr> <td colspan="2"> </td> <td align="center" colspan="3" +bgcolor="#f0f0ff"> scache(8) </td> </tr> + +</table> + +</blockquote> + +<p> The connection cache can be searched by destination domain name +(the right-hand side of the recipient address) and by the IP address +of the host at the other end of the connection. This allows Postfix +to reuse a connection even when the remote host is a mail server for +domains with different names. </p> + +<h2><a name="configuration">Connection cache configuration </a></h2> + +<p> The Postfix smtp(8) client supports two connection caching +strategies: </p> + +<ul> + +<li> <p> On-demand connection caching. This is enabled by default, +and is controlled with the smtp_connection_cache_on_demand configuration +parameter. When this feature is enabled, the Postfix smtp(8) client +automatically saves a connection to the connection cache when a +destination has a high volume of mail in the active queue. </p> + +<p> Example: </p> + +<blockquote> + +<pre> +/etc/postfix/main.cf: + smtp_connection_cache_on_demand = yes +</pre> + +</blockquote> + +<li> <p> Per-destination connection caching. This is enabled by +explicitly listing specific destinations with the +smtp_connection_cache_destinations configuration parameter. After +completing delivery to a selected destination, the Postfix smtp(8) +client <i>always</i> saves the connection to the connection cache. +</p> + +<p> Specify a comma or white space separated list of destinations +or pseudo-destinations: </p> + +<ul> + +<li> <p> if mail is sent without a relay host: a domain name (the +right-hand side of an email address, without the [] around a numeric +IP address), </p> + +<li> <p> if mail is sent via a relay host: a relay host name (without +the [] or non-default TCP port), as specified in main.cf or in the +transport map, </p> + +<li> <p> a /file/name with domain names and/or relay host names as +defined above, </p> + +<li> <p> a "type:table" with domain names and/or relay host names +on the left-hand side. The right-hand side result from "type:table" +lookups is ignored. </p> + +</ul> + +<p> Examples: </p> + +<blockquote> + +<pre> +/etc/postfix/main.cf: + smtp_connection_cache_destinations = $relayhost + smtp_connection_cache_destinations = hotmail.com, ... + smtp_connection_cache_destinations = static:all (<i>not recommended</i>) +</pre> + +</blockquote> + +<p> See <a href="TLS_README.html#client_tls_reuse">Client-side TLS +connection reuse</a> to enable multiple deliveries over a TLS-encrypted +connection (Postfix version 3.4 and later). </p> + +</ul> + +<h2><a name="safety">Connection cache safety mechanisms </a></h2> + +<p> Connection caching must be used wisely. It is anti-social to +keep an unused SMTP connection open for a significant amount of +time, and it is unwise to send huge numbers of messages through +the same connection. In order to avoid problems with SMTP connection +caching, Postfix implements the following safety mechanisms: </p> + +<ul> + +<li> <p> The Postfix scache(8) server keeps a connection open for +only a limited time. The time limit is specified with the +smtp_connection_cache_time_limit and with the connection_cache_ttl_limit +configuration parameters. This prevents anti-social behavior. </p> + +<li> <p> The Postfix smtp(8) client reuses a session for only a +limited number of times. This avoids triggering bugs in implementations +that do not correctly handle multiple deliveries per session. </p> + +<p> As of Postfix 2.3 connection reuse is preferably limited with +the smtp_connection_reuse_time_limit parameter. In addition, Postfix +2.11 provides smtp_connection_reuse_count_limit to limit how many +times a connection may be reused, but this feature is unsafe as it +introduces a "fatal attractor" failure mode (when a destination has +multiple inbound MTAs, the slowest inbound MTA will attract most +connections from Postfix to that destination). </p> + +<p> Postfix 2.3 logs the use count of multiply-used connections, +as shown in the following example: </p> + +<blockquote> +<pre> +Nov 3 16:04:31 myname postfix/smtp[30840]: 19B6B2900FE: +to=<wietse@test.example.com>, orig_to=<wietse@test>, +relay=mail.example.com[1.2.3.4], <b>conn_use=2</b>, delay=0.22, +delays=0.04/0.01/0.05/0.1, dsn=2.0.0, status=sent (250 2.0.0 Ok) +</pre> +</blockquote> + +<li> <p> The connection cache explicitly labels each cached connection +with destination domain and IP address information. A connection +cache lookup succeeds only when the correct information is specified. +This prevents mis-delivery of mail. </p> + +</ul> + +<h2><a name="limitations">Connection cache limitations</a></h2> + +<p> Postfix SMTP connection caching conflicts with certain applications: +</p> + +<ul> + +<li> <p> With Postfix versions < 3.4, the Postfix shared connection +cache cannot be used with TLS, because an open TLS connection can +be reused only in the process that creates it. For this reason, +the Postfix smtp(8) client historically always closed the connection +after completing an attempt to deliver mail over TLS.</p> + +<li> <p> Postfix connection caching currently does not support +multiple SASL accounts per mail server. Specifically, Postfix +connection caching assumes that a SASL credential is valid for all +hostnames or domain names that deliver via the same mail server IP +address and TCP port, and assumes that the SASL credential does not +depend on the message originator. </p> + +</ul> + + +<h2><a name="statistics">Connection cache statistics </a></h2> + +<p> The scache(8) connection cache server logs statistics about the +peak cache size and the cache hit rates. This information is logged +every connection_cache_status_update_time seconds, when the process +terminates after the maximal idle time is exceeded, or when Postfix +is reloaded. </p> + +<ul> + +<li> <p> Hit rates for connection cache lookups by domain will tell +you how useful connection caching is. </p> + +<li> <p> Connection cache lookups by network address will always +fail, unless you're sending mail to different domains that share +the same MX hosts. </p> + +<li> <p> No statistics are logged when no attempts are made to +access the connection cache. </p> + +</ul> + + +</body> + +</html> diff --git a/proto/CONTENT_INSPECTION_README.html b/proto/CONTENT_INSPECTION_README.html new file mode 100644 index 0000000..57d4836 --- /dev/null +++ b/proto/CONTENT_INSPECTION_README.html @@ -0,0 +1,92 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Content Inspection </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +Content Inspection </h1> + +<hr> + +<p> Postfix supports three content inspection methods, ranging from +light-weight one-line-at-a-time scanning before mail is queued, to +heavy duty machinery that does sophisticated content analysis after +mail is queued. Each approach serves a different purpose. </p> + +<dl> + +<dt> <b> before queue, built-in, light-weight</b> </dt> + +<dd> <p> This method inspects mail BEFORE it is stored in the queue, +and uses Postfix's built-in message header and message body +inspection. Although the main purpose is to stop a specific flood +of mail from worms or viruses, it is also useful to block a flood +of bounced junk email and email notifications from virus detection +systems. The built-in regular expressions are not meant to implement +general SPAM and virus detection. For that, you should use one of +the content inspection methods described below. Details are described +in the BUILTIN_FILTER_README and BACKSCATTER_README documents. +</p> + +<dt> <b> after queue, external, heavy-weight</b> </dt> + +<dd> <p> This method inspects mail AFTER it is stored in the queue, +and uses standard protocols such as SMTP or "pipe to command and +wait for exit status". After-queue inspection allows you to use +content filters of arbitrary complexity without causing timeouts +while receiving mail, and without running out of memory resources +under a peak load. Details of this approach are in the FILTER_README +document. </p> + +<dt> <b> before queue, external, medium-weight</b> </dt> + +<dd> <p> The following two methods inspect mail BEFORE it is stored in the +queue. </p> + +<ul> + +<li> <p> The first method uses the SMTP protocol, and is described +in the SMTPD_PROXY_README document. This approach is available +with Postfix version 2.1 and later. </p> + +<li> <p> The second method uses the Sendmail 8 Milter protocol, and +is described in the MILTER_README document. This approach is +available with Postfix version 2.3 and later. </p> + +</ul> + +<p> Although these approaches appear to be attractive, they have +some serious limitations that you need to be aware of. First, +content inspection software must finish in a limited amount of time; +if content inspection needs too much time then incoming mail +deliveries will time out. Second, content inspection software must +run in a limited amount of memory; if content inspection needs too +much memory then software will crash under a peak load. Before-queue +inspection limits the peak load that your system can handle, and +limits the sophistication of the content filter that you can use. +</p> + +</dl> + +<p> The more sophisticated content filtering software is not built +into Postfix for good reasons: writing an MTA requires different +skills than writing a SPAM or virus killer. Postfix encourages the +use of external filters and standard protocols because this allows +you to choose the best MTA and the best content inspection software +for your purpose. Information about external content inspection +software can be found on the Postfix website at http://www.postfix.org/, +and on the postfix-users@postfix.org mailing list. </p> + +</body> + +</html> diff --git a/proto/DATABASE_README.html b/proto/DATABASE_README.html new file mode 100644 index 0000000..1db3372 --- /dev/null +++ b/proto/DATABASE_README.html @@ -0,0 +1,497 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Lookup Table Overview</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +Lookup Table Overview</h1> + +<hr> + +<h2>Overview </h2> + +This document covers the following topics: + +<ul> + +<li><a href="#intro">The Postfix lookup table model</a> + +<li><a href="#lists">Postfix lists versus tables </a> + +<li><a href="#preparing">Preparing Postfix for LDAP or SQL lookups</a> + +<li><a href="#detect">Maintaining Postfix lookup table files</a> + +<li><a href="#safe_db">Updating Berkeley DB files safely</a> + +<li><a href="#types">Postfix lookup table types</a> + +</ul> + +<h2><a name="intro">The Postfix lookup table model</a></h2> + +<p> Postfix uses lookup tables to store and look up information +for access control, address rewriting and even for content filtering. +All Postfix lookup tables are specified as "type:table", where +"type" is one of the database types described under "<a +href="#types">Postfix lookup table types</a>" at the end of this +document, and where "table" is the lookup table name. The Postfix +documentation uses the terms "database" and "lookup table" for the +same thing. </p> + +<p> Examples of lookup tables that appear often in the Postfix +documentation: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + alias_maps = hash:/etc/postfix/aliases (local aliasing) + header_checks = regexp:/etc/postfix/header_checks (content filtering) + transport_maps = hash:/etc/postfix/transport (routing table) + virtual_alias_maps = hash:/etc/postfix/virtual (address rewriting) +</pre> +</blockquote> + +<p> All Postfix lookup tables store information as (key, value) +pairs. This interface may seem simplistic at first, but it turns +out to be very powerful. The (key, value) query interface completely +hides the complexities of LDAP or SQL from Postfix. This is a good +example of connecting complex systems with simple interfaces. </p> + +<p> Benefits of the Postfix (key, value) query interface:</p> + +<ul> + +<li> You can implement Postfix lookup tables first with local +Berkeley DB files and then switch to LDAP or MySQL without any +impact on the Postfix configuration itself, as described under "<a +href="#preparing">Preparing Postfix for LDAP or SQL lookups</a>" +below. + +<li> You can use Berkeley DB files with fixed lookup strings for +simple address rewriting operations and you can use regular expression +tables for the more complicated work. In other words, you don't +have to put everything into the same table. + +</ul> + +<h2><a name="lists">Postfix lists versus tables </a></h2> + +<p> Most Postfix lookup tables are used to look up information. +Examples are address rewriting (the lookup string is the old address, +and the result is the new address) or access control (the lookup +string is the client, sender or recipient, and the result is an +action such as "reject"). </p> + +<p> With some tables, however, Postfix needs to know only if the +lookup key exists. Any non-empty lookup result value may be used +here: the lookup result is not used. Examples +are the local_recipient_maps that determine what local recipients +Postfix accepts in mail from the network, the mydestination parameter +that specifies what domains Postfix delivers locally for, or the +mynetworks parameter that specifies the IP addresses of trusted +clients or client networks. Technically, these are lists, not +tables. Despite the difference, Postfix lists are described here +because they use the same underlying infrastructure as Postfix +lookup tables. </p> + +<h2><a name="preparing">Preparing Postfix for LDAP or SQL lookups</a> +</h2> + +<p> LDAP and SQL are complex systems. Trying to set up both Postfix +and LDAP or SQL at the same time is definitely not a good idea. +You can save yourself a lot of time by implementing Postfix first +with local files such as Berkeley DB. Local files have few surprises, +and are easy to debug with the postmap(1) command: </p> + +<blockquote> +<pre> +% <b>postmap -q info@example.com hash:/etc/postfix/virtual </b> +</pre> +</blockquote> + +<p> Once you have local files working properly you can follow the +instructions in ldap_table(5), mysql_table(5), pgsql_table(5) +or sqlite_table(5) +and replace local file lookups with LDAP or SQL lookups. When you +do this, you should use the postmap(1) command again, to verify +that database lookups still produce the exact same results as local +file lookup: </p> + +<blockquote> +<pre> +% <b>postmap -q info@example.com ldap:/etc/postfix/virtual.cf </b> +</pre> +</blockquote> + +<p> Be sure to exercise all the partial address or parent domain +queries that are documented under "table search order" in the +relevant manual page: access(5), canonical(5), virtual(5), +transport(5), or under the relevant configuration parameter: +mynetworks, relay_domains, parent_domain_matches_subdomains. </p> + +<h2><a name="detect">Maintaining Postfix lookup table files</a></h2> + +<p> When you make changes to a database while the mail system is +running, it would be desirable if Postfix avoids reading information +while that information is being changed. It would also be nice if +you can change a database without having to execute "postfix reload", +in order to force Postfix to use the new information. Each time +you do "postfix reload" Postfix loses a lot of performance. +</p> + +<ul> + +<li> <p> If you change a network database such as LDAP, NIS or +SQL, there is no need to execute "postfix reload". The LDAP, NIS +or SQL server takes care of read/write access conflicts and gives +the new data to Postfix once that data is available. </p> + +<li> <p> If you change a regexp:, pcre:, cidr: or texthash: file +then Postfix +may not pick up the file changes immediately. This is because a +Postfix process reads the entire file into memory once and never +examines the file again. </p> + +<ul> + +<li> <p> If the file is used by a short-running process such as +smtpd(8), cleanup(8) or local(8), there is no need to execute +"postfix reload" after making a change. </p> + +<li> <p> If the file is being used by a long-running process such +as trivial-rewrite(8) on a busy server it may be necessary to +execute "postfix reload". </p> + +</ul> + +<li> <p> If you change a local file based database such as DBM or +Berkeley DB, there is no need to execute "postfix reload". Postfix +uses file locking to avoid read/write access conflicts, and whenever +a Postfix daemon process notices that a file has changed it will +terminate before handling the next client request, so that a new +process can initialize with the new database. </p> + +</ul> + +<h2><a name="safe_db">Updating Berkeley DB files safely</a></h2> + +<p> Postfix uses file locking to avoid access conflicts while +updating Berkeley DB or other local database files. This used to +be safe, but as Berkeley DB has evolved to use more aggressive +caching, file locking may no longer be sufficient. </p> + +<p> Furthermore, file locking would not prevent problems when the +update fails because the disk is full or something else causes a +database update to fail. In particular, commands such as postmap(1) +or postalias(1) overwrite existing files. If the overwrite +fails in the middle then you have no usable database, and Postfix +will stop working. This is not an issue with the CDB database type +available with Postfix 2.2 and later: <a href="CDB_README.html">CDB</a> +creates a new file, and renames the file upon successful completion. +</p> + +<p> With Berkeley DB and other "one file" databases, it is +possible to add some extra robustness by using "mv" to REPLACE an +existing database file instead of overwriting it: </p> + +<blockquote> +<pre> +# <b>postmap access.in && mv access.in.db access.db</b> +</pre> +</blockquote> + +<p> This converts the input file "access.in" into the output file +"access.in.db", and replaces the file "access.db" only when the +postmap(1) command was successful. Of course typing such commands +becomes boring quickly, and this is why people use "make" instead, +as shown below. User input is shown in bold font. </p> + +<blockquote> +<pre> +# <b>cat Makefile</b> +all: aliases.db access.db virtual.db ...etcetera... + +# Note 1: commands are specified after a TAB character. +# Note 2: use postalias(1) for local aliases, postmap(1) for the rest. +aliases.db: aliases.in + postalias aliases.in + mv aliases.in.db aliases.db + +access.db: access.in + postmap access.in + mv access.in.db access.db + +virtual.db: virtual.in + postmap virtual.in + mv virtual.in.db virtual.db + +...etcetera... +# <b>vi access.in</b> +...editing session not shown... +# <b>make</b> +postmap access.in +mv access.in.db access.db +# +</pre> +</blockquote> + +<p> The "make" command updates only the files that have changed. +In case of error, the "make" command will stop and will not invoke +the "mv" command, so that Postfix will keep using the existing +database file as if nothing happened. </p> + +<h2><a name="types">Postfix lookup table types</a> </h2> + +<p> To find out what database types your Postfix system supports, +use the "<b>postconf -m</b>" command. Here is a list of database types +that are often supported: </p> + +<blockquote> + +<dl> + +<dt> <b>btree</b> </dt> + +<dd> A sorted, balanced tree structure. This is available only on +systems with support for Berkeley DB databases. Database files are +created with the postmap(1) or postalias(1) command. The lookup +table name as used in "btree:table" is the database file name +without the ".db" suffix. </dd> + +<dt> <b>cdb</b> </dt> + +<dd> A read-optimized structure with no support for incremental updates. +Database files are created with the postmap(1) or postalias(1) command. +The lookup table name as used in "cdb:table" is the database file name +without the ".cdb" suffix. This feature is available with Postfix 2.2 +and later. </dd> + +<dt> <b>cidr</b> </dt> + +<dd> A table that associates values with Classless Inter-Domain +Routing (CIDR) patterns. The table format is described in cidr_table(5). +</dd> + +<dt> <b>dbm</b> </dt> + +<dd> An indexed file type based on hashing. This is available only +on systems with support for DBM databases. Public database files +are created with the postmap(1) or postalias(1) command, and private +databases are maintained by Postfix daemons. The lookup table name +as used in "dbm:table" is the database file name without the ".dir" +or ".pag" suffix. </dd> + +<dt> <b>environ</b> </dt> + +<dd> The UNIX process environment array. The lookup key is the +variable name. The lookup table name in "environ:table" is ignored. +</dd> + +<dt> <b>fail</b> </dt> + +<dd> A table that reliably fails all requests. The lookup table +name is used for logging only. This table exists to simplify Postfix +error tests. </dd> + +<dt> <b>hash</b> </dt> + +<dd> An indexed file type based on hashing. This is available only +on systems with support for Berkeley DB databases. Public database +files are created with the postmap(1) or postalias(1) command, and +private databases are maintained by Postfix daemons. The database +name as used in "hash:table" is the database file name without the +".db" suffix. </dd> + +<dt> <b>inline</b> (read-only) </dt> + +<dd> A non-shared, in-memory lookup table. Example: "inline:{ +<i>key=value</i>, { <i>key = text with whitespace or comma</i> }}". +Key-value pairs are separated by whitespace or comma; with a key-value +pair inside "{}", whitespace is ignored after the opening "{", +around the "=" between key and value, and before the closing "}". +Inline tables eliminate the +need to create a database file for just a few fixed elements. See +also the static: map type. </dd> + +<dt> <b>internal</b> </dt> + +<dd> A non-shared, in-memory hash table. Its contents are lost when +a process terminates. </dd> + +<dt> <b>lmdb</b> </dt> + +<dd> OpenLDAP LMDB database. This is available only on systems +with support for LMDB databases. Public database files are created +with the postmap(1) or postalias(1) command, and private databases +are maintained by Postfix daemons. The database name as used in +"lmdb:table" is the database file name without the ".lmdb" suffix. +See lmdb_table(5) for details. </dd> + +<dt> <b>ldap</b> (read-only) </dt> + +<dd> LDAP database client. Configuration details are given in the +ldap_table(5). </dd> + +<dt> <b>memcache</b> </dt> + +<dd> Memcache database client. Configuration details are given in +memcache_table(5). </dd> + +<dt> <b>mysql</b> (read-only) </dt> + +<dd> MySQL database client. Configuration details are given in +mysql_table(5). </dd> + +<dt> <b>netinfo</b> (read-only) </dt> + +<dd> Netinfo database client. </dd> + +<dt> <b>nis</b> (read-only) </dt> + +<dd> NIS database client. </dd> + +<dt> <b>nisplus</b> (read-only) </dt> + +<dd> NIS+ database client. Configuration details are given in +nisplus_table(5). </dd> + +<dt> <b>pcre</b> (read-only) </dt> + +<dd> A lookup table based on Perl Compatible Regular Expressions. +The file format is described in pcre_table(5). The lookup table +name as used in "pcre:table" is the name of the regular expression +file. </dd> + +<dt> <b>pipemap</b> (read-only) </dt> + +<dd> A pipeline of lookup tables. Example: +"pipemap:{<i>type<sub>1</sub>:name<sub>1</sub>, ..., +type<sub>n</sub>:name<sub>n</sub></i>}". Each "pipemap:" query is +given to the first table. Each lookup result becomes the query for +the next table in the pipeline, and the last table produces the +final result. When any table lookup produces no result, the pipeline +produces no result. The first and last characters of the "pipemap:" +table name must be "{" and "}". Within these, individual maps are +separated with comma or whitespace. </dd> + +<dt> <b>pgsql</b> (read-only) </dt> + +<dd> PostgreSQL database client. Configuration details are given +in pgsql_table(5). </dd> + +<dt> <b>proxy</b> </dt> + +<dd> Postfix proxymap(8) client for shared access to Postfix +databases. The lookup table name syntax is "proxy:type:table". +</dd> + +<dt> <b>randmap</b> (read-only) </dt> + +<dd> An in-memory table that performs random selection. Example: +"randmap:{<i>result<sub>1</sub>. ..., result<sub>n</sub></i>}". +Each table query returns a random choice from the specified results. +The first and last characters of the "randmap:" table name must be +"{" and "}". Within these, individual maps are separated with comma +or whitespace. To give a specific result more weight, specify it +multiple times. </dd> + +<dt> <b>regexp</b> (read-only) </dt> + +<dd> A lookup table based on regular expressions. The file format +is described in regexp_table(5). The lookup table name as used in +"regexp:table" is the name of the regular expression file. </dd> + +<dt> <b>sdbm</b> </dt> + +<dd> An indexed file type based on hashing. This is available only +on systems with support for SDBM databases. Public database files +are created with the postmap(1) or postalias(1) command, and private +databases are maintained by Postfix daemons. The lookup table name +as used in "sdbm:table" is the database file name without the ".dir" +or ".pag" suffix. </dd> + +<dt> <b>socketmap</b> (read-only) </dt> + +<dd> Sendmail-style socketmap client. The name of the table is +either <b>inet</b>:<i>host</i>:<i>port</i>:<i>name</i> for a TCP/IP +server, or <b>unix</b>:<i>pathname</i>:<i>name</i> for a UNIX-domain +server. See socketmap_table(5) for details. </dd> + +<dt> <b>sqlite</b> (read-only) </dt> + +<dd> SQLite database. Configuration details are given in sqlite_table(5). +</dd> + +<dt> <b>static</b> (read-only) </dt> + +<dd> A table that always returns its name as the lookup result. +For example, "static:foobar" always returns the string "foobar" as +lookup result. Specify "static:{ <i>text with whitespace</i> }" +when the result contains whitespace; this form ignores whitespace +after the opening "{" and before the closing "}". See also the +inline: map type. </dd> + +<dt> <b>tcp</b> </dt> + +<dd> TCP/IP client. The protocol is described in tcp_table(5). The +lookup table name is "tcp:host:port" where "host" specifies a +symbolic hostname or a numeric IP address, and "port" specifies a +symbolic service name or a numeric port number. </dd> + +<dt> <b>texthash</b> (read-only) </dt> + +<dd> A table that produces similar results as hash: files, except +that you don't have to run the postmap(1) command before you can +use the file, and that texthash: does not detect changes after the +file is read. The lookup table name is "texthash:filename", where +the file name is taken literally; no suffix is appended. </dd> + +<dt> <b>unionmap</b> (read-only) </dt> + +<dd> A table that sends each query to multiple lookup tables and +that concatenates all found results, separated by comma. The table +name syntax is the same as for pipemap tables. </dd> + +<dt> <b>unix</b> (read-only) </dt> + +<dd> A limited view of the UNIX authentication database. The following +tables are implemented: + +<dl> + +<dt> <b>unix:passwd.byname</b> </dt> + +<dd>The table is the UNIX password database. The key is a login +name. The result is a password file entry in passwd(5) format. +</dd> + +<dt> <b>unix:group.byname</b> </dt> + +<dd> The table is the UNIX group database. The key is a group name. +The result is a group file entry in group(5) format. </dd> + +</dl> </dd> + +</dl> + +</blockquote> + +<p> Other lookup table types may be available depending on how +Postfix was built. With some Postfix distributions the list is +dynamically extensible as support for lookup tables is dynamically +linked into Postfix. </p> + +</body> + +</html> diff --git a/proto/DB_README.html b/proto/DB_README.html new file mode 100644 index 0000000..cca3e2b --- /dev/null +++ b/proto/DB_README.html @@ -0,0 +1,246 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Berkeley DB Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Berkeley DB Howto</h1> + +<hr> + +<h2>Introduction</h2> + +<p> Postfix uses databases of various kinds to store and look up +information. Postfix databases are specified as "type:name". +Berkeley DB implements the Postfix database type "hash" and +"btree". The name of a Postfix Berkeley DB database is the name +of the database file without the ".db" suffix. Berkeley DB databases +are maintained with the postmap(1) command. </p> + +<p> Note: Berkeley DB version 4 is not supported by Postfix versions +before 2.0. </p> + +<p> This document describes: </p> + +<ol> + +<li> <p> How to build Postfix <a href="#disable_db">without Berkeley +DB support</a> even if the system comes with Berkeley DB. </p> + +<li> <p> How to build Postfix on <a href="#no_db">systems that +normally have no Berkeley DB library</a>. </p> + +<li> <p> How to build Postfix on <a href="#bsd">BSD</a> or <a +href="#linux">Linux</a> systems with multiple Berkeley DB +versions. </p> + +<li> <p> How to <a href="#tweak">tweak</a> performance. </p> + +<li> <p> Missing <a href="#pthread">pthread</a> library trouble. </p> + +</ol> + +<h2><a name="disable_db">Building Postfix without Berkeley +DB support even if the system comes with Berkeley DB</a></h2> + +<p> Note: The following instructions apply to Postfix 2.9 and later. </p> + +<p> Postfix will normally enable Berkeley DB support if the system +is known to have it. To build Postfix without Berkeley DB support, +build the makefiles as follows: </p> + +<blockquote> +<pre> +% make makefiles CCARGS="-DNO_DB" +% make +</pre> +</blockquote> + +<p> This will disable support for "hash" and "btree" files. </p> + +<h2><a name="no_db">Building Postfix on systems that normally have +no Berkeley DB library</a></h2> + +<p> Some UNIXes ship without Berkeley DB support; for historical +reasons these use DBM files instead. A problem with DBM files is +that they can store only limited amounts of data. To build Postfix +with +Berkeley DB support you need to download and install the source +code from http://www.oracle.com/database/berkeley-db/. </p> + +<p> Warning: some Linux system libraries use Berkeley DB, as do +some third-party libraries such as SASL. If you compile Postfix +with a different Berkeley DB implementation, then every Postfix +program will dump core because either the system library, the SASL +library, or Postfix itself ends up using the wrong version. </p> + +<p>The more recent Berkeley DB versions have a compile-time switch, +"--with-uniquename", which renames the symbols so that multiple +versions of Berkeley DB can co-exist in the same application. +Although wasteful, this may be the only way to keep things from +falling apart. </p> + +<p> To build Postfix after you installed the Berkeley DB from +source code, use something like: </p> + +<blockquote> +<pre> +% make makefiles CCARGS="-DHAS_DB -I/usr/local/BerkeleyDB/include" \ + AUXLIBS="-L/usr/local/BerkeleyDB/lib -ldb" +% make +</pre> +</blockquote> + +<p> If your Berkeley DB shared library is in a directory that the RUN-TIME +linker does not know about, add a "-Wl,-R,/path/to/directory" option after +"-ldb". </p> + +<p> Solaris needs this: </p> + +<blockquote> +<pre> +% make makefiles CCARGS="-DHAS_DB -I/usr/local/BerkeleyDB/include" \ + AUXLIBS="-R/usr/local/BerkeleyDB/lib -L/usr/local/BerkeleyDB/lib -ldb" +% make +</pre> +</blockquote> + +<p> The exact pathnames depend on the Berkeley DB version, and on +how it was installed. </p> + +<p> Warning: the file format produced by Berkeley DB version 1 is +not compatible with that of versions 2 and 3 (versions 2 and 3 have +the same format). If you switch between DB versions, then you may +have to rebuild all your Postfix DB files. </p> + +<p> Warning: if you use Berkeley DB version 2 or later, do not +enable DB 1.85 compatibility mode. Doing so would break fcntl file +locking. </p> + +<p> Warning: if you use Perl to manipulate Postfix's Berkeley DB +files, then you need to use the same Berkeley DB version in Perl +as in Postfix. </p> + +<h2><a name="bsd">Building Postfix on BSD systems with multiple +Berkeley DB versions</a></h2> + +<p> Some BSD systems ship with multiple Berkeley DB implementations. +Normally, Postfix builds with the default DB version that ships +with the system. </p> + +<p> To build Postfix on BSD systems with a non-default DB version, +use a variant of the following commands: </p> + +<blockquote> +<pre> +% make makefiles CCARGS=-I/usr/include/db3 AUXLIBS=-ldb3 +% make +</pre> +</blockquote> + +<p> Warning: the file format produced by Berkeley DB version 1 is +not compatible with that of versions 2 and 3 (versions 2 and 3 have +the same format). If you switch between DB versions, then you may +have to rebuild all your Postfix DB files. </p> + +<p> Warning: if you use Berkeley DB version 2 or later, do not +enable DB 1.85 compatibility mode. Doing so would break fcntl file +locking. </p> + +<p> Warning: if you use Perl to manipulate Postfix's Berkeley DB +files, then you need to use the same Berkeley DB version in Perl +as in Postfix. </p> + +<h2><a name="linux">Building Postfix on Linux systems with multiple +Berkeley DB versions</a></h2> + +<p> Some Linux systems ship with multiple Berkeley DB implementations. +Normally, Postfix builds with the default DB version that ships +with the system. </p> + +<p> Warning: some Linux system libraries use Berkeley DB. If you +compile Postfix with a non-default Berkeley DB implementation, then +every Postfix program will dump core because either the system +library or Postfix itself ends up using the wrong version. </p> + +<p> On Linux, you need to edit the makedefs script in order to +specify a non-default DB library. The reason is that the location +of the default db.h include file changes randomly between vendors +and between versions, so that Postfix has to choose the file for +you. </p> + +<p> Warning: the file format produced by Berkeley DB version 1 is +not compatible with that of versions 2 and 3 (versions 2 and 3 have +the same format). If you switch between DB versions, then you may +have to rebuild all your Postfix DB files. </p> + +<p> Warning: if you use Berkeley DB version 2 or later, do not +enable DB 1.85 compatibility mode. Doing so would break fcntl file +locking. </p> + +<p> Warning: if you use Perl to manipulate Postfix's Berkeley DB +files, then you need to use the same Berkeley DB version in Perl +as in Postfix. </p> + +<h2><a name="tweak">Tweaking performance</a></h2> + +<p> Postfix provides two configuration parameters that control how +much buffering memory Berkeley DB will use. </p> + +<ul> + +<li> <p> berkeley_db_create_buffer_size (default: 16 MBytes per +table). This setting is used by the commands that maintain Berkeley +DB files: postalias(1) and postmap(1). For "hash" files, create +performance degrades rapidly unless the memory pool is O(file size). +For "btree" files, create performance is good with sorted input even +for small memory pools, but with random input degrades rapidly +unless the memory pool is O(file size). </p> + +<li> <p> berkeley_db_read_buffer_size (default: 128 kBytes per +table). This setting is used by all other Postfix programs. The +buffer size is adequate for reading. If the cache is smaller than +the table, random read performance is hardly cache size dependent, +except with btree tables, where the cache size must be large enough +to contain the entire path from the root node. Empirical evidence +shows that 64 kBytes may be sufficient. We double the size to play +safe, and to anticipate changes in implementation and bloat. </p> + +</ul> + +<h2><a name="pthread">Missing pthread library trouble</a></h2> + +<p> When building Postfix fails with: </p> + +<blockquote> +<pre> +undefined reference to `pthread_condattr_setpshared' +undefined reference to `pthread_mutexattr_destroy' +undefined reference to `pthread_mutexattr_init' +undefined reference to `pthread_mutex_trylock' +</pre> +</blockquote> + +<p> Add the "-lpthread" library to the "make makefiles" command. </p> + +<blockquote> +<pre> +% make makefiles .... AUXLIBS="... -lpthread" +</pre> +</blockquote> + +<p> More information is available at +http://www.oracle.com/database/berkeley-db/. </p> + +</body> + +</html> diff --git a/proto/DEBUG_README.html b/proto/DEBUG_README.html new file mode 100644 index 0000000..ea62cdc --- /dev/null +++ b/proto/DEBUG_README.html @@ -0,0 +1,597 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title> Postfix Debugging Howto </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Debugging Howto</h1> + +<hr> + +<h2>Purpose of this document</h2> + +<p> This document describes how to debug parts of the Postfix mail +system when things do not work according to expectation. The methods +vary from making Postfix log a lot of detail, to running some daemon +processes under control of a call tracer or debugger. </p> + +<p> The text assumes that the Postfix main.cf and master.cf +configuration files are stored in directory /etc/postfix. You can +use the command "<b>postconf config_directory</b>" to find out the +actual location of this directory on your machine. </p> + +<p> Listed in order of increasing invasiveness, the debugging +techniques are as follows: </p> + +<ul> + +<li><a href="#logging">Look for obvious signs of trouble</a> + +<li><a href="#trace_mail">Debugging Postfix from inside</a> + +<li><a href="#no_chroot">Try turning off chroot operation in +master.cf</a> + +<li><a href="#debug_peer">Verbose logging for specific SMTP +connections</a> + +<li><a href="#sniffer">Record the SMTP session with a network +sniffer</a> + +<li><a href="#verbose">Making Postfix daemon programs more verbose</a> + +<li><a href="#man_trace">Manually tracing a Postfix daemon process</a> + +<li><a href="#auto_trace">Automatically tracing a Postfix daemon +process</a> + +<li><a href="#ddd">Running daemon programs with the interactive +ddd debugger</a> + +<li><a href="#screen">Running daemon programs with the interactive +gdb debugger</a> + +<li><a href="#gdb">Running daemon programs under a non-interactive +debugger</a> + +<li><a href="#unreasonable">Unreasonable behavior</a> + +<li><a href="#mail">Reporting problems to postfix-users@postfix.org</a> + +</ul> + +<h2><a name="logging">Look for obvious signs of trouble</a></h2> + +<p> Postfix logs all failed and successful deliveries to a logfile. </p> + +<ul> + +<li> <p> When Postfix uses syslog logging (the default), the file +is usually called /var/log/maillog, /var/log/mail, or something +similar; the exact pathname is configured in a file called +/etc/syslog.conf, /etc/rsyslog.conf, or something similar. </p> + +<li> <p> When Postfix uses its own logging system (see MAILLOG_README), +the location of the logfile is configured with the Postfix maillog_file +parameter. </p> + +</ul> + +<p> When Postfix does not receive or deliver mail, the first order +of business is to look for errors that prevent Postfix from working +properly: </p> + +<blockquote> +<pre> +% <b>egrep '(warning|error|fatal|panic):' /some/log/file | more</b> +</pre> +</blockquote> + +<p> Note: the most important message is near the BEGINNING of the +output. Error messages that come later are less useful. </p> + +<p> The nature of each problem is indicated as follows: </p> + +<ul> + +<li> <p> "<b>panic</b>" indicates a problem in the software itself +that only a programmer can fix. Postfix cannot proceed until this +is fixed. </p> + +<li> <p> "<b>fatal</b>" is the result of missing files, incorrect +permissions, incorrect configuration file settings that you can +fix. Postfix cannot proceed until this is fixed. </p> + +<li> <p> "<b>error</b>" reports an error condition. For safety +reasons, a Postfix process will terminate when more than 13 of these +happen. </p> + +<li> <p> "<b>warning</b>" indicates a non-fatal error. These are +problems that you may not be able to fix (such as a broken DNS +server elsewhere on the network) but may also indicate local +configuration errors that could become a problem later. </p> + +</ul> + +<h2><a name="trace_mail">Debugging Postfix from inside</a> </h2> + +<p> Postfix version 2.1 and later can +produce mail delivery reports for debugging purposes. These reports +not only show sender/recipient addresses after address rewriting +and alias expansion or forwarding, they also show information about +delivery to mailbox, delivery to non-Postfix command, responses +from remote SMTP servers, and so on. +</p> + +<p> Postfix can produce two types of mail delivery reports for +debugging: </p> + +<ul> + +<li> <p> What-if: report what would happen, but do not actually +deliver mail. This mode of operation is requested with: </p> + +<pre> +% <b>/usr/sbin/sendmail -bv address...</b> +Mail Delivery Status Report will be mailed to <your login name>. +</pre> + +<li> <p> What happened: deliver mail and report successes and/or +failures, including replies from remote SMTP servers. This mode +of operation is requested with: </p> + +<pre> +% <b>/usr/sbin/sendmail -v address...</b> +Mail Delivery Status Report will be mailed to <your login name>. +</pre> + +</ul> + +<p> These reports contain information that is generated by Postfix +delivery agents. Since these run as daemon processes that cannot +interact with users directly, the result is sent as mail to the +sender of the test message. The format of these reports is practically +identical to that of ordinary non-delivery notifications. </p> + +<p> For a detailed example of a mail delivery status report, see +the <a href="ADDRESS_REWRITING_README.html#debugging"> debugging</a> +section at the end of the ADDRESS_REWRITING_README document. </p> + +<h2><a name="no_chroot">Try turning off chroot operation in master.cf</a></h2> + +<p> A common mistake is to turn on chroot operation in the master.cf +file without going through all the necessary steps to set up a +chroot environment. This causes Postfix daemon processes to fail +due to all kinds of missing files. </p> + +<p> The example below shows an SMTP server that is configured with +chroot turned off: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + # ============================================================= + # service type private unpriv <b>chroot</b> wakeup maxproc command + # (yes) (yes) <b>(yes)</b> (never) (100) + # ============================================================= + smtp inet n - <b>n</b> - - smtpd +</pre> +</blockquote> + +<p> Inspect master.cf for any processes that have chroot operation +not turned off. If you find any, save a copy of the master.cf file, +and edit the entries in question. After executing the command +"<b>postfix reload</b>", see if the problem has gone away. </p> + +<p> If turning off chrooted operation made the problem go away, +then congratulations. Leaving Postfix running in this way is +adequate for most sites. If you prefer chrooted operation, see +the Postfix <a href="BASIC_CONFIGURATION_README.html#chroot_setup"> +BASIC_CONFIGURATION_README</a> file for information about how to +prepare Postfix for chrooted operation. </p> + +<h2><a name="debug_peer">Verbose logging for specific SMTP +connections</a></h2> + +<p> In /etc/postfix/main.cf, list the remote site name or address +in the debug_peer_list parameter. For example, in order to make +the software log a lot of information to the syslog daemon for +connections from or to the loopback interface: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + debug_peer_list = 127.0.0.1 +</pre> +</blockquote> + +<p> You can specify one or more hosts, domains, addresses or +net/masks. To make the change effective immediately, execute the +command "<b>postfix reload</b>". </p> + +<h2><a name="sniffer">Record the SMTP session with a network sniffer</a></h2> + +<p> This example uses <b>tcpdump</b>. In order to record a conversation +you need to specify a large enough buffer with the "<b>-s</b>" +option or else you will miss some or all of the packet payload. +</p> + +<blockquote> +<pre> +# <b>tcpdump -w /file/name -s 0 host example.com and port 25</b> +</pre> +</blockquote> + +<p> Older tcpdump versions don't support "<b>-s 0</b>"; in that case, +use "<b>-s 2000</b>" instead. </p> + +<p> Run this for a while, stop with Ctrl-C when done. To view the +data use a binary viewer, <b>ethereal</b>, or good old <b>less</b>. +</p> + +<h2><a name="verbose">Making Postfix daemon programs more verbose</a></h2> + +<p> Append one or more "<b>-v</b>" options to selected daemon +definitions in /etc/postfix/master.cf and type "<b>postfix reload</b>". +This will cause a lot of activity to be logged to the syslog daemon. +For example, to make the Postfix SMTP server process more verbose: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + smtp inet n - n - - smtpd -v +</pre> +</blockquote> + +<p> To diagnose problems with address rewriting specify a "<b>-v</b>" +option for the cleanup(8) and/or trivial-rewrite(8) daemon, and to +diagnose problems with mail delivery specify a "<b>-v</b>" +option for the qmgr(8) or oqmgr(8) queue manager, or for the lmtp(8), +local(8), pipe(8), smtp(8), or virtual(8) delivery agent. </p> + +<h2><a name="man_trace">Manually tracing a Postfix daemon process</a></h2> + +<p> Many systems allow you to inspect a running process with a +system call tracer. For example: </p> + +<blockquote> +<pre> +# <b>trace -p process-id</b> (SunOS 4) +# <b>strace -p process-id</b> (Linux and many others) +# <b>truss -p process-id</b> (Solaris, FreeBSD) +# <b>ktrace -p process-id</b> (generic 4.4BSD) +</pre> +</blockquote> + +<p> Even more informative are traces of system library calls. +Examples: </p> + +<blockquote> +<pre> +# <b>ltrace -p process-id</b> (Linux, also ported to FreeBSD and BSD/OS) +# <b>sotruss -p process-id</b> (Solaris) +</pre> +</blockquote> + +<p> See your system documentation for details. </p> + +<p> Tracing a running process can give valuable information about +what a process is attempting to do. This is as much information as +you can get without running an interactive debugger program, as +described in a later section. </p> + +<h2><a name="auto_trace">Automatically tracing a Postfix daemon +process</a></h2> + +<p> Postfix can attach a call tracer whenever a daemon process +starts. Call tracers come in several kinds. </p> + +<ol> + +<li> <p> System call tracers such as <b>trace</b>, <b>truss</b>, +<b>strace</b>, or <b>ktrace</b>. These show the communication +between the process and the kernel. </p> + +<li> <p> Library call tracers such as <b>sotruss</b> and <b>ltrace</b>. +These show calls of library routines, and give a better idea of +what is going on within the process. </p> + +</ol> + +<p> Append a <b>-D</b> option to the suspect command in +/etc/postfix/master.cf, for example: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + smtp inet n - n - - smtpd -D +</pre> +</blockquote> + +<p> Edit the debugger_command definition in /etc/postfix/main.cf +so that it invokes the call tracer of your choice, for example: +</p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + debugger_command = + PATH=/bin:/usr/bin:/usr/local/bin; + (truss -p $process_id 2>&1 | logger -p mail.info) & sleep 5 +</pre> +</blockquote> + +<p> Type "<b>postfix reload</b>" and watch the logfile. </p> + +<h2><a name="ddd">Running daemon programs with the interactive +ddd debugger</a></h2> + +<p> If you have X Windows installed on the Postfix machine, then +an interactive debugger such as <b>ddd</b> can be convenient. +</p> + +<p> Edit the debugger_command definition in /etc/postfix/main.cf +so that it invokes <b>ddd</b>: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + debugger_command = + PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin + ddd $daemon_directory/$process_name $process_id & sleep 5 +</pre> +</blockquote> + +<p> Be sure that <b>gdb</b> is in the command search path, and +export <b>XAUTHORITY</b> so that X access control works, for example: +</p> + +<blockquote> +<pre> +% <b>setenv XAUTHORITY ~/.Xauthority</b> (csh syntax) +$ <b>export XAUTHORITY=$HOME/.Xauthority</b> (sh syntax) +</pre> +</blockquote> + +<p> Append a <b>-D</b> option to the suspect daemon definition in +/etc/postfix/master.cf, for example: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + smtp inet n - n - - smtpd -D +</pre> +</blockquote> + +<p> Stop and start the Postfix system. This is necessary so that +Postfix runs with the proper <b>XAUTHORITY</b> and <b>DISPLAY</b> +settings. </p> + +<p> Whenever the suspect daemon process is started, a debugger +window pops up and you can watch in detail what happens. </p> + +<h2><a name="screen">Running daemon programs with the interactive +gdb debugger</a></h2> + +<p> If you have the screen command installed on the Postfix machine, then +you can run an interactive debugger such as <b>gdb</b> as follows. </p> + +<p> Edit the debugger_command definition in /etc/postfix/main.cf +so that it runs <b>gdb</b> inside a detached <b>screen</b> session: +</p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + debugger_command = + PATH=/bin:/usr/bin:/sbin:/usr/sbin; export PATH; HOME=/root; + export HOME; screen -e^tt -dmS $process_name gdb + $daemon_directory/$process_name $process_id & sleep 2 +</pre> +</blockquote> + +<p> Be sure that <b>gdb</b> is in the command search path. </p> + +<p> Append a <b>-D</b> option to the suspect daemon definition in +/etc/postfix/master.cf, for example: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + smtp inet n - n - - smtpd -D +</pre> +</blockquote> + +<p> Execute the command "<b>postfix reload</b>" and wait until a +daemon process is started (you can see this in the maillog file). +</p> + +<p> Then attach to the screen, and debug away: </p> + +<blockquote> +<pre> +# HOME=/root screen -r +gdb) continue +gdb) where +</pre> +</blockquote> + +<h2><a name="gdb">Running daemon programs under a non-interactive +debugger</a></h2> + +<p> If you do not have X Windows installed on the Postfix machine, +or if you are not familiar with interactive debuggers, then you +can try to run <b>gdb</b> in non-interactive mode, and have it +print a stack trace when the process crashes. </p> + +<p> Edit the debugger_command definition in /etc/postfix/main.cf +so that it invokes the <b>gdb</b> debugger: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + debugger_command = + PATH=/bin:/usr/bin:/usr/local/bin; export PATH; (echo cont; echo + where; sleep 8640000) | gdb $daemon_directory/$process_name + $process_id 2>&1 + >$config_directory/$process_name.$process_id.log & sleep 5 +</pre> +</blockquote> + +<p> Append a <b>-D</b> option to the suspect daemon in +/etc/postfix/master.cf, for example: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + smtp inet n - n - - smtpd -D +</pre> +</blockquote> + +<p> Type "<b>postfix reload</b>" to make the configuration changes +effective. </p> + +<p> Whenever a suspect daemon process is started, an output file +is created, named after the daemon and process ID (for example, +smtpd.12345.log). When the process crashes, a stack trace (with +output from the "<b>where</b>" command) is written to its logfile. +</p> + +<h2><a name="unreasonable">Unreasonable behavior</a></h2> + +<p> Sometimes the behavior exhibited by Postfix just does not match the +source code. Why can a program deviate from the instructions given +by its author? There are two possibilities. </p> + +<ul> + +<li> <p> The compiler has erred. This rarely happens. </p> + +<li> <p> The hardware has erred. Does the machine have ECC memory? </p> + +</ul> + +<p> In both cases, the program being executed is not the program +that was supposed to be executed, so anything could happen. </p> + +<p> There is a third possibility: </p> + +<ul> + +<li> <p> Bugs in system software (kernel or libraries). </p> + +</ul> + +<p> Hardware-related failures usually do not reproduce in exactly +the same way after power cycling and rebooting the system. There's +little Postfix can do about bad hardware. Be sure to use hardware +that at the very least can detect memory errors. Otherwise, Postfix +will just be waiting to be hit by a bit error. Critical systems +deserve real hardware. </p> + +<p> When a compiler makes an error, the problem can be reproduced +whenever the resulting program is run. Compiler errors are most +likely to happen in the code optimizer. If a problem is reproducible +across power cycles and system reboots, it can be worthwhile to +rebuild Postfix with optimization disabled, and to see if optimization +makes a difference. </p> + +<p> In order to compile Postfix with optimizations turned off: </p> + +<blockquote> +<pre> +% <b>make tidy</b> +% <b>make makefiles OPT=</b> +</pre> +</blockquote> + +<p> This produces a set of Makefiles that do not request compiler +optimization. </p> + +<p> Once the makefiles are set up, build the software: </p> + +<blockquote> +<pre> +% <b>make</b> +% <b>su</b> +Password: +# <b>make install</b> +</pre> +</blockquote> + +<p> If the problem goes away, then it is time to ask your vendor +for help. </p> + +<h2><a name="mail">Reporting problems to postfix-users@postfix.org</a></h2> + +<p> The people who participate on postfix-users@postfix.org +are very helpful, especially if YOU provide them with sufficient +information. Remember, these volunteers are willing to help, but +their time is limited. </p> + +<p> When reporting a problem, be sure to include the following +information. </p> + +<ul> + +<li> <p> A summary of the problem. Please do not just send some +logging without explanation of what YOU believe is wrong. </p> + +<li> <p> Complete error messages. Please use cut-and-paste, or use +attachments, instead of reciting information from memory. +</p> + +<li> <p> Postfix logging. See the text at the top of the DEBUG_README +document to find out where logging is stored. Please do not frustrate +the helpers by word wrapping the logging. If the logging is more +than a few kbytes of text, consider posting an URL on a web or ftp +site. </p> + +<li> <p> Consider using a test email address so that you don't have +to reveal email addresses or passwords of innocent people. </p> + +<li> <p> If you can't use a test email address, please anonymize +email addresses and host names consistently. Replace each letter +by "A", each digit +by "D" so that the helpers can still recognize syntactical errors. +</p> + +<li> <p> Command output from:</p> + +<ul> + +<li> <p> "<b>postconf -n</b>". Please do not send your main.cf file, +or 1000+ lines of <b>postconf</b> command output. </p> + +<li> <p> "<b>postconf -Mf</b>" (Postfix 2.9 or later). </p> + +</ul> + +<li> <p> Better, provide output from the <b>postfinger</b> tool. +This can be found at https://github.com/ford--prefect/postfinger. </p> + +<li> <p> If the problem is SASL related, consider including the +output from the <b>saslfinger</b> tool. This can be found at +https://packages.debian.org/search?keywords=sasl2-bin. </p> + +<li> <p> If the problem is about too much mail in the queue, consider +including output from the <b>qshape</b> tool, as described in the +QSHAPE_README file. </p> + +<li> <p> If the problem is protocol related (connections time out, +or an SMTP server complains about syntax errors etc.) consider +recording a session with <b>tcpdump</b>, as described in the <a +href="#sniffer">DEBUG_README</a> document. </ul> + +</body> + +</html> diff --git a/proto/DSN_README.html b/proto/DSN_README.html new file mode 100644 index 0000000..f1ee0dc --- /dev/null +++ b/proto/DSN_README.html @@ -0,0 +1,156 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix DSN Support </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +DSN Support </h1> + +<hr> + +<h2>Introduction</h2> + +<p> Postfix version 2.3 introduces support for Delivery Status +Notifications as described in RFC 3464. This gives senders control +over successful and failed delivery notifications. </p> + +<p> Specifically, DSN support gives an email sender the ability to +specify: </p> + +<ul> + +<li> <p> What notifications are sent: success, failure, delay, or +none. Normally, Postfix informs the sender only when mail delivery +is delayed or when delivery fails. </p> + +<li> <p> What content is returned in case of failure: only the +message headers, or the full message. </p> + +<li> <p> An envelope ID that is returned as part of delivery status +notifications. This identifies the message <i>submission</i> +transaction, and must not be confused with the message ID, which +identifies the message <i>content</i>. </p> + +</ul> + +<p> The implementation of DSN support involves extra parameters to +the SMTP MAIL FROM and RCPT TO commands, as well as two Postfix +sendmail command line options that provide a sub-set of the functions +of the extra SMTP command parameters. </p> + +<p> This document has information on the following topics: </p> + +<ul> + +<li> <a href="#scope">Restricting the scope of "success" notifications</a> + +<li> <a href="#cli">Postfix sendmail command-line interface</a> + +<li> <a href="#compat">Postfix VERP support compatibility</a> + +</ul> + +<h2> <a name="scope">Restricting the scope of "success" notifications</a> </h2> + +<p> Just like reports of undeliverable mail, DSN reports of +<i>successful</i> delivery can give away more information about the +internal infrastructure than desirable. Unfortunately, disallowing +"success" notification requests requires disallowing other DSN +requests as well. The RFCs do not offer the option to negotiate +feature subsets. </p> + +<p> This is not as bad as it sounds. When you turn off DSN for +remote inbound mail, remote senders with DSN support will still be +informed that their mail reached your Postfix gateway successfully; +they just will not get successful delivery notices from your internal +systems. Remote senders lose very little: they can no longer specify +how Postfix should report delayed or failed delivery. </p> + +<p> Use the smtpd_discard_ehlo_keyword_address_maps feature if you +wish to allow DSN requests from trusted clients but not from random +strangers (see below for how to turn this off for all clients): +</p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_discard_ehlo_keyword_address_maps = + cidr:/etc/postfix/esmtp_access + +/etc/postfix/esmtp_access: + # Allow DSN requests from local subnet only + 192.168.0.0/28 silent-discard + 0.0.0.0/0 silent-discard, dsn + ::/0 silent-discard, dsn +</pre> +</blockquote> + +<p> If you want to disallow all use of DSN requests from the network, +use the smtpd_discard_ehlo_keywords feature: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_discard_ehlo_keywords = silent-discard, dsn +</pre> +</blockquote> + +<h2> <a name="cli">Postfix sendmail command-line interface</a> </h2> + +<p> Postfix has two Sendmail-compatible command-line options for +DSN support. </p> + +<ul> + +<li> <p> The first option specifies what notifications are sent +for mail that is submitted via the Postfix sendmail(1) command line: +</p> + +<blockquote> +<pre> +$ <b>sendmail -N success,delay,failure ...</b> (one or more of these) +$ <b>sendmail -N never ...</b> (or just this by itself) +</pre> +</blockquote> + +<p> The built-in default corresponds with "delay,failure". </p> + +<li> <p> The second option specifies an envelope ID which is reported +in delivery status notifications for mail that is submitted via the +Postfix sendmail(1) command line: </p> + +<blockquote> +<pre> +$ <b>sendmail -V <i>envelope-id</i> ...</b> +</pre> +</blockquote> + +<p> Note: this conflicts with VERP support in older Postfix versions, +as discussed in the next section. </p> + +</ul> + +<h2> <a name="compat">Postfix VERP support compatibility</a> </h2> + +<p> With Postfix versions before 2.3, the sendmail(1) command uses +the -V command-line option to request VERP-style delivery. In order +to request VERP style delivery with Postfix 2.3 and later, you must +specify -XV instead of -V. </p> + +<p> The Postfix 2.3 sendmail(1) command will recognize if you try +to use -V for VERP-style delivery. It will do the right thing and +will remind you of the new syntax. </p> + +</body> + +</html> diff --git a/proto/ETRN_README.html b/proto/ETRN_README.html new file mode 100644 index 0000000..e3e36a4 --- /dev/null +++ b/proto/ETRN_README.html @@ -0,0 +1,374 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix ETRN Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix ETRN Howto</h1> + +<hr> + +<h2>Purpose of the Postfix fast ETRN service</h2> + +<p> The SMTP ETRN command was designed for sites that have intermittent +Internet connectivity. With ETRN, a site can tell the mail server +of its provider to "Please deliver all my mail now". The SMTP server +searches the queue for mail to the customer, and delivers that mail +<b>by connecting to the customer's SMTP server</b>. The mail is +not delivered via the connection that was used for sending ETRN. +</p> + +<p> As of version 1.0, Postfix has a fast ETRN implementation that +does not require Postfix to examine every queue file. Instead, +Postfix maintains a record of what queue files contain mail for +destinations that are configured for ETRN service. ETRN service +is no longer available for domains that aren't configured for the +service. </p> + +<p> This document provides information on the following topics: </p> + +<ul> + +<li><a href="#using">Using the Postfix fast ETRN service</a> + +<li><a href="#how">How Postfix fast ETRN works</a> + +<li><a href="#dirty_secret">Postfix fast ETRN service limitations</a> + +<li><a href="#config">Configuring the Postfix fast ETRN service</a> + +<li><a href="#only">Configuring a domain for ETRN service only</a> + +<li><a href="#testing">Testing the Postfix fast ETRN service</a> + +</ul> + +<p> Other documents with information on this subject: </p> + +<ul> + +<li> flush(8), flush service implementation + +</ul> + +<h2><a name="using">Using the Postfix fast ETRN service</a> </h2> + +<p> The following is an example SMTP session that shows how an SMTP +client requests the ETRN service. Client commands are shown in bold +font. </p> + +<blockquote> +<pre> +220 my.server.tld ESMTP Postfix +<b>HELO my.client.tld</b> +250 Ok +<b>ETRN some.customer.domain</b> +250 Queuing started +<b>QUIT</b> +221 Bye +</pre> +</blockquote> + +<p> As mentioned in the introduction, the mail is delivered by +connecting to the customer's SMTP server; it is not sent over +the connection that was used to send the ETRN command. </p> + +<p> The Postfix operator can request delivery for a specific customer +by using the command "sendmail -qR<i>destination</i>" and, with +Postfix version 1.1 and later, "postqueue -s<i>destination</i>". +Access to this feature is controlled with the authorized_flush_users +configuration parameter (Postfix version 2.2 and later). +</p> + +<h2><a name="how">How Postfix fast ETRN works</a></h2> + +<p> When a Postfix delivery agent decides that mail must be delivered +later, it sends the destination domain name and the queue file name +to the flush(8) daemon which maintains per-destination logfiles +with file names of queued mail. These logfiles are kept below +$queue_directory/flush. Per-destination logfiles are maintained +only for destinations that are listed with the $fast_flush_domains +parameter and that have syntactically valid domain names. </p> + +<blockquote> + +<table> + +<tr> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> Postfix<br> +delivery<br> agent</td> + +<td> <tt>-</tt>(domain, queue ID)<tt>-></tt> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> Postfix<br> +flush<br> daemon</td> + +<td> <tt>-</tt>(queue ID)<tt>-></tt> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> One logfile <br> +per eligible<br> domain </td> + +</tr> + +</table> + +</blockquote> + +<p> When Postfix receives a request to "deliver mail for a domain +now", the flush(8) daemon moves all deferred queue files that are +listed for that domain to the incoming queue, and requests that +the queue manager deliver them. In order to force delivery, the +queue manager temporarily ignores the lists of undeliverable +destinations: the volatile in-memory list of dead domains, and +the list of message delivery transports specified with the +defer_transports configuration parameter. </p> + +<h2><a name="dirty_secret">Postfix fast ETRN service limitations</a></h2> + +<p> The design of the flush(8) server and of the flush queue +introduce a few limitations that should not be an issue unless you +want to turn on fast ETRN service for every possible destination. +</p> + +<ul> + +<li> <p> The flush(8) daemon maintains per-destination logfiles +with queue file names. When a request to "deliver mail now" arrives, +Postfix will attempt to deliver all recipients in the queue files +that have mail for the destination in question. This does not +perform well with queue files that have recipients in many different +domains, such as queue files with outbound mailing list traffic. +</p> + +<li> <p> The flush(8) daemon maintains per-destination logfiles +only for destinations listed with $fast_flush_domains. With other +destinations you cannot request delivery with "sendmail +-qR<i>destination</i>" or, with Postfix version 1.1 and later, +"postqueue -s<i>destination</i>". </p> + +<li> <p> Up to and including early versions of Postfix version 2.1, +the "fast flush" service may not deliver some messages if the +request to "deliver mail now" is received while a deferred queue +scan is already in progress. The reason is that the queue manager +does not ignore the volatile in-memory list of dead domains, and +the list of message delivery transports specified with the +defer_transports configuration parameter. </p> + +<li> <p> Up to and including Postfix version 2.3, the "fast flush" +service may not deliver some messages if the request to "deliver +mail now" arrives while an incoming queue scan is already in progress. +</p> + +</ul> + +<h2><a name="config">Configuring the Postfix fast ETRN service</a></h2> + +<p> The behavior of the flush(8) daemon is controlled by parameters +in the main.cf configuration file. </p> + +<p> By default, Postfix "fast ETRN" service is available only for +destinations that Postfix is willing to relay mail to: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + fast_flush_domains = $relay_domains + smtpd_etrn_restrictions = permit_mynetworks, reject +</pre> +</blockquote> + +<p> Notes: </p> + +<ul> + +<li> <p> The relay_domains parameter specifies what destinations +Postfix will relay to. For destinations that are not eligible for +the "fast ETRN" service, Postfix replies with an error message. +</p> + +<li> <p> The smtpd_etrn_restrictions parameter limits what clients +may execute the ETRN command. By default, any client has permission. +</p> + +</ul> + +<p> To enable "fast ETRN" for some other destination, specify: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + fast_flush_domains = $relay_domains, some.other.domain +</pre> +</blockquote> + +<p> To disable "fast ETRN", so that Postfix rejects all ETRN requests +and so that it maintains no per-destination logfiles, specify: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + fast_flush_domains = +</pre> +</blockquote> + +<h2><a name="only">Configuring a domain for ETRN service only</a></h2> + +<p> While an "ETRN" customer is off-line, Postfix will make +spontaneous attempts to deliver mail to it. These attempts are +separated in time by increasing time intervals, ranging from +$minimal_backoff_time to $maximal_backoff_time, and should not be +a problem unless a lot of mail is queued. </p> + +<p> To prevent Postfix from making spontaneous delivery attempts +you can configure Postfix to always defer mail for the "ETRN" +customer. Mail is delivered only after the ETRN command or with +"sendmail -q", with "sendmail -qR<i>domain</i>", or with "postqueue +-s<i>domain</i>"(Postfix version 1.1 and later only), </p> + +<p> In the example below we configure an "etrn-only" delivery +transport which is simply a duplicate of the "smtp" and "relay" +mail delivery transports. The only difference is that mail destined +for this delivery transport is deferred as soon as it arrives. +</p> + +<blockquote> +<pre> + 1 /etc/postfix/master.cf: + 2 # ============================================================= + 3 # service type private unpriv chroot wakeup maxproc command + 4 # (yes) (yes) (yes) (never) (100) + 5 # ============================================================= + 6 smtp unix - - n - - smtp + 7 relay unix - - n - - smtp + 8 etrn-only unix - - n - - smtp + 9 +10 /etc/postfix/main.cf: +11 relay_domains = customer.tld ...other domains... +12 defer_transports = etrn-only +13 transport_maps = hash:/etc/postfix/transport +14 +15 /etc/postfix/transport: +16 customer.tld etrn-only:[mailhost.customer.tld] +</pre> +</blockquote> + +<p>Translation: </p> + +<ul> + +<li> <p> Line 8: The "etrn-only" mail delivery service is a copy of the +"smtp" and "relay" service. </p> + +<li> <p> Line 11: Don't forget to authorize relaying for this +customer, either via relay_domains or with the permit_mx_backup +feature. </p> + +<li> <p> Line 12: The "etrn-only" mail delivery service is configured +so that spontaneous mail delivery is disabled. </p> + +<li> <p> Lines 13-16: Mail for the customer is given to the +"etrn-only" mail delivery service. </p> + +<li> <p> Line 16: The "[mailhost.customer.tld]" turns off MX record +lookups; you must specify this if your Postfix server is the primary +MX host for the customer's domain. </p> + +</ul> + +<h2><a name="testing">Testing the Postfix fast ETRN service</a></h2> + +<p> By default, "fast ETRN" service is enabled for all domains that +match $relay_domains. If you run Postfix with "fast ETRN" service +for the very first time, you need to run "sendmail -q" once +in order to populate the per-site deferred mail logfiles. If you +omit this step, no harm is done. The logfiles will eventually +become populated as Postfix routinely attempts to deliver delayed +mail, but that will take a couple hours. After the "sendmail +-q" command has completed all delivery attempts (this can take +a while), you're ready to test the "fast ETRN" service. + +<p> To test the "fast ETRN" service, telnet to the Postfix SMTP +server from a client that is allowed to execute ETRN commands (by +default, that's every client), and type the commands shown in +boldface: </p> + +<blockquote> +<pre> +220 my.server.tld ESMTP Postfix +<b>HELO my.client.tld</b> +250 Ok +<b>ETRN some.customer.domain</b> +250 Queuing started +</pre> +</blockquote> + +<p> where "some.customer.domain" is the name of a domain that has +a non-empty logfile somewhere under $queue_directory/flush. </p> + +<p> In the maillog file, you should immediately see a couple of +logfile records, as evidence that the queue manager has opened +queue files: </p> + +<blockquote> +<pre> +Oct 2 10:51:19 myhostname postfix/qmgr[51999]: 682E8440A4: + from=<whatever>, size=12345, nrcpt=1 (queue active) +Oct 2 10:51:19 myhostname postfix/qmgr[51999]: 02249440B7: + from=<whatever>, size=4711, nrcpt=1 (queue active) +</pre> +</blockquote> + +<p> What happens next depends on whether the destination is reachable. +If it's not reachable, the mail queue IDs will be added back to +the some.customer.domain logfile under $queue_directory/flush. +</p> + +<p> Repeat the exercise with some other destination that your server +is willing to relay to (any domain listed in $relay_domains), but +that has no mail queued. The text in bold face stands for the +commands that you type: </p> + +<blockquote> +<pre> +220 my.server.tld ESMTP Postfix +<b>HELO my.client.tld</b> +250 Ok +<b>ETRN some.other.customer.domain</b> +250 Queuing started +</pre> +</blockquote> + +<p> This time, the "ETRN"" command should trigger NO mail deliveries +at all. If this triggers delivery of all mail, then you used the +wrong domain name, or "fast ETRN" service is turned off. </p> + +<p> Finally, repeat the exercise with a destination that your mail +server is not willing to relay to. It does not matter if your +server has mail queued for that destination. </p> + +<blockquote> +<pre> +220 my.server.tld ESMTP Postfix +<b>HELO my.client.tld</b> +250 Ok +<b>ETRN not.a.customer.domain</b> +459 <not.a.customer.domain>: service unavailable +</pre> +</blockquote> + +<p> In this case, Postfix should reject the request +as shown above. </p> + +</body> + +</html> diff --git a/proto/FILTER_README.html b/proto/FILTER_README.html new file mode 100644 index 0000000..12120f0 --- /dev/null +++ b/proto/FILTER_README.html @@ -0,0 +1,980 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix After-Queue Content Filter </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix After-Queue Content Filter </h1> + +<hr> + +<h2>Introduction</h2> + +<p> This document requires Postfix version 2.1 or later. </p> + +<p> Normally, Postfix receives mail, stores it in the mail queue +and then delivers it. With the external content filter described +here, mail is filtered AFTER it is queued. This approach decouples +mail receiving processes from mail filtering processes, and gives +you maximal control over how many filtering processes you are +willing to run in parallel. </p> + +<p> The after-queue content filter is meant to be used as follows: </p> + +<blockquote> + +<table> + +<tr> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + Network or<br> local users </td> + + <td align="center" valign="middle"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + Postfix<br> queue </td> + + <td align="center" valign="middle"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + <b>Content<br> filter</b> </td> + + <td align="center" valign="middle"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + Postfix<br> queue </td> + + <td align="center" valign="middle"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + Network or<br> local mailbox </td> + +</tr> + +</table> + +</blockquote> + +<p> This document describes implementations that use a single +Postfix instance for everything: receiving, filtering and delivering +mail. Applications that use two separate Postfix instances will +be covered by a later version of this document. </p> + +<p> The after-queue content filter is not to be confused with the +approaches described in the SMTPD_PROXY_README or MILTER_README +documents, +where incoming SMTP mail is filtered BEFORE it is stored into the +Postfix queue. </p> + +<p> This document describes two approaches to content filter +all email, as well as several options to filter mail selectively: </p> + +<ul> + +<li><a href="#principles">Principles of operation</a> + +<li>Simple content filter + +<ul> + +<li><a href="#simple_filter">Simple content filter example</a> + +<li><a href="#simple_performance">Simple content filter performance</a> + +<li><a href="#simple_limitations">Simple content filter limitations</a> + +<li><a href="#simple_turnoff">Turning off the simple content filter</a> + +</ul> + +<li>Advanced content filter + +<ul> + +<li><a href="#advanced_filter">Advanced content filter example</a> + +<li><a href="#performance">Advanced content filter performance</a> + +<li><a href="#advanced_turnoff">Turning off the advanced content filter</a> + +</ul> + +<li>Selective content filtering + +<ul> + +<li><a href="#remote_only">Filtering mail from outside users only</a> + +<li><a href="#domain_dependent">Different filters for different domains</a> + +<li><a href="#dynamic_filter">FILTER actions in access or header/body tables</a> + +</ul> + +</ul> + + +<h2><a name="principles">Principles of operation</a> </h2> + +<p> An after-queue content filter receives unfiltered mail from Postfix +(as described further below) and can do one of the following: </p> + +<ol> + +<li> <p> Re-inject the mail back into Postfix, perhaps after changing + content and/or destination. </p> + +<li> <p> Discard or quarantine the mail. </p> + +<li> <p> Reject the mail (by sending a suitable status code back to + Postfix). Postfix will send the mail back to the sender address. </p> + +</ol> + +<p> NOTE: in this time of mail worms and forged spam, it is a VERY +BAD IDEA to send viruses back to the sender address, because the +sender address is almost certainly not the originator. It is better +to discard known viruses, and to quarantine material that is +suspect so that a human can decide what to do with it. </p> + +<h2><a name="simple_filter">Simple content filter example</a></h2> + +<p> The first example is simple to set up, but has major limitations +that will be addressed in a second example. Postfix receives +unfiltered mail from the network with the smtpd(8) server, and +delivers unfiltered mail to a content filter with the Postfix +pipe(8) delivery agent. The content filter injects filtered mail +back into Postfix with the Postfix sendmail(1) command, so that +Postfix can deliver it to the final destination. </p> + +<p> This means that mail submitted via the Postfix sendmail(1) +command cannot be content filtered. </p> + +<p> 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. </p> + +<blockquote> + +<table> + +<tr> + + <td align="center" valign="top"> Unfiltered<br> <br> </td> + + <td align="center" valign="top"> <tt> -></tt><br> <br> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + smtpd(8)<br> <br> pickup(8) </td> + + <td align="center" valign="middle"> <tt> >- </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + cleanup(8) </td> + + <td align="center" valign="middle"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + qmgr(8)<br> Postfix <br> queue </td> + + <td align="center" valign="middle"> <tt> -< </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + local(8)<br> smtp(8)<br> pipe(8) </td> + + <td align="center" valign="top"> <tt> -></tt><br> <tt> + -></tt><br> </td> + + <td align="center" valign="top"> Filtered<br> Filtered<br> + </td> + +</tr> + +<tr> + + <td colspan="2"> </td> + + <td align="center" valign="middle"> ^<br> <tt> | </tt> </td> + + <td colspan="5"> </td> + + <td align="center" valign="middle"> <tt> |<br> v </tt> </td> + + <td colspan="2"> </td> + +</tr> + +<tr> + + <td colspan="2"> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + <a href="QSHAPE_README.html#maildrop_queue"> maildrop <br> + queue </a> </td> + + <td align="center" valign="middle"> <tt> <- </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle">Postfix<br> + postdrop(1) </td> + + <td align="center" valign="middle"> <tt> <- </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle">Postfix<br> + sendmail(1) </td> + + <td align="center" valign="middle"> <tt> <- </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle">Content + <br> filter </td> + + <td colspan="2"> </td> + +</tr> + +</table> + +</blockquote> + +<p> The content filter can be a simple shell script like this: </p> + +<blockquote> +<pre> + 1 #!/bin/sh + 2 + 3 # Simple shell-based filter. It is meant to be invoked as follows: + 4 # /path/to/script -f sender recipients... + 5 + 6 # Localize these. The -G option does nothing before Postfix 2.3. + 7 INSPECT_DIR=/var/spool/filter + 8 SENDMAIL="/usr/sbin/sendmail -G -i" # NEVER NEVER NEVER use "-t" here. + 9 +10 # Exit codes from <sysexits.h> +11 EX_TEMPFAIL=75 +12 EX_UNAVAILABLE=69 +13 +14 # Clean up when done or when aborting. +15 trap "rm -f in.$$" 0 1 2 3 15 +16 +17 # Start processing. +18 cd $INSPECT_DIR || { +19 echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; } +20 +21 cat >in.$$ || { +22 echo Cannot save mail to file; exit $EX_TEMPFAIL; } +23 +24 # Specify your content filter here. +25 # filter <in.$$ || { +26 # echo Message content rejected; exit $EX_UNAVAILABLE; } +27 +28 $SENDMAIL "$@" <in.$$ +29 +30 exit $? +</pre> +</blockquote> + +<p> Notes: </p> + +<ul> + +<li> <p> Line 8: The -G option says the filter output is not a local +mail submission: don't do silly things like appending the local +domain name to addresses in message headers. This option does +nothing before Postfix version 2.3. </p> + +<li> <p> Line 8: The -i option says don't stop reading input when +a line contains "." only. </p> + +<li> <p> Line 8: NEVER NEVER NEVER use the "-t" command-line option +here. It will mis-deliver mail, like sending messages from a mailing +list back to the mailing list. </p> + +<li> <p> Line 21: The idea is to first capture the message to +file and then run the content through a third-party content filter +program. </p> + +<li> <p> Line 22: If the message cannot be captured to file, mail +delivery is deferred by terminating with exit status 75 (EX_TEMPFAIL). +Postfix places the message in the deferred mail queue and tries +again later. </p> + +<li> <p> Line 25: You will need to specify a real content filter +program here that receives the content on standard input. </p> + +<li> <p> Line 26: If the content filter program finds a problem, +the mail is bounced by terminating with exit status 69 (EX_UNAVAILABLE). +Postfix will send the message back to the sender as undeliverable +mail. +</p> + +<li> <p> NOTE: in this time of mail worms and spam, it is a BAD +IDEA to send known viruses or spam back to the sender, because that +address is likely to be forged. It is safer to discard known viruses +and to quarantine suspicious content so that it can +be inspected by a human being. </p> + +<li> <p> Line 28: If the content is OK, it is given as input to +the Postfix sendmail command, and the exit status of the filter +command is whatever exit status the Postfix sendmail command +produces. Postfix will deliver the message as usual. </p> + +<li> <p> Line 30: Postfix returns the exit status of the Postfix +sendmail command. </p> + +</ul> + +<p> I suggest that you first run this script by hand until you are +satisfied with the results. Run it with a real message (headers+body) +as input: </p> + +<blockquote> +<pre> +% /path/to/script -f sender -- recipient... <message-file +</pre> +</blockquote> + +<p> Once you're satisfied with the content filtering script: </p> + +<ul> + +<li> <p> Create a dedicated local user account called "filter". This +user handles all potentially dangerous mail content - that is +why it should be a separate account. Do not use "nobody", and +most certainly do not use "root" or "postfix". </p> + +<li> <p> Create a directory /var/spool/filter that is accessible only +to the "filter" user. This is where the content filtering script +is supposed to store its temporary files. </p> + +<li> <p> Configure Postfix to deliver mail to the content filter +with the pipe(8) delivery agent (see the pipe(8) manpage for a +description of the command syntax below). </p> + +<pre> +/etc/postfix/master.cf: + # ============================================================= + # service type private unpriv chroot wakeup maxproc command + # (yes) (yes) (yes) (never) (100) + # ============================================================= + filter unix - n n - 10 pipe + flags=Rq user=filter null_sender= + argv=/path/to/script -f ${sender} -- ${recipient} +</pre> + +<p> 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. The empty null_sender setting is +required with Postfix 2.3 and later. </p> + +<li> <p> To turn on content filtering for mail arriving via SMTP +only, append "-o content_filter=filter:dummy" to the master.cf +entry that defines the Postfix SMTP server: </p> + +<pre> +/etc/postfix/master.cf: + # ============================================================= + # service type private unpriv chroot wakeup maxproc command + # (yes) (yes) (yes) (never) (100) + # ============================================================= + smtp inet ...other stuff here, do not change... smtpd + -o content_filter=filter:dummy +</pre> + +<p> The "-o content_filter" line causes Postfix to add one content +filter request record to each incoming mail message, with content +"filter:dummy". This record overrides the normal mail routing +and causes mail to be given to the content filter instead. </p> + +<p> The content_filter configuration parameter expects a value of +the form <i>transport:destination</i>. The <i>transport</i> name +specifies the first field of a mail delivery agent definition in +master.cf; the syntax of the next-hop <i>destination</i> is described +in the manual page of the corresponding delivery agent. </p> + +<p> The meaning of an empty next-hop filter <i>destination</i> is +version dependent. Postfix 2.7 and later will use the recipient +domain; earlier versions will use $myhostname. Specify +"default_filter_nexthop = $myhostname" for compatibility with Postfix +2.6 or earlier, or specify a non-empty next-hop filter <i>destination</i>. +</p> + +<p> The content_filter setting has lower precedence than a FILTER +action that is specified in an access(5), header_checks(5) or +body_checks(5) table. </p> + +<li> <p> Execute "<b>postfix reload</b>" to complete the change. +</p> + +</ul> + +<h2> <a name="simple_performance">Simple content filter performance</a> </h2> + +<p> With the shell script as shown above you will lose a factor of +four in Postfix performance for transit mail that arrives and leaves +via SMTP. You will lose another factor in transit performance for +each additional temporary file that is created and deleted in the +process of content filtering. The performance impact is less for +mail that is submitted or delivered locally, because such deliveries +are already slower than SMTP transit mail. </p> + +<h2><a name="simple_limitations">Simple content filter limitations</a></h2> + +<p> The problem with content filters like the one above is that +they are not very robust. The reason is that the software does not +talk a well-defined protocol with Postfix. If the filter shell +script aborts because the shell runs into some memory allocation +problem, the script will not produce a nice exit status as defined +in the file /usr/include/sysexits.h. Instead of going to the +deferred queue, mail will bounce. The same lack of robustness can +happen when the content filtering software itself runs into a +resource problem. </p> + +<p> The simple content filter method is not suitable for content +filter actions that are invoked via header_checks or body_checks +patterns. These patterns will be applied again after mail is +re-injected with the Postfix sendmail command, resulting in a mail +filtering loop. The advanced content filtering method (see below) +makes it possible to turn off header_checks or body_checks patterns +for filtered mail. </p> + +<h2><a name="simple_turnoff">Turning off the simple content filter</a> </h2> + +<p> To turn off "simple" content filtering: </p> + +<ul> <li> <p> Edit the master.cf file, remove the "-o +content_filter=filter:dummy" text from the entry that defines the +Postfix SMTP server. </p> + +<li> <p> Execute "<b>postsuper -r ALL</b>" to remove content +filter request records from existing queue files. </p> + +<li> <p> Execute another "<b>postfix reload</b>". </p> + +</ul> + +<h2><a name="advanced_filter">Advanced content filter example</a></h2> + +<p> 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. </p> + +<p> For non-SMTP capable content filtering software, Bennett Todd's +SMTP proxy implements a nice PERL/SMTP content filtering framework. +See: https://web.archive.org/web/20151022025756/http://bent.latency.net/smtpprox/. </p> + +<p> 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. </p> + +<blockquote> + +<table> + +<tr> + + <td align="center" valign="middle"> Unfiltered<br> <br> + Unfiltered</td> + + <td align="center" valign="middle"> <tt> -></tt><br> <br> + <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + smtpd(8)<br> <br> pickup(8) </td> + + <td align="center" valign="middle"> <tt> >- </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + cleanup(8) </td> + + <td align="center" valign="middle"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + qmgr(8)<br> Postfix <br> queue </td> + + <td align="center" valign="middle"> <tt> -< </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + smtp(8)<br> <br> local(8) </td> + + <td align="center" valign="middle"> <tt> -></tt><br> <br> + <tt> -> </tt></td> + + <td align="center" valign="middle"> Filtered<br> <br> + Filtered</td> + +</tr> + +<tr> + + <td colspan="4"> </td> + + <td align="center" valign="middle"> ^<br> <tt> | </tt> </td> + + <td> </td> + + <td align="center" valign="middle"> <tt> |<br> v </tt> </td> + + <td colspan="4"> </td> + +</tr> + +<tr> + + <td colspan="4"> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + smtpd(8)<br> 10026 </td> + + <td> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle"> + smtp(8)<br> </td> + + <td colspan="4"> </td> + +</tr> + +<tr> + + <td colspan="4"> </td> + + <td align="center" valign="middle"> ^<br> <tt> | </tt> </td> + + <td> </td> + + <td align="center" valign="middle"> <tt> |<br> v </tt> </td> + + <td colspan="4"> </td> + +</tr> + +<tr> + + <td colspan="4"> </td> + + <td colspan="3" bgcolor="#f0f0ff" align="center" + valign="middle">content filter 10025</td> + + <td colspan="4"> </td> + +</tr> + +</table> + +</blockquote> + +<p> The example given here filters all mail, including mail that +arrives via SMTP and mail that is locally submitted via the Postfix +sendmail command (local submissions enter Postfix via the pickup(8) +server; to keep the figure simple we omit local submission details). +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. </p> + +<p> 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. </p> + +<h3>Advanced content filter: requesting that all mail is filtered</h3> + +<p> To enable the advanced content filter method for all mail, +specify in main.cf: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + content_filter = scan:localhost:10025 + receive_override_options = no_address_mappings +</pre> +</blockquote> + +<ul> + +<li> <p> 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. </p> + +<li> <p> 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). </p> + +<li> <p> 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. </p> + +<li> <p> The content_filter configuration parameter expects a value +of the form <i>transport:destination</i>. The <i>transport</i> name +specifies the first field of a mail delivery agent definition in +master.cf; the syntax of the next-hop <i>destination</i> is described +in the manual page of the corresponding delivery agent. </p> + +<li> <p> The meaning of an empty next-hop filter <i>destination</i> +is version dependent. Postfix 2.7 and later will use the recipient +domain; earlier versions will use $myhostname. Specify +"default_filter_nexthop = $myhostname" for compatibility with Postfix +2.6 or earlier, or specify a non-empty next-hop filter <i>destination</i>. + +<li> <p> The content_filter setting has lower precedence than a +FILTER action that is specified in an access(5), header_checks(5) +or body_checks(5) table. </p> + +</ul> + +<h3> Advanced content filter: sending unfiltered mail to the content +filter</h3> + +<p> 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: +</p> + +<blockquote> +<pre> +/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 + -o smtp_generic_maps= +</pre> +</blockquote> + +<ul> + +<li> <p> 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. </p> + +<li> <p> 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. </p> + +<li> <p> 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 8-bit mail. </p> + +<li> <p> The "-o smtp_generic_maps=" is a workaround that prevents +local address rewriting with generic(5) maps. Such rewriting should +happen only when mail is sent out to the Internet. </p> + +</ul> + +<h3>Advanced content filter: running the content filter</h3> + +<p> 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: </p> + +<blockquote> +<pre> +/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 +</pre> +</blockquote> + +<ul> + +<li> <p> "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. +</p> + +<li> <p> By default, Postfix will terminate a command that runs +longer than command_time_limit seconds (default: 1000s). This is a +safety measure that prevents filters from running forever. </p> + +</ul> + +<p> 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. </p> + +<h3>Advanced filter: injecting mail back into Postfix</h3> + +<p> 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. </p> + +<p> 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. </p> + +<blockquote> +<pre> +/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= + # Postfix 2.10 and later: specify empty smtpd_relay_restrictions. + -o smtpd_relay_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 +</pre> +</blockquote> + +<ul> + +<li> <p> NOTE: do not use spaces around the "=" or "," characters. </p> + +<li> <p> NOTE: the SMTP server must not have a smaller process +limit than the "filter" master.cf entry. </p> + +<li> <p> 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 loop. </p> + +<li> <p> 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: </p> + +<ul> + + <li> <p> We specify "no_unknown_recipient_checks" to disable + attempts to find out if a recipient is unknown. </p> + + <li> <p> We specify "no_header_body_checks" to disable header/body + checks. </p> + + <li> <p> We specify "no_milters" to disable Milter applications + (this option is available only in Postfix 2.3 and later). </p> + + <li> <p> We don't specify "no_address_mappings" 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. </p> + +</ul> + + <p> These receive override options are either implemented by the + SMTP server itself, or they are passed on to the cleanup server. + </p> + +<li> <p> 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. + +<li> <p> 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). </p> + +</ul> + +<h2><a name="performance">Advanced content filter performance</a></h2> + +<p> With the "sandwich" approach to content filtering described +here, it is important to match the filter concurrency to the +available CPU, memory and I/O resources. Too few content filter +processes and mail accumulates in the active queue even with low +traffic volume; too much concurrency and Postfix ends up deferring +mail destined for the content filter because processes fail due to +insufficient resources. </p> + +<p> Currently, content filter performance tuning is a process of +trial and error; analysis is handicapped because filtered and +unfiltered messages share the same queue. As mentioned in the +introduction of this document, content filtering with multiple +Postfix instances will be covered in a future version. </p> + +<h2><a name="advanced_turnoff">Turning off the advanced content filter</a> </h2> + +<p> To turn off "advanced" content filtering: </p> + +<ul> <li> <p> Delete or comment out the two following main.cf lines. +The other changes made for advanced content filtering have no effect +when content filtering is turned off. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + content_filter = scan:localhost:10025 + receive_override_options = no_address_mappings +</pre> +</blockquote> + +<li> <p> Execute "<b>postsuper -r ALL</b>" to remove content +filter request records from existing queue files. </p> + +<li> <p> Execute another "<b>postfix reload</b>". </p> + +</ul> + +<h2><a name="remote_only">Filtering mail from outside users only</a></h2> + +<p> The easiest approach is to configure ONE Postfix instance with +multiple SMTP server IP addresses in master.cf: </p> + +<ul> + +<li> <p> Two SMTP server IP addresses for mail from inside users only, +with content filtering turned off. </p> + +<pre> +/etc/postfix.master.cf: + # ================================================================== + # service type private unpriv chroot wakeup maxproc command + # (yes) (yes) (yes) (never) (100) + # ================================================================== + 1.2.3.4:smtp inet n - n - - smtpd + -o smtpd_client_restrictions=permit_mynetworks,reject + 127.0.0.1:smtp inet n - n - - smtpd + -o smtpd_client_restrictions=permit_mynetworks,reject +</pre> + +<li> <p> One SMTP server address for mail from outside users with +content filtering turned on. </p> + +<pre> +/etc/postfix.master.cf: + # ================================================================= + # service type private unpriv chroot wakeup maxproc command + # (yes) (yes) (yes) (never) (100) + # ================================================================= + 1.2.3.5:smtp inet n - n - - smtpd + -o content_filter=filter-service:filter-destination + -o receive_override_options=no_address_mappings +</pre> + +</ul> + +<p> After this, you can follow the same procedure as outlined in +the "advanced" or "simple" content filtering examples above, except +that you must not specify "content_filter" or "receive_override_options" +in the main.cf file. </p> + +<h2><a name="domain_dependent">Different filters for different +domains</a></h2> + +<p> If you are an MX service provider and want to apply different +content filters for different domains, you can configure ONE Postfix +instance with multiple SMTP server IP addresses in master.cf. Each +address provides a different content filter service. </p> + +<blockquote> +<pre> +/etc/postfix.master.cf: + # ================================================================= + # service type private unpriv chroot wakeup maxproc command + # (yes) (yes) (yes) (never) (100) + # ================================================================= + # SMTP service for domains that are filtered with service1:dest1 + 1.2.3.4:smtp inet n - n - - smtpd + -o content_filter=service1:dest1 + -o receive_override_options=no_address_mappings + + # SMTP service for domains that are filtered with service2:dest2 + 1.2.3.5:smtp inet n - n - - smtpd + -o content_filter=service2:dest2 + -o receive_override_options=no_address_mappings +</pre> +</blockquote> + +<p> After this, you can follow the same procedure as outlined in +the "advanced" or "simple" content filtering examples above, except +that you must not specify "content_filter" or "receive_override_options" +in the main.cf file. </p> + +<p> Set up MX records in the DNS that route each domain to the +proper SMTP server instance. </p> + +<h2><a name="dynamic_filter">FILTER actions in access or header/body +tables</a></h2> + +<p> The above filtering configurations are static. Mail that follows +a given path is either always filtered or it is never filtered. As +of Postfix 2.0 you can also turn on content filtering on the fly. +</p> + +<p> To turn on content filtering with an access(5) table rule: </p> + +<blockquote> +<pre> +/etc/postfix/access: + <i>whatever</i> FILTER foo:bar +</pre> +</blockquote> + +<p> To turn on content filtering with a header_checks(5) or +body_checks(5) table pattern: </p> + +<blockquote> +<pre> +/etc/postfix/header_checks: + /<i>whatever</i>/ FILTER foo:bar +</pre> +</blockquote> + +<p> You can do this in smtpd access maps as well as the cleanup +server's header/body_checks. This feature must be used with great +care: you must disable all the UCE features in the after-filter +smtpd and cleanup daemons or else you will have a content filtering +loop. </p> + +<p> Limitations: </p> + +<ul> + +<li> <p> FILTER actions from smtpd access maps and header/body_checks +take precedence over filters specified with the main.cf content_filter +parameter. </p> + +<li> <p> If a message triggers more than one filter action, only +the last one takes effect. </p> + +<li> <p> The same content filter is applied to all the recipients +of a given message. </p> + +</ul> + +</body> + +</html> diff --git a/proto/FORWARD_SECRECY_README.html b/proto/FORWARD_SECRECY_README.html new file mode 100644 index 0000000..0ed87d6 --- /dev/null +++ b/proto/FORWARD_SECRECY_README.html @@ -0,0 +1,727 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>TLS Forward Secrecy in Postfix</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT=""> +TLS Forward Secrecy in Postfix +</h1> + +<hr> + +<h2> Warning </h2> + +<p> Forward secrecy does not protect against active attacks such +as forged DNS replies or forged TLS server certificates. If such +attacks are a concern, then the SMTP client will need to authenticate +the remote SMTP server in a sufficiently-secure manner. For example, +by the fingerprint of a (CA or leaf) public key or certificate. +Conventional PKI relies on many trusted parties and is easily +subverted by a state-funded adversary. </p> + +<h2> Overview </h2> + +<p> Postfix supports forward secrecy of TLS network communication +since version 2.2. This support was adopted from Lutz Jänicke's +"Postfix TLS patch" for earlier Postfix versions. This document +will focus on TLS Forward Secrecy in the Postfix SMTP client and +server. See <a href="TLS_README.html">TLS_README</a> for a general +description of Postfix TLS support. </p> + +<p> Topics covered in this document: </p> + +<ul> + +<li> <p> Give me some background on forward secrecy in Postfix </p> + +<ul> + +<li><a href="#dfn_fs">What is Forward Secrecy</a> + +<li><a href="#tls_fs">Forward Secrecy in TLS</a> + +<li><a href="#server_fs">Forward Secrecy in the Postfix SMTP Server</a> + +<li><a href="#client_fs">Forward Secrecy in the Postfix SMTP Client</a> + +</ul> + +<li> <p> Never mind, just show me what it takes to get forward +secrecy </p> + +<ul> + +<li><a href="#quick-start">Getting started, quick and dirty</a> + +<li><a href="#test">How can I see that a connection has forward secrecy?</a> + +<li><a href="#ciphers"> What ciphers provide forward secrecy? </a> + +<li><a href="#status"> What do "Anonymous", "Untrusted", etc. in +Postfix logging mean? </a> + +</ul> + +<li> <p> <a href="#credits"> Credits </a> </p> + +</ul> + +<h2><a name="dfn_fs">What is Forward Secrecy</a></h2> + +<p> The term "Forward Secrecy" (or sometimes "Perfect Forward Secrecy") +is used to describe security protocols in which the confidentiality +of past traffic is not compromised when long-term keys used by either +or both sides are later disclosed. </p> + +<p> Forward secrecy is accomplished by negotiating session keys +using per-session cryptographically-strong random numbers that are +not saved, and signing the exchange with long-term authentication +keys. Later disclosure of the long-term keys allows impersonation +of the key holder from that point on, but not recovery of prior +traffic, since with forward secrecy, the discarded random key +agreement inputs are not available to the attacker. </p> + +<p> Forward secrecy is only "perfect" when brute-force attacks on +the key agreement algorithm are impractical even for the best-funded +adversary and the random-number generators used by both parties are +sufficiently strong. Otherwise, forward secrecy leaves the attacker +with the challenge of cracking the key-agreement protocol, which +is likely quite computationally intensive, but may be feasible for +sessions of sufficiently high value. Thus forward secrecy places +cost constraints on the efficacy of bulk surveillance, recovering +all past traffic is generally infeasible, and even recovery of +individual sessions may be infeasible given a sufficiently-strong +key agreement method. </p> + +<h2><a name="tls_fs">Forward Secrecy in TLS</a></h2> + +<p> Early implementations of the SSL protocol do not provide forward +secrecy (some provide it only with artificially-weakened "export" +cipher suites, but we will ignore those here). The client +sends a random "pre-master secret" to the server encrypted with the +server's RSA public key. The server decrypts this with its private +key, and uses it together with other data exchanged in the clear +to generate the session key. An attacker with access to the server's +private key can perform the same computation at any later time. +The TLS library in Windows XP and Windows Server 2003 only supported +cipher suites of this type, and Exchange 2003 servers largely do +not support forward secrecy. </p> + +<p> Later revisions to the TLS protocol introduced forward-secrecy +cipher suites in which the client and server implement a key exchange +protocol based on ephemeral secrets. Sessions encrypted with one +of these newer cipher suites are not compromised by future disclosure +of long-term authentication keys. </p> + +<p> The key-exchange algorithms used for forward secrecy require +the TLS server to designate appropriate "parameters" consisting of a +mathematical "group" and an element of that group called a "generator". +Presently, there are two flavors of "groups" that work with PFS: </p> + +<ul> + +<li> <p> <b> Prime-field groups (EDH):</b> The server needs to be +configured with a suitably-large prime and a corresponding "generator". +The acronym for forward secrecy over prime fields is EDH for Ephemeral +Diffie-Hellman (also abbreviated as DHE). +</p> + +<li> <p> <b> Elliptic-curve groups (EECDH): </b> The server needs +to be configured with a "named curve". These offer better security +at lower computational cost than prime field groups, but are not +as widely implemented. The acronym for the elliptic curve version +is EECDH which is short for Ephemeral Elliptic Curve Diffie-Hellman +(also abbreviated as ECDHE). </p> + +</ul> + +<p> It is not essential to know what these are, but one does need +to know that OpenSSL supports EECDH with version 1.0.0 or later. +Thus the configuration parameters related to Elliptic-Curve forward +secrecy are available when Postfix is linked with OpenSSL ≥ 1.0.0 +(provided EC support has not been disabled by the vendor, as in +some versions of RedHat Linux). </p> + +<p> Elliptic curves used in cryptography are typically identified +by a "name" that stands for a set of well-known parameter values, +and it is these "names" (or associated ASN.1 object identifiers) +that are used in the TLS protocol. On the other hand, with TLS there +are no specially designated prime field groups, so each server is +free to select its own suitably-strong prime and generator. </p> + +<h2><a name="server_fs">Forward Secrecy in the Postfix SMTP Server</a></h2> + +<p> The Postfix ≥ 2.2 SMTP server supports forward secrecy in +its default configuration. If the remote SMTP client prefers cipher +suites with forward secrecy, then the traffic between the server +and client will resist decryption even if the server's long-term +authentication keys are <i>later</i> compromised. </p> + +<p> Some remote SMTP clients may support forward secrecy, but prefer +cipher suites <i>without</i> forward secrecy. In that case, Postfix +≥ 2.8 could be configured to ignore the client's preference with +the main.cf setting "tls_preempt_cipherlist = yes". However, this +will likely cause interoperability issues with older Exchange servers +and is not recommended for now. </p> + +<h3> EDH Server support </h3> + +<p> Postfix ≥ 2.2 supports 1024-bit-prime EDH out of the box, +with no additional configuration, but you may want to override the +default prime to be 2048 bits long, and you may want to regenerate +your primes periodically. See the <a href="#quick-start">quick-start</a> +section for details. With Postfix ≥ 3.1 the out of the box +(compiled-in) EDH prime size is 2048 bits. </p> + +<p> With prime-field EDH, OpenSSL wants the server to provide +two explicitly-selected (prime, generator) combinations. One for +the now long-obsolete "export" cipher suites, and another for +non-export cipher suites. Postfix has two such default combinations +compiled in, but also supports explicitly-configured overrides. +</p> + +<ul> + +<li> <p> The "export" EDH parameters are used only with the obsolete +"export" ciphers. To use a non-default prime, generate a 512-bit +DH parameter file and set smtpd_tls_dh512_param_file to the filename +(see the <a href="#quick-start">quick-start</a> section for details). +With Postfix releases after the middle of 2015 the default opportunistic +TLS cipher grade (smtpd_tls_ciphers) is "medium" or stronger, and +export ciphers are no longer used. </p> + +<li> <p> The non-export EDH parameters are used for all other EDH +cipher suites. To use a non-default prime, generate a 1024-bit or +2048-bit DH parameter file and set smtpd_tls_dh1024_param_file to +the filename. Despite the name this is simply the non-export +parameter file and the prime need not actually be 1024 bits long +(see the <a href="#quick-start">quick-start</a> section for details). +</p> + +</ul> + +<p> As of mid-2015, SMTP clients are starting to reject TLS +handshakes with primes smaller than 2048 bits. Each site needs to +determine which prime size works best for the majority of its +clients. See the <a href="#quick-start">quick-start</a> section +for the recommended configuration to work around this issue. </p> + +<h3> EECDH Server support </h3> + +<p> Postfix ≥ 2.6 supports NIST P-256 EECDH when built with OpenSSL +≥ 1.0.0. When the remote SMTP client also supports EECDH and +implements the P-256 curve, forward secrecy just works. </p> + +<blockquote> <p> Note: With Postfix 2.6 and 2.7, enable EECDH by +setting the main.cf parameter smtpd_tls_eecdh_grade to "strong". +</p> </blockquote> + +<p> The elliptic curve standards are evolving, with new curves +introduced in RFC 8031 to augment or replace the NIST curves tarnished +by the Snowden revelations. Fortunately, TLS clients advertise +their list of supported curves to the server so that servers can +choose newer stronger curves when mutually supported. OpenSSL 1.0.2 +released in January 2015 was the first release to implement negotiation +of supported curves in TLS servers. In older OpenSSL releases, the +server is limited to selecting a single widely supported curve. </p> + +<p> With Postfix prior to 3.2 or OpenSSL prior to 1.0.2, only a +single server-side curve can be configured, by specifying a suitable +EECDH "grade": </p> + +<blockquote> +<pre> + smtpd_tls_eecdh_grade = strong | ultra + # Underlying curves, best not changed: + # tls_eecdh_strong_curve = prime256v1 + # tls_eecdh_ultra_curve = secp384r1 +</pre> +</blockquote> + +<p> Postfix ≥ 3.2 supports the curve negotiation API of OpenSSL +≥ 1.0.2. When using this software combination, the default setting +of "smtpd_tls_eecdh_grade" changes to "auto", which selects a curve +that is supported by both the server and client. The list of +candidate curves can be configured via "tls_eecdh_auto_curves", +which can be used to configure a prioritized list of supported +curves (most preferred first) on both the server and client. +The default list is suitable for most users. </p> + +<h2> <a name="client_fs">Forward Secrecy in the Postfix SMTP Client</a> </h2> + +<p> The Postfix ≥ 2.2 SMTP client supports forward secrecy in +its default configuration. All supported OpenSSL releases support +EDH key exchange. OpenSSL releases ≥ 1.0.0 also support EECDH +key exchange (provided elliptic-curve support has not been disabled +by the vendor as in some versions of RedHat Linux). If the +remote SMTP server supports cipher suites with forward secrecy (and +does not override the SMTP client's cipher preference), then the +traffic between the server and client will resist decryption even +if the server's long-term authentication keys are <i>later</i> +compromised. </p> + +<p> Postfix ≥ 3.2 supports the curve negotiation API of OpenSSL +≥ 1.0.2. The list of candidate curves can be changed via the +"tls_eecdh_auto_curves" configuration parameter, which can be used +to select a prioritized list of supported curves (most preferred +first) on both the Postfix SMTP server and SMTP client. The default +list is suitable for most users. </p> + +<p> The default Postfix SMTP client cipher lists are correctly +ordered to prefer EECDH and EDH cipher suites ahead of similar +cipher suites that don't implement forward secrecy. Administrators +are strongly discouraged from changing the cipher list definitions. </p> + +<p> The default minimum cipher grade for opportunistic TLS is +"medium" for Postfix releases after the middle of 2015, "export" +for older releases. Changing the minimum cipher grade does not +change the cipher preference order. Note that cipher grades higher +than "medium" exclude Exchange 2003 and likely other MTAs, thus a +"high" cipher grade should be chosen only on a case-by-case basis +via the <a href="TLS_README.html#client_tls_policy">TLS policy</a> +table. </p> + +<h2><a name="quick-start">Getting started, quick and dirty</a></h2> + +<h3> EECDH Client support (Postfix ≥ 2.2 with OpenSSL ≥ 1.0.0) </h3> + +<p> This works "out of the box" with no need for additional +configuration. </p> + +<p> Postfix ≥ 3.2 supports the curve negotiation API of OpenSSL +≥ 1.0.2. The list of candidate curves can be changed via the +"tls_eecdh_auto_curves" configuration parameter, which can be used +to select a prioritized list of supported curves (most preferred +first) on both the Postfix SMTP server and SMTP client. The default +list is suitable for most users. </p> + +<h3> EECDH Server support (Postfix ≥ 2.6 with OpenSSL ≥ 1.0.0) </h3> + +<p> With Postfix 2.6 and 2.7, enable elliptic-curve support in the +Postfix SMTP server. This is the default with Postfix +≥ 2.8. Note, however, that elliptic-curve support may be disabled +by the vendor, as in some versions of RedHat Linux. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # Postfix 2.6 & 2.7 only. EECDH is on by default with Postfix ≥ 2.8. + # The default grade is "auto" with Postfix ≥ 3.2. + smtpd_tls_eecdh_grade = strong +</pre> +</blockquote> + +<h3> EDH Client support (Postfix ≥ 2.2, all supported OpenSSL +versions) </h3> + +<p> This works "out of the box" without additional configuration. </p> + +<h3> EDH Server support (Postfix ≥ 2.2, all supported OpenSSL +versions) </h3> + +<p> Optionally generate non-default Postfix SMTP server EDH parameters +for improved security against pre-computation attacks and for +compatibility with Debian-patched Exim SMTP clients that require a +≥ 2048-bit length for the non-export prime. </p> + +<p> With Postfix ≥ 3.7 built against OpenSSL version is 3.0.0 or later, when +the value of smtpd_tls_dh1024_param_file is either empty or "<b>auto</b>", the +EDH parameter selection is delegated to the OpenSSL library, which selects +appropriate parameters based on the TLS handshake. This choice is likely to be +the most interoperable with SMTP clients using various TLS libraries, and +custom local parameters are no longer recommended when using Postfix ≥ 3.7 +built against OpenSSL 3.0.0. Just leave smtpd_tls_dh1024_param_file at its +default value (both in main.cf(5) and any master.cf(5) overrides, and let +OpenSSL do the work. </p> + +<p> Otherwise, execute as root (prime group generation can take a +few seconds to a few minutes): </p> + +<blockquote> +<pre> +# cd /etc/postfix +# umask 022 +# openssl dhparam -out dh512.tmp 512 && mv dh512.tmp dh512.pem +# openssl dhparam -out dh1024.tmp 1024 && mv dh1024.tmp dh1024.pem +# openssl dhparam -out dh2048.tmp 2048 && mv dh2048.tmp dh2048.pem +# chmod 644 dh512.pem dh1024.pem dh2048.pem +</pre> +</blockquote> + +<p> The Postfix SMTP server EDH parameter files are not secret, +after all these parameters are sent to all remote SMTP clients in +the clear. Mode 0644 is appropriate. </p> + +<p> You can improve security against pre-computation attacks further +by regenerating the Postfix SMTP server EDH parameters periodically +(an hourly or daily cron job running the above commands as root can +automate this task). </p> + +<p> Once the parameters are in place, update main.cf as follows: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_dh1024_param_file = ${config_directory}/dh2048.pem + smtpd_tls_dh512_param_file = ${config_directory}/dh512.pem +</pre> +</blockquote> + +<p> If some of your MSA clients don't support 2048-bit EDH, you may +need to adjust the submission entry in master.cf accordingly: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + submission inet n - n - - smtpd + # Some submission clients may not yet do 2048-bit EDH, if such + # clients use your MSA, configure 1024-bit EDH instead. However, + # as of mid-2015, many submission clients no longer accept primes + # with less than 2048-bits. Each site needs to determine which + # type of client is more important to support. + -o smtpd_tls_dh1024_param_file=${config_directory}/dh1024.pem + -o smtpd_tls_security_level=encrypt + -o smtpd_sasl_auth_enable=yes + ... +</pre> +</blockquote> + +<h2><a name="test">How can I see that a connection has forward +secrecy? </a> </h2> + +<p> Postfix can be configured to report information about the +negotiated cipher, the corresponding key lengths, and the remote +peer certificate or public-key verification status. </p> + +<ul> + +<li> <p> With "smtp_tls_loglevel = 1" and "smtpd_tls_loglevel = 1", +the Postfix SMTP client and server will log TLS connection information +to the maillog file. The general logfile format is shown below. +With TLS 1.3 there may be additional properties logged after the +cipher name and bits. </p> + +<blockquote> +<pre> +postfix/smtp[<i>process-id</i>]: Untrusted TLS connection established +to host.example.com[192.168.0.2]:25: TLSv1 with cipher <i>cipher-name</i> +(<i>actual-key-size</i>/<i>raw-key-size</i> bits) + +postfix/smtpd[<i>process-id</i>]: Anonymous TLS connection established +from host.example.com[192.168.0.2]: TLSv1 with cipher <i>cipher-name</i> +(<i>actual-key-size</i>/<i>raw-key-size</i> bits) +</pre> +</blockquote> + +<li> <p> With "smtpd_tls_received_header = yes", the Postfix SMTP +server will record TLS connection information in the Received: +header in the form of comments (text inside parentheses). The general +format depends on the smtpd_tls_ask_ccert setting. With TLS 1.3 there +may be additional properties logged after the cipher name and bits. </p> + +<blockquote> +<pre> +Received: from host.example.com (host.example.com [192.168.0.2]) + (using TLSv1 with cipher <i>cipher-name</i> + (<i>actual-key-size</i>/<i>raw-key-size</i> bits)) + (Client CN "host.example.com", Issuer "John Doe" (not verified)) + +Received: from host.example.com (host.example.com [192.168.0.2]) + (using TLSv1 with cipher <i>cipher-name</i> + (<i>actual-key-size</i>/<i>raw-key-size</i> bits)) + (No client certificate requested) +</pre> +</blockquote> + +<p> TLS 1.3 examples. Some of the new attributes may not appear when not +applicable or not available in older versions of the OpenSSL library. </p> + +<blockquote> +<pre> +Received: from localhost (localhost [127.0.0.1]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) + (No client certificate requested) + +Received: from localhost (localhost [127.0.0.1]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 + client-signature ECDSA (P-256) client-digest SHA256) + (Client CN "example.org", Issuer "example.org" (not verified)) +</pre> +</blockquote> + +<ul> +<li> <p> The "key-exchange" attribute records the type of "Diffie-Hellman" +group used for key agreement. Possible values include "DHE", "ECDHE", "X25519" +and "X448". With "DHE", the bit size of the prime will be reported in +parentheses after the algorithm name, with "ECDHE", the curve name. </p> + +<li> <p> The "server-signature" attribute shows the public key signature +algorithm used by the server. With "RSA-PSS", the bit size of the modulus will +be reported in parentheses. With "ECDSA", the curve name. If, for example, +the server has both an RSA and an ECDSA private key and certificate, it will be +possible to track which one was used for a given connection. </p> + +<li> <p> The new "server-digest" attribute records the digest algorithm used by +the server to prepare handshake messages for signing. The Ed25519 and Ed448 +signature algorithms do not make use of such a digest, so no "server-digest" +will be shown for these signature algorithms. </p> + +<li> <p> When a client certificate is requested with "smtpd_tls_ask_ccert" and +the client uses a TLS client-certificate, the "client-signature" and +"client-digest" attributes will record the corresponding properties of the +client's TLS handshake signature. </p> </ul> + +</ul> + +<p> The next sections will explain what <i>cipher-name</i>, +<i>key-size</i>, and peer verification status information to expect. +</p> + +<h2><a name="ciphers"> What ciphers provide forward secrecy? </a> </h2> + +<p> There are dozens of ciphers that support forward secrecy. What +follows is the beginning of a list of 51 ciphers available with +OpenSSL 1.0.1e. The list is sorted in the default Postfix preference +order. It excludes null ciphers that only authenticate and don't +encrypt, together with export and low-grade ciphers whose encryption +is too weak to offer meaningful secrecy. The first column shows the +cipher name, and the second shows the key exchange method. </p> + +<blockquote> +<pre> +$ openssl ciphers -v \ + 'aNULL:-aNULL:kEECDH:kEDH:+RC4:!eNULL:!EXPORT:!LOW:@STRENGTH' | + awk '{printf "%-32s %s\n", $1, $3}' +AECDH-AES256-SHA Kx=ECDH +ECDHE-RSA-AES256-GCM-SHA384 Kx=ECDH +ECDHE-ECDSA-AES256-GCM-SHA384 Kx=ECDH +ECDHE-RSA-AES256-SHA384 Kx=ECDH +ECDHE-ECDSA-AES256-SHA384 Kx=ECDH +ECDHE-RSA-AES256-SHA Kx=ECDH +ECDHE-ECDSA-AES256-SHA Kx=ECDH +ADH-AES256-GCM-SHA384 Kx=DH +ADH-AES256-SHA256 Kx=DH +ADH-AES256-SHA Kx=DH +ADH-CAMELLIA256-SHA Kx=DH +DHE-DSS-AES256-GCM-SHA384 Kx=DH +DHE-RSA-AES256-GCM-SHA384 Kx=DH +DHE-RSA-AES256-SHA256 Kx=DH +... +</pre> +</blockquote> + +<p> To date, all ciphers that support forward secrecy have one of +five values for the first component of their OpenSSL name: "AECDH", +"ECDHE", "ADH", "EDH" or "DHE". Ciphers that don't implement forward +secrecy have names that don't start with one of these prefixes. +This pattern is likely to persist until some new key-exchange +mechanism is invented that also supports forward secrecy. </p> + +<p> The actual key length and raw algorithm key length +are generally the same with non-export ciphers, but they may +differ for the legacy export ciphers where the actual key +is artificially shortened. </p> + +<p> Starting with TLS 1.3 the cipher name no longer contains enough +information to determine which forward-secrecy scheme was employed, +but TLS 1.3 <b>always</b> uses forward-secrecy. On the client side, +up-to-date Postfix releases log additional information for TLS 1.3 +connections, reporting the signature and key exchange algorithms. +Two examples below (the long single line messages are folded across +multiple lines for readability): </p> + +<blockquote> +<pre> +postfix/smtp[<i>process-id</i>]: + Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25: + TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 + client-signature ECDSA (P-256) client-digest SHA256 + +postfix/smtp[<i>process-id</i>]: + Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25: + TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange ECDHE (P-256) server-signature ECDSA (P-256) server-digest SHA256 +</pre> +</blockquote> + +<p> In the above connections, the "key-exchange" value records the +"Diffie-Hellman" algorithm used for key agreement. The "server-signature" value +records the public key algorithm used by the server to sign the key exchange. +The "server-digest" value records any hash algorithm used to prepare the data +for signing. With "ED25519" and "ED448", no separate hash algorithm is used. +</p> + +<p> Examples of Postfix SMTP server logging: </p> + +<blockquote> +<pre> +postfix/smtpd[<i>process-id</i>]: + Untrusted TLS connection established from localhost[127.0.0.1]:25: + TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 + client-signature ECDSA (P-256) client-digest SHA256 + +postfix/smtpd[<i>process-id</i>]: + Anonymous TLS connection established from localhost[127.0.0.1]: + TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + server-signature RSA-PSS (2048 bits) server-digest SHA256 + +postfix/smtpd[<i>process-id</i>]: + Anonymous TLS connection established from localhost[127.0.0.1]: + TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + server-signature ED25519 +</pre> +</blockquote> + +<p> Note that Postfix ≥ 3.4 server logging may also include a +"to <i>sni-name</i>" element to record the use of an alternate +server certificate chain for the connection in question. This happens +when the client uses the TLS SNI extension, and the server selects +a non-default certificate chain based on the client's SNI value: +</p> + +<blockquote> +<pre> +postfix/smtpd[<i>process-id</i>]: + Untrusted TLS connection established from client.example[192.0.2.1] + to server.example: TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 + client-signature ECDSA (P-256) client-digest SHA256 +</pre> +</blockquote> + +<h2><a name="status"> What do "Anonymous", "Untrusted", etc. in +Postfix logging mean? </a> </h2> + +<p> The verification levels below are subject to man-in-the-middle +attacks to different degrees. If such attacks are a concern, then +the SMTP client will need to authenticate the remote SMTP server +in a sufficiently-secure manner. For example, by the fingerprint +of a (CA or leaf) public key or certificate. Remember that +conventional PKI relies on many trusted parties and is easily +subverted by a state-funded adversary. </p> + +<dl> + +<dt><b>Anonymous</b> (no peer certificate)</dt> + +<dd> <p> <b> Postfix SMTP client:</b> With opportunistic TLS (the "may" security level) the Postfix +SMTP client does not verify any information in the peer certificate. +In this case it enables and prefers anonymous cipher suites in which +the remote SMTP server does not present a certificate (these ciphers +offer forward secrecy of necessity). When the remote SMTP server +also supports anonymous TLS, and agrees to such a cipher suite, the +verification status will be logged as "Anonymous". </p> </dd> + +<dd> <p> <b> Postfix SMTP server:</b> This is by far most common, +as client certificates are optional, and the Postfix SMTP server +does not request client certificates by default (see smtpd_tls_ask_ccert). +Even when client certificates are requested, the remote SMTP client +might not send a certificate. Unlike the Postfix SMTP client, the +Postfix SMTP server "anonymous" verification status does not imply +that the cipher suite is anonymous, which corresponds to the +<i>server</i> not sending a certificate. </p> </dd> + +<dt><b>Untrusted</b> (peer certificate not signed by trusted CA)</dt> + +<dd> + +<p> <b> Postfix SMTP client:</b> The remote SMTP server presented +a certificate, but the Postfix SMTP client was unable to check the +issuing CA signature. With opportunistic TLS this is common with +remote SMTP servers that don't support anonymous cipher suites. +</p> + +<p> <b> Postfix SMTP server:</b> The remote SMTP client presented +a certificate, but the Postfix SMTP server was unable to check the +issuing CA signature. This can happen when the server is configured +to request client certificates (see smtpd_tls_ask_ccert). </p> + +</dd> + +<dt><b>Trusted</b> (peer certificate signed by trusted CA, unverified +peer name)</dt> + +<dd> + +<p> <b> Postfix SMTP client:</b> The remote SMTP server's certificate +was signed by a CA that the Postfix SMTP client trusts, but either +the client was not configured to verify the destination server name +against the certificate, or the server certificate did not contain +any matching names. This is common with opportunistic TLS +(smtp_tls_security_level is "may" or else "dane" with no usable +TLSA DNS records) when the Postfix SMTP client's trusted CAs can +verify the authenticity of the remote SMTP server's certificate, +but the client is not configured or unable to verify the server +name. </p> + +<p> <b> Postfix SMTP server:</b> The remote SMTP client certificate +was signed by a CA that the Postfix SMTP server trusts. The Postfix +SMTP server never verifies the remote SMTP client name against the +names in the client certificate. Since the client chooses to connect +to the server, the Postfix SMTP server has no expectation of a +particular client hostname. </p> + +</dd> + +<dt><b>Verified</b> (peer certificate signed by trusted CA and +verified peer name; or: peer certificate with expected public-key +or certificate fingerprint)</dt> + +<dd> + +<p> <b> Postfix SMTP client:</b> The remote SMTP server's certificate +was signed by a CA that the Postfix SMTP client trusts, and the +certificate name matches the destination or server name(s). The +Postfix SMTP client was configured to require a verified name, +otherwise the verification status would have been just "Trusted". +</p> + +<p> <b> Postfix SMTP client:</b> The "Verified" status may also +mean that the Postfix SMTP client successfully matched the expected +fingerprint against the remote SMTP server public key or certificate. +The expected fingerprint may come from smtp_tls_policy_maps or from +TLSA (secure) DNS records. The Postfix SMTP client ignores the CA +signature. </p> + +<p> <b> Postfix SMTP server:</b> The status is never "Verified", +because the Postfix SMTP server never verifies the remote SMTP +client name against the names in the client certificate, and because +the Postfix SMTP server does not expect a specific fingerprint in +the client public key or certificate. </p> + +</dd> + +</dl> + +<h2><a name="credits">Credits </a> </h2> + +<ul> + +<li> TLS support for Postfix was originally developed by Lutz +Jänicke at Cottbus Technical University. + +<li> Wietse Venema adopted and restructured the code and documentation. + +<li> Viktor Dukhovni implemented support for many subsequent TLS +features, including EECDH, and authored the initial version of this +document. + +</ul> + +</body> + +</html> diff --git a/proto/INSTALL.html b/proto/INSTALL.html new file mode 100644 index 0000000..71bcc4f --- /dev/null +++ b/proto/INSTALL.html @@ -0,0 +1,1676 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Installation From Source Code </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +Installation From Source Code </h1> + +<hr> + +<h2> <a name="1">1 - Purpose of this document</a> </h2> + +<p> If you are using a pre-compiled version of Postfix, you should +start with BASIC_CONFIGURATION_README and the general documentation +referenced by it. INSTALL is only a bootstrap document to get +Postfix up and running from scratch with the minimal number of +steps; it should not be considered part of the general documentation. +</p> + +<p> This document describes how to build, install and configure a +Postfix system so that it can do one of the following: </p> + +<ul> + +<li> Send mail only, without changing an existing Sendmail +installation. + +<li> Send and receive mail via a virtual host interface, still +without any change to an existing Sendmail installation. + +<li> Run Postfix instead of Sendmail. + +</ul> + +<p> Topics covered in this document: </p> + +<ol> + +<li> <a href="#1">Purpose of this document</a> + +<li> <a href="#2">Typographical conventions</a> + +<li> <a href="#3">Documentation</a> + +<li> <a href="#4">Building on a supported system</a> + +<li> <a href="#5">Porting Postfix to an unsupported system</a> + +<li> <a href="#install">Installing the software after successful +compilation </a> + +<li> <a href="#send_only">Configuring Postfix to send mail +only </a> + +<li> <a href="#send_receive">Configuring Postfix to send and +receive mail via virtual interface </a> + +<li> <a href="#replace">Running Postfix instead of Sendmail</a> + +<li> <a href="#mandatory">Mandatory configuration file edits</a> + +<li> <a href="#hamlet">To chroot or not to chroot</a> + +<li> <a href="#care">Care and feeding of the Postfix system</a> + +</ol> + +<h2> <a name="2">2 - Typographical conventions</a> </h2> + +<p> In the instructions below, a command written as </p> + +<blockquote> +<pre> +# command +</pre> +</blockquote> + +<p> should be executed as the superuser. </p> + +<p> A command written as </p> + +<blockquote> +<pre> +$ command +</pre> +</blockquote> + +<p> should be executed as an unprivileged user. </p> + +<h2> <a name="3">3 - Documentation</a> </h2> + +<p> Documentation is available as README files (start with the file +README_FILES/AAAREADME), as HTML web pages (point your browser to +"html/index.html") and as UNIX-style manual pages. </p> + +<p> You should view the README files with a pager such as more(1) +or less(1), because the files use backspace characters in order to +produce <b>bold</b> font. To print a README file without backspace +characters, use the col(1) command. For example: </p> + +<blockquote> +<pre> +$ col -bx <file | lpr +</pre> +</blockquote> + +<p> In order to view the manual pages before installing Postfix, +point your MANPATH environment variable to the "man" subdirectory; +be sure to use an absolute path. </p> + +<blockquote> +<pre> +$ export MANPATH; MANPATH="`pwd`/man:$MANPATH" +$ setenv MANPATH "`pwd`/man:$MANPATH" +</pre> +</blockquote> + +<p> Of particular interest is the postconf(5) manual page that +lists all the 500+ configuration parameters. The HTML version of +this text makes it easy to navigate around. </p> + +<p> All Postfix source files have their own built-in manual page. +Tools to extract those embedded manual pages are available in the +mantools directory. </p> + +<h2> <a name="4">4 - Building on a supported system</a> </h2> + +<p> Postfix development happens on FreeBSD and MacOS X, with regular +tests on Linux (Fedora, Ubuntu) and Solaris. Support for other +systems relies on feedback from their users, and may not always be +up-to-date. </p> + +<p> OpenBSD is partially supported. The libc resolver does not +implement the documented "internal resolver options which are [...] +set by changing fields in the _res structure" (documented in the +OpenBSD 5.6 resolver(3) manpage). This results in too many DNS +queries, and false positives for queries that should fail. </p> + +<!-- + +<p> At some point in time, a version of Postfix was supported on: </p> + +<blockquote> +<p> +AIX 3.2.5, 4.1.x, 4.2.0, 4.3.x, 5.2 <br> +BSD/OS 2.x, 3.x, 4.x <br> +FreeBSD 2.x .. 9.x <br> +HP-UX 9.x, 10.x, 11.x <br> +IRIX 5.x, 6.x <br> +Linux Debian 1.3.1 and later <br> +Linux RedHat 3.x (January 2004) and later <br> +Linux Slackware 3.x and later <br> +Linux SuSE 5.x and later <br> +Linux Ubuntu 4.10 and later<br> +Mac OS X <br> +NEXTSTEP 3.x <br> +NetBSD 1.x and later <br> +OPENSTEP 4.x <br> +OSF1.V3 - OSF1.V5 (Digital UNIX) <br> +Reliant UNIX 5.x <br> +SunOS 4.1.4 (March 2007) <br> +SunOS 5.4 - 5.10 (Solaris 2.4..10) <br> +Ultrix 4.x (well, that was long ago) <br> +</p> +</blockquote> + +<p> or something closely resemblant. </p> + +--> + +<p> Overview of topics: </p> + +<ul> + +<li><a href="#build_first">4.1 - Getting started</a> + +<li><a href="#build_cc">4.2 - What compiler to use</a> + +<li><a href="#build_pie">4.3 - Building with Postfix position-independent +executables (Postfix ≥ 3.0)</a> + +<li><a href="#build_dll">4.4 - Building with Postfix dynamically-linked +libraries and database plugins (Postfix ≥ 3.0)</a> + +<li><a href="#build_opt">4.5 - Building with optional features</a> + +<li><a href="#build_over">4.6 - Overriding built-in parameter default +settings</a> + +<li><a href="#build_other">4.7 - Overriding other compile-time +features</a> + +<li><a href="#build_proc">4.8 - Support for thousands of processes</a> + +<li><a href="#build_final">4.9 - Compiling Postfix, at last</a> + +</ul> + + +<h3><a name="build_first">4.1 - Getting started</a> </h3> + +<p> On Solaris, the "make" command and other development utilities +are in /usr/ccs/bin, so you MUST have /usr/ccs/bin in your command +search path. If these files do not exist, you need to install the +development packages first. </p> + +<p> If you need to build Postfix for multiple architectures from a +single source-code tree, use the "lndir" command to build a shadow +tree with symbolic links to the source files. </p> + +<p> If at any time in the build process you get messages like: "make: +don't know how to ..." you should be able to recover by running +the following command from the Postfix top-level directory: </p> + +<blockquote> +<pre> +$ make -f Makefile.init makefiles +</pre> +</blockquote> + +<p> If you copied the Postfix source code after building it on another +machine, it is a good idea to cd into the top-level directory and +first do this:</p> + +<blockquote> +<pre> +$ make tidy +</pre> +</blockquote> + +<p> This will get rid of any system dependencies left over from +compiling the software elsewhere. </p> + +<h3><a name="build_cc">4.2 - What compiler to use</a></h3> + +<p> To build with GCC, or with the native compiler if people told me +that is better for your system, just cd into the top-level Postfix +directory of the source tree and type: </p> + +<blockquote> +<pre> +$ make +</pre> +</blockquote> + +<p> To build with a non-default compiler, you need to specify the name +of the compiler. Here are a few examples: </p> + +<blockquote> +<pre> +$ make makefiles CC=/opt/SUNWspro/bin/cc (Solaris) +$ make + +$ make makefiles CC="/opt/ansic/bin/cc -Ae" (HP-UX) +$ make + +$ make makefiles CC="purify cc" +$ make +</pre> +</blockquote> + +<p> and so on. In some cases, optimization will be turned off +automatically. </p> + +<h3><a name="build_pie">4.3 - Building with Postfix position-independent +executables (Postfix ≥ 3.0)</a> </h3> + +<p> On some systems Postfix can be built with Position-Independent +Executables. PIE is used by the ASLR exploit mitigation technique +(ASLR = Address-Space Layout Randomization): </p> + +<blockquote> +<pre> +$ make makefiles pie=yes ...other arguments... +</pre> +</blockquote> + +<p> (Specify "make makefiles pie=no" to explicitly disable Postfix +position-independent executable support). </p> + +<p> Postfix PIE support appears to work on Fedora Core 20, Ubuntu +14.04, FreeBSD 9 and 10, and NetBSD 6 (all with the default system +compilers). </p> + +<p> Whether the "pie=yes" above has any effect depends on the +compiler. Some compilers always produce PIE executables, and some +may even complain that the Postfix build option is redundant. </p> + +<h3><a name="build_dll">4.4 - Building with Postfix dynamically-linked +libraries and database plugins (Postfix ≥ 3.0)</a> </h3> + +<p> Postfix dynamically-linked library and database plugin support +exists for recent versions of Linux, FreeBSD and MacOS X. +Dynamically-linked library builds may become the default at some +point in the future. </p> + +<p> Overview of topics: </p> + +<ul> + +<li><a href="#shared_enable">4.4.1 Turning on Postfix dynamically-linked +library support</a> + +<li><a href="#dynamicmaps_enable">4.4.2 Turning on Postfix database-plugin +support</a> + +<li><a href="#shared_custom">4.4.3 Customizing Postfix dynamically-linked +libraries and database plugins</a> + +<li><a href="#shared_tips">4.4.4 Tips for distribution maintainers</a> + +</ul> + +<p> Note: directories with Postfix dynamically-linked libraries +or database plugins should contain only postfix-related files. +Postfix dynamically-linked libraries and database plugins should +not be installed in a "public" system directory such as /usr/lib +or /usr/local/lib. Linking Postfix dynamically-linked library or +database-plugin files into non-Postfix programs is not supported. +Postfix dynamically-linked libraries and database plugins implement +a Postfix-internal API that changes without maintaining compatibility. +</p> + +<h4><a name="shared_enable"> 4.4.1 Turning on Postfix dynamically-linked +library support </a></h4> + +<p> Postfix can be built with Postfix dynamically-linked libraries +(files typically named <tt>libpostfix-*.so</tt>). Postfix +dynamically-linked libraries add minor run-time overhead and result +in significantly-smaller Postfix executable files. </p> + +<p> Specify "shared=yes" on the "make makefiles" command line to +build Postfix with dynamically-linked library support. </p> + +<blockquote> +<pre> +$ make makefiles shared=yes ...other arguments... +$ make +</pre> +</blockquote> + +<p> (Specify "make makefiles shared=no" to explicitly disable Postfix +dynamically-linked library support). </p> + +<p> This installs dynamically-linked libraries in $shlib_directory, +typically /usr/lib/postfix or /usr/local/lib/postfix, with file +names libpostfix-<i>name</i>.so, where the <i>name</i> is a source-code +directory name such as "util" or "global". </p> + +<p> See section 4.4.3 "<a href="#shared_custom">Customizing Postfix +dynamically-linked libraries and database plugins</a>" below for +how to customize the Postfix dynamically-linked library location, +including support to upgrade a running mail system safely. </p> + +<h4><a name="dynamicmaps_enable"> 4.4.2 Turning on Postfix +database-plugin support </a></h4> + +<p> Additionally, Postfix can be built to support dynamic loading +of Postfix database clients (database plugins) with the Debian-style +dynamicmaps feature. Postfix 3.0 supports dynamic loading of cdb:, +ldap:, lmdb:, mysql:, pcre:, pgsql:, sdbm:, and sqlite: database +clients. Dynamic loading is useful when you distribute or install +pre-compiled Postfix packages. </p> + +<p> Specify "dynamicmaps=yes" on the "make makefiles" command line +to build Postfix with support to dynamically load Postfix database +clients with the Debian-style dynamicmaps feature. +</p> + +<blockquote> +<pre> +$ make makefiles dynamicmaps=yes ...other arguments... +$ make +</pre> +</blockquote> + +<p> (Specify "make makefiles dynamicmaps=no" to explicitly disable +Postfix database-plugin support). </p> + +<p> This implicitly enables dynamically-linked library support, +installs the configuration file dynamicmaps.cf in $meta_directory +(usually, /etc/postfix or /usr/local/etc/postfix), and installs +database plugins in $shlib_directory (see above). Database plugins +are named postfix-<i>type</i>.so where the <i>type</i> is a database +type such as "cdb" or "ldap". </p> + +<blockquote> + +<p> NOTE: The Postfix 3.0 build procedure expects that you specify +database library dependencies with variables named AUXLIBS_CDB, +AUXLIBS_LDAP, etc. With Postfix 3.0 and later, the old AUXLIBS +variable still supports building a statically-loaded database client, +but only the new AUXLIBS_CDB etc. variables support building a +dynamically-loaded or statically-loaded CDB etc. database client. +See CDB_README, LDAP_README, etc. for details. </p> + +<p> Failure to follow this advice will defeat the purpose of dynamic +database client loading. Every Postfix executable file will have +database library dependencies. And that was exactly what dynamic +database client loading was meant to avoid. </p> + +</blockquote> + +<p> See the next section for how to customize the location and +version of Postfix database plugins and the location of the file +dynamicmaps.cf. </p> + +<h4><a name="shared_custom"> 4.4.3 Customizing Postfix dynamically-linked +libraries and database plugins </a></h4> + +<h5> Customizing build-time and run-time options for Postfix +dynamically-linked libraries and database plugins </h5> + +<p> The build-time environment variables SHLIB_CFLAGS, SHLIB_RPATH, +and SHLIB_SUFFIX provide control over how Postfix libraries and +plugins are compiled, linked, and named. + +<blockquote> +<pre> +$ make makefiles SHLIB_CFLAGS=flags SHLIB_RPATH=rpath SHLIB_SUFFIX=suffix ...other arguments... +$ make +</pre> +</blockquote> + +<p> See section 4.7 "<a href="#build_other">Overriding other +compile-time features</a>" below for details. </p> + +<h5> Customizing the location of Postfix dynamically-linked libraries +and database plugins </h5> + +<p> As a reminder, the directories with Postfix dynamically-linked +libraries or database plugins should contain only Postfix-related +files. Linking these files into other programs is not supported. +</p> + +<p> To override the default location of Postfix dynamically-linked +libraries and database plugins specify, for example: </p> + +<blockquote> +<pre> +$ make makefiles shared=yes shlib_directory=/usr/local/lib/postfix ... +</pre> +</blockquote> + +<p> If you intend to upgrade Postfix without stopping the mail +system, then you should append the Postfix release version to the +shlib_directory pathname, to eliminate the possibility that programs +will link with dynamically-linked libraries or database plugins +from the wrong Postfix version. For example: </p> + +<blockquote> +<pre> +$ make makefiles shared=yes \ + shlib_directory=/usr/local/lib/postfix/MAIL_VERSION ... +</pre> +</blockquote> + +<p> The command "make makefiles name=value..." will replace the +string MAIL_VERSION at the end of a configuration parameter value +with the Postfix release version. Do not try to specify something +like $mail_version on this command line. This produces inconsistent +results with different versions of the make(1) command. </p> + +<p> You can change the shlib_directory setting after Postfix is +built, with "make install" or "make upgrade". However, you may have +to run ldconfig if you change shlib_directory after Postfix is built +(the symptom is that Postfix programs fail because the run-time +linker cannot find the files libpostfix-*.so). No ldconfig command +is needed if you keep the files libpostfix-*.so in the compiled-in +default $shlib_directory location. </p> + +<blockquote> +<pre> +# make upgrade shlib_directory=/usr/local/lib/postfix ... +# make install shlib_directory=/usr/local/lib/postfix ... +</pre> +</blockquote> + +<p> To append the Postfix release version to the pathname if you +intend to upgrade Postfix without stopping the mail system: </p> + +<blockquote> +<pre> +# make upgrade shlib_directory=/usr/local/lib/postfix/MAIL_VERSION ... +# make install shlib_directory=/usr/local/lib/postfix/MAIL_VERSION ... +</pre> +</blockquote> + +<p> See also the comments above for appending MAIL_VERSION with +the "make makefiles" command. </p> + +<h5> Customizing the location of dynamicmaps.cf and other files +</h5> + +<p> The meta_directory parameter has the same default setting as +the config_directory parameter, typically /etc/postfix or +/usr/local/etc/postfix. </p> + +<p> You can override the default meta_directory location at compile +time or after Postfix is built. To override the default location +at compile time specify, for example: </p> + +<blockquote> +<pre> +% make makefiles meta_directory=/usr/libexec/postfix ... +</pre> +</blockquote> + +<p> Here is a tip if you want to make a pathname dependent on the +Postfix release version: the command "make makefiles name=value..." +will replace the string MAIL_VERSION at the end of a configuration +parameter value with the Postfix release version. Do not try to +specify something like $mail_version on this command line. This +produces inconsistent results with different versions of the make(1) +command. </p> + +<p> You can override the meta_directory setting after Postfix is +built, with "make install" or "make upgrade". </p> + +<blockquote> +<pre> +# make upgrade meta_directory=/usr/libexec/postfix ... +# make install meta_directory=/usr/libexec/postfix ... +</pre> +</blockquote> + +<p> As with the command "make makefiles", the command "make +install/upgrade name=value..." will replace the string MAIL_VERSION +at the end of a configuration parameter value with the Postfix +release version. Do not try to specify something like $mail_version +on this command line. This produces inconsistent results with +different versions of the make(1) command. </p> + +<h4><a name="shared_tips"> 4.4.4 Tips for distribution maintainers +</a></h4> + +<ul> + +<li> <p> The shlib_directory parameter setting also provides the +default directory for database plugin files with a relative pathname +in the file dynamicmaps.cf. </p> + +<li> <p> The meta_directory parameter specifies the location of the +files dynamicmaps.cf, postfix-files, and some multi-instance template +files. The meta_directory parameter has the same default value as +the config_directory parameter (typically, /etc/postfix or +/usr/local/etc/postfix). For backwards compatibility with Postfix +2.6 .. 2.11, specify "meta_directory = $daemon_directory" in main.cf +before installing or upgrading Postfix, or specify "meta_directory += /path/name" on the "make makefiles", "make install" or "make +upgrade" command line. </p> + +<li> <p> The configuration file dynamicmaps.cf will automatically +include files under the directory dynamicmaps.cf.d, just like the +configuration file postfix-files will automatically include files +under the directory postfix-files.d. Thanks to this, you can install +or deinstall a database plugin package without having to edit +postfix-files or dynamicmaps.cf. Instead, you give that plugin its +own configuration files under dynamicmaps.cf.d and postfix-files.d, and +you add or remove those configuration files along with the database +plugin dynamically-linked object. </p> + +<li> <p> Each configuration file under the directory dynamicmaps.cf.d +must have the same format as the configuration file dynamicmaps.cf. +There is no requirement that these configuration file *names* have a +specific format. </p> + +<li> <p> Each configuration file under the directory postfix-files.d +must have the same format as the configuration file postfix-files. +There is no requirement that these configuration file *names* have a +specific format. </p> + +</ul> + +<h3><a name="build_opt">4.5 - Building with optional features</a></h3> + +By default, Postfix builds as a mail system with relatively few +bells and whistles. Support for third-party databases etc. +must be configured when Postfix is compiled. The following documents +describe how to build Postfix with support for optional features: + +<blockquote> +<table border="1"> + +<tr> <th>Optional feature </th> <th>Document </th> <th>Availability</th> +</tr> + +<tr> <td> Berkeley DB database</td> <td>DB_README</td> <td> Postfix +1.0 </td> </tr> + +<tr> <td> LMDB database</td> <td>LMDB_README</td> <td> Postfix +2.11 </td> </tr> + +<tr> <td> LDAP database</td> <td>LDAP_README</td> <td> Postfix +1.0 </td> </tr> + +<tr> <td> MySQL database</td> <td>MYSQL_README</td> <td> Postfix +1.0 </td> </tr> + +<tr> <td> Perl compatible regular expression</td> <td>PCRE_README</td> +<td> Postfix 1.0 </td> </tr> + +<tr> <td> PostgreSQL database</td> <td>PGSQL_README</td> <td> +Postfix 2.0 </td> </tr> + +<tr> <td> SASL authentication </td> <td>SASL_README</td> <td> +Postfix 1.0 </td> </tr> + +<tr> <td> SQLite database</td> <td>SQLITE_README</td> <td> Postfix +2.8 </td> </tr> + +<tr> <td> STARTTLS session encryption </td> <td>TLS_README</td> <td> +Postfix 2.2 </td> </tr> + +</table> + +</blockquote> + +<p> Note: IP version 6 support is compiled into Postfix on operating +systems that have IPv6 support. See the IPV6_README file for details. +</p> + +<h3><a name="build_over">4.6 - Overriding built-in parameter default +settings</a></h3> + +<h4>4.6.1 - Postfix 3.0 and later </h4> + +<p> All Postfix configuration parameters can be changed by editing +a Postfix configuration file, except for one: the parameter that +specifies the location of Postfix configuration files. In order to +build Postfix with a configuration directory other than /etc/postfix, +use: </p> + +<blockquote> +<pre> +$ make makefiles config_directory=/some/where ...other arguments... +$ make +</pre> +</blockquote> + +<p> The command "make makefiles name=value ..." will replace the +string MAIL_VERSION at the end of a configuration parameter value +with the Postfix release version. Do not try to specify something +like $mail_version on this command line. This produces inconsistent +results with different versions of the make(1) command. </p> + +<p> Parameters whose defaults can be specified in this way are +listed below. See the postconf(5) manpage for a description +(command: "<tt>nroff -man man/man5/postconf.5 | less</tt>"). </p> + +<blockquote> + +<table border="1"> + +<tr> <th>parameter name</th> <th>typical default</th> </tr> + +<tr> <td>command_directory</td> <td>/usr/sbin</td> </tr> + +<tr> <td>config_directory</td> <td>/etc/postfix</td> </tr> + +<tr> <td>default_database_type</td> <td>hash</td> </tr> + +<tr> <td>daemon_directory</td> <td>/usr/libexec/postfix</td> </tr> + +<tr> <td>data_directory</td> <td>/var/lib/postfix</td> </tr> + +<tr> <td>html_directory</td> <td>no</td> </tr> + +<tr> <td>mail_spool_directory</td> <td>/var/mail</td> </tr> + +<tr> <td>mailq_path</td> <td>/usr/bin/mailq</td> </tr> + +<tr> <td>manpage_directory</td> <td>/usr/local/man</td> </tr> + +<tr> <td>meta_directory</td> <td>/etc/postfix</td> </tr> + +<tr> <td>newaliases_path</td> <td>/usr/bin/newaliases</td> </tr> + +<tr> <td>openssl_path</td> <td>openssl</td> </tr> + +<tr> <td>queue_directory</td> <td>/var/spool/postfix</td> </tr> + +<tr> <td>readme_directory</td> <td>no</td> </tr> + +<tr> <td>sendmail_path</td> <td>/usr/sbin/sendmail</td> </tr> + +<tr> <td>shlib_directory</td> <td>/usr/lib/postfix</td> </tr> + +</table> + +</blockquote> + +<h4>4.6.2 - All Postfix versions </h4> + +<p> All Postfix configuration parameters can be changed by editing +a Postfix configuration file, except for one: the parameter that +specifies the location of Postfix configuration files. In order to +build Postfix with a configuration directory other than /etc/postfix, +use: </p> + +<blockquote> +<pre> +$ make makefiles CCARGS='-DDEF_CONFIG_DIR=\"/some/where\"' +$ make +</pre> +</blockquote> + +<p> IMPORTANT: Be sure to get the quotes right. These details matter +a lot. </p> + +<p> Parameters whose defaults can be specified in this way are +listed below. See the postconf(5) manpage for a description +(command: "<tt>nroff -man man/man5/postconf.5 | less</tt>"). </p> + +<blockquote> + +<table border="1"> + +<tr><th> Macro name </th> <th>default value for</th> <th>typical +default</th> </tr> + +<tr> <td>DEF_COMMAND_DIR</td> <td>command_directory</td> +<td>/usr/sbin</td> </tr> + +<tr> <td>DEF_CONFIG_DIR</td> <td>config_directory</td> +<td>/etc/postfix</td> </tr> + +<tr> <td>DEF_DB_TYPE</td> <td>default_database_type</td> +<td>hash</td> </tr> + +<tr> <td>DEF_DAEMON_DIR</td> <td>daemon_directory</td> +<td>/usr/libexec/postfix</td> </tr> + +<tr> <td>DEF_DATA_DIR</td> <td>data_directory</td> +<td>/var/lib/postfix</td> </tr> + +<tr> <td>DEF_MAILQ_PATH</td> <td>mailq_path</td> <td>/usr/bin/mailq</td> +</tr> + +<tr> <td>DEF_HTML_DIR</td> <td>html_directory</td> +<td>no</td> </tr> + +<tr> <td>DEF_MANPAGE_DIR</td> <td>manpage_directory</td> +<td>/usr/local/man</td> </tr> + +<tr> <td>DEF_NEWALIAS_PATH</td> <td>newaliases_path</td> +<td>/usr/bin/newaliases</td> </tr> + +<tr> <td>DEF_QUEUE_DIR</td> <td>queue_directory</td> +<td>/var/spool/postfix</td> </tr> + +<tr> <td>DEF_README_DIR</td> <td>readme_directory</td> +<td>no</td> </tr> + +<tr> <td>DEF_SENDMAIL_PATH</td> <td>sendmail_path</td> +<td>/usr/sbin/sendmail</td> </tr> + +</table> + +</blockquote> + +<p> Note: the data_directory parameter (for caches and pseudo-random +numbers) was introduced with Postfix version 2.5. </p> + +<h3><a name="build_other">4.7 - Overriding other compile-time +features</a></h3> + +<p> The general method to override Postfix compile-time features +is as follows: </p> + +<blockquote> +<pre> +$ make makefiles name=value name=value... +$ make +</pre> +</blockquote> + +<p> The following is an extensive list of names and values. </p> + +<table border="1"> + +<tr> <th colspan="2"> Name/Value </th> <th> Description </th> </tr> + +<tr> <td colspan="2"> AUXLIBS="object_library..."</td> <td> Specifies +one or more non-default object libraries. Postfix 3.0 and later +specify some of their database library dependencies with AUXLIBS_CDB, +AUXLIBS_LDAP, AUXLIBS_LMDB, AUXLIBS_MYSQL, AUXLIBS_PCRE, AUXLIBS_PGSQL, +AUXLIBS_SDBM, and AUXLIBS_SQLITE, respectively. </td> </tr> + +<tr> <td colspan="2"> CC=compiler_command</td> <td> Specifies a +non-default compiler. On many systems, the default is <tt>gcc</tt>. +</td> </tr> + +<tr> <td colspan="2"> CCARGS="compiler_arguments..."</td> <td> +Specifies non-default compiler arguments, for example, a non-default +<tt>include</tt> directory. The following directives turn +off Postfix features at compile time:</td> </tr> + +<tr> <td> </td> <td> -DNO_DB </td> <td> Do not build with Berkeley +DB support. By default, Berkeley DB support is compiled in on +platforms that are known to support this feature. If you override +this, then you probably should also override DEF_DB_TYPE as described +in section 4.6. </td> </tr> + +<tr> <td> </td> <td> -DNO_DNSSEC </td> <td> Do not build with DNSSEC +support, even if the resolver library appears to support it. </td> +</tr> + +<tr> <td> </td> <td> -DNO_DEVPOLL </td> <td> Do not build with +Solaris <tt>/dev/poll</tt> support. By default, <tt>/dev/poll</tt> +support is compiled in on Solaris versions that are known to support +this feature. </td> </tr> + +<tr> <td> </td> <td> -DNO_EPOLL </td> <td> Do not build with Linux +EPOLL support. By default, EPOLL support is compiled in on platforms +that are known to support this feature. </td> </tr> + +<tr> <td> </td> <td> -DNO_EAI </td> <td> Do not build with EAI +(SMTPUTF8) support. By default, EAI support is compiled in when +the "icuuc" library and header files are found. </td> </tr> + +<tr> <td> </td> <td> -DNO_INLINE </td> <td> Do not require support +for C99 "inline" functions. Instead, implement argument typechecks +for non-printf/scanf-like functions with ternary operators and +unreachable code. </td> </tr> + +<tr> <td> </td> <td> -DNO_IPV6 </td> <td> Do not build with IPv6 +support. By default, IPv6 support is compiled in on platforms that +are known to have IPv6 support. Note: this directive is for debugging +And testing only. It is not guaranteed to work on all platforms. +If you don't want IPv6 support, set "inet_protocols = ipv4" in +main.cf. +</td> </tr> + +<tr> <td> </td> <td> -DNO_KQUEUE </td> <td> Do not build with FreeBSD +/ NetBSD / OpenBSD / MacOSX KQUEUE support. By default, KQUEUE +support is compiled in on platforms that are known to support it. +</td> </tr> + +<tr> <td> </td> <td> -DNO_NIS </td> <td> Do not build with NIS or +NISPLUS support. NIS is not available on some recent Linux +distributions. </td> </tr> + +<tr> <td> </td> <td> -DNO_NISPLUS </td> <td> Do not build with +NISPLUS support. NISPLUS is not available on some recent Solaris +distributions. </td> </tr> + +<tr> <td> </td> <td> -DNO_PCRE </td> <td> Do not build with PCRE +support. By default, PCRE support is compiled in when the +<tt>pcre-config</tt> utility is installed. </td> </tr> + +<tr> <td> </td> <td> -DNO_POSIX_GETPW_R </td> <td> Disable support +for POSIX <tt>getpwnam_r/getpwuid_r</tt>. By default Postfix uses +these where they are known to be available. </td> </tr> + +<tr> <td> </td> <td> -DNO_RES_NCALLS </td> <td> Do not build with +the threadsafe resolver(5) API (res_ninit() etc.). </td> </tr> + +<tr> <td> </td> <td> -DNO_SIGSETJMP </td> <td> Use +<tt>setjmp()/longjmp()</tt> instead of <tt>sigsetjmp()/siglongjmp()</tt>. +By default, Postfix uses <tt>sigsetjmp()/siglongjmp()</tt> when +they are known to be available. </td> </tr> + +<tr> <td> </td> <td> -DNO_SNPRINTF </td> <td> Use <tt>sprintf()</tt> +instead of <tt>snprintf()</tt>. By default, Postfix uses +<tt>snprintf()</tt> except on ancient systems. </td> </tr> + +<tr> <td colspan="2"> DEBUG=debug_level </td> <td> Specifies a +non-default compiler debugging level. The default is "<tt>-g</tt>". +Specify DEBUG= to turn off debugging. </td> </tr> + +<tr> <td colspan="2"> OPT=optimization_level </td> <td> Specifies +a non-default optimization level. The default is "<tt>-O</tt>". +Specify OPT= to turn off optimization. </td> </tr> + +<tr> <td colspan="2"> POSTFIX_INSTALL_OPTS=-option... </td> <td> +Specifies options for the <tt>postfix-install</tt> command, separated +by whitespace. Currently, the only supported option is +"<tt>-keep-build-mtime</tt>". </td> </tr> + +<tr> <td colspan="2"> SHLIB_CFLAGS=flags </td> <td> Specifies +non-default compiler options for building Postfix dynamically-linked +libraries and database plugins. The typical default is "-fPIC". +</td> </tr> + +<tr> <td colspan="2"> SHLIB_RPATH=rpath </td> <td> Specifies +a non-default runpath for Postfix dynamically-linked libraries. The +typical default is "'-Wl,-rpath,${SHLIB_DIR}'". </td> </tr> + +<tr> <td colspan="2"> SHLIB_SUFFIX=suffix </td> <td> Specifies +a non-default suffix for Postfix dynamically-linked libraries and +database plugins. The typical default is "<tt>.so</tt>". </td> +</tr> + +<tr> <td colspan="2"> WARN="warning_flags..." </td> <td> Specifies +non-default compiler warning options for use when "<tt>make</tt>" +is invoked in a source subdirectory only. </td> +</tr> + +</table> + +<h3><a name="build_proc">4.8 - Support for thousands of processes</a></h3> + +<p> The number of connections that Postfix can manage simultaneously +is limited by the number of processes that it can run. This number +in turn is limited by the number of files and sockets that a single +process can open. For example, the Postfix queue manager has a +separate connection to each delivery process, and the anvil(8) +server has one connection per smtpd(8) process. </p> + +<p> Postfix version 2.4 and later have no built-in limits on the +number of open files or sockets, when compiled on systems that +support one of the following: </p> + +<ul> + +<li> BSD kqueue(2) (FreeBSD 4.1, NetBSD 2.0, OpenBSD 2.9), + +<li> Solaris 8 /dev/poll, + +<li> Linux 2.6 epoll(4). + +</ul> + + +<p> With other Postfix versions or operating systems, the number +of file descriptors per process is limited by the value of the +FD_SETSIZE macro. If you expect to run more than 1000 mail delivery +processes, you may need to override the definition of the FD_SETSIZE +macro to make select() work correctly: </p> + +<blockquote> +<pre> +$ make makefiles CCARGS=-DFD_SETSIZE=2048 +</pre> +</blockquote> + +<p> Warning: the above has no effect on some Linux versions. +Apparently, on these systems the FD_SETSIZE value can be changed +only by using undocumented interfaces. Currently, that means +including <bits/types.h> directly (which is not allowed) and +overriding the __FD_SETSIZE macro. Beware, undocumented interfaces +can change at any time and without warning. </p> + +<p> But wait, there is more: none of this will work unless the +operating system is configured to handle thousands of connections. +See the TUNING_README guide for examples of how to increase the +number of open sockets or files. </p> + +<h3><a name="build_final">4.9 - Compiling Postfix, at last</a></h3> + +<p> If the command </p> + +<blockquote> +<pre> +$ make +</pre> +</blockquote> + +<p> is successful, then you can proceed to <a href="#install">install</a> +Postfix (section 6). + +<p> If the command produces compiler error messages, it may be time +to search the web or to ask the postfix-users@postfix.org mailing +list, but be sure to search the mailing list archives first. Some +mailing list archives are linked from http://www.postfix.org/. </p> + +<h2> <a name="5">5 - Porting Postfix to an unsupported system</a> </h2> + +<p> Each system type that Postfix knows is identified by a unique +name. Examples: SUNOS5, FREEBSD4, and so on. When porting Postfix +to a new system, the first step is to choose a SYSTEMTYPE name for +the new system. You must use a name that includes at least the +major version of the operating system (such as SUNOS4 or LINUX2), +so that different releases of the same system can be supported +without confusion. </p> + +<p> Add a case statement to the "makedefs" shell script in the +source code top-level directory that recognizes the new system +reliably, and that emits the right system-specific information. +Be sure to make the code robust against user PATH settings; if the +system offers multiple UNIX flavors (e.g. BSD and SYSV) be sure to +build for the native flavor, instead of the emulated one. </p> + +<p> Add an "#ifdef SYSTEMTYPE" section to the central util/sys_defs.h +include file. You may have to invent new feature macro names. +Please choose sensible feature macro names such as HAS_DBM or +FIONREAD_IN_SYS_FILIO_H. + +<p> I strongly recommend against using "#ifdef SYSTEMTYPE" in +individual source files. While this may look like the quickest +solution, it will create a mess when newer versions of the same +SYSTEMTYPE need to be supported. You're likely to end up placing +"#ifdef" sections all over the source code again. </p> + +<h2><a name="install">6 - Installing the software after successful +compilation</a></h2> + +<p> This text describes how to install Postfix from source code. +See the PACKAGE_README file if you are building a package for +distribution to other systems. </p> + +<h3>6.1 - Save existing Sendmail binaries</h3> + +<p> <a name="save">IMPORTANT</a>: if you are REPLACING an existing +Sendmail installation with Postfix, you may need to keep the old +sendmail program running for some time in order to flush the mail +queue. </p> + +<ul> + +<li> <p> Some systems implement a mail switch mechanism where +different MTAs (Postfix, Sendmail, etc.) can be installed at the +same time, while only one of them is actually being used. Examples +of such switching mechanisms are the FreeBSD mailwrapper(8) or the +Linux mail switch. In this case you should try to "flip" the switch +to "Postfix" before installing Postfix. </p> + +<li> <p> If your system has no mail switch mechanism, execute the +following commands (your sendmail, newaliases and mailq programs +may be in a different place): </p> + +<pre> +# mv /usr/sbin/sendmail /usr/sbin/sendmail.OFF +# mv /usr/bin/newaliases /usr/bin/newaliases.OFF +# mv /usr/bin/mailq /usr/bin/mailq.OFF +# chmod 755 /usr/sbin/sendmail.OFF /usr/bin/newaliases.OFF \ + /usr/bin/mailq.OFF +</pre> + +</ul> + +<h3>6.2 - Create account and groups</h3> + +<p> Before you install Postfix for the first time you need to +create an account and a group:</p> + +<ul> + +<li> <p> Create a user account "postfix" with a user id and group +id that are not used by any other user account. Preferably, this +is an account that no-one can log into. The account does not need +an executable login shell, and needs no existing home directory. +My password and group file entries look like this: </p> + +<blockquote> +<pre> +/etc/passwd: + postfix:*:12345:12345:postfix:/no/where:/no/shell + +/etc/group: + postfix:*:12345: +</pre> +</blockquote> + +<p> Note: there should be no whitespace before "postfix:". </p> + +<li> <p> Create a group "postdrop" with a group id that is not used +by any other user account. Not even by the postfix user account. +My group file entry looks like: + +<blockquote> +<pre> +/etc/group: + postdrop:*:54321: +</pre> +</blockquote> + +<p> Note: there should be no whitespace before "postdrop:". </p> + +</ul> + +<h3>6.3 - Install Postfix</h3> + +<p> To install or upgrade Postfix from compiled source code, run +one of the following commands as the super-user:</p> + +<blockquote> +<pre> +# make install (interactive version, first time install) + +# make upgrade (non-interactive version, for upgrades) +</pre> +</blockquote> + +<ul> + +<li> <p> The interactive version ("make install") asks for pathnames +for Postfix data and program files, and stores your preferences in +the main.cf file. <b> If you don't want Postfix to overwrite +non-Postfix "sendmail", "mailq" and "newaliases" files, specify +pathnames that end in ".postfix"</b>. </p> + +<li> <p> The non-interactive version ("make upgrade") needs the +/etc/postfix/main.cf file from a previous installation. If the file +does not exist, use interactive installation ("make install") +instead. </p> + +<li> <p> If you specify name=value arguments on the "make install" +or "make upgrade" command line, then these will take precedence +over compiled-in default settings or main.cf settings. </p> + +<p> The command "make install/upgrade name=value ..." will replace +the string MAIL_VERSION at the end of a configuration parameter +value with the Postfix release version. Do not try to specify +something like $mail_version on this command line. This produces +inconsistent results with different versions of the make(1) command. +</p> + +</ul> + +<h3>6.4 - Configure Postfix</h3> + +<p> Proceed to the section on how you wish to run Postfix on +your particular machine: </p> + +<ul> + +<li> <p> <a href="#send_only">Send</a> mail only, without changing +an existing Sendmail installation (section 7). </p> + +<li> <p> <a href="#send_receive">Send and receive</a> mail via a +virtual host interface, still without any change to an existing +Sendmail installation (section 8). </p> + +<li> <p> Run Postfix <a href="#replace">instead of</a> Sendmail +(section 9). </p> + +</ul> + +<h2><a name="send_only">7 - Configuring Postfix to send mail +only</a></h2> + +<p> If you are going to use Postfix to send mail only, there is no +need to change your existing sendmail setup. Instead, set up your +mail user agent so that it calls the Postfix sendmail program +directly. </p> + +<p> Follow the instructions in the "<a href="#mandatory">Mandatory +configuration file edits</a>" in section 10, and review the "<a +href="#hamlet">To chroot or not to chroot</a>" text in section +11. </p> + +<p> You MUST comment out the "smtp inet" entry in /etc/postfix/master.cf, +in order to avoid conflicts with the real sendmail. Put a "#" +character in front of the line that defines the smtpd service: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + #smtp inet n - n - - smtpd +</pre> +</blockquote> + +<p> Start the Postfix system: </p> + +<blockquote> +<pre> +# postfix start +</pre> +</blockquote> + +<p> or, if you feel nostalgic, use the Postfix sendmail command: </p> + +<blockquote> +<pre> +# sendmail -bd -qwhatever +</pre> +</blockquote> + +<p> and watch your maillog file for any error messages. The pathname +is /var/log/maillog, /var/log/mail, /var/log/syslog, or something +else. Typically, the pathname is defined in the /etc/syslog.conf +file. </p> + +<blockquote> +<pre> +$ egrep '(reject|warning|error|fatal|panic):' /some/log/file +</pre> +</blockquote> + +<p> Note: the most important error message is logged first. Later +messages are not as useful. </p> + +<p> In order to inspect the mail queue, use one of the following +commands: </p> + +<blockquote> +<pre> +$ mailq + +$ sendmail -bp + +$ postqueue -p +</pre> +</blockquote> + +<p> See also the "<a href="#care">Care and feeding</a>" section 12 +below. </p> + +<h2><a name="send_receive">8 - Configuring Postfix to send and +receive mail via virtual interface</a></h2> + +<p> Alternatively, you can use the Postfix system to send AND +receive mail while leaving your Sendmail setup intact, by running +Postfix on a virtual interface address. Simply configure your mail +user agent to directly invoke the Postfix sendmail program. </p> + +<p> To create a virtual network interface address, study your +system ifconfig manual page. The command syntax could be any +of: </p> + +<blockquote> +<pre> +# <b>ifconfig le0:1 <address> netmask <mask> up</b> +# <b>ifconfig en0 alias <address> netmask 255.255.255.255</b> +</pre> +</blockquote> + +<p> In the /etc/postfix/main.cf file, I would specify </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + myhostname = virtual.host.tld + inet_interfaces = $myhostname + mydestination = $myhostname +</pre> +</blockquote> + +<p> Follow the instructions in the "<a href="#mandatory">Mandatory +configuration file edits</a>" in section 10, and review the "<a +href="#hamlet">To chroot or not to chroot</a>" text in section +11. </p> + +<p> Start the Postfix system: </p> + +<blockquote> +<pre> +# postfix start +</pre> +</blockquote> + +<p> or, if you feel nostalgic, use the Postfix sendmail command: </p> + +<blockquote> +<pre> +# sendmail -bd -qwhatever +</pre> +</blockquote> + +<p> and watch your maillog file for any error messages. The pathname +is /var/log/maillog, /var/log/mail, /var/log/syslog, or something +else. Typically, the pathname is defined in the /etc/syslog.conf +file. </p> + +<blockquote> +<pre> +$ egrep '(reject|warning|error|fatal|panic):' /some/log/file +</pre> +</blockquote> + +<p> Note: the most important error message is logged first. Later +messages are not as useful. </p> + +<p> In order to inspect the mail queue, use one of the following +commands: </p> + +<blockquote> +<pre> +$ mailq + +$ sendmail -bp + +$ postqueue -p +</pre> +</blockquote> + +<p> See also the "<a href="#care">Care and feeding</a>" section 12 +below. </p> + +<h2><a name="replace">9 - Running Postfix instead of Sendmail</a></h2> + +<p> Prior to installing Postfix you should <a href="#save">save</a> +any existing sendmail program files as described in section 6. Be +sure to keep the old sendmail running for at least a couple days +to flush any unsent mail. To do so, stop the sendmail daemon and +restart it as: </p> + +<blockquote> +<pre> +# /usr/sbin/sendmail.OFF -q +</pre> +</blockquote> + +<p> Note: this is old sendmail syntax. Newer versions use separate +processes for mail submission and for running the queue. </p> + +<p> After you have visited the "<a href="#mandatory">Mandatory +configuration file edits</a>" section below, you can start the +Postfix system with: </p> + +<blockquote> +<pre> +# postfix start +</pre> +</blockquote> + +<p> or, if you feel nostalgic, use the Postfix sendmail command: </p> + +<blockquote> +<pre> +# sendmail -bd -qwhatever +</pre> +</blockquote> + +<p> and watch your maillog file for any error messages. The pathname +is /var/log/maillog, /var/log/mail, /var/log/syslog, or something +else. Typically, the pathname is defined in the /etc/syslog.conf +file. </p> + +<blockquote> +<pre> +$ egrep '(reject|warning|error|fatal|panic):' /some/log/file +</pre> +</blockquote> + +<p> Note: the most important error message is logged first. Later +messages are not as useful. </p> + +<p> In order to inspect the mail queue, use one of the following +commands: </p> + +<blockquote> +<pre> +$ mailq + +$ sendmail -bp + +$ postqueue -p +</pre> +</blockquote> + +<p> See also the "<a href="#care">Care and feeding</a>" section 12 +below. </p> + +<h2><a name="mandatory">10 - Mandatory configuration file edits</a></h2> + +<p> Note: the material covered in this section is covered in more +detail in the BASIC_CONFIGURATION_README document. The information +presented below is targeted at experienced system administrators. +</p> + +<h3>10.1 - Postfix configuration files</h3> + +<p> By default, Postfix configuration files are in /etc/postfix. +The two most important files are main.cf and master.cf; these files +must be owned by root. Giving someone else write permission to +main.cf or master.cf (or to their parent directories) means giving +root privileges to that person. </p> + +<p> In /etc/postfix/main.cf, you will have to set up a minimal number +of configuration parameters. Postfix configuration parameters +resemble shell variables, with two important differences: the first +one is that Postfix does not know about quotes like the UNIX shell +does.</p> + +<p> You specify a configuration parameter as: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + parameter = value +</pre> +</blockquote> + +<p> and you use it by putting a "$" character in front of its name: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + other_parameter = $parameter +</pre> +</blockquote> + +<p> You can use $parameter before it is given a value (that is the +second main difference with UNIX shell variables). The Postfix +configuration language uses lazy evaluation, and does not look at +a parameter value until it is needed at runtime. </p> + +<p> Whenever you make a change to the main.cf or master.cf file, +execute the following command in order to refresh a running mail +system: </p> + +<blockquote> +<pre> +# postfix reload +</pre> +</blockquote> + +<h3>10.2 - Default domain for unqualified addresses</h3> + +<p> First of all, you must specify what domain will be appended to an +unqualified address (i.e. an address without @domain.tld). The +"myorigin" parameter defaults to the local hostname, but that is +probably OK only for very small sites. </p> + +<p> Some examples (use only one): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + myorigin = $myhostname (send mail as "user@$myhostname") + myorigin = $mydomain (send mail as "user@$mydomain") +</pre> +</blockquote> + +<h3>10.3 - What domains to receive locally</h3> + +<p> Next you need to specify what mail addresses Postfix should deliver +locally. </p> + +<p> Some examples (use only one): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + mydestination = $myhostname, localhost.$mydomain, localhost + mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain + mydestination = $myhostname +</pre> +</blockquote> + +<p>The first example is appropriate for a workstation, the second +is appropriate for the mailserver for an entire domain. The third +example should be used when running on a virtual host interface.</p> + +<h3>10.4 - Proxy/NAT interface addresses </h3> + +<p> The proxy_interfaces parameter specifies all network addresses +that Postfix receives mail on by way of a proxy or network address +translation unit. You may specify symbolic hostnames instead of +network addresses. </p> + +<p> IMPORTANT: You must specify your proxy/NAT external addresses +when your system is a backup MX host for other domains, otherwise +mail delivery loops will happen when the primary MX host is down. +</p> + +<p> Example: host behind NAT box running a backup MX host. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + proxy_interfaces = 1.2.3.4 (the proxy/NAT external network address) +</pre> +</blockquote> + +<h3>10.5 - What local clients to relay mail from </h3> + +<p> If your machine is on an open network then you must specify +what client IP addresses are authorized to relay their mail through +your machine into the Internet. The default setting includes all +subnetworks that the machine is attached to. This may give relay +permission to too many clients. My own settings are: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + mynetworks = 168.100.189.0/28, 127.0.0.0/8 +</pre> +</blockquote> + +<h3>10.6 - What relay destinations to accept from strangers </h3> + +<p> If your machine is on an open network then you must also specify +whether Postfix will forward mail from strangers. The default +setting will forward mail to all domains (and subdomains of) what +is listed in $mydestination. This may give relay permission for +too many destinations. Recommended settings (use only one): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + relay_domains = (do not forward mail from strangers) + relay_domains = $mydomain (my domain and subdomains) + relay_domains = $mydomain, other.domain.tld, ... +</pre> +</blockquote> + +<h3>10.7 - Optional: configure a smart host for remote delivery</h3> + +<p> If you're behind a firewall, you should set up a relayhost. If +you can, specify the organizational domain name so that Postfix +can use DNS lookups, and so that it can fall back to a secondary +MX host when the primary MX host is down. Otherwise just specify +a hard-coded hostname. </p> + +<p> Some examples (use only one): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + relayhost = $mydomain + relayhost = [mail.$mydomain] +</pre> +</blockquote> + +<p> The form enclosed with <tt>[]</tt> eliminates DNS MX lookups. </p> + +<p> By default, the SMTP client will do DNS lookups even when you +specify a relay host. If your machine has no access to a DNS server, +turn off SMTP client DNS lookups like this: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + disable_dns_lookups = yes +</pre> +</blockquote> + +<p> The STANDARD_CONFIGURATION_README file has more hints and tips for +firewalled and/or dial-up networks. </p> + +<h3>10.8 - Create the aliases database</h3> + +<p> Postfix uses a Sendmail-compatible aliases(5) table to redirect +mail for local(8) recipients. Typically, this information is kept +in two files: in a text file /etc/aliases and in an indexed file +/etc/aliases.db. The command "postconf alias_maps" will tell you +the exact location of the text file. </p> + +<p> First, be sure to update the text file with aliases for root, +postmaster and "postfix" that forward mail to a real person. Postfix +has a sample aliases file /etc/postfix/aliases that you can adapt +to local conditions. </p> + +<blockquote> +<pre> +/etc/aliases: + root: you + postmaster: root + postfix: root + bin: root + <i>etcetera...</i> +</pre> +</blockquote> + +<p> Note: there should be no whitespace before the ":". </p> + +<p> Finally, build the indexed aliases file with one of the +following commands: </p> + +<blockquote> +<pre> +# newaliases +# sendmail -bi +# postalias /etc/aliases (pathname is system dependent!) +</pre> +</blockquote> + +<h2><a name="hamlet">11 - To chroot or not to chroot</a></h2> + +<p> Postfix daemon processes can be configured (via master.cf) to +run in a chroot jail. The processes run at a fixed low privilege +and with access only to the Postfix queue directories (/var/spool/postfix). +This provides a significant barrier against intrusion. The barrier +is not impenetrable, but every little bit helps. </p> + +<p> With the exception of Postfix daemons that deliver mail locally +and/or that execute non-Postfix commands, every Postfix daemon can +run chrooted. </p> + +<p> Sites with high security requirements should consider to chroot +all daemons that talk to the network: the smtp(8) and smtpd(8) +processes, and perhaps also the lmtp(8) client. The author's own +porcupine.org mail server runs all daemons chrooted that can be +chrooted. </p> + +<p> The default /etc/postfix/master.cf file specifies that no +Postfix daemon runs chrooted. In order to enable chroot operation, +edit the file /etc/postfix/master.cf. Instructions are in the file. +</p> + +<p> Note that a chrooted daemon resolves all filenames relative to +the Postfix queue directory (/var/spool/postfix). For successful +use of a chroot jail, most UNIX systems require you to bring in +some files or device nodes. The examples/chroot-setup directory +in the source code distribution has a collection of scripts that +help you set up Postfix chroot environments on different operating +systems. </p> + +<p> Additionally, you almost certainly need to configure syslogd +so that it listens on a socket inside the Postfix queue directory. +Examples for specific systems: </p> + +<dl> + +<dt> FreeBSD: </dt> + +<dd> <pre> +# mkdir -p /var/spool/postfix/var/run +# syslogd -l /var/spool/postfix/var/run/log +</pre> </dd> + +<dt> Linux, OpenBSD: </dt> + +<dd> <pre> +# mkdir -p /var/spool/postfix/dev +# syslogd -a /var/spool/postfix/dev/log +</pre> </dd> + +</dl> + +<h2><a name="care">12 - Care and feeding of the Postfix system</a></h2> + +<p> Postfix daemon processes run in the background, and log problems +and normal activity to the syslog daemon. The names of logfiles +are specified in /etc/syslog.conf. At the very least you need +something like: </p> + +<blockquote> +<pre> +/etc/syslog.conf: + mail.err /dev/console + mail.debug /var/log/maillog +</pre> +</blockquote> + +<p> IMPORTANT: the syslogd will not create files. You must create +them before (re)starting syslogd. </p> + +<p> IMPORTANT: on Linux you need to put a "-" character before +the pathname, e.g., -/var/log/maillog, otherwise the syslogd +will use more system resources than Postfix does. </p> + +<p> Hopefully, the number of problems will be small, but it is a good +idea to run every night before the syslog files are rotated: </p> + +<blockquote> +<pre> +# postfix check +# egrep '(reject|warning|error|fatal|panic):' /some/log/file +</pre> +</blockquote> + +<ul> + +<li> <p> The first line (postfix check) causes Postfix to report +file permission/ownership discrepancies. </p> + +<li> <p> The second line looks for problem reports from the mail +software, and reports how effective the relay and junk mail access +blocks are. This may produce a lot of output. You will want to +apply some postprocessing to eliminate uninteresting information. +</p> + +</ul> + +<p> The <a href="DEBUG_README.html#logging"> DEBUG_README </a> +document describes the meaning of the "warning" etc. labels in +Postfix logging. </p> + +</body> + +</html> diff --git a/proto/IPV6_README.html b/proto/IPV6_README.html new file mode 100644 index 0000000..01ea51b --- /dev/null +++ b/proto/IPV6_README.html @@ -0,0 +1,360 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix IPv6 Support</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +IPv6 Support</h1> + +<hr> + +<h2>Introduction</h2> + +<p> Postfix 2.2 introduces support for the IPv6 (IP version 6) +protocol. IPv6 support for older Postfix versions was available as +an add-on patch. The section "<a href="#compat">Compatibility with +Postfix <2.2 IPv6 support</a>" below discusses the differences +between these implementations. </p> + +<p> The main feature of interest is that IPv6 uses 128-bit IP +addresses instead of the 32-bit addresses used by IPv4. It can +therefore accommodate a much larger number of hosts and networks +without ugly kluges such as NAT. A side benefit of the much larger +address space is that it makes random network scanning impractical. +</p> + +<p> Postfix uses the same SMTP protocol over IPv6 as it already +uses over the older IPv4 network, and does AAAA record lookups in +the DNS in addition to the older A records. Information about IPv6 +can be found at http://www.ipv6.org/. </p> + +<p> This document provides information on the following topics: +</p> + +<ul> + +<li><a href="#platforms">Supported platforms</a> + +<li><a href="#configuration">Configuration</a> + +<li><a href="#limitations">Known limitations</a> + +<li><a href="#compat">Compatibility with Postfix <2.2 IPv6 support</a> + +<li><a href="#porting">IPv6 Support for unsupported platforms</a> + +<li><a href="#credits">Credits</a> + +</ul> + +<h2><a name="platforms">Supported Platforms</a></h2> + +<p> Postfix version 2.2 supports IPv4 and IPv6 on the following +platforms: </p> + +<ul> + +<li> AIX 5.1+ +<li> Darwin 7.3+ +<li> FreeBSD 4+ +<li> Linux 2.4+ +<li> NetBSD 1.5+ +<li> OpenBSD 2+ +<li> Solaris 8+ +<li> Tru64Unix V5.1+ + +</ul> + +<p> On other platforms Postfix will simply use IPv4 as it has always +done. </p> + +<p> See <a href="#porting">below</a> for tips how to port Postfix +IPv6 support to other environments. </p> + +<h2><a name="configuration">Configuration</a></h2> + +<p> Postfix IPv6 support introduces two new main.cf configuration +parameters, and introduces an important change in address syntax +notation in match lists such as mynetworks or +debug_peer_list. </p> + +<p> Postfix IPv6 address syntax is a little tricky, because there +are a few places where you must enclose an IPv6 address inside +"<tt>[]</tt>" characters, and a few places where you must not. It is +a good idea to use "<tt>[]</tt>" only in the few places where you +have to. Check out the postconf(5) manual whenever you do IPv6 +related configuration work with Postfix. </p> + +<ul> + +<li> <p> Instead of hard-coding 127.0.0.1 and ::1 loopback addresses +in master.cf, specify "inet_interfaces = loopback-only" in main.cf. +This way you can use the same master.cf file regardless of whether +or not Postfix will run on an IPv6-enabled system. </p> + +<li> <p> The first new parameter is called inet_protocols. This +specifies what protocols Postfix will use when it makes or accepts +network connections, and also controls what DNS lookups Postfix +will use when it makes network connections. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # You must stop/start Postfix after changing this parameter. + inet_protocols = all (enable IPv4, and IPv6 if supported) + inet_protocols = ipv4 (enable IPv4 only) + inet_protocols = ipv4, ipv6 (enable both IPv4 and IPv6) + inet_protocols = ipv6 (enable IPv6 only) +</pre> +</blockquote> + +<p> The default is compile-time dependent: "all" when Postfix is built +on a software distribution with IPv6 support, "ipv4" otherwise. </p> + +<p> Note 1: you must stop and start Postfix after changing the +inet_protocols configuration parameter. </p> + +<p> Note 2: on older Linux and Solaris systems, the setting +"inet_protocols = ipv6" will not prevent Postfix from +accepting IPv4 connections. </p> + +<li> <p> The other new parameter is smtp_bind_address6. +This sets the local interface address for outgoing IPv6 SMTP +connections, just like the smtp_bind_address parameter +does for IPv4: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_bind_address6 = 2001:240:587:0:250:56ff:fe89:1 +</pre> +</blockquote> + +<li> <p> If you left the value of the mynetworks parameter at its +default (i.e. no mynetworks setting in main.cf) Postfix will figure +out by itself what its network addresses are. This is what a typical +setting looks like: </p> + +<blockquote> +<pre> +% postconf mynetworks +mynetworks = 127.0.0.0/8 168.100.189.0/28 [::1]/128 [fe80::]/10 [2001:240:587::]/64 +</pre> +</blockquote> + +<p> If you did specify the mynetworks parameter value in +main.cf, you need to update the mynetworks value to include +the IPv6 networks the system is in. Be sure to specify IPv6 address +information inside "<tt>[]</tt>", like this: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + mynetworks = ...<i>IPv4 networks</i>... [::1]/128 [2001:240:587::]/64 ... +</pre> +</blockquote> + +</ul> + +<p> <b> NOTE: when configuring Postfix match lists such as +mynetworks or debug_peer_list, you must specify +IPv6 address information inside "<tt>[]</tt>" in the main.cf parameter +value and in files specified with a "<i>/file/name</i>" pattern. +IPv6 addresses contain the ":" character, and would otherwise be +confused with a "<i>type:table</i>" pattern. </b> </p> + +<h2><a name="limitations">Known Limitations</a></h2> + +<ul> + +<li> <p> Postfix SMTP clients before version 2.8 try to connect +over IPv6 before trying IPv4. With more recent Postfix versions, +the order of IPv6 versus IPv4 outgoing connection attempts is +configurable with the smtp_address_preference parameter. </p> + +<li> <p> Postfix versions before 2.6 do not support DNSBL (DNS +blocklist) lookups for IPv6 client IP addresses. </p> + +<li> <p> IPv6 does not have class A, B, C, etc. networks. With IPv6 +networks, the setting "mynetworks_style = class" has the +same effect as the setting "mynetworks_style = subnet". +</p> + +<li> <p> On Tru64Unix and AIX, Postfix can't figure out the local +subnet mask +and always assumes a /128 network. This is a problem only with +"mynetworks_style = subnet" and no explicit mynetworks +setting in main.cf. </p> + +</ul> + +<h2> <a name="compat">Compatibility with Postfix <2.2 IPv6 support</a> +</h2> + +<p> Postfix version 2.2 IPv6 support is based on the Postfix/IPv6 patch +by Dean Strik and others, but differs in a few minor ways. </p> + +<ul> + +<li> <p> main.cf: The inet_interfaces parameter does not support +the notation "ipv6:all" or "ipv4:all". Use the +inet_protocols parameter instead. </p> + +<li> <p> main.cf: Specify "inet_protocols = all" or +"inet_protocols = ipv4, ipv6" in order to enable both IPv4 +and IPv6 support. </p> + +<li> <p> main.cf: The inet_protocols parameter also controls +what DNS lookups Postfix will attempt to make when delivering or +receiving mail. </p> + +<li> <p> main.cf: Specify "inet_interfaces = loopback-only" +to listen on loopback network interfaces only. </p> + +<li> <p> The lmtp_bind_address and lmtp_bind_address6 +features were omitted. Postfix version 2.3 merged the LMTP client +into the SMTP client, so there was no reason to keep adding features +to the LMTP client. </p> + +<li> <p> The SMTP server now requires that IPv6 addresses in SMTP +commands are specified as [ipv6:<i>ipv6address</i>], as +described in RFC 2821. </p> + +<li> <p> The IPv6 network address matching code was rewritten from +the ground up, and is expected to be closer to the specification. +The result may be incompatible with the Postfix/IPv6 patch. +</p> + +</ul> + +<h2><a name="porting">IPv6 Support for unsupported platforms</a></h2> + +<p> Getting Postfix IPv6 working on other platforms involves the +following steps: </p> + +<ul> + +<li> <p> Specify how Postfix should find the local network interfaces. +Postfix needs this information to avoid mailer loops and to find out +if mail for <i>user@[ipaddress]</i> is a local or remote destination. </p> + +<p> If your system has the getifaddrs() routine then add +the following to your platform-specific section in +src/util/sys_defs.h: </p> + +<blockquote> +<pre> +#ifndef NO_IPV6 +# define HAS_IPV6 +# define HAVE_GETIFADDRS +#endif +</pre> +</blockquote> + +<p> Otherwise, if your system has the SIOCGLIF ioctl() +command in /usr/include/*/*.h, add the following to your +platform-specific section in src/util/sys_defs.h: </p> + +<blockquote> +<pre> +#ifndef NO_IPV6 +# define HAS_IPV6 +# define HAS_SIOCGLIF +#endif +</pre> +</blockquote> + +<p> Otherwise, Postfix will have to use the old SIOCGIF commands +and get along with reduced IPv6 functionality (it won't be able to +figure out your IPv6 netmasks, which are needed for "mynetworks_style += subnet". Add this to your platform-specific section in +src/util/sys_defs.h: </p> + +<blockquote> +<pre> +#ifndef NO_IPV6 +# define HAS_IPV6 +#endif +</pre> +</blockquote> + +<li> <p> Test if Postfix can figure out its interface information. </p> + +<p> After compiling Postfix in the usual manner, step into the +src/util directory and type "<b>make inet_addr_local</b>". +Running this file by hand should produce all the interface addresses +and network masks, for example: </p> + +<blockquote> +<pre> +% make +% cd src/util +% make inet_addr_local +[... some messages ...] +% ./inet_addr_local +[... some messages ...] +./inet_addr_local: inet_addr_local: configured 2 IPv4 addresses +./inet_addr_local: inet_addr_local: configured 4 IPv6 addresses +168.100.189.2/255.255.255.224 +127.0.0.1/255.0.0.0 +fe80:1::2d0:b7ff:fe88:2ca7/ffff:ffff:ffff:ffff:: +2001:240:587:0:2d0:b7ff:fe88:2ca7/ffff:ffff:ffff:ffff:: +fe80:5::1/ffff:ffff:ffff:ffff:: +::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +</pre> +</blockquote> + +<p> The above is for an old FreeBSD machine. Other systems produce +slightly different results, but you get the idea. </p> + +</ul> + +<p> If none of all this produces a usable result, send email to the +postfix-users@postfix.org mailing list and we'll try to help you +through this. </p> + +<h2><a name="credits">Credits</a></h2> + +<p> The following information is in part based on information that +was compiled by Dean Strik. </p> + +<ul> + +<li> <p> Mark Huizer wrote the original Postfix IPv6 patch. </p> + +<li> <p> Jun-ichiro 'itojun' Hagino of the KAME project made +substantial improvements. Since then, we speak of the KAME patch. +</p> + +<li> <p> The PLD Linux Distribution ported the code to other stacks +(notably USAGI). We speak of the PLD patch. A very important +feature of the PLD patch was that it can work with Lutz Jaenicke's +TLS patch for Postfix. </p> + +<li> <p> Dean Strik extended IPv6 support to platforms other than +KAME and USAGI, updated the patch to keep up with Postfix development, +and provided a combined IPv6 + TLS patch. Information about his +effort can be found on Dean Strik's Postfix website at +http://www.ipnet6.org/postfix/. </p> + +<li> <p> Wietse Venema took Dean Strik's IPv6 patch, merged it into +Postfix 2.2, and took the opportunity to eliminate all IPv4-specific +code from Postfix that could be removed. For systems without IPv6 +support in the kernel and system libraries, Postfix has a simple +compatibility layer, so that it will use IPv4 as before. </p> + +</ul> + +</body> + +</html> diff --git a/proto/LDAP_README.html b/proto/LDAP_README.html new file mode 100644 index 0000000..720d1c0 --- /dev/null +++ b/proto/LDAP_README.html @@ -0,0 +1,632 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix LDAP Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix LDAP Howto</h1> + +<hr> + +<h2>LDAP Support in Postfix</h2> + +<p> Postfix can use an LDAP directory as a source for any of its +lookups: aliases(5), virtual(5), canonical(5), etc. This allows +you to keep information for your mail service in a replicated +network database with fine-grained access controls. By not storing +it locally on the mail server, the administrators can maintain it +from anywhere, and the users can control whatever bits of it you +think appropriate. You can have multiple mail servers using the +same information, without the hassle and delay of having to copy +it to each. </p> + +<p> Topics covered in this document:</p> + +<ul> + +<li><a href="#build">Building Postfix with LDAP support</a> + +<li><a href="#config">Configuring LDAP lookups</a> + +<li><a href="#example_alias">Example: aliases</a> + +<li><a href="#example_virtual">Example: virtual domains/addresses</a> + +<li><a href="#example_group">Example: expanding LDAP groups</a> + +<li><a href="#other">Other uses of LDAP lookups</a> + +<li><a href="#hmmmm">Notes and things to think about</a> + +<li><a href="#feedback">Feedback</a> + +<li><a href="#credits">Credits</a> + +</ul> + +<h2><a name="build">Building Postfix with LDAP support</a></h2> + +<p> These instructions assume that you build Postfix from source +code as described in the INSTALL document. Some modification may +be required if you build Postfix from a vendor-specific source +package. </p> + +<p> Note 1: Postfix no longer supports the LDAP version 1 interface. +</p> + +<p> Note 2: to use LDAP with Debian GNU/Linux's Postfix, all you +need is to install the postfix-ldap package and you're done. There +is no need to recompile Postfix. </p> + +<p> You need to have LDAP libraries and include files installed +somewhere on your system, and you need to configure the Postfix +Makefiles accordingly. </p> + +<p> For example, to build the OpenLDAP libraries for use with +Postfix (i.e. LDAP client code only), you could use the following +command: </p> + +<blockquote> +<pre> +% ./configure --without-kerberos --without-cyrus-sasl --without-tls \ + --without-threads --disable-slapd --disable-slurpd \ + --disable-debug --disable-shared +</pre> +</blockquote> + +<p> If you're using the libraries from the UM distribution +(http://www.umich.edu/~dirsvcs/ldap/ldap.html) or OpenLDAP +(http://www.openldap.org), something like this in the top level of +your Postfix source tree should work: </p> + +<blockquote> +<pre> +% make tidy +% make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \ + AUXLIBS_LDAP="-L/usr/local/lib -lldap -L/usr/local/lib -llber" +</pre> +</blockquote> + +<p> If your LDAP shared library is in a directory that the RUN-TIME +linker does not know about, add a "-Wl,-R,/path/to/directory" option after +"-lldap". </p> + +<p> Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_LDAP. +With Postfix 3.0 and later, the old AUXLIBS variable still supports +building a statically-loaded LDAP database client, but only the new +AUXLIBS_LDAP variable supports building a dynamically-loaded or +statically-loaded LDAP database client. </p> + +<blockquote> + +<p> Failure to use the AUXLIBS_LDAP variable will defeat the purpose +of dynamic database client loading. Every Postfix executable file +will have LDAP database library dependencies. And that was exactly +what dynamic database client loading was meant to avoid. </p> + +</blockquote> + +<p> On Solaris 2.x you may have to specify run-time link information, +otherwise ld.so will not find some of the shared libraries: </p> + +<blockquote> +<pre> +% make tidy +% make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \ + AUXLIBS_LDAP="-L/usr/local/lib -R/usr/local/lib -lldap \ + -L/usr/local/lib -R/usr/local/lib -llber" +</pre> +</blockquote> + +<p> The 'make tidy' command is needed only if you have previously +built Postfix without LDAP support. </p> + +<p> Instead of '/usr/local' specify the actual locations of your +LDAP include files and libraries. Be sure to not mix LDAP include +files and LDAP libraries of different versions!! </p> + +<p> If your LDAP libraries were built with Kerberos support, you'll +also need to include your Kerberos libraries in this line. Note +that the KTH Kerberos IV libraries might conflict with Postfix's +lib/libdns.a, which defines dns_lookup. If that happens, you'll +probably want to link with LDAP libraries that lack Kerberos support +just to build Postfix, as it doesn't support Kerberos binds to the +LDAP server anyway. Sorry about the bother. </p> + +<p> If you're using one of the Netscape LDAP SDKs, you'll need to +change the AUXLIBS line to point to libldap10.so or libldapssl30.so +or whatever you have, and you may need to use the appropriate linker +option (e.g. '-R') so the executables can find it at runtime. </p> + +<p> If you are using OpenLDAP, and the libraries were built with SASL +support, you can add -DUSE_LDAP_SASL to the CCARGS to enable SASL support. +For example: </p> + +<blockquote> +<pre> + CCARGS="-I/usr/local/include -DHAS_LDAP -DUSE_LDAP_SASL" +</pre> +</blockquote> + +<h2><a name="config">Configuring LDAP lookups</a></h2> + +<p> In order to use LDAP lookups, define an LDAP source +as a table lookup in main.cf, for example: </p> + +<blockquote> +<pre> +alias_maps = hash:/etc/aliases, ldap:/etc/postfix/ldap-aliases.cf +</pre> +</blockquote> + +<p> The file /etc/postfix/ldap-aliases.cf can specify a great number +of parameters, including parameters that enable LDAP SSL or STARTTLS, +and LDAP SASL. For a complete description, see the ldap_table(5) +manual page. </p> + +<h2><a name="example_alias">Example: local(8) aliases</a></h2> + +<p> Here's a basic example for using LDAP to look up local(8) +aliases. Assume that in main.cf, you have: </p> + +<blockquote> +<pre> +alias_maps = hash:/etc/aliases, ldap:/etc/postfix/ldap-aliases.cf +</pre> +</blockquote> + +<p> and in ldap:/etc/postfix/ldap-aliases.cf you have: </p> + +<blockquote> +<pre> +server_host = ldap.example.com +search_base = dc=example, dc=com +</pre> +</blockquote> + +<p> Upon receiving mail for a local address "ldapuser" that isn't +found in the /etc/aliases database, Postfix will search the LDAP +server listening at port 389 on ldap.example.com. It will bind anonymously, +search for any directory entries whose mailacceptinggeneralid +attribute is "ldapuser", read the "maildrop" attributes of those +found, and build a list of their maildrops, which will be treated +as RFC822 addresses to which the message will be delivered. </p> + +<h2><a name="example_virtual">Example: virtual domains/addresses</a></h2> + +<p> If you want to keep information for virtual lookups in your +directory, it's only a little more complicated. First, you need to +make sure Postfix knows about the virtual domain. An easy way to +do that is to add the domain to the mailacceptinggeneralid attribute +of some entry in the directory. Next, you'll want to make sure all +of your virtual recipient's mailacceptinggeneralid attributes are +fully qualified with their virtual domains. Finally, if you want +to designate a directory entry as the default user for a virtual +domain, just give it an additional mailacceptinggeneralid (or the +equivalent in your directory) of "@fake.dom". That's right, no +user part. If you don't want a catchall user, omit this step and +mail to unknown users in the domain will simply bounce. </p> + +<p> In summary, you might have a catchall user for a virtual domain +that looks like this: </p> + +<blockquote> +<pre> + dn: cn=defaultrecipient, dc=fake, dc=dom + objectclass: top + objectclass: virtualaccount + cn: defaultrecipient + owner: uid=root, dc=someserver, dc=isp, dc=dom +1 -> mailacceptinggeneralid: fake.dom +2 -> mailacceptinggeneralid: @fake.dom +3 -> maildrop: realuser@real.dom +</pre> +</blockquote> + +<dl compact> + +<dd> <p> 1: Postfix knows fake.dom is a valid virtual domain when +it looks for this and gets something (the maildrop) back. </p> + +<dd> <p> 2: This causes any mail for unknown users in fake.dom to +go to this entry ... </p> + +<dd> <p> 3: ... and then to its maildrop. </p> + +</dl> + +<p> Normal users might simply have one mailacceptinggeneralid and +maildrop, e.g. "normaluser@fake.dom" and "normaluser@real.dom". +</p> + +<h2><a name="example_group">Example: expanding LDAP groups</a></h2> + +<p> +LDAP is frequently used to store group member information. There are a +number of ways of handling LDAP groups. We will show a few examples in +order of increasing complexity, but owing to the number of independent +variables, we can only present a tiny portion of the solution space. +We show how to: +</p> + +<ol> + +<li> <p> query groups as lists of addresses; </p> + +<li> <p> query groups as lists of user objects containing addresses; </p> + +<li> <p> forward special lists unexpanded to a separate list server, +for moderation or other processing; </p> + +<li> <p> handle complex schemas by controlling expansion and by treating +leaf nodes specially, using features that are new in Postfix 2.4. </p> + +</ol> + +<p> +The example LDAP entries and implied schema below show two group entries +("agroup" and "bgroup") and four user entries ("auser", "buser", "cuser" +and "duser"). The group "agroup" has the users "auser" (1) and "buser" (2) +as members via DN references in the multi-valued attribute "memberdn", and +direct email addresses of two external users "auser@example.org" (3) and +"buser@example.org" (4) stored in the multi-valued attribute "memberaddr". +The same is true of "bgroup" and "cuser"/"duser" (6)/(7)/(8)/(9), but +"bgroup" also has a "maildrop" attribute of "bgroup@mlm.example.com" +(5): </p> + +<blockquote> +<pre> + dn: cn=agroup, dc=example, dc=com + objectclass: top + objectclass: ldapgroup + cn: agroup + mail: agroup@example.com +1 -> memberdn: uid=auser, dc=example, dc=com +2 -> memberdn: uid=buser, dc=example, dc=com +3 -> memberaddr: auser@example.org +4 -> memberaddr: buser@example.org +</pre> +<br> + +<pre> + dn: cn=bgroup, dc=example, dc=com + objectclass: top + objectclass: ldapgroup + cn: bgroup + mail: bgroup@example.com +5 -> maildrop: bgroup@mlm.example.com +6 -> memberdn: uid=cuser, dc=example, dc=com +7 -> memberdn: uid=duser, dc=example, dc=com +8 -> memberaddr: cuser@example.org +9 -> memberaddr: duser@example.org +</pre> +<br> + +<pre> + dn: uid=auser, dc=example, dc=com + objectclass: top + objectclass: ldapuser + uid: auser +10 -> mail: auser@example.com +11 -> maildrop: auser@mailhub.example.com +</pre> +<br> + +<pre> + dn: uid=buser, dc=example, dc=com + objectclass: top + objectclass: ldapuser + uid: buser +12 -> mail: buser@example.com +13 -> maildrop: buser@mailhub.example.com +</pre> +<br> + +<pre> + dn: uid=cuser, dc=example, dc=com + objectclass: top + objectclass: ldapuser + uid: cuser +14 -> mail: cuser@example.com +</pre> +<br> + +<pre> + dn: uid=duser, dc=example, dc=com + objectclass: top + objectclass: ldapuser + uid: duser +15 -> mail: duser@example.com +</pre> +<br> + +</blockquote> + +<p> Our first use case ignores the "memberdn" attributes, and assumes +that groups hold only direct "memberaddr" strings as in (3), (4), (8) and +(9). The goal is to map the group address to the list of constituent +"memberaddr" values. This is simple, ignoring the various connection +related settings (hosts, ports, bind settings, timeouts, ...) we have: +</p> + +<blockquote> +<pre> + simple.cf: + ... + search_base = dc=example, dc=com + query_filter = mail=%s + result_attribute = memberaddr + $ postmap -q agroup@example.com ldap:/etc/postfix/simple.cf \ + auser@example.org,buser@example.org +</pre> +</blockquote> + +<p> We search "dc=example, dc=com". The "mail" attribute is used in the +query_filter to locate the right group, the "result_attribute" setting +described in ldap_table(5) is used to specify that "memberaddr" values +from the matching group are to be returned as a comma separated list. +Always check tables using postmap(1) with the "-q" option, before +deploying them into production use in main.cf. </p> + +<p> Our second use case instead expands "memberdn" attributes (1), (2), +(6) and (7), follows the DN references and returns the "maildrop" of the +referenced user entries. Here we use the "special_result_attribute" +setting from ldap_table(5) to designate the "memberdn" attribute +as holding DNs of the desired member entries. The "result_attribute" +setting selects which attributes are returned from the selected DNs. It +is important to choose a result attribute that is not also present in +the group object, because result attributes are collected from both +the group and the member DNs. In this case we choose "maildrop" and +assume for the moment that groups never have a "maildrop" (the "bgroup" +"maildrop" attribute is for a different use case). The returned data for +"auser" and "buser" is from items (11) and (13) in the example data. </p> + +<blockquote> +<pre> + special.cf: + ... + search_base = dc=example, dc=com + query_filter = mail=%s + result_attribute = maildrop + special_result_attribute = memberdn + $ postmap -q agroup@example.com ldap:/etc/postfix/special.cf \ + auser@mailhub.example.com,buser@mailhub.example.com +</pre> +</blockquote> + +<p> Note: if the desired member object result attribute is always also +present in the group, you get surprising results: the expansion also +returns the address of the group. This is a known limitation of Postfix +releases prior to 2.4, and is addressed in the new with Postfix 2.4 +"leaf_result_attribute" feature described in ldap_table(5). </p> + +<p> Our third use case has some groups that are expanded immediately, +and other groups that are forwarded to a dedicated mailing list manager +host for delayed expansion. This uses two LDAP tables, one for users +and forwarded groups and a second for groups that can be expanded +immediately. It is assumed that groups that require forwarding are +never nested members of groups that are directly expanded. </p> + +<blockquote> +<pre> + no_expand.cf: + ... + search_base = dc=example, dc=com + query_filter = mail=%s + result_attribute = maildrop + expand.cf + ... + search_base = dc=example, dc=com + query_filter = mail=%s + result_attribute = maildrop + special_result_attribute = memberdn + $ postmap -q auser@example.com \ + ldap:/etc/postfix/no_expand.cf ldap:/etc/postfix/expand.cf \ + auser@mailhub.example.com + $ postmap -q agroup@example.com \ + ldap:/etc/postfix/no_expand.cf ldap:/etc/postfix/expand.cf \ + auser@mailhub.example.com,buser@mailhub.example.com + $ postmap -q bgroup@example.com \ + ldap:/etc/postfix/no_expand.cf ldap:/etc/postfix/expand.cf \ + bgroup@mlm.example.com +</pre> +</blockquote> + +<p> Non-group objects and groups with delayed expansion (those that have a +maildrop attribute) are rewritten to a single maildrop value. Groups that +don't have a maildrop are expanded as the second use case. This admits +a more elegant solution with Postfix 2.4 and later. </p> + +<p> Our final use case is the same as the third, but this time uses new +features in Postfix 2.4. We now are able to use just one LDAP table and +no longer need to assume that forwarded groups are never nested inside +expanded groups. </p> + +<blockquote> +<pre> + fancy.cf: + ... + search_base = dc=example, dc=com + query_filter = mail=%s + result_attribute = memberaddr + special_result_attribute = memberdn + terminal_result_attribute = maildrop + leaf_result_attribute = mail + $ postmap -q auser@example.com ldap:/etc/postfix/fancy.cf \ + auser@mailhub.example.com + $ postmap -q cuser@example.com ldap:/etc/postfix/fancy.cf \ + cuser@example.com + $ postmap -q agroup@example.com ldap:/etc/postfix/fancy.cf \ + auser@mailhub.example.com,buser@mailhub.example.com,auser@example.org,buser@example.org + $ postmap -q bgroup@example.com ldap:/etc/postfix/fancy.cf \ + bgroup@mlm.example.com +</pre> +</blockquote> + +<p> Above, delayed expansion is enabled via "terminal_result_attribute", +which, if present, is used as the sole result and all other expansion is +suppressed. Otherwise, the "leaf_result_attribute" is only returned for +leaf objects that don't have a "special_result_attribute" (non-groups), +while the "result_attribute" (direct member address of groups) is returned +at every level of recursive expansion, not just the leaf nodes. This fancy +example illustrates all the features of Postfix 2.4 group expansion. </p> + +<h2><a name="other">Other uses of LDAP lookups</a></h2> + +Other common uses for LDAP lookups include rewriting senders and +recipients with Postfix's canonical lookups, for example in order +to make mail leaving your site appear to be coming from +"First.Last@example.com" instead of "userid@example.com". + +<h2><a name="hmmmm">Notes and things to think about</a></h2> + +<ul> + +<li> <p> The bits of schema and attribute names used in this document are just + examples. There's nothing special about them, other than that some are + the defaults in the LDAP configuration parameters. You can use + whatever schema you like, and configure Postfix accordingly. </p> + +<li> <p> You probably want to make sure that mailacceptinggeneralids are + unique, and that not just anyone can specify theirs as postmaster or + root, say. </p> + +<li> <p> An entry can have an arbitrary number of mailacceptinggeneralids or + maildrops. Maildrops can also be comma-separated lists of addresses. + They will all be found and returned by the lookups. For example, you + could define an entry intended for use as a mailing list that looks + like this (Warning! Schema made up just for this example): </p> + +<blockquote> +<pre> +dn: cn=Accounting Staff List, dc=example, dc=com +cn: Accounting Staff List +o: example.com +objectclass: maillist +mailacceptinggeneralid: accountingstaff +mailacceptinggeneralid: accounting-staff +maildrop: mylist-owner +maildrop: an-accountant +maildrop: some-other-accountant +maildrop: this, that, theother +</pre> +</blockquote> + +<li> <p> If you use an LDAP map for lookups other than aliases, you may have to + make sure the lookup makes sense. In the case of virtual lookups, + maildrops other than mail addresses are pretty useless, because + Postfix can't know how to set the ownership for program or file + delivery. Your <b>query_filter</b> should probably look something like this: </p> + +<blockquote> +<pre> +query_filter = (&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*")))) +</pre> +</blockquote> + +<li> <p> And for that matter, even for aliases, you may not want users to be able to + specify their maildrops as programs, includes, etc. This might be + particularly pertinent on a "sealed" server where they don't have + local UNIX accounts, but exist only in LDAP and Cyrus. You might allow + the fun stuff only for directory entries owned by an administrative + account, + so that if the object had a program as its maildrop and weren't owned + by "cn=root" it wouldn't be returned as a valid local user. This will + require some thought on your part to implement safely, considering the + ramifications of this type of delivery. You may decide it's not worth + the bother to allow any of that nonsense in LDAP lookups, ban it in + the <b>query_filter</b>, and keep things like majordomo lists in local alias + databases. </p> + +<blockquote> +<pre> +query_filter = (&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))(owner=cn=root, dc=your, dc=com))) +</pre> +</blockquote> + +<li> <p> LDAP lookups are slower than local DB or DBM lookups. For most sites + they won't be a bottleneck, but it's a good idea to know how to tune + your directory service. </p> + +<li> <p> Multiple LDAP maps share the same LDAP connection if they differ + only in their query related parameters: base, scope, query_filter, and + so on. To take advantage of this, avoid spurious differences in the + definitions of LDAP maps: host selection order, version, bind, tls + parameters, ... should be the same for multiple maps whenever possible. </p> + +</ul> + +<h2><a name="feedback">Feedback</a></h2> + +<p> If you have questions, send them to postfix-users@postfix.org. Please +include relevant information about your Postfix setup: LDAP-related +output from postconf, which LDAP libraries you built with, and which +directory server you're using. If your question involves your directory +contents, please include the applicable bits of some directory entries. </p> + +<h2><a name="credits">Credits</a></h2> + +<ul> + +<li>Manuel Guesdon: Spotted a bug with the timeout attribute. + +<li>John Hensley: Multiple LDAP sources with more configurable attributes. + +<li>Carsten Hoeger: Search scope handling. + +<li>LaMont Jones: Domain restriction, URL and DN searches, multiple result + attributes. + +<li>Mike Mattice: Alias dereferencing control. + +<li>Hery Rakotoarisoa: Patches for LDAPv3 updating. + +<li>Prabhat K Singh: Wrote the initial Postfix LDAP lookups and connection caching. + +<li>Keith Stevenson: RFC 2254 escaping in queries. + +<li>Samuel Tardieu: Noticed that searches could include wildcards, prompting + the work on RFC 2254 escaping in queries. Spotted a bug + in binding. + +<li>Sami Haahtinen: Referral chasing and v3 support. + +<li>Victor Duchovni: ldap_bind() timeout. With fixes from LaMont Jones: + OpenLDAP cache deprecation. Limits on recursion, expansion + and search results size. LDAP connection sharing for maps + differing only in the query parameters. + +<li>Liviu Daia: Support for SSL/STARTTLS. Support for storing map definitions in + external files (ldap:/path/ldap.cf) needed to securely store + passwords for plain auth. + +<li>Liviu Daia revised the configuration interface and added the main.cf + configuration feature.</li> + +<li>Liviu Daia with further refinements from Jose Luis Tallon and +Victor Duchovni developed the common query, result_format, domain and +expansion_limit interface for LDAP, MySQL and PosgreSQL.</li> + +<li>Gunnar Wrobel provided a first implementation of a feature to +limit LDAP search results to leaf nodes only. Victor generalized +this into the Postfix 2.4 "leaf_result_attribute" feature. </li> + +<li>Quanah Gibson-Mount contributed support for advanced LDAP SASL +mechanisms, beyond the password-based LDAP "simple" bind. </li> + +</ul> + +And of course Wietse. + +</body> + +</html> diff --git a/proto/LINUX_README.html b/proto/LINUX_README.html new file mode 100644 index 0000000..76c605f --- /dev/null +++ b/proto/LINUX_README.html @@ -0,0 +1,119 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix and Linux</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix and Linux</h1> + +<hr> + +<h2> Host lookup issues </h2> + +<p> By default Linux /etc/hosts lookups do not support multiple IP +addresses per hostname. This causes warnings from the Postfix SMTP +server that "hostname XXX does not resolve to address YYY", and is +especially a problem with hosts that have both IPv4 and IPv6 +addresses. To fix this, turn on support for multiple IP addresses: </p> + +<blockquote> +<pre> +/etc/host.conf: + ... + # We have machines with multiple IP addresses. + multi on + ... +</pre> +</blockquote> + +<p> Alternatively, specify the RESOLV_MULTI environment variable +in main.cf: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + import_environment = MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ XAUTHORITY DISPLAY LANG=C RESOLV_MULTI=on +</pre> +</blockquote> + +<h2>Berkeley DB issues</h2> + +<p> If you can't compile Postfix because the file "db.h" +isn't found, then you MUST install the Berkeley DB development +package (name: db???-devel-???) that matches your system library. +You can find out what is installed with the rpm command. For example: +</p> + +<blockquote> +<pre> +$ <b>rpm -qf /usr/lib/libdb.so</b> +db4-4.3.29-2 +</pre> +</blockquote> + +<p> This means that you need to install db4-devel-4.3.29-2 (on +some systems, specify "<b>rpm -qf /lib/libdb.so</b>" instead). </p> + +<p> DO NOT download some Berkeley DB version from the network. +Every Postfix program will dump core when it is built with a different +Berkeley DB version than the version that is used by the system +library routines. See the DB_README file for further information. +</p> + +<h2>Procmail issues</h2> + +<p> On RedHat Linux 7.1 and later <b>procmail</b> no longer has +permission +to write to the mail spool directory. Workaround: </p> + +<blockquote> +<pre> +# chmod 1777 /var/spool/mail +</pre> +</blockquote> + +<h2>Logging in a container</h2> + +<p> When running Postfix inside a container, you can use stdout +logging as described in MAILLOG_README. Alternatives: run syslogd +inside the container, or mount the host's syslog socket inside the +container. </p> + +<h2>Syslogd performance</h2> + +<p> LINUX <b>syslogd</b> uses synchronous writes by default. Because +of this, <b>syslogd</b> can actually use more system resources than +Postfix. To avoid such badness, disable synchronous mail logfile +writes by editing /etc/syslog.conf and by prepending a - to the +logfile name: </p> + +<blockquote> +<pre> +/etc/syslog.conf: + mail.* -/var/log/mail.log +</pre> +</blockquote> + +<p> Send a "<b>kill -HUP</b>" to the <b>syslogd</b> to make the +change effective. </p> + +<h2>Other logging performance issues</h2> + +<p> LINUX <b>systemd</b> intercepts all logging and enforces its +own rate limits before handing off requests to a backend such as +<b>rsyslogd</b> or <b>syslog-ng</b>. On a busy mail server this can +result in information loss. As a workaround, you can use Postfix's +built-in logging as described in MAILLOG_README. </p> + +</body> + +</html> diff --git a/proto/LMDB_README.html b/proto/LMDB_README.html new file mode 100644 index 0000000..a9794cc --- /dev/null +++ b/proto/LMDB_README.html @@ -0,0 +1,421 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix OpenLDAP LMDB Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix OpenLDAP LMDB Howto</h1> + +<hr> + +<h2>Introduction</h2> + +<p> Postfix uses databases of various kinds to store and look up +information. Postfix databases are specified as "type:name". OpenLDAP +LMDB (called "LMDB" from here on) implements the Postfix database +type "lmdb". The name of a Postfix LMDB database is the name of +the database file without the ".lmdb" suffix. </p> + +<p> This document describes: </p> + +<ul> + +<li> <p> <a href="#with_lmdb">Building Postfix with LMDB support</a>. +</p> + +<li> <p> <a href="#configure">Configuring LMDB settings</a>. </p> + +<li> <p> <a href="#locking">Using LMDB maps with non-Postfix programs</a>. </p> + +<li> <p> <a href="#supported"> Required minimum LMDB patchlevel</a>. </p> + +<li> <p> <a href="#credits"> Credits</a>. </p> + +</ul> + +<h2><a name="with_lmdb">Building Postfix with LMDB support</a></h2> + +<p> Postfix normally does not enable LMDB support. To +build Postfix with LMDB support, use something like: </p> + +<blockquote> +<pre> +% make makefiles CCARGS="-DHAS_LMDB -I/usr/local/include" \ + AUXLIBS_LMDB="-L/usr/local/lib -llmdb" +% make +</pre> +</blockquote> + +<p> If your LMDB shared library is in a directory that the RUN-TIME +linker does not know about, add a "-Wl,-R,/path/to/directory" option after +"-llmdb". </p> + +<p> Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_LMDB. +With Postfix 3.0 and later, the old AUXLIBS variable still supports +building a statically-loaded LMDB database client, but only the new +AUXLIBS_LMDB variable supports building a dynamically-loaded or +statically-loaded LMDB database client. </p> + +<blockquote> + +<p> Failure to use the AUXLIBS_LMDB variable will defeat the purpose +of dynamic database client loading. Every Postfix executable file +will have LMDB database library dependencies. And that was exactly +what dynamic database client loading was meant to avoid. </p> + +</blockquote> + + +<p> Solaris may need this: </p> + +<blockquote> +<pre> +% make makefiles CCARGS="-DHAS_LMDB -I/usr/local/include" \ + AUXLIBS_LMDB="-R/usr/local/lib -L/usr/local/lib -llmdb" +% make +</pre> +</blockquote> + +<p> The exact pathnames depend on how LMDB was installed. </p> + +<p> When building Postfix fails with: </p> + +<blockquote> +<pre> +undefined reference to `pthread_mutexattr_destroy' +undefined reference to `pthread_mutexattr_init' +undefined reference to `pthread_mutex_lock' +</pre> +</blockquote> + +<p> Add the "-lpthread" library to the "make makefiles" command. </p> + +<blockquote> +<pre> +% make makefiles .... AUXLIBS_LMDB="... -lpthread" +</pre> +</blockquote> + +<h2><a name="configure">Configuring LMDB settings</a></h2> + +<p> Postfix provides one configuration parameter that controls +LMDB database behavior. </p> + +<ul> + +<li> <p> lmdb_map_size (default: 16777216). This setting specifies +the initial LMDB database size limit in bytes. Each time a database +becomes "full", its size limit is doubled. The maximum size is the +largest signed integer value of "long". </p> + +</ul> + +<h2> <a name="locking">Using LMDB maps with non-Postfix programs</a> </h2> + +<p> Programs that use LMDB's built-in locking protocol will corrupt +a Postfix LMDB database or will read garbage. </p> + +<p> Postfix does not use LMDB's built-in locking protocol, because +that would require world-writable lockfiles, and would violate +Postfix security policy. Instead, Postfix uses external locks based +on fcntl(2) to prevent writers from corrupting the database, and +to prevent readers from receiving garbage. </p> + +<p> See lmdb_table(5) for a detailed description of the locking +protocol that all programs must use when they access a Postfix LMDB +database. </p> + +<h2> <a name="supported"> Required minimum LMDB patchlevel </a> </h2> + +<p> Currently, Postfix requires LMDB 0.9.11 or later. The required +minimum LMDB patchlevel has evolved over time, as the result of +Postfix deployment experience: </p> + +<ul> + +<li> <p> LMDB 0.9.11 allows Postfix daemons to log an LMDB error +message, instead of falling out of the sky without any notification. +</p> + +<li> <p> LMDB 0.9.10 closes an information leak where LMDB was +writing up to 4-kbyte chunks of uninitialized heap memory to the +database. This would persist information that was not meant to be +persisted, or share information that was not meant to be shared. +</p> + +<li> <p> LMDB 0.9.9 allows Postfix to use external (fcntl()-based) +locks, instead of having to use world-writable LMDB lock files, +violating the Postfix security model in multiple ways. </p> + +<li> <p> LMDB 0.9.8 allows Postfix to recover from a "database full" +error without having to close the database. This version adds support +to update the database size limit on-the-fly. This is necessary +because Postfix database sizes vary with mail server load. </p> + +<li> <p> LMDB 0.9.7 allows the postmap(1) and postalias(1) commands +to use a bulk-mode transaction larger than the amount of physical +memory. This is necessary because LMDB supports databases larger +than physical memory. </p> + +</ul> + +<h2> <a name="credits"> Credits</a> </h2> + +<ul> + +<li> <p> Howard Chu contributed the initial Postfix dict_lmdb driver. +</p> + +<li> <p> Wietse Venema wrote an abstraction layer (slmdb) that +behaves more like Berkeley DB, NDBM, etc. This layer automatically +retries an LMDB request when a database needs to be resized, or +after a database was resized by a different process. </p> + +<li> <p> Howard and Wietse went through many iterations with changes +to both LMDB and Postfix, with input from Viktor Dukhovni. </p> + +</ul> + +<!-- + +<h2><a name="limitations">Unexpected failure modes of Postfix LMDB +databases. </a> </h2> + +<p> As documented below, conversion to LMDB introduces a number of +failure modes that don't exist with other Postfix databases. Some +failure modes have been eliminated in the course of time. +The writeup below reflects the status as of LMDB 0.9.9. </p> + +--> + +<!-- + +<p> <strong>Unexpected "Permission denied" errors. </strong></p> + +<dl> + +<dt> Problem: </dt> <dd> <p> A world-readable LMDB database cannot +be opened by a process with a UID that differs from the database +file owner, even when an attempt is made to open the database +read-only. This problem does not exist with other Postfix databases. +</p> </dd> + +<dt> Background: </dt> <dd> <p> The LMDB implementation requires +write access to maintain read locks, and perhaps for other purposes. +</p> </dd> + +<dt> Solution: </dt> <dd> <p> Consider using cdb: to manage root-owned +databases under the root-owned <tt>/etc</tt> or config_directory +(default: <tt>/etc/postfix</tt>) such as access(5), virtual(5), +transport(5). Support to create LMDB databases is available only +for unprivileged Postfix daemon processes such as postscreen(8), +tlsmgr(8) and verify(8) that manage postfix-owned databases under +the postfix-owned data_directory (default: <tt>/var/lib/postfix</tt>). +</p> </dd> + +</dl> + +--> + +<!-- + +<p> <strong>Unexpected "readers full" errors. </strong></p> + +<dl> + +<dt> Problem: </dt> <dd> <p> Under heavy load, database read +operations fail with MDB_READERS_FULL errors. This problem does not +exist with other Postfix databases. </p> </dd> + +<dt> Background: </dt> <dd> <p> The LMDB implementation enforces a +hard limit on the number of simultaneous read requests for the same +database environment. This limit must be specified in advance with +the lmdb_max_readers configuration parameter. </p> </dd> + +<dt> Mitigation: </dt> <dd> <p> Postfix logs a warning suggesting +that the lmdb_max_readers parameter value be increased, and retries +the failed operation for a limited number of times while running +with reduced performance. </p> </dd> + +<dt> Prevention: </dt> <dd> <p> Monitor your LMDB files for +MDB_READERS_FULL errors. After making the necessary adjustments, +restart Postfix. </p> </dd> + +</dl> + +--> + +<!-- + +<p> <strong>Unexpected postmap(1)/postalias(1) "database full" +errors. </strong></p> + +<dl> + +<dt> Problem: </dt> <dd> <p> The "postmap lmdb:filename" command +fails with an MDB_TXN_FULL error. This problem does not exist with +other Postfix databases. </p> </dd> + +<dt> Background: </dt> + +<dd> + +<p> The LMDB implementation has a hard limit on the total transaction +size. This limit is independent of the LMDB database size. Therefore, +the problem cannot be resolved by increasing the lmdb_map_size +value. </p> + +<p> This symptom is indicative of a flawed design. All LMDB data +structures should share the same storage pool so that they can scale +with the database size, and so that all "out of storage" errors are +resolved by increasing the database size. </p> </dd> + +--> + +<!-- + +<p> Problem: </dt> <dd> <p> The "postmap lmdb:filename" command +fails with an MDB_MAP_FULL error. This problem does not exist with +other Postfix databases. </p> </dd> + +<dl> + +<dt> Background: </dt> + +<dd> + +<p> LMDB databases have a hard size limit (configured with the +lmdb_map_size configuration parameter). </p> + +<p> When executing "postmap lmdb:filename", the Postfix LMDB database +client stores the new data in a transaction which takes up space +in addition to the existing data, and commits the transaction when +it closes the database. Only then can the space for old data be +reused. </p> + +</dd> + +<dt> Impact: </dt> <dd> <p> This failure does not affect Postfix +availability, because the old data still exists in the database. +</p> </dd> + +<dt> Mitigation: </dt> <dd> + +<p> When the postmap(1) or postalias(1) command fails with an +MDB_MAP_FULL error, it expands the database file size to the current +LMDB map size limit before terminating. </p> + +<p> Next, when you re-run the postmap(1) or postalias(1) command, +it discovers that the LMDB file is larger than lmdb_map_size/3, +logs a warning, and uses a larger LMDB map size limit instead: </p> + +<p> <tt> warning: <i>filename</i>.lmdb: file size 15024128 ≥ +(lmdb map size limit 16777216)/3<br> warning: <i>filename</i>.lmdb: +using map size limit 45072384</tt> </p> + +<p> By repeating the two steps above you can automate recovery and +avoid the need for human intervention. Just repeat "postmap +lmdb:filename" (up to some limit). After each failure it will use +a 3x larger size limit, and eventually the "database full" error +should disappear. This fails only when the disk is full or when +the LMDB map size limit would exceed the memory address space size +limit. </p> + +<dt> Prevention: </dt> <dd> <p> Monitor your LMDB files and make +sure that in main.cf, lmdb_map_size > 3x the largest LMDB file +size. </p> </dd> </dl> + +</dl> + +--> + +<!-- + +<p> <strong>Unexpected Postfix daemon "database full" errors. +</strong></p> + +<dl> + +<dt> Problem: </dt> <dd> <p> Postfix daemon programs fail with +"database full" errors, such as postscreen(8), tlsmgr(8) or verify(8). +This problem does not exist with other Postfix databases. </p> +</dd> + +<dt> Impact: </dt> <dd> <p> This failure temporarily affects Postfix +availability. The daemon restarts automatically and tries to open +the database again as described next. </p> </dd> + +<dt> Mitigation: </dt> <dd> <p> When a Postfix daemon opens an LMDB +file larger than lmdb_map_size/3, it logs a warning and uses a +larger size limit instead: </p> + +<p> <tt> warning: <i>filename</i>.lmdb: file size 15024128 ≥ +(lmdb map size limit 16777216)/3 <br>warning: <i>filename</i>.lmdb: +using map size limit 45072384</tt> </p> + +<p> This can be used to automate recovery and avoid the need for +human intervention. Each time the daemon runs into a "database full" +error, it restarts and uses a 3x larger size limit. The "database +full" error will disappear, at least for a while. </p> + +<dt> Prevention: </dt> <dd> <p> Monitor your LMDB files and make +sure that lmdb_map_size > 3x the largest LMDB file size. </p> +</dd> </dl> + +--> + +<!-- + +<p> <strong>Non-obvious recovery with postmap(1), postalias(1), or +tlsmgr(8) from a corrupted database. </strong></p> + +<dl> + +<dt> Problem: </dt> <dd> <p> A corrupted LMDB database can't be +rebuilt simply by re-running postmap(1) or postalias(1), or by +waiting until a tlsmgr(8) daemon restarts. This problem does not +exist with other Postfix databases. </p> </dd> + +<dt> Background: </dt> <dd> <p> The Postfix LMDB database client +does not truncate the database file. Instead it attempts to create +a transaction for a "drop" request plus subsequent "store" requests. +That is obviously not possible with a corrupted database file. </p> +</dd> + +<dt> Impact: </dt> <dd> <p> Postfix does not process mail until +someone fixes the problem. </p> </dd> + +<dt> Recovery: </dt> <dd> <p> First delete the ".lmdb" file by hand. +Then rebuild the file with the postmap(1) or postalias(1) +command if the file was created with those commands, or restart +postfix daemons if the file is maintained by tlsmgr(8). +</p> </dd> + +<dt> Prevention: </dt> <dd> + +<p> Arrange your file systems such that they never run out of free +space. </p> + +<p> Use ECC memory to detect and correct silent corruption of +in-memory file system data and metadata. </p> + +<p> Use a file system such as ZFS to detect and correct silent +corruption of on-disk file system data and metadata. DO NOT +use ZFS on systems without ECC memory error correction. </p> + +</dd> </dl> + +--> + +</body> + +</html> diff --git a/proto/LOCAL_RECIPIENT_README.html b/proto/LOCAL_RECIPIENT_README.html new file mode 100644 index 0000000..12828cd --- /dev/null +++ b/proto/LOCAL_RECIPIENT_README.html @@ -0,0 +1,180 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Rejecting Unknown Local Recipients with Postfix</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Rejecting Unknown Local Recipients with Postfix</h1> + +<hr> + +<h2>Introduction</h2> + +<p> As of Postfix version 2.0, the Postfix SMTP server rejects mail +for unknown recipients in local domains (domains that match +$mydestination or the IP addresses in $inet_interfaces or +$proxy_interfaces) with "User unknown in local recipient table". +This feature was optional with earlier Postfix versions. </p> + +<p> The good news is that this keeps undeliverable mail out of your +queue, so that your mail queue is not clogged up with undeliverable +MAILER-DAEMON messages. </p> + +<p> The bad news is that it may cause mail to be rejected when you +upgrade from a Postfix system that was not configured to reject +mail for unknown local recipients. </p> + +<p> This document describes what steps are needed in order to reject +unknown local recipients correctly. </p> + +<ul> + +<li><a href="#main_config">Configuring local_recipient_maps +in main.cf</a> + +<li><a href="#change">When you need to change the local_recipient_maps +setting in main.cf</a> + +<li><a href="#format">Local recipient table format </a> + +</ul> + +<h2><a name="main_config">Configuring local_recipient_maps +in main.cf</a></h2> + +<p> The local_recipient_maps parameter specifies lookup tables with +all names or addresses of local recipients. A recipient address is +local when its domain matches $mydestination, $inet_interfaces or +$proxy_interfaces. If a local username or address is not listed in +$local_recipient_maps, then the Postfix SMTP server will reject +the address with "User unknown in local recipient table". </p> + +<p> The default setting, shown below, assumes that you use the +default Postfix local(8) delivery agent for local delivery, where +recipients are either UNIX accounts or local aliases: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + local_recipient_maps = proxy:unix:passwd.byname $alias_maps +</pre> +</blockquote> + +<p> To turn off unknown local recipient rejects by the SMTP server, +specify: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + local_recipient_maps = +</pre> +</blockquote> + +<p> That is, an empty value. With this setting, the Postfix SMTP +server will not reject mail with "User unknown in local recipient +table". <b> Don't do this on systems that receive mail directly +from the Internet. With today's worms and viruses, Postfix will +become a backscatter source: it accepts mail for non-existent +recipients and then tries to return that mail as "undeliverable" +to the often forged sender address</b>. </p> + +<h2><a name="change">When you need to change the local_recipient_maps +setting in main.cf</a></h2> + +<ul> + + <li> <p> Problem: you don't use the default Postfix local(8) + delivery agent for domains matching $mydestination, $inet_interfaces, + or $proxy_interfaces. For example, you redefined the + "local_transport" setting in main.cf. </p> + + <p> Solution: your local_recipient_maps setting needs to specify + a database that lists all the known user names or addresses + for that delivery agent. For example, if you deliver users in + $mydestination etc. domains via the virtual(8) delivery agent, + specify: </p> + +<pre> +/etc/postfix/main.cf + mydestination = $myhostname localhost.$mydomain localhost ... + local_transport = virtual + local_recipient_maps = $virtual_mailbox_maps +</pre> + + <p> If you use a different delivery agent for $mydestination + etc. domains, see the section "<a href="#format">Local recipient + table format</a>" below for a description of how the table + should be populated. </p> + + <li> <p> Problem: you use the mailbox_transport or fallback_transport + feature of the Postfix local(8) delivery agent in order to + deliver mail to non-UNIX accounts. </p> + + <p> Solution: you need to add the database that lists the + non-UNIX users: </p> + +<pre> +/etc/postfix/main.cf + local_recipient_maps = proxy:unix:passwd.byname, $alias_maps, + <the database with non-UNIX accounts> +</pre> + + <p> See the section "<a href="#format">Local recipient table + format</a>" below for a description of how the table should be + populated. </p> + + <li> <p> Problem: you use the luser_relay feature of the Postfix + local delivery agent. </p> + + <p> Solution: you must disable the local_recipient_maps feature + completely, so that Postfix accepts mail for all local addresses: + </p> + +<pre> +/etc/postfix/main.cf + local_recipient_maps = +</pre> + +</ul> + +<h2><a name="format">Local recipient table format</a> </h2> + +<p> If you use local files in postmap(1) format, then +local_recipient_maps expects the following table format: </p> + +<ul> + +<li> <p> In the left-hand side, specify a bare username, an +"@domain.tld" wild-card, or specify a complete "user@domain.tld" +address. </p> + +<li> <p> You have to specify something on the right-hand side of +the table, but the value is ignored by local_recipient_maps. + +</ul> + +<p> If you use lookup tables based on NIS, LDAP, MYSQL, or PGSQL, +then local_recipient_maps does the same queries as for local files +in postmap(1) format, and expects the same results. </p> + +<p> With regular expression tables, Postfix only queries with the +full recipient address, and not with the bare username or the +"@domain.tld" wild-card. </p> + +<p> NOTE: a lookup table should always return a result when the address +exists, and should always return "not found" when the address does +not exist. In particular, a zero-length result does not count as +a "not found" result. </p> + +</body> + +</html> diff --git a/proto/MAILDROP_README.html b/proto/MAILDROP_README.html new file mode 100644 index 0000000..0271ea9 --- /dev/null +++ b/proto/MAILDROP_README.html @@ -0,0 +1,195 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix + Maildrop Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix + Maildrop Howto</h1> + +<hr> + +<h2> Introduction </h2> + +<p> This document discusses various options to plug the maildrop +delivery agent into Postfix: </p> + +<ul> + +<li><a href="#direct">Direct delivery without the local delivery agent</a> + +<li><a href="#indirect">Indirect delivery via the local delivery agent</a> + +<li><a href="#credits">Credits</a> + +</ul> + +<h2><a name="direct">Direct delivery without the local delivery agent</a></h2> + +<p> Postfix can be configured to deliver mail directly to maildrop, +without using the local(8) delivery agent as an intermediate. This +means that you do not get local aliases(5) expansion or $HOME/.forward +file processing. You would typically do this for hosted domains with +recipients that don't have UNIX home directories. </p> + +<p> The following example shows how to use maildrop for some.domain +and for someother.domain. The example comes in two parts. </p> + +<p> Part 1 describes changes to the main.cf file: </p> + +<blockquote> +<pre> + 1 /etc/postfix/main.cf: + 2 maildrop_destination_recipient_limit = 1 + 3 virtual_mailbox_domains = some.domain someother.domain + 4 virtual_transport = maildrop + 5 virtual_mailbox_maps = hash:/etc/postfix/virtual_mailbox + 6 virtual_alias_maps = hash:/etc/postfix/virtual_alias + 7 + 8 /etc/postfix/virtual_mailbox: + 9 user1@some.domain <i>...text here does not matter...</i> +10 user2@some.domain <i>...text here does not matter...</i> +11 user3@someother.domain <i>...text here does not matter...</i> +12 +13 /etc/postfix/virtual_alias: +14 postmaster@some.domain postmaster +15 postmaster@someother.domain postmaster +</pre> +</blockquote> + +<ul> + +<li> <p> Line 2 is needed so that Postfix will provide one recipient +at a time to the maildrop delivery agent. </p> + +<li> <p> Line 3 informs Postfix that some.domain and someother.domain +are so-called virtual mailbox domains. +Instead of listing the names in main.cf you can also +list them in a file; see the virtual_mailbox_domains documentation for +details. </p> + +<li> <p> Line 4 specifies that mail for some.domain and someother.domain +should be delivered by the maildrop delivery agent. </p> + +<li> <p> Lines 5 and 8-11 specify what recipients the Postfix SMTP +server should receive mail for. This prevents the mail queue from +becoming clogged with undeliverable messages. Specify an empty +value ("virtual_mailbox_maps =") to disable this feature. </p> + +<li> <p> Lines 6 and 13-15 redirect mail for postmaster to the +local postmaster. RFC 821 requires that every domain has a postmaster +address. </p> + +</ul> + +<p> The vmail userid as used below is the user that maildrop should +run as. This would be the owner of the virtual mailboxes if they +all have the same owner. If maildrop is suid (see maildrop +documentation), then maildrop will change to the appropriate owner +to deliver the mail. </p> + +<p> Note: Do not use the postfix user as the maildrop user. </p> + +<p> Part 2 describes changes to the master.cf file: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + maildrop unix - n n - - pipe + flags=ODRhu user=vmail argv=/path/to/maildrop -d ${recipient} +</pre> +</blockquote> + +<p> The pipe(8) manual page gives a detailed description of the +above command line arguments, and more. </p> + +<p> If you want to support user+extension@domain style addresses, +use the following instead: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + maildrop unix - n n - - pipe + flags=ODRhu user=vmail argv=/path/to/maildrop + -d ${user}@${domain} ${extension} ${recipient} ${user} ${nexthop} +</pre> +</blockquote> + +<p> The mail is delivered to ${user}@${domain} (search key for +maildrop userdb lookup). The ${extension} and the other address +components are available to maildrop rules as $1, $2, $3, ... and +can be omitted from master.cf or ignored by maildrop when not +needed. </p> + +<p> With Postfix 2.4 and earlier, use ${nexthop} instead of ${domain}. +</p> + +<h2><a name="indirect">Indirect delivery via the local delivery agent</a></h2> + +<p> Postfix can be configured to deliver mail to maildrop via the +local delivery agent. This is slightly less efficient than the +"direct" approach discussed above, but gives you the convenience +of local aliases(5) expansion and $HOME/.forward file processing. +You would typically use this for domains that are listed in +mydestination and that have users with a UNIX system account. </p> + +<p> To configure maildrop delivery for all UNIX system accounts: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + mailbox_command = /path/to/maildrop -d ${USER} +</pre> +</blockquote> + +<p> Note: ${USER} is spelled in upper case. </p> + +<p> To enable maildrop delivery for specific users only, you can +use the Postfix local(8) delivery agent's mailbox_command_maps feature: +</p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + mailbox_command_maps = hash:/etc/postfix/mailbox_commands + +/etc/postfix/mailbox_commands: + you /path/to/maildrop -d ${USER} +</pre> +</blockquote> + +<p> Maildrop delivery for specific users is also possible by +invoking it from the user's $HOME/.forward file: </p> + +<blockquote> +<pre> +/home/you/.forward: + "|/path/to/maildrop -d ${USER}" +</pre> +</blockquote> + +<h2><a name="credits">Credits</a></h2> + +<ul> + +<li> The original text was kindly provided by Russell Mosemann. + +<li> Victor Duchovni provided tips for supporting user+foo@domain +addresses. + +<li> Tonni Earnshaw contributed text about delivery via the local(8) +delivery agent. + +</ul> + +</body> + +</html> diff --git a/proto/MAILLOG_README.html b/proto/MAILLOG_README.html new file mode 100644 index 0000000..5a19a92 --- /dev/null +++ b/proto/MAILLOG_README.html @@ -0,0 +1,183 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix logging to file or stdout</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +logging to file or stdout</h1> + +<hr> + +<h2>Overview </h2> + +<p> Postfix supports it own logging system as an alternative to +syslog (which remains the default). This is available with Postfix +version 3.4 or later. </p> + +<p> Topics covered in this document: </p> + +<ul> + +<li><a href="#log-to-file">Configuring logging to file</a> + +<li><a href="#log-to-stdout">Configuring logging to stdout</a> + +<li><a href="#logrotate">Rotating logs </a> + +<li><a href="#limitations">Limitations</a> + +</ul> + +<h2> <a name="log-to-file"> Configuring logging to file </a> </h2> + +<p> Logging to file solves a usability problem for MacOS, and +eliminates multiple problems for systemd-based systems. </p> + +<ol> + +<li> <p> Add the following line to master.cf if not already present +(note: there must be no whitespace at the start of the line): </p> + +<blockquote> +<pre> +postlog unix-dgram n - n - 1 postlogd +</pre> +</blockquote> + +<p> Note: the service type "<b>unix-dgram</b>" was introduced with +Postfix 3.4. Remove the above line before backing out to an older +Postfix version. </p> + +<li> <p> Configure Postfix to write logging, to, for example, +/var/log/postfix.log. See also the "<a href="#logrotate">Logfile +rotation</a>" section below for logfile management. </p> + +<blockquote> +<pre> +# postfix stop +# postconf maillog_file=/var/log/postfix.log +# postfix start +</pre> +</blockquote> + +<p> By default, the logfile name must start with "/var" or "/dev/stdout" +(the list of allowed prefixes is configured with the maillog_file_prefixes +parameter). This safety mechanism limits the damage from a single +configuration mistake. </p> + +</ol> + +<h2> <a name="log-to-stdout"> Configuring logging to stdout </a> </h2> + +<p> Logging to stdout is useful when Postfix runs in a container, +as it eliminates a syslogd dependency. </p> + +<ol> + +<li> <p> Add the following line to master.cf if not already present (note: +there must be no whitespace at the start of the line): </p> + +<blockquote> +<pre> +postlog unix-dgram n - n - 1 postlogd +</pre> +</blockquote> + +<p> Note: the service type "<b>unix-dgram</b>" was introduced with +Postfix 3.4. Remove the above line before backing out to an older +Postfix version. </p> + +<li> <p> Configure main.cf with "maillog_file = /dev/stdout". </p> + +<li> <p> Start Postfix with "<b>postfix start-fg</b>". </p> + +</ol> + +<h2> <a name="logrotate"> Rotating logs </a> </h2> + +<p> The command "<b>postfix logrotate</b>" may be run by hand or +by a cronjob. It logs all errors, and reports errors to stderr if +run from a terminal. This command implements the following steps: +</p> + +<ul> + +<li> <p> Rename the current logfile by appending a suffix that +contains the date and time. This suffix is configured with the +maillog_file_rotate_suffix parameter (default: %Y%m%d-%H%M%S). </p> + +<li> <p> Reload Postfix so that postlogd(8) immediately closes the +old logfile. </p> + +<li> <p> After a brief pause, compress the old logfile. The compression +program is configured with the maillog_file_compressor parameter +(default: gzip). </p> + +</ul> + +<p> Notes: </p> + +<ul> + +<li> <p> This command will not rotate a logfile with a pathname under +the /dev directory, such as /dev/stdout. </p> + +<li> <p> This command does not (yet) remove old logfiles. </p> + +</ul> + +<h2> <a name="limitations">Limitations</a> </h2> + +<p> Background: </p> + +<ul> + +<li> <p> Postfix consists of a number of daemon programs that run +in the background, as well as non-daemon programs for local mail +submission or Postfix management. + +<li> <p> Logging to the Postfix logfile or stdout requires the Postfix +postlogd(8) service. This ensures that simultaneous logging from +different programs will not get mixed up. </p> + +<li> <p> All Postfix programs can log to syslog, but not all programs +have sufficient privileges to use the Postfix logging service, and +many non-daemon programs must not log to stdout as that would corrupt +their output. </p> + +</ul> + +<p> Limitations: </p> + +<ul> + +<li> <p> Non-daemon Postfix programs will log errors to syslogd(8) +before they have processed command-line options and main.cf parameters. + +<li> <p> If Postfix is down, the non-daemon programs postfix(1), +postsuper(1), postmulti(1), and postlog(1), will log directly to +$maillog_file. These programs expect to run with root privileges, +for example during Postfix start-up, reload, or shutdown. + +<li> <p> Other non-daemon Postfix programs will never write directly +to $maillog_file (also, logging to stdout would interfere with the +operation of some of these programs). These programs can log to +postlogd(8) if they are run by the super-user, or if their executable +file has set-gid permission. Do not set this permission on programs +other than postdrop(1) and postqueue(1). + +</ul> + +</body> + +</html> diff --git a/proto/MEMCACHE_README.html b/proto/MEMCACHE_README.html new file mode 100644 index 0000000..d144935 --- /dev/null +++ b/proto/MEMCACHE_README.html @@ -0,0 +1,76 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix memcache client Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix memcache client Howto</h1> + +<hr> + +<h2>Introduction</h2> + +<p>The Postfix memcache client allows you to hook up Postfix to a +memcache server. The current implementation supports one memcache +server per Postfix table, with one optional Postfix database that +provides persistent backup. The Postfix memcache client supports +the lookup, update, delete and sequence operations. The sequence +(i.e. first/next) operation requires a backup database that supports +this operation. </p> + +<p> Typically, the Postfix memcache client is used to reduce query +load on a persistent database, but it may also be used to query a +memory-only database for low-value, easy-to-recreate, information +such as a reputation cache for postscreen(8), verify(8) or greylisting. +</p> + +<h2>Limitations</h2> + +<ul> + +<li> <p> The Postfix memcache client cannot be used for security-sensitive +tables such as <tt>alias_maps</tt> (these may contain "<tt>|command</tt>" +and "<tt>/file/name</tt>" destinations), or <tt>virtual_uid_maps</tt>, +<tt>virtual_gid_maps</tt> and <tt>virtual_mailbox_maps</tt> (these +specify UNIX process privileges or "<tt>/file/name</tt>" destinations). +Typically, a memcache database is writable by any process that can +talk to the memcache server; in contrast, security-sensitive tables +must never be writable by the unprivileged Postfix user. </p> + +<li> <p> The Postfix memcache client requires additional configuration +when used as postscreen(8) or verify(8) cache. For details see the +<tt>backup</tt> and <tt>ttl</tt> parameter discussions in the +memcache_table(5) manual page. </p> + +</ul> + +<h2>Building Postfix with memcache support</h2> + +<p>The Postfix memcache client has no external dependencies, +and is therefore built into Postfix by default. </p> + +<h2>Configuring memcache lookup tables</h2> + +<p> Configuration is described in the memcache_table(5) manpage. </p> + +<h2>Credits</h2> + +<p> The first memcache client for Postfix was written by Omar Kilani, +and was based on the libmemcache library. </p> + +<p> Wietse wrote the current memcache client from the ground up for +Postfix version 2.9. This implementation does not use libmemcache, +and bears no resemblance to earlier work. </p> + +</body> + +</html> diff --git a/proto/MILTER_README.html b/proto/MILTER_README.html new file mode 100644 index 0000000..a0d5ac6 --- /dev/null +++ b/proto/MILTER_README.html @@ -0,0 +1,952 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix before-queue Milter support </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix before-queue Milter support </h1> + +<hr> + +<h2>Introduction</h2> + +<p> Postfix implements support for the Sendmail version 8 Milter +(mail filter) protocol. This protocol is used by applications that +run outside the MTA to inspect SMTP events (CONNECT, DISCONNECT), +SMTP commands (HELO, MAIL FROM, etc.) as well as mail content +(headers and body). All this happens before mail is queued. </p> + +<p> The reason for adding Milter support to Postfix is that there +exists a large collection of applications, not only to block unwanted +mail, but also to verify authenticity (examples: <a +href="http://www.opendkim.org/">OpenDKIM</a> and <a +href="http://www.trusteddomain.org/opendmarc/">DMARC </a>) +or to digitally sign mail (example: <a +href="http://www.opendkim.org/">OpenDKIM</a>). +Having yet another Postfix-specific version of all that software +is a poor use of human and system resources. </p> + +<p> The Milter protocol has evolved over time, and different Postfix +versions implement different feature sets. See the <a +href="#workarounds">workarounds</a> and <a +href="#limitations">limitations</a> sections at the end of this +document for differences between Postfix and Sendmail implementations. +</p> + +<p> This document provides information on the following topics: </p> + +<ul> + +<li><a href="#plumbing">How Milter applications plug into Postfix </a> + +<li><a href="#building">Building Milter applications</a> + +<li><a href="#running">Running Milter applications</a> + +<li><a href="#config">Configuring Postfix</a> + +<li><a href="#workarounds">Workarounds</a> + +<li><a href="#limitations">Limitations</a> + +</ul> + +<h2><a name="plumbing">How Milter applications plug into Postfix </a> </h2> + +<p> The Postfix Milter implementation uses two different lists of +mail filters: one list of filters for SMTP mail only, +and one list of filters for non-SMTP mail. The two +lists have different capabilities, which is unfortunate. Avoiding +this would require major restructuring of Postfix. </p> + +<ul> + +<li> <p> The SMTP-only filters handle mail that arrives via the +Postfix smtpd(8) server. They are typically used to filter unwanted +mail and to sign mail from authorized SMTP clients. You specify +SMTP-only Milter applications with the smtpd_milters parameter as +described in a later section. Mail that arrives via the Postfix +smtpd(8) server is not filtered by the non-SMTP filters that are +described next. </p> + +<li> <p> The non-SMTP filters handle mail that arrives via the +Postfix sendmail(1) command-line or via the Postfix qmqpd(8) server. +They are typically used to digitally sign mail only. Although +non-SMTP filters can be used to filter unwanted mail, they have +limitations compared to the SMTP-only filters. You specify non-SMTP +Milter applications with the non_smtpd_milters parameter as described +in a later section. </p> + +</ul> + +<p> For those who are familiar with the Postfix architecture, the +figure below shows how Milter applications plug into Postfix. Names +followed by a number are Postfix commands or server programs, while +unnumbered names inside shaded areas represent Postfix queues. To +avoid clutter, the path for local submission is simplified (the +OVERVIEW document has a more complete description of the Postfix +architecture). </p> + +<blockquote> + +<table> + +<tr> + +<td colspan="2"> </td> + +<td align="center"> SMTP-only <br> filters </td> + +<td> </td> + +<td align="center"> non-SMTP <br> filters </td> + +</tr> + +<tr> + +<td colspan="2"> </td> + +<td align="center"> <table> <tr> <td align="center"> +^<br> <tt> | </tt> </td> <td align="center"> <tt> |<br> v </tt> +</td> </tr> </table> </td> + +<td rowspan="2"> </td> + +<td rowspan="3" align="center"> <table> <tr> <td align="center"> +^<br> <tt> |<br> |<br> | </tt> </td> <td align="center"> <tt> |<br> +|<br> |<br> v </tt> </td> </tr> </table> </td> + +</tr> + +<tr> + +<td> Network </td> <td> <tt> -> </tt> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> smtpd(8) +</td> + +</tr> + +<tr> + +<td colspan="3"> </td> <td> <tt> \ </tt> </td> + +</tr> + +<tr> + +<td> Network </td> <td> <tt> -> </tt> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> qmqpd(8) +</td> + +<td> <tt> -> </tt> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> cleanup(8) +</td> + +<td> <tt> -> </tt> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> <a +href="QSHAPE_README.html#incoming_queue"> incoming </a> </td> + +</tr> + +<tr> + +<td colspan="3"> </td> <td> <tt> / </tt> </td> + +</tr> + +<tr> + +<td colspan="2"> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> pickup(8) +</td> + +</tr> + +<tr> <td colspan="2"> </td> <td align="center"> : </td> </tr> + +<tr> + +<td> Local </td> <td> <tt> -> </tt> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> sendmail(1) +</td> + +</tr> + +</table> + +</blockquote> + +<h2><a name="building">Building Milter applications</a></h2> + +<p> Milter applications have been written in C, JAVA and Perl, but +this document deals with C applications only. For these, you need +an object library that implements the Sendmail 8 Milter protocol. +Postfix currently does not provide such a library, but Sendmail +does. </p> + +<p> Some +systems install the Sendmail libmilter library by default. With +other systems, libmilter may be provided by a package (called +"sendmail-devel" on some Linux systems). </p> + +<p> Once libmilter is installed, applications such as <a +href="http://www.opendkim.org/">OpenDKIM</a> and +<a href="http://www.trusteddomain.org/opendmarc/">OpenDMARC</a> +build out of the box without requiring any tinkering:</p> + +<blockquote> +<pre> +$ <b>gzcat opendkim-<i>x.y.z</i>.tar.gz | tar xf -</b> +$ <b>cd opendkim-<i>x.y.z</i></b> +$ <b>./configure ...<i>options</i>...</b> +$ <b>make</b> +[...<i>lots of output omitted</i>...] +$ <b>make install</b> +</pre> +</blockquote> + +<h2><a name="running">Running Milter applications</a></h2> + +<p> To run a Milter application, see the documentation of the filter +for options. A typical command looks like this:</p> + +<blockquote> +<pre> +# <b>/some/where/opendkim -l -u <i>userid</i> -p inet:<i>portnumber</i>@localhost ...<i>other options</i>...</b> +</pre> +</blockquote> + +<p> Please specify a <i>userid</i> value that isn't used for other +applications (not "postfix", not "www", etc.). </p> + +<h2><a name="config">Configuring Postfix</a></h2> + +<p> Like Sendmail, Postfix has a lot of configuration options that +control how it talks to Milter applications. Besides global options +that apply to all Milter applications, Postfix 3.0 and later +support per-Milter timeouts, per-Milter error handling, etc. </p> + +<p> Information in this section: </p> + +<ul> + +<li><a href="#smtp-only-milters">SMTP-Only Milter applications </a> + +<li><a href="#non-smtp-milters">Non-SMTP Milter applications </a> + +<li><a href="#errors">Milter error handling </a> + +<li><a href="#version">Milter protocol version</a> + +<li><a href="#timeouts">Milter protocol timeouts</a> + +<li><a href="#per-milter">Different settings for different Milter +applications </a> + +<li><a href="#per-client">Different settings for different SMTP +clients </a> + +<li><a href="#macros">Sendmail macro emulation</a> + +<li><a href="#send-macros">What macros will Postfix send to Milters?</a> + +</ul> + +<h3><a name="smtp-only-milters">SMTP-Only Milter applications</a></h3> + +<p> The SMTP-only Milter applications handle mail that arrives via +the Postfix smtpd(8) server. They are typically used to filter +unwanted mail, and to sign mail from authorized SMTP clients. Mail +that arrives via the Postfix smtpd(8) server is not filtered by the +non-SMTP filters that are described in the next section. </p> + +<blockquote> NOTE for Postfix versions that have a mail_release_date +before 20141018: do not use the header_checks(5) IGNORE action to remove +Postfix's own Received: message header. This causes problems with +mail signing filters. Instead, keep Postfix's own Received: message +header and use the header_checks(5) REPLACE action to sanitize +information. </blockquote> + +<p> You specify SMTP-only Milter applications (there can be more +than one) with the smtpd_milters parameter. Each Milter application +is identified by the name of its listening socket; other Milter +configuration options will be discussed in later sections. Milter +applications are applied in the order as specified, and the first +Milter application that rejects a command will override the responses +from other Milter applications. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # Milters for mail that arrives via the smtpd(8) server. + # See below for socket address syntax. + smtpd_milters = inet:localhost:<i>portnumber</i> ...<i>other filters</i>... +</pre> +</blockquote> + +<p> The general syntax for listening sockets is as follows: </p> + +<blockquote> + +<dl> + +<dt> <b>unix:</b><i>pathname</i> </dt> <dd><p>Connect to the local +UNIX-domain server that is bound to the specified pathname. If the +smtpd(8) or cleanup(8) process runs chrooted, an absolute pathname +is interpreted relative to the Postfix queue directory. On many +systems, <b>local</b> is a synonym for <b>unix</b></p> </dd> + +<dt> <b> inet:</b><i>host</i><b>:</b><i>port</i> </dt> <dd> <p> +Connect to the specified TCP port on the specified local or remote +host. The host and port can be specified in numeric or symbolic +form.</p> + +<p> NOTE: Postfix syntax differs from Milter syntax which has the +form <b>inet:</b><i>port</i><b>@</b><i>host</i>. </p> </dd> + +</dl> + +</blockquote> + +<p> For advanced configuration see "<a href="#per-client">Different +settings for different SMTP clients</a>" and "<a +href="#per-milter">Different settings for different Milter +applications</a>". </p> + +<h3> <a name="non-smtp-milters">Non-SMTP Milter applications </a> </h3> + +<p> The non-SMTP Milter applications handle mail that arrives via +the Postfix sendmail(1) command-line or via the Postfix qmqpd(8) +server. They are typically used to digitally sign mail. Although +non-SMTP filters can be used to filter unwanted mail, there are +limitations as discussed later in this section. Mail that arrives +via the Postfix smtpd(8) server is not filtered by the non-SMTP +filters. </p> + +<p> NOTE: Do not use the header_checks(5) IGNORE action to remove +Postfix's own Received: message header. This causes problems with +mail signing filters. Instead, keep Postfix's own Received: message +header and use the header_checks(5) REPLACE action to sanitize +information. </p> + +<p> You specify non-SMTP Milter applications with the non_smtpd_milters +parameter. This parameter uses the same syntax as the smtpd_milters +parameter in the previous section. As with the SMTP-only filters, +you can specify more than one Milter application; they are applied +in the order as specified, and the first Milter application that +rejects a command will override the responses from the other +applications. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # Milters for non-SMTP mail. + # See below for socket address syntax. + non_smtpd_milters = inet:localhost:<i>portnumber</i> ...<i>other filters</i>... +</pre> +</blockquote> + +<p> There's one small complication when using Milter applications +for non-SMTP mail: there is no SMTP session. To keep Milter +applications happy, the Postfix cleanup(8) server actually has to +simulate the SMTP client CONNECT and DISCONNECT events, and the +SMTP client EHLO, MAIL FROM, RCPT TO and DATA commands. </p> + +<ul> + +<li> <p> When new mail arrives via the sendmail(1) command line, +the Postfix cleanup(8) server pretends that the mail arrives with +ESMTP from "localhost" with IP address "127.0.0.1". The result is +very similar to what happens with command line submissions in +Sendmail version 8.12 and later, although Sendmail uses a different +mechanism to achieve this result. </p> + +<li> <p> When new mail arrives via the qmqpd(8) server, the Postfix +cleanup(8) server pretends that the mail arrives with ESMTP, and +uses the QMQPD client hostname and IP address. </p> + +<li> <p> When old mail is re-injected into the queue with "postsuper +-r", the Postfix cleanup(8) server uses the same client information +that was used when the mail arrived as new mail. </p> + +</ul> + +<p> This generally works as expected, with only one exception: +non-SMTP filters must not REJECT or TEMPFAIL simulated RCPT TO +commands. When a non_smtpd_milters application REJECTs or TEMPFAILs +a recipient, Postfix will report a configuration error, and mail +will stay in the queue. </p> + +<h4> Signing internally-generated bounce messages </h4> + +<p> Postfix normally does not apply content filters to mail +that is generated internally such as bounces or Postmaster +notifications. Filtering internally-generated bounces would result +in loss of mail when a filter rejects a message, as the resulting +double-bounce message would almost certainly also be blocked. </p> + +<p> To sign Postfix's own bounce messages, enable filtering of +internally-generated bounces (line 2 below), and don't reject any +internally-generated bounces with non_smtpd_milters, header_checks +or body_checks (lines 3-5 below). </p> + +<blockquote> +<pre> +1 /etc/postfix/main.cf: +2 internal_mail_filter_classes = bounce +3 non_smtpd_milters = <i>don't reject internally-generated bounces</i> +4 header_checks = <i>don't reject internally-generated bounces</i> +5 body_checks = <i>don't reject internally-generated bounces</i> +</pre> +</blockquote> + +<h3><a name="errors">Milter error handling</a></h3> + +<p> The milter_default_action parameter specifies how Postfix handles +Milter application errors. The default action is to respond with a +temporary error status, so that the client will try again later. +Specify "accept" if you want to receive mail as if the filter does +not exist, and "reject" to reject mail with a permanent status. +The "quarantine" action is like "accept" but freezes the message +in the "hold" queue, and is available with Postfix 2.6 or later. +</p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # What to do in case of errors? Specify accept, reject, tempfail, + # or quarantine (Postfix 2.6 or later). + milter_default_action = tempfail +</pre> +</blockquote> + +<p> See "<a href="#per-milter">Different settings for different +Milter applications</a>" for advanced configuration options. </p> + +<h3><a name="version">Milter protocol version</a></h3> + +<p> As Postfix is not built with the Sendmail libmilter library, +you may need to configure the Milter protocol version that Postfix +should use. The default version is 6 (before Postfix 2.6 the default +version is 2). </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # Postfix ≥ 2.6 + milter_protocol = 6 + # 2.3 ≤ Postfix ≤ 2.5 + milter_protocol = 2 +</pre> +</blockquote> + +<p> If the Postfix milter_protocol setting specifies a too low +version, the libmilter library will log an error message like this: +</p> + +<blockquote> +<pre> +<i>application name</i>: st_optionneg[<i>xxxxx</i>]: 0x<i>yy</i> does not fulfill action requirements 0x<i>zz</i> +</pre> +</blockquote> + +<p> The remedy is to increase the Postfix milter_protocol version +number. See, however, the <a href="#limitations">limitations</a> +section below for features that aren't supported by Postfix. </p> + +<p> With Postfix 2.7 and earlier, if the Postfix milter_protocol +setting specifies a too high +version, the libmilter library simply hangs up without logging a +warning, and you see a Postfix warning message like one of the +following: </p> + +<blockquote> +<pre> +warning: milter inet:<i>host</i>:<i>port</i>: can't read packet header: Unknown error : 0 +warning: milter inet:<i>host</i>:<i>port</i>: can't read packet header: Success +warning: milter inet:<i>host</i>:<i>port</i>: can't read SMFIC_DATA reply packet header: No such file or directory +</pre> +</blockquote> + +<p> The remedy is to lower the Postfix milter_protocol version +number. Postfix 2.8 and later will automatically turn off protocol +features that the application's libmilter library does not expect. +</p> + +<p> See "<a href="#per-milter">Different settings for different +Milter applications</a>" for advanced configuration options. </p> + +<h3><a name="timeouts">Milter protocol timeouts</a></h3> + +<p> Postfix uses different time limits at different Milter protocol +stages. The table shows the timeout settings and the corresponding +protocol stages +(EOH = end of headers; EOM = end of message). </p> + +<blockquote> + +<table border="1"> + +<tr> <th> Postfix parameter </th> <th> Time limit </th> <th> Milter +protocol stage</th> </tr> + +<tr> <td> milter_connect_timeout </td> <td> 30s </td> <td> CONNECT +</td> </tr> + +<tr> <td> milter_command_timeout </td> <td> 30s </td> <td> HELO, +MAIL, RCPT, DATA, UNKNOWN </td> </tr> + +<tr> <td> milter_content_timeout </td> <td> 300s </td> <td> HEADER, +EOH, BODY, EOM </td> </tr> + +</table> + +</blockquote> + +<p> Beware: 30s may be too short for Milter applications that do +lots of DNS lookups. However, if you increase the above timeouts +too much, remote SMTP clients may hang up and mail may be delivered +multiple times. This is an inherent problem with before-queue +filtering. </p> + +<p> See "<a href="#per-milter">Different settings for different +Milter applications</a>" for advanced configuration options. </p> + +<h3><a name="per-milter">Different settings for different Milter +applications </a></h3> + +<p> The previous sections list a number of Postfix main.cf parameters +that control time limits and other settings for all Postfix Milter +clients. This is sufficient for simple configurations. With more +complex configurations it becomes desirable to have different +settings for different Milter clients. This is supported with Postfix +3.0 and later. </p> + +<p> The following example shows a "non-critical" Milter client with +a short connect timeout, and with "accept" as default action when +the service is unvailable. </p> + +<blockquote> +<pre> +1 /etc/postfix/main.cf: +2 smtpd_milters = { inet:host:port, +3 connect_timeout=10s, default_action=accept } +</pre> +</blockquote> + +<p> Instead of a server endpoint, we now have a list enclosed in {}. </p> + +<ul> + +<li> <p> Line 2: The first item in the list is the server endpoint. +This supports the exact same "inet" and "unix" syntax as described +earlier. </p> + +<li> <p> Line 3: The remainder of the list contains per-Milter +settings. These settings override global main.cf parameters, and +have the same name as those parameters, without the "milter_" prefix. +The per-Milter settings that are supported as of Postfix 3.0 are +command_timeout, connect_timeout, content_timeout, default_action, +and protocol. </p> + +</ul> + +<p> Inside the list, syntax is similar to what we already know from +main.cf: items separated by space or comma. There is one difference: +<b>you must enclose a setting in parentheses, as in "{ name = value +}", if you want to have space or comma within a value or around +"="</b>. </p> + +<h3><a name="per-client">Different settings for different SMTP +clients </a></h3> + +<p> The smtpd_milter_maps feature supports different Milter settings +for different client IP addresses. Lookup results override the the +global smtpd_milters setting, and have the same syntax. For example, +to disable Milter settings for local address ranges: </p> + +<pre> +/etc/postfix/main.cf: + smtpd_milter_maps = cidr:/etc/postfix/smtpd_milter_map + smtpd_milters = inet:host:port, { inet:host:port, ... }, ... + +/etc/postfix/smtpd_milter_map: + # Disable Milters for local clients. + 127.0.0.0/8 DISABLE + 192.168.0.0/16 DISABLE + ::/64 DISABLE + 2001:db8::/32 DISABLE +</pre> + +<p> This feature is available with Postfix 3.2 and later. </p> + +<h3><a name="macros">Sendmail macro emulation</a></h3> + +<p> Postfix emulates a limited number of Sendmail macros, as shown +in the table. Some macro values depend on whether a recipient is +rejected (rejected recipients are available on request by the Milter +application). Different macros are available at different Milter +protocol stages (EOH = end-of-header, EOM = end-of-message); their +availability is not +always the same as in Sendmail. See the <a +href="#workarounds">workarounds</a> section below for solutions. +</p> + +<blockquote> + +<table border="1"> + +<tr> <th> Sendmail macro </th> <th> Milter protocol stage </th> +<th> Description </th> </tr> + +<tr> <td> i </td> <td> DATA, EOH, EOM </td> <td> Queue ID, also +Postfix queue file name </td> </tr> + +<tr> <td> j </td> <td> Always </td> <td> Value of myhostname </td> +</tr> + +<tr> <td> _ </td> <td> Always </td> <td> The validated client name +and address </td> </tr> + +<tr> <td> {auth_authen} </td> <td> MAIL, DATA, EOH, EOM </td> <td> SASL +login name </td> </tr> + +<tr> <td> {auth_author} </td> <td> MAIL, DATA, EOH, EOM </td> <td> SASL +sender </td> </tr> + +<tr> <td> {auth_type} </td> <td> MAIL, DATA, EOH, EOM </td> <td> SASL +login method </td> </tr> + +<tr> <td> {client_addr} </td> <td> Always </td> <td> Remote client +IP address </td> </tr> + +<tr> <td> {client_connections} </td> <td> CONNECT </td> <td> +Connection concurrency for this client (zero if the client is +excluded from all smtpd_client_* limits). </td> </tr> + +<tr> <td> {client_name} </td> <td> Always </td> <td> Remote client +hostname <br> When address → name lookup or name → address +verification fails: "unknown" </td> </tr> + +<tr> <td> {client_port} </td> <td> Always (Postfix ≥2.5) </td> +<td> Remote client TCP port </td> </tr> + +<tr> <td> {client_ptr} </td> <td> CONNECT, HELO, MAIL, DATA </td> +<td> Client name from address → name lookup <br> When address +→ name lookup fails: "unknown" </td> </tr> + +<tr> <td> {cert_issuer} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> <td> +TLS client certificate issuer </td> </tr> + +<tr> <td> {cert_subject} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> +<td> TLS client certificate subject </td> </tr> + +<tr> <td> {cipher_bits} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> <td> +TLS session key size </td> </tr> + +<tr> <td> {cipher} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> <td> TLS +cipher </td> </tr> + +<tr> <td> {daemon_addr} </td> <td> Always (Postfix ≥3.2) </td> +<td> Local server IP address </td> </tr> + +<tr> <td> {daemon_name} </td> <td> Always </td> <td> value of +milter_macro_daemon_name </td> </tr> + +<tr> <td> {daemon_port} </td> <td> Always (Postfix ≥3.2) </td> +<td> Local server TCP port </td> </tr> + +<tr> <td> {mail_addr} </td> <td> MAIL </td> <td> Sender address +</td> </tr> + +<tr> <td> {mail_host} </td> <td> MAIL (Postfix ≥ 2.6, only with +smtpd_milters) </td> <td> Sender next-hop destination </td> </tr> + +<tr> <td> {mail_mailer} </td> <td> MAIL (Postfix ≥ 2.6, only with +smtpd_milters) </td> <td> Sender mail delivery transport </td> </tr> + +<tr> <td> {rcpt_addr} </td> <td> RCPT </td> <td> Recipient address +<br> With rejected recipient: descriptive text </td> </tr> + +<tr> <td> {rcpt_host} </td> <td> RCPT (Postfix ≥ 2.6, only with +smtpd_milters) </td> <td> Recipient next-hop destination <br> With +rejected recipient: enhanced status code </td> </tr> + +<tr> <td> {rcpt_mailer} </td> <td> RCPT (Postfix ≥ 2.6, only with +smtpd_milters) </td> <td> Recipient mail delivery transport <br> +With rejected recipient: "error" </td> </tr> + +<tr> <td> {tls_version} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> +<td> TLS protocol version </td> </tr> + +<tr> <td> v </td> <td> Always </td> <td> value of milter_macro_v +</td> </tr> + +</table> + +</blockquote> + +<h3><a name="send-macros">What macros will Postfix send to Milters?</a></h3> + +<p> Postfix sends specific sets of macros at different Milter protocol +stages. The sets are configured with the parameters as shown in the +table below (EOH = end of headers; EOM = end of message). The +protocol version is a number that Postfix sends at the beginning +of the Milter protocol handshake. </p> + +<p> As of Sendmail 8.14.0, Milter applications can specify what +macros they want to receive at different Milter protocol stages. +An application-specified list takes precedence over a Postfix-specified +list. </p> + +<blockquote> + +<table border="1"> + +<tr> <th> Postfix parameter </th> <th> Milter protocol version </th> +<th> Milter protocol stage </th> </tr> + +<tr> <td> milter_connect_macros </td> <td> 2 or higher </td> <td> +CONNECT </td> </tr> + +<tr> <td> milter_helo_macros </td> <td> 2 or higher </td> <td> +HELO/EHLO </td> </tr> + +<tr> <td> milter_mail_macros </td> <td> 2 or higher </td> <td> MAIL +FROM </td> </tr> + +<tr> <td> milter_rcpt_macros </td> <td> 2 or higher </td> <td> RCPT +TO </td> </tr> + +<tr> <td> milter_data_macros </td> <td> 4 or higher </td> <td> DATA +</td> </tr> + +<tr> <td> milter_end_of_header_macros </td> <td> 6 or higher </td> +<td> EOH </td> </tr> + +<tr> <td> milter_end_of_data_macros </td> <td> 2 or higher </td> +<td> EOM </td> </tr> + +<tr> <td> milter_unknown_command_macros </td> <td> 3 or higher </td> +<td> unknown command </td> </tr> + +</table> + +</blockquote> + +<p> By default, Postfix will send only macros whose values have been +updated with information from main.cf or master.cf, from an SMTP session +(for example; SASL login, or TLS certificates) or from a Mail delivery +transaction (for example; queue ID, sender, or recipient). </p> + +<p> To force a macro to be sent even when its value has not been updated, +you may specify macro default values with the milter_macro_defaults +parameter. Specify zero or more <i>name=value</i> pairs separated by +comma or whitespace; you may even specify macro names that Postfix does +not know about! </p> + +<h2><a name="workarounds">Workarounds</a></h2> + +<ul> + +<li> <p> To avoid breaking DKIM etc. signatures with an SMTP-based +content filter, update the before-filter SMTP client in master.cf, +and add a line with "-o disable_mime_output_conversion=yes" (note: +no spaces around the "="). For details, see the <a +href="FILTER_README.html#advanced_filter">advanced content filter</a> +example. </p> + +<pre> +/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 + -o smtp_generic_maps= +</pre> + +<li> <p> Some Milter applications use the "<tt>{if_addr}</tt>" macro +to recognize local mail; this macro does not exist in Postfix. +Workaround: use the "<tt>{daemon_addr}</tt>" (Postfix ≥ 3.2) or +"<tt>{client_addr}</tt>" macro instead. </p> + +<li> <p> Some Milter applications log a warning that looks like +this: </p> + +<blockquote> <pre> +sid-filter[36540]: WARNING: sendmail symbol 'i' not available +</pre> +</blockquote> + +<p> And they may insert an ugly message header with "unknown-msgid" +like this: </p> + +<blockquote> +<pre> +X-SenderID: Sendmail Sender-ID Filter vx.y.z host.example.com <unknown-msgid> +</pre> +</blockquote> + +<p> The problem is that Milter applications expect that the queue +ID is known <i>before</i> the MTA accepts the MAIL FROM (sender) +command. Postfix does not choose a queue ID, which is used as the +queue file name, until <i>after</i> it accepts the first valid RCPT +TO (recipient) command. </p> + +<p> If you experience the ugly header problem, see if a recent +version of the Milter application fixes it. For example, current +versions of dkim-filter and dk-filter already have code that looks +up the Postfix queue ID at a later protocol stage, and sid-filter +version 1.0.0 no longer includes the queue ID in the message header. +</p> + +<p> To fix the ugly message header, you will need to add code that +looks up the Postfix queue ID at some later point in time. The +example below adds the lookup after the end-of-message. </p> + +<ul> + +<li> <p> Edit the filter source file (typically named +<tt>xxx-filter/xxx-filter.c</tt> or similar). </p> + +<li> <p> Look up the <tt>mlfi_eom()</tt> function and add code near +the top shown as <b>bold</b> text below: </p> + +</ul> + +<blockquote> +<pre> +dfc = cc->cctx_msg; +assert(dfc != NULL); +<b> +/* Determine the job ID for logging. */ +if (dfc->mctx_jobid == 0 || strcmp(dfc->mctx_jobid, JOBIDUNKNOWN) == 0) { + char *jobid = smfi_getsymval(ctx, "i"); + if (jobid != 0) + dfc->mctx_jobid = jobid; +}</b> +</pre> +</blockquote> + +<p> NOTES: </p> + +<ul> + +<li> <p> Different mail filters use slightly different names for +variables. If the above code does not compile, look elsewhere in +the mail filter source file for code that looks up the "i" macro +value, and copy that code. </p> + +<li> <p> This change fixes only the ugly message header, but not +the WARNING message. Fortunately, many Milters log that message +only once. </p> + +</ul> + +</ul> + +<h2><a name="limitations">Limitations</a></h2> + +<p> This section lists limitations of the Postfix Milter implementation. +Some limitations will be removed as the implementation is extended +over time. Of course the usual limitations of before-queue filtering +will always apply. See the CONTENT_INSPECTION_README document for +a discussion. </p> + +<ul> + +<li> <p> The Milter protocol has evolved over time. Therefore, +different Postfix versions implement different feature sets. </p> + +<table border="1"> + +<tr> <th> Postfix </th> <th> Supported Milter requests </th> +</tr> + +<tr> <td align="center"> 2.6 </td> <td> All Milter requests of +Sendmail 8.14.0 (see notes below). </td> </tr> + +<tr> <td align="center"> 2.5 </td> <td> All Milter requests of +Sendmail 8.14.0, except: <br> SMFIP_RCPT_REJ (report rejected +recipients to the mail filter), <br> SMFIR_CHGFROM (replace sender, +with optional ESMTP parameters), <br> SMFIR_ADDRCPT_PAR (add +recipient, with optional ESMTP parameters). </td> </tr> + +<tr> <td align="center"> 2.4 </td> <td> All Milter requests of +Sendmail 8.13.0. </td> </tr> + +<tr> <td align="center"> 2.3 </td> <td> All Milter requests of +Sendmail 8.13.0, except: <br> SMFIR_REPLBODY (replace message body). + +</table> + +<li> <p> For Milter applications that are written in C, you need +to use the Sendmail libmilter library. </p> + +<li> <p> Postfix has TWO sets of mail filters: filters that are used +for SMTP mail only (specified with the smtpd_milters parameter), +and filters for non-SMTP mail (specified with the non_smtpd_milters +parameter). The non-SMTP filters are primarily for local submissions. +</p> + +<p> When mail is filtered by non_smtpd_milters, the Postfix cleanup(8) +server has to simulate SMTP client requests. This works as expected, +with only one exception: non_smtpd_milters must not REJECT or +TEMPFAIL simulated RCPT TO commands. When this rule is violated, +Postfix will report a configuration error, and mail will stay in +the queue. </p> + +<li> <p> When you use the before-queue content filter for incoming +SMTP mail (see SMTPD_PROXY_README), Milter applications have access +only to the SMTP command information; they have no access to the +message header or body, and cannot make modifications to the message +or to the envelope. </p> + +<li> <p> Postfix 2.6 ignores the optional ESMTP parameters in +requests to replace the sender (SMFIR_CHGFROM) or to append a +recipient (SMFIR_ADDRCPT_PAR). Postfix logs a warning message when +a Milter application supplies such ESMTP parameters: </p> + +<pre> +warning: <i>queue-id</i>: cleanup_chg_from: ignoring ESMTP arguments "<i>whatever</i>" +warning: <i>queue-id</i>: cleanup_add_rcpt: ignoring ESMTP arguments "<i>whatever</i>" +</pre> + +<li> <p> Postfix 2.3 does not implement requests to replace the +message body. Milter applications log a warning message when they +need this unsupported operation: </p> + +<pre> +st_optionneg[134563840]: 0x3d does not fulfill action requirements 0x1e +</pre> + +<p> The solution is to use Postfix version 2.4 or later. </p> + +<li> <p> Most Milter configuration options are global. Future Postfix +versions may support per-Milter timeouts, per-Milter error handling, +etc. </p> + +</ul> + +</body> + +</html> diff --git a/proto/MULTI_INSTANCE_README.html b/proto/MULTI_INSTANCE_README.html new file mode 100644 index 0000000..196f804 --- /dev/null +++ b/proto/MULTI_INSTANCE_README.html @@ -0,0 +1,1274 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Managing multiple Postfix instances on a single host</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Managing +multiple Postfix instances on a single host</h1> + +<hr> + +<h2>Overview </h2> + +<p> This document is a guide to managing multiple Postfix instances +on a single host using the postmulti(1) instance manager. Multi-instance +support is available with Postfix version 2.6 and later. See the +postfix-wrapper(5) manual page for background on the instance +management framework, and on how to deploy a custom instance manager. +</p> + +<p> Topics covered in this document: </p> + +<ul> + +<li><a href="#why"> Why multiple Postfix instances </a> + +<li><a href="#split"> Null-client instances versus service instances </a> + +<li><a href="#quick"> Multi-instance walk-through </a> + +<li><a href="#parts"> Components of a Postfix system </a> + +<li><a href="#default"> The default Postfix instance </a> + +<li><a href="#group"> Instance groups </a> + +<li><a href="#params"> Multi-instance configuration parameters </a> + +<li><a href="#how"> Using the postmulti(1) command </a> + +<li><a href="#credits"> Credits </a> + +</ul> + +<h2><a name="why"> Why multiple Postfix instances </a></h2> + +<p> Postfix is a general-purpose mail system that can be configured +to serve a variety of needs. Examples of Postfix applications are: </p> + +<ul> + +<li><p> Local mail submission for shell users and system processes. </p> + +<li><p> Incoming (MX host) email from the Internet. </p> + +<li><p> Outbound mail relay for a corporate network. </p> + +<li><p> Authenticated submission for roaming users. </p> + +<li><p> Before/after content-filter mail. </p> + +</ul> + +<p> A single Postfix configuration can provide many or all of these +services, but a complex interplay of settings may be required, for +example with master.cf options overriding main.cf settings. In this +document we take the view that multiple Postfix instances may be a +simpler way to configure a multi-function Postfix system. With +multiple Postfix instances, each instance has its own directories +for configuration, queue and data files, but it shares all Postfix +program and documentation files with other instances. </p> + +<p> Since there is no single right way to configure your system, +we recommend that you choose what makes you most comfortable. If +different Postfix services don't involve incompatible main.cf or +master.cf settings, and if they can be combined together without +complex tricks, then a single monolithic configuration may be the +simplest approach. </p> + +<p> The purpose of multi-instance support in Postfix is not to force +you to create multiple Postfix instances, but rather to give you a +choice. Multiple instances give you the freedom to tune each Postfix +instance to a single task that it does well and to combine instances +into complete systems. </p> + +<p> With the introduction of the postmulti(1) utility and the reduction +of the per-instance configuration footprint of a secondary Postfix +instance to just a main.cf and master.cf file (other files are now in +shared locations), we hope that multiple instances will be easier to +use than ever before. </p> + +<h2><a name="split"> Null-client instances versus service instances </a></h2> + +<p> In the multi-instance approach to configuring Postfix, the first +simplification is with the default local-submission Postfix instance. +</p> + +<p> Most UNIX systems require support for email submission with the +sendmail(1) command so that system processes such as cron jobs can +send status reports, and so that system users can send email with +command-line utilities. Such email can be handled with a <a +href="STANDARD_CONFIGURATION_README.html#null_client">null-client</a> +Postfix configuration that forwards all mail to a central mail hub. +The null client will typically either not run an SMTP listener at +all (master_service_disable = inet), or it will listen only on the +loopback interface (inet_interfaces = loopback-only). </p> + +<p> When implementing specialized servers for inbound Internet +email, outbound MTAs, internal mail hubs, and so on, we recommend +using a null client for local submission and creating single-function +secondary Postfix instances to serve the specialized needs. </p> + +<blockquote> + +<p> Note: usually, you need to use different "myhostname" settings +when you run multiple instances on the same host. Otherwise, there +will be false "mail loops back to myself" alarms when one instance +tries to send mail into another instance. Typically, the null-client +instance will use the system's hostname, and other instances will +use their own dedicated "myhostname" settings. Different names are +not needed when instances send mail to each other with a protocol +other than SMTP, or with SMTP over a TCP port other than 25 as is +usual with SMTP-based content filters. </p> + +</blockquote> + +<h2><a name="quick"> Multi-instance walk-through </a></h2> + +<p> Before discussing the fine details of multi-instance operation +we first show the steps for creating a border mail server. This +server has with a null-client Postfix instance for local submission, +an input Postfix instance to receive mail from the Internet, plus +an <a href="FILTER_README.html#advanced_filter">advanced</a> SMTP +content-filter and an output Postfix instance to deliver filtered +email to its internal destination. </p> + +<h3>Setting up the null-client Postfix instance </h3> + +<p> On a border mail hub, while mail from the Internet requires a +great deal of scrutiny, locally submitted messages are typically +limited to mail from cron jobs and other system services. In this +regard the border MTA is not different from other Unix hosts in +your environment. For this reason, it will submit locally-generated +email to the internal mail hub. We start the construction of the +border mail server with the <a href="#default_instance">default</a> +instance, which will be a local-submission <a +href="STANDARD_CONFIGURATION_README.html#null_client">null client</a>: +</p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # We are mta1.example.com + # + myhostname = mta1.example.com + mydomain = example.com + + # Flat user-account namespace in example.com: + # + # user@example.com not user@host.example.com + # + myorigin = $mydomain + + # Postfix 2.6+, disable inet services, specifically disable smtpd(8) + # + master_service_disable = inet + + # No local delivery: + # + mydestination = + local_transport = error:5.1.1 Mailbox unavailable + alias_database = + alias_maps = + local_recipient_maps = + + # Send everything to the internal mailhub + # + relayhost = [mailhub.example.com] + + # Indexed table macro: + # (use "hash", ... when <a href="CDB_README.html">cdb</a> is not available) + # + default_database_type = cdb + indexed = ${default_database_type}:${config_directory}/ + + # Expose origin host of mail from "root", ... + # + smtp_generic_maps = ${indexed}generic + + # Send messages addressed to "root", ... to the MTA support team + # + virtual_alias_maps = ${indexed}virtual + +/etc/postfix/generic: + # The smarthost supports "+" addressing (recipient_delimiter = +). + # Mail from "root" exposes the origin host, without replies + # and bounces going back to the same host. + # + # On clustered MTAs this file is typically machine-built from + # a template file. The build process expands the template into + # "mtaadmin+root=mta1" + # + root mtaadmin+root=mta1 + +/etc/postfix/virtual: + # Caretaker aliases: + # + root mtaadmin + postmaster root +</pre> +</blockquote> + +<p> You would typically also add a Makefile, to automatically run +postmap(1) commands when source files change. This Makefile also +creates a "generic" database when none exists. </p> + +<blockquote> +<pre> +/etc/postfix/Makefile: + MTAADMIN=mtaadmin + + all: virtual.cdb generic.cdb + + generic: Makefile + @echo Creating $@ + @rm -f $@.tmp + @printf '%s\t%s+root=%s\n' root ${MTAADMIN} `uname -n` > $@.tmp + @mv $@.tmp generic + + %.cdb: % + postmap cdb:$< +</pre> +</blockquote> + +<p> Construct the "virtual" and "generic" databases (the latter is +created by running "make"), then start and test the null-client: +</p> + +<blockquote> +<pre> +# cd /etc/postfix; make +# postfix start +# sendmail -i -f root -t <<EOF +From: root +To: root +Subject: test + +testing +EOF +</pre> +</blockquote> + +<p> The test message should be delivered to the members of the "mtaadmin" +address group (or whatever address group you choose) with the +following headers: </p> + +<blockquote> +<pre> +From: mtaadmin+root=mta1@example.com +To: mtadmin+root=mta1@example.com +Subject: test +</pre> +</blockquote> + +<h3>Setting up the "output" Postfix instance </h3> + +<p> With the null-client instance out of the way, we can create the +MTA "output" instance that will deliver filtered mail to the inside +network. We add the "output" instance first, because the output +instance needs to be up and running before the input instance can +be fully tested, and when the system boots, the "output" instance +must start before the input instance. We will put the output and +input instances into a single instance group named "mta". </p> + +<p> Just once, when adding the first secondary instance, enable +multi-instance support in the default (null-client) instance: </p> + +<blockquote> +<pre> +# postmulti -e init +</pre> +</blockquote> + +<p> Then create the output instance: <p> + +<blockquote> +<pre> +# postmulti -I postfix-out -G mta -e create +</pre> +</blockquote> + +<p> The instance configuration directory defaults to /etc/postfix-out, +more precisely, the "postfix-out" subdirectory of the parent directory +of the default-instance configuration directory. The new instance will +be created in a "disabled" state: </p> + +<blockquote> +<pre> +/etc/postfix-out/main.cf + # + # ... "stock" main.cf settings ... + # + multi_instance_name = postfix-out + queue_directory = /var/spool/postfix-out + data_directory = /var/lib/postfix-out + # + multi_instance_enable = no + master_service_disable = inet + authorized_submit_users = +</pre> +</blockquote> + +<p> This instance has a "stock" master.cf file, and its queue and +data directories, also named "postfix-out", will be located in the +same parent directories as the corresponding directories of the +default instance (e.g., /var/spool/postfix-out and /var/lib/postfix-out). +</p> + +<p> While this instance is immediately safe to start, it is not yet +usefully configured. It needs to be customized to fit the role of a +post-filter re-injection SMTP service. Typical additions include: </p> + +<blockquote> +<pre> +/etc/postfix-out/master.cf: + # Replace default "smtp inet" entry with one listening on port 10026. + 127.0.0.1:10026 inet n - n - - smtpd + +/etc/postfix-out/main.cf + # ... + + # Comment out if you don't use IPv6 internally + # inet_protocols = ipv4 + inet_interfaces = loopback-only + mynetworks_style = host + smtpd_authorized_xforward_hosts = $mynetworks + + # Don't anvil(8) control the re-injection port. + # + smtpd_client_connection_count_limit = 0 + smtpd_client_event_limit_exceptions = $mynetworks + + # Best practice when inet_interfaces is set, as this is not a + # "secondary IP personality" configuration. + # + smtp_bind_address = 0.0.0.0 + + # All header rewriting happens upstream + # + local_header_rewrite_clients = + + # No local delivery on border gateway + # + mydestination = + alias_maps = + alias_database = + local_recipient_maps = + local_transport = error:5.1.1 Mailbox unavailable + + # May need a recipient_delimiter for per-user transport lookups: + # + recipient_delimiter = + + + # Only one (unrestricted client) + # With multiple instances, rarely need "-o param=value" overrides + # in master.cf, each instance gets its own main.cf file. + # + # Postfix 2.10 and later: specify empty smtpd_relay_restrictions. + smtpd_relay_restrictions = + smtpd_recipient_restrictions = permit_mynetworks, reject + + # Tolerate occasional high latency in the content filter. + # + smtpd_timeout = 1200s + + # Best when empty, with all parent domain matches explicit. + # + parent_domain_matches_subdomains = + + # Use the "relay" transport for inbound mail, and the default + # "smtp" transport for outbound mail (bounces, ...). The latter + # won't starve the former of delivery agent slots. + # + relay_domains = example.com, .example.com + + # With xforward, match the input instance setting, if you + # want "yes", set both to "yes". + # + smtpd_client_port_logging = no + + # Transport settings ... + # Message size limit + # Concurrency tuning for "relay" and "smtp" transport + # ... +</pre> +</blockquote> + +<p> With the "output" configuration in place, enable and start the +instance: </p> + +<blockquote> +<pre> +1 # postmulti -i postfix-out -x postconf -e \ +2 "master_service_disable =" "authorized_submit_users = root" +3 # postmulti -i postfix-out -e enable +4 # postmulti -i postfix-out -p start +</pre> +</blockquote> + +<p> This uses the postmulti(1) command to invoke postconf(1) in the +context (MAIL_CONFIG=/etc/postfix-out) of the output instance. </p> + +<ul> + +<li> <p> Lines 1-2: With "authorized_submit_users = root", the +superuser can test the postfix-out instance with "postmulti -i +postfix-out -x sendmail -bv recipient...", but otherwise local +submission remains disabled. </p> + +<li> <p> Lines 1-2: With "master_service_disable =", the "inet" +listeners are re-enabled. </p> + +<li> <p> Line 3: The output instance is enabled for multi-instance +start/stop. </p> + +<li> <p> Line 4: The output instance is started. </p> + +</ul> + +<p> Test the output instance by submitting probe messages via "sendmail +-bv" and "telnet". For production systems, in-depth configuration tests +should be done on a lab system. The simple tests just suggested will only +confirm successful deployment of a configuration that should already be +known good. </p> + +<h3> Setting up the content-filter proxy </h3> + +<p> With the output instance ready, deploy your content-filter +proxy. Most proxies will need their own /etc/rc* start/stop script. +Some proxies, however, are started on demand by the Postfix spawn(8) +service, in which case you need to add the relevant spawn(8) entry +to the output instance master.cf file. </p> + +<p> Configure the proxy to listen on 127.0.0.1:10025 and to re-inject +filtered email to 127.0.0.1:10026. Start the proxy service if +necessary, then test the proxy via "telnet" or automated SMTP +injectors. The proxy should support the following ESMTP features: +DSN, 8BITMIME, and XFORWARD. In addition, the proxy should support +multiple mail deliveries within an SMTP session. </p> + +<h3> Setting up the input Postfix instance </h3> + +<p> The input Postfix instance receives mail from the network and +sends it through the content filter. Now we create the input instance, +also part of the "mta" instance group: </p> + +<blockquote> +<pre> +# postmulti -I postfix-in -G mta -e create +</pre> +</blockquote> + +<p> The new instance configuration directory defaults to /etc/postfix-in, +more precisely, the "postfix-in" subdirectory of the parent directory +of the default-instance configuration directory. The new instance will +be created in a "disabled" state: </p> + +<blockquote> +<pre> +/etc/postfix-in/main.cf + # + # ... "stock" main.cf settings ... + # + multi_instance_name = postfix-in + queue_directory = /var/spool/postfix-in + data_directory = /var/lib/postfix-in + # + multi_instance_enable = no + master_service_disable = inet + authorized_submit_users = +</pre> +</blockquote> + +<p> As before, make appropriate changes to main.cf and master.cf to +make the instance production ready. Consider setting "soft_bounce = yes" +during the first few hours of deployment, so you can iron-out any unexpected +"kinks". </p> + +<p> Manual testing can start with: + +<blockquote> +<pre> +/etc/postfix-in/main.cf + # Accept only local traffic, but allow impersonation: + inet_interfaces = 127.0.0.1 + smtpd_authorized_xclient_hosts = 127.0.0.1 +</pre> +</blockquote> + +<p> This allows you to use the Postfix-specific <a +href="XCLIENT_README.html">XCLIENT</a> SMTP command to safely +simulate connections from remote systems before any remote systems +are able to connect. If the test results look good, revert the above +settings to the required production values. Typical settings in the +pre-filter input instance include: </p> + +<blockquote> +<pre> +/etc/postfix-in/main.cf + # + # ... + # + + # No local delivery on border gateway + # + mydestination = + alias_maps = + alias_database = + local_recipient_maps = + local_transport = error:5.1.1 Mailbox unavailable + + # Don't rewrite remote headers + # + local_header_rewrite_clients = + + # All recipients of not yet filtered email go to the same filter together. + # + # With multiple instances, the content-filter is specified + # via transport settings not the "content_filter" transport + # switch override! Here the filter listens on local port 10025. + # + # If you need to route some users or recipient domains directly to the + # output instance bypassing the filter, just define a transport table + # with suitable entries. + # + default_transport = smtp:[127.0.0.1]:10025 + relay_transport = $default_transport + virtual_transport = $default_transport + transport_maps = + + # Pass original client log information through the filter. + # + smtp_send_xforward_command = yes + + # Avoid splitting the envelope and scanning messages multiple times. + # Match the re-injection server's recipient limit. + # + smtp_destination_recipient_limit = 1000 + + # Tolerate occasional high latency in the content filter. + # + smtp_data_done_timeout = 1200s + + # With xforward, match the output instance setting, if you + # want "yes", set both to "yes". + # + smtpd_client_port_logging = no + + # ... Lots of settings for inbound MX host ... +</pre> +</blockquote> + +<p> With the "input" instance configured, enable and start it: </p> + +<blockquote> +<pre> +# postmulti -i postfix-in -x postconf -e \ + "master_service_disable =" "authorized_submit_users = root" +# postmulti -i postfix-in -e enable +# postmulti -i postfix-in -p start +</pre> +</blockquote> + +<p> That's it. You now have a 3-instance configuration. A null-client +sending all locally submitted mail to the internal mail hub and a pair of +"mta" instances that receive mail from the Internet, pass it through a +content-filter, and then deliver it to the internal destination. </p> + +<p> Running "postfix start" or "postfix stop" will now start/stop all +three Postfix instances. You can use "postfix -c /config/path start" +to start just one instance, or use the instance name (or instance +group name) via postmulti(1): </p> + +<blockquote> +<pre> +# postmulti -i - -p stop +# postmulti -g mta -p status +# postmulti -i postfix-out -p flush +# postmulti -i postfix-in -p reload +# ... +</pre> +</blockquote> + +<p> This example ends the multi-instance "walk through". The remainder +of this document provides background information on Postfix +multi-instance support features and options. </p> + +<h2><a name="parts"> Components of a Postfix system </a></h2> + +<p> A Postfix system consists of the following components: </p> + +<p> Shared among all instances: </p> + +<ul> + +<li><p> Command-line utilities for administrators and users installed in +$command_directory, $sendmail_path, $mailq_path and $newaliases_path. </p> + +<li><p> Daemon executables, and run-time support files installed in +$daemon_directory. </p> + +<li><p> Bundled documentation, installed in $html_directory, +$manpage_directory and $readme_directory. </p> + +<li><p> Entries in /etc/passwd and /etc/group for the $mail_owner user and +$setgid_group group. The $mail_owner user provides the mail system +with a protected (non-root) execution context. The $setgid_group group +is used exclusively to support the setgid postdrop(1) and postqueue(1) +utilities (it <b>must not</b> be the primary group or secondary group +of any users, including the $mail_owner user). </p> + +</ul> + +<p> Private to each instance: </p> + +<ul> + +<li><p> The main.cf, master.cf (and other optional) configuration +files in $config_directory. </p> + +<li> <p> The maildrop, incoming, active, deferred and hold queues +in $queue_directory (which contains additional directories needed +by Postfix, and which optionally doubles as a chroot jail for Postfix +daemon processes). </p> + +<li> <p> Various caches (TLS session, address verification, ...) +in $data_directory. </p> + +</ul> + +<p> The Postfix configuration parameters mentioned above are +collectively referred to as "installation parameters". Their default +values are set when the Postfix software is built from source, and +all but one may be optionally set to a non-default value via the +main.cf file. The one parameter that (catch-22) cannot be set in +main.cf is $config_directory, as this defines the location of the +main.cf file itself. </p> + +<p> Though config_directory cannot be set in main.cf, postfix(1) and +most of the other command-line Postfix utilities allow you to specify a +non-default configuration directory via a command line option (typically +<b>-c</b>) or via the MAIL_CONFIG environment variable. In this way, +it is possible to have multiple configuration directories on the same +machine, and to have multiple running master(8) daemons each with its +own configuration files, queue directory and data directory. </p> + +<p> These multiple running copies of master(8) share the base Postfix +software. They do not (and cannot) share their configuration +directories, queue directories or data directories. </p> + +<p> Each combination of configuration directory, together with the queue +directory and data directory (specified in the corresponding main.cf file) +make up a Postfix <b>instance</b>. </p> + +<h2><a name="default"> The default Postfix instance </a></h2> + +<p> One Postfix instance is special: this is the instance whose +configuration directory is the default one compiled into the Postfix +utilities. The location of the default configuration directory is +typically /etc/postfix, and can be queried via the "postconf -d +config_directory" command. We call the instance with this configuration +directory the "default instance". </p> + +<p> The default instance is responsible for local mail submission. The +setgid postdrop(1) utility is used by the sendmail(1) local submission +program to spool messages into the <b>maildrop</b> sub-directory of the +queue directory of the default instance. </p> + +<p> Even in the rare case when "sendmail -C" is used to submit local mail +into a non-default Postfix instance, for security reasons, postdrop(1) +will consult the default main.cf file to check the validity of the +requested non-default configuration directory. </p> + +<p> So, while in most other respects, all instances are equal, the +default instance is "more equal than others". You may choose to create +additional instances, but you must have at least the default instance, +with its configuration directory in the default compiled-in location. </p> + +<h2><a name="group"> Instance groups </a></h2> + +<p> The postmulti(1) multi-instance manager supports the notion of an +instance "group". Typically, the member instances of an instance group +constitute a logical service, and are expected to all be running or all +be stopped. </p> + +<p> In many cases a single Postfix instance will be a complete logical +"service". You should define such instances as stand-alone instances +that are not members of any instance "group". The null-client +instance is an example of a non-group instance. </p> + +<p> When a logical service consists of multiple Postfix instances, +often a pair of pre-filter and post-filter instances with a content +filter proxy between them, the related instances should be members +of a single instance group (however, the content filter usually has +its own start/stop procedure that is separate from any Postfix +instance). </p> + +<p> The default instance main.cf file's $multi_instance_directories +configuration parameter lists the configuration directories of all +secondary (non-default) instances. Together with the default instance, +these secondary instances are managed by the multi-instance manager. +Instances are started in the order listed, and stopped in the +opposite order. For instances that are members of a service "group", +you should arrange to start the service back-to-front, with the +output stages started and ready to receive mail before the input +stages are started. </p> + +<h2><a name="params"> Multi-instance configuration parameters </a></h2> + +<dl> + +<dt> multi_instance_wrapper </dt> + +<dd> <p> This default-instance configuration parameter must be set +to a suitable multi-instance manager's "wrapper" program that +controls the starting, stopping, etc. of a multi-instance Postfix +system. To use the postmulti(1) manager described in this document, +this parameter should be set with the "<a href="#init">postmulti +-e init</a>" command. </p> </dd> + +<dt> multi_instance_directories </dt> + +<dd> <p> This default-instance configuration parameter specifies +an optional list of the secondary instances controlled via the +multi-instance manager. Instances are listed in their "start" order, +with the default instance always started first (if enabled). If +$multi_instance_directories is left empty, the postfix(1) command +runs with multi-instance support turned off, and none of the +multi_instance_ configuration parameters will have any effect. </p> + +<p> Do not assign a non-empty list of secondary instance configuration +directories to multi_instance_directories until you have configured a +suitable multi_instance_wrapper setting! This is best accomplished via +the "<a href="#init">postmulti -e init</a>" command. +</p> </dd> + +<dt> multi_instance_name </dt> + +<dd> <p> Each Postfix instance may be assigned a distinct name (with +"postfix -e create/import/assign -I <i>name</i>..."). This name can +be used with the postmulti(1) command-line utility to perform tasks +on the instance by name (rather than the full pathname of its +configuration directory). Choose a name that concisely captures the +role of the instance (it must start with "postfix-"). It is an +error for two instances to have the same $multi_instance_name. You +can leave an instance "nameless" by leaving this parameter at the +default empty setting. </p> + +<p> To avoid confusion in your logs, if you don't assign each +secondary instance a non-empty (distinct) $multi_instance_name, you +should make sure that the $syslog_name setting is different for +each instance. The $syslog_name parameter defaults to $multi_instance_name +when the latter is non-empty. If at all possible, the syslog_name +should start with "postfix-", this helps log parsers to identify +log entries from secondary Postfix instances. </p> </dd> + +<dt> multi_instance_group </dt> + +<dd> <p> Each Postfix instance may be assigned an "instance group" +name (with "postfix -e create/import/assign -G <i>name</i>..."). +The default (empty) value of multi_instance_group parameter indicates +a stand-alone instance that is not part of any group. The group +name can be used with the postmulti(1) command-line utility to +perform a task on the members of a group by name. Choose a single-word +group name that concisely captures the role of the group. </p> +</dd> + +<dt> multi_instance_enable </dt> + +<dd> <p> This parameter controls whether a Postfix instance will +be started by a Postfix multi-instance manager. The default value +is "no". The instance can be started explicitly with "postfix -c +/path/to/config/directory"; this is useful for testing. </p> + +<p> When an instance is disabled, the postfix(1) "start" command +is replaced by "check". </p> + +<p> Some postfix(1) commands (such as "stop", "flush", ...) require +a running Postfix instance, and skip instances that are disabled. +</p> + +<p> Other postfix(1) commands (such as "status", "set-permissions", +"upgrade-configuration", ...) do not require a running Postfix +system, and apply to all instances whether enabled or not. </p> +</dd> + +</dl> + +<p> The postmulti(1) utility can be used to create (or destroy) instances. +It can also be used to "import" or "deport" existing instances into or +from the list of managed instances. When using postmulti(1) to manage +instances, the above configuration parameters are managed for you +automatically. See below. </p> + +<h2><a name="how"> Using the postmulti(1) command </a></h2> + +<ul> + +<li><a href="#init"> Initializing the multi-instance manager </a> + +<li><a href="#list"> Listing managed instances </a> + +<li><a href="#start"> Starting or stopping a multi-instance system </a> + +<li><a href="#adhoc"> Ad-hoc multi-instance operations </a> + +<li><a href="#create"> Creating a new Postfix instance </a> + +<li><a href="#destroy"> Destroying a Postfix instance </a> + +<li><a href="#import"> Importing an existing Postfix instance </a> + +<li><a href="#deport"> Deporting a managed Postfix instance </a> + +<li><a href="#assign"> Assigning a new name or group name </a> + +<li><a href="#enable"> Enabling/disabling managed instances </a> + +</ul> + +<h3><a name="init"> Initializing the multi-instance manager </a></h3> + +<p> Before postmulti(1) is used for the first time, you must install +it as the multi_instance_wrapper for your Postfix system and enable +multi-instance operation of the default Postfix instance. You can then +proceed to add <a href="#create">new</a> or <a href="#import">existing</a> +instances to the multi-instance configuration. This initial installation +is accomplished as follows: </p> + +<blockquote> +<pre> + # postmulti -e init +</pre> +</blockquote> + +<p> This updates the default instance main.cf file as follows: </p> + +<blockquote> +<pre> + # Use postmulti(1) as a postfix-wrapper(5) + # + multi_instance_wrapper = ${command_directory}/postmulti -p -- + + # Configure the default instance to start when in multi-instance mode + # + multi_instance_enable = yes +</pre> +</blockquote> + +<p> If you prefer, you can make these changes by editing the default +main.cf directly, or by using "postconf -e". </p> + +<h3><a name="list"> Listing managed instances </a></h3> + +<p> The list of managed instances consists of the default instance and +the additional instances whose configuration directories are listed +(in start order) under the multi_instance_directories parameter of the +default main.cf configuration file. </p> + +<p> You can list selected instances, groups of instances or all +instances by specifying only the instance matching options with the +"-l" option. The "-a" option is assumed if no other instance +selection options are specified (this behavior changes with the +"-e" option). As a special case, even if it has an explicit name, +the default instance can always be selected via "-i -". </p> + +<blockquote> +<pre> +# postmulti -l -a +# postmulti -l -g a_group +# postmulti -l -i an_instance +</pre> +</blockquote> + +<p> The output is one line per instance (in "postfix start" order): +</p> + +<blockquote> + +<table border="1"> + +<tr> <th align="left">name</th> <th align="left">group</th> <th +align="left">enabled</th> <th align="left">config_directory</th> +</tr> + +<tr> <td>-</td> <td>-</td> <td>yes</td> <td>/etc/postfix + +<tr> <td>mta-out</td> <td>mta</td> <td>yes</td> <td>/etc/postfix/mta-out + +<tr> <td>mta-in</td> <td>mta</td> <td>yes</td> <td>/etc/postfix-mta-in + +<tr> <td>msa-out</td> <td>msa</td> <td>yes</td> <td>/etc/postfix-msa-out + +<tr> <td>msa-in</td> <td>msa</td> <td>yes</td> <td>/etc/postfix-msa-in + +<tr> <td>test</td> <td>-</td> <td>no</td> <td>/etc/postfix-test + +</table> + +</blockquote> + +<p> The first line showing the column headings is not part of the +output. When either the instance name or the instance group is not +set, it is shown as a "-". </p> + +<p> When selecting an existing instance via the "-i" option, you +can always use the full pathname of its configuration directory +instead of the instance (short) name. This is the only way to select +a non-default nameless instance. The default instance can be selected +via "-i -", whether it has a name or not. </p> + +<p> To list instances in reverse start order, include the "-R" +option together with the instance selection options. </p> + +<h3><a name="start"> Starting or stopping a multi-instance system +</a></h3> + +<p> To start, stop, reload, etc. the complete (already configured as +above) multi-instance system just use postfix(1) as you would with a +single-instance system. The Postfix multi-instance wrapper framework +insulates Postfix init.d start and package upgrade scripts from the +details of multi-instance management! </p> + +<p> The <b>-p</b> option of postmulti(1) turns on postfix(1) compatibility +mode. With this option the remaining arguments are exactly those supported +by postfix(1), but commands are applied to all instances or all enabled +instances as appropriate. As described above, this switch is required +when using postmulti(1) as the multi_instance_wrapper. </p> + +<p> If you want to specify a subset of instances by name, or group name, +or run arbitrary commands (not just "postfix stop/start/etc. in the +context (MAIL_CONFIG environment variable setting) of a particular +instance or group of instances, then you can use the instance-aware +postmulti(1) utility directly. </p> + +<h3><a name="adhoc"> Ad-hoc multi-instance operations </a></h3> + +<p> The postmulti(1) command can be used by the administrator to run arbitrary +commands in the context of one or more Postfix instances. The most common +use-case is stopping or starting a group of Postfix instances: </p> + +<blockquote> +<pre> +# postmulti -g mygroup -p start +# postmulti -g mygroup -p flush +# postmulti -g mygroup -p reload +# postmulti -g mygroup -p status +# postmulti -g mygroup -p stop +# postmulti -g mygroup -p upgrade-configuration +</pre> +</blockquote> + +<p> The <b>-p</b> option is essentially a short-hand for a leading +<b>postfix</b> command argument, but with appropriate additional options +turned on depending on the first argument. In the case of "start", +disabled instances are "checked" (postfix check) rather than simply +skipped. </p> + +<p> The resulting command is executed for each candidate instance with +the <b>MAIL_CONFIG</b> environment variable set to the configuration +directory of the corresponding Postfix instance. </p> + +<p> The postmulti(1) utility is able to launch commands other than +postfix(1), Use the <b>-x</b> option to ask postmulti to execute an +ad-hoc command for all instances, a group of instances, or just one +instance. With ad-hoc commands the multi_instance_enable parameter +is ignored: the command is unconditionally executed for the instances +selected via -a, -g or -i. In addition to MAIL_CONFIG, the following +instance parameters are exported into the command environment: </p> + +<blockquote> +<pre> +command_directory=$command_directory +daemon_directory=$daemon_directory +config_directory=$config_directory +queue_directory=$queue_directory +data_directory=$data_directory +multi_instance_name=$multi_instance_name +multi_instance_group=$multi_instance_group +multi_instance_enable=$multi_instance_enable +</pre> +</blockquote> + +<p> The config_directory setting is of course the same as MAIL_CONFIG, +and is arguably redundant, but leaving it in is less surprising. If +you want to skip disabled instances, just check multi_instance_enable +environment variable and exit if it is set to "no". </p> + +<p> The ability to run ad-hoc commands opens up a wealth of additional +possibilities: </p> + +<ul> + +<li><p> Specify an instance by name rather than configuration directory +when using sendmail(1) to send a verification probe: </p> + +<blockquote> +<pre> +$ postmulti -i postfix-myinst -x sendmail -bv test@example.net +</pre> +</blockquote> + +<li><p> Display non-default main.cf settings of all Postfix instances. +This uses an inline shell script to package together multiple shell +commands to execute for each instance: </p> + +<blockquote> +<pre> +$ postmulti -x sh -c 'echo "-- $MAIL_CONFIG"; postconf -n' +</pre> +</blockquote> + +<li><p> Put all mail in enabled member instances of a group on hold: </p> + +<blockquote> +<pre> +# postmulti -g group_name -x \ + sh -c 'test $multi_instance_enable = yes && postsuper -h ALL' +</pre> +</blockquote> + +<li><p> Show top 10 domains in the deferred queue of all instances: +</p> + +<blockquote> +<pre> +# postmulti -x sh -c 'echo "-- $MAIL_CONFIG"; qshape deferred | head -12' +</pre> +</blockquote> + +</ul> + +<h3><a name="create"> Creating a new Postfix instance </a></h3> + +<p> The postmulti(1) command can be used to create additional Postfix +instances. New instances are created with local submission and all "inet" +services disabled via the following non-default parameter settings in +the main.cf file: </p> + +<blockquote> +<pre> +authorized_submit_users = +master_service_disable = inet +</pre> +</blockquote> + +<p> The above settings ensure that new instances are safe to start +immediately: they will not conflict with inet listeners in existing +Postfix instances. They will also not accept any mail until they are +fully configured, at which point you can do away with one or both of +the above safety measures. </p> + +<p> The postmulti(1) command encourages a preferred way of organizing +the configuration directories, queue directories and data directories +of non-default instances. If the default instance settings are: </p> + +<blockquote> +<pre> +config_directory = /conf-path/postfix +queue_directory = /queue-path/postfix +data_directory = /data-path/postfix +</pre> +</blockquote> + +<p> A newly-created instance named <i>postfix-myinst</i> will by default +have: </p> + +<blockquote> +<pre> +multi_instance_enable = no +multi_instance_name = postfix-myinst +config_directory = /conf-path/postfix-myinst +queue_directory = /queue-path/postfix-myinst +data_directory = /data-path/postfix-myinst +</pre> +</blockquote> + +<p> You can override any of these defaults when creating the instance, +but unless you want to spread instance queue directories over multiple +file-systems, use the default naming strategy. It keeps the multiple +instances organized in a uniform, predictable fashion. </p> + +<p> When specifying the instance name later, you can refer to it +either as "postfix-myinst", or via the full path of the configuration +directory. </p> + +<p> To create a new instance just use the <b>-e create</b> option: </p> + +<blockquote> +<pre> +# postmulti -I postfix-myinst -e create +</pre> +</blockquote> + +<p> If the new instance is to belong to a group of related instances that +implement a single logical service, assign it to a group: </p> + +<blockquote> +<pre> +# postmulti -I postfix-myinst -G mygroup -e create +</pre> +</blockquote> + +<p> If you want to override the conventional values of the instance +installation parameters, specify their values on the command-line: </p> + +<blockquote> +<pre> +# postmulti [-I postfix-myinst] [-G mygroup] -e create \ + "config_directory = /path/to/config_directory" \ + "queue_directory = /path/to/queue_directory" \ + "data_directory = /path/to/data_directory" +</pre> +</blockquote> + +<p> A note on the <b>-I</b> and <b>-G</b> options above. These are always +used to assign a name or group name to an instance, while the <b>-i</b> +and <b>-g</b> options always select existing instances. By default, +the configuration directories of newly managed instances are appended +to the instance list. You can use the "-i" or "-g" or "-a" options to +insert the new instance before the specified instance or group, or at +the beginning of the instance list (multi_instance_directories parameter +of the default instance). </p> + +<p> If you do specify a name (use "-I" with a name that is not "-") +for the new instance, you may omit any of the 3 instance installation +parameters whose instance-name based value is acceptable. Otherwise, all +three instance installation parameters are required. You should set the +"syslog_name" explicitly in the main.cf file of a "nameless" instance, +in order to avoid confusion in the mail logs when multiple instances +are in use. </p> + +<h3><a name="destroy"> Destroying a Postfix instance </a></h3> + +<p> If you no longer need an instance, you can destroy it via: </p> + +<blockquote> +<pre> +# postmulti -i postfix-myinst -p stop +# postmulti -i postfix-myinst -e disable +# postmulti -i postfix-myinst -e destroy +</pre> +</blockquote> + +<p> The instance must be stopped, disabled and have no queued messages. +This is expected to fully delete a just created instance that has never +been used. If the instance is not freshly created, files added after +the instance was created will remain in the configuration, queue or +data directories, in which case the corresponding directory may not +be fully removed and a warning to that effect will be displayed. You +can complete the destruction of the instance manually by removing any +unwanted remnants of the instance-specific "private" directories. </p> + +<h3><a name="import"> Importing an existing Postfix instance </a></h3> + +<p> If you already have an existing secondary Postfix instance that is +not yet managed via postmulti(1), you can "import" it into the list +of managed instances. If your instance is already using the default +configuration directory naming scheme, just specify the corresponding +instance name (the multi_instance_name parameter in its configuration +file will be adjusted to match this name if necessary): </p> + +<blockquote> +<pre> +# postmulti -I postfix-myinst [-G mygroup] -e import +</pre> +</blockquote> + +<p> Otherwise, you must specify the location of its configuration +directory: </p> + +<blockquote> +<pre> +# postmulti [-I postfix-myinst] [-G mygroup] -e import \ + "config_directory = /path/of/config_directory" +</pre> +</blockquote> + +<p> When the instance is imported, you can assign a name or a group. As +with <a href="#create">"create"</a>, you can control the placement of the +new instance in the start order by using "-i", "-g" or "-a" to prepend +before the selected instance or instances. </p> + +<p> An imported instance is usually not multi-instance "enabled", +unless it was part of a multi-instance configuration at an earlier +time. If it is fully configured and ready to run, don't forget +to <a href="#enable">enable</a> it and if necessary start it. When +other enabled instances are already running, new instances need to +be started individually when they are first created or imported. +</p> + +<p> To find out what instances are running, use: </p> + +<blockquote> +<pre> +# postfix status +</pre> +</blockquote> + +<h3><a name="deport"> Deporting a managed Postfix instance </a></h3> + +<p> You can "deport" an existing instance from the list of managed +instances. This does not destroy the instance, rather the instance +just becomes a stand-alone Postfix instance not registered with the +multi-instance manager. postmulti(1) will refuse to "deport" an +instance that is not stopped and disabled. </p> + +<blockquote> +<pre> +# postmulti -i postfix-myinst -p stop +# postmulti -i postfix-myinst -e disable +# postmulti -i postfix-myinst -e deport +</pre> +</blockquote> + +<h3><a name="assign"> Assigning a new name or group name </a></h3> + +<p> You can assign a new name or new group to a managed instance. +Use "-" as the new value to assign the instance to no group or make it +nameless. To specify a nameless secondary instance use the configuration +directory path instead of the old name: </p> + +<blockquote> +<pre> +# postmulti -i postfix-old [-I postfix-new] [-G newgroup] -e assign +</pre> +</blockquote> + +<h3><a name="enable"> Enabling/disabling managed instances </a></h3> + +<p> You can enable or disable a managed instance. As documented in +postfix-wrapper(5), disabled instances are skipped with actions +that <a href="postconf.5.html#postmulti_start_commands">start</a>, +<a href="postconf.5.html#postmulti_start_commands">stop</a> or <a +href="postconf.5.html#postmulti_control_commands">control</a> running +Postfix instances. </p> + +<blockquote> +<pre> +# postmulti -i postfix-myinst -e enable +# postmulti -i postfix-myinst -e disable +</pre> +</blockquote> + +<h2><a name="credits"> Credits </a></h2> + +<p> Wietse Venema created Postfix, designed and implemented the +multi-instance wrapper framework and provided design feedback that made +the postmulti(1) utility much more general and useful than originally +envisioned. </p> + +<p> The postmulti(1) utility was developed by Victor Duchovni of Morgan +Stanley, who also wrote the initial version of this document. </p> + +</body> </html> diff --git a/proto/MYSQL_README.html b/proto/MYSQL_README.html new file mode 100644 index 0000000..db52f02 --- /dev/null +++ b/proto/MYSQL_README.html @@ -0,0 +1,186 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix MySQL Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix MySQL Howto</h1> + +<hr> + +<h2>Introduction</h2> + +<p> The Postfix mysql map type allows you to hook up Postfix to a +MySQL database. This implementation allows for multiple mysql +databases: you can use one for a virtual(5) table, one for an +access(5) table, and one for an aliases(5) table if you want. You +can specify multiple servers for the same database, so that Postfix +can switch to a good database server if one goes bad. </p> + +<p> Busy mail servers using mysql maps will generate lots of +concurrent mysql clients, so the mysql server(s) should be run with +this fact in mind. You can reduce the number of concurrent mysql +clients by using the Postfix proxymap(8) service. </p> + +<h2>Building Postfix with MySQL support</h2> + +<p> These instructions assume that you build Postfix from source +code as described in the INSTALL document. Some modification may +be required if you build Postfix from a vendor-specific source +package. </p> + +<p> Note: to use mysql with Debian GNU/Linux's Postfix, all you +need is to install the postfix-mysql package and you're done. +There is no need to recompile Postfix. </p> + +<p> The Postfix MySQL client utilizes the mysql client library, +which can be obtained from: </p> + +<blockquote> + <p> http://www.mysql.com/downloads/ </p> +</blockquote> + +<p> In order to build Postfix with mysql map support, you will need to add +-DHAS_MYSQL and -I for the directory containing the mysql headers, and +the mysqlclient library (and libm) to AUXLIBS_MYSQL, for example: </p> + +<blockquote> +<pre> +make -f Makefile.init makefiles \ + 'CCARGS=-DHAS_MYSQL -I/usr/local/mysql/include' \ + 'AUXLIBS_MYSQL=-L/usr/local/mysql/lib -lmysqlclient -lz -lm' +</pre> +</blockquote> + +<p> If your MySQL shared library is in a directory that the RUN-TIME +linker does not know about, add a "-Wl,-R,/path/to/directory" option after +"-lmysqlclient". </p> + +<p> Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_MYSQL. +With Postfix 3.0 and later, the old AUXLIBS variable still supports +building a statically-loaded MySQL database client, but only the new +AUXLIBS_MYSQL variable supports building a dynamically-loaded or +statically-loaded MySQL database client. </p> + +<blockquote> + +<p> Failure to use the AUXLIBS_MYSQL variable will defeat the purpose +of dynamic database client loading. Every Postfix executable file +will have MYSQL database library dependencies. And that was exactly +what dynamic database client loading was meant to avoid. </p> + +</blockquote> + +<p> On Solaris, use this instead: </p> + +<blockquote> +<pre> +make -f Makefile.init makefiles \ + 'CCARGS=-DHAS_MYSQL -I/usr/local/mysql/include' \ + 'AUXLIBS_MYSQL=-L/usr/local/mysql/lib -R/usr/local/mysql/lib \ + -lmysqlclient -lz -lm' +</pre> +</blockquote> + +<p> Then, just run 'make'. This requires libz, the compression +library. Older mysql implementations build without libz. </p> + +<h2>Using MySQL tables</h2> + +<p> Once Postfix is built with mysql support, you can specify a +map type in main.cf like this: </p> + +<blockquote> +<pre> +alias_maps = mysql:/etc/postfix/mysql-aliases.cf +</pre> +</blockquote> + +<p> The file /etc/postfix/mysql-aliases.cf specifies lots of +information telling Postfix how to reference the mysql database. +For a complete description, see the mysql_table(5) manual page. </p> + +<h2>Example: local aliases </h2> + +<pre> +# +# mysql config file for local(8) aliases(5) lookups +# + +# The user name and password to log into the mysql server. +user = someone +password = some_password + +# The database name on the servers. +dbname = customer_database + +# For Postfix 2.2 and later The SQL query template. +# See mysql_table(5) for details. +query = SELECT forw_addr FROM mxaliases WHERE alias='%s' AND status='paid' + +# For Postfix releases prior to 2.2. See mysql_table(5) for details. +select_field = forw_addr +table = mxaliases +where_field = alias +# Don't forget the leading "AND"! +additional_conditions = AND status = 'paid' + +# This is necessary to make UTF8 queries work for Postfix 2.11 .. 3.1, +# and is the default setting as of Postfix 3.2. +option_group = client +</pre> + +<h2>Additional notes</h2> + +<p> Postfix 3.2 and later read <b>[client]</b> option group settings +by default. To disable this, specify no <b>option_file</b> and +specify "<b>option_group =</b>" (i.e. an empty value). </p> + +<p> Postfix 3.1 and earlier don't read <b>[client]</b> option group +settings unless a non-empty <b>option_file</b> or <b>option_group</b> +value are specified. To enable this, specify, for example +"<b>option_group = client</b>". </p> + +<p> The MySQL configuration interface setup allows for multiple +mysql databases: you can use one for a virtual table, one for an +access table, and one for an aliases table if you want. </p> + +<p> Since sites that have a need for multiple mail exchangers may +enjoy the convenience of using a networked mailer database, but do +not want to introduce a single point of failure to their system, +we've included the ability to have Postfix reference multiple hosts +for access to a single mysql map. This will work if sites set up +mirrored mysql databases on two or more hosts. Whenever queries +fail with an error at one host, the rest of the hosts will be tried +in random order. If no mysql server hosts are reachable, then mail +will be deferred until at least one of those hosts is reachable. +</p> + +<h2>Credits</h2> + +<ul> + +<li> The initial version was contributed by Scott Cotton and Joshua +Marcus, IC Group, Inc.</li> + +<li> Liviu Daia revised the configuration interface and added the +main.cf configuration feature.</li> + +<li> Liviu Daia with further refinements from Jose Luis Tallon and +Victor Duchovni developed the common query, result_format, domain and +expansion_limit interface for LDAP, MySQL and PostgreSQL.</li> + +</ul> + +</body> + +</html> diff --git a/proto/Makefile.in b/proto/Makefile.in new file mode 100644 index 0000000..511bd44 --- /dev/null +++ b/proto/Makefile.in @@ -0,0 +1,535 @@ +SHELL = /bin/sh + +# For now, just hard-coded rules. + +CONFIG = ../conf/access ../conf/aliases ../conf/canonical ../conf/relocated \ + ../conf/transport ../conf/virtual ../conf/header_checks \ + ../conf/generic + +HTML = ../html/ADDRESS_CLASS_README.html \ + ../html/ADDRESS_REWRITING_README.html \ + ../html/ADDRESS_VERIFICATION_README.html \ + ../html/BACKSCATTER_README.html \ + ../html/BASIC_CONFIGURATION_README.html \ + ../html/BDAT_README.html \ + ../html/BUILTIN_FILTER_README.html \ + ../html/CDB_README.html \ + ../html/COMPATIBILITY_README.html \ + ../html/CONNECTION_CACHE_README.html \ + ../html/CONTENT_INSPECTION_README.html \ + ../html/DATABASE_README.html ../html/DB_README.html \ + ../html/DEBUG_README.html \ + ../html/DSN_README.html \ + ../html/ETRN_README.html ../html/FILTER_README.html \ + ../html/FORWARD_SECRECY_README.html \ + ../html/INSTALL.html ../html/IPV6_README.html \ + ../html/LDAP_README.html \ + ../html/LINUX_README.html \ + ../html/LOCAL_RECIPIENT_README.html ../html/MAILDROP_README.html \ + ../html/MAILLOG_README.html \ + ../html/LMDB_README.html \ + ../html/MEMCACHE_README.html \ + ../html/MILTER_README.html \ + ../html/MULTI_INSTANCE_README.html \ + ../html/MYSQL_README.html ../html/NFS_README.html \ + ../html/OVERVIEW.html \ + ../html/PACKAGE_README.html ../html/PCRE_README.html \ + ../html/PGSQL_README.html \ + ../html/POSTSCREEN_3_5_README.html \ + ../html/POSTSCREEN_README.html \ + ../html/QSHAPE_README.html \ + ../html/RESTRICTION_CLASS_README.html ../html/SASL_README.html \ + ../html/SCHEDULER_README.html ../html/SMTPD_ACCESS_README.html \ + ../html/SMTPD_POLICY_README.html \ + ../html/SMTPD_PROXY_README.html \ + ../html/SMTPUTF8_README.html \ + ../html/SOHO_README.html \ + ../html/SQLITE_README.html \ + ../html/STANDARD_CONFIGURATION_README.html \ + ../html/STRESS_README.html \ + ../html/TLS_README.html ../html/TLS_LEGACY_README.html \ + ../html/TUNING_README.html \ + ../html/UUCP_README.html \ + ../html/VERP_README.html ../html/VIRTUAL_README.html \ + ../html/XCLIENT_README.html ../html/XFORWARD_README.html \ + ../html/postconf.5.html + +README = ../README_FILES/ADDRESS_CLASS_README \ + ../README_FILES/ADDRESS_REWRITING_README \ + ../README_FILES/ADDRESS_VERIFICATION_README \ + ../README_FILES/BACKSCATTER_README \ + ../README_FILES/BASIC_CONFIGURATION_README \ + ../README_FILES/BDAT_README \ + ../README_FILES/BUILTIN_FILTER_README \ + ../README_FILES/CDB_README \ + ../README_FILES/COMPATIBILITY_README \ + ../README_FILES/CONNECTION_CACHE_README \ + ../README_FILES/CONTENT_INSPECTION_README \ + ../README_FILES/DATABASE_README ../README_FILES/DB_README \ + ../README_FILES/DEBUG_README \ + ../README_FILES/DSN_README \ + ../README_FILES/ETRN_README ../README_FILES/FILTER_README \ + ../README_FILES/FORWARD_SECRECY_README \ + ../README_FILES/INSTALL ../README_FILES/IPV6_README \ + ../README_FILES/LDAP_README \ + ../README_FILES/LINUX_README \ + ../README_FILES/LOCAL_RECIPIENT_README ../README_FILES/MAILDROP_README \ + ../README_FILES/MAILLOG_README \ + ../README_FILES/LMDB_README \ + ../README_FILES/MEMCACHE_README \ + ../README_FILES/MILTER_README \ + ../README_FILES/MULTI_INSTANCE_README \ + ../README_FILES/MYSQL_README ../README_FILES/NFS_README \ + ../README_FILES/OVERVIEW \ + ../README_FILES/PACKAGE_README ../README_FILES/PCRE_README \ + ../README_FILES/PGSQL_README \ + ../README_FILES/POSTSCREEN_3_5_README \ + ../README_FILES/POSTSCREEN_README \ + ../README_FILES/QSHAPE_README \ + ../README_FILES/RESTRICTION_CLASS_README \ + ../README_FILES/SASL_README ../README_FILES/SCHEDULER_README \ + ../README_FILES/SMTPD_ACCESS_README \ + ../README_FILES/SMTPD_POLICY_README ../README_FILES/SMTPD_PROXY_README \ + ../README_FILES/SMTPUTF8_README \ + ../README_FILES/SOHO_README \ + ../README_FILES/SQLITE_README \ + ../README_FILES/STANDARD_CONFIGURATION_README \ + ../README_FILES/STRESS_README \ + ../README_FILES/TLS_README ../README_FILES/TLS_LEGACY_README \ + ../README_FILES/TUNING_README \ + ../README_FILES/UUCP_README \ + ../README_FILES/VERP_README ../README_FILES/VIRTUAL_README \ + ../README_FILES/XCLIENT_README ../README_FILES/XFORWARD_README \ + ../README_FILES/AAAREADME + +MAN = ../man/man5/postconf.5 + +TOP = ../INSTALL + +AWK = awk '{ print; if (NR == 1) print ".pl 9999\n.ll 65" }' +SRCTOMAN= ../mantools/srctoman +POSTLINK= ../mantools/postlink +DETAB = pr -tre +NROFF = LANG=C GROFF_NO_SGR=1 nroff +HT2READ = ../mantools/html2readme +MAKEAAA = ../mantools/makereadme +MAKESOHO= ../mantools/make_soho_readme +DEPSOHO = SASL_README.html STANDARD_CONFIGURATION_README.html + +update: $(CONFIG) $(HTML) $(README) $(MAN) $(TOP) + +clean: + : + +tidy: clean + +clobber: + rm -f $(CONFIG) $(README) $(HTML) + +#$(README): $(HT2READ) +#$(HTML): $(POSTLINK) + +../conf/access: access + $(SRCTOMAN) - $? | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /' >$@ + +../conf/aliases: aliases0 aliases + (cat aliases0; $(SRCTOMAN) - aliases | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /') >$@ + +../conf/canonical: canonical + $(SRCTOMAN) - $? | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /' >$@ + +../conf/generic: generic + $(SRCTOMAN) - $? | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /' >$@ + +../conf/header_checks: header_checks + $(SRCTOMAN) - $? | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /' >$@ + +../conf/relocated: relocated + $(SRCTOMAN) - $? | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /' >$@ + +../conf/transport: transport + $(SRCTOMAN) - $? | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /' >$@ + +../conf/virtual: virtual + $(SRCTOMAN) - $? | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /' >$@ + +../html/ADDRESS_CLASS_README.html: ADDRESS_CLASS_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/ADDRESS_REWRITING_README.html: ADDRESS_REWRITING_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/ADDRESS_VERIFICATION_README.html: ADDRESS_VERIFICATION_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/BACKSCATTER_README.html: BACKSCATTER_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/CDB_README.html: CDB_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/COMPATIBILITY_README.html: COMPATIBILITY_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/CONNECTION_CACHE_README.html: CONNECTION_CACHE_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/CONTENT_INSPECTION_README.html: CONTENT_INSPECTION_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/CYRUS_README.html: CYRUS_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/BASIC_CONFIGURATION_README.html: BASIC_CONFIGURATION_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/BDAT_README.html: BDAT_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/BUILTIN_FILTER_README.html: BUILTIN_FILTER_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/DATABASE_README.html: DATABASE_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/DB_README.html: DB_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/DEBUG_README.html: DEBUG_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/DSN_README.html: DSN_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/ETRN_README.html: ETRN_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/FILTER_README.html: FILTER_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/FORWARD_SECRECY_README.html: FORWARD_SECRECY_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/INSTALL.html: INSTALL.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/IPV6_README.html: IPV6_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/LDAP_README.html: LDAP_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/LINUX_README.html: LINUX_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/LOCAL_RECIPIENT_README.html: LOCAL_RECIPIENT_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/MAILDROP_README.html: MAILDROP_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/MAILLOG_README.html: MAILLOG_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/LMDB_README.html: LMDB_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/MEMCACHE_README.html: MEMCACHE_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/MILTER_README.html: MILTER_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/MULTI_INSTANCE_README.html: MULTI_INSTANCE_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/MYSQL_README.html: MYSQL_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/NFS_README.html: NFS_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/OVERVIEW.html: OVERVIEW.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/PACKAGE_README.html: PACKAGE_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/PCRE_README.html: PCRE_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/PGSQL_README.html: PGSQL_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/POSTSCREEN_3_5_README.html: POSTSCREEN_3_5_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/POSTSCREEN_README.html: POSTSCREEN_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/QMQP_README.html: QMQP_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/QSHAPE_README.html: QSHAPE_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/RESTRICTION_CLASS_README.html: RESTRICTION_CLASS_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/SASL_README.html: SASL_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/SCHEDULER_README.html: SCHEDULER_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/SMTPD_ACCESS_README.html: SMTPD_ACCESS_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/SMTPD_POLICY_README.html: SMTPD_POLICY_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/SMTPD_PROXY_README.html: SMTPD_PROXY_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/SMTPUTF8_README.html: SMTPUTF8_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/SOHO_README.html: $(MAKESOHO) $(DEPSOHO) + $(MAKESOHO) | $(POSTLINK) | $(DETAB) >$@ + +../html/SQLITE_README.html: SQLITE_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/STANDARD_CONFIGURATION_README.html: STANDARD_CONFIGURATION_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/STRESS_README.html: STRESS_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/TUNING_README.html: TUNING_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/UUCP_README.html: UUCP_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/ULTRIX_README.html: ULTRIX_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/VERP_README.html: VERP_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/VIRTUAL_README.html: VIRTUAL_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/XCLIENT_README.html: XCLIENT_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/XFORWARD_README.html: XFORWARD_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/TLS_README.html: TLS_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../html/TLS_LEGACY_README.html: TLS_LEGACY_README.html + $(DETAB) $? | $(POSTLINK) >$@ + +../README_FILES/ADDRESS_CLASS_README: ADDRESS_CLASS_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/ADDRESS_REWRITING_README: ADDRESS_REWRITING_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/ADDRESS_VERIFICATION_README: ADDRESS_VERIFICATION_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/BACKSCATTER_README: BACKSCATTER_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/BASIC_CONFIGURATION_README: BASIC_CONFIGURATION_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/BDAT_README: BDAT_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/BUILTIN_FILTER_README: BUILTIN_FILTER_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/CDB_README: CDB_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/COMPATIBILITY_README: COMPATIBILITY_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/CONNECTION_CACHE_README: CONNECTION_CACHE_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/CONTENT_INSPECTION_README: CONTENT_INSPECTION_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/CYRUS_README: CYRUS_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/DATABASE_README: DATABASE_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/DB_README: DB_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/DEBUG_README: DEBUG_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/DSN_README: DSN_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/ETRN_README: ETRN_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/FILTER_README: FILTER_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/FORWARD_SECRECY_README: FORWARD_SECRECY_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/INSTALL: INSTALL.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/IPV6_README: IPV6_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/LDAP_README: LDAP_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/LINUX_README: LINUX_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/LOCAL_RECIPIENT_README: LOCAL_RECIPIENT_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/MAILDROP_README: MAILDROP_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/MAILLOG_README: MAILLOG_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/LMDB_README: LMDB_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/MEMCACHE_README: MEMCACHE_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/MILTER_README: MILTER_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/MULTI_INSTANCE_README: MULTI_INSTANCE_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/MYSQL_README: MYSQL_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/NFS_README: NFS_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/OVERVIEW: OVERVIEW.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/PACKAGE_README: PACKAGE_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/PCRE_README: PCRE_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/PGSQL_README: PGSQL_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/POSTSCREEN_3_5_README: POSTSCREEN_3_5_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/POSTSCREEN_README: POSTSCREEN_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/QMQP_README: QMQP_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/QSHAPE_README: QSHAPE_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/RESTRICTION_CLASS_README: RESTRICTION_CLASS_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/SASL_README: SASL_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/SCHEDULER_README: SCHEDULER_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/SMTPD_ACCESS_README: SMTPD_ACCESS_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/SMTPD_POLICY_README: SMTPD_POLICY_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/SMTPD_PROXY_README: SMTPD_PROXY_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/SMTPUTF8_README: SMTPUTF8_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/SOHO_README: $(MAKESOHO) $(DEPSOHO) + $(MAKESOHO) | $(HT2READ) | $(DETAB) >$@ + +../README_FILES/SQLITE_README: SQLITE_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/STANDARD_CONFIGURATION_README: STANDARD_CONFIGURATION_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/STRESS_README: STRESS_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/TUNING_README: TUNING_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/UUCP_README: UUCP_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/ULTRIX_README: ULTRIX_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/VERP_README: VERP_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/VIRTUAL_README: VIRTUAL_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/XCLIENT_README: XCLIENT_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/XFORWARD_README: XFORWARD_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/TLS_README: TLS_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/TLS_LEGACY_README: TLS_LEGACY_README.html + $(DETAB) $? | $(HT2READ) >$@ + +../README_FILES/AAAREADME: ../html/index.html $(MAKEAAA) + $(MAKEAAA) ../html/index.html | $(HT2READ) | $(DETAB) >$@ + +../man/man5/postconf.5: postconf.man.prolog postconf.proto postconf.man.epilog \ + ../mantools/xpostconf ../mantools/postconf2html ../mantools/postconf2man + (cat postconf.man.prolog; ../mantools/xpostconf postconf.proto | \ + $(DETAB) | ../mantools/postconf2html -n | \ + ../mantools/postconf2man | \ + sed 's/\\e&/\\\&/'; cat postconf.man.epilog ) > $@ + +../html/postconf.5.html: postconf.html.prolog postconf.proto \ + postconf.html.epilog ../mantools/xpostconf ../mantools/postconf2html \ + ../mantools/postlink + (cat postconf.html.prolog; ../mantools/xpostconf postconf.proto | \ + ../mantools/postconf2html | ../mantools/postlink; \ + cat postconf.html.epilog ) | $(DETAB) > $@ + +../INSTALL: ../README_FILES/INSTALL + rm -f $@ + col -b < $? > $@ diff --git a/proto/NFS_README.html b/proto/NFS_README.html new file mode 100644 index 0000000..0f970ee --- /dev/null +++ b/proto/NFS_README.html @@ -0,0 +1,137 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix and NFS</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix and NFS</h1> + +<hr> + +<h2> Postfix support status for NFS </h2> + +<p> What is the status of support for Postfix on NFS? The answer +is that Postfix itself is supported when you use NFS, but there is +no promise that an NFS-related problem will promptly receive a +Postfix workaround, or that a workaround will even be possible. +</p> + +<p> That said, Postfix will in many cases work very well on NFS, +because Postfix implements a number of workarounds (see below). +Good NFS implementations seldom if ever give problems with Postfix, +so Wietse recommends that you spend your money wisely. </p> + +<h2> Postfix file locking and NFS </h2> + +<p> For the Postfix mail queue, it does not matter how well NFS +file locking works. The reason is that you cannot share Postfix +queues among multiple running Postfix instances. You can use NFS +to switch a Postfix mail queue from one NFS client to another one, +but only one NFS client can access a Postfix mail queue at any +particular point in time. </p> + +<p> For mailbox file sharing with NFS, your options are to use +<b>fcntl</b> (kernel locks), <b>dotlock</b> (<i>username</i>.lock +files), to use both locking methods simultaneously, or to switch +to maildir format. The maildir format uses one file per message and +needs no file locking support in Postfix or in other mail software. +</p> + +<p> Many sites that use mailbox format play safe and use both locking +methods simultaneously. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + virtual_mailbox_lock = fcntl, dotlock + mailbox_delivery_lock = fcntl, dotlock +</pre> +</blockquote> + +<h2> Postfix NFS workarounds </h2> + +<p> The list below summarizes the workarounds that exist for running +Postfix on NFS as of the middle of 2003. As a reminder, Postfix +itself is still supported when it runs on NFS, but there is no +promise that an NFS-related problem will promptly receive a Postfix +workaround, or that a workaround will even be possible. </p> + +<ul> + +<li> <p> Problem: when renaming a file, the operation may succeed +but report an error anyway<sup>[1]</sup>. </p> + +<p> Workaround: when rename(old, new) reports an error, Postfix +checks if the new name exists and the old name is gone. If the check +succeeds, Postfix assumes that the rename() operation completed +normally. </p> + +<li> <p> Problem: when creating a directory, the operation may succeed +but report an error anyway<sup>[1]</sup>. </p> + +<p> Workaround: when mkdir(new) reports an EEXIST error, Postfix +checks if the new name resolves to a directory. If the check succeeds, +Postfix assumes that the mkdir() operation completed normally. </p> + +<li> <p> Problem: when creating a hardlink to a file, the operation +may succeed but report an error anyway<sup>[1]</sup>. </p> + +<p> Workaround: when link(old, new) fails, Postfix compares the +device and inode number of the old and new files. When the two files +are identical, Postfix assumes that the link() operation completed +normally. </p> + +<li> <p> Problem: when creating a dotlock (<i>username</i>.lock) +file, the operation may succeed but report an error anyway<sup>[1]</sup>. +</p> + +<p> Workaround: in this case, the only safe action is to back off +and try again later. </p> + +<li> <p> Problem: when a file server's "time of day" clock is not +synchronized with the client's "time of day" clock, email deliveries +are delayed by a minute or more. </p> + +<p> Workaround: Postfix explicitly sets file time stamps to avoid +delays with new mail (Postfix uses "last modified" file time stamps +to decide when a queue file is ready for delivery). </p> + +</ul> + +<p> <sup>[1]</sup> How can an operation succeed and report an error +anyway? </p> + +<p> Suppose that an NFS server executes a client request successfully, +and that the server's reply to the client is lost. After some time +the client retransmits the request to the server. Normally, the +server remembers that it already completed the request (it keeps a +list of recently-completed requests and replies), and simply +retransmits the reply. </p> + +<p> However, when the server has rebooted or when it has been very +busy, the server no longer remembers that it already completed the +request, and repeats the operation. This causes no problems with +file read/write requests (they contain a file offset and can therefore +be repeated safely), but fails with non-idempotent operations. For +example, when the server executes a retransmitted rename() request, +the server reports an ENOENT error because the old name does not +exist; and when the server executes a retransmitted link(), mkdir() +or create() request, the server reports an EEXIST error because the +name already exists. </p> + +<p> Thus, successful, non-idempotent, NFS operations will report +false errors when the server reply is lost, the client retransmits +the request, and the server does not remember that it already +completed the request. </p> + +</body> +</html> diff --git a/proto/OVERVIEW.html b/proto/OVERVIEW.html new file mode 100644 index 0000000..af743aa --- /dev/null +++ b/proto/OVERVIEW.html @@ -0,0 +1,936 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Architecture Overview </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1> <img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +Architecture Overview </h1> + +<hr> + +<h2> Introduction </h2> + +<p> This document presents an overview of the Postfix architecture, +and provides pointers to descriptions of every Postfix command +or server program. The text gives the general context in which +each command or server program is used, and provides pointers to +documents with specific usage examples and background information. +</p> + +<p> Topics covered by this document: </p> + +<ul> + +<li> <a href="#receiving"> How Postfix receives mail </a> + +<li> <a href="#delivering"> How Postfix delivers mail </a> + +<li> <a href="#behind"> Postfix behind the scenes </a> + +<li> <a href="#commands"> Postfix support commands </a> + +</ul> + +<h2><a name="receiving"> How Postfix receives mail </a> </h2> + +<p> When a message enters the Postfix mail system, the first stop +on the inside is the incoming queue. The figure below shows the +main processes that are involved with new mail. Names followed by +a number are Postfix commands or server programs, while unnumbered +names inside shaded areas represent Postfix queues. </p> + +<blockquote> + +<table> + +<tr> + +<td colspan="4"> </td> + +<td bgcolor="#f0f0ff" align="center"> trivial-<br>rewrite(8) </td> + +</tr> + +<tr> + +<td> Network </td> <td> <tt> -> </tt> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> smtpd(8) +</td> + +<td> </td> + +<td rowspan="2" align="center"> <table> <tr> <td align="center"> +^<br> <tt> | </tt> </td> <td align="center"> <tt> |<br> v </tt> +</td> </tr> </table> </td> + +</tr> + +<tr> + +<td colspan="3"> </td> <td> <tt> \ </tt> </td> + +</tr> + +<tr> + +<td> Network </td> <td> <tt> -> </tt> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> qmqpd(8) +</td> + +<td> <tt> -> </tt> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> cleanup(8) +</td> + +<td> <tt> -> </tt> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> <a +href="QSHAPE_README.html#incoming_queue"> incoming </a> </td> + +</tr> + +<tr> + +<td colspan="3"> </td> <td> <tt> / </tt> </td> + +</tr> + +<tr> + +<td colspan="2"> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> pickup(8) +</td> + +<td> <tt> <- </tt> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> <a +href="QSHAPE_README.html#maildrop_queue"> maildrop </a> </td> + +</tr> + +<tr> + +<td colspan="4" align="center"> </td> + +<td align="center"> ^<br> <tt> | </tt> </td> + +</tr> + +<tr> + +<td> Local </td> <td> <tt> -> </tt> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> sendmail(1) +</td> + +<td> <tt> -> </tt> </td> + +<td bgcolor="#f0f0ff" align="center" valign="middle"> postdrop(1) +</td> + +</tr> + +</table> + +</blockquote> + +<ul> + +<li> <p> Network mail enters Postfix via the smtpd(8) or qmqpd(8) +servers. These servers remove the SMTP or QMQP protocol encapsulation, +enforce some sanity checks to protect Postfix, and give the sender, +recipients and message content to the cleanup(8) server. The +smtpd(8) server can be configured to block unwanted mail, as +described in the SMTPD_ACCESS_README document. </p> + +<li> <p> Local submissions are received with the Postfix sendmail(1) +compatibility command, and are queued in the maildrop queue by +the privileged postdrop(1) command. This arrangement even works +while the Postfix mail system is not running. The local pickup(8) +server picks up local submissions, enforces some sanity checks to +protect Postfix, and gives the sender, recipients and message +content to the cleanup(8) server. </p> + +<li> <p> Mail from internal sources is given directly to the +cleanup(8) server. These sources are not shown in the figure, and +include: mail that is forwarded by the local(8) delivery agent (see +next section), messages that are returned to the sender by the +bounce(8) server (see second-next section), and postmaster +notifications about problems with Postfix. </p> + +<li> <p> The cleanup(8) server implements the final processing +stage before mail is queued. It adds missing From: and other message +headers, and transforms addresses as described in the +ADDRESS_REWRITING_README +document. Optionally, the cleanup(8) server can be configured to +do light-weight content inspection with regular expressions as +described in the BUILTIN_FILTER_README document. The cleanup(8) +server places the result as a single file into the incoming queue, +and notifies the queue manager (see next section) of the arrival +of new mail. </p> + +<li> <p> The trivial-rewrite(8) server rewrites addresses to the +standard "user@fully.qualified.domain" form, as described in the +ADDRESS_REWRITING_README document. Postfix currently does not +implement a rewriting language, but a lot can be done via table +lookups and, if need be, regular expressions. </p> + +</ul> + +<h2> <a name="delivering"> How Postfix delivers mail </a> </h2> + +<p> Once a message has reached the incoming queue the next step is +to deliver it. The figure shows the main components of the Postfix +mail delivery apparatus. Names followed by a number are Postfix +commands or server programs, while unnumbered names inside shaded +areas represent Postfix queues. </p> + +<blockquote> + +<table> + +<tr> + +<td rowspan="2" colspan="4"> </td> + +<td rowspan="2" bgcolor="#f0f0ff" align="center"> trivial-<br>rewrite(8) +</td> + +<td> </td> + +<td bgcolor="#f0f0ff" align="center"> smtp(8) </td> + +<td> <tt> -> </tt> </td> <td> Network </td> + +</tr> + +<tr> + +<td align="right"> <tt> / </tt> </td> + +</tr> + +<tr> + +<td rowspan="2" colspan="4"> </td> + +<td rowspan="2" align="center"> <table> <tr> <td align="center"> +^<br> <tt> | </tt> </td> <td align="center"> <tt> |<br> v </tt> +</td> </tr> </table> </td> + +<td align="right"> <tt> - </tt> </td> + +<td bgcolor="#f0f0ff" align="center"> lmtp(8) </td> + +<td> <tt> -> </tt> </td> <td> Network </td> + +</tr> + +<tr> + +<td align="left"> <tt> / </tt> </td> + +</tr> + +<tr> + +<td bgcolor="#f0f0ff" align="center"> <a +href="QSHAPE_README.html#incoming_queue"> incoming </a> </td> + +<td> <tt> -> </tt> </td> + +<td bgcolor="#f0f0ff" align="center"> <a +href="QSHAPE_README.html#active_queue"> active </a> </td> + +<td> <tt> -> </tt> </td> + +<td bgcolor="#f0f0ff" align="center"> qmgr(8) </td> + +<td align="right"> <tt> --- </tt> </td> + +<td bgcolor="#f0f0ff" align="center"> local(8) </td> + +<td> <tt> -> </tt> </td> <td> File, command </td> + +</tr> + +<tr> + +<td rowspan="2" colspan="2"> </td> + +<td rowspan="2" align="center"> <table> <tr> <td align="center"> +^<br> <tt> | </tt> </td> <td align="center"> <tt> |<br> v </tt> +</td> </tr> </table> </td> + +<td rowspan="2" colspan="2"> </td> + +<td align="left"> <tt> \ </tt> </td> + +</tr> + +<tr> + +<td align="right"> <tt> - </tt> </td> + +<td bgcolor="#f0f0ff" align="center"> virtual(8) </td> + +<td> <tt> -> </tt> </td> <td> File </td> + +</tr> + +<tr> + +<td colspan="2"> </td> + +<td bgcolor="#f0f0ff" align="center"> <a +href="QSHAPE_README.html#deferred_queue"> deferred </a> </td> + +<td colspan="2"> </td> + +<td align="right"> <tt> \ </tt> </td> + +</tr> + +<tr> + +<td colspan="6"> + +<td bgcolor="#f0f0ff" align="center"> pipe(8) </td> + +<td> <tt> -> </tt> </td> <td> Command </td> + +</tr> + +</table> + +</blockquote> + +<ul> + +<li> <p> The queue manager (the qmgr(8) server process in the +figure) is the heart of Postfix mail delivery. It contacts the +smtp(8), lmtp(8), local(8), virtual(8), pipe(8), discard(8) or +error(8) delivery agents, and sends a delivery request for one +or more recipient addresses. The discard(8) and error(8) delivery +agents are special: they discard or bounce all mail, and are not +shown in the figure above. </p> + +<p> The queue manager maintains a small active queue with the +messages that it has opened for delivery. The active queue acts as +a limited window on potentially large incoming or deferred queues. +The limited active queue prevents the queue manager from running +out of memory under heavy load. </p> + +<p> The queue manager maintains a separate deferred queue for mail +that cannot be delivered, so that a large mail backlog will not +slow down normal queue accesses. The queue manager's strategy for +delayed mail delivery attempts is described in the QSHAPE_README +and TUNING_README documents. </p> + +<li> <p> The trivial-rewrite(8) server resolves each recipient +address according to its local or remote address class, as defined +in the ADDRESS_CLASS_README document. Additional routing information +can be specified with the optional transport(5) table. The +trivial-rewrite(8) server optionally queries the relocated(5) table +for recipients whose address has changed; mail for such recipients is +returned to the sender with an explanation. </p> + +<li> <p> The smtp(8) client looks up a list of mail exchangers for +the destination host, sorts the list by preference, and tries each +server in turn until it finds a server that responds. It then +encapsulates the sender, recipient and message content as required +by the SMTP protocol; this includes conversion of 8-bit MIME to +7-bit encoding. </p> + +<li> <p> The lmtp(8) client speaks a protocol similar to SMTP that +is optimized for delivery to mailbox servers such as Cyrus. The +advantage of this setup is that one Postfix machine can feed multiple +mailbox servers over LMTP. The opposite is true as well: one +mailbox server can be fed over LMTP by multiple Postfix machines. +</p> + +<li> <p> The local(8) delivery agent understands UNIX-style mailboxes, +qmail-compatible maildir files, Sendmail-style system-wide aliases(5) +databases, and Sendmail-style per-user .forward files. Multiple +local delivery agents can be run in parallel, but parallel delivery +to the same user is usually limited. </p> + +<p> The local(8) delivery agent has hooks for alternative forms of +local delivery: you can configure it to deliver to mailbox files +in user home directories, you can configure it to delegate mailbox +delivery to an external command such as procmail, or you can delegate +delivery to a different Postfix delivery agent. </p> + +<li> <p> The virtual(8) delivery agent is a bare-bones delivery +agent that delivers to UNIX-style mailbox or qmail-style maildir +files only. This delivery agent can deliver mail for multiple +domains, which makes it especially suitable for hosting lots of +small domains on a single machine. This is described in the +VIRTUAL_README document. </p> + +<li> <p> The pipe(8) mailer is the outbound interface to other mail +processing systems (the Postfix sendmail(1) command being the +inbound interface). The interface is UNIX compatible: it provides +information on the command line and on the standard input stream, +and expects a process exit status code as defined in <sysexits.h>. +Examples of delivery via the pipe(8) mailer are in the MAILDROP_README +and UUCP_README documents. + +</ul> + +<h2> <a name="behind"> Postfix behind the scenes </a> </h2> + +<p> The previous sections gave an overview of how Postfix server +processes send and receive mail. These server processes rely on +other server processes that do things behind the scenes. The text +below attempts to visualize each service in its own context. As +before, names followed by a number are Postfix commands or server +programs, while unnumbered names inside shaded areas represent +Postfix queues. </p> + +<ul> + +<li> <p> The resident master(8) server is the supervisor that keeps +an eye on the well-being of the Postfix mail system. It is typically +started at system boot time with the "postfix start" command, and +keeps running until the system goes down. The master(8) server is +responsible for starting Postfix server processes to receive and +deliver mail, and for restarting servers that terminate prematurely +because of some problem. The master(8) server is also responsible +for enforcing the server process count limits as specified in the +<b>master.cf</b> configuration file. The picture below gives the +program hierarchy when Postfix is started up. Only some of the mail +handling daemon processes are shown. </p> + +<table> + +<tr> <td colspan="2"> </td> <td align="center" bgcolor="#f0f0ff"> +postfix(1) </td> </tr> + +<tr> <td colspan="2"> </td> <td align="center"> |<br> |</td> </tr> + +<tr> <td colspan="2"> </td> <td align="center" bgcolor="#f0f0ff"> +postfix-script(1) </td> </tr> + +<tr> <td> </td> <td> <table> <tr> <td> </td> <td> / </td> </tr> +<tr> <td> / </td> <td> </td> </tr> </table> </td> <td align="center"> +|<br> |</td> <td> <table> <tr> <td> \ </td> <td> </td> </tr> <tr> +<td> </td> <td> \ </td> </tr> </table> </td> </tr> + +<tr> <td align="center" bgcolor="#f0f0ff"> postsuper(1) </td> <td> +</td> <td align="center" bgcolor="#f0f0ff"> master(8) </td> <td> +</td> <td align="center" bgcolor="#f0f0ff"> postlog(1) </td> </tr> + +<tr> <td> </td> <td> <table> <tr> <td> </td> <td> / </td> </tr> +<tr> <td> / </td> <td> </td> </tr> </table> </td> <td align="center"> +|<br> |</td> <td> <table> <tr> <td> \ </td> <td> </td> </tr> <tr> +<td> </td> <td> \ </td> </tr> </table> </td> </tr> + +<tr> <td align="center" bgcolor="#f0f0ff"> smtpd(8) </td> <td> +</td> <td align="center" bgcolor="#f0f0ff"> qmgr(8) </td> <td> +</td> <td align="center" bgcolor="#f0f0ff"> local(8) </td> </tr> + +</table> + +<li> <p> The anvil(8) server implements client connection and +request rate +limiting for all smtpd(8) servers. The TUNING_README document +provides guidance for dealing with mis-behaving SMTP clients. The +anvil(8) service is available in Postfix version 2.2 and later. +</p> + +<table> + +<tr> <td> Network </td> <td> <tt> -> </tt> </td> <td align="center" +bgcolor="#f0f0ff"> <br> smtpd(8)<br><br> </td> <td> <tt> <-> +</tt> </td> <td align="center" bgcolor="#f0f0ff"> <br> anvil(8)<br><br> +</td> </tr> + +</table> + +<li> <p> The bounce(8), defer(8) and trace(8) services each maintain +their own queue directory trees with per-message logfiles. Postfix +uses this information when sending "failed", "delayed" or "success" +delivery status notifications to the sender. </p> + +<p> The trace(8) service also implements support for the Postfix +"sendmail +-bv" and "sendmail -v" commands which produce reports about how +Postfix delivers mail, and is available with Postfix version 2.1 +and later. See <a href="DEBUG_README.html#trace_mail"> DEBUG_README +</a> for examples. </p> + +<table> + +<tr> <td align="center" bgcolor="#f0f0ff"> cleanup(8) </td> <td +valign="middle"> <tt> -> </tt> </td> <td align="center" +bgcolor="#f0f0ff"> qmgr(8)<br> Postfix<br> queue </td> <td +valign="middle"> <tt> -> </tt> </td> <td align="center" +bgcolor="#f0f0ff"> Delivery<br> agents</td> </tr> + +<tr> <td align="center"> ^<br> <tt> | </tt> </td> <td> </td> <td +align="center"> <tt> |<br> v </tt> </td> <td> </td> <td align="center"> +<tt> |<br> v </tt> </td> </tr> + +<tr> <td align="center"> (Non-)<br> delivery<br> notice </td> <td +valign="middle"> <tt> <- </tt> </td> <td align="center" +bgcolor="#f0f0ff"> bounce(8)<br> defer(8)<br> trace(8) </td> <td +valign="middle"> <tt> <- </tt> </td> <td align="center"> Queue +id,<br> recipient,<br> status</td> </tr> + +<tr> <td colspan="2"> </td> <td align="center"> <table> <tr> <td +align="center"> ^<br> <tt> | </tt> </td> <td align="center"> <tt> +|<br> v </tt> </td> </tr> </table> </td> </tr> + +<tr> <td colspan="2"> </td> <td align="center" bgcolor="#f0f0ff"> +Per- <br> message<br> logfiles </td> </tr> + +</table> + +<li> <p> The flush(8) servers maintain per-destination logs and +implement both ETRN and "sendmail -qRdestination", as described +in the ETRN_README document. This moves selected queue files from +the deferred queue back to the incoming queue and requests their +delivery. The flush(8) service is available with Postfix version +1.0 and later. </p> + +<table> + +<tr> <td colspan="4"> </td> <td align="center" bgcolor="#f0f0ff"> +<a href="QSHAPE_README.html#incoming_queue"> incoming </a><br>^ +<br><a href="QSHAPE_README.html#deferred_queue"> deferred </a> +</td> </tr> + +<tr> <td colspan="4"> </td> <td align="center"> ^<br> |</td> </tr> + +<tr> <td align="center" bgcolor="#f0f0ff"> smtpd(8)<br> sendmail(1)<br> +postqueue(1) </td> <td> <tt> - </tt> </td> <td align="center"> +Destination<br> to flush</td> <td> <tt> -> </tt> </td> <td +align="center" bgcolor="#f0f0ff"> flush(8) </td> <td> <tt> <- +</tt> </td> <td align="center"> Deferred<br> destination,<br> queue +id </td> <td> <tt> - </tt> </td> <td align="center" bgcolor="#f0f0ff"> +Delivery<br> agents,<br> qmgr(8) </td> </tr> + +<tr> <td colspan="4"> </td> <td align="center"> <table> <tr> <td +align="center"> ^<br> <tt> | </tt> </td> <td align="center"> <tt> +|<br> v </tt> </td> </tr> </table> </td> </tr> + +<tr> <td colspan="4"> </td> <td align="center"> Per-dest-<br> +ination<br> logs </td> </tr> + +</table> + +<li> <p> The proxymap(8) servers provide read-only and read-write +table lookup +service to Postfix processes. This overcomes chroot restrictions, +reduces the number of open lookup tables by sharing one open +table among multiple processes, and implements single-updater +tables. </p> + +<li> <p> The scache(8) server maintains the connection cache for +the Postfix smtp(8) client. When connection caching is enabled for +selected destinations, the smtp(8) client does not disconnect +immediately after a mail transaction, but gives the connection to +the connection cache server which keeps the connection open for a +limited amount of time. The smtp(8) client continues with some +other mail delivery request. Meanwhile, any smtp(8) process can +ask the scache(8) server for that cached connection and reuse it +for mail delivery. As a safety measure, Postfix limits the number +of times that a connection may be reused. </p> + +<p> When delivering mail to a destination with multiple mail servers, +connection caching can help to skip over a non-responding server, +and thus dramatically speed up delivery. SMTP connection caching +is available in Postfix version 2.2 and later. More information +about this feature is in the CONNECTION_CACHE_README document. </p> + +<table> + +<tr> <td> </td> <td> <tt> /-- </tt> </td> <td align="center" +colspan="3" bgcolor="#f0f0ff"> smtp(8) </td> <td colspan="2"> <tt> +--> </tt> </td> <td> Internet </td> </tr> + +<tr> <td align="center" bgcolor="#f0f0ff"> qmgr(8) </td> <td> </td> +<td align="center" rowspan="3"><tt>|<br>|<br>|<br>|<br>v</tt></td> +</tr> + +<tr> <td> </td> <td> <tt> \-- </tt> </td> <td align="center" +colspan="4" bgcolor="#f0f0ff"> smtp(8) </td> <td align="left"> + </td> </tr> + +<tr> <td colspan="2"> </td> <td> </td> <td +align="center"><tt>^<br>|</tt></td> </tr> + +<tr> <td colspan="2"> </td> <td align="center" colspan="3" +bgcolor="#f0f0ff"> scache(8) </td> </tr> + +</table> + +<p> A Postfix smtp(8) client can reuse a TLS-encrypted connection +(with "smtp_tls_connection_reuse = yes"). This can greatly reduce +the overhead of connection setup and improves message delivery +rates. After a Postfix smtp(8) client connects to a remote SMTP +server and sends plaintext EHLO and STARTTLS commands, the smtp(8) +client inserts a tlsproxy(8) process into the connection as shown +below. </p> + +<p> After the mail transaction completes, the Postfix smtp(8) client +gives the smtp(8)-to-tlsproxy(8) connection to the scache(8) +server, which keeps the connection open for a limited amount of +time. The smtp(8) client continues with some other mail delivery +request. Meanwhile, any Postfix smtp(8) client can ask the scache(8) +server for that cached connection and reuse it for mail delivery. +</p> + +<table> + +<tr> <td> </td> <td> <tt> /-- </tt> </td> <td align="center" +colspan="3" bgcolor="#f0f0ff"> smtp(8) </td> <td colspan="2"> <tt> +--> </tt> </td> <td align="center"bgcolor="#f0f0ff"> tlsproxy(8) +</td> <td> <tt> --> </tt> </td> <td> Internet </td> </tr> + +<tr> <td align="center" bgcolor="#f0f0ff"> qmgr(8) </td> <td> </td> +<td align="center" rowspan="3"><tt>|<br>|<br>|<br>|<br>v</tt></td> +</tr> + +<tr> <td> </td> <td> <tt> \-- </tt> </td> <td align="center" +colspan="4" bgcolor="#f0f0ff"> smtp(8) </td> <td align="left"> + </td> </tr> + +<tr> <td colspan="2"> </td> <td> </td> <td +align="center"><tt>^<br>|</tt></td> </tr> + +<tr> <td colspan="2"> </td> <td align="center" colspan="3" +bgcolor="#f0f0ff"> scache(8) </td> </tr> + +</table> + +<li> <p> The showq(8) servers list the Postfix queue status. This +is the queue listing service that does the work for the mailq(1) +and postqueue(1) commands. </p> + +<table> + +<tr> <td> Output </td> <td> <tt> <- </tt> </td> <td align="center" +bgcolor="#f0f0ff"> mailq(1)<br> + +<a href="postqueue.1.html"> post-<br>queue(1) </a> <br> </td> <td> +<tt> <- </tt> </td> <td align="center" valign="middle" +bgcolor="#f0f0ff"> showq(8) </td> <td> <tt> <- </tt></td> <td +align="center" valign="middle" bgcolor="#f0f0ff"> Postfix<br> queue +</td> </tr> + +</table> + +<li> <p> The spawn(8) servers run non-Postfix commands on request, +with the client connected via socket or FIFO to the command's +standard input, output and error streams. You can find examples of +its use in the SMTPD_POLICY_README document. </p> + +<li> <p> The tlsmgr(8) server runs when TLS (Transport Layer +Security, formerly known as SSL) is turned on in the Postfix smtp(8) +client or smtpd(8) server. This process has two duties: </p> + +<ul> + +<li> <p> Maintain the pseudo-random number generator (PRNG) that +is used to seed the TLS engines in Postfix smtp(8) client or smtpd(8) +server processes. The state of this PRNG is periodically saved to +a file, and is read when tlsmgr(8) starts up. </p> + +<li> <p> Maintain the optional Postfix smtp(8) client or smtpd(8) +server caches with TLS session keys. Saved keys can improve +performance by reducing the amount of computation at the start of +a TLS session. </p> + +</ul> + +<p> TLS support is available in Postfix version 2.2 and later. +Information about the Postfix TLS implementation is in the TLS_README +document. </p> + +<table> + +<tr> <td>Network<tt>-> </tt> </td> <td align="center" +bgcolor="#f0f0ff"> <br> smtpd(8) <br> </td> <td colspan="2"> +<tt> <---seed---<br><br><-session-> </tt> </td> <td +align="center" bgcolor="#f0f0ff"> <br> tlsmgr(8) <br> </td> +<td colspan="3"> <tt> ---seed---><br> <br><-session-> +</tt> </td> <td align="center" bgcolor="#f0f0ff"> <br> smtp(8) <br> + </td> <td> <tt> -></tt>Network </td> </tr> + +<tr> <td colspan="3"> </td> <td align="right"> <table> <tr> <td> +</td> <td> / </td> </tr> <tr> <td> / </td> <td> </td> </tr> </table> +</td> <td align="center"> |<br> |</td> <td align="left"> <table> +<tr> <td> \ </td> <td> </td> </tr> <tr> <td> </td> <td> \ </td> +</tr> </table> </td> <td colspan="3"> </td> </tr> + +<tr> <td colspan="2"> </td> <td align="center" bgcolor="#f0f0ff"> +smtpd<br> session<br> cache </td> <td> </td> <td align="center" +bgcolor="#f0f0ff"> PRNG<br> state <br>file </td> <td> </td> <td +align="center" bgcolor="#f0f0ff"> smtp<br> session<br> cache </td> +<td colspan="2"> </td> </tr> + +</table> + + +<li> <p> The verify(8) server verifies that a sender or recipient +address is deliverable before the smtpd(8) server accepts it. The +verify(8) server queries a cache with address verification results. +If a result is not found, the verify(8) server injects a probe +message into the Postfix queue and processes the status update from +a delivery agent or queue manager. +This process is described in the ADDRESS_VERIFICATION_README +document. The verify(8) service is available with Postfix version +2.1 and later. </p> + +<table> + +<tr> + + <td rowspan="2" colspan="5" align="center" valign="middle"> + </td> <td rowspan="3" align="center" valign="bottom"> + <tt> -> </tt> </td> <td rowspan="3" align="center" + valign="middle"> probe<br> message </td> <td rowspan="3" + align="center" valign="middle"> <tt> -> </tt> </td> <td + rowspan="3" bgcolor="#f0f0ff" align="center" valign="middle"> + Postfix<br> mail<br> queue </td> + +</tr> + +<tr> <td> </td> </tr> + +<tr> + + <td rowspan="3" align="center" valign="middle"> Network </td> + <td rowspan="3" align="center" valign="middle"> <tt> -> </tt> + </td> <td rowspan="3" bgcolor="#f0f0ff" align="center" + valign="middle"> smtpd(8) </td> <td rowspan="3" align="center" + valign="middle"> <tt> <-> </tt> </td> <td rowspan="3" + bgcolor="#f0f0ff" align="center" valign="middle"> verify(8) + </td> + +</tr> + +<tr> + + <td rowspan="1" colspan="3"> </td> <td rowspan="1" align="center" + valign="middle"> <tt> |</tt><br> <tt> v</tt> </td> + +</tr> + +<tr> + + <td rowspan="3" align="center" valign="top"> <tt> <- </tt> + </td> <td rowspan="3" align="center" valign="middle"> probe<br> + status </td> <td rowspan="3" align="center" valign="middle"> + <tt> <- </tt> </td> <td rowspan="3" bgcolor="#f0f0ff" + align="center" valign="middle"> Postfix<br> delivery<br> agents + </td> <td rowspan="3" align="left" valign="middle"> <tt>-></tt> + Local<br> <tt>-></tt> Network</td> + +</tr> + +<tr> + + <td rowspan="3" colspan="4" align="center" valign="middle"> + </td> <td rowspan="3" align="center" valign="middle"> + <tt> ^</tt><br> <tt> |</tt><br> <tt> v</tt> </td> + +</tr> + +<tr> <td> </td> </tr> + +<tr> <td colspan="4"> </td> </tr> + +<tr> + + <td colspan="4" align="center" valign="middle"> </td> + <td bgcolor="#f0f0ff" align="center" valign="middle"> Address<br> + verification<br> cache </td> + +</tr> + +</table> + +<li> <p> The postscreen(8) server can be put "in front" of Postfix +smtpd(8) processes. Its purpose is to accept connections from the +network and to decide what SMTP clients are allowed to talk to +Postfix. According to the 2008 MessageLabs annual report, 81% of +all email was spam, and 90% of that was sent by botnets; by 2010, +those numbers were 92% and 95%, respectively. While postscreen(8) +keeps the zombies away, more smtpd(8) processes remain available +for legitimate clients. </p> + +<p> postscreen(8) maintains a temporary allowlist for clients that +pass its tests; by allowing allowlisted clients to skip tests, +postscreen(8) minimizes its impact on legitimate email traffic. +</p> + +<p> The postscreen(8) server is available with Postfix 2.8 and +later. To keep the implementation simple, postscreen(8) delegates +DNS allow/denylist lookups to dnsblog(8) server processes, and +delegates TLS encryption/decryption to tlsproxy(8) server processes. +This delegation is invisible to the remote SMTP client. </p> + +<table> + +<tr> <td colspan="2"> </td> <td align="center"> zombie </td> </tr> + +<tr> <td colspan="3"> </td> <td align="left"> <tt> \ </tt> </td> </tr> + +<tr> <td> zombie </td> <td> <tt> - </tt> </td> <td bgcolor="#f0f0ff" align="center"> tlsproxy(8) </td> <td align="left"> <tt> - </tt> </td> <td> +</td> <td> </td> <td> </td> <td align="right"> <tt> - </tt> </td> +<td bgcolor="#f0f0ff" align="center"> smtpd(8) </td> </tr> + +<tr> <td colspan="3"> </td> <td align="right"> <tt> \ </tt> </td> <td> </td> +<td align="left"> <tt> / </tt> </td> </tr> + +<tr> <td colspan="2"> </td> <td bgcolor="#f0f0ff" align="center"> other </td> <td> <tt> +--- </tt> </td> <td bgcolor="#f0f0ff" align="center" valign="middle"> +postscreen(8) </td> </tr> + +<tr> <td colspan="3"> </td> <td align="right"> <tt> / </tt> </td> <td> </td> +<td align="right"> <tt> \ </tt> </td> </tr> + +<tr> <td colspan="2"> </td> <td bgcolor="#f0f0ff" align="center"> other </td> <td align="left"> +<tt> - </tt> </td> <td> </td> <td> </td> <td> </td> <td align="right"> +<tt> - </tt> </td> <td bgcolor="#f0f0ff" align="center"> smtpd(8) +</td> </tr> + +<tr> <td colspan="3"> </td> <td align="left"> <tt> / </tt> </td> </tr> + +<tr> <td colspan="2"> </td> <td align="center"> zombie </td> </tr> + +</table> + +<li> <p>The postlogd(8) server provides an alternative to syslog +logging, which remains the default. This feature is available with +Postfix version 3.4 or later, and supports the following modes: +</p> + + +<ul> + +<li> <p>Logging to file, which addresses a usability problem with +MacOS, and eliminates information loss caused by systemd rate limits. +</p> + +<table> + +<tr> <td bgcolor="#f0f0ff" rowspan="3" valign="middle" align="center"> +commands<br>or daemons</td> <td colspan="4"> </td> </tr> + +<tr> <td colspan="2"> <td> <tt> -> </tt> </td> <td bgcolor="#f0f0ff"> +postlogd(8) </td> <td> <tt> -> </tt> </td> <td> /path/to/file +</td> </tr> + +<tr> <td colspan=6> </td> </tr> + +</table> + +<li> <p>Logging to stdout, which eliminates a syslog dependency +when Postfix runs inside a container. </p> + +<table> + +<tr> <td bgcolor="#f0f0ff" rowspan="3" valign="middle" align="center"> +commands<br>or daemons</td> <td colspan="4"> </td> <td +rowspan="3" align="center"> stdout inherited<br>from "postfix +start-fg" </td> </tr> + +<tr> <td colspan="2"> <tt> -> </tt> </td> <td bgcolor="#f0f0ff"> +postlogd(8) </td> <td> <tt> -> </tt> </td> </tr> + +<tr> <td colspan=5> </td> </tr> + +</table> + +</ul> + +<p> See MAILLOG_README for details and limitations. </p> + +</ul> + +<h2> <a name="commands"> Postfix support commands </a> </h2> + +<p> The Postfix architecture overview ends with a summary of +command-line utilities for day-to-day use of the Postfix mail +system. Besides the Sendmail-compatible sendmail(1), mailq(1), and +newaliases(1) commands, the Postfix system comes with it own +collection of command-line utilities. For consistency, these are +all named post<i>something</i>. </p> + +<ul> + +<li> <p> The postfix(1) command controls the operation of the mail +system. It is the interface for starting, stopping, and restarting +the mail system, as well as for some other administrative operations. +This command is reserved to the super-user. </p> + +<li> <p> The postalias(1) command maintains Postfix aliases(5) type +databases. This is the program that does the work for the +newaliases(1) command. </p> + +<li> <p> The postcat(1) command displays the contents of Postfix +queue files. This is a limited, preliminary utility. This program +is likely to be superseded by something more powerful that can also +edit Postfix queue files. </p> + +<li> <p> The postconf(1) command displays or updates Postfix main.cf +parameters and displays system dependent information about the +supported file locking methods, and the supported types of lookup +tables. </p> + +<li> <p> The postdrop(1) command is the mail posting utility that +is run by the Postfix sendmail(1) command in order to deposit mail +into the maildrop queue directory. </p> + +<li> <p> The postkick(1) command makes some Postfix internal +communication channels available for use in, for example, shell +scripts. </p> + +<li> <p> The postlock(1) command provides Postfix-compatible mailbox +locking for use in, for example, shell scripts. </p> + +<li> <p> The postlog(1) command provides Postfix-compatible logging +for shell scripts. </p> + +<li> <p> The postmap(1) command maintains Postfix lookup tables +such as canonical(5), virtual(5) and others. It is a cousin of the +UNIX makemap command. </p> + +<li> <p> The postmulti(1) command repeats the "postfix start" etc. +command for each Postfix instance, and supports creation, deletion +etc. of Postfix instances. For a tutorial, see MULTI_INSTANCE_README. +</p> + +<li> <p> The postqueue(1) command is the privileged command that +is run by Postfix sendmail(1) and mailq(1) in order to flush or +list the +mail queue. </p> + +<li> <p> The postsuper(1) command maintains the Postfix queue. It +removes old temporary files, and moves queue files into the right +directory after a change in the hashing depth of queue directories. +This command is run at mail system startup time and when Postfix +is restarted. </p> + +</ul> + +</body> + +</html> diff --git a/proto/PACKAGE_README.html b/proto/PACKAGE_README.html new file mode 100644 index 0000000..a30d072 --- /dev/null +++ b/proto/PACKAGE_README.html @@ -0,0 +1,154 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Guidelines for Package Builders</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Guidelines for Package Builders</h1> + +<hr> + +<h2>Purpose of this document</h2> + +<p> This document has hints and tips for those who manage their +own Postfix binary distribution for internal use, and for those who +maintain Postfix binary distributions for general use. </p> + +<h2>General distributions: please provide a small default main.cf +file</h2> + +<p> The installed main.cf file must be small. PLEASE resist the +temptation to list all parameters in the main.cf file. Postfix +is supposed to be easy to configure. Listing all parameters in main.cf +defeats the purpose. It is an invitation for hobbyists to make +random changes without understanding what they do, and gets them +into endless trouble. </p> + +<h2>General distributions: please include README or HTML files</h2> + +<p> Please provide the applicable README or HTML files. They are +referenced by the Postfix manual pages and by other files. Without +README or HTML files, Postfix will be difficult if not impossible +to configure. </p> + +<h2>Postfix Installation parameters</h2> + +<p> Postfix installation is controlled by a dozen installation +parameters. See the postfix-install and post-install files for +details. Most parameters have system-dependent default settings +that are configurable at compile time, as described in the INSTALL +file. </p> + +<h2>Preparing a pre-built package for distribution to other +systems</h2> + +<p> You can build a Postfix package on a machine that does not have +Postfix installed on it. All you need is Postfix source code and +a compilation environment that is compatible with the target system. +</p> + +<p> You can build a pre-built Postfix package as an unprivileged +user. </p> + +<p> First compile Postfix. After successful compilation, execute: +</p> + +<blockquote> <pre> % <b>make package</b> </pre> +</blockquote> + +<p> With Postfix versions before 2.2 you must invoke the post-install +script directly (<tt>% <b>sh post-install</b></tt>). </p> + +<p> You will be prompted for installation parameters. Specify an +install_root directory other than /. The mail_owner and setgid_group +installation parameter settings will be recorded in the main.cf +file, but they won't take effect until the package is unpacked and +installed on the destination machine. </p> + +<p> If you want to fully automate this process, specify all the +non-default installation parameters on the command line: </p> + +<blockquote> +<pre> % <b>make non-interactive-package install_root=/some/where</b>... +</pre> </blockquote> + +<p> With Postfix versions before 2.2 you must invoke the post-install +script directly (<tt>% <b>sh post-install -non-interactive +install_root...</b></tt>). </p> + +<p> With Postfix 3.0 and later, the command "make package name=value +..." will replace the string MAIL_VERSION in a configuration parameter +value with the Postfix release version. Do not try to specify +something like $mail_version on this command line. This produces +inconsistent results with different versions of the make(1) command. +</p> + +<h2>Begin Security Alert</h2> + +<p> <b> When building an archive for distribution, be sure to +archive only files and symbolic links, not their parent directories. +Otherwise, unpacking a pre-built Postfix package may mess up +permission and/or ownership of system directories such as / /etc +/usr /usr/bin /var /var/spool and so on. This is especially an +issue if you executed postfix-install (see above) as an unprivileged +user. </b> </p> + +<h2>End Security Alert</h2> + +<p> Thus, to tar up the pre-built package, take the following steps: +</p> + +<blockquote> <pre> +% cd INSTALL_ROOT +% rm -f SOMEWHERE/outputfile +% find . \! -type d -print | xargs tar rf SOMEWHERE/outputfile +% gzip SOMEWHERE/outputfile </pre> </blockquote> + +<p>This way you will not include any directories that might cause +trouble upon extraction. </p> + +<h2>Installing a pre-built Postfix package</h2> + +<ul> + +<li> <p> To unpack a pre-built Postfix package, execute the equivalent +of: </p> + +<pre> +# umask 022 +# gzip -d <outputfile.tar.gz | (cd / ; tar xvpf -) </pre> + +<p> The umask command is necessary for getting the correct permissions +on non-Postfix directories that need to be created in the process. +</p> + +<li> <p> Create the necessary mail_owner account and setgid_group +group for exclusive use by Postfix. </p> + +<li> <p> Execute the postfix command to set ownership and permission +of Postfix files and directories, and to update Postfix configuration +files. If necessary, specify any non-default settings for mail_owner +or setgid_group on the postfix command line: </p> + +<pre> +# postfix set-permissions upgrade-configuration \ + setgid_group=xxx mail_owner=yyy +</pre> + +<p> With Postfix versions before 2.1 you achieve the same result +by invoking the post-install script directly. </p> + +</ul> + +</body> + +</html> diff --git a/proto/PCRE_README.html b/proto/PCRE_README.html new file mode 100644 index 0000000..1741826 --- /dev/null +++ b/proto/PCRE_README.html @@ -0,0 +1,123 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix PCRE Support</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix PCRE Support</h1> + +<hr> + +<h2>PCRE (Perl Compatible Regular Expressions) map support</h2> + +<p> The optional "pcre" map type allows you to specify regular +expressions with the PERL style notation such as \s for space and +\S for non-space. The main benefit, however, is that pcre lookups +are often faster than regexp lookups. This is because the pcre +implementation is often more efficient than the POSIX regular +expression implementation that you find on many systems. </p> + +<p> A description of how to use pcre tables, including examples, +is given in the pcre_table(5) manual page. Information about PCRE +itself can be found at http://www.pcre.org/. </p> + +<h2>Using Postfix packages with PCRE support</h2> + +<p> To use pcre with Debian GNU/Linux's Postfix, or with Fedora or +RHEL Postfix, all you +need is to install the postfix-pcre package and you're done. There +is no need to recompile Postfix. </p> + +<h2>Building Postfix from source with PCRE support</h2> + +<p> These instructions assume that you build Postfix from source +code as described in the INSTALL document. </p> + +<p> To build Postfix from source with pcre support, you need a pcre +library. Install a vendor package, or download the source code from +locations in https://www.pcre.org/ and build that yourself. + +<p> Postfix can build with the pcre2 library or the legacy pcre +library. It's probably easiest to let the Postfix build procedure +pick one. The following commands will first discover if the pcre2 +library is installed, and if that is not available, will discover +if the legacy pcre library is installed. </p> + +<blockquote> +<pre> +$ make -f Makefile.init makefiles +$ make +</pre> +</blockquote> + +<p> To build Postfix explicitly with a pcre2 library (Postfix 3.7 +and later): </p> + +<blockquote> +<pre> +$ make -f Makefile.init makefiles \ + "CCARGS=-DHAS_PCRE=2 `pcre2-config --cflags`" \ + "AUXLIBS_PCRE=`pcre2-config --libs8`" +$ make +</pre> +</blockquote> + +<p> To build Postfix explicitly with a legacy pcre library (all +Postfix versions): </p> + +<blockquote> +<pre> +$ make -f Makefile.init makefiles \ + "CCARGS=-DHAS_PCRE=1 `pcre-config --cflags`" \ + "AUXLIBS_PCRE=`pcre-config --libs`" +$ make +</pre> +</blockquote> + +<p> Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_PCRE. +With Postfix 3.0 and later, the old AUXLIBS variable still supports +building a statically-loaded PCRE database client, but only the new +AUXLIBS_PCRE variable supports building a dynamically-loaded or +statically-loaded PCRE database client. </p> + +<blockquote> + +<p> Failure to use the AUXLIBS_PCRE variable will defeat the purpose +of dynamic database client loading. Every Postfix executable file +will have PCRE library dependencies. And that was exactly +what dynamic database client loading was meant to avoid. </p> + +</blockquote> + +<h2>Things to know</h2> + +<ul> + +<li> <p> When Postfix searches a pcre: or regexp: lookup table, +each pattern is applied to the entire input string. Depending on +the application, that string is an entire client hostname, an entire +client IP address, or an entire mail address. Thus, no parent domain +or parent network search is done, "user@domain" mail addresses are +not broken up into their user and domain constituent parts, and +"user+foo" is not broken up into user and foo. </p> + +<li> <p> Regular expression tables such as pcre: or regexp: are +not allowed to do $number substitution in lookup results that can +be security sensitive: currently, that restriction applies to the +local aliases(5) database or the virtual(8) delivery agent tables. +</p> + +</ul> + +</body> + +</html> diff --git a/proto/PGSQL_README.html b/proto/PGSQL_README.html new file mode 100644 index 0000000..61445ba --- /dev/null +++ b/proto/PGSQL_README.html @@ -0,0 +1,174 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix PostgreSQL Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix PostgreSQL Howto</h1> + +<hr> + +<h2>Introduction</h2> + +<p> The Postfix pgsql map type allows you to hook up Postfix to a +PostgreSQL database. This implementation allows for multiple pgsql +databases: you can use one for a virtual(5) table, one for an +access(5) table, and one for an aliases(5) table if you want. You +can specify multiple servers for the same database, so that Postfix +can switch to a good database server if one goes bad. </p> + +<p> Busy mail servers using pgsql maps will generate lots of +concurrent pgsql clients, so the pgsql server(s) should be run with +this fact in mind. You can reduce the number of concurrent pgsql +clients by using the Postfix proxymap(8) service. </p> + +<h2>Building Postfix with PostgreSQL support</h2> + +<p> These instructions assume that you build Postfix from source +code as described in the INSTALL document. Some modification may +be required if you build Postfix from a vendor-specific source +package. </p> + +<p> Note: to use pgsql with Debian GNU/Linux's Postfix, all you +need to do is to install the postfix-pgsql package and you're done. +There is no need to recompile Postfix. </p> + +<p> In order to build Postfix with pgsql map support, you specify +-DHAS_PGSQL, the directory with the PostgreSQL header files, and +the location of the libpq library file. </p> + +<p> For example: </p> + +<blockquote> +<pre> +% make tidy +% make -f Makefile.init makefiles \ + 'CCARGS=-DHAS_PGSQL -I/usr/local/include/pgsql' \ + 'AUXLIBS_PGSQL=-L/usr/local/lib -lpq' +</pre> +</blockquote> + +<p> If your PostgreSQL shared library is in a directory that the RUN-TIME +linker does not know about, add a "-Wl,-R,/path/to/directory" option after +"-lpq". </p> + +<p> Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_PGSQL. +With Postfix 3.0 and later, the old AUXLIBS variable still supports +building a statically-loaded PostgreSQL database client, but only +the new AUXLIBS_PGSQL variable supports building a dynamically-loaded +or statically-loaded PostgreSQL database client. </p> + +<blockquote> + +<p> Failure to use the AUXLIBS_PGSQL variable will defeat the purpose +of dynamic database client loading. Every Postfix executable file +will have PGSQL database library dependencies. And that was exactly +what dynamic database client loading was meant to avoid. </p> + +</blockquote> + +<p> Then just run 'make'. </p> + +<h2>Configuring PostgreSQL lookup tables</h2> + +<p> Once Postfix is built with pgsql support, you can specify a +map type in main.cf like this: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + alias_maps = pgsql:/etc/postfix/pgsql-aliases.cf +</pre> +</blockquote> + +<p> The file /etc/postfix/pgsql-aliases.cf specifies lots of +information telling postfix how to reference the pgsql database. +For a complete description, see the pgsql_table(5) manual page. </p> + +<h2>Example: local aliases </h2> + +<pre> +# +# pgsql config file for local(8) aliases(5) lookups +# + +# +# The hosts that Postfix will try to connect to +hosts = host1.some.domain host2.some.domain + +# The user name and password to log into the pgsql server. +user = someone +password = some_password + +# The database name on the servers. +dbname = customer_database + +# Postfix 2.2 and later The SQL query template. See pgsql_table(5). +query = SELECT forw_addr FROM mxaliases WHERE alias='%s' AND status='paid' + +# For Postfix releases prior to 2.2. See pgsql_table(5) for details. +select_field = forw_addr +table = mxaliases +where_field = alias +# Don't forget the leading "AND"! +additional_conditions = AND status = 'paid' +</pre> + +<h2>Using mirrored databases</h2> + +<p> Sites that have a need for multiple mail exchangers may enjoy +the convenience of using a networked mailer database, but do not +want to introduce a single point of failure to their system. </p> + +<p> For this reason we've included the ability to have Postfix +reference multiple hosts for access to a single pgsql map. This +will work if sites set up mirrored pgsql databases on two or more +hosts. </p> + +<p> Whenever queries fail with an error at one host, the rest of +the hosts will be tried in random order. If no pgsql server hosts +are reachable, then mail will be deferred until at least one of +those hosts is reachable. </p> + +<h2>Credits</h2> + +<ul> + +<li> This code is based upon the Postfix mysql map by Scott Cotton +and Joshua Marcus, IC Group, Inc.</li> + +<li> The PostgreSQL changes were done by Aaron Sethman.</li> + +<li> Updates for Postfix 1.1.x and PostgreSQL 7.1+ and support for +calling stored procedures were added by Philip Warner.</li> + +<li> LaMont Jones was the initial Postfix pgsql maintainer.</li> + +<li> Liviu Daia revised the configuration interface and added the +main.cf configuration feature.</li> + +<li> Liviu Daia revised the configuration interface and added the main.cf +configuration feature.</li> + +<li> Liviu Daia with further refinements from Jose Luis Tallon and +Victor Duchovni developed the common query, result_format, domain and +expansion_limit interface for LDAP, MySQL and PosgreSQL.</li> + +<li> Leandro Santi updated the PostgreSQL client after the PostgreSQL +developers made major database API changes in response to SQL +injection problems, and made PQexec() handling more robust. </li> + +</ul> + +</body> + +</html> diff --git a/proto/POSTSCREEN_3_5_README.html b/proto/POSTSCREEN_3_5_README.html new file mode 100644 index 0000000..56db379 --- /dev/null +++ b/proto/POSTSCREEN_3_5_README.html @@ -0,0 +1,1198 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<head> + +<title>Postfix Postscreen Howto (Postfix 2.8 - 3.5)</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Postscreen Howto (Postfix 2.8 - 3.5)</h1> + +<hr> + +<h2> <a name="intro">Introduction</a> </h2> + +<p> This document describes features that are available in Postfix +2.8 - 3.5. </p> + +<p> The Postfix postscreen(8) daemon provides additional protection +against mail server overload. One postscreen(8) process handles +multiple inbound SMTP connections, and decides which clients may +talk to a Postfix SMTP server process. By keeping spambots away, +postscreen(8) leaves more SMTP server processes available for +legitimate clients, and delays the onset of <a +href="STRESS_README.html">server overload</a> conditions. </p> + +<p> postscreen(8) should not be used on SMTP ports that receive +mail from end-user clients (MUAs). In a typical deployment, +postscreen(8) handles the MX service on TCP port 25, while MUA +clients submit mail via the submission service on TCP port 587 which +requires client authentication. Alternatively, a site could set up +a dedicated, non-postscreen, "port 25" server that provides submission +service and client authentication, but no MX service. </p> + +<p> postscreen(8) maintains a temporary allowlist for clients that +pass its tests; by allowing allowlisted clients to skip tests, +postscreen(8) minimizes its impact on legitimate email traffic. +</p> + +<p> postscreen(8) is part of a multi-layer defense. <p> + +<ul> + +<li> <p> As the first layer, postscreen(8) blocks connections from +zombies and other spambots that are responsible for about 90% of +all spam. It is implemented as a single process to make this defense +as inexpensive as possible. </p> + +<li> <p> The second layer implements more complex SMTP-level access +checks with <a href="SMTPD_ACCESS_README.html">Postfix SMTP servers</a>, +<a href="SMTPD_POLICY_README.html">policy daemons</a>, and +<a href="MILTER_README.html">Milter applications</a>. </p> + +<li> <p> The third layer performs light-weight content inspection +with the Postfix built-in header_checks and body_checks. This can +block unacceptable attachments such as executable programs, and +worms or viruses with easy-to-recognize signatures. </p> + +<li> <p> The fourth layer provides heavy-weight content inspection +with external content filters. Typical examples are <a +href="http://www.ijs.si/software/amavisd/">Amavisd-new</a>, <a +href="http://spamassassin.apache.org/">SpamAssassin</a>, and <a +href="MILTER_README.html">Milter applications</a>. </p> + +</ul> + +<p> Each layer reduces the spam volume. The general strategy is to +use the less expensive defenses first, and to use the more expensive +defenses only for the spam that remains. </p> + +<p> Topics in this document: </p> + +<ul> + +<li> <a href="#intro">Introduction</a> + +<li> <a href="#basic">The basic idea behind postscreen(8)</a> + +<li> <a href="#general"> General operation </a> + +<li> <a href="#quick">Quick tests before everything else</a> + +<li> <a href="#before_220"> Tests before the 220 SMTP server greeting </a> + +<li> <a href="#after_220">Tests after the 220 SMTP server greeting</a> + +<li> <a href="#other_error">Other errors</a> + +<li> <a href="#victory">When all tests succeed</a> + +<li> <a href="#config"> Configuring the postscreen(8) service</a> + +<li> <a href="#historical"> Historical notes and credits </a> + +</ul> + +<h2> <a name="basic">The basic idea behind postscreen(8)</a> </h2> + +<p> Most email is spam, and most spam is sent out by zombies (malware +on compromised end-user computers). Wietse expects that the zombie +problem will get worse before things improve, if ever. Without a +tool like postscreen(8) that keeps the zombies away, Postfix would be +spending most of its resources not receiving email. </p> + +<p> The main challenge for postscreen(8) is to make an is-a-zombie +decision based on a single measurement. This is necessary because +many zombies try to fly under the radar and avoid spamming the same +site repeatedly. Once postscreen(8) decides that a client is +not-a-zombie, it allowlists the client temporarily to avoid further +delays for legitimate mail. </p> + +<p> Zombies have challenges too: they have only a limited amount +of time to deliver spam before their IP address becomes denylisted. +To speed up spam deliveries, zombies make compromises in their SMTP +protocol implementation. For example, they speak before their turn, +or they ignore responses from SMTP servers and continue sending +mail even when the server tells them to go away. </p> + +<p> postscreen(8) uses a variety of measurements to recognize +zombies. First, postscreen(8) determines if the remote SMTP client +IP address is denylisted. Second, postscreen(8) looks for protocol +compromises that are made to speed up delivery. These are good +indicators for making is-a-zombie decisions based on single +measurements. </p> + +<p> postscreen(8) does not inspect message content. Message content +can vary from one delivery to the next, especially with clients +that (also) send legitimate email. Content is not a good indicator +for making is-a-zombie decisions based on single measurements, +and that is the problem that postscreen(8) is focused on. </p> + +<h2> <a name="general"> General operation </a> </h2> + +<p> For each connection from an SMTP client, postscreen(8) performs +a number of tests +in the order as described below. Some tests introduce a delay of +a few seconds. postscreen(8) maintains a temporary allowlist for +clients that pass its tests; by allowing allowlisted clients to +skip tests, postscreen(8) minimizes its impact on legitimate email +traffic. </p> + +<p> By default, postscreen(8) hands off all connections to a Postfix +SMTP server process after logging its findings. This mode is useful +for non-destructive testing. </p> + +<p> In a typical production setting, postscreen(8) is configured +to reject mail from clients that fail one or more tests, after +logging the helo, sender and recipient information. </p> + +<p> Note: postscreen(8) is not an SMTP proxy; this is intentional. +The purpose is to keep zombies away from Postfix, with minimal +overhead for legitimate clients. </p> + +<h2> <a name="quick">Quick tests before everything else</a> </h2> + +<p> Before engaging in SMTP-level tests. postscreen(8) queries a +number of local deny and allowlists. These tests speed up the +handling of known clients. </p> + +<ul> + +<li> <a href="#perm_white_black"> Permanent allow/denylist test </a> + +<li> <a href="#temp_white"> Temporary allowlist test </a> + +<li> <a href="#white_veto"> MX Policy test </a> + +</ul> + +<h3> <a name="perm_white_black"> Permanent allow/denylist test </a> </h3> + +<p> The postscreen_access_list parameter (default: permit_mynetworks) +specifies a permanent access list for SMTP client IP addresses. Typically +one would specify something that allowlists local networks, followed +by a CIDR table for selective allow- and denylisting. </p> + +<p> Example: </p> + +<pre> +/etc/postfix/main.cf: + postscreen_access_list = permit_mynetworks, + cidr:/etc/postfix/postscreen_access.cidr + +/etc/postfix/postscreen_access.cidr: + # Rules are evaluated in the order as specified. + # Denylist 192.168.* except 192.168.0.1. + 192.168.0.1 permit + 192.168.0.0/16 reject +</pre> + +<p> See the postscreen_access_list manpage documentation for more +details. </p> + +<p> When the SMTP client address matches a "permit" action, +postscreen(8) logs this with the client address and port number as: +</p> + +<pre> + <b>WHITELISTED</b> <i>[address]:port</i> +</pre> + +<p> The allowlist action is not configurable: immediately hand off the +connection to a Postfix SMTP server process. </p> + +<p> When the SMTP client address matches a "reject" action, +postscreen(8) logs this with the client address and port number as: +</p> + +<pre> + <b>BLACKLISTED</b> <i>[address]:port</i> +</pre> + +<p> The postscreen_blacklist_action parameter specifies the action +that is taken next. See "<a href="#fail_before_220">When tests +fail before the 220 SMTP server greeting</a>" below. </p> + +<h3> <a name="temp_white"> Temporary allowlist test </a> </h3> + +<p> The postscreen(8) daemon maintains a <i>temporary</i> +allowlist for SMTP client IP addresses that have passed all +the tests described below. The postscreen_cache_map parameter +specifies the location of the temporary allowlist. The +temporary allowlist is not used for SMTP client addresses +that appear on the <i>permanent</i> access list. </p> + +<p> By default the temporary allowlist is not shared with other +postscreen(8) daemons. See +<a href="#temp_white_sharing"> Sharing +the temporary allowlist </a> below for alternatives. </p> + +<p> When the SMTP client address appears on the temporary +allowlist, postscreen(8) logs this with the client address and port +number as: </p> + +<pre> + <b>PASS OLD</b> <i>[address]:port</i> +</pre> + +<p> The action is not configurable: immediately hand off the +connection to a Postfix SMTP server process. The client is +excluded from further tests until its temporary allowlist +entry expires, as controlled with the postscreen_*_ttl +parameters. Expired entries are silently renewed if possible. </p> + +<h3> <a name="white_veto"> MX Policy test </a> </h3> + +<p> When the remote SMTP client is not on the static access list +or temporary allowlist, postscreen(8) can implement a number of +allowlist tests, before it grants the client a temporary allowlist +status that allows it to talk to a Postfix SMTP server process. </p> + +<p> When postscreen(8) is configured to monitor all primary and +backup MX addresses, it can refuse to allowlist clients that connect +to a backup MX address only (an old spammer trick to take advantage +of backup MX hosts with weaker anti-spam policies than primary MX +hosts). </p> + +<blockquote> <p> NOTE: The following solution is for small sites. +Larger sites would have to share the postscreen(8) cache between +primary and backup MTAs, which would introduce a common point of +failure. </p> </blockquote> + +<ul> + +<li> <p> First, configure the host to listen on both primary and +backup MX addresses. Use the appropriate <tt>ifconfig</tt> or <tt>ip</tt> +command for the local operating system, or update the appropriate +configuration files and "refresh" the network protocol stack. </p> + +<p> <p> Second, configure Postfix to listen on the new IP address +(this step is needed when you have specified inet_interfaces in +main.cf). </p> + +<li> <p> Then, configure postscreen(8) to deny the temporary allowlist +status on the backup MX address(es). An example for Wietse's +server is: </p> + +<pre> +/etc/postfix/main.cf: + postscreen_whitelist_interfaces = !168.100.189.8 static:all +</pre> + +<p> Translation: allow clients to obtain the temporary allowlist +status on all server IP addresses except 168.100.189.8, which is a +backup MX address. </p> + +</ul> + +<p> When a non-allowlisted client connects the backup MX address, +postscreen(8) logs this with the client address and port number as: +</p> + +<pre> + <b>CONNECT from</b> <i>[address]:port</i> <b>to [168.100.189.8]:25</b> + <b>WHITELIST VETO</b> <i>[address]:port</i> +</pre> + +<p> Translation: the client at <i>[address]:port</i> connected to +the backup MX address 168.100.189.8 while it was not allowlisted. +The client will not be granted the temporary allowlist status, even +if passes all the allowlist tests described below. </p> + +<h2> <a name="before_220"> Tests before the 220 SMTP server greeting </a> </h2> + +<p> The postscreen_greet_wait parameter specifies a short time +interval before the "220 <i>text</i>..." server greeting, where +postscreen(8) can run a number of tests in parallel. </p> + +<p> When a good client passes these tests, and no "<a +href="#after_220">deep protocol tests</a>" +are configured, postscreen(8) +adds the client to the temporary allowlist and hands off the "live" +connection to a Postfix SMTP server process. The client can then +continue as if postscreen(8) never even existed (except of course +for the short postscreen_greet_wait delay). </p> + +<ul> + +<li> <a href="#pregreet"> Pregreet test </a> + +<li> <a href="#dnsbl"> DNS Allow/denylist test </a> + +<li> <a href="#fail_before_220">When tests fail before the 220 SMTP server greeting</a> + +</ul> + +<h3> <a name="pregreet"> Pregreet test </a> </h3> + +<p> The SMTP protocol is a classic example of a protocol where the +server speaks before the client. postscreen(8) detects zombies +that are in a hurry and that speak before their turn. This test is +enabled by default. </p> + +<p> The postscreen_greet_banner parameter specifies the <i>text</i> +portion of a "220-<i>text</i>..." teaser banner (default: $smtpd_banner). +Note that this becomes the first part of a multi-line server greeting. +The postscreen(8) daemon sends this before the postscreen_greet_wait +timer is started. The purpose of the teaser banner is to confuse +zombies so that they speak before their turn. It has no effect on +SMTP clients that correctly implement the protocol. </p> + +<p> To avoid problems with poorly-implemented SMTP engines in network +appliances or network testing tools, either exclude them from all +tests with the postscreen_access_list feature or else specify +an empty teaser banner: </p> + +<pre> +/etc/postfix/main.cf: + # Exclude broken clients by allowlisting. Clients in mynetworks + # should always be allowlisted. + postscreen_access_list = permit_mynetworks, + cidr:/etc/postfix/postscreen_access.cidr + +/etc/postfix/postscreen_access.cidr: + 192.168.254.0/24 permit +</pre> + +<pre> +/etc/postfix/main.cf: + # Disable the teaser banner (try allowlisting first if you can). + postscreen_greet_banner = +</pre> + +<p> When an SMTP client sends a command before the +postscreen_greet_wait time has elapsed, postscreen(8) logs this as: +</p> + +<pre> + <b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>[address]:port text...</i> +</pre> + +<p> Translation: the client at <i>[address]:port</i> sent <i>count</i> +bytes before its turn to speak. This happened <i>time</i> seconds +after the postscreen_greet_wait timer was started. The <i>text</i> +is what the client sent (truncated to 100 bytes, and with non-printable +characters replaced with C-style escapes such as \r for carriage-return +and \n for newline). </p> + +<p> The postscreen_greet_action parameter specifies the action that +is taken next. See "<a href="#fail_before_220">When tests fail +before the 220 SMTP server greeting</a>" below. </p> + +<h3> <a name="dnsbl"> DNS Allow/denylist test </a> </h3> + +<p> The postscreen_dnsbl_sites parameter (default: empty) specifies +a list of DNS blocklist servers with optional filters and weight +factors (positive weights for denylisting, negative for allowlisting). +These servers will be queried in parallel with the reverse client +IP address. This test is disabled by default. </p> + +<blockquote> +<p> +CAUTION: when postscreen rejects mail, its SMTP reply contains the +DNSBL domain name. Use the postscreen_dnsbl_reply_map feature to +hide "password" information in DNSBL domain names. +</p> +</blockquote> + +<p> When the postscreen_greet_wait time has elapsed, and the combined +DNSBL score is equal to or greater than the postscreen_dnsbl_threshold +parameter value, postscreen(8) logs this as: </p> + +<pre> + <b>DNSBL rank</b> <i>count</i> <b>for</b> <i>[address]:port</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> has a combined +DNSBL score of <i>count</i>. </p> + +<p> The postscreen_dnsbl_action parameter specifies the action that +is taken when the combined DNSBL score is equal to or greater than +the threshold. See "<a href="#fail_before_220">When tests fail +before the 220 SMTP server greeting</a>" below. </p> + +<h3> <a name="fail_before_220">When tests fail before the 220 SMTP server greeting</a> </h3> + +<p> When the client address matches the permanent denylist, or +when the client fails the pregreet or DNSBL tests, the action is +specified with postscreen_blacklist_action, postscreen_greet_action, +or postscreen_dnsbl_action, respectively. </p> + +<dl> + +<dt> <b>ignore</b> (default) </dt> + +<dd> Ignore the failure of this test. Allow other tests to complete. +Repeat this test the next time the client connects. This option +is useful for testing and collecting statistics without blocking +mail. </dd> + +<dt> <b>enforce</b> </dt> + +<dd> Allow other tests to complete. Reject attempts to deliver mail +with a 550 SMTP reply, and log the helo/sender/recipient information. +Repeat this test the next time the client connects. </dd> + +<dt> <b>drop</b> </dt> + +<dd> Drop the connection immediately with a 521 SMTP reply. Repeat +this test the next time the client connects. </dd> + +</dl> + +<h2> <a name="after_220">Tests after the 220 SMTP server greeting</a> </h2> + +<p> In this phase of the protocol, postscreen(8) implements a +number of "deep protocol" tests. These tests use an SMTP protocol +engine that is built into the postscreen(8) server. </p> + +<p> Important note: these protocol tests are disabled by default. +They are more intrusive than the pregreet and DNSBL tests, and they +have limitations as discussed next. </p> + +<ul> + +<li> <p> The main limitation of "after 220 greeting" tests is that +a new client must disconnect after passing these tests (reason: +postscreen is not a proxy). Then the client must reconnect from +the same IP address before it can deliver mail. The following +measures may help to avoid email delays: </p> + +<ul> + +<li> <p> Allow "good" clients to skip tests with the +postscreen_dnsbl_whitelist_threshold feature (Postfix 2.11 and +later). This is especially effective for sites such as Google that +never retry immediately from the same IP address. </p> + +<li> <p> Small sites: Configure postscreen(8) to listen on multiple +IP addresses, published in DNS as different IP addresses for the +same MX hostname or for different MX hostnames. This avoids mail +delivery delays with clients that reconnect immediately from the +same IP address. </p> + +<li> <p> Large sites: Share the postscreen(8) cache between different +Postfix MTAs with a large-enough memcache_table(5). Again, this +avoids mail delivery delays with clients that reconnect immediately +from the same IP address. </p> + +</ul> + +<li> <p> postscreen(8)'s built-in SMTP engine does not implement the +AUTH, XCLIENT, and XFORWARD features. If you need to make these +services available on port 25, then do not enable the tests after +the 220 server greeting. </p> + +<li> <p> End-user clients should connect directly to the submission +service, so that they never have to deal with postscreen(8)'s tests. +</p> + +</ul> + +<p> The following "after 220 greeting" tests are available: </p> + +<ul> + +<li> <a href="#pipelining">Command pipelining test</a> + +<li> <a href="#non_smtp">Non-SMTP command test</a> + +<li> <a href="#barelf">Bare newline test</a> + +<li> <a href="#fail_after_220">When tests fail after the 220 SMTP server greeting</a> + +</ul> + +<h3> <a name="pipelining">Command pipelining test</a> </h3> + +<p> By default, SMTP is a half-duplex protocol: the sender and +receiver send one command and one response at a time. Unlike the +Postfix SMTP server, postscreen(8) does not announce support +for ESMTP command pipelining. Therefore, clients are not allowed +to send multiple commands. postscreen(8)'s +<a href="#after_220">deep +protocol test</a> for this is disabled by default. </p> + +<p> With "postscreen_pipelining_enable = yes", postscreen(8) detects +zombies that send multiple commands, instead of sending one command +and waiting for the server to reply. </p> + +<p> This test is opportunistically enabled when postscreen(8) has +to use the built-in SMTP engine anyway. This is to make postscreen(8) +logging more informative. </p> + +<p> When a client sends multiple commands, postscreen(8) logs this +as: </p> + +<pre> + <b>COMMAND PIPELINING from</b> <i>[address]:port</i> <b>after</b> <i>command</i>: <i>text</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> sent +multiple SMTP commands, instead of sending one command and then +waiting for the server to reply. This happened after the client +sent <i>command</i>. The <i>text</i> shows part of the input that +was sent too early; it is not logged with Postfix 2.8. </p> + +<p> The postscreen_pipelining_action parameter specifies the action +that is taken next. See "<a href="#fail_after_220">When tests fail +after the 220 SMTP server greeting</a>" below. </p> + +<h3> <a name="non_smtp">Non-SMTP command test</a> </h3> + +<p> Some spambots send their mail through open proxies. A symptom +of this is the usage of commands such as CONNECT and other non-SMTP +commands. Just like the Postfix SMTP server's smtpd_forbidden_commands +feature, postscreen(8) has an equivalent postscreen_forbidden_commands +feature to block these clients. postscreen(8)'s +<a href="#after_220">deep +protocol test</a> for this is disabled by default. </p> + +<p> With "postscreen_non_smtp_command_enable = yes", postscreen(8) +detects zombies that send commands specified with the +postscreen_forbidden_commands parameter. This also detects commands +with the syntax of a message header label. The latter is a symptom +that the client is sending message content after ignoring all the +responses from postscreen(8) that reject mail. </p> + +<p> This test is opportunistically enabled when postscreen(8) has +to use the built-in SMTP engine anyway. This is to make postscreen(8) +logging more informative. </p> + +<p> When a client sends non-SMTP commands, postscreen(8) logs this +as: </p> + +<pre> + <b>NON-SMTP COMMAND from</b> <i>[address]:port</i> <b>after</b> <i>command: text</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> sent a +command that matches the postscreen_forbidden_commands +parameter, or that has the syntax of a message header label (text +followed by optional space and ":"). +The "<tt><b>after</b> <i>command</i></tt>" portion is logged with +Postfix 2.10 and later. </p> + +<p> The postscreen_non_smtp_command_action parameter specifies +the action that is taken next. See "<a href="#fail_after_220">When +tests fail after the 220 SMTP server greeting</a>" below. </p> + +<h3> <a name="barelf">Bare newline test</a> </h3> + +<p> SMTP is a line-oriented protocol: lines have a limited length, +and are terminated with <CR><LF>. Lines ending in a +"bare" <LF>, that is newline not preceded by carriage return, +are not allowed in SMTP. postscreen(8)'s +<a href="#after_220">deep +protocol test</a> for this is disabled by default. </p> + +<p> With "postscreen_bare_newline_enable = yes", postscreen(8) +detects clients that send lines ending in bare newline characters. +</p> + +<p> This test is opportunistically enabled when postscreen(8) has +to use the built-in SMTP engine anyway. This is to make postscreen(8) +logging more informative. </p> + +<p> When a client sends bare newline characters, postscreen(8) logs +this as: +</p> + +<pre> + <b>BARE NEWLINE from</b> <i>[address]:port</i> <b>after</b> <i>command</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> sent a bare +newline character, that is newline not preceded by carriage +return. +The "<tt><b>after</b> <i>command</i></tt>" portion is logged with +Postfix 2.10 and later. </p> + +<p> The postscreen_bare_newline_action parameter specifies the +action that is taken next. See "<a href="#fail_after_220">When +tests fail after the 220 SMTP server greeting</a>" below. </p> + +<h3> <a name="fail_after_220">When tests fail after the 220 SMTP server greeting</a> </h3> + +<p> When the client fails the pipelining, non-SMTP command or bare +newline tests, the action is specified with postscreen_pipelining_action, +postscreen_non_smtp_command_action or postscreen_bare_newline_action, +respectively. </p> + +<dl> + +<dt> <b>ignore</b> (default for bare newline) </dt> + +<dd> Ignore the failure of this test. Allow other tests to complete. +Do NOT repeat this test before the result from some other test +expires. + +This option is useful for testing and collecting statistics without +blocking mail permanently. </dd> + +<dt> <b>enforce</b> (default for pipelining) </dt> + +<dd> Allow other tests to complete. Reject attempts to deliver +mail with a 550 SMTP reply, and log the helo/sender/recipient +information. Repeat this test the next time the client connects. +</dd> + +<dt> <b>drop</b> (default for non-SMTP commands) </dt> + +<dd> Drop the connection immediately with a 521 SMTP reply. Repeat +this test the next time the client connects. This action is +compatible with the Postfix SMTP server's smtpd_forbidden_commands +feature. </dd> + +</dl> + +<h2> <a name="other_error">Other errors</a> </h2> + +<p> When an SMTP client hangs up unexpectedly, postscreen(8) logs +this as: </p> + +<pre> + <b>HANGUP after</b> <i>time</i> <b>from</b> <i>[address]:port</i> <b>in</b> <i>test name</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> disconnected +unexpectedly, <i>time</i> seconds after the start of the +test named <i>test name</i>. </p> + +<p> There is no punishment for hanging up. A client that hangs up +without sending the QUIT command can still pass all postscreen(8) +tests. </p> + +<!-- + +<p> While an unexpired penalty is in effect, an SMTP client is not +allowed to pass any tests, and postscreen(8) logs each connection +with the remaining amount of penalty time as: </p> + +<pre> + <b>PENALTY</b> <i>time</i> <b>for</b> <i>[address]:port</i> +</pre> + +<p> During this time, all attempts by the client to deliver mail +will be deferred with a 450 SMTP status. </p> + +--> + +<p> The following errors are reported by the built-in SMTP engine. +This engine never accepts mail, therefore it has per-session limits +on the number of commands and on the session length. </p> + +<pre> + <b>COMMAND TIME LIMIT</b> <b>from</b> <i>[address]:port</i> <b>after</b> <i>command</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> reached the +per-command time limit as specified with the postscreen_command_time_limit +parameter. The session is terminated immediately. +The "<tt><b>after</b> <i>command</i></tt>" portion is logged with +Postfix 2.10 and later. </p> + +<pre> + <b>COMMAND COUNT LIMIT from</b> <i>[address]:port</i> <b>after</b> <i>command</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> reached the +per-session command count limit as specified with the +postscreen_command_count_limit parameter. The session is terminated +immediately. +The "<tt><b>after</b> <i>command</i></tt>" portion is logged with +Postfix 2.10 and later. </p> + +<pre> + <b>COMMAND LENGTH LIMIT from</b> <i>[address]:port</i> <b>after</b> <i>command</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> reached the +per-command length limit, as specified with the line_length_limit +parameter. The session is terminated immediately. +The "<tt><b>after</b> <i>command</i></tt>" portion is logged with +Postfix 2.10 and later. </p> + +<p> When an SMTP client makes too many connections at the same time, +postscreen(8) rejects the connection with a 421 status code and logs: </p> + +<pre> + <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: too many connections</b> +</pre> + +<p> The postscreen_client_connection_count_limit parameter controls this limit. </p> + +<p> When an SMTP client connects after postscreen(8) has reached a +connection count limit, postscreen(8) rejects the connection with +a 421 status code and logs: </p> + +<pre> + <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all screening ports busy</b> + <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all server ports busy</b> +</pre> + +<p> The postscreen_pre_queue_limit and postscreen_post_queue_limit +parameters control these limits. </p> + +<h2> <a name="victory">When all tests succeed</a> </h2> + +<p> When a new SMTP client passes all tests (i.e. it is not allowlisted +via some mechanism), postscreen(8) logs this as: </p> + +<pre> + <b>PASS NEW</b> <i>[address]:port</i> +</pre> + +<p> Where <i>[address]:port</i> are the client IP address and port. +Then, postscreen(8) +creates a temporary allowlist entry that excludes the client IP +address from further tests until the temporary allowlist entry +expires, as controlled with the postscreen_*_ttl parameters. </p> + +<p> When no "<a href="#after_220">deep protocol tests</a>" are +configured, postscreen(8) hands off the "live" connection to a Postfix +SMTP server process. The client can then continue as if postscreen(8) +never even existed (except for the short postscreen_greet_wait delay). +</p> + +<p> When any "<a href="#after_220">deep protocol tests</a>" are +configured, postscreen(8) cannot hand off the "live" connection to +a Postfix SMTP server process in the middle of the session. Instead, +postscreen(8) defers mail delivery attempts with a 4XX status, logs +the helo/sender/recipient information, and waits for the client to +disconnect. The next time the client connects it will be allowed +to talk to a Postfix SMTP server process to deliver its mail. +postscreen(8) mitigates the impact of this limitation by giving +<a href="#after_220">deep protocol tests</a> a long expiration +time. </p> + +<h2> <a name="config"> Configuring the postscreen(8) service</a> +</h2> + +<p> postscreen(8) has been tested on FreeBSD [4-8], Linux 2.[4-6] +and Solaris 9 systems. </p> + +<ul> + +<li> <a href="#enable"> Turning on postscreen(8) without blocking +mail</a> + +<li> <a href="#starttls"> postscreen(8) TLS configuration </a> + +<li> <a href="#blocking"> Blocking mail with postscreen(8) </a> + +<li> <a href="#turnoff"> Turning off postscreen(8) </a> + +<li> <a href="#temp_white_sharing"> Sharing the temporary allowlist +</a> + +</ul> + +<h3> <a name="enable"> Turning on postscreen(8) without blocking mail</a> </h3> + +<p> To enable the postscreen(8) service and log client information +without blocking mail: </p> + +<ol> + +<li> <p> Make sure that local clients and systems with non-standard +SMTP implementations are excluded from any postscreen(8) tests. The +default is to exclude all clients in mynetworks. To exclude additional +clients, for example, third-party performance monitoring tools (these +tend to have broken SMTP implementations): </p> + +<pre> +/etc/postfix/main.cf: + # Exclude broken clients by allowlisting. Clients in mynetworks + # should always be allowlisted. + postscreen_access_list = permit_mynetworks, + cidr:/etc/postfix/postscreen_access.cidr + +/etc/postfix/postscreen_access.cidr: + 192.168.254.0/24 permit +</pre> + +<li> <p> Comment out the "<tt>smtp inet ... smtpd</tt>" service +in master.cf, including any "<tt>-o parameter=value</tt>" entries +that follow. </p> + +<pre> +/etc/postfix/master.cf: + #smtp inet n - n - - smtpd + # -o parameter=value ... +</pre> + +<li> <p> Uncomment the new "<tt>smtpd pass ... smtpd</tt>" service +in master.cf, and duplicate any "<tt>-o parameter=value</tt>" entries +from the smtpd service that was commented out in the previous step. +</p> + +<pre> +/etc/postfix/master.cf: + smtpd pass - - n - - smtpd + -o parameter=value ... +</pre> + +<li> <p> Uncomment the new "<tt>smtp inet ... postscreen</tt>" +service in master.cf. </p> + +<pre> +/etc/postfix/master.cf: + smtp inet n - n - 1 postscreen +</pre> + +<li> <p> Uncomment the new "<tt>tlsproxy unix ... tlsproxy</tt>" +service in master.cf. This service implements STARTTLS support for +postscreen(8). </p> + +<pre> +/etc/postfix/master.cf: + tlsproxy unix - - n - 0 tlsproxy +</pre> + +<li> <p> Uncomment the new "<tt>dnsblog unix ... dnsblog</tt>" +service in master.cf. This service does DNSBL lookups for postscreen(8) +and logs results. </p> + +<pre> +/etc/postfix/master.cf: + dnsblog unix - - n - 0 dnsblog +</pre> + +<li> <p> To enable DNSBL lookups, list some DNS blocklist sites in +main.cf, separated by whitespace. Different sites can have different +weights. For example: + +<pre> +/etc/postfix/main.cf: + postscreen_dnsbl_threshold = 2 + postscreen_dnsbl_sites = zen.spamhaus.org*2 + bl.spamcop.net*1 b.barracudacentral.org*1 +</pre> + +<p> Note: if your DNSBL queries have a "secret" in the domain name, +you must censor this information from the postscreen(8) SMTP replies. +For example: </p> + +<pre> +/etc/postfix/main.cf: + postscreen_dnsbl_reply_map = texthash:/etc/postfix/dnsbl_reply +</pre> + +<pre> +/etc/postfix/dnsbl_reply: + # Secret DNSBL name Name in postscreen(8) replies + secret.zen.dq.spamhaus.net zen.spamhaus.org +</pre> + +<p> The texthash: format is similar to hash: except that there is +no need to run postmap(1) before the file can be used, and that it +does not detect changes after the file is read. It is new with +Postfix version 2.8. </p> + +<li> <p> Read the new configuration with "<tt>postfix reload</tt>". +</p> + +</ol> + +<p> Notes: </p> + +<ul> + +<li> <p> Some postscreen(8) configuration parameters implement +stress-dependent behavior. This is supported only when the default +value is stress-dependent (that is, "postconf -d <i>parametername</i>" +output shows +"<i>parametername</i> = ${stress?<i>something</i>}${stress:<i>something</i>}" or +"<i>parametername</i> = ${stress?{<i>something</i>}:{<i>something</i>}}"). +Other parameters always evaluate as if the stress value is the empty +string. </p> + +<li> <p> See "<a href="#before_220">Tests before the 220 SMTP server +greeting</a>" for details about the logging from these +postscreen(8) tests. </p> + +<li> <p> If you run Postfix 2.6 or earlier you must stop and start +the master daemon ("<tt>postfix stop; postfix start</tt>"). This +is needed because the Postfix "pass" master service type did not +work reliably on all systems. </p> + +</ul> + +<h3> <a name="starttls"> postscreen(8) TLS configuration </a> </h3> + +<p> postscreen(8) TLS support is available for remote SMTP clients +that aren't allowlisted, including clients that need to renew their +temporary allowlist status. When a remote SMTP client requests TLS +service, postscreen(8) invisibly hands off the connection to a +tlsproxy(8) process. Then, tlsproxy(8) encrypts and decrypts the +traffic between postscreen(8) and the remote SMTP client. One +tlsproxy(8) process can handle multiple SMTP sessions. The number +of tlsproxy(8) processes slowly increases with server load, but it +should always be much smaller than the number of postscreen(8) TLS +sessions. </p> + +<p> TLS support for postscreen(8) and tlsproxy(8) uses the same +parameters as with smtpd(8). We recommend that you keep the relevant +configuration parameters in main.cf. If you must specify "-o +smtpd_mumble=value" parameter overrides in master.cf for a +postscreen-protected smtpd(8) service, then you should specify those +same parameter overrides for the postscreen(8) and tlsproxy(8) +services. </p> + +<h3> <a name="blocking"> Blocking mail with postscreen(8) </a> </h3> + +<p> For compatibility with smtpd(8), postscreen(8) implements the +soft_bounce safety feature. This causes Postfix to reject mail with +a "try again" reply code. </p> + +<ul> + +<li> <p> To turn this on for all of Postfix, specify "<tt>soft_bounce += yes</tt>" in main.cf. </p> + +<li> <p> To turn this on for postscreen(8) only, append "<tt>-o +soft_bounce=yes</tt>" (note: NO SPACES around '=') to the postscreen +entry in master.cf. <p> + +</ul> + +<p> Execute "<tt>postfix reload</tt>" to make the change effective. </p> + +<p> After testing, do not forget to remove the soft_bounce feature, +otherwise senders won't receive their non-delivery notification +until many days later. </p> + +<p> To use the postscreen(8) service to block mail, edit main.cf and +specify one or more of: </p> + +<ul> + +<li> <p> "<tt>postscreen_dnsbl_action = enforce</tt>", to reject +clients that are on DNS blocklists, and to log the helo/sender/recipient +information. With good DNSBLs this reduces the amount of load on +Postfix SMTP servers dramatically. </p> + +<li> <p> "<tt>postscreen_greet_action = enforce</tt>", to reject +clients that talk before their turn, and to log the helo/sender/recipient +information. This stops over half of all known-to-be illegitimate +connections to Wietse's mail server. It is backup protection for +zombies that haven't yet been denylisted. </p> + +<li> <p> You can also enable "<a href="#after_220">deep protocol +tests</a>", but these are more intrusive than the pregreet or DNSBL +tests. </p> + +<p> When a good client passes the "<a href="#after_220">deep +protocol tests</a>", +postscreen(8) adds the client to the temporary +allowlist but it cannot hand off the "live" connection to a Postfix +SMTP server process in the middle of the session. Instead, postscreen(8) +defers mail delivery attempts with a 4XX status, logs the +helo/sender/recipient information, and waits for the client to +disconnect. </p> + +<p> When the good client comes back in a later session, it is allowed +to talk directly to a Postfix SMTP server. See "<a href="#after_220">Tests +after the 220 SMTP server greeting</a>" above for limitations with +AUTH and other features that clients may need. </p> + +<p> An unexpected benefit from "<a href="#after_220">deep protocol +tests</a>" is that some "good" clients don't return after the 4XX +reply; these clients were not so good after all. </p> + +<p> Unfortunately, some senders will retry requests from different +IP addresses, and may never get allowlisted. For this reason, +Wietse stopped using "<a href="#after_220">deep protocol tests</a>" +on his own internet-facing mail server. </p> + +<li> <p> There is also support for permanent denylisting and +allowlisting; see the description of the postscreen_access_list +parameter for details. </p> + +</ul> + +<h3> <a name="turnoff"> Turning off postscreen(8) </a> </h3> + +<p> To turn off postscreen(8) and handle mail directly with Postfix +SMTP server processes: </p> + +<ol> + +<li> <p> Comment out the "<tt>smtp inet ... postscreen</tt>" service +in master.cf, including any "<tt>-o parameter=value</tt>" entries +that follow. </p> + +<pre> +/etc/postfix/master.cf: + #smtp inet n - n - 1 postscreen + # -o parameter=value ... +</pre> + +<li> <p> Comment out the "<tt>dnsblog unix ... dnsblog</tt>" service +in master.cf. </p> + +<pre> +/etc/postfix/master.cf: + #dnsblog unix - - n - 0 dnsblog +</pre> + +<li> <p> Comment out the "<tt>smtpd pass ... smtpd</tt>" service +in master.cf, including any "<tt>-o parameter=value</tt>" entries +that follow. </p> + +<pre> +/etc/postfix/master.cf: + #smtpd pass - - n - - smtpd + # -o parameter=value ... +</pre> + +<li> <p> Comment out the "<tt>tlsproxy unix ... tlsproxy</tt>" +service in master.cf, including any "<tt>-o parameter=value</tt>" +entries that follow. </p> + +<pre> +/etc/postfix/master.cf: + #tlsproxy unix - - n - 0 tlsproxy + # -o parameter=value ... +</pre> + +<li> <p> Uncomment the "<tt>smtp inet ... smtpd</tt>" service in +master.cf, including any "<tt>-o parameter=value</tt>" entries that +may follow. </p> + +<pre> +/etc/postfix/master.cf: + smtp inet n - n - - smtpd + -o parameter=value ... +</pre> + +<li> <p> Read the new configuration with "<tt>postfix reload</tt>". +</p> + +</ol> + +<h3> <a name="temp_white_sharing"> Sharing the temporary allowlist </a> </h3> + +<p> By default, the temporary allowlist is not shared between +multiple postscreen(8) daemons. To enable sharing, choose one +of the following options: </p> + +<ul> + +<li> <p> A non-persistent memcache: temporary allowlist can be shared + between postscreen(8) daemons on the same host or different + hosts. Disable cache cleanup (postscreen_cache_cleanup_interval + = 0) in all postscreen(8) daemons because memcache: has no + first-next API (but see example 4 below for memcache: with + persistent backup). This requires Postfix 2.9 or later. </p> + + <pre> + # Example 1: non-persistent memcache: allowlist. + /etc/postfix/main.cf: + postscreen_cache_map = memcache:/etc/postfix/postscreen_cache + postscreen_cache_cleanup_interval = 0 + + /etc/postfix/postscreen_cache: + memcache = inet:127.0.0.1:11211 + key_format = postscreen:%s + </pre> + +<li> <p> + A persistent lmdb: temporary allowlist can be shared between + postscreen(8) daemons that run under the same master(8) daemon, + or under different master(8) daemons on the same host. Disable + cache cleanup (postscreen_cache_cleanup_interval = 0) in all + postscreen(8) daemons except one that is responsible for cache + cleanup. This requires Postfix 2.11 or later. </p> + + <pre> + # Example 2: persistent lmdb: allowlist. + /etc/postfix/main.cf: + postscreen_cache_map = lmdb:$data_directory/postscreen_cache + # See note 1 below. + # postscreen_cache_cleanup_interval = 0 + </pre> + +<li> <p> Other kinds of persistent temporary allowlist can be shared + only between postscreen(8) daemons that run under the same + master(8) daemon. In this case, temporary allowlist access must + be shared through the proxymap(8) daemon. This requires Postfix + 2.9 or later. </p> + + <pre> + # Example 3: proxied btree: allowlist. + /etc/postfix/main.cf: + postscreen_cache_map = + proxy:btree:/var/lib/postfix/postscreen_cache + # See note 1 below. + # postscreen_cache_cleanup_interval = 0 + + # Example 4: proxied btree: allowlist with memcache: accelerator. + /etc/postfix/main.cf: + postscreen_cache_map = memcache:/etc/postfix/postscreen_cache + proxy_write_maps = + proxy:btree:/var/lib/postfix/postscreen_cache + ... other proxied tables ... + # See note 1 below. + # postscreen_cache_cleanup_interval = 0 + + /etc/postfix/postscreen_cache: + # Note: the $data_directory macro is not defined in this context. + memcache = inet:127.0.0.1:11211 + backup = proxy:btree:/var/lib/postfix/postscreen_cache + key_format = postscreen:%s + </pre> + + <p> Note 1: disable cache cleanup (postscreen_cache_cleanup_interval + = 0) in all postscreen(8) daemons except one that is responsible + for cache cleanup. </p> + + <p> Note 2: postscreen(8) cache sharing via proxymap(8) requires Postfix + 2.9 or later; earlier proxymap(8) implementations don't support + cache cleanup. </p> + +</ul> + +<h2> <a name="historical"> Historical notes and credits </a> </h2> + +<p> Many ideas in postscreen(8) were explored in earlier work by +Michael Tokarev, in OpenBSD spamd, and in MailChannels Traffic +Control. </p> + +<p> Wietse threw together a crude prototype with pregreet and dnsbl +support in June 2009, because he needed something new for a Mailserver +conference presentation in July. Ralf Hildebrandt ran this code on +several servers to collect real-world statistics. This version used +the dnsblog(8) ad-hoc DNS client program. </p> + +<p> Wietse needed new material for a LISA conference presentation +in November 2010, so he added support for DNSBL weights and filters +in August, followed by a major code rewrite, deep protocol tests, +helo/sender/recipient logging, and stress-adaptive behavior in +September. Ralf Hildebrandt ran this code on several servers to +collect real-world statistics. This version still used the embarrassing +dnsblog(8) ad-hoc DNS client program. </p> + +<p> Wietse added STARTTLS support in December 2010. This makes +postscreen(8) usable for sites that require TLS support. The +implementation introduces the tlsproxy(8) event-driven TLS proxy +that decrypts/encrypts the sessions for multiple SMTP clients. </p> + +<p> The tlsproxy(8) implementation led to the discovery of a "new" +class of vulnerability (<a +href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-0411" +>CVE-2011-0411</a>) that affected multiple implementations of SMTP, +POP, IMAP, NNTP, and FTP over TLS. </p> + +<p> postscreen(8) was officially released as part of the Postfix +2.8 stable release in January 2011.</p> + +</body> + +</html> diff --git a/proto/POSTSCREEN_README.html b/proto/POSTSCREEN_README.html new file mode 100644 index 0000000..8ab3235 --- /dev/null +++ b/proto/POSTSCREEN_README.html @@ -0,0 +1,1214 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<head> + +<title>Postfix Postscreen Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Postscreen Howto</h1> + +<hr> + +<h2> <a name="intro">Introduction</a> </h2> + +<p> This document describes features that are available in Postfix +3.6 and later. See <a href="POSTSCREEN_3_5_README.html"> +POSTSCREEN_3_5_README.html</a> for Postfix versions 2.8 - 3.5. </p> + +<p> The Postfix postscreen(8) daemon provides additional protection +against mail server overload. One postscreen(8) process handles +multiple inbound SMTP connections, and decides which clients may +talk to a Postfix SMTP server process. By keeping spambots away, +postscreen(8) leaves more SMTP server processes available for +legitimate clients, and delays the onset of <a +href="STRESS_README.html">server overload</a> conditions. </p> + +<p> postscreen(8) should not be used on SMTP ports that receive +mail from end-user clients (MUAs). In a typical deployment, +postscreen(8) handles the MX service on TCP port 25, while MUA +clients submit mail via the submission service on TCP port 587 which +requires client authentication. Alternatively, a site could set up +a dedicated, non-postscreen, "port 25" server that provides submission +service and client authentication, but no MX service. </p> + +<p> postscreen(8) maintains a temporary allowlist for clients that +pass its tests; by allowing allowlisted clients to skip tests, +postscreen(8) minimizes its impact on legitimate email traffic. +</p> + +<p> postscreen(8) is part of a multi-layer defense. <p> + +<ul> + +<li> <p> As the first layer, postscreen(8) blocks connections from +zombies and other spambots that are responsible for about 90% of +all spam. It is implemented as a single process to make this defense +as inexpensive as possible. </p> + +<li> <p> The second layer implements more complex SMTP-level access +checks with <a href="SMTPD_ACCESS_README.html">Postfix SMTP servers</a>, +<a href="SMTPD_POLICY_README.html">policy daemons</a>, and +<a href="MILTER_README.html">Milter applications</a>. </p> + +<li> <p> The third layer performs light-weight content inspection +with the Postfix built-in header_checks and body_checks. This can +block unacceptable attachments such as executable programs, and +worms or viruses with easy-to-recognize signatures. </p> + +<li> <p> The fourth layer provides heavy-weight content inspection +with external content filters. Typical examples are <a +href="http://www.ijs.si/software/amavisd/">Amavisd-new</a>, <a +href="http://spamassassin.apache.org/">SpamAssassin</a>, and <a +href="MILTER_README.html">Milter applications</a>. </p> + +</ul> + +<p> Each layer reduces the spam volume. The general strategy is to +use the less expensive defenses first, and to use the more expensive +defenses only for the spam that remains. </p> + +<p> Topics in this document: </p> + +<ul> + +<li> <a href="#intro">Introduction</a> + +<li> <a href="#basic">The basic idea behind postscreen(8)</a> + +<li> <a href="#general"> General operation </a> + +<li> <a href="#quick">Quick tests before everything else</a> + +<li> <a href="#before_220"> Tests before the 220 SMTP server greeting </a> + +<li> <a href="#after_220">Tests after the 220 SMTP server greeting</a> + +<li> <a href="#other_error">Other errors</a> + +<li> <a href="#victory">When all tests succeed</a> + +<li> <a href="#config"> Configuring the postscreen(8) service</a> + +<li> <a href="#historical"> Historical notes and credits </a> + +</ul> + +<h2> <a name="basic">The basic idea behind postscreen(8)</a> </h2> + +<p> Most email is spam, and most spam is sent out by zombies (malware +on compromised end-user computers). Wietse expects that the zombie +problem will get worse before things improve, if ever. Without a +tool like postscreen(8) that keeps the zombies away, Postfix would be +spending most of its resources not receiving email. </p> + +<p> The main challenge for postscreen(8) is to make an is-a-zombie +decision based on a single measurement. This is necessary because +many zombies try to fly under the radar and avoid spamming the same +site repeatedly. Once postscreen(8) decides that a client is +not-a-zombie, it allowlists the client temporarily to avoid further +delays for legitimate mail. </p> + +<p> Zombies have challenges too: they have only a limited amount +of time to deliver spam before their IP address becomes denylisted. +To speed up spam deliveries, zombies make compromises in their SMTP +protocol implementation. For example, they speak before their turn, +or they ignore responses from SMTP servers and continue sending +mail even when the server tells them to go away. </p> + +<p> postscreen(8) uses a variety of measurements to recognize +zombies. First, postscreen(8) determines if the remote SMTP client +IP address is denylisted. Second, postscreen(8) looks for protocol +compromises that are made to speed up delivery. These are good +indicators for making is-a-zombie decisions based on single +measurements. </p> + +<p> postscreen(8) does not inspect message content. Message content +can vary from one delivery to the next, especially with clients +that (also) send legitimate email. Content is not a good indicator +for making is-a-zombie decisions based on single measurements, +and that is the problem that postscreen(8) is focused on. </p> + +<h2> <a name="general"> General operation </a> </h2> + +<p> For each connection from an SMTP client, postscreen(8) performs +a number of tests +in the order as described below. Some tests introduce a delay of +a few seconds. postscreen(8) maintains a temporary allowlist for +clients that pass its tests; by allowing allowlisted clients to +skip tests, postscreen(8) minimizes its impact on legitimate email +traffic. </p> + +<p> By default, postscreen(8) hands off all connections to a Postfix +SMTP server process after logging its findings. This mode is useful +for non-destructive testing. </p> + +<p> In a typical production setting, postscreen(8) is configured +to reject mail from clients that fail one or more tests, after +logging the helo, sender and recipient information. </p> + +<p> Note: postscreen(8) is not an SMTP proxy; this is intentional. +The purpose is to keep zombies away from Postfix, with minimal +overhead for legitimate clients. </p> + +<h2> <a name="quick">Quick tests before everything else</a> </h2> + +<p> Before engaging in SMTP-level tests. postscreen(8) queries a +number of local deny and allowlists. These tests speed up the +handling of known clients. </p> + +<ul> + +<li> <a href="#perm_allow_deny"> Permanent allow/denylist test </a> + +<li> <a href="#temp_allow"> Temporary allowlist test </a> + +<li> <a href="#allow_veto"> MX Policy test </a> + +</ul> + +<h3> <a name="perm_allow_deny"> Permanent allow/denylist test </a> </h3> + +<p> The postscreen_access_list parameter (default: permit_mynetworks) +specifies a permanent access list for SMTP client IP addresses. Typically +one would specify something that allowlists local networks, followed +by a CIDR table for selective allow- and denylisting. </p> + +<p> Example: </p> + +<pre> +/etc/postfix/main.cf: + postscreen_access_list = permit_mynetworks, + cidr:/etc/postfix/postscreen_access.cidr + +/etc/postfix/postscreen_access.cidr: + # Rules are evaluated in the order as specified. + # Denylist 192.168.* except 192.168.0.1. + 192.168.0.1 permit + 192.168.0.0/16 reject +</pre> + +<p> See the postscreen_access_list manpage documentation for more +details. </p> + +<p> When the SMTP client address matches a "permit" action, +postscreen(8) logs this with the client address and port number as: +</p> + +<blockquote> +<pre> +<b>ALLOWLISTED</b> <i>[address]:port</i> +</pre> +</blockquote> + +<blockquote> <p> Use the respectful_logging configuration parameter to +select a deprecated form of this logging. </p> </blockquote> + +<p> The allowlist action is not configurable: immediately hand off the +connection to a Postfix SMTP server process. </p> + +<p> When the SMTP client address matches a "reject" action, +postscreen(8) logs this with the client address and port number as: +</p> + +<blockquote> +<pre> +<b>DENYLISTED</b> <i>[address]:port</i> +</pre> +</blockquote> + +<blockquote> <p> Use the respectful_logging configuration parameter to +select a deprecated form of this logging. </p> </blockquote> + +<p> The postscreen_denylist_action parameter specifies the action +that is taken next. See "<a href="#fail_before_220">When tests +fail before the 220 SMTP server greeting</a>" below. </p> + +<h3> <a name="temp_allow"> Temporary allowlist test </a> </h3> + +<p> The postscreen(8) daemon maintains a <i>temporary</i> +allowlist for SMTP client IP addresses that have passed all +the tests described below. The postscreen_cache_map parameter +specifies the location of the temporary allowlist. The +temporary allowlist is not used for SMTP client addresses +that appear on the <i>permanent</i> access list. </p> + +<p> By default the temporary allowlist is not shared with other +postscreen(8) daemons. See +<a href="#temp_allow_sharing"> Sharing +the temporary allowlist </a> below for alternatives. </p> + +<p> When the SMTP client address appears on the temporary +allowlist, postscreen(8) logs this with the client address and port +number as: </p> + +<pre> + <b>PASS OLD</b> <i>[address]:port</i> +</pre> + +<p> The action is not configurable: immediately hand off the +connection to a Postfix SMTP server process. The client is +excluded from further tests until its temporary allowlist +entry expires, as controlled with the postscreen_*_ttl +parameters. Expired entries are silently renewed if possible. </p> + +<h3> <a name="allow_veto"> MX Policy test </a> </h3> + +<p> When the remote SMTP client is not on the static access list +or temporary allowlist, postscreen(8) can implement a number of +allowlist tests, before it grants the client a temporary allowlist +status that allows it to talk to a Postfix SMTP server process. </p> + +<p> When postscreen(8) is configured to monitor all primary and +backup MX addresses, it can refuse to allowlist clients that connect +to a backup MX address only (an old spammer trick to take advantage +of backup MX hosts with weaker anti-spam policies than primary MX +hosts). </p> + +<blockquote> <p> NOTE: The following solution is for small sites. +Larger sites would have to share the postscreen(8) cache between +primary and backup MTAs, which would introduce a common point of +failure. </p> </blockquote> + +<ul> + +<li> <p> First, configure the host to listen on both primary and +backup MX addresses. Use the appropriate <tt>ifconfig</tt> or <tt>ip</tt> +command for the local operating system, or update the appropriate +configuration files and "refresh" the network protocol stack. </p> + +<p> <p> Second, configure Postfix to listen on the new IP address +(this step is needed when you have specified inet_interfaces in +main.cf). </p> + +<li> <p> Then, configure postscreen(8) to deny the temporary allowlist +status on the backup MX address(es). An example for Wietse's +server is: </p> + +<pre> +/etc/postfix/main.cf: + postscreen_allowlist_interfaces = !168.100.189.8 static:all +</pre> + +<p> Translation: allow clients to obtain the temporary allowlist +status on all server IP addresses except 168.100.189.8, which is a +backup MX address. </p> + +</ul> + +<p> When a non-allowlisted client connects the backup MX address, +postscreen(8) logs this with the client address and port number as: +</p> + +<blockquote> <pre> +<b>CONNECT from</b> <i>[address]:port</i> <b>to [168.100.189.8]:25</b> +<b>ALLOWLIST VETO</b> <i>[address]:port</i> +</pre> </blockquote> + +<blockquote> <p> Use the respectful_logging configuration parameter to +select a deprecated form of this logging. </p> </blockquote> + +<p> Translation: the client at <i>[address]:port</i> connected to +the backup MX address 168.100.189.8 while it was not allowlisted. +The client will not be granted the temporary allowlist status, even +if passes all the allowlist tests described below. </p> + +<h2> <a name="before_220"> Tests before the 220 SMTP server greeting </a> </h2> + +<p> The postscreen_greet_wait parameter specifies a short time +interval before the "220 <i>text</i>..." server greeting, where +postscreen(8) can run a number of tests in parallel. </p> + +<p> When a good client passes these tests, and no "<a +href="#after_220">deep protocol tests</a>" +are configured, postscreen(8) +adds the client to the temporary allowlist and hands off the "live" +connection to a Postfix SMTP server process. The client can then +continue as if postscreen(8) never even existed (except of course +for the short postscreen_greet_wait delay). </p> + +<ul> + +<li> <a href="#pregreet"> Pregreet test </a> + +<li> <a href="#dnsbl"> DNS Allow/denylist test </a> + +<li> <a href="#fail_before_220">When tests fail before the 220 SMTP server greeting</a> + +</ul> + +<h3> <a name="pregreet"> Pregreet test </a> </h3> + +<p> The SMTP protocol is a classic example of a protocol where the +server speaks before the client. postscreen(8) detects zombies +that are in a hurry and that speak before their turn. This test is +enabled by default. </p> + +<p> The postscreen_greet_banner parameter specifies the <i>text</i> +portion of a "220-<i>text</i>..." teaser banner (default: $smtpd_banner). +Note that this becomes the first part of a multi-line server greeting. +The postscreen(8) daemon sends this before the postscreen_greet_wait +timer is started. The purpose of the teaser banner is to confuse +zombies so that they speak before their turn. It has no effect on +SMTP clients that correctly implement the protocol. </p> + +<p> To avoid problems with poorly-implemented SMTP engines in network +appliances or network testing tools, either exclude them from all +tests with the postscreen_access_list feature or else specify +an empty teaser banner: </p> + +<pre> +/etc/postfix/main.cf: + # Exclude broken clients by allowlisting. Clients in mynetworks + # should always be allowlisted. + postscreen_access_list = permit_mynetworks, + cidr:/etc/postfix/postscreen_access.cidr + +/etc/postfix/postscreen_access.cidr: + 192.168.254.0/24 permit +</pre> + +<pre> +/etc/postfix/main.cf: + # Disable the teaser banner (try allowlisting first if you can). + postscreen_greet_banner = +</pre> + +<p> When an SMTP client sends a command before the +postscreen_greet_wait time has elapsed, postscreen(8) logs this as: +</p> + +<pre> + <b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>[address]:port text...</i> +</pre> + +<p> Translation: the client at <i>[address]:port</i> sent <i>count</i> +bytes before its turn to speak. This happened <i>time</i> seconds +after the postscreen_greet_wait timer was started. The <i>text</i> +is what the client sent (truncated to 100 bytes, and with non-printable +characters replaced with C-style escapes such as \r for carriage-return +and \n for newline). </p> + +<p> The postscreen_greet_action parameter specifies the action that +is taken next. See "<a href="#fail_before_220">When tests fail +before the 220 SMTP server greeting</a>" below. </p> + +<h3> <a name="dnsbl"> DNS Allow/denylist test </a> </h3> + +<p> The postscreen_dnsbl_sites parameter (default: empty) specifies +a list of DNS blocklist servers with optional filters and weight +factors (positive weights for denylisting, negative for allowlisting). +These servers will be queried in parallel with the reverse client +IP address. This test is disabled by default. </p> + +<blockquote> +<p> +CAUTION: when postscreen rejects mail, its SMTP reply contains the +DNSBL domain name. Use the postscreen_dnsbl_reply_map feature to +hide "password" information in DNSBL domain names. +</p> +</blockquote> + +<p> When the postscreen_greet_wait time has elapsed, and the combined +DNSBL score is equal to or greater than the postscreen_dnsbl_threshold +parameter value, postscreen(8) logs this as: </p> + +<pre> + <b>DNSBL rank</b> <i>count</i> <b>for</b> <i>[address]:port</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> has a combined +DNSBL score of <i>count</i>. </p> + +<p> The postscreen_dnsbl_action parameter specifies the action that +is taken when the combined DNSBL score is equal to or greater than +the threshold. See "<a href="#fail_before_220">When tests fail +before the 220 SMTP server greeting</a>" below. </p> + +<h3> <a name="fail_before_220">When tests fail before the 220 SMTP server greeting</a> </h3> + +<p> When the client address matches the permanent denylist, or +when the client fails the pregreet or DNSBL tests, the action is +specified with postscreen_denylist_action, postscreen_greet_action, +or postscreen_dnsbl_action, respectively. </p> + +<dl> + +<dt> <b>ignore</b> (default) </dt> + +<dd> Ignore the failure of this test. Allow other tests to complete. +Repeat this test the next time the client connects. This option +is useful for testing and collecting statistics without blocking +mail. </dd> + +<dt> <b>enforce</b> </dt> + +<dd> Allow other tests to complete. Reject attempts to deliver mail +with a 550 SMTP reply, and log the helo/sender/recipient information. +Repeat this test the next time the client connects. </dd> + +<dt> <b>drop</b> </dt> + +<dd> Drop the connection immediately with a 521 SMTP reply. Repeat +this test the next time the client connects. </dd> + +</dl> + +<h2> <a name="after_220">Tests after the 220 SMTP server greeting</a> </h2> + +<p> In this phase of the protocol, postscreen(8) implements a +number of "deep protocol" tests. These tests use an SMTP protocol +engine that is built into the postscreen(8) server. </p> + +<p> Important note: these protocol tests are disabled by default. +They are more intrusive than the pregreet and DNSBL tests, and they +have limitations as discussed next. </p> + +<ul> + +<li> <p> The main limitation of "after 220 greeting" tests is that +a new client must disconnect after passing these tests (reason: +postscreen is not a proxy). Then the client must reconnect from +the same IP address before it can deliver mail. The following +measures may help to avoid email delays: </p> + +<ul> + +<li> <p> Allow "good" clients to skip tests with the +postscreen_dnsbl_allowlist_threshold feature. This is especially effective +for large providers that usually don't retry from the same IP +address. </p> + +<li> <p> Small sites: Configure postscreen(8) to listen on multiple +IP addresses, published in DNS as different IP addresses for the +same MX hostname or for different MX hostnames. This avoids mail +delivery delays with clients that reconnect immediately from the +same IP address. </p> + +<li> <p> Large sites: Share the postscreen(8) cache between different +Postfix MTAs with a large-enough memcache_table(5). Again, this +avoids mail delivery delays with clients that reconnect immediately +from the same IP address. </p> + +</ul> + +<li> <p> postscreen(8)'s built-in SMTP engine does not implement the +AUTH, XCLIENT, and XFORWARD features. If you need to make these +services available on port 25, then do not enable the tests after +the 220 server greeting. </p> + +<li> <p> End-user clients should connect directly to the submission +service, so that they never have to deal with postscreen(8)'s tests. +</p> + +</ul> + +<p> The following "after 220 greeting" tests are available: </p> + +<ul> + +<li> <a href="#pipelining">Command pipelining test</a> + +<li> <a href="#non_smtp">Non-SMTP command test</a> + +<li> <a href="#barelf">Bare newline test</a> + +<li> <a href="#fail_after_220">When tests fail after the 220 SMTP server greeting</a> + +</ul> + +<h3> <a name="pipelining">Command pipelining test</a> </h3> + +<p> By default, SMTP is a half-duplex protocol: the sender and +receiver send one command and one response at a time. Unlike the +Postfix SMTP server, postscreen(8) does not announce support +for ESMTP command pipelining. Therefore, clients are not allowed +to send multiple commands. postscreen(8)'s +<a href="#after_220">deep +protocol test</a> for this is disabled by default. </p> + +<p> With "postscreen_pipelining_enable = yes", postscreen(8) detects +zombies that send multiple commands, instead of sending one command +and waiting for the server to reply. </p> + +<p> This test is opportunistically enabled when postscreen(8) has +to use the built-in SMTP engine anyway. This is to make postscreen(8) +logging more informative. </p> + +<p> When a client sends multiple commands, postscreen(8) logs this +as: </p> + +<pre> + <b>COMMAND PIPELINING from</b> <i>[address]:port</i> <b>after</b> <i>command</i>: <i>text</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> sent +multiple SMTP commands, instead of sending one command and then +waiting for the server to reply. This happened after the client +sent <i>command</i>. The <i>text</i> shows part of the input that +was sent too early; it is not logged with Postfix 2.8. </p> + +<p> The postscreen_pipelining_action parameter specifies the action +that is taken next. See "<a href="#fail_after_220">When tests fail +after the 220 SMTP server greeting</a>" below. </p> + +<h3> <a name="non_smtp">Non-SMTP command test</a> </h3> + +<p> Some spambots send their mail through open proxies. A symptom +of this is the usage of commands such as CONNECT and other non-SMTP +commands. Just like the Postfix SMTP server's smtpd_forbidden_commands +feature, postscreen(8) has an equivalent postscreen_forbidden_commands +feature to block these clients. postscreen(8)'s +<a href="#after_220">deep +protocol test</a> for this is disabled by default. </p> + +<p> With "postscreen_non_smtp_command_enable = yes", postscreen(8) +detects zombies that send commands specified with the +postscreen_forbidden_commands parameter. This also detects commands +with the syntax of a message header label. The latter is a symptom +that the client is sending message content after ignoring all the +responses from postscreen(8) that reject mail. </p> + +<p> This test is opportunistically enabled when postscreen(8) has +to use the built-in SMTP engine anyway. This is to make postscreen(8) +logging more informative. </p> + +<p> When a client sends non-SMTP commands, postscreen(8) logs this +as: </p> + +<pre> + <b>NON-SMTP COMMAND from</b> <i>[address]:port</i> <b>after</b> <i>command: text</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> sent a +command that matches the postscreen_forbidden_commands +parameter, or that has the syntax of a message header label (text +followed by optional space and ":"). +The "<tt><b>after</b> <i>command</i></tt>" portion is logged with +Postfix 2.10 and later. </p> + +<p> The postscreen_non_smtp_command_action parameter specifies +the action that is taken next. See "<a href="#fail_after_220">When +tests fail after the 220 SMTP server greeting</a>" below. </p> + +<h3> <a name="barelf">Bare newline test</a> </h3> + +<p> SMTP is a line-oriented protocol: lines have a limited length, +and are terminated with <CR><LF>. Lines ending in a +"bare" <LF>, that is newline not preceded by carriage return, +are not allowed in SMTP. postscreen(8)'s +<a href="#after_220">deep +protocol test</a> for this is disabled by default. </p> + +<p> With "postscreen_bare_newline_enable = yes", postscreen(8) +detects clients that send lines ending in bare newline characters. +</p> + +<p> This test is opportunistically enabled when postscreen(8) has +to use the built-in SMTP engine anyway. This is to make postscreen(8) +logging more informative. </p> + +<p> When a client sends bare newline characters, postscreen(8) logs +this as: +</p> + +<pre> + <b>BARE NEWLINE from</b> <i>[address]:port</i> <b>after</b> <i>command</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> sent a bare +newline character, that is newline not preceded by carriage +return. +The "<tt><b>after</b> <i>command</i></tt>" portion is logged with +Postfix 2.10 and later. </p> + +<p> The postscreen_bare_newline_action parameter specifies the +action that is taken next. See "<a href="#fail_after_220">When +tests fail after the 220 SMTP server greeting</a>" below. </p> + +<h3> <a name="fail_after_220">When tests fail after the 220 SMTP server greeting</a> </h3> + +<p> When the client fails the pipelining, non-SMTP command or bare +newline tests, the action is specified with postscreen_pipelining_action, +postscreen_non_smtp_command_action or postscreen_bare_newline_action, +respectively. </p> + +<dl> + +<dt> <b>ignore</b> (default for bare newline) </dt> + +<dd> Ignore the failure of this test. Allow other tests to complete. +Do NOT repeat this test before the result from some other test +expires. + +This option is useful for testing and collecting statistics without +blocking mail permanently. </dd> + +<dt> <b>enforce</b> (default for pipelining) </dt> + +<dd> Allow other tests to complete. Reject attempts to deliver +mail with a 550 SMTP reply, and log the helo/sender/recipient +information. Repeat this test the next time the client connects. +</dd> + +<dt> <b>drop</b> (default for non-SMTP commands) </dt> + +<dd> Drop the connection immediately with a 521 SMTP reply. Repeat +this test the next time the client connects. This action is +compatible with the Postfix SMTP server's smtpd_forbidden_commands +feature. </dd> + +</dl> + +<h2> <a name="other_error">Other errors</a> </h2> + +<p> When an SMTP client hangs up unexpectedly, postscreen(8) logs +this as: </p> + +<pre> + <b>HANGUP after</b> <i>time</i> <b>from</b> <i>[address]:port</i> <b>in</b> <i>test name</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> disconnected +unexpectedly, <i>time</i> seconds after the start of the +test named <i>test name</i>. </p> + +<p> There is no punishment for hanging up. A client that hangs up +without sending the QUIT command can still pass all postscreen(8) +tests. </p> + +<!-- + +<p> While an unexpired penalty is in effect, an SMTP client is not +allowed to pass any tests, and postscreen(8) logs each connection +with the remaining amount of penalty time as: </p> + +<pre> + <b>PENALTY</b> <i>time</i> <b>for</b> <i>[address]:port</i> +</pre> + +<p> During this time, all attempts by the client to deliver mail +will be deferred with a 450 SMTP status. </p> + +--> + +<p> The following errors are reported by the built-in SMTP engine. +This engine never accepts mail, therefore it has per-session limits +on the number of commands and on the session length. </p> + +<pre> + <b>COMMAND TIME LIMIT</b> <b>from</b> <i>[address]:port</i> <b>after</b> <i>command</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> reached the +per-command time limit as specified with the postscreen_command_time_limit +parameter. The session is terminated immediately. +The "<tt><b>after</b> <i>command</i></tt>" portion is logged with +Postfix 2.10 and later. </p> + +<pre> + <b>COMMAND COUNT LIMIT from</b> <i>[address]:port</i> <b>after</b> <i>command</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> reached the +per-session command count limit as specified with the +postscreen_command_count_limit parameter. The session is terminated +immediately. +The "<tt><b>after</b> <i>command</i></tt>" portion is logged with +Postfix 2.10 and later. </p> + +<pre> + <b>COMMAND LENGTH LIMIT from</b> <i>[address]:port</i> <b>after</b> <i>command</i> +</pre> + +<p> Translation: the SMTP client at <i>[address]:port</i> reached the +per-command length limit, as specified with the line_length_limit +parameter. The session is terminated immediately. +The "<tt><b>after</b> <i>command</i></tt>" portion is logged with +Postfix 2.10 and later. </p> + +<p> When an SMTP client makes too many connections at the same time, +postscreen(8) rejects the connection with a 421 status code and logs: </p> + +<pre> + <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: too many connections</b> +</pre> + +<p> The postscreen_client_connection_count_limit parameter controls this limit. </p> + +<p> When an SMTP client connects after postscreen(8) has reached a +connection count limit, postscreen(8) rejects the connection with +a 421 status code and logs: </p> + +<pre> + <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all screening ports busy</b> + <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all server ports busy</b> +</pre> + +<p> The postscreen_pre_queue_limit and postscreen_post_queue_limit +parameters control these limits. </p> + +<h2> <a name="victory">When all tests succeed</a> </h2> + +<p> When a new SMTP client passes all tests (i.e. it is not allowlisted +via some mechanism), postscreen(8) logs this as: </p> + +<pre> + <b>PASS NEW</b> <i>[address]:port</i> +</pre> + +<p> Where <i>[address]:port</i> are the client IP address and port. +Then, postscreen(8) +creates a temporary allowlist entry that excludes the client IP +address from further tests until the temporary allowlist entry +expires, as controlled with the postscreen_*_ttl parameters. </p> + +<p> When no "<a href="#after_220">deep protocol tests</a>" are +configured, postscreen(8) hands off the "live" connection to a Postfix +SMTP server process. The client can then continue as if postscreen(8) +never even existed (except for the short postscreen_greet_wait delay). +</p> + +<p> When any "<a href="#after_220">deep protocol tests</a>" are +configured, postscreen(8) cannot hand off the "live" connection to +a Postfix SMTP server process in the middle of the session. Instead, +postscreen(8) defers mail delivery attempts with a 4XX status, logs +the helo/sender/recipient information, and waits for the client to +disconnect. The next time the client connects it will be allowed +to talk to a Postfix SMTP server process to deliver its mail. +postscreen(8) mitigates the impact of this limitation by giving +<a href="#after_220">deep protocol tests</a> a long expiration +time. </p> + +<h2> <a name="config"> Configuring the postscreen(8) service</a> +</h2> + +<p> postscreen(8) has been tested on FreeBSD [4-8], Linux 2.[4-6] +and Solaris 9 systems. </p> + +<ul> + +<li> <a href="#enable"> Turning on postscreen(8) without blocking +mail</a> + +<li> <a href="#starttls"> postscreen(8) TLS configuration </a> + +<li> <a href="#blocking"> Blocking mail with postscreen(8) </a> + +<li> <a href="#turnoff"> Turning off postscreen(8) </a> + +<li> <a href="#temp_allow_sharing"> Sharing the temporary allowlist +</a> + +</ul> + +<h3> <a name="enable"> Turning on postscreen(8) without blocking mail</a> </h3> + +<p> To enable the postscreen(8) service and log client information +without blocking mail: </p> + +<ol> + +<li> <p> Make sure that local clients and systems with non-standard +SMTP implementations are excluded from any postscreen(8) tests. The +default is to exclude all clients in mynetworks. To exclude additional +clients, for example, third-party performance monitoring tools (these +tend to have broken SMTP implementations): </p> + +<pre> +/etc/postfix/main.cf: + # Exclude broken clients by allowlisting. Clients in mynetworks + # should always be allowlisted. + postscreen_access_list = permit_mynetworks, + cidr:/etc/postfix/postscreen_access.cidr + +/etc/postfix/postscreen_access.cidr: + 192.168.254.0/24 permit +</pre> + +<li> <p> Comment out the "<tt>smtp inet ... smtpd</tt>" service +in master.cf, including any "<tt>-o parameter=value</tt>" entries +that follow. </p> + +<pre> +/etc/postfix/master.cf: + #smtp inet n - n - - smtpd + # -o parameter=value ... +</pre> + +<li> <p> Uncomment the new "<tt>smtpd pass ... smtpd</tt>" service +in master.cf, and duplicate any "<tt>-o parameter=value</tt>" entries +from the smtpd service that was commented out in the previous step. +</p> + +<pre> +/etc/postfix/master.cf: + smtpd pass - - n - - smtpd + -o parameter=value ... +</pre> + +<li> <p> Uncomment the new "<tt>smtp inet ... postscreen</tt>" +service in master.cf. </p> + +<pre> +/etc/postfix/master.cf: + smtp inet n - n - 1 postscreen +</pre> + +<li> <p> Uncomment the new "<tt>tlsproxy unix ... tlsproxy</tt>" +service in master.cf. This service implements STARTTLS support for +postscreen(8). </p> + +<pre> +/etc/postfix/master.cf: + tlsproxy unix - - n - 0 tlsproxy +</pre> + +<li> <p> Uncomment the new "<tt>dnsblog unix ... dnsblog</tt>" +service in master.cf. This service does DNSBL lookups for postscreen(8) +and logs results. </p> + +<pre> +/etc/postfix/master.cf: + dnsblog unix - - n - 0 dnsblog +</pre> + +<li> <p> To enable DNSBL lookups, list some DNS blocklist sites in +main.cf, separated by whitespace. Different sites can have different +weights. For example: + +<pre> +/etc/postfix/main.cf: + postscreen_dnsbl_threshold = 2 + postscreen_dnsbl_sites = zen.spamhaus.org*2 + bl.spamcop.net*1 b.barracudacentral.org*1 +</pre> + +<p> Note: if your DNSBL queries have a "secret" in the domain name, +you must censor this information from the postscreen(8) SMTP replies. +For example: </p> + +<pre> +/etc/postfix/main.cf: + postscreen_dnsbl_reply_map = texthash:/etc/postfix/dnsbl_reply +</pre> + +<pre> +/etc/postfix/dnsbl_reply: + # Secret DNSBL name Name in postscreen(8) replies + secret.zen.dq.spamhaus.net zen.spamhaus.org +</pre> + +<p> The texthash: format is similar to hash: except that there is +no need to run postmap(1) before the file can be used, and that it +does not detect changes after the file is read. It is new with +Postfix version 2.8. </p> + +<li> <p> Read the new configuration with "<tt>postfix reload</tt>". +</p> + +</ol> + +<p> Notes: </p> + +<ul> + +<li> <p> Some postscreen(8) configuration parameters implement +stress-dependent behavior. This is supported only when the default +value is stress-dependent (that is, "postconf -d <i>parametername</i>" +output shows +"<i>parametername</i> = ${stress?<i>something</i>}${stress:<i>something</i>}" or +"<i>parametername</i> = ${stress?{<i>something</i>}:{<i>something</i>}}"). +Other parameters always evaluate as if the stress value is the empty +string. </p> + +<li> <p> See "<a href="#before_220">Tests before the 220 SMTP server +greeting</a>" for details about the logging from these +postscreen(8) tests. </p> + +<li> <p> If you run Postfix 2.6 or earlier you must stop and start +the master daemon ("<tt>postfix stop; postfix start</tt>"). This +is needed because the Postfix "pass" master service type did not +work reliably on all systems. </p> + +</ul> + +<h3> <a name="starttls"> postscreen(8) TLS configuration </a> </h3> + +<p> postscreen(8) TLS support is available for remote SMTP clients +that aren't allowlisted, including clients that need to renew their +temporary allowlist status. When a remote SMTP client requests TLS +service, postscreen(8) invisibly hands off the connection to a +tlsproxy(8) process. Then, tlsproxy(8) encrypts and decrypts the +traffic between postscreen(8) and the remote SMTP client. One +tlsproxy(8) process can handle multiple SMTP sessions. The number +of tlsproxy(8) processes slowly increases with server load, but it +should always be much smaller than the number of postscreen(8) TLS +sessions. </p> + +<p> TLS support for postscreen(8) and tlsproxy(8) uses the same +parameters as with smtpd(8). We recommend that you keep the relevant +configuration parameters in main.cf. If you must specify "-o +smtpd_mumble=value" parameter overrides in master.cf for a +postscreen-protected smtpd(8) service, then you should specify those +same parameter overrides for the postscreen(8) and tlsproxy(8) +services. </p> + +<h3> <a name="blocking"> Blocking mail with postscreen(8) </a> </h3> + +<p> For compatibility with smtpd(8), postscreen(8) implements the +soft_bounce safety feature. This causes Postfix to reject mail with +a "try again" reply code. </p> + +<ul> + +<li> <p> To turn this on for all of Postfix, specify "<tt>soft_bounce += yes</tt>" in main.cf. </p> + +<li> <p> To turn this on for postscreen(8) only, append "<tt>-o +soft_bounce=yes</tt>" (note: NO SPACES around '=') to the postscreen +entry in master.cf. <p> + +</ul> + +<p> Execute "<tt>postfix reload</tt>" to make the change effective. </p> + +<p> After testing, do not forget to remove the soft_bounce feature, +otherwise senders won't receive their non-delivery notification +until many days later. </p> + +<p> To use the postscreen(8) service to block mail, edit main.cf and +specify one or more of: </p> + +<ul> + +<li> <p> "<tt>postscreen_dnsbl_action = enforce</tt>", to reject +clients that are on DNS blocklists, and to log the helo/sender/recipient +information. With good DNSBLs this reduces the amount of load on +Postfix SMTP servers dramatically. </p> + +<li> <p> "<tt>postscreen_greet_action = enforce</tt>", to reject +clients that talk before their turn, and to log the helo/sender/recipient +information. This stops over half of all known-to-be illegitimate +connections to Wietse's mail server. It is backup protection for +zombies that haven't yet been denylisted. </p> + +<li> <p> You can also enable "<a href="#after_220">deep protocol +tests</a>", but these are more intrusive than the pregreet or DNSBL +tests. </p> + +<p> When a good client passes the "<a href="#after_220">deep +protocol tests</a>", +postscreen(8) adds the client to the temporary +allowlist but it cannot hand off the "live" connection to a Postfix +SMTP server process in the middle of the session. Instead, postscreen(8) +defers mail delivery attempts with a 4XX status, logs the +helo/sender/recipient information, and waits for the client to +disconnect. </p> + +<p> When the good client comes back in a later session, it is allowed +to talk directly to a Postfix SMTP server. See "<a href="#after_220">Tests +after the 220 SMTP server greeting</a>" above for limitations with +AUTH and other features that clients may need. </p> + +<p> An unexpected benefit from "<a href="#after_220">deep protocol +tests</a>" is that some "good" clients don't return after the 4XX +reply; these clients were not so good after all. </p> + +<p> Unfortunately, some senders will retry requests from different +IP addresses, and may never get allowlisted. For this reason, +Wietse stopped using "<a href="#after_220">deep protocol tests</a>" +on his own internet-facing mail server. </p> + +<li> <p> There is also support for permanent denylisting and +allowlisting; see the description of the postscreen_access_list +parameter for details. </p> + +</ul> + +<h3> <a name="turnoff"> Turning off postscreen(8) </a> </h3> + +<p> To turn off postscreen(8) and handle mail directly with Postfix +SMTP server processes: </p> + +<ol> + +<li> <p> Comment out the "<tt>smtp inet ... postscreen</tt>" service +in master.cf, including any "<tt>-o parameter=value</tt>" entries +that follow. </p> + +<pre> +/etc/postfix/master.cf: + #smtp inet n - n - 1 postscreen + # -o parameter=value ... +</pre> + +<li> <p> Comment out the "<tt>dnsblog unix ... dnsblog</tt>" service +in master.cf. </p> + +<pre> +/etc/postfix/master.cf: + #dnsblog unix - - n - 0 dnsblog +</pre> + +<li> <p> Comment out the "<tt>smtpd pass ... smtpd</tt>" service +in master.cf, including any "<tt>-o parameter=value</tt>" entries +that follow. </p> + +<pre> +/etc/postfix/master.cf: + #smtpd pass - - n - - smtpd + # -o parameter=value ... +</pre> + +<li> <p> Comment out the "<tt>tlsproxy unix ... tlsproxy</tt>" +service in master.cf, including any "<tt>-o parameter=value</tt>" +entries that follow. </p> + +<pre> +/etc/postfix/master.cf: + #tlsproxy unix - - n - 0 tlsproxy + # -o parameter=value ... +</pre> + +<li> <p> Uncomment the "<tt>smtp inet ... smtpd</tt>" service in +master.cf, including any "<tt>-o parameter=value</tt>" entries that +may follow. </p> + +<pre> +/etc/postfix/master.cf: + smtp inet n - n - - smtpd + -o parameter=value ... +</pre> + +<li> <p> Read the new configuration with "<tt>postfix reload</tt>". +</p> + +</ol> + +<h3> <a name="temp_allow_sharing"> Sharing the temporary allowlist </a> </h3> + +<p> By default, the temporary allowlist is not shared between +multiple postscreen(8) daemons. To enable sharing, choose one +of the following options: </p> + +<ul> + +<li> <p> A non-persistent memcache: temporary allowlist can be shared + between postscreen(8) daemons on the same host or different + hosts. Disable cache cleanup (postscreen_cache_cleanup_interval + = 0) in all postscreen(8) daemons because memcache: has no + first-next API (but see example 4 below for memcache: with + persistent backup). This requires Postfix 2.9 or later. </p> + + <pre> + # Example 1: non-persistent memcache: allowlist. + /etc/postfix/main.cf: + postscreen_cache_map = memcache:/etc/postfix/postscreen_cache + postscreen_cache_cleanup_interval = 0 + + /etc/postfix/postscreen_cache: + memcache = inet:127.0.0.1:11211 + key_format = postscreen:%s + </pre> + +<li> <p> + A persistent lmdb: temporary allowlist can be shared between + postscreen(8) daemons that run under the same master(8) daemon, + or under different master(8) daemons on the same host. Disable + cache cleanup (postscreen_cache_cleanup_interval = 0) in all + postscreen(8) daemons except one that is responsible for cache + cleanup. This requires Postfix 2.11 or later. </p> + + <pre> + # Example 2: persistent lmdb: allowlist. + /etc/postfix/main.cf: + postscreen_cache_map = lmdb:$data_directory/postscreen_cache + # See note 1 below. + # postscreen_cache_cleanup_interval = 0 + </pre> + +<li> <p> Other kinds of persistent temporary allowlist can be shared + only between postscreen(8) daemons that run under the same + master(8) daemon. In this case, temporary allowlist access must + be shared through the proxymap(8) daemon. This requires Postfix + 2.9 or later. </p> + + <pre> + # Example 3: proxied btree: allowlist. + /etc/postfix/main.cf: + postscreen_cache_map = + proxy:btree:/var/lib/postfix/postscreen_cache + # See note 1 below. + # postscreen_cache_cleanup_interval = 0 + + # Example 4: proxied btree: allowlist with memcache: accelerator. + /etc/postfix/main.cf: + postscreen_cache_map = memcache:/etc/postfix/postscreen_cache + proxy_write_maps = + proxy:btree:/var/lib/postfix/postscreen_cache + ... other proxied tables ... + # See note 1 below. + # postscreen_cache_cleanup_interval = 0 + + /etc/postfix/postscreen_cache: + # Note: the $data_directory macro is not defined in this context. + memcache = inet:127.0.0.1:11211 + backup = proxy:btree:/var/lib/postfix/postscreen_cache + key_format = postscreen:%s + </pre> + + <p> Note 1: disable cache cleanup (postscreen_cache_cleanup_interval + = 0) in all postscreen(8) daemons except one that is responsible + for cache cleanup. </p> + + <p> Note 2: postscreen(8) cache sharing via proxymap(8) requires Postfix + 2.9 or later; earlier proxymap(8) implementations don't support + cache cleanup. </p> + +</ul> + +<h2> <a name="historical"> Historical notes and credits </a> </h2> + +<p> Many ideas in postscreen(8) were explored in earlier work by +Michael Tokarev, in OpenBSD spamd, and in MailChannels Traffic +Control. </p> + +<p> Wietse threw together a crude prototype with pregreet and dnsbl +support in June 2009, because he needed something new for a Mailserver +conference presentation in July. Ralf Hildebrandt ran this code on +several servers to collect real-world statistics. This version used +the dnsblog(8) ad-hoc DNS client program. </p> + +<p> Wietse needed new material for a LISA conference presentation +in November 2010, so he added support for DNSBL weights and filters +in August, followed by a major code rewrite, deep protocol tests, +helo/sender/recipient logging, and stress-adaptive behavior in +September. Ralf Hildebrandt ran this code on several servers to +collect real-world statistics. This version still used the embarrassing +dnsblog(8) ad-hoc DNS client program. </p> + +<p> Wietse added STARTTLS support in December 2010. This makes +postscreen(8) usable for sites that require TLS support. The +implementation introduces the tlsproxy(8) event-driven TLS proxy +that decrypts/encrypts the sessions for multiple SMTP clients. </p> + +<p> The tlsproxy(8) implementation led to the discovery of a "new" +class of vulnerability (<a +href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-0411" +>CVE-2011-0411</a>) that affected multiple implementations of SMTP, +POP, IMAP, NNTP, and FTP over TLS. </p> + +<p> postscreen(8) was officially released as part of the Postfix +2.8 stable release in January 2011.</p> + +<p> Noel Jones helped with the Postfix 3.6 transition towards respectful +documentation. </p> + +</body> +</html> diff --git a/proto/QSHAPE_README.html b/proto/QSHAPE_README.html new file mode 100644 index 0000000..6956b46 --- /dev/null +++ b/proto/QSHAPE_README.html @@ -0,0 +1,938 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Bottleneck Analysis</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Bottleneck Analysis</h1> + +<hr> + +<h2>Purpose of this document </h2> + +<p> This document is an introduction to Postfix queue congestion analysis. +It explains how the qshape(1) program can help to track down the +reason for queue congestion. qshape(1) is bundled with Postfix +2.1 and later source code, under the "auxiliary" directory. This +document describes qshape(1) as bundled with Postfix 2.4. </p> + +<p> This document covers the following topics: </p> + +<ul> + +<li><a href="#qshape">Introducing the qshape tool</a> + +<li><a href="#trouble_shooting">Trouble shooting with qshape</a> + +<li><a href="#healthy">Example 1: Healthy queue</a> + +<li><a href="#dictionary_bounce">Example 2: Deferred queue full of +dictionary attack bounces</a></li> + +<li><a href="#active_congestion">Example 3: Congestion in the active +queue</a></li> + +<li><a href="#backlog">Example 4: High volume destination backlog</a> + +<li><a href="#queues">Postfix queue directories</a> + +<ul> + +<li> <a href="#maildrop_queue"> The "maildrop" queue </a> + +<li> <a href="#hold_queue"> The "hold" queue </a> + +<li> <a href="#incoming_queue"> The "incoming" queue </a> + +<li> <a href="#active_queue"> The "active" queue </a> + +<li> <a href="#deferred_queue"> The "deferred" queue </a> + +</ul> + +<li><a href="#credits">Credits</a> + +</ul> + +<h2><a name="qshape">Introducing the qshape tool</a></h2> + +<p> When mail is draining slowly or the queue is unexpectedly large, +run qshape(1) as the super-user (root) to help zero in on the problem. +The qshape(1) program displays a tabular view of the Postfix queue +contents. </p> + +<ul> + +<li> <p> On the horizontal axis, it displays the queue age with +fine granularity for recent messages and (geometrically) less fine +granularity for older messages. </p> + +<li> <p> The vertical axis displays the destination (or with the +"-s" switch the sender) domain. Domains with the most messages are +listed first. </p> + +</ul> + +<p> For example, in the output below we see the top 10 lines of +the (mostly forged) sender domain distribution for captured spam +in the "hold" queue: </p> + +<blockquote> +<pre> +$ qshape -s hold | head + T 5 10 20 40 80 160 320 640 1280 1280+ + TOTAL 486 0 0 1 0 0 2 4 20 40 419 + yahoo.com 14 0 0 1 0 0 0 0 1 0 12 + extremepricecuts.net 13 0 0 0 0 0 0 0 2 0 11 + ms35.hinet.net 12 0 0 0 0 0 0 0 0 1 11 + winnersdaily.net 12 0 0 0 0 0 0 0 2 0 10 + hotmail.com 11 0 0 0 0 0 0 0 0 1 10 + worldnet.fr 6 0 0 0 0 0 0 0 0 0 6 + ms41.hinet.net 6 0 0 0 0 0 0 0 0 0 6 + osn.de 5 0 0 0 0 0 1 0 0 0 4 +</pre> +</blockquote> + +<ul> + +<li> <p> The "T" column shows the total (in this case sender) count +for each domain. The columns with numbers above them, show counts +for messages aged fewer than that many minutes, but not younger +than the age limit for the previous column. The row labeled "TOTAL" +shows the total count for all domains. </p> + +<li> <p> In this example, there are 14 messages allegedly from +yahoo.com, 1 between 10 and 20 minutes old, 1 between 320 and 640 +minutes old and 12 older than 1280 minutes (1440 minutes in a day). +</p> + +</ul> + +<p> When the output is a terminal intermediate results showing the top 20 +domains (-n option) are displayed after every 1000 messages (-N option) +and the final output also shows only the top 20 domains. This makes +qshape useful even when the "deferred" queue is very large and it may +otherwise take prohibitively long to read the entire "deferred" queue. </p> + +<p> By default, qshape shows statistics for the union of both the +"incoming" and "active" queues which are the most relevant queues to +look at when analyzing performance. </p> + +<p> One can request an alternate list of queues: </p> + +<blockquote> +<pre> +$ qshape deferred +$ qshape incoming active deferred +</pre> +</blockquote> + +<p> this will show the age distribution of the "deferred" queue or +the union of the "incoming", "active" and "deferred" queues. </p> + +<p> Command line options control the number of display "buckets", +the age limit for the smallest bucket, display of parent domain +counts and so on. The "-h" option outputs a summary of the available +switches. </p> + +<h2><a name="trouble_shooting">Trouble shooting with qshape</a> +</h2> + +<p> Large numbers in the qshape output represent a large number of +messages that are destined to (or alleged to come from) a particular +domain. It should be possible to tell at a glance which domains +dominate the queue sender or recipient counts, approximately when +a burst of mail started, and when it stopped. </p> + +<p> The problem destinations or sender domains appear near the top +left corner of the output table. Remember that the "active" queue +can accommodate up to 20000 ($qmgr_message_active_limit) messages. +To check whether this limit has been reached, use: </p> + +<blockquote> +<pre> +$ qshape -s active <i>(show sender statistics)</i> +</pre> +</blockquote> + +<p> If the total sender count is below 20000 the "active" queue is +not yet saturated, any high volume sender domains show near the +top of the output. + +<p> With oqmgr(8) the "active" queue is also limited to at most 20000 +recipient addresses ($qmgr_message_recipient_limit). To check for +exhaustion of this limit use: </p> + +<blockquote> +<pre> +$ qshape active <i>(show recipient statistics)</i> +</pre> +</blockquote> + +<p> Having found the high volume domains, it is often useful to +search the logs for recent messages pertaining to the domains in +question. </p> + +<blockquote> +<pre> +# Find deliveries to example.com +# +$ tail -10000 /var/log/maillog | + egrep -i ': to=<.*@example\.com>,' | + less + +# Find messages from example.com +# +$ tail -10000 /var/log/maillog | + egrep -i ': from=<.*@example\.com>,' | + less +</pre> +</blockquote> + +<p> You may want to drill in on some specific queue ids: </p> + +<blockquote> +<pre> +# Find all messages for a specific queue id. +# +$ tail -10000 /var/log/maillog | egrep ': 2B2173FF68: ' +</pre> +</blockquote> + +<p> Also look for queue manager warning messages in the log. These +warnings can suggest strategies to reduce congestion. </p> + +<blockquote> +<pre> +$ egrep 'qmgr.*(panic|fatal|error|warning):' /var/log/maillog +</pre> +</blockquote> + +<p> When all else fails try the Postfix mailing list for help, but +please don't forget to include the top 10 or 20 lines of qshape(1) +output. </p> + +<h2><a name="healthy">Example 1: Healthy queue</a></h2> + +<p> When looking at just the "incoming" and "active" queues, under +normal conditions (no congestion) the "incoming" and "active" queues +are nearly empty. Mail leaves the system almost as quickly as it +comes in or is deferred without congestion in the "active" queue. +</p> + +<blockquote> +<pre> +$ qshape <i>(show "incoming" and "active" queue status)</i> + + T 5 10 20 40 80 160 320 640 1280 1280+ + TOTAL 5 0 0 0 1 0 0 0 1 1 2 + meri.uwasa.fi 5 0 0 0 1 0 0 0 1 1 2 +</pre> +</blockquote> + +<p> If one looks at the two queues separately, the "incoming" queue +is empty or perhaps briefly has one or two messages, while the +"active" queue holds more messages and for a somewhat longer time: +</p> + +<blockquote> +<pre> +$ qshape incoming + + T 5 10 20 40 80 160 320 640 1280 1280+ + TOTAL 0 0 0 0 0 0 0 0 0 0 0 + +$ qshape active + + T 5 10 20 40 80 160 320 640 1280 1280+ + TOTAL 5 0 0 0 1 0 0 0 1 1 2 + meri.uwasa.fi 5 0 0 0 1 0 0 0 1 1 2 +</pre> +</blockquote> + +<h2><a name="dictionary_bounce">Example 2: Deferred queue full of +dictionary attack bounces</a></h2> + +<p> This is from a server where recipient validation is not yet +available for some of the hosted domains. Dictionary attacks on +the unvalidated domains result in bounce backscatter. The bounces +dominate the queue, but with proper tuning they do not saturate the +"incoming" or "active" queues. The high volume of deferred mail is not +a direct cause for alarm. </p> + +<blockquote> +<pre> +$ qshape deferred | head + + T 5 10 20 40 80 160 320 640 1280 1280+ + TOTAL 2234 4 2 5 9 31 57 108 201 464 1353 + heyhihellothere.com 207 0 0 1 1 6 6 8 25 68 92 + pleazerzoneprod.com 105 0 0 0 0 0 0 0 5 44 56 + groups.msn.com 63 2 1 2 4 4 14 14 14 8 0 + orion.toppoint.de 49 0 0 0 1 0 2 4 3 16 23 + kali.com.cn 46 0 0 0 0 1 0 2 6 12 25 + meri.uwasa.fi 44 0 0 0 0 1 0 2 8 11 22 + gjr.paknet.com.pk 43 1 0 0 1 1 3 3 6 12 16 + aristotle.algonet.se 41 0 0 0 0 0 1 2 11 12 15 +</pre> +</blockquote> + +<p> The domains shown are mostly bulk-mailers and all the volume +is the tail end of the time distribution, showing that short term +arrival rates are moderate. Larger numbers and lower message ages +are more indicative of current trouble. Old mail still going nowhere +is largely harmless so long as the "active" and "incoming" queues are +short. We can also see that the groups.msn.com undeliverables are +low rate steady stream rather than a concentrated dictionary attack +that is now over. </p> + +<blockquote> +<pre> +$ qshape -s deferred | head + + T 5 10 20 40 80 160 320 640 1280 1280+ + TOTAL 2193 4 4 5 8 33 56 104 205 465 1309 + MAILER-DAEMON 1709 4 4 5 8 33 55 101 198 452 849 + example.com 263 0 0 0 0 0 0 0 0 2 261 + example.org 209 0 0 0 0 0 1 3 6 11 188 + example.net 6 0 0 0 0 0 0 0 0 0 6 + example.edu 3 0 0 0 0 0 0 0 0 0 3 + example.gov 2 0 0 0 0 0 0 0 1 0 1 + example.mil 1 0 0 0 0 0 0 0 0 0 1 +</pre> +</blockquote> + +<p> Looking at the sender distribution, we see that as expected +most of the messages are bounces. </p> + +<h2><a name="active_congestion">Example 3: Congestion in the active +queue</a></h2> + +<p> This example is taken from a Feb 2004 discussion on the Postfix +Users list. Congestion was reported with the +"active" and "incoming" queues +large and not shrinking despite very large delivery agent +process limits. The thread is archived at: +http://groups.google.com/groups?threadm=c0b7js$2r65$1@FreeBSD.csie.NCTU.edu.tw +and +http://archives.neohapsis.com/archives/postfix/2004-02/thread.html#1371 +</p> + +<p> Using an older version of qshape(1) it was quickly determined +that all the messages were for just a few destinations: </p> + +<blockquote> +<pre> +$ qshape <i>(show "incoming" and "active" queue status)</i> + + T A 5 10 20 40 80 160 320 320+ + TOTAL 11775 9996 0 0 1 1 42 94 221 1420 + user.sourceforge.net 7678 7678 0 0 0 0 0 0 0 0 + lists.sourceforge.net 2313 2313 0 0 0 0 0 0 0 0 + gzd.gotdns.com 102 0 0 0 0 0 0 0 2 100 +</pre> +</blockquote> + +<p> The "A" column showed the count of messages in the "active" queue, +and the numbered columns showed totals for the "deferred" queue. At +10000 messages (Postfix 1.x "active" queue size limit) the "active" queue +is full. The "incoming" queue was growing rapidly. </p> + +<p> With the trouble destinations clearly identified, the administrator +quickly found and fixed the problem. It is substantially harder to +glean the same information from the logs. While a careful reading +of mailq(1) output should yield similar results, it is much harder +to gauge the magnitude of the problem by looking at the queue +one message at a time. </p> + +<h2><a name="backlog">Example 4: High volume destination backlog</a></h2> + +<p> When a site you send a lot of email to is down or slow, mail +messages will rapidly build up in the "deferred" queue, or worse, in +the "active" queue. The qshape output will show large numbers for +the destination domain in all age buckets that overlap the starting +time of the problem: </p> + +<blockquote> +<pre> +$ qshape deferred | head + + T 5 10 20 40 80 160 320 640 1280 1280+ + TOTAL 5000 200 200 400 800 1600 1000 200 200 200 200 + highvolume.com 4000 160 160 320 640 1280 1440 0 0 0 0 + ... +</pre> +</blockquote> + +<p> Here the "highvolume.com" destination is continuing to accumulate +deferred mail. The "incoming" and "active" queues are fine, but the +"deferred" queue started growing some time between 1 and 2 hours ago +and continues to grow. </p> + +<p> If the high volume destination is not down, but is instead +slow, one might see similar congestion in the "active" queue. +"Active" queue congestion is a greater cause for alarm; one might need to +take measures to ensure that the mail is deferred instead or even +add an access(5) rule asking the sender to try again later. </p> + +<p> If a high volume destination exhibits frequent bursts of consecutive +connections refused by all MX hosts or "421 Server busy errors", it +is possible for the queue manager to mark the destination as "dead" +despite the transient nature of the errors. The destination will be +retried again after the expiration of a $minimal_backoff_time timer. +If the error bursts are frequent enough it may be that only a small +quantity of email is delivered before the destination is again marked +"dead". In some cases enabling static (not on demand) connection +caching by listing the appropriate nexthop domain in a table included in +"smtp_connection_cache_destinations" may help to reduce the error rate, +because most messages will re-use existing connections. </p> + +<p> The MTA that has been observed most frequently to exhibit such +bursts of errors is Microsoft Exchange, which refuses connections +under load. Some proxy virus scanners in front of the Exchange +server propagate the refused connection to the client as a "421" +error. </p> + +<p> Note that it is now possible to configure Postfix to exhibit similarly +erratic behavior by misconfiguring the anvil(8) service. Do not use +anvil(8) for steady-state rate limiting, its purpose is (unintentional) +DoS prevention and the rate limits set should be very generous! </p> + +<p> If one finds oneself needing to deliver a high volume of mail to a +destination that exhibits frequent brief bursts of errors and connection +caching does not solve the problem, there is a subtle workaround. </p> + +<ul> + +<li> <p> Postfix version 2.5 and later: </p> + +<ul> + +<li> <p> In master.cf set up a dedicated clone of the "smtp" transport +for the destination in question. In the example below we will call +it "fragile". </p> + +<li> <p> In master.cf configure a reasonable process limit for the +cloned smtp transport (a number in the 10-20 range is typical). </p> + +<li> <p> IMPORTANT!!! In main.cf configure a large per-destination +pseudo-cohort failure limit for the cloned smtp transport. </p> + +<pre> +/etc/postfix/main.cf: + transport_maps = hash:/etc/postfix/transport + fragile_destination_concurrency_failed_cohort_limit = 100 + fragile_destination_concurrency_limit = 20 + +/etc/postfix/transport: + example.com fragile: + +/etc/postfix/master.cf: + # service type private unpriv chroot wakeup maxproc command + fragile unix - - n - 20 smtp +</pre> + +<p> See also the documentation for +default_destination_concurrency_failed_cohort_limit and +default_destination_concurrency_limit. </p> + +</ul> + +<li> <p> Earlier Postfix versions: </p> + +<ul> + +<li> <p> In master.cf set up a dedicated clone of the "smtp" +transport for the destination in question. In the example below +we will call it "fragile". </p> + +<li> <p> In master.cf configure a reasonable process limit for the +transport (a number in the 10-20 range is typical). </p> + +<li> <p> IMPORTANT!!! In main.cf configure a very large initial +and destination concurrency limit for this transport (say 2000). </p> + +<pre> +/etc/postfix/main.cf: + transport_maps = hash:/etc/postfix/transport + initial_destination_concurrency = 2000 + fragile_destination_concurrency_limit = 2000 + +/etc/postfix/transport: + example.com fragile: + +/etc/postfix/master.cf: + # service type private unpriv chroot wakeup maxproc command + fragile unix - - n - 20 smtp +</pre> + +<p> See also the documentation for default_destination_concurrency_limit. +</p> + +</ul> + +</ul> + +<p> The effect of this configuration is that up to 2000 +consecutive errors are tolerated without marking the destination +dead, while the total concurrency remains reasonable (10-20 +processes). This trick is only for a very specialized situation: +high volume delivery into a channel with multi-error bursts +that is capable of high throughput, but is repeatedly throttled by +the bursts of errors. </p> + +<p> When a destination is unable to handle the load even after the +Postfix process limit is reduced to 1, a desperate measure is to +insert brief delays between delivery attempts. </p> + +<ul> + +<li> <p> Postfix version 2.5 and later: </p> + +<ul> + +<li> <p> In master.cf set up a dedicated clone of the "smtp" transport +for the problem destination. In the example below we call it "slow". +</p> + +<li> <p> In main.cf configure a short delay between deliveries to +the same destination. </p> + +<pre> +/etc/postfix/main.cf: + transport_maps = hash:/etc/postfix/transport + slow_destination_rate_delay = 1 + slow_destination_concurrency_failed_cohort_limit = 100 + +/etc/postfix/transport: + example.com slow: + +/etc/postfix/master.cf: + # service type private unpriv chroot wakeup maxproc command + slow unix - - n - - smtp +</pre> + +</ul> + +<p> See also the documentation for default_destination_rate_delay. </p> + +<p> This solution forces the Postfix smtp(8) client to wait for +$slow_destination_rate_delay seconds between deliveries to the same +destination. </p> + +<p> IMPORTANT!! The large slow_destination_concurrency_failed_cohort_limit +value is needed. This prevents Postfix from deferring all mail for +the same destination after only one connection or handshake error +(the reason for this is that non-zero slow_destination_rate_delay +forces a per-destination concurrency of 1). </p> + +<li> <p> Earlier Postfix versions: </p> + +<ul> + +<li> <p> In the transport map entry for the problem destination, +specify a dead host as the primary nexthop. </p> + +<li> <p> In the master.cf entry for the transport specify the +problem destination as the fallback_relay and specify a small +smtp_connect_timeout value. </p> + +<pre> +/etc/postfix/main.cf: + transport_maps = hash:/etc/postfix/transport + +/etc/postfix/transport: + example.com slow:[dead.host] + +/etc/postfix/master.cf: + # service type private unpriv chroot wakeup maxproc command + slow unix - - n - 1 smtp + -o fallback_relay=problem.example.com + -o smtp_connect_timeout=1 + -o smtp_connection_cache_on_demand=no +</pre> + +</ul> + +<p> This solution forces the Postfix smtp(8) client to wait for +$smtp_connect_timeout seconds between deliveries. The connection +caching feature is disabled to prevent the client from skipping +over the dead host. </p> + +</ul> + +<h2><a name="queues">Postfix queue directories</a></h2> + +<p> The following sections describe Postfix queues: their purpose, +what normal behavior looks like, and how to diagnose abnormal +behavior. </p> + +<h3> <a name="maildrop_queue"> The "maildrop" queue </a> </h3> + +<p> Messages that have been submitted via the Postfix sendmail(1) +command, but not yet brought into the main Postfix queue by the +pickup(8) service, await processing in the "maildrop" queue. Messages +can be added to the "maildrop" queue even when the Postfix system +is not running. They will begin to be processed once Postfix is +started. </p> + +<p> The "maildrop" queue is drained by the single threaded pickup(8) +service scanning the queue directory periodically or when notified +of new message arrival by the postdrop(1) program. The postdrop(1) +program is a setgid helper that allows the unprivileged Postfix +sendmail(1) program to inject mail into the "maildrop" queue and +to notify the pickup(8) service of its arrival. </p> + +<p> All mail that enters the main Postfix queue does so via the +cleanup(8) service. The cleanup service is responsible for envelope +and header rewriting, header and body regular expression checks, +automatic bcc recipient processing, milter content processing, and +reliable insertion of the message into the Postfix "incoming" queue. </p> + +<p> In the absence of excessive CPU consumption in cleanup(8) header +or body regular expression checks or other software consuming all +available CPU resources, Postfix performance is disk I/O bound. +The rate at which the pickup(8) service can inject messages into +the queue is largely determined by disk access times, since the +cleanup(8) service must commit the message to stable storage before +returning success. The same is true of the postdrop(1) program +writing the message to the "maildrop" directory. </p> + +<p> As the pickup service is single threaded, it can only deliver +one message at a time at a rate that does not exceed the reciprocal +disk I/O latency (+ CPU if not negligible) of the cleanup service. +</p> + +<p> Congestion in this queue is indicative of an excessive local message +submission rate or perhaps excessive CPU consumption in the cleanup(8) +service due to excessive body_checks, or (Postfix ≥ 2.3) high latency +milters. </p> + +<p> Note, that once the "active" queue is full, the cleanup service +will attempt to slow down message injection by pausing $in_flow_delay +for each message. In this case "maildrop" queue congestion may be +a consequence of congestion downstream, rather than a problem in +its own right. </p> + +<p> Note, you should not attempt to deliver large volumes of mail via +the pickup(8) service. High volume sites should avoid using "simple" +content filters that re-inject scanned mail via Postfix sendmail(1) +and postdrop(1). </p> + +<p> A high arrival rate of locally submitted mail may be an indication +of an uncaught forwarding loop, or a run-away notification program. +Try to keep the volume of local mail injection to a moderate level. +</p> + +<p> The "postsuper -r" command can place selected messages into +the "maildrop" queue for reprocessing. This is most useful for +resetting any stale content_filter settings. Requeuing a large number +of messages using "postsuper -r" can clearly cause a spike in the +size of the "maildrop" queue. </p> + +<h3> <a name="hold_queue"> The "hold" queue </a> </h3> + +<p> The administrator can define "smtpd" access(5) policies, or +cleanup(8) header/body checks that cause messages to be automatically +diverted from normal processing and placed indefinitely in the +"hold" queue. Messages placed in the "hold" queue stay there until +the administrator intervenes. No periodic delivery attempts are +made for messages in the "hold" queue. The postsuper(1) command +can be used to manually release messages into the "deferred" queue. +</p> + +<p> Messages can potentially stay in the "hold" queue longer than +$maximal_queue_lifetime. If such "old" messages need to be released from +the "hold" queue, they should typically be moved into the "maildrop" queue +using "postsuper -r", so that the message gets a new timestamp and +is given more than one opportunity to be delivered. Messages that are +"young" can be moved directly into the "deferred" queue using +"postsuper -H". </p> + +<p> The "hold" queue plays little role in Postfix performance, and +monitoring of the "hold" queue is typically more closely motivated +by tracking spam and malware, than by performance issues. </p> + +<h3> <a name="incoming_queue"> The "incoming" queue </a> </h3> + +<p> All new mail entering the Postfix queue is written by the +cleanup(8) service into the "incoming" queue. New queue files are +created owned by the "postfix" user with an access bitmask (or +mode) of 0600. Once a queue file is ready for further processing +the cleanup(8) service changes the queue file mode to 0700 and +notifies the queue manager of new mail arrival. The queue manager +ignores incomplete queue files whose mode is 0600, as these are +still being written by cleanup. </p> + +<p> The queue manager scans the "incoming" queue bringing any new +mail into the "active" queue if the "active" queue resource limits +have not been exceeded. By default, the "active" queue accommodates +at most 20000 messages. Once the "active" queue message limit is +reached, the queue manager stops scanning the "incoming" queue +(and the "deferred" queue, see below). </p> + +<p> Under normal conditions the "incoming" queue is nearly empty (has +only mode 0600 files), with the queue manager able to import new +messages into the "active" queue as soon as they become available. +</p> + +<p> The "incoming" queue grows when the message input rate spikes +above the rate at which the queue manager can import messages into +the "active" queue. The main factors slowing down the queue manager +are disk I/O and lookup queries to the trivial-rewrite service. If the queue +manager is routinely not keeping up, consider not using "slow" +lookup services (MySQL, LDAP, ...) for transport lookups or speeding +up the hosts that provide the lookup service. If the problem is I/O +starvation, consider striping the queue over more disks, faster controllers +with a battery write cache, or other hardware improvements. At the very +least, make sure that the queue directory is mounted with the "noatime" +option if applicable to the underlying filesystem. </p> + +<p> The in_flow_delay parameter is used to clamp the input rate +when the queue manager starts to fall behind. The cleanup(8) service +will pause for $in_flow_delay seconds before creating a new queue +file if it cannot obtain a "token" from the queue manager. </p> + +<p> Since the number of cleanup(8) processes is limited in most +cases by the SMTP server concurrency, the input rate can exceed +the output rate by at most "SMTP connection count" / $in_flow_delay +messages per second. </p> + +<p> With a default process limit of 100, and an in_flow_delay of +1s, the coupling is strong enough to limit a single run-away injector +to 1 message per second, but is not strong enough to deflect an +excessive input rate from many sources at the same time. </p> + +<p> If a server is being hammered from multiple directions, consider +raising the in_flow_delay to 10 seconds, but only if the "incoming" queue +is growing even while the "active" queue is not full and the +trivial-rewrite service is using a fast transport lookup mechanism. +</p> + +<h3> <a name="active_queue"> The "active" queue </a> </h3> + +<p> The queue manager is a delivery agent scheduler; it works to +ensure fast and fair delivery of mail to all destinations within +designated resource limits. </p> + +<p> The "active" queue is somewhat analogous to an operating system's +process run queue. Messages in the "active" queue are ready to be +sent (runnable), but are not necessarily in the process of being +sent (running). </p> + +<p> While most Postfix administrators think of the "active" queue +as a directory on disk, the real "active" queue is a set of data +structures in the memory of the queue manager process. </p> + +<p> Messages in the "maildrop", "hold", "incoming" and "deferred" queues +(see below) do not occupy memory; they are safely stored on +disk waiting for their turn to be processed. The envelope information +for messages in the "active" queue is managed in memory, allowing +the queue manager to do global scheduling, allocating available +delivery agent processes to an appropriate message in the "active" queue. </p> + +<p> Within the "active" queue, (multi-recipient) messages are broken +up into groups of recipients that share the same transport/nexthop +combination; the group size is capped by the transport's recipient +concurrency limit. </p> + +<p> Multiple recipient groups (from one or more messages) are queued +for delivery grouped by transport/nexthop combination. The +<b>destination</b> concurrency limit for the transports caps the number +of simultaneous delivery attempts for each nexthop. Transports with +a <b>recipient</b> concurrency limit of 1 are special: these are grouped +by the actual recipient address rather than the nexthop, yielding +per-recipient concurrency limits rather than per-domain +concurrency limits. Per-recipient limits are appropriate when +performing final delivery to mailboxes rather than when relaying +to a remote server. </p> + +<p> Congestion occurs in the "active" queue when one or more destinations +drain slower than the corresponding message input rate. </p> + +<p> Input into the "active" queue comes both from new mail in the "incoming" queue, +and retries of mail in the "deferred" queue. Should the "deferred" queue +get really large, retries of old mail can dominate the arrival +rate of new mail. Systems with more CPU, faster disks and more network +bandwidth can deal with larger "deferred" queues, but as a rule of thumb +the "deferred" queue scales to somewhere between 100,000 and 1,000,000 +messages with good performance unlikely above that "limit". Systems with +queues this large should typically stop accepting new mail, or put the +backlog "on hold" until the underlying issue is fixed (provided that +there is enough capacity to handle just the new mail). </p> + +<p> When a destination is down for some time, the queue manager will +mark it dead, and immediately defer all mail for the destination without +trying to assign it to a delivery agent. In this case the messages +will quickly leave the "active" queue and end up in the "deferred" queue +(with Postfix < 2.4, this is done directly by the queue manager, +with Postfix ≥ 2.4 this is done via the "retry" delivery agent). </p> + +<p> When the destination is instead simply slow, or there is a problem +causing an excessive arrival rate the "active" queue will grow and will +become dominated by mail to the congested destination. </p> + +<p> The only way to reduce congestion is to either reduce the input +rate or increase the throughput. Increasing the throughput requires +either increasing the concurrency or reducing the latency of +deliveries. </p> + +<p> For high volume sites a key tuning parameter is the number of +"smtp" delivery agents allocated to the "smtp" and "relay" transports. +High volume sites tend to send to many different destinations, many +of which may be down or slow, so a good fraction of the available +delivery agents will be blocked waiting for slow sites. Also mail +destined across the globe will incur large SMTP command-response +latencies, so high message throughput can only be achieved with +more concurrent delivery agents. </p> + +<p> The default "smtp" process limit of 100 is good enough for most +sites, and may even need to be lowered for sites with low bandwidth +connections (no use increasing concurrency once the network pipe +is full). When one finds that the queue is growing on an "idle" +system (CPU, disk I/O and network not exhausted) the remaining +reason for congestion is insufficient concurrency in the face of +a high average latency. If the number of outbound SMTP connections +(either ESTABLISHED or SYN_SENT) reaches the process limit, mail +is draining slowly and the system and network are not loaded, raise +the "smtp" and/or "relay" process limits! </p> + +<p> When a high volume destination is served by multiple MX hosts with +typically low delivery latency, performance can suffer dramatically when +one of the MX hosts is unresponsive and SMTP connections to that host +timeout. For example, if there are 2 equal weight MX hosts, the SMTP +connection timeout is 30 seconds and one of the MX hosts is down, the +average SMTP connection will take approximately 15 seconds to complete. +With a default per-destination concurrency limit of 20 connections, +throughput falls to just over 1 message per second. </p> + +<p> The best way to avoid bottlenecks when one or more MX hosts is +non-responsive is to use connection caching. Connection caching was +introduced with Postfix 2.2 and is by default enabled on demand for +destinations with a backlog of mail in the "active" queue. When connection +caching is in effect for a particular destination, established connections +are re-used to send additional messages, this reduces the number of +connections made per message delivery and maintains good throughput even +in the face of partial unavailability of the destination's MX hosts. </p> + +<p> If connection caching is not available (Postfix < 2.2) or does +not provide a sufficient latency reduction, especially for the "relay" +transport used to forward mail to "your own" domains, consider setting +lower than default SMTP connection timeouts (1-5 seconds) and higher +than default destination concurrency limits. This will further reduce +latency and provide more concurrency to maintain throughput should +latency rise. </p> + +<p> Setting high concurrency limits to domains that are not your own may +be viewed as hostile by the receiving system, and steps may be taken +to prevent you from monopolizing the destination system's resources. +The defensive measures may substantially reduce your throughput or block +access entirely. Do not set aggressive concurrency limits to remote +domains without coordinating with the administrators of the target +domain. </p> + +<p> If necessary, dedicate and tune custom transports for selected high +volume destinations. The "relay" transport is provided for forwarding mail +to domains for which your server is a primary or backup MX host. These can +make up a substantial fraction of your email traffic. Use the "relay" and +not the "smtp" transport to send email to these domains. Using the "relay" +transport allocates a separate delivery agent pool to these destinations +and allows separate tuning of timeouts and concurrency limits. </p> + +<p> Another common cause of congestion is unwarranted flushing of the +entire "deferred" queue. The "deferred" queue holds messages that are likely +to fail to be delivered and are also likely to be slow to fail delivery +(time out). As a result the most common reaction to a large "deferred" queue +(flush it!) is more than likely counter-productive, and typically makes +the congestion worse. Do not flush the "deferred" queue unless you expect +that most of its content has recently become deliverable (e.g. relayhost +back up after an outage)! </p> + +<p> Note that whenever the queue manager is restarted, there may +already be messages in the "active" queue directory, but the "real" +"active" queue in memory is empty. In order to recover the in-memory +state, the queue manager moves all the "active" queue messages +back into the "incoming" queue, and then uses its normal "incoming" queue +scan to refill the "active" queue. The process of moving all +the messages back and forth, redoing transport table (trivial-rewrite(8) +resolve service) lookups, and re-importing the messages back into +memory is expensive. At all costs, avoid frequent restarts of the +queue manager (e.g. via frequent execution of "postfix reload"). </p> + +<h3> <a name="deferred_queue"> The "deferred" queue </a> </h3> + +<p> When all the deliverable recipients for a message are delivered, +and for some recipients delivery failed for a transient reason (it +might succeed later), the message is placed in the "deferred" queue. +</p> + +<p> The queue manager scans the "deferred" queue periodically. The scan +interval is controlled by the queue_run_delay parameter. While a "deferred" queue +scan is in progress, if an "incoming" queue scan is also in progress +(ideally these are brief since the "incoming" queue should be short), the +queue manager alternates between looking for messages in the "incoming" queue +and in the "deferred" queue. This "round-robin" strategy prevents +starvation of either the "incoming" or the "deferred" queues. </p> + +<p> Each "deferred" queue scan only brings a fraction of the "deferred" queue +back into the "active" queue for a retry. This is because each +message in the "deferred" queue is assigned a "cool-off" time when +it is deferred. This is done by time-warping the modification +time of the queue file into the future. The queue file is not +eligible for a retry if its modification time is not yet reached. +</p> + +<p> The "cool-off" time is at least $minimal_backoff_time and at +most $maximal_backoff_time. The next retry time is set by doubling +the message's age in the queue, and adjusting up or down to lie +within the limits. This means that young messages are initially +retried more often than old messages. </p> + +<p> If a high volume site routinely has large "deferred" queues, it +may be useful to adjust the queue_run_delay, minimal_backoff_time and +maximal_backoff_time to provide short enough delays on first failure +(Postfix ≥ 2.4 has a sensibly low minimal backoff time by default), +with perhaps longer delays after multiple failures, to reduce the +retransmission rate of old messages and thereby reduce the quantity +of previously deferred mail in the "active" queue. If you want a really +low minimal_backoff_time, you may also want to lower queue_run_delay, +but understand that more frequent scans will increase the demand for +disk I/O. </p> + +<p> One common cause of large "deferred" queues is failure to validate +recipients at the SMTP input stage. Since spammers routinely launch +dictionary attacks from unrepliable sender addresses, the bounces +for invalid recipient addresses clog the "deferred" queue (and at high +volumes proportionally clog the "active" queue). Recipient validation +is strongly recommended through use of the local_recipient_maps and +relay_recipient_maps parameters. Even when bounces drain quickly they +inundate innocent victims of forgery with unwanted email. To avoid +this, do not accept mail for invalid recipients. </p> + +<p> When a host with lots of deferred mail is down for some time, +it is possible for the entire "deferred" queue to reach its retry +time simultaneously. This can lead to a very full "active" queue once +the host comes back up. The phenomenon can repeat approximately +every maximal_backoff_time seconds if the messages are again deferred +after a brief burst of congestion. Perhaps, a future Postfix release +will add a random offset to the retry time (or use a combination +of strategies) to reduce the odds of repeated complete "deferred" queue +flushes. </p> + +<h2><a name="credits">Credits</a></h2> + +<p> The qshape(1) program was developed by Victor Duchovni of Morgan +Stanley, who also wrote the initial version of this document. </p> + +</body> + +</html> diff --git a/proto/README b/proto/README new file mode 100644 index 0000000..b1db3e4 --- /dev/null +++ b/proto/README @@ -0,0 +1,34 @@ +This directory contains source for manual pages that aren't generated +from C source code comments, and for README files. + +Tools for these conversions are found in the ../mantools subdirectory. +The most important tool is postlink, which adds all the hyperlinks +between manual pages, configuration parameters and README files. + +Manual pages are in the form of "shell" style comments. They are +converted into nroff(1) input with the srctoman utility, converted +to HTML with man2html, and hyperlinked with postlink. + +The README files are in the form of HTML. The are converted into +hyperlinked HTML with postlink, and are converted into ASCII files +with html2readme. + +The format of the README source files is a little tricky, because +of the way postlink works. + +- postlink hyperlinks all the references to Postfix manual pages, +configuration parameters, README file names, RFC documents, Postfix +address class names, and URLs. Therefore you should not hyperlink +those elements yourself. + +- URLs (such as "http://www.example.com") cannot contain quote, comma, +or space characters. + +- An URL that appears at the end of a line must be followed by one +other character. + +- Text must go between <p> and </p>, especially within lists, for +consistency of vertical space. + +- Code fragments must go between <pre> and </pre>, again for +consistency of vertical space. diff --git a/proto/RESTRICTION_CLASS_README.html b/proto/RESTRICTION_CLASS_README.html new file mode 100644 index 0000000..4988a33 --- /dev/null +++ b/proto/RESTRICTION_CLASS_README.html @@ -0,0 +1,239 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Per-Client/User/etc. Access Control</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +Per-Client/User/etc. Access Control</h1> + +<hr> + +<h2>Postfix restriction classes</h2> + +<p> The Postfix SMTP server supports access restrictions such as +reject_rbl_client or reject_unknown_client_hostname on the right-hand side +of SMTP server access(5) tables. This allows you to implement +different junk mail restrictions for different clients or users. +</p> + +<p> Having to specify lists of access restrictions for every +recipient becomes tedious quickly. Postfix restriction classes +allow you to give easy-to-remember names to groups of UCE restrictions +(such as "permissive", "restrictive", and so on). </p> + +<p> The real reason for the existence of Postfix restriction classes +is more mundane: you can't specify a lookup table on the right-hand +side of a Postfix access table. This is because Postfix needs to +open lookup tables ahead of time, but the reader probably does not +care about these low-level details. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_restriction_classes = restrictive, permissive + # With Postfix < 2.3 specify reject_unknown_client. + restrictive = reject_unknown_sender_domain reject_unknown_client_hostname ... + permissive = permit + + smtpd_recipient_restrictions = + permit_mynetworks + # reject_unauth_destination is not needed here if the mail + # relay policy is specified with smtpd_relay_restrictions + # (available with Postfix 2.10 and later). + reject_unauth_destination + check_recipient_access hash:/etc/postfix/recipient_access + ... + +/etc/postfix/recipient_access: + joe@my.domain permissive + jane@my.domain restrictive +</pre> +</blockquote> + +<p> With this in place, you can use "restrictive" or "permissive" +on the right-hand side of your per-client, helo, sender, or recipient +SMTPD access tables. </p> + +<p> The remainder of this document gives examples of how Postfix +access restriction classes can be used to: </p> + +<ul> + +<li> <a href="#internal"> Shield an internal mailing list from +outside posters</a>, + +<li> <a href="#external"> Prevent external access by internal +senders</a>. + +</ul> + +<p> These questions come up frequently, and the examples hopefully +make clear that Postfix restriction classes aren't really the right +solution. They should be used for what they were designed to do, +different junk mail restrictions for different clients or users. +</p> + +<h2><a name="internal">Protecting internal email distribution +lists</a></h2> + +<blockquote> + +<p> We want to implement an internal email distribution list. +Something like all@our.domain.com, which aliases to all employees. +My first thought was to use the aliases map, but that would lead +to "all" being accessible from the "outside", and this is not +desired... :-) </p> + +</blockquote> + +<p> Postfix can implement per-address access controls. What follows +is based on the SMTP client IP address, and therefore is subject +to IP spoofing. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_recipient_restrictions = + ... + check_recipient_access hash:/etc/postfix/access + <i>...the usual stuff...</i> + +/etc/postfix/access: + all@my.domain permit_mynetworks,reject + all@my.hostname permit_mynetworks,reject +</pre> +</blockquote> + +<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses +<b>dbm</b> files instead of <b>db</b> files. To find out what map +types Postfix supports, use the command <b>postconf -m</b>. </p> + +<p> Now, that would be sufficient when your machine receives all +Internet mail directly from the Internet. That's unlikely if your +network is a bit larger than an office. For example, your backup +MX hosts would "launder" the client IP address of mail from the +outside so it would appear to come from a trusted machine. </p> + +<p> In the general case you need two lookup tables: one table that +lists destinations that need to be protected, and one table that +lists domains that are allowed to send to the protected destinations. +</p> + +<p> What follows is based on the sender SMTP envelope address, and +therefore is subject to SMTP sender spoofing. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_recipient_restrictions = + ... + check_recipient_access hash:/etc/postfix/protected_destinations + <i>...the usual stuff...</i> + + smtpd_restriction_classes = insiders_only + insiders_only = check_sender_access hash:/etc/postfix/insiders, reject + +/etc/postfix/protected_destinations: + all@my.domain insiders_only + all@my.hostname insiders_only + +/etc/postfix/insiders: + my.domain OK <i>matches my.domain and subdomains</i> + another.domain OK <i>matches another.domain and subdomains</i> +</pre> +</blockquote> + +<p> Getting past this scheme is relatively easy, because all one +has to do is to spoof the SMTP sender address. </p> + +<p> If the internal list is a low-volume one, perhaps it makes more +sense to make it moderated. </p> + +<h2><a name="external">Restricting what users can send mail to +off-site destinations</a></h2> + +<blockquote> + +<p> How can I configure Postfix in a way that some users can send +mail to the internet and other users not. The users with no access +should receive a generic bounce message. Please don't discuss +whether such access restrictions are necessary, it was not my +decision. </p> + +</blockquote> + +<p> Postfix has support for per-user restrictions. The restrictions +are implemented by the SMTP server. Thus, users that violate the +policy have their mail rejected by the SMTP server. Like this: +</p> + +<blockquote> +<pre> +554 <user@remote>: Access denied +</pre> +</blockquote> + +<p> The implementation uses two lookup tables. One table defines +what users are restricted in where they can send mail, and the +other table defines what destinations are local. It is left as an +exercise for the reader to change this into a scheme where only +some users have permission to send mail to off-site destinations, +and where most users are restricted. </p> + +<p> The example assumes DB/DBM files, but this could also be done +with LDAP or SQL. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_recipient_restrictions = + ... + check_sender_access hash:/etc/postfix/restricted_senders + <i>...other stuff...</i> + + smtpd_restriction_classes = local_only + local_only = + check_recipient_access hash:/etc/postfix/local_domains, reject + +/etc/postfix/restricted_senders: + foo@domain local_only + bar@domain local_only + +/etc/postfix/local_domains: + this.domain OK <i>matches this.domain and subdomains</i> + that.domain OK <i>matches that.domain and subdomains</i> +</pre> +</blockquote> + +<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses +<b>dbm</b> files instead of <b>db</b> files. To find out what map +types Postfix supports, use the command <b>postconf -m</b>. </p> + +<p> Note: this scheme does not authenticate the user, and therefore it can be +bypassed in several ways: </p> + +<ul> + +<li> <p> By sending mail via a less restrictive mail +relay host. </p> + +<li> <p> By sending mail as someone else who does have permission +to send mail to off-site destinations. </p> + +</ul> + +</body> + +</html> diff --git a/proto/SASL_README.html b/proto/SASL_README.html new file mode 100644 index 0000000..c70d242 --- /dev/null +++ b/proto/SASL_README.html @@ -0,0 +1,2261 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<head> + +<title>Postfix SASL Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix SASL Howto</h1> + +<hr> + +<h2><a name="intro">How Postfix uses SASL authentication</a></h2> + +<p> SMTP servers need to decide whether an SMTP client is authorized +to send mail to remote destinations, or only to destinations that +the server itself is responsible for. Usually, SMTP servers accept +mail to remote destinations when the client's IP address is in the +"same network" as the server's IP address. </p> + +<p> SMTP clients outside the SMTP server's network need a different +way to get "same network" privileges. To address this need, Postfix +supports SASL authentication (RFC 4954, formerly RFC 2554). With +this a remote SMTP client can authenticate to the Postfix SMTP +server, and the Postfix SMTP client can authenticate to a remote +SMTP server. Once a client is authenticated, a server can give it +"same network" privileges. </p> + +<p> Postfix does not implement SASL itself, but instead uses existing +implementations as building blocks. This means that some SASL-related +configuration files will belong to Postfix, while other +configuration files belong to the specific SASL +implementation that Postfix will use. This document covers both the +Postfix and non-Postfix configuration. </p> + +<p> NOTE: People who go to the trouble of installing Postfix may +have the expectation that Postfix is more secure than some other +mailers. The Cyrus SASL library contains a lot of code. With this, +Postfix becomes as secure as other mail systems that use the Cyrus +SASL library. Dovecot provides an alternative that may be worth +considering. </p> + +<p> You can read more about the following topics: </p> + +<ul> + +<li><a href="#server_sasl">Configuring SASL authentication in the +Postfix SMTP server</a></li> + +<li><a href="#client_sasl">Configuring SASL authentication in the Postfix SMTP/LMTP client</a></li> + +<li><a href="#postfix_build">Building Postfix with SASL support</a></li> + +<li><a href="#cyrus_legacy">Using Cyrus SASL version 1.5.x</a></li> + +<li><a href="#credits">Credits</a></li> + +</ul> + +<h2><a name="server_sasl">Configuring SASL authentication in the +Postfix SMTP server</a></h2> + +<p> As mentioned earlier, SASL is implemented separately from +Postfix. For this reason, configuring SASL authentication in the +Postfix SMTP server involves two different steps: </p> + +<ul> + +<li> <p> Configuring the SASL implementation to offer a list of +mechanisms that are suitable for SASL authentication and, depending +on the SASL implementation used, configuring authentication backends +that verify the remote SMTP client's authentication data against +the system password file or some other database. </p> </li> + +<li> <p> Configuring the Postfix SMTP server to enable SASL +authentication, and to authorize clients to relay mail or to control +what envelope sender addresses the client may use. </p> </li> + +</ul> + +<p> Successful authentication in the Postfix SMTP server requires +a functional SASL framework. Configuring SASL should therefore +always be the first step, before configuring Postfix. </p> + +<p> You can read more about the following topics: </p> + +<ul> + +<li><a href="#server_which">Which SASL Implementations are +supported?</a></li> + +<li><a href="#server_dovecot">Configuring Dovecot SASL</a> + +<ul> + +<li><a href="#server_dovecot_comm">Postfix to Dovecot SASL +communication</a></li> + +</ul> </li> + +<li><a href="#server_cyrus">Configuring Cyrus SASL</a> + +<ul> + +<li><a href="#server_cyrus_name">Cyrus SASL configuration file +name</a></li> + +<li><a href="#server_cyrus_location">Cyrus SASL configuration +file location</a></li> + +<li><a href="#server_cyrus_comm">Postfix to Cyrus SASL +communication</a></li> + +</ul> </li> + +<li><a href="#server_sasl_enable">Enabling SASL authentication and +authorization in the Postfix SMTP server</a> + +<ul> + +<li><a href="#server_sasl_authc">Enabling SASL authentication in +the Postfix SMTP server</a></li> + +<li><a href="#smtpd_sasl_security_options">Postfix SMTP Server +policy - SASL mechanism properties</a></li> + +<li><a href="#server_sasl_authz">Enabling SASL authorization in the +Postfix SMTP server</a></li> + +<li><a href="#server_sasl_other">Additional SMTP Server SASL +options</a></li> + +</ul></li> + +<li><a href="#server_test">Testing SASL authentication in the Postfix +SMTP server</a></li> + +</ul> + + +<h3><a name="server_which">Which SASL Implementations are +supported?</a></h3> + +<p> Currently the Postfix SMTP server supports the Cyrus SASL and +Dovecot SASL implementations. </p> + +<blockquote> + +<strong>Note</strong> + +<p> Current Postfix versions have a plug-in architecture that can +support multiple SASL implementations. Before Postfix version 2.3, +Postfix had support only for Cyrus SASL. </p> + +</blockquote> + +<p> To find out what SASL implementations are compiled into Postfix, +use the following commands: </p> + +<blockquote> +<pre> +% <strong><code>postconf -a</code></strong> (SASL support in the SMTP server) +% <strong><code>postconf -A</code></strong> (SASL support in the SMTP+LMTP client) +</pre> +</blockquote> + +<p> These commands are available only with Postfix version 2.3 and +later. </p> + +<h3><a name="server_dovecot">Configuring Dovecot SASL</a></h3> + +<p> Dovecot is a POP/IMAP server that has its own configuration to +authenticate POP/IMAP clients. When the Postfix SMTP server uses +Dovecot SASL, it reuses parts of this configuration. Consult the +<a href="http://wiki.dovecot.org">Dovecot documentation</a> for how +to configure and operate the Dovecot authentication server. </p> + +<h4><a name="server_dovecot_comm">Postfix to Dovecot SASL communication</a></h4> + +<p> Communication between the Postfix SMTP server and Dovecot SASL +happens over a UNIX-domain socket or over a TCP socket. We will +be using a UNIX-domain socket for better privacy. </p> + +<p> The following fragment for Dovecot version 2 assumes that the +Postfix queue is under <code>/var/spool/postfix/</code>. </p> + +<blockquote> +<pre> + 1 conf.d/10-master.conf: + 2 service auth { + 3 ... + 4 unix_listener /var/spool/postfix/private/auth { + 5 mode = 0660 + 6 # Assuming the default Postfix user and group + 7 user = postfix + 8 group = postfix + 9 } +10 ... +11 } +12 +13 conf.d/10-auth.conf +14 auth_mechanisms = plain login +</pre> +</blockquote> + +<p> Line 4 places the Dovecot SASL socket in +<code>/var/spool/postfix/private/auth</code>, lines 5-8 limit +read+write permissions to user and group <code>postfix</code> only, +and line 14 provides <code>plain</code> and <code>login</code> as +mechanisms for the Postfix SMTP server. </p> + +<p> Proceed with the section "<a href="#server_sasl_enable">Enabling +SASL authentication and authorization in the Postfix SMTP server</a>" +to turn on and use SASL in the Postfix SMTP server. </p> + +<h3><a name="server_cyrus">Configuring Cyrus SASL</a></h3> + +<p> The Cyrus SASL framework supports a wide variety of applications +(POP, IMAP, SMTP, etc.). Different applications may require different +configurations. As a consequence each application may have its own +configuration file. </p> + +<p> The first step configuring Cyrus SASL is to determine name and +location of a configuration file that describes how the Postfix +SMTP server will use the SASL framework. </p> + +<h4><a name="server_cyrus_name">Cyrus SASL configuration file name</a></h4> + +<p> The name of the configuration file (default: <code>smtpd.conf</code>) +is configurable. It is a concatenation from a value that the Postfix +SMTP server sends to the Cyrus SASL library, and the suffix +<code>.conf</code>, added by Cyrus SASL. </p> + +<p> The value sent by Postfix is the name of the server component +that will use Cyrus SASL. It defaults to <code>smtpd</code> and +is configured with one of the following variables: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # Postfix 2.3 and later + smtpd_sasl_path = smtpd + + # Postfix < 2.3 + smtpd_sasl_application_name = smtpd +</pre> +</blockquote> + +<h4><a name="server_cyrus_location">Cyrus SASL configuration file +location</a></h4> + +<p> The location where Cyrus SASL searches for the named file depends +on the Cyrus SASL version and the OS/distribution used. </p> + +<p> You can read more about the following topics: </p> + +<ul> + +<li> <p> Cyrus SASL version 2.x searches for the configuration file +in <code>/usr/lib/sasl2/</code>. </p> </li> + +<li> <p> Cyrus SASL version 2.1.22 and newer additionally search +in <code>/etc/sasl2/</code>. </p> </li> + +<li> <p> Some Postfix distributions are modified and look for the +Cyrus SASL configuration file in <code>/etc/postfix/sasl/</code>, +<code>/var/lib/sasl2/</code> etc. See the distribution-specific +documentation to determine the expected location. </p> </li> + +</ul> + +<blockquote> + +<strong>Note</strong> + +<p> Cyrus SASL searches <code>/usr/lib/sasl2/</code> first. If it +finds the specified configuration file there, it will not examine +other locations. </p> + +</blockquote> + +<h4><a name="server_cyrus_comm">Postfix to Cyrus SASL communication</a></h4> + +<p> As the Postfix SMTP server is linked with the Cyrus SASL library +<code>libsasl</code>, communication between Postfix and Cyrus SASL +takes place by calling functions in the SASL library. </p> + +<p> The SASL library may use an external password verification +service, or an internal plugin to connect to authentication backends +and verify the SMTP client's authentication data against the system +password file or other databases. </p> + +<p> The following table shows typical combinations discussed in +this document: </p> + +<blockquote> + +<table border="1"> + +<tr> + +<th align="center">authentication backend</th> + +<th align="center">password verification service / plugin</th> + +</tr> + +<tr> + +<td>/etc/shadow</td> + +<td><a href="#saslauthd">saslauthd</a></td> + +</tr> + +<tr> + +<td>PAM</td> + +<td><a href="#saslauthd">saslauthd</a></td> + +</tr> + +<tr> + +<td>IMAP server</td> + +<td><a href="#saslauthd">saslauthd</a></td> + +</tr> + +<tr> + +<td>sasldb</td> + +<td><a href="#auxprop_sasldb">sasldb</a></td> + +</tr> + +<tr> + +<td>MySQL, PostgreSQL, SQLite</td> + +<td><a href="#auxprop_sql">sql</a></td> + +</tr> + +<tr> + +<td>LDAP</td> + +<td><a href="#auxprop_ldapdb">ldapdb</a></td> + +</tr> + +</table> + +</blockquote> + +<blockquote> + +<strong>Note</strong> + +<p> Read the Cyrus SASL documentation for other backends it can +use. </p> + +</blockquote> + +<h4><a name="saslauthd">saslauthd - Cyrus SASL password verification service</a></h4> + +<p> Communication between the Postfix SMTP server (read: Cyrus SASL's +<code>libsasl</code>) and the <code>saslauthd</code> server takes +place over a UNIX-domain socket. </p> + +<p> <code>saslauthd</code> usually establishes the UNIX domain +socket in <code>/var/run/saslauthd/</code> and waits for authentication +requests. The Postfix SMTP server must have read+execute permission +to this directory or authentication attempts will fail. </p> + +<blockquote> + +<strong>Important</strong> + +<p> Some distributions require the user <code>postfix</code> to be +member of a special group e.g. <code>sasl</code>, otherwise it +will not be able to access the <code>saslauthd</code> socket +directory. </p> + +</blockquote> + +<p> The following example configures the Cyrus SASL library to +contact <code>saslauthd</code> as its password verification service: +</p> + +<blockquote> +<pre> +/etc/sasl2/smtpd.conf: + pwcheck_method: saslauthd + mech_list: PLAIN LOGIN +</pre> +</blockquote> + +<blockquote> + +<strong>Important</strong> + +<p> Do not specify any other mechanisms in <code>mech_list</code> +than <code>PLAIN</code> or <code>LOGIN</code> when using +<code>saslauthd</code>! It can only handle these two mechanisms, +and authentication will fail if clients are allowed to choose other +mechanisms. </p> + +</blockquote> + +<blockquote> + +<strong>Important</strong> + +<p> Plaintext mechanisms (<code>PLAIN</code>, <code>LOGIN</code>) +send credentials unencrypted. This information should be protected +by an additional security layer such as a TLS-encrypted SMTP session +(see: TLS_README). </p> + +</blockquote> + +<p> Additionally the <code>saslauthd</code> server itself must be +configured. It must be told which authentication backend to turn +to for password verification. The backend is selected with a +<code>saslauthd</code> command-line option and will be shown in the +following examples. </p> + +<blockquote> + +<strong>Note</strong> + +<p> Some distributions use a configuration file to provide saslauthd +command line options to set e.g. the authentication backend. Typical +locations are <code>/etc/sysconfig/saslauthd</code> or +<code>/etc/default/saslauthd</code>. </p> + +</blockquote> + +<h4><a name="saslauthd_shadow">Using saslauthd with /etc/shadow</a></h4> + +<p> Access to the <code>/etc/shadow</code> system password file +requires <code>root</code> privileges. The Postfix SMTP server +(and in consequence <code>libsasl</code> linked to the server) runs +with the least privilege possible. Direct access to +<code>/etc/shadow</code> would not be possible without breaking the +Postfix security architecture. </p> + +<p> The <code>saslauthd</code> socket builds a safe bridge. Postfix, +running as limited user <code>postfix</code>, can access the +UNIX-domain socket that <code>saslauthd</code> receives commands +on; <code>saslauthd</code>, running as privileged user <code>root</code>, +has the privileges required to access the shadow file. </p> + +<p> The <code>saslauthd</code> server verifies passwords against the +authentication backend <code>/etc/shadow</code> if started like this: </p> + +<blockquote> +<pre> +% <strong><code>saslauthd -a shadow</code></strong> +</pre> +</blockquote> + +<p> See section "<a href="#testing_saslauthd">Testing saslauthd +authentication</a>" for test instructions. </p> + +<h4><a name="saslauthd_pam">Using saslauthd with PAM</a></h4> + +<p> Cyrus SASL can use the PAM framework to authenticate credentials. +<code>saslauthd</code> uses the PAM framework when started like +this: </p> + +<blockquote> +<pre> +% <strong><code>saslauthd -a pam</code></strong> +</pre> +</blockquote> + +<blockquote> + +<strong>Note</strong> + +<p> PAM configuration for the Postfix SMTP server is usually given +in <code>/etc/pam.d/smtp</code> and is beyond the scope of this +document. </p> + +</blockquote> + +<p> See section "<a href="#testing_saslauthd">Testing saslauthd +authentication</a>" for test instructions. </p> + +<h4><a name="saslauthd_imap">Using saslauthd with an IMAP server</a></h4> + +<p> <code>saslauthd</code> can verify the SMTP client credentials +by using them to log into an IMAP server. If the login succeeds, +SASL authentication also succeeds. <code>saslauthd</code> contacts +an IMAP server when started like this: </p> + +<blockquote> +<pre> +% <strong><code>saslauthd -a rimap -O imap.example.com</code></strong> +</pre> +</blockquote> + +<blockquote> + +<strong>Note</strong> + +<p> The option "<code>-O imap.example.com</code>" specifies the +IMAP server <code>saslauthd</code> should contact when it verifies +credentials. </p> + +</blockquote> + +<blockquote> + +<strong>Important</strong> + +<p> <code>saslauthd</code> sends IMAP login information unencrypted. +Any IMAP session leaving the local host should be protected by an +additional security layer such as an SSL tunnel. </p> + +</blockquote> + +<p> See section "<a href="#testing_saslauthd">Testing saslauthd +authentication</a>" for test instructions. </p> + +<h4><a name="testing_saslauthd">Testing saslauthd authentication</a></h4> + +<p> Cyrus SASL provides the <code>testsaslauthd</code> utility to +test <code>saslauthd</code> authentication. The username and password +are given as command line arguments. The example shows the response +when authentication is successful: </p> + +<blockquote> +<pre> +% <strong><code>testsaslauthd -u <em>username</em> -p <em>password</em></code></strong> +0: OK "Success." +</pre> +</blockquote> + +<blockquote> + +<strong>Note</strong> + +<p> Sometimes the <code>testsaslauthd</code> program is not distributed +with a the Cyrus SASL main package. In that case, it may be +distributed with <code>-devel</code>, <code>-dev</code> or +<code>-debug</code> packages. </p> + +</blockquote> + +<p> Specify an additional "<code>-s smtp</code>" if <code>saslauthd</code> +was configured to contact the PAM authentication framework, and +specify an additional "<code>-f <em>/path/to/socketdir/mux</em></code>" +if <code>saslauthd</code> establishes the UNIX-domain socket in a +non-default location. </p> + +<p> If authentication succeeds, proceed with the section "<a +href="#server_sasl_enable">Enabling SASL authentication and authorization +in the Postfix SMTP server</a>". </p> + +<h4><a name="auxprop">Cyrus SASL Plugins - auxiliary property +plugins</a></h4> + +<p> Cyrus SASL uses a plugin infrastructure (called <code>auxprop</code>) +to expand <code>libsasl</code>'s capabilities. Currently Cyrus +SASL sources provide three authentication plugins. </p> + +<blockquote> + +<table border="1"> + +<tr> <th>Plugin </th> <th>Description </th> </tr> + +<tr> <td><a href="#auxprop_sasldb">sasldb</a></td> <td> Accounts +are stored stored in a Cyrus SASL Berkeley DB database </td> </tr> + +<tr> <td><a href="#auxprop_sql">sql</a></td> <td> Accounts are +stored in a SQL database </td> </tr> + +<tr> <td><a href="#auxprop_ldapdb">ldapdb</a></td> <td> Accounts +are stored stored in an LDAP database </td> </tr> + +</table> + +</blockquote> + +<blockquote> + +<strong>Important</strong> + +<p> These three plugins support shared-secret mechanisms i.e. +CRAM-MD5, DIGEST-MD5 and NTLM. These mechanisms send credentials +encrypted but their verification process requires the password to +be available in plaintext. Consequently passwords cannot (!) be +stored in encrypted form. </p> + +</blockquote> + +<h4><a name="auxprop_sasldb">The sasldb plugin</a></h4> + +<p> The sasldb auxprop plugin authenticates SASL clients against +credentials that are stored in a Berkeley DB database. The database +schema is specific to Cyrus SASL. The database is usually located +at <code>/etc/sasldb2</code>. </p> + +<blockquote> + +<strong>Note</strong> + +<p> The <code>sasldb2</code> file contains passwords in +plaintext, and should have read+write access only to user +<code>postfix</code> or a group that <code>postfix</code> is member +of. </p> + +</blockquote> + +<p> The <code>saslpasswd2</code> command-line utility creates +and maintains the database: </p> + +<blockquote> +<pre> +% <strong>saslpasswd2 -c -u <em>example.com</em> <em>username</em></strong> +Password: +Again (for verification): +</pre> +</blockquote> + +<p> This command creates an account +<code><em>username@example.com</em></code>. </p> + +<blockquote> + +<strong>Important</strong> + +<p> users must specify <code><em>username@example.com</em></code> +as login name, not <code><em>username</em></code>. </p> + +</blockquote> + +<p> Run the following command to reuse the Postfix <code>mydomain</code> +parameter value as the login domain: </p> + +<blockquote> +<pre> +% <strong>saslpasswd2 -c -u `postconf -h mydomain` <em>username</em></strong> +Password: +Again (for verification): +</pre> +</blockquote> + +<blockquote> + +<strong>Note</strong> + +<p> Run <code>saslpasswd2</code> without any options for further +help on how to use the command. </p> + +</blockquote> + +<p> The <code>sasldblistusers2</code> command lists all existing +users in the sasldb database: </p> + +<blockquote> +<pre> +% <strong>sasldblistusers2</strong> +username1@example.com: password1 +username2@example.com: password2 +</pre> +</blockquote> + +<p> Configure libsasl to use sasldb with the following instructions: </p> + +<blockquote> +<pre> +/etc/sasl2/smtpd.conf: + pwcheck_method: auxprop + auxprop_plugin: sasldb + mech_list: PLAIN LOGIN CRAM-MD5 DIGEST-MD5 NTLM +</pre> +</blockquote> + +<blockquote> + +<strong>Note</strong> + +<p> In the above example adjust <code>mech_list</code> to the +mechanisms that are applicable for your environment. </p> + +</blockquote> + +<h4><a name="auxprop_sql">The sql plugin</a></h4> + +<p> The sql auxprop plugin is a generic SQL plugin. It provides +access to credentials stored in a MySQL, PostgreSQL or SQLite +database. This plugin requires that SASL client passwords are +stored as plaintext. </p> + +<blockquote> + +<strong>Tip</strong> + +<p> If you must store encrypted passwords, you cannot use the sql +auxprop plugin. Instead, see section "<a href="#saslauthd_pam">Using +saslauthd with PAM</a>", and configure PAM to look up the encrypted +passwords with, for example, the <code>pam_mysql</code> module. +You will not be able to use any of the methods that require access +to plaintext passwords, such as the shared-secret methods CRAM-MD5 +and DIGEST-MD5. </p> + +</blockquote> + +<p> The following example configures libsasl to use the sql plugin +and connects it to a PostgreSQL server: </p> + +<blockquote> +<pre> +/etc/sasl2/smtpd.conf: + pwcheck_method: auxprop + auxprop_plugin: sql + mech_list: PLAIN LOGIN CRAM-MD5 DIGEST-MD5 NTLM + sql_engine: pgsql + sql_hostnames: 127.0.0.1, 192.0.2.1 + sql_user: username + sql_passwd: secret + sql_database: dbname + sql_select: SELECT password FROM users WHERE user = '%u@%r' +</pre> +</blockquote> + +<blockquote> + +<strong>Note</strong> + +<p> Set appropriate permissions if <code>smtpd.conf</code> contains +a password. The file should be readable by the <code>postfix</code> +user. </p> + +</blockquote> + +<blockquote> + +<strong>Note</strong> + +<p> In the above example, adjust <code>mech_list</code> to the +mechanisms that are applicable for your environment. </p> + +</blockquote> + +<p> The sql plugin has the following configuration options: </p> + +<blockquote> + +<dl> + +<dt>sql_engine</dt> + +<dd> + +<p> Specify <code>mysql</code> to connect to a MySQL server, +<code>pgsql</code> for a PostgreSQL server or <code>sqlite</code> +for an SQLite database </p> + +</dd> + +<dt>sql_hostnames</dt> + +<dd> + +<p> Specify one or more servers (hostname or hostname:port) separated +by commas. </p> + +<blockquote> + +<strong>Note</strong> + +<p> With MySQL servers, specify <code>localhost</code> to connect +over a UNIX-domain socket, and specify <code>127.0.0.1</code> to +connect over a TCP socket. </p> + +</blockquote> + +</dd> + +<dt>sql_user</dt> + +<dd> + +<p> The login name to gain access to the database. </p> + +</dd> + +<dt>sql_passwd</dt> + +<dd> + +<p> The password to gain access to the database. </p> + +</dd> + +<dt>sql_database</dt> + +<dd> + +<p> The name of the database to connect to. </p> + +</dd> + +<dt>sql_select</dt> + +<dd> + +<p> The SELECT statement that should retrieve the plaintext password +from a database table. </p> + +<blockquote> + +<strong>Important</strong> + +<p> Do not enclose the statement in quotes! Use single quotes to +escape macros! </p> + +</blockquote> + +</dd> + +</dl> + +</blockquote> + +<p> The sql plugin provides macros to build <code>sql_select</code> +statements. They will be replaced with arguments sent from the client. The +following macros are available: </p> + +<blockquote> + +<dl> + +<dt>%u</dt> + +<dd> + +<p> The name of the user whose properties are being selected. </p> + +</dd> + +<dt>%p</dt> + +<dd> + +<p> The name of the property being selected. While this could technically be +anything, Cyrus SASL will try userPassword and cmusaslsecretMECHNAME (where +MECHNAME is the name of a SASL mechanism). </p> + +</dd> + +<dt>%r</dt> + +<dd> + +<p> The name of the realm to which the user belongs. This could be +the KERBEROS realm, the fully-qualified domain name of the computer +the SASL application is running on, or the domain after the "@" in a +username. </p> + +</dd> + +</dl> + +</blockquote> + +<h4><a name="auxprop_ldapdb">The ldapdb plugin</a></h4> + +<p> The ldapdb auxprop plugin provides access to credentials stored +in an LDAP server. This plugin requires that SASL client passwords are +stored as plaintext. </p> + +<blockquote> + +<strong>Tip</strong> + +<p> If you must store encrypted passwords, you cannot use the ldapdb +auxprop plugin. Instead, you can use "<code>saslauthd -a ldap</code>" +to query the LDAP database directly, with appropriate configuration +in <code>saslauthd.conf</code>, <a +href="http://git.cyrusimap.org/cyrus-sasl/tree/saslauthd/LDAP_SASLAUTHD">as +described here</a>. You will not be able to use any of the +methods that require access to plaintext passwords, such as the +shared-secret methods CRAM-MD5 and DIGEST-MD5. </p> + +</blockquote> + +<p> The ldapdb plugin implements proxy authorization. This means +that the ldapdb plugin uses its own username and password to +authenticate with the LDAP server, before it asks the LDAP server +for the remote SMTP client's password. The LDAP server then decides +if the ldapdb plugin is authorized to read the remote SMTP client's +password. </p> + +<p> In a nutshell: Configuring ldapdb means authentication and +authorization must be configured twice - once in the Postfix SMTP +server to authenticate and authorize the remote SMTP client, and +once in the LDAP server to authenticate and authorize the ldapdb +plugin. </p> + +<p> This example configures libsasl to use the ldapdb plugin and +the plugin to connect to an LDAP server: </p> + +<blockquote> +<pre> +/etc/sasl2/smtpd.conf: + pwcheck_method: auxprop + auxprop_plugin: ldapdb + mech_list: PLAIN LOGIN NTLM CRAM-MD5 DIGEST-MD5 + ldapdb_uri: ldap://localhost + ldapdb_id: proxyuser + ldapdb_pw: password + ldapdb_mech: DIGEST-MD5 +</pre> +</blockquote> + +<blockquote> + +<strong>Important</strong> + +<p> Set appropriate permissions if <code>smtpd.conf</code> contains a +password. The file should be readable by the <code>postfix</code> +user. </p> + +</blockquote> + +<blockquote> + +<strong>Note</strong> + +<p> The shared-secret mechanisms (CRAM-MD5, etc.) require that the +SASL client passwords are stored as plaintext. </p> + +</blockquote> + +<p> The following is a summary of applicable <code>smtpd.conf</code> +file entries: </p> + +<blockquote> + +<dl> + +<dt>auxprop_plugin</dt> + +<dd> <p> Specify <code>ldapdb</code> to enable the plugin. </p> </dd> + +<dt>ldapdb_uri</dt> + +<dd> <p> Specify either <code>ldapi://</code> to connect over +a UNIX-domain socket, <code>ldap://</code> for an unencrypted TCP +connection, or <code>ldaps://</code> for an encrypted TCP connection. +</p> </dd> + +<dt>ldapdb_id</dt> + +<dd> <p> The login name to authenticate the ldapdb plugin to the +LDAP server (proxy authorization). </p> </dd> + +<dt>ldapdb_pw</dt> + +<dd> <p> The password (in plaintext) to authenticate the ldapdb +plugin to the LDAP server (proxy authorization). </p> </dd> + +<dt>ldapdb_mech</dt> + +<dd> <p> The mechanism to authenticate the ldapdb plugin to the +LDAP server. </p> + +<blockquote> + +<strong>Note</strong> + +<p> Specify a mechanism here that is supported by the LDAP server. +</p> + +</blockquote> + +</dd> + +<dt>ldapdb_rc (optional)</dt> + +<dd> <p> The path to a file containing individual configuration +options for the ldapdb LDAP client (libldap). This allows to specify +a TLS client certificate which in turn can be used to use the SASL +EXTERNAL mechanism. </p> + +<blockquote> + +<strong>Note</strong> + +<p> This mechanism supports authentication over an encrypted transport +layer, which is recommended if the plugin must connect to an OpenLDAP +server on a remote machine. </p> + +</blockquote> + +</dd> + +<dt>ldapdb_starttls (optional)</dt> + +<dd> <p> The TLS policy for connecting to the LDAP server. Specify +either <code>try</code> or <code>demand</code>. If the option is +<code>try</code> the plugin will attempt to establish a TLS-encrypted +connection with the LDAP server, and will fallback to an unencrypted +connection if TLS fails. If the policy is <code>demand</code> and +a TLS-encrypted connection cannot be established, the connection +fails immediately. </p> </dd> + +</dl> + +</blockquote> + +<p> When the ldapdb plugin connects to the OpenLDAP server and +successfully authenticates, the OpenLDAP server decides if the +plugin user is authorized to read SASL account information. </p> + +<p> The following configuration gives an example of authorization configuration +in the OpenLDAP slapd server: </p> + +<blockquote> +<pre> +/etc/openldap/slapd.conf: + authz-regexp + uid=(.*),cn=.*,cn=auth + ldap:///dc=example,dc=com??sub?cn=$1 + authz-policy to +</pre> +</blockquote> + +<p> Here, the <code>authz-regexp</code> option serves for authentication +of the ldapdb user. It maps its login name to a DN in the LDAP +directory tree where <code>slapd</code> can look up the SASL account +information. The <code>authz-policy</code> options defines the +authentication policy. In this case it grants authentication +privileges "<code>to</code>" the ldapdb plugin. </p> + +<p> The last configuration step is to tell the OpenLDAP <code>slapd</code> +server where ldapdb may search for usernames matching the one given +by the mail client. The example below adds an additional attribute +ldapdb user object (here: <code>authzTo</code> because the authz-policy +is "<code>to</code>") and configures the scope where the login name +"proxyuser" may search: </p> + +<blockquote> +<pre> +dn: cn=proxyuser,dc=example,dc=com +changetype: modify +add: authzTo +authzTo: dn.regex:uniqueIdentifier=(.*),ou=people,dc=example,dc=com +</pre> +</blockquote> + +<p> Use the <code>ldapmodify</code> or <code>ldapadd</code> command +to add the above attribute. </p> + +<blockquote> + +<strong>Note</strong> + +<p> Read the chapter "Using SASL" in the <a +href="http://www.openldap.org/doc/admin">OpenLDAP Admin Guide</a> +for more detailed instructions to set up SASL authentication in +OpenLDAP. </p> + +</blockquote> + +<h3><a name="server_sasl_enable">Enabling SASL authentication and +authorization in the Postfix SMTP server</a></h3> + +<p> By default the Postfix SMTP server uses the Cyrus SASL +implementation. If the Dovecot SASL implementation should be used, +specify an <code>smtpd_sasl_type</code> value of <code>dovecot</code> +instead of <code>cyrus</code>: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_sasl_type = dovecot +</pre> +</blockquote> + +<p> Additionally specify how Postfix SMTP server can find the Dovecot +authentication server. This depends on the settings that you have +selected in the section "<a href="#server_dovecot_comm">Postfix to +Dovecot SASL communication</a>". </p> + +<ul> + +<li> <p> If you configured Dovecot for UNIX-domain socket communication, +configure Postfix as follows: </p> + +<pre> +/etc/postfix/main.cf: + smtpd_sasl_path = private/auth +</pre> + +<strong>Note</strong> + +<p> This example uses a pathname relative to the Postfix queue +directory, so that it will work whether or not the Postfix SMTP +server runs chrooted. </p> + +<li> <p> If you configured Dovecot for TCP socket communication, +configure Postfix as follows. If Dovecot runs on a different machine, +replace 127.0.0.1 by that machine's IP address. </p> + +<pre> +/etc/postfix/main.cf: + smtpd_sasl_path = inet:127.0.0.1:12345 +</pre> + +<strong>Note</strong> + +<p> If you specify a remote IP address, information +will be sent as plaintext over the network. </p> + +</ul> + +<h4><a name="server_sasl_authc">Enabling SASL authentication +in the Postfix SMTP server</a></h4> + +<p> Regardless of the SASL implementation type, enabling SMTP +authentication in the Postfix SMTP server always requires setting +the <code>smtpd_sasl_auth_enable</code> option: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_sasl_auth_enable = yes +</pre> +</blockquote> + +<p> After a "postfix reload", SMTP clients will see the additional +capability AUTH in an SMTP session, followed by a list of +authentication mechanisms the server supports: </p> + +<blockquote> +<pre> +% <strong>telnet server.example.com 25</strong> +... +220 server.example.com ESMTP Postfix +<strong>EHLO client.example.com</strong> +250-server.example.com +250-PIPELINING +250-SIZE 10240000 +250-AUTH DIGEST-MD5 PLAIN CRAM-MD5 +... +</pre> +</blockquote> + +<p> However not all clients recognize the AUTH capability as defined +by the SASL authentication RFC. Some historical implementations expect the +server to send an "<code>=</code>" as separator between the AUTH +verb and the list of mechanisms that follows it. </p> + +<p> The <code>broken_sasl_auth_clients</code> configuration option +lets Postfix repeat the AUTH statement in a form that these broken +clients understand: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + broken_sasl_auth_clients = yes +</pre> +</blockquote> + +<blockquote> + +<strong>Note</strong> + +<p> Enable this option for Outlook up to and including version 2003 +and Outlook Express up to version 6. This option does not hurt other +clients. </p> + +</blockquote> + +<p> After "postfix reload", the Postfix SMTP server will propagate +the AUTH capability twice - once for compliant and once for broken +clients: </p> + +<blockquote> +<pre> +% <strong>telnet server.example.com 25</strong> +... +220 server.example.com ESMTP Postfix +<strong>EHLO client.example.com</strong> +250-server.example.com +250-PIPELINING +250-SIZE 10240000 +250-AUTH DIGEST-MD5 PLAIN CRAM-MD5 +250-AUTH=DIGEST-MD5 PLAIN CRAM-MD5 +... +</pre> +</blockquote> + +<h4><a name="smtpd_sasl_security_options">Postfix SMTP Server policy +- SASL mechanism properties</a></h4> + +<p> The Postfix SMTP server supports policies that limit the SASL +mechanisms that it makes available to clients, based on the properties +of those mechanisms. The next two sections give examples of how +these policies are used. </p> + +<blockquote> + +<table border="1"> + +<tr> <th>Property</th> <th>Description</th> </tr> + +<tr> <td>noanonymous</td> <td> Don't use mechanisms that permit +anonymous authentication. </td> </tr> + +<tr> <td>noplaintext</td> <td> Don't use mechanisms that transmit +unencrypted username and password information. </td> </tr> + +<tr> <td>nodictionary</td> <td> Don't use mechanisms that are +vulnerable to dictionary attacks. </td> </tr> + +<tr> <td>forward_secrecy</td> <td> Require forward secrecy between +sessions (breaking one session does not break earlier sessions). +</td> </tr> + +<tr> <td>mutual_auth</td> <td> Use only mechanisms that authenticate +both the client and the server to each other. </td> </tr> + +</table> + +</blockquote> + +<h4><a name="id396877">Unencrypted SMTP session</a></h4> + +<p> The default policy is to allow any mechanism in the Postfix SMTP server +except for those based on anonymous authentication: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # Specify a list of properties separated by comma or whitespace + smtpd_sasl_security_options = noanonymous +</pre> +</blockquote> + +<blockquote> + +<strong>Important</strong> + +<p> Always set at least the <code>noanonymous</code> option. +Otherwise, the Postfix SMTP server can give strangers the same +authorization as a properly-authenticated client. </p> + +</blockquote> + +<h4><a name="id396969">Encrypted SMTP session (TLS)</a></h4> + +<p> A separate parameter controls Postfix SASL mechanism policy +during a TLS-encrypted SMTP session. The default is to copy the +settings from the unencrypted session: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_sasl_tls_security_options = $smtpd_sasl_security_options +</pre> +</blockquote> + +<p> A more sophisticated policy allows plaintext mechanisms, but +only over a TLS-encrypted connection: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_sasl_security_options = noanonymous, noplaintext + smtpd_sasl_tls_security_options = noanonymous +</pre> +</blockquote> + +<p> To offer SASL authentication only after a TLS-encrypted session has been +established specify this: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_auth_only = yes +</pre> +</blockquote> + +<h4><a name="server_sasl_authz">Enabling SASL authorization in the Postfix +SMTP server</a></h4> + +<p> After the client has authenticated with SASL, the Postfix SMTP +server decides what the remote SMTP client will be authorized +for. Examples of possible SMTP clients authorizations are: </p> + +<ul> + +<li> <p> Send a message to a remote recipient. </p> </li> + +<li> <p> Use a specific envelope sender in the MAIL FROM command. </p> </li> + +</ul> + +<p> These permissions are not enabled by default. </p> + +<h4><a name="server_sasl_authz_relay">Mail relay authorization</a></h4> + +<p> With <code>permit_sasl_authenticated</code> the Postfix SMTP +server can allow +SASL-authenticated SMTP clients to send mail to remote destinations. +Examples: +</p> + +<blockquote> +<pre> +# With Postfix 2.10 and later, the mail relay policy is +# preferably specified under smtpd_relay_restrictions. +/etc/postfix/main.cf: + smtpd_relay_restrictions = + permit_mynetworks + <strong>permit_sasl_authenticated</strong> + reject_unauth_destination +</pre> + +<pre> +# Older configurations combine relay control and spam control under +# smtpd_recipient_restrictions. To use this example with Postfix ≥ +# 2.10 specify "smtpd_relay_restrictions=". +/etc/postfix/main.cf: + smtpd_recipient_restrictions = + permit_mynetworks + <strong>permit_sasl_authenticated</strong> + reject_unauth_destination + ...other rules... +</pre> +</blockquote> + +<h4><a name="server_sasl_authz_envelope">Envelope sender address +authorization</a></h4> + +<p> By default an SMTP client may specify any envelope sender address +in the MAIL FROM command. That is because the Postfix SMTP server +only knows the remote SMTP client hostname and IP address, but not +the user who controls the remote SMTP client. </p> + +<p> This changes the moment an SMTP client uses SASL authentication. +Now, the Postfix SMTP server knows who the sender is. Given a table +of envelope sender addresses and SASL login names, the Postfix SMTP +server can decide if the SASL authenticated client is allowed to +use a particular envelope sender address: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + <strong>smtpd_sender_login_maps = hash:/etc/postfix/controlled_envelope_senders</strong> + + smtpd_recipient_restrictions = + ... + <strong>reject_sender_login_mismatch</strong> + permit_sasl_authenticated + ... +</pre> +</blockquote> + +<p> The <code>controlled_envelope_senders</code> table specifies +the binding between a sender envelope address and the SASL login +names that own that address: </p> + +<blockquote> +<pre> +/etc/postfix/controlled_envelope_senders + # envelope sender owners (SASL login names) + john@example.com john@example.com + helpdesk@example.com john@example.com, mary@example.com + postmaster admin@example.com + @example.net barney, fred, john@example.com, mary@example.com +</pre> +</blockquote> + +<p> With this, the <code>reject_sender_login_mismatch</code> +restriction above will reject the sender address in the MAIL FROM +command if <code>smtpd_sender_login_maps</code> does not specify +the SMTP client's login name as an owner of that address. </p> + +<p> See also <code>reject_authenticated_sender_login_mismatch</code>, +<code>reject_known_sender_login_mismatch</code>, and +<code>reject_unauthenticated_sender_login_mismatch</code> for additional +control over the SASL login name and the envelope sender. </p> + +<h4><a name="server_sasl_other">Additional SMTP Server SASL options</a></h4> + +<p> Postfix provides a wide range of SASL authentication configuration +options. The next section lists a few that are discussed frequently. +See postconf(5) for a complete list. </p> + +<h4><a name="sasl_access">Per-account access control</a></h4> + +<p> Postfix can implement policies that depend on the SASL login +name (Postfix 2.11 and later). Typically this is used to HOLD or +REJECT mail from accounts whose credentials have been compromised. +</p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_recipient_restrictions = + permit_mynetworks + check_sasl_access hash:/etc/postfix/sasl_access + permit_sasl_authenticated + ... + +/etc/postfix/sasl_access: + # Use this when smtpd_sasl_local_domain is empty. + username HOLD + # Use this when smtpd_sasl_local_domain=example.com. + username@example.com HOLD +</pre> +</blockquote> + +<h4><a name="id397172">Default authentication domain</a></h4> + +<p> Postfix can append a domain name (or any other string) to a +SASL login name that does not have a domain part, e.g. "<code>john</code>" +instead of "<code>john@example.com</code>": </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_sasl_local_domain = example.com +</pre> +</blockquote> + +<p> This is useful as a default setting and safety net for misconfigured +clients, or during a migration to an authentication method/backend +that requires an authentication REALM or domain name, before all +SMTP clients are configured to send such information. </p> + +<h4><a name="id397205">Hiding SASL authentication from clients or +networks</a></h4> + +<p> Some clients insist on using SASL authentication if it is offered, even +when they are not configured to send credentials - and therefore +they will always fail and disconnect. </p> + +<p> Postfix can hide the AUTH capability from these clients/networks: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_sasl_exceptions_networks = !192.0.2.171/32, 192.0.2.0/24 +</pre> +</blockquote> + +<h4><a name="id397226">Adding the SASL login name to mail headers</a></h4> + +<p> To report SASL login names in Received: message headers (Postfix +version 2.3 and later): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_sasl_authenticated_header = yes +</pre> +</blockquote> + +<blockquote> + +<strong>Note</strong> + +<p> The SASL login names will be shared with the entire world. </p> + +</blockquote> + +<h3><a name="server_test">Testing SASL authentication in the Postfix SMTP Server</a></h3> + +<p> To test the server side, connect (for example, with +<code>telnet</code>) to the Postfix SMTP server port and you should +be able to have a conversation as shown below. Information sent by +the client (that is, you) is shown in <strong>bold</strong> font. +</p> + +<blockquote> +<pre> +% <strong>telnet server.example.com 25</strong> +... +220 server.example.com ESMTP Postfix +<strong>EHLO client.example.com</strong> +250-server.example.com +250-PIPELINING +250-SIZE 10240000 +250-ETRN +250-AUTH DIGEST-MD5 PLAIN CRAM-MD5 +250 8BITMIME +<strong>AUTH PLAIN AHRlc3QAdGVzdHBhc3M=</strong> +235 Authentication successful +</pre> +</blockquote> + +<p> To test this over a connection that is encrypted with TLS, use +<code>openssl s_client</code> instead of <code>telnet</code>: + +<blockquote> +<pre> +% <strong>openssl s_client -connect server.example.com:25 -starttls smtp</strong> +... +220 server.example.com ESMTP Postfix +<strong>EHLO client.example.com</strong> +...see above example for more... +</pre> +</blockquote> + +<p> Instead of <code>AHRlc3QAdGVzdHBhc3M=</code>, specify the +base64-encoded form of <code>\0username\0password</code> (the \0 +is a null byte). The example above is for a user named `<code>test</code>' +with password `<code>testpass</code>'. </p> +<blockquote> + +<strong>Caution</strong> + +<p> When posting logs of the SASL negotiations to public lists, +please keep in mind that username/password information is trivial +to recover from the base64-encoded form. </p> + +</blockquote> + +<p> You can use one of the following commands to generate base64 +encoded authentication information: </p> + +<ul> + +<li> <p> Using a recent version of the <b>bash</b> shell: </p> + +<blockquote> +<pre> +% <strong>echo -ne '\000username\000password' | openssl base64</strong> +</pre> +</blockquote> + +<p> Some other shells support similar syntax. </p> + +<li> <p> Using the <b>printf</b> command: </p> + +<blockquote> +<pre> +% <strong>printf '\0%s\0%s' '<em>username</em>' '<em>password</em>' | openssl base64</strong> +% <strong>printf '\0%s\0%s' '<em>username</em>' '<em>password</em>' | mmencode</strong> +</pre> +</blockquote> + +<p> The <strong>mmencode</strong> command is part of the metamail +software. </p> + +<li> <p> Using Perl <b>MIME::Base64</b> (from http://www.cpan.org/): </p> + +<blockquote> +<pre> +% <strong>perl -MMIME::Base64 -e \ + 'print encode_base64("\0<em>username</em>\0<em>password</em>");'</strong> +</pre> +</blockquote> + +<p> If the username or password contain "@", you must specify "\@". </p> + +<li> <p> Using the <b>gen-auth</b> script: </p> + +<blockquote> +<pre> +% <strong>gen-auth plain</strong> +username: <strong><em>username</em></strong> +password: +</pre> +</blockquote> + +<p> The <strong>gen-auth</strong> Perl script was written by John +Jetmore and can be found at http://jetmore.org/john/code/gen-auth. </p> + +</ul> + +<h2><a name="client_sasl">Configuring SASL authentication in the Postfix SMTP/LMTP client</a></h2> + +<p> The Postfix SMTP and the LMTP client can authenticate with a +remote SMTP server via the Cyrus SASL framework. At this time, the +Dovecot SASL implementation does not provide client functionality. +</p> + +<blockquote> + +<strong>Note</strong> + +<p> The examples in this section discuss only the SMTP client. +Replace <code>smtp_</code> with <code>lmtp_</code> to get the +corresponding LMTP client configuration. </p> + +</blockquote> + +<p> You can read more about the following topics: </p> + +<ul> + +<li><a href="#client_sasl_enable">Enabling SASL authentication in +the Postfix SMTP/LMTP client</a></li> + +<li><a href="#client_sasl_sender">Configuring sender-dependent SASL +authentication</a></li> + +<li><a href="#client_sasl_policy">Postfix SMTP/LMTP client policy +- SASL mechanism <em>properties</em></a></li> + +<li><a href="#client_sasl_filter">Postfix SMTP/LMTP client policy +- SASL mechanism <em>names</em></a></li> + +</ul> + +<h3><a name="client_sasl_enable">Enabling SASL authentication in the +Postfix SMTP/LMTP client</a></h3> + +<p> This section shows a typical scenario where the Postfix SMTP +client sends all messages via a mail gateway server that requires +SASL authentication. </p> + +<blockquote> + +<strong> Trouble solving tips: </strong> + +<ul> + +<li> <p> If your SASL logins fail with "SASL authentication failure: +No worthy mechs found" in the mail logfile, then see the section +"<a href="SASL_README.html#client_sasl_policy">Postfix SMTP/LMTP +client policy - SASL mechanism <em>properties</em></a>". + +<li> <p> For a solution to a more obscure class of SASL authentication +failures, see "<a href="SASL_README.html#client_sasl_filter">Postfix +SMTP/LMTP client policy - SASL mechanism <em>names</em></a>". + +</ul> + +</blockquote> + +<p> To make the example more readable we introduce it in two parts. +The first part takes care of the basic configuration, while the +second part sets up the username/password information. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_sasl_auth_enable = yes + smtp_tls_security_level = encrypt + smtp_sasl_tls_security_options = noanonymous + relayhost = [mail.isp.example] + # Alternative form: + # relayhost = [mail.isp.example]:submission + smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd +</pre> +</blockquote> + +<ul> + +<li> <p> The <code>smtp_sasl_auth_enable</code> setting enables +client-side authentication. We will configure the client's username +and password information in the second part of the example. </p> +</li> + +<li> <p> The <code>smtp_tls_security_level</code> setting ensures +that the connection to the remote smtp server will be encrypted, and +<code>smtp_sasl_tls_security_options</code> removes the prohibition on +plaintext passwords. </p> + +<li> <p> The <code>relayhost</code> setting forces the Postfix SMTP +to send all remote messages to the specified mail server instead +of trying to deliver them directly to their destination. </p> </li> + +<li> <p> In the <code>relayhost</code> setting, the "<code>[</code>" +and "<code>]</code>" prevent the Postfix SMTP client from looking +up MX (mail exchanger) records for the enclosed name. </p> </li> + +<li> <p> The <code>relayhost</code> destination may also specify a +non-default TCP port. For example, the alternative form +<code>[mail.isp.example]:submission</code> tells Postfix to connect +to TCP network port 587, which is reserved for email client +applications. </p> </li> + +<li> <p> The Postfix SMTP client is compatible with SMTP servers +that use the non-standard "<code>AUTH=<em>method.</em>...</code>" +syntax in response to the EHLO command; this requires no additional +Postfix client configuration. </p> </li> + +<li> <p> With the setting "smtp_tls_wrappermode = yes", the Postfix +SMTP client supports the "wrappermode" protocol, which uses TCP +port 465 on the SMTP server (Postfix 3.0 and later). </p> </li> + +<li> <p> With the <code>smtp_sasl_password_maps</code> parameter, +we configure the Postfix SMTP client to send username and password +information to the mail gateway server. As discussed in the next +section, the Postfix SMTP client supports multiple ISP accounts. +For this reason the username and password are stored in a table +that contains one username/password combination for each mail gateway +server. </p> + +</ul> + +<blockquote> +<pre> +/etc/postfix/sasl_passwd: + # destination credentials + [mail.isp.example] username:password + # Alternative form: + # [mail.isp.example]:submission username:password +</pre> +</blockquote> + +<blockquote> + +<strong>Important</strong> + +<p> Keep the SASL client password file in <code>/etc/postfix</code>, +and make the file read+write only for <code>root</code> to protect +the username/password combinations against other users. The Postfix +SMTP client will still be able to read the SASL client passwords. +It opens the file as user <code>root</code> before it drops privileges, +and before entering an optional chroot jail. </p> + +</blockquote> + +<ul> + +<li> <p> Use the <code>postmap</code> command whenever you +change the <code>/etc/postfix/sasl_passwd</code> file. </p> </li> + +<li> <p> If you specify the "<code>[</code>" and "<code>]</code>" +in the <code>relayhost</code> destination, then you must use the +same form in the <code>smtp_sasl_password_maps</code> file. </p> +</li> + +<li> <p> If you specify a non-default TCP Port (such as +"<code>:submission</code>" or "<code>:587</code>") in the +<code>relayhost</code> destination, then you must use the same form +in the <code>smtp_sasl_password_maps</code> file. </p> </li> + +</ul> + +<h3><a name="client_sasl_sender">Configuring Sender-Dependent SASL +authentication</a></h3> + +<p> Postfix supports different ISP accounts for different sender +addresses (version 2.3 and later). This can be useful when one +person uses the same machine for work and for personal use, or when +people with different ISP accounts share the same Postfix server. +</p> + +<p> To make this possible, Postfix supports per-sender SASL passwords +and per-sender relay hosts. In the example below, the Postfix SMTP +client will search the SASL password file by sender address before +it searches that same file by destination. Likewise, the Postfix +trivial-rewrite(8) daemon will search the per-sender relayhost file, +and use the default <code>relayhost</code> setting only as a final +resort. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_sender_dependent_authentication = yes + sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay + smtp_sasl_auth_enable = yes + smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd + relayhost = [mail.isp.example] + # Alternative form: + # relayhost = [mail.isp.example]:submission +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/sasl_passwd: + # Per-sender authentication; see also /etc/postfix/sender_relay. + user1@example.com username1:password1 + user2@example.net username2:password2 + # Login information for the default relayhost. + [mail.isp.example] username:password + # Alternative form: + # [mail.isp.example]:submission username:password +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/sender_relay: + # Per-sender provider; see also /etc/postfix/sasl_passwd. + user1@example.com [mail.example.com]:submission + user2@example.net [mail.example.net] +</pre> +</blockquote> + +<ul> + +<li> <p> If you are creative, then you can try to combine the two +tables into one single MySQL database, and configure different +Postfix queries to extract the appropriate information. </p> + +<li> <p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses +<b>dbm</b> files instead of <b>db</b> files. To find out what lookup +tables Postfix supports, use the command "<b>postconf -m</b>". </p> + +<li> <p> Execute the command "<b>postmap /etc/postfix/sasl_passwd</b>" +whenever you change the sasl_passwd table. </p> + +<li> <p> Execute the command "<b>postmap /etc/postfix/sender_relay</b>" +whenever you change the sender_relay table. </p> + +</ul> + +<h3><a name="client_sasl_policy">Postfix SMTP/LMTP client policy - +SASL mechanism <em>properties</em></a></h3> + +<p> Just like the Postfix SMTP server, the SMTP client has a policy +that determines which SASL mechanisms are acceptable, based on their +properties. The next two sections give examples of how these policies +are used. </p> + +<blockquote> + +<table border="1"> + +<tr> <th>Property</th> <th>Description</th> </tr> + +<tr> <td>noanonymous</td> <td> Don't use mechanisms that permit +anonymous authentication. </td> </tr> + +<tr> <td>noplaintext</td> <td> Don't use mechanisms that transmit +unencrypted username and password information. </td> </tr> + +<tr> <td>nodictionary</td> <td> Don't use mechanisms that are +vulnerable to dictionary attacks. </td> </tr> + +<tr> <td>mutual_auth</td> <td> Use only mechanisms that authenticate +both the client and the server to each other. </td> </tr> + +</table> + +</blockquote> + +<h4>Unencrypted SMTP session</h4> + +<p> The default policy is stricter than that of the Postfix SMTP +server - plaintext mechanisms are not allowed (nor is any anonymous +mechanism): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_sasl_security_options = noplaintext, noanonymous +</pre> +</blockquote> + +<p> This default policy, which allows no plaintext passwords, leads +to authentication failures if the remote server only offers plaintext +authentication mechanisms (the SMTP server announces "<code>AUTH +PLAIN LOGIN</code>"). In such cases the SMTP client will log the +following error message: </p> + +<blockquote> +<pre> +SASL authentication failure: No worthy mechs found +</pre> +</blockquote> + +<blockquote> + +<strong>Note</strong> + +<p> This same error message will also be logged when the +<code>libplain.so</code> or <code>liblogin.so</code> modules are +not installed in the <code>/usr/lib/sasl2</code> directory. </p> + +</blockquote> + +<p> The insecure approach is to lower the security standards and +permit plaintext authentication mechanisms: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_sasl_security_options = noanonymous +</pre> +</blockquote> + +<p> The more secure approach is to protect the plaintext username +and password with TLS session encryption. To find out if the remote +SMTP server supports TLS, connect to the server and see if it +announces STARTTLS support as shown in the example. Information +sent by the client (that is, you) is shown in <strong>bold</strong> +font. </p> + +<blockquote> +<pre> +% <strong>telnet server.example.com 25</strong> +... +220 server.example.com ESMTP Postfix +<strong>EHLO client.example.com</strong> +250-server.example.com +250-PIPELINING +250-SIZE 10240000 +250-STARTTLS +... +</pre> +</blockquote> + +<p> Instead of port 25 (smtp), specify port 587 (submission) where +appropriate. </p> + +<h4>Encrypted SMTP session (TLS)</h4> + +<p> To turn on TLS in the Postfix SMTP client, see TLS_README for +configuration details. </p> + +<p> The smtp_sasl_tls_security_options parameter controls Postfix +SASL mechanism policy during a TLS-encrypted SMTP session. The +default is to copy the settings from the unencrypted session: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_sasl_tls_security_options = $smtp_sasl_security_options +</pre> +</blockquote> + +<p> A more sophisticated policy allows plaintext mechanisms, but +only over a TLS-encrypted connection: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_sasl_security_options = noanonymous, noplaintext + smtp_sasl_tls_security_options = noanonymous +</pre> +</blockquote> + +<h3><a name="client_sasl_filter">Postfix SMTP/LMTP client policy - +SASL mechanism <em>names</em></a></h3> + +<p> Given the SASL security options of the previous section, the +Cyrus SASL library will choose the most secure authentication +mechanism that both the SMTP client and server implement. Unfortunately, +that authentication mechanism may fail because the client or server +is not configured to use that mechanism.</p> + +<p> To prevent this, the Postfix SMTP client can filter the names +of the authentication mechanisms from the remote SMTP server. Used +correctly, the filter hides unwanted mechanisms from the Cyrus SASL +library, forcing the library to choose from the mechanisms the +Postfix SMTP client filter passes through. </p> + +<p> The following example filters out everything but the mechanisms +<code>PLAIN</code> and <code>LOGIN</code>: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_sasl_mechanism_filter = plain, login +</pre> +</blockquote> + +<blockquote> + +<strong>Note</strong> + +<p> If the remote server does not offer any of the mechanisms on +the filter list, authentication will fail. </p> + +</blockquote> + +<p> We close this section with an example that passes every mechanism +except for <code>GSSAPI</code> and <code>LOGIN</code>: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_sasl_mechanism_filter = !gssapi, !login, static:all +</pre> +</blockquote> + +<h2><a name="postfix_build">Building Postfix with SASL support</a></h2> + +<p> As mentioned elsewhere, Postfix supports two SASL implementations: +Cyrus SASL (SMTP client and server) and Dovecot SASL (SMTP server +only). Both implementations can be built into Postfix simultaneously. +</p> + +<ul> + +<li><a href="#build_dovecot">Building Dovecot SASL support</a></li> + +<li><a href="#sasl_support">Building Cyrus SASL support</a></li> + +</ul> + +<h3><a name="build_dovecot">Building Dovecot SASL support</a></h3> + +<p> These instructions assume that you build Postfix from source +code as described in the INSTALL document. Some modification may +be required if you build Postfix from a vendor-specific source +package. </p> + +<p> Support for the Dovecot version 1 SASL protocol is available +in Postfix 2.3 and later. At the time of writing, only server-side +SASL support is available, so you can't use it to authenticate the +Postfix SMTP client to your network provider's server. </p> + +<p> Dovecot uses its own daemon process for authentication. This +keeps the Postfix build process simple, because there is no need +to link extra libraries into Postfix. </p> + +<p> To generate the necessary Makefiles, execute the following in +the Postfix top-level directory: </p> + +<blockquote> +<pre> +% <strong>make tidy</strong> # if you have left-over files from a previous build +% <strong>make makefiles CCARGS='-DUSE_SASL_AUTH \ + -DDEF_SERVER_SASL_TYPE=\"dovecot\"'</strong> +</pre> +</blockquote> + +<p> After this, proceed with "<code>make</code>" as described in +the INSTALL document. </p> + +<strong>Note</strong> + +<ul> + +<li> + +<p> The <code>-DDEF_SERVER_SASL_TYPE=\"dovecot\"</code> is not +necessary; it just makes Postfix configuration a little more +convenient because you don't have to specify the SASL plug-in type +in the Postfix main.cf file (but this may cause surprises when you +switch to a later Postfix version that is built with the default +SASL type of <code>cyrus</code>). </p> + +</li> + +<li> + +<p> If you also want support for LDAP or TLS (or for Cyrus SASL), +you need to merge their <code>CCARGS</code> and <code>AUXLIBS</code> +options into the above command line; see the LDAP_README and +TLS_README for details. </p> + +<blockquote> +<pre> +% <strong>make tidy</strong> # if you have left-over files from a previous build +% <strong>make makefiles CCARGS='-DUSE_SASL_AUTH \ + -DDEF_SERVER_SASL_TYPE=\"dovecot\" \ + ...<i>CCARGS options for LDAP or TLS etc.</i>...' \ + AUXLIBS='...<i>AUXLIBS options for LDAP or TLS etc.</i>...'</strong> +</pre> +</blockquote> + +</li> + +</ul> + +<h3><a name="sasl_support">Building Cyrus SASL support</a></h3> + +<h4><a name="build_sasl">Building the Cyrus SASL library</a></h4> + +<p> Postfix works with cyrus-sasl-1.5.x or cyrus-sasl-2.1.x, which are +available from https://github.com/cyrusimap/cyrus-sasl/releases. </p> + +<blockquote> + +<strong>Important</strong> + +<p> If you install the Cyrus SASL libraries as per the default, you will have +to create a symlink <code>/usr/lib/sasl</code> -> +<code>/usr/local/lib/sasl</code> for version 1.5.x or +<code>/usr/lib/sasl2</code> -> <code>/usr/local/lib/sasl2</code> +for version 2.1.x. </p> + +</blockquote> + +<p> Reportedly, Microsoft Outlook (Express) requires the non-standard LOGIN +and/or NTLM authentication mechanism. To enable these authentication +mechanisms, build the Cyrus SASL libraries with: </p> + +<blockquote> +<pre> +% <strong>./configure --enable-login --enable-ntlm</strong> +</pre> +</blockquote> + +<h4><a name="build_postfix">Building Postfix with Cyrus SASL support</a></h4> + +<p> These instructions assume that you build Postfix from source +code as described in the INSTALL document. Some modification may +be required if you build Postfix from a vendor-specific source +package. </p> + +<p> The following assumes that the Cyrus SASL include files are in +<code>/usr/local/include</code>, and that the Cyrus SASL libraries are in +<code>/usr/local/lib</code>. </p> + +<p> On some systems this generates the necessary <code>Makefile</code> +definitions: </p> + +<dl> + +<dt>Cyrus SASL version 2.1.x</dt> + +<dd> + +<pre> +% <strong>make tidy</strong> # if you have left-over files from a previous build +% <strong>make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \ + -I/usr/local/include/sasl" AUXLIBS="-L/usr/local/lib -lsasl2"</strong> +</pre> + +<p> If your Cyrus SASL shared library is in a directory that the RUN-TIME +linker does not know about, add a "-Wl,-R,/path/to/directory" option after +"-lsasl2". </p> + +</dd> + +<dt>Cyrus SASL version 1.5.x</dt> + +<dd> + +<pre> +% <strong>make tidy</strong> # if you have left-over files from a previous build +% <strong>make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \ + -I/usr/local/include" AUXLIBS="-L/usr/local/lib -lsasl"</strong> +</pre> + +</dd> + +</dl> + +<p> On Solaris 2.x you need to specify run-time link information, +otherwise the ld.so run-time linker will not find the SASL shared +library: </p> + +<dl> + +<dt>Cyrus SASL version 2.1.x</dt> + +<dd> + +<pre> +% <strong>make tidy</strong> # remove left-over files from a previous build +% <strong>make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \ + -I/usr/local/include/sasl" AUXLIBS="-L/usr/local/lib \ + -R/usr/local/lib -lsasl2"</strong> +</pre> + +</dd> + +<dt>Cyrus SASL version 1.5.x</dt> + +<dd> + +<pre> +% <strong>make tidy</strong> # if you have left-over files from a previous build +% <strong>make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \ + -I/usr/local/include" AUXLIBS="-L/usr/local/lib \ + -R/usr/local/lib -lsasl"</strong> +</pre> + +</dd> + +</dl> + +<h2><a name="cyrus_legacy">Using Cyrus SASL version 1.5.x</a></h2> + +<p> Postfix supports Cyrus SASL version 1.x, but you shouldn't use +it unless you are forced to. The makers of Cyrus SASL write: </p> + +<blockquote> <i> This library is being deprecated and applications +should transition to using the SASLv2 library</i> (source: <a +href="http://www.cyrusimap.org/download.html">Project Cyrus: +Downloads</a>). </blockquote> + +<p> If you still need to set it up, here's a quick rundown: </p> + +<p> Read the regular section on SMTP server configurations for the +Cyrus SASL framework. The differences are: </p> + +<ul> + +<li> <p> Cyrus SASL version 1.5.x searches for configuration +(<code>smtpd.conf</code>) in <code>/usr/lib/sasl/</code> only. You +must place the configuration in that directory. Some systems may +have modified Cyrus SASL and put the files into e.g. +<code>/var/lib/sasl/</code>. </p> </li> + +<li> <p> Use the <code>saslpasswd</code> command instead of +<code>saslpasswd2</code> to create users in <code>sasldb</code>. +</p> </li> + +<li> <p> Use the <code>sasldblistusers</code> command instead of +<code>sasldblistusers2</code> to find users in <code>sasldb</code>. +</p> </li> + +<li> <p> In the <code>smtpd.conf</code> file you can't use +<code>mech_list</code> to limit the range of mechanisms offered. +Instead, remove their libraries from <code>/usr/lib/sasl/</code> +(and remember remove those files again when a system update +re-installs new versions). </p> </li> + +</ul> + +<h2><a name="credits">Credits</a></h2> + +<ul> + +<li> Postfix SASL support was originally implemented by Till Franke +of SuSE Rhein/Main AG. </li> + +<li> Wietse trimmed down the code to only the bare necessities. + </li> + +<li> Support for Cyrus SASL version 2 was contributed by Jason Hoos. +</li> + +<li> Liviu Daia added smtpd_sasl_application_name, separated +reject_sender_login_mismatch into +reject_authenticated_sender_login_mismatch and +reject_unauthenticated_sender_login_mismatch, and revised the docs. + </li> + +<li> Wietse made another iteration through the code to add plug-in +support for multiple SASL implementations, and for reasons that +have been lost, also changed smtpd_sasl_application_name into +smtpd_sasl_path. </li> + +<li> The Dovecot SMTP server-only plug-in was originally implemented +by Timo Sirainen of Procontrol, Finland. </li> + +<li> Patrick Ben Koetter revised this document for Postfix 2.4 and +made much needed updates. </li> + +<li> Patrick Ben Koetter revised this document again for Postfix +2.7 and made much needed updates. </li> + +</ul> + +</body> + +</html> + diff --git a/proto/SCHEDULER_README.html b/proto/SCHEDULER_README.html new file mode 100644 index 0000000..d80b8f4 --- /dev/null +++ b/proto/SCHEDULER_README.html @@ -0,0 +1,1839 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Queue Scheduler</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +Queue Scheduler</h1> + +<hr> + +<h2> Disclaimer </h2> + +<p> Many of the <i>transport</i>-specific configuration parameters +discussed in this document will not show up in "postconf" command +output before Postfix version 2.9. This limitation applies to many +parameters whose name is a combination of a master.cf service name +such as "relay" and a built-in suffix such as +"_destination_concurrency_limit". </p> + +<h2> Overview </h2> + +<p> The queue manager is by far the most complex part of the Postfix +mail system. It schedules delivery of new mail, retries failed +deliveries at specific times, and removes mail from the queue after +the last delivery attempt. There are two major classes of mechanisms +that control the operation of the queue manager. </p> + +<p> Topics covered by this document: </p> + +<ul> + +<li> <a href="#concurrency"> Concurrency scheduling</a>, concerned +with the number of concurrent deliveries to a specific destination, +including decisions on when to suspend deliveries after persistent +failures. + +<li> <a href="#jobs"> Preemptive scheduling</a>, concerned with +the selection of email messages and recipients for a given destination. + +<li> <a href="#credits"> Credits</a>, something this document would not be +complete without. + +</ul> + +<!-- + +<p> Once started, the qmgr(8) process runs until "postfix reload" +or "postfix stop". As a persistent process, the queue manager has +to meet strict requirements with respect to code correctness and +robustness. Unlike non-persistent daemon processes, the queue manager +cannot benefit from Postfix's process rejuvenation mechanism that +limit the impact from resource leaks and other coding errors +(translation: replacing a process after a short time covers up bugs +before they can become a problem). </p> + +--> + +<h2> <a name="concurrency"> Concurrency scheduling </a> </h2> + +<p> The following sections document the Postfix 2.5 concurrency +scheduler, after a discussion of the limitations of the earlier +concurrency scheduler. This is followed by results of medium-concurrency +experiments, and a discussion of trade-offs between performance and +robustness. </p> + +<p> The material is organized as follows: </p> + +<ul> + +<li> <a href="#concurrency_drawbacks"> Drawbacks of the existing +concurrency scheduler </a> + +<li> <a href="#concurrency_summary_2_5"> Summary of the Postfix 2.5 +concurrency feedback algorithm </a> + +<li> <a href="#dead_summary_2_5"> Summary of the Postfix 2.5 "dead +destination" detection algorithm </a> + +<li> <a href="#pseudo_code_2_5"> Pseudocode for the Postfix 2.5 +concurrency scheduler </a> + +<li> <a href="#concurrency_results"> Results for delivery to +concurrency limited servers </a> + +<li> <a href="#concurrency_discussion"> Discussion of concurrency +limited server results </a> + +<li> <a href="#concurrency_limitations"> Limitations of less-than-1 +per delivery feedback </a> + +<li> <a href="#concurrency_config"> Concurrency configuration +parameters </a> + +</ul> + +<h3> <a name="concurrency_drawbacks"> Drawbacks of the existing +concurrency scheduler </a> </h3> + +<p> From the start, Postfix has used a simple but robust algorithm +where the per-destination delivery concurrency is decremented by 1 +after delivery failed due to connection or handshake failure, and +incremented by 1 otherwise. Of course the concurrency is never +allowed to exceed the maximum per-destination concurrency limit. +And when a destination's concurrency level drops to zero, the +destination is declared "dead" and delivery is suspended. </p> + +<p> Drawbacks of +/-1 concurrency feedback per delivery are: <p> + +<ul> + +<li> <p> Overshoot due to exponential delivery concurrency growth +with each pseudo-cohort(*). This can be an issue with high-concurrency +channels. For example, with the default initial concurrency of 5, +concurrency would proceed over time as (5-10-20). </p> + +<li> <p> Throttling down to zero concurrency after a single +pseudo-cohort(*) failure. This was especially an issue with +low-concurrency channels where a single failure could be sufficient +to mark a destination as "dead", causing the suspension of further +deliveries to the affected destination. </p> + +</ul> + +<p> (*) A pseudo-cohort is a number of delivery requests equal to +a destination's delivery concurrency. </p> + +<p> The revised concurrency scheduler has a highly modular structure. +It uses separate mechanisms for per-destination concurrency control +and for "dead destination" detection. The concurrency control in +turn is built from two separate mechanisms: it supports less-than-1 +feedback per delivery to allow for more gradual concurrency +adjustments, and it uses feedback hysteresis to suppress concurrency +oscillations. And instead of waiting for delivery concurrency to +throttle down to zero, a destination is declared "dead" after a +configurable number of pseudo-cohorts reports connection or handshake +failure. </p> + +<h3> <a name="concurrency_summary_2_5"> Summary of the Postfix 2.5 +concurrency feedback algorithm </a> </h3> + +<p> We want to increment a destination's delivery concurrency when +some (not necessarily consecutive) number of deliveries complete +without connection or handshake failure. This is implemented with +positive feedback g(N) where N is the destination's delivery +concurrency. With g(N)=1 feedback per delivery, concurrency increases +by 1 after each positive feedback event; this gives us the old +scheduler's exponential growth in time. With g(N)=1/N feedback per +delivery, concurrency increases by 1 after an entire pseudo-cohort +N of positive feedback reports; this gives us linear growth in time. +Less-than-1 feedback per delivery and integer truncation naturally +give us hysteresis, so that transitions to larger concurrency happen +every 1/g(N) positive feedback events. </p> + +<p> We want to decrement a destination's delivery concurrency when +some (not necessarily consecutive) number of deliveries complete +after connection or handshake failure. This is implemented with +negative feedback f(N) where N is the destination's delivery +concurrency. With f(N)=1 feedback per delivery, concurrency decreases +by 1 after each negative feedback event; this gives us the old +scheduler's behavior where concurrency is throttled down dramatically +after a single pseudo-cohort failure. With f(N)=1/N feedback per +delivery, concurrency backs off more gently. Again, less-than-1 +feedback per delivery and integer truncation naturally give us +hysteresis, so that transitions to lower concurrency happen every +1/f(N) negative feedback events. </p> + +<p> However, with negative feedback we introduce a subtle twist. +We "reverse" the negative hysteresis cycle so that the transition +to lower concurrency happens at the <b>beginning</b> of a sequence +of 1/f(N) negative feedback events. Otherwise, a correction for +overload would be made too late. This makes the choice of f(N) +relatively unimportant, as borne out by measurements later in this +document. </p> + +<p> In summary, the main ingredients for the Postfix 2.5 concurrency +feedback algorithm are a) the option of less-than-1 positive feedback +per delivery to avoid overwhelming servers, b) the option of +less-than-1 negative feedback per delivery to avoid giving up too +fast, c) feedback hysteresis to avoid rapid oscillation, and d) a +"reverse" hysteresis cycle for negative feedback, so that it can +correct for overload quickly. </p> + +<h3> <a name="dead_summary_2_5"> Summary of the Postfix 2.5 "dead destination" detection algorithm </a> </h3> + +<p> We want to suspend deliveries to a specific destination after +some number of deliveries suffers connection or handshake failure. +The old scheduler declares a destination "dead" when negative (-1) +feedback throttles the delivery concurrency down to zero. With +less-than-1 feedback per delivery, this throttling down would +obviously take too long. We therefore have to separate "dead +destination" detection from concurrency feedback. This is implemented +by introducing the concept of pseudo-cohort failure. The Postfix +2.5 concurrency scheduler declares a destination "dead" after a +configurable number of pseudo-cohorts suffers from connection or +handshake failures. The old scheduler corresponds to the special +case where the pseudo-cohort failure limit is equal to 1. </p> + +<h3> <a name="pseudo_code_2_5"> Pseudocode for the Postfix 2.5 concurrency scheduler </a> </h3> + +<p> The pseudo code shows how the ideas behind new concurrency +scheduler are implemented as of November 2007. The actual code can +be found in the module qmgr/qmgr_queue.c. </p> + +<pre> +Types: + Each destination has one set of the following variables + int concurrency + double success + double failure + double fail_cohorts + +Feedback functions: + N is concurrency; x, y are arbitrary numbers in [0..1] inclusive + positive feedback: g(N) = x/N | x/sqrt(N) | x + negative feedback: f(N) = y/N | y/sqrt(N) | y + +Initialization: + concurrency = initial_concurrency + success = 0 + failure = 0 + fail_cohorts = 0 + +After success: + fail_cohorts = 0 + Be prepared for feedback > hysteresis, or rounding error + success += g(concurrency) + while (success >= 1) Hysteresis 1 + concurrency += 1 Hysteresis 1 + failure = 0 + success -= 1 Hysteresis 1 + Be prepared for overshoot + if (concurrency > concurrency limit) + concurrency = concurrency limit + +Safety: + Don't apply positive feedback unless + concurrency < busy_refcount + init_dest_concurrency + otherwise negative feedback effect could be delayed + +After failure: + if (concurrency > 0) + fail_cohorts += 1.0 / concurrency + if (fail_cohorts > cohort_failure_limit) + concurrency = 0 + if (concurrency > 0) + Be prepared for feedback > hysteresis, rounding errors + failure -= f(concurrency) + while (failure < 0) + concurrency -= 1 Hysteresis 1 + failure += 1 Hysteresis 1 + success = 0 + Be prepared for overshoot + if (concurrency < 1) + concurrency = 1 +</pre> + +<h3> <a name="concurrency_results"> Results for delivery to concurrency-limited servers </a> </h3> + +<p> Discussions about the concurrency scheduler redesign started +early 2004, when the primary goal was to find alternatives that did +not exhibit exponential growth or rapid concurrency throttling. No +code was implemented until late 2007, when the primary concern had +shifted towards better handling of server concurrency limits. For +this reason we measure how well the new scheduler does this +job. The table below compares mail delivery performance of the old ++/-1 feedback per delivery with several less-than-1 feedback +functions, for different limited-concurrency server scenarios. +Measurements were done with a FreeBSD 6.2 client and with FreeBSD +6.2 and various Linux servers. </p> + +<p> Server configuration: </p> + +<ul> <li> The mail flow was slowed down with 1 second latency per +recipient ("smtpd_client_restrictions = sleep 1"). The purpose was +to make results less dependent on hardware details, by avoiding +slow-downs by queue file I/O, logging I/O, and network I/O. + +<li> Concurrency was limited by the server process limit +("default_process_limit = 5" and "smtpd_client_event_limit_exceptions += static:all"). Postfix was stopped and started after changing the +process limit, because the same number is also used as the backlog +argument to the listen(2) system call, and "postfix reload" does +not re-issue this call. + +<li> Mail was discarded with "local_recipient_maps = static:all" and +"local_transport = discard". The discard action in access maps or +header/body checks +could not be used as it fails to update the in_flow_delay counters. + +</ul> + +<p> Client configuration: </p> + +<ul> + +<li> Queue file overhead was minimized by sending one message to a +virtual alias that expanded into 2000 different remote recipients. +All recipients were accounted for according to the maillog file. +The virtual_alias_expansion_limit setting was increased to avoid +complaints from the cleanup(8) server. + +<li> The number of deliveries was maximized with +"smtp_destination_recipient_limit = 2". A smaller limit would cause +Postfix to schedule the concurrency per recipient instead of domain, +which is not what we want. + +<li> Maximum concurrency was limited with +"smtp_destination_concurrency_limit = 20", and +initial_destination_concurrency was set to the same value. + +<li> The positive and negative concurrency feedback hysteresis was +1. Concurrency was incremented by 1 at the END of 1/feedback steps +of positive feedback, and was decremented by 1 at the START of +1/feedback steps of negative feedback. + +<li> The SMTP client used the default 30s SMTP connect timeout and +300s SMTP greeting timeout. + +</ul> + +<h4> Impact of the 30s SMTP connect timeout </h4> + +<p> The first results are for a FreeBSD 6.2 server, where our +artificially low listen(2) backlog results in a very short kernel +queue for established connections. The table shows that all deferred +deliveries failed due to a 30s connection timeout, and none failed +due to a server greeting timeout. This measurement simulates what +happens when the server's connection queue is completely full under +load, and the TCP engine drops new connections. </p> + +<blockquote> + +<table> + +<tr> <th>client<br> limit</th> <th>server<br> limit</th> <th>feedback<br> +style</th> <th>connection<br> caching</th> <th>percentage<br> +deferred</th> <th colspan="2">client concurrency<br> average/stddev</th> +<th colspan=2>timed-out in<br> connect/greeting </th> </tr> + +<tr> <td align="center" colspan="9"> <hr> </td> </tr> + +<tr><td align="center">20</td> <td align="center">5</td> <td +align="center">1/N</td> <td align="center">no</td> <td +align="center">9.9</td> <td align="center">19.4</td> <td +align="center">0.49</td> <td align="center">198</td> <td +align="center">-</td> </tr> + +<tr><td align="center">20</td> <td align="center">5</td> <td +align="center">1/N</td> <td align="center">yes</td> <td +align="center">10.3</td> <td align="center">19.4</td> <td +align="center">0.49</td> <td align="center">206</td> <td +align="center">-</td> </tr> + +<tr><td align="center">20</td> <td align="center">5</td> <td +align="center">1/sqrt(N)</td> <td align="center">no</td> +<td align="center">10.4</td> <td align="center">19.6</td> <td +align="center">0.59</td> <td align="center">208</td> <td +align="center">-</td> </tr> + +<tr><td align="center">20</td> <td align="center">5</td> <td +align="center">1/sqrt(N)</td> <td align="center">yes</td> +<td align="center">10.6</td> <td align="center">19.6</td> <td +align="center">0.61</td> <td align="center">212</td> <td +align="center">-</td> </tr> + +<tr><td align="center">20</td> <td align="center">5</td> <td +align="center">1</td> <td align="center">no</td> <td +align="center">10.1</td> <td align="center">19.5</td> <td +align="center">1.29</td> <td align="center">202</td> <td +align="center">-</td> </tr> + +<tr><td align="center">20</td> <td align="center">5</td> <td +align="center">1</td> <td align="center">yes</td> <td +align="center">10.8</td> <td align="center">19.3</td> <td +align="center">1.57</td> <td align="center">216</td> <td +align="center">-</td> </tr> + +<tr> <td align="center" colspan="9"> <hr> </td> </tr> + +</table> + +<p> A busy server with a completely full connection queue. N is +the client delivery concurrency. Failed deliveries time out after +30s without completing the TCP handshake. See text for a discussion +of results. </p> + +</blockquote> + +<h4> Impact of the 300s SMTP greeting timeout </h4> + +<p> The next table shows results for a Fedora Core 8 server (results +for RedHat 7.3 are identical). In this case, the artificially small +listen(2) backlog argument does not impact our measurement. The +table shows that practically all deferred deliveries fail after the +300s SMTP greeting timeout. As these timeouts were 10x longer than +with the first measurement, we increased the recipient count (and +thus the running time) by a factor of 10 to keep the results +comparable. The deferred mail percentages are a factor 10 lower +than with the first measurement, because the 1s per-recipient delay +was 1/300th of the greeting timeout instead of 1/30th of the +connection timeout. </p> + +<blockquote> + +<table> + +<tr> <th>client<br> limit</th> <th>server<br> limit</th> <th>feedback<br> +style</th> <th>connection<br> caching</th> <th>percentage<br> +deferred</th> <th colspan="2">client concurrency<br> average/stddev</th> +<th colspan=2>timed-out in<br> connect/greeting </th> </tr> + +<tr> <td align="center" colspan="9"> <hr> </td> </tr> + +<tr> <td align="center">20</td> <td align="center">5</td> <td +align="center">1/N</td> <td align="center">no</td> <td +align="center">1.16</td> <td align="center">19.8</td> <td +align="center">0.37</td> <td align="center">-</td> <td +align="center">230</td> </tr> + +<tr> <td align="center">20</td> <td align="center">5</td> <td +align="center">1/N</td> <td align="center">yes</td> <td +align="center">1.36</td> <td align="center">19.8</td> <td +align="center">0.36</td> <td align="center">-</td> <td +align="center">272</td> </tr> + +<tr> <td align="center">20</td> <td align="center">5</td> <td +align="center">1/sqrt(N)</td> <td align="center">no</td> +<td align="center">1.21</td> <td align="center">19.9</td> <td +align="center">0.23</td> <td align="center">4</td> <td +align="center">238</td> </tr> + +<tr> <td align="center">20</td> <td align="center">5</td> <td +align="center">1/sqrt(N)</td> <td align="center">yes</td> +<td align="center">1.36</td> <td align="center">20.0</td> <td +align="center">0.23</td> <td align="center">-</td> <td +align="center">272</td> </tr> + +<tr> <td align="center">20</td> <td align="center">5</td> <td +align="center">1</td> <td align="center">no</td> <td +align="center">1.18</td> <td align="center">20.0</td> <td +align="center">0.16</td> <td align="center">-</td> <td +align="center">236</td> </tr> + +<tr> <td align="center">20</td> <td align="center">5</td> <td +align="center">1</td> <td align="center">yes</td> <td +align="center">1.39</td> <td align="center">20.0</td> <td +align="center">0.16</td> <td align="center">-</td> <td +align="center">278</td> </tr> + +<tr> <td align="center" colspan="9"> <hr> </td> </tr> + +</table> + +<p> A busy server with a non-full connection queue. N is the client +delivery concurrency. Failed deliveries complete at the TCP level, +but time out after 300s while waiting for the SMTP greeting. See +text for a discussion of results. </p> + +</blockquote> + +<h4> Impact of active server concurrency limiter </h4> + +<p> The final concurrency-limited result shows what happens when +SMTP connections don't time out, but are rejected immediately with +the Postfix server's smtpd_client_connection_count_limit feature +(the server replies with a 421 status and disconnects immediately). +Similar results can be expected with concurrency limiting features +built into other MTAs or firewalls. For this measurement we specified +a server concurrency limit and a client initial destination concurrency +of 5, and a server process limit of 10; all other conditions were +the same as with the first measurement. The same result would be +obtained with a FreeBSD or Linux server, because the "pushing back" +is done entirely by the receiving side. </p> + +<blockquote> + +<table> + +<tr> <th>client<br> limit</th> <th>server<br> limit</th> <th>feedback<br> +style</th> <th>connection<br> caching</th> <th>percentage<br> +deferred</th> <th colspan="2">client concurrency<br> average/stddev</th> +<th>theoretical<br>defer rate</th> </tr> + +<tr> <td align="center" colspan="9"> <hr> </td> </tr> + +<tr> <td align="center">20</td> <td align="center">5</td> <td +align="center">1/N</td> <td align="center">no</td> <td +align="center">16.5</td> <td align="center">5.17</td> <td +align="center">0.38</td> <td align="center">1/6</td> </tr> + +<tr> <td align="center">20</td> <td align="center">5</td> <td +align="center">1/N</td> <td align="center">yes</td> <td +align="center">16.5</td> <td align="center">5.17</td> <td +align="center">0.38</td> <td align="center">1/6</td> </tr> + +<tr> <td align="center">20</td> <td align="center">5</td> <td +align="center">1/sqrt(N)</td> <td align="center">no</td> +<td align="center">24.5</td> <td align="center">5.28</td> <td +align="center">0.45</td> <td align="center">1/4</td> </tr> + +<tr> <td align="center">20</td> <td align="center">5</td> <td +align="center">1/sqrt(N)</td> <td align="center">yes</td> +<td align="center">24.3</td> <td align="center">5.28</td> <td +align="center">0.46</td> <td align="center">1/4</td> </tr> + +<tr> <td align="center">20</td> <td align="center">5</td> <td +align="center">1</td> <td align="center">no</td> <td +align="center">49.7</td> <td align="center">5.63</td> <td +align="center">0.67</td> <td align="center">1/2</td> </tr> + +<tr> <td align="center">20</td> <td align="center">5</td> <td +align="center">1</td> <td align="center">yes</td> <td +align="center">49.7</td> <td align="center">5.68</td> <td +align="center">0.70</td> <td align="center">1/2</td> </tr> + +<tr> <td align="center" colspan="9"> <hr> </td> </tr> + +</table> + +<p> A server with active per-client concurrency limiter that replies +with 421 and disconnects. N is the client delivery concurrency. +The theoretical defer rate is 1/(1+roundup(1/feedback)). This is +always 1/2 with the fixed +/-1 feedback per delivery; with the +concurrency-dependent feedback variants, the defer rate decreases +with increasing concurrency. See text for a discussion of results. +</p> + +</blockquote> + +<h3> <a name="concurrency_discussion"> Discussion of concurrency-limited server results </a> </h3> + +<p> All results in the previous sections are based on the first +delivery runs only; they do not include any second etc. delivery +attempts. It's also worth noting that the measurements look at +steady-state behavior only. They don't show what happens when the +client starts sending at a much higher or lower concurrency. +</p> + +<p> The first two examples show that the effect of feedback +is negligible when concurrency is limited due to congestion. This +is because the initial concurrency is already at the client's +concurrency maximum, and because there is 10-100 times more positive +than negative feedback. Under these conditions, it is no surprise +that the contribution from SMTP connection caching is also negligible. +</p> + +<p> In the last example, the old +/-1 feedback per delivery will +defer 50% of the mail when confronted with an active (anvil-style) +server concurrency limit, where the server hangs up immediately +with a 421 status (a TCP-level RST would have the same result). +Less aggressive feedback mechanisms fare better than more aggressive +ones. Concurrency-dependent feedback fares even better at higher +concurrencies than shown here, but has limitations as discussed in +the next section. </p> + +<h3> <a name="concurrency_limitations"> Limitations of less-than-1 per delivery feedback </a> </h3> + +<p> Less-than-1 feedback is of interest primarily when sending large +amounts of mail to destinations with active concurrency limiters +(servers that reply with 421, or firewalls that send RST). When +sending small amounts of mail per destination, less-than-1 per-delivery +feedback won't have a noticeable effect on the per-destination +concurrency, because the number of deliveries to the same destination +is too small. You might just as well use zero per-delivery feedback +and stay with the initial per-destination concurrency. And when +mail deliveries fail due to congestion instead of active concurrency +limiters, the measurements above show that per-delivery feedback +has no effect. With large amounts of mail you might just as well +use zero per-delivery feedback and start with the maximal per-destination +concurrency. </p> + +<p> The scheduler with less-than-1 concurrency +feedback per delivery solves a problem with servers that have active +concurrency limiters. This works only because feedback is handled +in a peculiar manner: positive feedback will increment the concurrency +by 1 at the <b>end</b> of a sequence of events of length 1/feedback, +while negative feedback will decrement concurrency by 1 at the +<b>beginning</b> of such a sequence. This is how Postfix adjusts +quickly for overshoot without causing lots of mail to be deferred. +Without this difference in feedback treatment, less-than-1 feedback +per delivery would defer 50% of the mail, and would be no better +in this respect than the old +/-1 feedback per delivery. </p> + +<p> Unfortunately, the same feature that corrects quickly for +concurrency overshoot also makes the scheduler more sensitive for +noisy negative feedback. The reason is that one lonely negative +feedback event has the same effect as a complete sequence of length +1/feedback: in both cases delivery concurrency is dropped by 1 +immediately. As a worst-case scenario, consider multiple servers +behind a load balancer on a single IP address, and no backup MX +address. When 1 out of K servers fails to complete the SMTP handshake +or drops the connection, a scheduler with 1/N (N = concurrency) +feedback stops increasing its concurrency once it reaches a concurrency +level of about K, even though the good servers behind the load +balancer are perfectly capable of handling more traffic. </p> + +<p> This noise problem gets worse as the amount of positive feedback +per delivery gets smaller. A compromise is to use fixed less-than-1 +positive feedback values instead of concurrency-dependent positive +feedback. For example, to tolerate 1 of 4 bad servers in the above +load balancer scenario, use positive feedback of 1/4 per "good" +delivery (no connect or handshake error), and use an equal or smaller +amount of negative feedback per "bad" delivery. The downside of +using concurrency-independent feedback is that some of the old +/-1 +feedback problems will return at large concurrencies. Sites that +must deliver mail at non-trivial per-destination concurrencies will +require special configuration. </p> + +<h3> <a name="concurrency_config"> Concurrency configuration parameters </a> </h3> + +<p> The Postfix 2.5 concurrency scheduler is controlled with the +following configuration parameters, where "<i>transport</i>_foo" +provides a transport-specific parameter override. All parameter +default settings are compatible with earlier Postfix versions. </p> + +<blockquote> + +<table border="0"> + +<tr> <th> Parameter name </th> <th> Postfix version </th> <th> +Description </th> </tr> + +<tr> <td colspan="3"> <hr> </td> </tr> + +<tr> <td> initial_destination_concurrency<br> +<i>transport</i>_initial_destination_concurrency </td> <td +align="center"> all<br> 2.5 </td> <td> Initial per-destination +delivery concurrency </td> </tr> + +<tr> <td> default_destination_concurrency_limit<br> +<i>transport</i>_destination_concurrency_limit </td> <td align="center"> +all<br> all </td> <td> Maximum per-destination delivery concurrency +</td> </tr> + +<tr> <td> default_destination_concurrency_positive_feedback<br> +<i>transport</i>_destination_concurrency_positive_feedback </td> +<td align="center"> 2.5<br> 2.5 </td> <td> Per-destination positive +feedback amount, per delivery that does not fail with connection +or handshake failure </td> </tr> + +<tr> <td> default_destination_concurrency_negative_feedback<br> +<i>transport</i>_destination_concurrency_negative_feedback </td> +<td align="center"> 2.5<br> 2.5 </td> <td> Per-destination negative +feedback amount, per delivery that fails with connection or handshake +failure </td> </tr> + +<tr> <td> default_destination_concurrency_failed_cohort_limit<br> +<i>transport</i>_destination_concurrency_failed_cohort_limit </td> +<td align="center"> 2.5<br> 2.5 </td> <td> Number of failed +pseudo-cohorts after which a destination is declared "dead" and +delivery is suspended </td> </tr> + +<tr> <td> destination_concurrency_feedback_debug</td> <td align="center"> +2.5 </td> <td> Enable verbose logging of concurrency scheduler +activity </td> </tr> + +<tr> <td colspan="3"> <hr> </td> </tr> + +</table> + +</blockquote> + +<h2> <a name="jobs"> Preemptive scheduling </a> </h2> + +<p> + +The following sections describe the new queue manager and its +preemptive scheduler algorithm. Note that the document was originally +written to describe the changes between the new queue manager (in +this text referred to as <tt>nqmgr</tt>, the name it was known by +before it became the default queue manager) and the old queue manager +(referred to as <tt>oqmgr</tt>). This is why it refers to <tt>oqmgr</tt> +every so often. + +</p> + +<p> + +This document is divided into sections as follows: + +</p> + +<ul> + +<li> <a href="#<tt>nqmgr</tt>_structures"> The structures used by +nqmgr </a> + +<li> <a href="#<tt>nqmgr</tt>_pickup"> What happens when nqmgr picks +up the message </a> - how it is assigned to transports, jobs, peers, +entries + +<li> <a href="#<tt>nqmgr</tt>_selection"> How the entry selection +works </a> + +<li> <a href="#<tt>nqmgr</tt>_preemption"> How the preemption +works </a> - what messages may be preempted and how and what messages +are chosen to preempt them + +<li> <a href="#<tt>nqmgr</tt>_concurrency"> How destination concurrency +limits affect the scheduling algorithm </a> + +<li> <a href="#<tt>nqmgr</tt>_memory"> Dealing with memory resource +limits </a> + +</ul> + +<h3> <a name="<tt>nqmgr</tt>_structures"> The structures used by +nqmgr </a> </h3> + +<p> + +Let's start by recapitulating the structures and terms used when +referring to the queue manager and how it operates. Many of these are +partially described elsewhere, but it is nice to have a coherent +overview in one place: + +</p> + +<ul> + +<li> <p> Each message structure represents one mail message which +Postfix is to deliver. The message recipients specify to what +destinations is the message to be delivered and what transports are +going to be used for the delivery. </p> + +<li> <p> Each recipient entry groups a batch of recipients of one +message which are all going to be delivered to the same destination +(and over the same transport). +</p> + +<li> <p> Each transport structure groups everything what is going +to be delivered by delivery agents dedicated for that transport. +Each transport maintains a set of queues (describing the destinations +it shall talk to) and jobs (referencing the messages it shall +deliver). </p> + +<li> <p> Each transport queue (not to be confused with the on-disk +"active" queue or "incoming" queue) groups everything what is going be +delivered to given destination (aka nexthop) by its transport. Each +queue belongs to one transport, so each destination may be referred +to by several queues, one for each transport. Each queue maintains +a list of all recipient entries (batches of message recipients) +which shall be delivered to given destination (the todo list), and +a list of recipient entries already being delivered by the delivery +agents (the busy list). </p> + +<li> <p> Each queue corresponds to multiple peer structures. Each +peer structure is like the queue structure, belonging to one transport +and referencing one destination. The difference is that it lists +only the recipient entries which all originate from the same message, +unlike the queue structure, whose entries may originate from various +messages. For messages with few recipients, there is usually just +one recipient entry for each destination, resulting in one recipient +entry per peer. But for large mailing list messages the recipients +may need to be split to multiple recipient entries, in which case +the peer structure may list many entries for single destination. +</p> + +<li> <p> Each transport job groups everything it takes to deliver +one message via its transport. Each job represents one message +within the context of the transport. The job belongs to one transport +and message, so each message may have multiple jobs, one for each +transport. The job groups all the peer structures, which describe +the destinations the job's message has to be delivered to. </p> + +</ul> + +<p> + +The first four structures are common to both <tt>nqmgr</tt> and +<tt>oqmgr</tt>, the latter two were introduced by <tt>nqmgr</tt>. + +</p> + +<p> + +These terms are used extensively in the text below, feel free to +look up the description above anytime you'll feel you have lost a +sense what is what. + +</p> + +<h3> <a name="<tt>nqmgr</tt>_pickup"> What happens when nqmgr picks +up the message </a> </h3> + +<p> + +Whenever <tt>nqmgr</tt> moves a queue file into the "active" queue, +the following happens: It reads all necessary information from the +queue file as <tt>oqmgr</tt> does, and also reads as many recipients +as possible - more on that later, for now let's just pretend it +always reads all recipients. + +</p> + +<p> + +Then it resolves the recipients as <tt>oqmgr</tt> does, which +means obtaining (address, nexthop, transport) triple for each +recipient. For each triple, it finds the transport; if it does not +exist yet, it instantiates it (unless it's dead). Within the +transport, it finds the destination queue for the given nexthop; if it +does not exist yet, it instantiates it (unless it's dead). The +triple is then bound to given destination queue. This happens in +qmgr_resolve() and is basically the same as in <tt>oqmgr</tt>. + +</p> + +<p> + +Then for each triple which was bound to some queue (and thus +transport), the program finds the job which represents the message +within that transport's context; if it does not exist yet, it +instantiates it. Within the job, it finds the peer which represents +the bound destination queue within this jobs context; if it does +not exist yet, it instantiates it. Finally, it stores the address +from the resolved triple to the recipient entry which is appended +to both the queue entry list and the peer entry list. The addresses +for the same nexthop are batched in the entries up to the +<i>transport</i>_destination_recipient_limit for that transport. +This happens in qmgr_message_assign(), and apart +from that it operates with job and peer structures, it is basically the +same as in <tt>oqmgr</tt>. + +</p> + +<p> + +When the job is instantiated, it is enqueued on the transport's job +list based on the time its message was picked up by <tt>nqmgr</tt>. +For first batch of recipients this means it is appended to the end +of the job list, but the ordering of the job list by the enqueue +time is important as we will see shortly. + +</p> + +<p> + +[Now you should have a pretty good idea what the state of the +<tt>nqmgr</tt> is after a couple of messages were picked up, and what the +relation is between all those job, peer, queue and entry structures.] + +</p> + +<h3> <a name="<tt>nqmgr</tt>_selection"> How the entry selection +works </a> </h3> + +<p> + +Having prepared all those above mentioned structures, the task of +the <tt>nqmgr</tt>'s scheduler is to choose the recipient entries +one at a time and pass them to the delivery agent for corresponding +transport. Now how does this work? + +</p> + +<p> + +The first approximation of the new scheduling algorithm is like this: + +</p> + +<blockquote> +<pre> +foreach transport (round-robin-by-transport) +do + if transport busy continue + if transport process limit reached continue + foreach transport's job (in the order of the transport's job list) + do + foreach job's peer (round-robin-by-destination) + if peer->queue->concurrency < peer->queue->window + return next peer entry. + done + done +done +</pre> +</blockquote> + +<p> + +Now what is the "order of the transport's job list"? As we know +already, the job list is by default kept in the order the message +was picked up by the <tt>nqmgr</tt>. So by default we get the +top-level round-robin transport, and within each transport we get +the FIFO message delivery. The round-robin of the peers by the +destination is perhaps of little importance in most real-life cases +(unless the <i>transport</i>_destination_recipient_limit is reached, +in one job there +is only one peer structure for each destination), but theoretically +it makes sure that even within single jobs, destinations are treated +fairly. + +</p> + +<p> + +[By now you should have a feeling you really know how the scheduler +works, except for the preemption, under ideal conditions - that is, +no recipient resource limits and no destination concurrency problems.] + +</p> + +<h3> <a name="<tt>nqmgr</tt>_preemption"> How the preemption +works </a> </h3> + +<p> + +As you might perhaps expect by now, the transport's job list does +not remain sorted by the job's message enqueue time all the time. +The most cool thing about <tt>nqmgr</tt> is not the simple FIFO +delivery, but that it is able to slip mail with little recipients +past the mailing-list bulk mail. This is what the job preemption +is about - shuffling the jobs on the transport's job list to get +the best message delivery rates. Now how is it achieved? + +</p> + +<p> + +First I have to tell you that there are in fact two job lists in +each transport. One is the scheduler's job list, which the scheduler +is free to play with, while the other one keeps the jobs always +listed in the order of the enqueue time and is used for recipient +pool management we will discuss later. For now, we will deal with +the scheduler's job list only. + +</p> + +<p> + +So, we have the job list, which is first ordered by the time the +jobs' messages were enqueued, oldest messages first, the most recently +picked one at the end. For now, let's assume that there are no +destination concurrency problems. Without preemption, we pick some +entry of the first (oldest) job on the queue, assign it to delivery +agent, pick another one from the same job, assign it again, and so +on, until all the entries are used and the job is delivered. We +would then move onto the next job and so on and on. Now how do we +manage to sneak in some entries from the recently added jobs when +the first job on the job list belongs to a message going to the +mailing-list and has thousands of recipient entries? + +</p> + +<p> + +The <tt>nqmgr</tt>'s answer is that we can artificially "inflate" +the delivery time of that first job by some constant for free - it +is basically the same trick you might remember as "accumulation of +potential" from the amortized complexity lessons. For example, +instead of delivering the entries of the first job on the job list +every time a delivery agent becomes available, we can do it only +every second time. If you view the moments the delivery agent becomes +available on a timeline as "delivery slots", then instead of using +every delivery slot for the first job, we can use only every other +slot, and still the overall delivery efficiency of the first job +remains the same. So the delivery <tt>11112222</tt> becomes +<tt>1.1.1.1.2.2.2.2</tt> (1 and 2 are the imaginary job numbers, . +denotes the free slot). Now what do we do with free slots? + +</p> + +<p> + +As you might have guessed, we will use them for sneaking the mail +with little recipients in. For example, if we have one four-recipient +mail followed by four one recipients mail, the delivery sequence +(that is, the sequence in which the jobs are assigned to the +delivery slots) might look like this: <tt>12131415</tt>. Hmm, fine +for sneaking in the single recipient mail, but how do we sneak in +the mail with more than one recipient? Say if we have one four-recipient +mail followed by two two-recipient mails? + +</p> + +<p> + +The simple answer would be to use delivery sequence <tt>12121313</tt>. +But the problem is that this does not scale well. Imagine you have +mail with a thousand recipients followed by mail with a hundred recipients. +It is tempting to suggest the delivery sequence like <tt>121212....</tt>, +but alas! Imagine there arrives another mail with say ten recipients. +But there are no free slots anymore, so it can't slip by, not even +if it had only one recipient. It will be stuck until the +hundred-recipient mail is delivered, which really sucks. + +</p> + +<p> + +So, it becomes obvious that while inflating the message to get +free slots is a great idea, one has to be really careful of how the +free slots are assigned, otherwise one might corner himself. So, +how does <tt>nqmgr</tt> really use the free slots? + +</p> + +<p> + +The key idea is that one does not have to generate the free slots +in a uniform way. The delivery sequence <tt>111...1</tt> is no +worse than <tt>1.1.1.1</tt>, in fact, it is even better as some +entries are in the first case selected earlier than in the second +case, and none is selected later! So it is possible to first +"accumulate" the free delivery slots and then use them all at once. +It is even possible to accumulate some, then use them, then accumulate +some more and use them again, as in <tt>11..1.1</tt> . + +</p> + +<p> + +Let's get back to the one hundred recipient example. We now know +that we could first accumulate one hundred free slots, and only +after then to preempt the first job and sneak the one hundred +recipient mail in. Applying the algorithm recursively, we see the +hundred recipient job can accumulate ten free delivery slots, and +then we could preempt it and sneak in the ten-recipient mail... +Wait wait wait! Could we? Aren't we overinflating the original one +thousand recipient mail? + +</p> + +<p> + +Well, despite the fact that it looks so at the first glance, another trick will +allow us to answer "no, we are not!". If we had said that we will +inflate the delivery time twice at maximum, and then we consider +every other slot as a free slot, then we would overinflate in case +of the recursive preemption. BUT! The trick is that if we use only +every n-th slot as a free slot for n>2, there is always some worst +inflation factor which we can guarantee not to be breached, even +if we apply the algorithm recursively. To be precise, if for every +k>1 normally used slots we accumulate one free delivery slot, than +the inflation factor is not worse than k/(k-1) no matter how many +recursive preemptions happen. And it's not worse than (k+1)/k if +only non-recursive preemption happens. Now, having got through the +theory and the related math, let's see how <tt>nqmgr</tt> implements +this. + +</p> + +<p> + +Each job has so called "available delivery slot" counter. Each +transport has a <i>transport</i>_delivery_slot_cost parameter, which +defaults to default_delivery_slot_cost parameter which is set to 5 +by default. This is the k from the paragraph above. Each time k +entries of the job are selected for delivery, this counter is +incremented by one. Once there are some slots accumulated, a job which +requires no more than that number of slots to be fully delivered +can preempt this job. + +</p> + +<p> + +[Well, the truth is, the counter is incremented every time an entry +is selected and it is divided by k when it is used. +But to understand, it's good enough to use +the above approximation of the truth.] + +</p> + +<p> + +OK, so now we know the conditions which must be satisfied so one +job can preempt another one. But what job gets preempted, how do +we choose what job preempts it if there are several valid candidates, +and when does all this exactly happen? + +</p> + +<p> + +The answer for the first part is simple. The job whose entry was +selected the last time is the so called current job. Normally, it is +the first job on the scheduler's job list, but destination concurrency +limits may change this as we will see later. It is always only the +current job which may get preempted. + +</p> + +<p> + +Now for the second part. The current job has a certain amount of +recipient entries, and as such may accumulate at maximum some amount +of available delivery slots. It might have already accumulated some, +and perhaps even already used some when it was preempted before +(remember a job can be preempted several times). In either case, +we know how many are accumulated and how many are left to deliver, +so we know how many it may yet accumulate at maximum. Every other +job which may be delivered by less than that number of slots is a +valid candidate for preemption. How do we choose among them? + +</p> + +<p> + +The answer is - the one with maximum enqueue_time/recipient_entry_count. +That is, the older the job is, the more we should try to deliver +it in order to get best message delivery rates. These rates are of +course subject to how many recipients the message has, therefore +the division by the recipient (entry) count. No one shall be surprised +that a message with n recipients takes n times longer to deliver than +a message with one recipient. + +</p> + +<p> + +Now let's recap the previous two paragraphs. Isn't it too complicated? +Why don't the candidates come only among the jobs which can be +delivered within the number of slots the current job already +accumulated? Why do we need to estimate how much it has yet to +accumulate? If you found out the answer, congratulate yourself. If +we did it this simple way, we would always choose the candidate +with the fewest recipient entries. If there were enough single recipient +mails coming in, they would always slip by the bulk mail as soon +as possible, and the two or more recipients mail would never get +a chance, no matter how long they have been sitting around in the +job list. + +</p> + +<p> + +This candidate selection has an interesting implication - that when +we choose the best candidate for preemption (this is done in +qmgr_choose_candidate()), it may happen that we may not use it for +preemption immediately. This leads to an answer to the last part +of the original question - when does the preemption happen? + +</p> + +<p> + +The preemption attempt happens every time next transport's recipient +entry is to be chosen for delivery. To avoid needless overhead, the +preemption is not attempted if the current job could never accumulate +more than <i>transport</i>_minimum_delivery_slots (defaults to +default_minimum_delivery_slots which defaults to 3). If there are +already enough accumulated slots to preempt the current job by the +chosen best candidate, it is done immediately. This basically means +that the candidate is moved in front of the current job on the +scheduler's job list and decreasing the accumulated slot counter +by the amount used by the candidate. If there are not enough slots... +well, I could say that nothing happens and the another preemption +is attempted the next time. But that's not the complete truth. + +</p> + +<p> + +The truth is that it turns out that it is not really necessary to +wait until the jobs counter accumulates all the delivery slots in +advance. Say we have ten-recipient mail followed by two two-recipient +mails. If the preemption happened when enough delivery slots accumulate +(assuming slot cost 2), the delivery sequence becomes +<tt>11112211113311</tt>. Now what would we get if we would wait +only for 50% of the necessary slots to accumulate and we promise +we would wait for the remaining 50% later, after we get back +to the preempted job? If we use such a slot loan, the delivery sequence +becomes <tt>11221111331111</tt>. As we can see, it makes it not +considerably worse for the delivery of the ten-recipient mail, but +it allows the small messages to be delivered sooner. + +</p> + +<p> + +The concept of these slot loans is where the +<i>transport</i>_delivery_slot_discount and +<i>transport</i>_delivery_slot_loan come from (they default to +default_delivery_slot_discount and default_delivery_slot_loan, whose +values are by default 50 and 3, respectively). The discount (resp. +loan) specifies how many percent (resp. how many slots) one "gets +in advance", when the number of slots required to deliver the best +candidate is compared with the number of slots the current slot had +accumulated so far. + +</p> + +<p> + +And that pretty much concludes this chapter. + +</p> + +<p> + +[Now you should have a feeling that you pretty much understand the +scheduler and the preemption, or at least that you will have +after you read the last chapter a couple more times. You shall clearly +see the job list and the preemption happening at its head, in ideal +delivery conditions. The feeling of understanding shall last until +you start wondering what happens if some of the jobs are blocked, +which you might eventually figure out correctly from what had been +said already. But I would be surprised if your mental image of the +scheduler's functionality is not completely shattered once you +start wondering how it works when not all recipients may be read +in-core. More on that later.] + +</p> + +<h3> <a name="<tt>nqmgr</tt>_concurrency"> How destination concurrency +limits affect the scheduling algorithm </a> </h3> + +<p> + +The <tt>nqmgr</tt> uses the same algorithm for destination concurrency +control as <tt>oqmgr</tt>. Now what happens when the destination +limits are reached and no more entries for that destination may be +selected by the scheduler? + +</p> + +<p> + +From the user's point of view it is all simple. If some of the peers +of a job can't be selected, those peers are simply skipped by the +entry selection algorithm (the pseudo-code described before) and +only the selectable ones are used. If none of the peers may be +selected, the job is declared a "blocker job". Blocker jobs are +skipped by the entry selection algorithm and they are also excluded +from the candidates for preemption of the current job. Thus the scheduler +effectively behaves as if the blocker jobs didn't exist on the job +list at all. As soon as at least one of the peers of a blocker job +becomes unblocked (that is, the delivery agent handling the delivery +of the recipient entry for the given destination successfully finishes), +the job's blocker status is removed and the job again participates +in all further scheduler actions normally. + +</p> + +<p> + +So the summary is that the users don't really have to be concerned +about the interaction of the destination limits and scheduling +algorithm. It works well on its own and there are no knobs they +would need to control it. + +</p> + +<p> + +From a programmer's point of view, the blocker jobs complicate the +scheduler quite a lot. Without them, the jobs on the job list would +be normally delivered in strict FIFO order. If the current job is +preempted, the job preempting it is completely delivered unless it +is preempted itself. Without blockers, the current job is thus +always either the first job on the job list, or the top of the stack +of jobs preempting the first job on the job list. + +</p> + +<p> + +The visualization of the job list and the preemption stack without +blockers would be like this: + +</p> + +<blockquote> +<pre> +first job-> 1--2--3--5--6--8--... <- job list +on job list | + 4 <- preemption stack + | +current job-> 7 +</pre> +</blockquote> + +<p> + +In the example above we see that job 1 was preempted by job 4 and +then job 4 was preempted by job 7. After job 7 is completed, remaining +entries of job 4 are selected, and once they are all selected, job +1 continues. + +</p> + +<p> + +As we see, it's all very clean and straightforward. Now how does +this change because of blockers? + +</p> + +<p> + +The answer is: a lot. Any job may become a blocker job at any time, +and also become a normal job again at any time. This has several +important implications: + +</p> + +<ol> + +<li> <p> + +The jobs may be completed in arbitrary order. For example, in the +example above, if the current job 7 becomes blocked, the next job +4 may complete before the job 7 becomes unblocked again. Or if both +7 and 4 are blocked, then 1 is completed, then 7 becomes unblocked +and is completed, then 2 is completed and only after that 4 becomes +unblocked and is completed... You get the idea. + +</p> + +<p> + +[Interesting side note: even when jobs are delivered out of order, +from a single destination's point of view the jobs are still delivered +in the expected order (that is, FIFO unless there was some preemption +involved). This is because whenever a destination queue becomes +unblocked (the destination limit allows selection of more recipient +entries for that destination), all jobs which have peers for that +destination are unblocked at once.] + +</p> + +<li> <p> + +The idea of the preemption stack at the head of the job list is +gone. That is, it must be possible to preempt any job on the job +list. For example, if the jobs 7, 4, 1 and 2 in the example above +become all blocked, job 3 becomes the current job. And of course +we do not want the preemption to be affected by the fact that there +are some blocked jobs or not. Therefore, if it turns out that job +3 might be preempted by job 6, the implementation shall make it +possible. + +</p> + +<li> <p> + +The idea of the linear preemption stack itself is gone. It's no +longer true that one job is always preempted by only one job at one +time (that is directly preempted, not counting the recursively +nested jobs). For example, in the example above, job 1 is directly +preempted by only job 4, and job 4 by job 7. Now assume job 7 becomes +blocked, and job 4 is being delivered. If it accumulates enough +delivery slots, it is natural that it might be preempted for example +by job 8. Now job 4 is preempted by both job 7 AND job 8 at the +same time. + +</p> + +</ol> + +<p> + +Now combine the points 2) and 3) with point 1) again and you realize +that the relations on the once linear job list became pretty +complicated. If we extend the point 3) example: jobs 7 and 8 preempt +job 4, now job 8 becomes blocked too, then job 4 completes. Tricky, +huh? + +</p> + +<p> + +If I illustrate the relations after the above mentioned examples +(but those in point 1), the situation would look like this: + +</p> + +<blockquote> +<pre> + v- parent + +adoptive parent -> 1--2--3--5--... <- "stack" level 0 + | | +parent gone -> ? 6 <- "stack" level 1 + / \ +children -> 7 8 ^- child <- "stack" level 2 + + ^- siblings +</pre> +</blockquote> + +<p> + +Now how does <tt>nqmgr</tt> deal with all these complicated relations? + +</p> + +<p> + +Well, it maintains them all as described, but fortunately, all these +relations are necessary only for the purpose of proper counting of +available delivery slots. For the purpose of ordering the jobs for +entry selection, the original rule still applies: "the job preempting +the current job is moved in front of the current job on the job +list". So for entry selection purposes, the job relations remain +as simple as this: + +</p> + +<blockquote> +<pre> +7--8--1--2--6--3--5--.. <- scheduler's job list order +</pre> +</blockquote> + +<p> + +The job list order and the preemption parent/child/siblings relations +are maintained separately. And because the selection works only +with the job list, you can happily forget about those complicated +relations unless you want to study the <tt>nqmgr</tt> sources. In +that case the text above might provide some helpful introduction +to the problem domain. Otherwise I suggest you just forget about +all this and stick with the user's point of view: the blocker jobs +are simply ignored. + +</p> + +<p> + +[By now, you should have a feeling that there are more things going +on under the hood than you ever wanted to know. You decide that +forgetting about this chapter is the best you can do for the sake +of your mind's health and you basically stick with the idea how the +scheduler works in ideal conditions, when there are no blockers, +which is good enough.] + +</p> + +<h3> <a name="<tt>nqmgr</tt>_memory"> Dealing with memory resource +limits </a> </h3> + +<p> + +When discussing the <tt>nqmgr</tt> scheduler, we have so far assumed +that all recipients of all messages in the "active" queue are completely +read into memory. This is simply not true. There is an upper +bound on the amount of memory the <tt>nqmgr</tt> may use, and +therefore it must impose some limits on the information it may store +in memory at any given time. + +</p> + +<p> + +First of all, not all messages may be read in-core at once. At any +time, only qmgr_message_active_limit messages may be read in-core +at maximum. When read into memory, the messages are picked from the +"incoming" and "deferred" queues and moved to the "active" queue +(incoming having priority), so if there are more than +qmgr_message_active_limit messages queued in the "active" queue, the +rest will have to wait until (some of) the messages in the "active" queue +are completely delivered (or deferred). + +</p> + +<p> + +Even with the limited amount of in-core messages, there is another +limit which must be imposed in order to avoid memory exhaustion. +Each message may contain a huge number of recipients (tens or hundreds +of thousands are not uncommon), so if <tt>nqmgr</tt> read all +recipients of all messages in the "active" queue, it may easily run +out of memory. Therefore there must be some upper bound on the +amount of message recipients which are read into memory at the +same time. + +</p> + +<p> + +Before discussing how exactly <tt>nqmgr</tt> implements the recipient +limits, let's see how the sole existence of the limits themselves +affects the <tt>nqmgr</tt> and its scheduler. + +</p> + +<p> + +The message limit is straightforward - it just limits the size of +the +lookahead the <tt>nqmgr</tt>'s scheduler has when choosing which +message can preempt the current one. Messages not in the "active" queue +are simply not considered at all. + +</p> + +<p> + +The recipient limit complicates more things. First of all, the +message reading code must support reading the recipients in batches, +which among other things means accessing the queue file several +times and continuing where the last recipient batch ended. This is +invoked by the scheduler whenever the current job has space for more +recipients, subject to transport's refill_limit and refill_delay parameters. +It is also done any time when all +in-core recipients of the message are dealt with (which may also +mean they were deferred) but there are still more in the queue file. + +</p> + +<p> + +The second complication is that with some recipients left unread +in the queue file, the scheduler can't operate with exact counts +of recipient entries. With unread recipients, it is not clear how +many recipient entries there will be, as they are subject to +per-destination grouping. It is not even clear to what transports +(and thus jobs) the recipients will be assigned. And with messages +coming from the "deferred" queue, it is not even clear how many unread +recipients are still to be delivered. This all means that the +scheduler must use only estimates of how many recipients entries +there will be. Fortunately, it is possible to estimate the minimum +and maximum correctly, so the scheduler can always err on the safe +side. Obviously, the better the estimates, the better the results, so +it is best when we are able to read all recipients in-core and turn +the estimates into exact counts, or at least try to read as many +as possible to make the estimates as accurate as possible. + +</p> + +<p> + +The third complication is that it is no longer true that the scheduler +is done with a job once all of its in-core recipients are delivered. +It is possible that the job will be revived later, when another +batch of recipients is read in core. It is also possible that some +jobs will be created for the first time long after the first batch +of recipients was read in core. The <tt>nqmgr</tt> code must be +ready to handle all such situations. + +</p> + +<p> + +And finally, the fourth complication is that the <tt>nqmgr</tt> +code must somehow impose the recipient limit itself. Now how does +it achieve it? + +</p> + +<p> + +Perhaps the easiest solution would be to say that each message may +have at maximum X recipients stored in-core, but such a solution would +be poor for several reasons. With reasonable qmgr_message_active_limit +values, the X would have to be quite low to maintain a reasonable +memory footprint. And with low X lots of things would not work well. +The <tt>nqmgr</tt> would have problems to use the +<i>transport</i>_destination_recipient_limit efficiently. The +scheduler's preemption would be suboptimal as the recipient count +estimates would be inaccurate. The message queue file would have +to be accessed many times to read in more recipients again and +again. + +</p> + +<p> + +Therefore it seems reasonable to have a solution which does not use +a limit imposed on a per-message basis, but which maintains a pool +of available recipient slots, which can be shared among all messages +in the most efficient manner. And as we do not want separate +transports to compete for resources whenever possible, it seems +appropriate to maintain such a recipient pool for each transport +separately. This is the general idea, now how does it work in +practice? + +</p> + +<p> + +First we have to solve a little chicken-and-egg problem. If we want +to use the per-transport recipient pools, we first need to know to +what transport(s) the message is assigned. But we will find that +out only after we first read in the recipients. So it is obvious +that we first have to read in some recipients, use them to find out +to what transports the message is to be assigned, and only after +that can we use the per-transport recipient pools. + +</p> + +<p> + +Now how many recipients shall we read for the first time? This is +what qmgr_message_recipient_minimum and qmgr_message_recipient_limit +values control. The qmgr_message_recipient_minimum value specifies +how many recipients of each message we will read the first time, +no matter what. It is necessary to read at least one recipient +before we can assign the message to a transport and create the first +job. However, reading only qmgr_message_recipient_minimum recipients +even if there are only few messages with few recipients in-core would +be wasteful. Therefore if there are fewer than qmgr_message_recipient_limit +recipients in-core so far, the first batch of recipients may be +larger than qmgr_message_recipient_minimum - as large as is required +to reach the qmgr_message_recipient_limit limit. + +</p> + +<p> + +Once the first batch of recipients was read in core and the message +jobs were created, the size of the subsequent recipient batches (if +any - of course it's best when all recipients are read in one batch) +is based solely on the position of the message jobs on their +corresponding transports' job lists. Each transport has a pool of +<i>transport</i>_recipient_limit recipient slots which it can +distribute among its jobs (how this is done is described later). +The subsequent recipient batch may be as large as the sum of all +recipient slots of all jobs of the message permits (plus the +qmgr_message_recipient_minimum amount which always applies). + +</p> + +<p> + +For example, if a message has three jobs, the first with 1 recipient +still in-core and 4 recipient slots, the second with 5 recipients in-core +and 5 recipient slots, and the third with 2 recipients in-core and 0 +recipient slots, it has 1+5+2=8 recipients in-core and 4+5+0=9 jobs' +recipients slots in total. This means that we could immediately +read 2+qmgr_message_recipient_minimum more recipients of that message +in core. + +</p> + +<p> + +The above example illustrates several things which might be worth +mentioning explicitly: first, note that although the per-transport +slots are assigned to particular jobs, we can't guarantee that once +the next batch of recipients is read in core, that the corresponding +amounts of recipients will be assigned to those jobs. The jobs lend +its slots to the message as a whole, so it is possible that some +jobs end up sponsoring other jobs of their message. For example, +if in the example above the 2 newly read recipients were assigned +to the second job, the first job sponsored the second job with 2 +slots. The second notable thing is the third job, which has more +recipients in-core than it has slots. Apart from sponsoring by other +job we just saw it can be result of the first recipient batch, which +is sponsored from global recipient pool of qmgr_message_recipient_limit +recipients. It can be also sponsored from the message recipient +pool of qmgr_message_recipient_minimum recipients. + +</p> + +<p> + +Now how does each transport distribute the recipient slots among +its jobs? The strategy is quite simple. As most scheduler activity +happens on the head of the job list, it is our intention to make +sure that the scheduler has the best estimates of the recipient +counts for those jobs. As we mentioned above, this means that we +want to try to make sure that the messages of those jobs have all +recipients read in-core. Therefore the transport distributes the +slots "along" the job list from start to end. In this case the job +list sorted by message enqueue time is used, because it doesn't +change over time as the scheduler's job list does. + +</p> + +<p> + +More specifically, each time a job is created and appended to the +job list, it gets all unused recipient slots from its transport's +pool. It keeps them until all recipients of its message are read. +When this happens, all unused recipient slots are transferred to +the next job (which is now in fact the first such job) on the job +list which still has some recipients unread, or eventually back to +the transport pool if there is no such job. Such a transfer then also +happens whenever a recipient entry of that job is delivered. + +</p> + +<p> + +There is also a scenario when a job is not appended to the end of +the job list (for example it was created as a result of a second or +later recipient batch). Then it works exactly as above, except that +if it was put in front of the first unread job (that is, the job +of a message which still has some unread recipients in the queue file), +that job is first forced to return all of its unused recipient slots +to the transport pool. + +</p> + +<p> + +The algorithm just described leads to the following state: The first +unread job on the job list always gets all the remaining recipient +slots of that transport (if there are any). The jobs queued before +this job are completely read (that is, all recipients of their +message were already read in core) and have at maximum as many slots +as they still have recipients in-core (the maximum is there because +of the sponsoring mentioned before) and the jobs after this job get +nothing from the transport recipient pool (unless they got something +before and then the first unread job was created and enqueued in +front of them later - in such a case, they also get at maximum as many +slots as they have recipients in-core). + +</p> + +<p> + +Things work fine in such a state for most of the time, because the +current job is either completely read in-core or has as many recipient +slots as there are, but there is one situation which we still have +to take care of specially. Imagine if the current job is preempted +by some unread job from the job list and there are no more recipient +slots available, so this new current job could read only batches +of qmgr_message_recipient_minimum recipients at a time. This would +really degrade performance. For this reason, each transport has an +extra pool of <i>transport</i>_extra_recipient_limit recipient +slots, dedicated exactly for this situation. Each time an unread +job preempts the current job, it gets half of the remaining recipient +slots from the normal pool and this extra pool. + +</p> + +<p> + +And that's it. It sure does sound pretty complicated, but fortunately +most people don't really have to care exactly how it works as long +as it works. Perhaps the only important things to know for most +people are the following upper bound formulas: + +</p> + +<p> + +Each transport has at maximum + +</p> + +<blockquote> +<pre> +max( +qmgr_message_recipient_minimum * qmgr_message_active_limit ++ *_recipient_limit + *_extra_recipient_limit, +qmgr_message_recipient_limit +) +</pre> +</blockquote> + +<p> + +recipients in core. + +</p> + +<p> + +The total amount of recipients in core is + +</p> + +<blockquote> +<pre> +max( +qmgr_message_recipient_minimum * qmgr_message_active_limit ++ sum( *_recipient_limit + *_extra_recipient_limit ), +qmgr_message_recipient_limit +) +</pre> +</blockquote> + +<p> + +where the sum is over all used transports. + +</p> + +<p> + +And this terribly complicated chapter concludes the documentation +of the <tt>nqmgr</tt> scheduler. + +</p> + +<p> + +[By now you should theoretically know the <tt>nqmgr</tt> scheduler +inside out. In practice, you still hope that you will never have +to really understand the last or last two chapters completely, and +fortunately most people really won't. Understanding how the scheduler +works in ideal conditions is more than good enough for the vast majority +of users.] + +</p> + +<h2> <a name="credits"> Credits </a> </h2> + +<ul> + +<li> Wietse Venema designed and implemented the initial queue manager +with per-domain FIFO scheduling, and per-delivery +/-1 concurrency +feedback. + +<li> Patrik Rak designed and implemented preemption where mail with +fewer recipients can slip past mail with more recipients in a +controlled manner, and wrote up its documentation. + +<li> Wietse Venema initiated a discussion with Patrik Rak and Victor +Duchovni on alternatives for the +/-1 feedback scheduler's aggressive +behavior. This is when K/N feedback was reviewed (N = concurrency). +The discussion ended without a good solution for both negative +feedback and dead site detection. + +<li> Victor Duchovni resumed work on concurrency feedback in the +context of concurrency-limited servers. + +<li> Wietse Venema then re-designed the concurrency scheduler in +terms of the simplest possible concepts: less-than-1 concurrency +feedback per delivery, forward and reverse concurrency feedback +hysteresis, and pseudo-cohort failure. At this same time, concurrency +feedback was separated from dead site detection. + +<li> These simplifications, and their modular implementation, helped +to develop further insights into the different roles that positive +and negative concurrency feedback play, and helped to identify some +worst-case scenarios. + +</ul> + +</body> + +</html> diff --git a/proto/SMTPD_ACCESS_README.html b/proto/SMTPD_ACCESS_README.html new file mode 100644 index 0000000..ce38bc8 --- /dev/null +++ b/proto/SMTPD_ACCESS_README.html @@ -0,0 +1,439 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix SMTP relay and access control </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +SMTP relay and access control </h1> + +<hr> + +<h2> Introduction </h2> + +<p> The Postfix SMTP server receives mail from the network and is +exposed to the big bad world of junk email and viruses. This document +introduces the built-in and external methods that control what SMTP +mail Postfix will accept, what mistakes to avoid, and how to test +your configuration. </p> + +<p> Topics covered in this document: </p> + +<ul> + +<li> <a href="#relay"> Relay control, junk mail control, and per-user +policies </a> + +<li> <a href="#global"> Restrictions that apply to all SMTP mail +</a> + +<li> <a href="#lists"> Getting selective with SMTP access restriction +lists </a> + +<li> <a href="#timing"> Delayed evaluation of SMTP access restriction lists </a> + +<li> <a href="#danger"> Dangerous use of smtpd_recipient_restrictions +</a> + +<li> <a href="#testing"> SMTP access rule testing </a> + +</ul> + +<h2> <a name="relay"> Relay control, junk mail control, and per-user +policies </a> </h2> + +<p> In a distant past, the Internet was a friendly environment. +Mail servers happily forwarded mail on behalf of anyone towards +any destination. On today's Internet, spammers abuse servers that +forward mail from arbitrary systems, and abused systems end up on +anti-spammer denylists. See, for example, the information on +http://www.mail-abuse.org/ and other websites. </p> + +<p> By default, Postfix has a moderately restrictive approach to +mail relaying. Postfix forwards mail only from clients in trusted +networks, from clients that have authenticated with SASL, or to +domains that are configured as authorized relay +destinations. For a description of the default mail relay policy, +see the smtpd_relay_restrictions parameter in the postconf(5) manual +page, and the information that is referenced from there. </p> + +<blockquote> <p> NOTE: Postfix versions before 2.10 did not have +smtpd_relay_restrictions. They combined the mail relay and spam +blocking policies, under smtpd_recipient_restrictions. This could +lead to unexpected results. For example, a permissive spam blocking +policy could unexpectedly result in a permissive mail relay policy. +An example of this is documented under "<a href="#danger">Dangerous +use of smtpd_recipient_restrictions</a>". </p> </blockquote> + +<p> Most of the Postfix SMTP server access controls are targeted +at stopping junk email. </p> + +<ul> + +<li> <p> Protocol oriented: some SMTP server access controls block +mail by being very strict with respect to the SMTP protocol; these +catch poorly implemented and/or poorly configured junk email +software, as well as email worms that come with their own non-standard +SMTP client implementations. Protocol-oriented access controls +become less useful over time as spammers and worm writers learn to +read RFC documents. </p> + +<li> <p> Denylist oriented: some SMTP server access controls +query denylists with known to be bad sites such as open mail +relays, open web proxies, and home computers that have been +compromised and that are under remote control by criminals. The +effectiveness of these denylists depends on how complete and how +up to date they are. </p> + +<li> <p> Threshold oriented: some SMTP server access controls attempt +to raise the bar by either making the client do more work (greylisting) +or by asking for a second opinion (SPF and sender/recipient address +verification). The greylisting and SPF policies are implemented +externally, and are the subject of the SMTPD_POLICY_README document. +Sender/recipient address verification is the subject of the +ADDRESS_VERIFICATION_README document. </p> + +</ul> + +<p> Unfortunately, all junk mail controls have the possibility of +falsely rejecting legitimate mail. This can be a problem for sites +with many different types of users. For some users it is unacceptable +when any junk email slips through, while for other users the world +comes to an end when a single legitimate email message is blocked. +Because there is no single policy that is "right" for all users, +Postfix supports different SMTP access restrictions for different +users. This is described in the RESTRICTION_CLASS_README document. +</p> + +<h2> <a name="global"> Restrictions that apply to all SMTP mail </a> </h2> + +<p> Besides the restrictions that can be made configurable per +client or per user as described in the next section, Postfix +implements a few restrictions that apply to all SMTP mail. </p> + +<ul> + +<li> <p> The built-in header_checks and body_checks content +restrictions, as described in the BUILTIN_FILTER_README document. +This happens while Postfix receives mail, before it is stored in +the incoming queue. </p> + +<li> <p> The external before-queue content restrictions, as described +in the SMTPD_PROXY_README document. This happens while Postfix +receives mail, before it is stored in the incoming queue. </p> + +<li> <p> Requiring that the client sends the HELO or EHLO command +before sending the MAIL FROM or ETRN command. This may cause problems +with home-grown applications that send mail. For this reason, the +requirement is disabled by default ("smtpd_helo_required = no"). +</p> + +<li> <p> Disallowing illegal syntax in MAIL FROM or RCPT TO commands. +This may cause problems with home-grown applications that send +mail, and with ancient PC mail clients. For this reason, the +requirement is disabled by default ("strict_rfc821_envelopes = +no"). </p> + +<ul> + +<li> <p> Disallowing RFC 822 address syntax (example: "MAIL FROM: the +dude <dude@example.com>"). </p> + +<li> <p> Disallowing addresses that are not enclosed with <> +(example: "MAIL FROM: dude@example.com"). </p> + +</ul> + +<li> <p> Rejecting mail from a non-existent sender address. This form +of egress filtering helps to slow down worms and other malware, but +may cause problems with home-grown software that sends out mail +software with an unreplyable address. For this reason the requirement +is disabled by default ("smtpd_reject_unlisted_sender = no"). </p> + +<li> <p> Rejecting mail for a non-existent recipient address. This +form of ingress filtering helps to keep the mail queue free of +undeliverable MAILER-DAEMON messages. This requirement is enabled +by default ("smtpd_reject_unlisted_recipient = yes"). </p> + +</ul> + +<h2> <a name="lists"> Getting selective with SMTP access restriction +lists </a> </h2> + +<p> Postfix allows you to specify lists of access restrictions for +each stage of the SMTP conversation. Individual restrictions are +described in the postconf(5) manual page. </p> + +<p> Examples of simple restriction lists are: </p> + +<pre> +/etc/postfix/main.cf: + # Allow connections from trusted networks only. + smtpd_client_restrictions = permit_mynetworks, reject + + # Don't talk to mail systems that don't know their own hostname. + # With Postfix < 2.3, specify reject_unknown_hostname. + smtpd_helo_restrictions = reject_unknown_helo_hostname + + # Don't accept mail from domains that don't exist. + smtpd_sender_restrictions = reject_unknown_sender_domain + + # Spam control: exclude local clients and authenticated clients + # from DNSBL lookups. + smtpd_recipient_restrictions = permit_mynetworks, + permit_sasl_authenticated, + # reject_unauth_destination is not needed here if the mail + # relay policy is specified under smtpd_relay_restrictions + # (available with Postfix 2.10 and later). + reject_unauth_destination + reject_rbl_client zen.spamhaus.org, + reject_rhsbl_reverse_client dbl.spamhaus.org, + reject_rhsbl_helo dbl.spamhaus.org, + reject_rhsbl_sender dbl.spamhaus.org + + # Relay control (Postfix 2.10 and later): local clients and + # authenticated clients may specify any destination domain. + smtpd_relay_restrictions = permit_mynetworks, + permit_sasl_authenticated, + reject_unauth_destination + + # Block clients that speak too early. + smtpd_data_restrictions = reject_unauth_pipelining + + # Enforce mail volume quota via policy service callouts. + smtpd_end_of_data_restrictions = check_policy_service unix:private/policy +</pre> + +<p> Each restriction list is evaluated from left to right until +some restriction produces a result of PERMIT, REJECT or DEFER (try +again later). The end of each list is equivalent to a PERMIT result. +By placing a PERMIT restriction before a REJECT restriction you +can make exceptions for specific clients or users. This is called +allowlisting; the smtpd_relay_restrictions example above allows mail from local +networks, and from SASL authenticated clients, but otherwise rejects mail +to arbitrary destinations. </p> + +<p> The table below summarizes the purpose of each SMTP access +restriction list. All lists use the exact same syntax; they differ +only in the time of evaluation and in the effect of a REJECT or +DEFER result. </p> + +<blockquote> + +<table border="1"> + +<tr> <th> Restriction list name </th> <th> Version </th> <th> Status +</th> <th> Effect +of REJECT or DEFER result </th> </tr> + +<tr> <td> smtpd_client_restrictions </td> <td> All </td> <td> +Optional </td> <td> +Reject all client commands </td> </tr> + +<tr> <td> smtpd_helo_restrictions </td> <td> All </td> <td> Optional +</td> <td> +Reject HELO/EHLO information </td> </tr> + +<tr> <td> smtpd_sender_restrictions </td> <td> All </td> <td> +Optional </td> <td> +Reject MAIL FROM information </td> </tr> + +<tr> <td rowspan="2"> smtpd_recipient_restrictions </td> <td> ≥ +2.10 </td> <td> Required if smtpd_relay_restrictions does not enforce +relay policy</td> +<td rowspan="2"> Reject RCPT TO information </td> </tr> + +<tr> <td> < 2.10</td> <td> Required </td> </tr> + +<tr> <td rowspan="2"> smtpd_relay_restrictions </td> <td> ≥ 2.10 +</td> <td> Required if smtpd_recipient_restrictions does not enforce +relay policy</td> +<td rowspan="2"> Reject RCPT TO information </td> </tr> + +<tr> <td> < 2.10</td> <td> Not available </td> +</tr> + +<tr> <td> smtpd_data_restrictions </td> <td> ≥ 2.0 </td> <td> +Optional </td> <td> +Reject DATA command </td> </tr> + +<tr> <td> smtpd_end_of_data_restrictions </td> <td> ≥ 2.2 </td> +<td> Optional </td> <td> +Reject END-OF-DATA command </td> </tr> + +<tr> <td> smtpd_etrn_restrictions </td> <td> All </td> <td> Optional +</td> <td> +Reject ETRN command </td> </tr> + +</table> + +</blockquote> + +<h2> <a name="timing"> Delayed evaluation of SMTP access restriction lists +</a> </h2> + +<p> Early Postfix versions evaluated SMTP access restrictions lists +as early as possible. The client restriction list was evaluated +before Postfix sent the "220 $myhostname..." greeting banner to +the SMTP client, the helo restriction list was evaluated before +Postfix replied to the HELO (EHLO) command, the sender restriction +list was evaluated before Postfix replied to the MAIL FROM command, +and so on. This approach turned out to be difficult to use. </p> + +<p> Current Postfix versions postpone the evaluation of client, +helo and sender restriction lists until the RCPT TO or ETRN command. +This behavior is controlled by the smtpd_delay_reject parameter. +Restriction lists are still evaluated in the proper order of (client, +helo, etrn) or (client, helo, sender, relay, recipient, data, or +end-of-data) restrictions. +When a restriction list (example: client) evaluates to REJECT or +DEFER the restriction lists that follow (example: helo, sender, etc.) +are skipped. </p> + +<p> Around the time that smtpd_delay_reject was introduced, Postfix +was also changed to support mixed restriction lists that combine +information about the client, helo, sender and recipient or etrn +command. </p> + +<p> Benefits of delayed restriction evaluation, and of restriction +mixing: </p> + +<ul> + +<li> <p> Some SMTP clients do not expect a negative reply early in +the SMTP session. When the bad news is postponed until the RCPT TO +reply, the client goes away as it is supposed to, instead of hanging +around until a timeout happens, or worse, going into an endless +connect-reject-connect loop. </p> + +<li> <p> Postfix can log more useful information. For example, when +Postfix rejects a client name or address and delays the action +until the RCPT TO command, it can log the sender and the recipient +address. This is more useful than logging only the client hostname +and IP address and not knowing whose mail was being blocked. </p> + +<li> <p> Mixing is needed for complex allowlisting policies. For +example, in order to reject local sender addresses in mail from +non-local clients, you need to be able to mix restrictions on client +information with restrictions on sender information in the same +restriction list. Without this ability, many per-user access +restrictions would be impossible to express. </p> + +</ul> + +<h2> <a name="danger"> Dangerous use of smtpd_recipient_restrictions </a> </h2> + +<p> By now the reader may wonder why we need smtpd client, helo +or sender restrictions, when their evaluation is postponed until +the RCPT TO or ETRN command. Some people recommend placing ALL the +access restrictions in the smtpd_recipient_restrictions list. +Unfortunately, this can result in too permissive access. How is +this possible? </p> + +<p> The purpose of the smtpd_recipient_restrictions feature is to +control how Postfix replies to the RCPT TO command. If the restriction +list evaluates to REJECT or DEFER, the recipient address is rejected; +no surprises here. If the result is PERMIT, then the recipient +address is accepted. And this is where surprises can happen. </p> + +<p> The problem is that Postfix versions before 2.10 did not have +smtpd_relay_restrictions. They combined the mail relay and spam +blocking policies, under smtpd_recipient_restrictions. The result +is that a permissive spam blocking policy could unexpectedly result +in a permissive mail relay policy. </p> + +<p> Here is an example that shows when a PERMIT result can result +in too much access permission: </p> + +<pre> +1 /etc/postfix/main.cf: +2 smtpd_recipient_restrictions = +3 permit_mynetworks +4 check_helo_access hash:/etc/postfix/helo_access +5 reject_unknown_helo_hostname +6 <b>reject_unauth_destination</b> +7 +8 /etc/postfix/helo_access: +9 localhost.localdomain PERMIT +</pre> + +<p> Line 5 rejects mail from hosts that don't specify a proper +hostname in the HELO command (with Postfix < 2.3, specify +reject_unknown_hostname). Lines 4 and 9 make an exception to +allow mail from some machine that announces itself with "HELO +localhost.localdomain". </p> + +<p> The problem with this configuration is that +smtpd_recipient_restrictions evaluates to PERMIT for EVERY host +that announces itself as "localhost.localdomain", making Postfix +an open relay for all such hosts. </p> + +<p> With Postfix before version 2.10 you should place non-recipient +restrictions AFTER the reject_unauth_destination restriction, not +before. In the above example, the HELO based restrictions should +be placed AFTER reject_unauth_destination, or better, the HELO +based restrictions should be placed under smtpd_helo_restrictions +where they can do no harm. </p> + +<pre> +1 /etc/postfix/main.cf: +2 smtpd_recipient_restrictions = +3 permit_mynetworks +4 <b>reject_unauth_destination</b> +5 check_helo_access hash:/etc/postfix/helo_access +6 reject_unknown_helo_hostname +7 +8 /etc/postfix/helo_access: +9 localhost.localdomain PERMIT +</pre> + +<p> The above mistake will not happen with Postfix 2.10 and later, +when the relay policy is specified under smtpd_relay_restrictions, +and the spam blocking policy under smtpd_recipient_restrictions. +Then, a permissive spam blocking policy will not result in a +permissive mail relay policy. </p> + +<h2> <a name="testing"> SMTP access rule testing </a> </h2> + +<p> Postfix has several features that aid in SMTP access rule +testing: </p> + +<dl> + +<dt> soft_bounce </dt> <dd> <p> This is a safety net that changes +SMTP server REJECT actions into DEFER (try again later) actions. +This keeps mail queued that would otherwise be returned to the +sender. Specify "soft_bounce = yes" in the main.cf file to prevent +the Postfix SMTP server from rejecting mail permanently, by changing +all 5xx SMTP reply codes into 4xx. </p> </dd> + +<dt> warn_if_reject </dt> <dd> <p> When placed before a reject-type +restriction, access table query, or check_policy_service query, +this logs a "reject_warning" message instead of rejecting a request +(when a reject-type restriction fails due to a temporary error, +this logs a "reject_warning" message for any implicit "defer_if_permit" +actions that would normally prevent mail from being accepted by +some later access restriction). This feature has no effect on +defer_if_reject restrictions. </p> </dd> + +<dt> XCLIENT </dt> <dd> <p> With this feature, an authorized SMTP +client can impersonate other systems and perform realistic SMTP +access rule tests. Examples of how to impersonate other systems +for access rule testing are given at the end of the XCLIENT_README +document. <br> This feature is available in Postfix 2.1. </p> +</dd> + +</dl> + +</body> + +</html> diff --git a/proto/SMTPD_POLICY_README.html b/proto/SMTPD_POLICY_README.html new file mode 100644 index 0000000..b8df76e --- /dev/null +++ b/proto/SMTPD_POLICY_README.html @@ -0,0 +1,811 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix SMTP Access Policy Delegation </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix SMTP Access Policy Delegation </h1> + +<hr> + +<h2>Purpose of Postfix SMTP access policy delegation</h2> + +<p> The Postfix SMTP server has a number of built-in mechanisms to +block or accept mail at specific SMTP protocol stages. In addition, +the Postfix SMTP server can delegate decisions to an external policy +server (Postfix 2.1 and later). </p> + +<p> With this policy delegation mechanism, a simple +<a href="#greylist">greylist</a> policy can be implemented with only a dozen lines of +Perl, as is shown at the end of this document. A complete example +can be found in the Postfix source code, in the directory +examples/smtpd-policy. </p> + +<p> Another example of policy delegation is the SPF policy server +at https://web.archive.org/web/20190221142057/http://www.openspf.org/Software. </p> + +<p> Policy delegation is now the preferred method for adding policies +to Postfix. It's much easier to develop a new feature in few lines +of Perl, Python, Ruby, or TCL, than trying to do the same in C code. +The difference in +performance will be unnoticeable except in the most demanding +environments. On active systems a policy daemon process is used +multiple times, for up to $max_use incoming SMTP connections. </p> + +<p> This document covers the following topics: </p> + +<ul> + +<li><a href="#protocol">Policy protocol description</a> + +<li><a href="#client_config">Simple policy client/server configuration</a> + +<li><a href="#advanced">Advanced policy client configuration</a> + +<li><a href="#greylist">Example: greylist policy server</a> + +<li><a href="#frequent">Greylisting mail from frequently forged domains</a> + +<li><a href="#all_mail">Greylisting all your mail</a> + +<li><a href="#maintenance">Routine greylist maintenance</a> + +<li><a href="#greylist_code">Example Perl greylist server</a> + +</ul> + +<h2><a name="protocol">Protocol description</a></h2> + +<p> The Postfix policy delegation protocol is really simple. The client +sends a request and the server sends a response. Unless there was an +error, the server must not close the connection, so that the same +connection can be used multiple times. </p> + +<p> The client request is a sequence of name=value attributes separated +by newline, and is terminated by an empty line. The server reply is one +name=value attribute and it, too, is terminated by an empty line. </p> + +<p> Here is an example of all the attributes that the Postfix SMTP +server sends in a delegated SMTPD access policy request: </p> + +<blockquote> +<pre> +<b>Postfix version 2.1 and later:</b> +request=smtpd_access_policy +protocol_state=RCPT +protocol_name=SMTP +helo_name=some.domain.tld +queue_id=8045F2AB23 +sender=foo@bar.tld +recipient=bar@foo.tld +recipient_count=0 +client_address=1.2.3.4 +client_name=another.domain.tld +reverse_client_name=another.domain.tld +instance=123.456.7 +<b>Postfix version 2.2 and later:</b> +sasl_method=plain +sasl_username=you +sasl_sender= +size=12345 +ccert_subject=solaris9.porcupine.org +ccert_issuer=Wietse+20Venema +ccert_fingerprint=C2:9D:F4:87:71:73:73:D9:18:E7:C2:F3:C1:DA:6E:04 +<b>Postfix version 2.3 and later:</b> +encryption_protocol=TLSv1/SSLv3 +encryption_cipher=DHE-RSA-AES256-SHA +encryption_keysize=256 +etrn_domain= +<b>Postfix version 2.5 and later:</b> +stress= +<b>Postfix version 2.9 and later:</b> +ccert_pubkey_fingerprint=68:B3:29:DA:98:93:E3:40:99:C7:D8:AD:5C:B9:C9:40 +<b>Postfix version 3.0 and later:</b> +client_port=1234 +<b>Postfix version 3.1 and later:</b> +policy_context=submission +<b>Postfix version 3.2 and later:</b> +server_address=10.3.2.1 +server_port=54321 +[empty line] +</pre> +</blockquote> + +<p> Notes: </p> + +<ul> + + <li> <p> The "request" attribute is required. In this example + the request type is "smtpd_access_policy". </p> + + <li> <p> The order of the attributes does not matter. The policy + server should ignore any attributes that it does not care about. + </p> + + <li> <p> When the same attribute name is sent more than once, + the server may keep the first value or the last attribute value. + </p> + + <li> <p> When an attribute value is unavailable, the client + either does not send the attribute, sends the attribute with + an empty value ("name="), or sends a zero value ("name=0") in + the case of a numerical attribute. </p> + + <li> <p> The "recipient" attribute is available in the "RCPT + TO" stage. It is also available in the "DATA" and "END-OF-MESSAGE" + stages if Postfix accepted only one recipient for the current + message. + The DATA protocol state also applies to email that is received + with BDAT commands (Postfix 3.4 and later). </p> + + <li> <p> The "recipient_count" attribute (Postfix 2.3 and later) + is non-zero only in the "DATA" and "END-OF-MESSAGE" stages. It + specifies the number of recipients that Postfix accepted for + the current message. + The DATA protocol state also applies to email that is received + with BDAT commands (Postfix 3.4 and later). </p> + + <li> <p> The remote client or local server IP address is an + IPv4 dotted quad in the form 1.2.3.4 or it is an IPv6 address + in the form 1:2:3::4:5:6. </p> + + <li> <p> The remote client or local server port is a decimal + number in the range 0-65535. </p> + + <li> <p> For a discussion of the differences between reverse + and verified client_name information, see the + reject_unknown_client_hostname discussion in the postconf(5) + document. </p> + + <li> <p> An attribute name must not contain "=", null or newline, + and an attribute value must not contain null or newline. </p> + + <li> <p> The "instance" attribute value can be used to correlate + different requests regarding the same message delivery. These + requests are sent over the same policy connection (unless the + policy daemon terminates the connection). Once Postfix sends + a query with a different instance attribute over that same + policy connection, the previous message delivery is either + completed or aborted. </p> + + <li> <p> The "size" attribute value specifies the message size + that the client specified in the MAIL FROM command (zero if + none was specified). With Postfix 2.2 and later, it specifies + the actual message size after the client sends the END-OF-MESSAGE. + </p> + + <li> <p> The "sasl_*" attributes (Postfix 2.2 and later) specify + information about how the client was authenticated via SASL. + These attributes are empty in case of no SASL authentication. + </p> + + <li> <p> The "ccert_*" attributes (Postfix 2.2 and later) specify + information about how the client was authenticated via TLS. + These attributes are empty in case of no certificate authentication. + As of Postfix 2.2.11 these attribute values are encoded as + xtext: some characters are represented by +XX, where XX is the + two-digit hexadecimal representation of the character value. With + Postfix 2.6 and later, the decoded string is an UTF-8 string + without non-printable ASCII characters. </p> + + <li> <p> The "encryption_*" attributes (Postfix 2.3 and later) + specify information about how the connection is encrypted. With + plaintext connections the protocol and cipher attributes are + empty and the keysize is zero. </p> + + <li> <p> The "etrn_domain" attribute is defined only in the + context of the ETRN command, and specifies the ETRN command + parameter. </p> + + <li> <p> The "stress" attribute is either empty or "yes". See + the STRESS_README document for further information. </p> + + <li> <p> The "policy_context" attribute provides a way to pass + information that is not available via other attributes (Postfix + version 3.1 and later). </p> + +</ul> + +<p> The following is specific to SMTPD delegated policy requests: +</p> + +<ul> + + <li> <p> Protocol names are ESMTP or SMTP. </p> + + <li> <p> Protocol states are CONNECT, EHLO, HELO, MAIL, RCPT, + DATA, END-OF-MESSAGE, VRFY or ETRN; these are the SMTP protocol + states where + the Postfix SMTP server makes an OK/REJECT/HOLD/etc. decision. + The DATA protocol state also applies to email that is received + with BDAT commands (Postfix 3.4 and later). + </p> + +</ul> + +<p> The policy server replies with any action that is allowed in a +Postfix SMTPD access(5) table. Example: </p> + +<blockquote> +<pre> +action=defer_if_permit Service temporarily unavailable +[empty line] +</pre> +</blockquote> + +<p> This causes the Postfix SMTP server to reject the request with +a 450 temporary error code and with text "Service temporarily +unavailable", if the Postfix SMTP server finds no reason to reject +the request permanently. </p> + +<p> In case of trouble the policy server must not send a reply. +Instead the server must log a warning and disconnect. Postfix will +retry the request at some later time. </p> + +<h2><a name="client_config">Simple policy client/server configuration</a></h2> + +<p> The Postfix delegated policy client can connect to a TCP socket +or to a UNIX-domain socket. Examples: </p> + +<blockquote> +<pre> +inet:127.0.0.1:9998 +unix:/some/where/policy +unix:private/policy +</pre> +</blockquote> + +<p> The first example specifies that the policy server listens on +a TCP socket at 127.0.0.1 port 9998. The second example specifies +an absolute pathname of a UNIX-domain socket. The third example +specifies a pathname relative to the Postfix queue directory; use +this for policy servers that are spawned by the Postfix master +daemon. On many systems, "local" is a synonym for "unix".</p> + +<p> To create a policy service that listens on a UNIX-domain socket +called "policy", and that runs under control of the Postfix spawn(8) +daemon, you would use something like this: </p> + +<blockquote> +<pre> + 1 /etc/postfix/master.cf: + 2 policy unix - n n - 0 spawn + 3 user=nobody argv=/some/where/policy-server + 4 + 5 /etc/postfix/main.cf: + 6 smtpd_recipient_restrictions = + 7 ... + 8 reject_unauth_destination + 9 check_policy_service unix:private/policy +10 ... +11 policy_time_limit = 3600 +12 # smtpd_policy_service_request_limit = 1 +</pre> +</blockquote> + +<p> NOTES: </p> + +<ul> + +<li> <p> Lines 2-3: this creates the service called "policy" that +listens on a UNIX-domain socket. The service is implemented by the +Postfix spawn(8) daemon, which executes the policy server program +that is specified with the <b>argv</b> attribute, using the privileges +specified with the <b>user</b> attribute. </p> + +<li> <p> Line 2: specify a "0" process limit instead of the default +"-", to avoid "connection refused" and other problems when you +increase the smtpd process limit. </p> + +<li> <p> Line 8: reject_unauth_destination is not needed here if +the mail relay policy is specified with smtpd_relay_restrictions +(available with Postfix 2.10 and later). </p> + +<li> <p> Lines 8, 9: always specify "check_policy_service" AFTER +"reject_unauth_destination" or else your system could become an +open relay. </p> + +<li> <p> Line 11: this increases the time that a policy server +process may run to 3600 seconds. The default time limit of 1000 +seconds is too short; the policy daemon needs to run as long as the +SMTP server process that talks to it. +See the spawn(8) manpage for more information about the +<i>transport</i>_time_limit parameter. </p> + +<blockquote> <p> Note: the "policy_time_limit" parameter will not +show up in "postconf" command output before Postfix version 2.9. +This limitation applies to many parameters whose name is a combination +of a master.cf service name (in the above example, "policy") and a +built-in suffix (in the above example: "_time_limit"). </p> +</blockquote> + +<li> <p> Line 12: specify smtpd_policy_service_request_limit to +avoid error-recovery delays with policy servers that cannot +maintain a persistent connection. </p> + +<li> <p> With Solaris < 9, or Postfix < 2.10 on any Solaris +version, use TCP sockets instead of UNIX-domain sockets: </p> + +</ul> + +<blockquote> +<pre> + 1 /etc/postfix/master.cf: + 2 127.0.0.1:9998 inet n n n - 0 spawn + 3 user=nobody argv=/some/where/policy-server + 4 + 5 /etc/postfix/main.cf: + 6 smtpd_recipient_restrictions = + 7 ... + 8 reject_unauth_destination + 9 check_policy_service inet:127.0.0.1:9998 +10 ... +11 127.0.0.1:9998_time_limit = 3600 +12 # smtpd_policy_service_request_limit = 1 +</pre> +</blockquote> + +<p> Configuration parameters that control the client side of the +policy delegation protocol: </p> + +<ul> + +<li> <p> smtpd_policy_service_default_action (default: 451 4.3.5 +Server configuration problem): The default action when an SMTPD +policy service request fails. Available with Postfix 3.0 and +later. </p> + +<li> <p> smtpd_policy_service_max_idle (default: 300s): The amount +of time before the Postfix SMTP server closes an unused policy +client connection. </p> + +<li> <p> smtpd_policy_service_max_ttl (default: 1000s): The amount +of time before the Postfix SMTP server closes an active policy +client connection. </p> + +<li> <p> smtpd_policy_service_request_limit (default: 0): The maximal +number of requests per policy connection, or zero (no limit). +Available with Postfix 3.0 and later. </p> + +<li> <p> smtpd_policy_service_timeout (default: 100s): The time +limit to connect to, send to or receive from a policy server. </p> + +<li> <p> smtpd_policy_service_try_limit (default: 2): The maximal +number of attempts to send an SMTPD policy service request before +giving up. Available with Postfix 3.0 and later. </p> + +<li> <p> smtpd_policy_service_retry_delay (default: 1s): The delay +between attempts to resend a failed SMTPD policy service request. +Available with Postfix 3.0 and later. </p> + +<li> <p> smtpd_policy_service_policy_context (default: empty): +Optional information that is passed in the "policy_context" attribute +of an SMTPD policy service request (originally, to share the same +SMTPD service endpoint among multiple check_policy_service clients). +Available with Postfix 3.1 and later. </p> + +</ul> + +<p> Configuration parameters that control the server side of the +policy delegation protocol: </p> + +<ul> + +<li> <p> <i>transport</i>_time_limit ($command_time_limit): The +maximal amount of time the policy daemon is allowed to run before +it is terminated. The <i>transport</i> is the service name of the +master.cf entry for the policy daemon service. In the above +examples, the service name is "policy" or "127.0.0.1:9998". </p> + +</ul> + +<h2><a name="advanced">Advanced policy client configuration</a></h2> + +<p> The previous section lists a number of Postfix main.cf parameters +that control time limits and other settings for all policy clients. +This is sufficient for simple configurations. With more complex +configurations it becomes desirable to have different settings per +policy client. This is supported with Postfix 3.0 and later. </p> + +<p> The following example shows a "non-critical" policy service +with a short timeout, and with "DUNNO" as default action when the +service is unvailable. The "DUNNO" action causes Postfix to ignore +the result. </p> + +<blockquote> +<pre> +1 /etc/postfix/main.cf: +2 mua_recipient_restrictions = +3 ... +4 reject_unauth_destination +5 check_policy_service { inet:host:port, +6 timeout=10s, default_action=DUNNO +7 policy_context=submission } +8 ... +</pre> +</blockquote> + +<p> Instead of a server endpoint, we now have a list enclosed in {}. </p> + +<ul> + +<li> <p> Line 5: The first item in the list is the server endpoint. +This supports the exact same "inet" and "unix" syntax as described +earlier. </p> + +<li> <p> Line 6-7: The remainder of the list contains per-client +settings. These settings override global main.cf parameters, +and have the same name as those parameters, without the +"smtpd_policy_service_" prefix. </p> + +</ul> + +<p> Inside the list, syntax is similar to what we already know from +main.cf: items separated by space or comma. There is one difference: +<b>you must enclose a setting in parentheses, as in "{ name = value +}", if you want to have space or comma within a value or around +"="</b>. This comes in handy when different policy servers require +different default actions with different SMTP status codes or text: +</p> + +<blockquote> +<pre> +1 /etc/postfix/main.cf: +2 smtpd_recipient_restrictions = +3 ... +4 reject_unauth_destination +5 check_policy_service { +6 inet:host:port1, +7 { default_action = 451 4.3.5 See http://www.example.com/support1 } +8 } +9 ... +</pre> +</blockquote> + +<h2><a name="greylist">Example: greylist policy server</a></h2> + +<p> Greylisting is a defense against junk email that is described at +http://www.greylisting.org/. The idea was discussed on the +postfix-users mailing list <a +href="http://archives.neohapsis.com/archives/postfix/2002-03/0846.html"> +one year before it was popularized</a>. </p> + +<p> The file examples/smtpd-policy/greylist.pl in the Postfix source +tree implements a simplified greylist policy server. This server +stores a time stamp for every (client, sender, recipient) triple. +By default, mail is not accepted until a time stamp is more than +60 seconds old. This stops junk mail with randomly selected sender +addresses, and mail that is sent through randomly selected open +proxies. It also stops junk mail from spammers that change their +IP address frequently. </p> + +<p> Copy examples/smtpd-policy/greylist.pl to /usr/libexec/postfix +or whatever location is appropriate for your system. </p> + +<p> In the greylist.pl Perl script you need to specify the +location of the greylist database file, and how long mail will +be delayed before it is accepted. The default settings are: +</p> + +<blockquote> +<pre> +$database_name="/var/mta/greylist.db"; +$greylist_delay=60; +</pre> +</blockquote> + +<p> The /var/mta directory (or whatever you choose) should be +writable by "nobody", or by whatever username you configure below +in master.cf for the policy service. </p> + +<p> Example: </p> + +<blockquote> +<pre> +# mkdir /var/mta +# chown nobody /var/mta +</pre> +</blockquote> + +<p> Note: DO NOT create the greylist database in a world-writable +directory such as /tmp or /var/tmp, and DO NOT create the greylist +database in a file system that may run out of space. Postfix can +survive "out of space" conditions with the mail queue and with the +mailbox store, but it cannot survive a corrupted greylist database. +If the file becomes corrupted you may not be able to receive mail +at all until you delete the file by hand. </p> + +<p> The greylist.pl Perl script can be run under control by +the Postfix master daemon. For example, to run the script as user +"nobody", using a UNIX-domain socket that is accessible by Postfix +processes only: </p> + +<blockquote> +<pre> + 1 /etc/postfix/master.cf: + 2 greylist unix - n n - 0 spawn + 3 user=nobody argv=/usr/bin/perl /usr/libexec/postfix/greylist.pl + 4 + 5 /etc/postfix/main.cf: + 6 greylist_time_limit = 3600 + 7 smtpd_recipient_restrictions = + 8 ... + 9 reject_unauth_destination +10 check_policy_service unix:private/greylist +11 ... +12 # smtpd_policy_service_request_limit = 1 +</pre> +</blockquote> + +<p> Notes: </p> + +<ul> + +<li> <p> Lines 2-3: this creates the service called "greylist" that +listens on a UNIX-domain socket. The service is implemented by the +Postfix spawn(8) daemon, which executes the greylist.pl script that +is specified with the <b>argv</b> attribute, using the privileges +specified with the <b>user</b> attribute. </p> + +<li> <p> Line 2: specify a "0" process limit instead of the default +"-", to avoid "connection refused" and other problems when you +increase the smtpd process limit. </p> + +<li> <p> Line 3: Specify "greylist.pl -v" for verbose logging of +each request and reply. </p> + +<li> <p> Line 6: this increases the time that a greylist server +process may run to 3600 seconds. The default time limit of 1000 +seconds is too short; the greylist daemon needs to run as long as the +SMTP server process that talks to it. +See the spawn(8) manpage for more information about the +<i>transport</i>_time_limit parameter. </p> + +<li> <p> Line 9: reject_unauth_destination is not needed here if +the mail relay policy is specified with smtpd_relay_restrictions +(available with Postfix 2.10 and later). </p> + +<blockquote> <p> Note: the "greylist_time_limit" parameter will not +show up in "postconf" command output before Postfix version 2.9. +This limitation applies to many parameters whose name is a combination +of a master.cf service name (in the above example, "greylist") and +a built-in suffix (in the above example: "_time_limit"). </p> +</blockquote> + +<li> <p> Line 12: specify smtpd_policy_service_request_limit to +avoid error-recovery delays with policy servers that cannot +maintain a persistent connection. </p> + +</ul> + +<p> With Solaris < 9, or Postfix < 2.10 on any Solaris +version, use inet: style sockets instead of unix: +style, as detailed in the "<a href="#client_config">Policy +client/server configuration</a>" section above. </p> + +<blockquote> +<pre> + 1 /etc/postfix/master.cf: + 2 127.0.0.1:9998 inet n n n - 0 spawn + 3 user=nobody argv=/usr/bin/perl /usr/libexec/postfix/greylist.pl + 4 + 5 /etc/postfix/main.cf: + 6 127.0.0.1:9998_time_limit = 3600 + 7 smtpd_recipient_restrictions = + 8 ... + 9 reject_unauth_destination +10 check_policy_service inet:127.0.0.1:9998 +11 ... +12 # smtpd_policy_service_request_limit = 1 +</pre> +</blockquote> + +<h2><a name="frequent">Greylisting mail from frequently forged domains</a></h2> + +<p> It is relatively safe to turn on greylisting for specific +domains that often appear in forged email. At some point +in cyberspace/time a list of frequently +forged MAIL FROM domains could be found at +https://web.archive.org/web/20080526153208/http://www.monkeys.com/anti-spam/filtering/sender-domain-validate.in. + +<blockquote> +<pre> + 1 /etc/postfix/main.cf: + 2 smtpd_recipient_restrictions = + 3 reject_unlisted_recipient + 4 ... + 5 reject_unauth_destination + 6 check_sender_access hash:/etc/postfix/sender_access + 7 ... + 8 smtpd_restriction_classes = greylist + 9 greylist = check_policy_service unix:private/greylist +10 +11 /etc/postfix/sender_access: +12 aol.com greylist +13 hotmail.com greylist +14 bigfoot.com greylist +15 ... <i>etcetera</i> ... +</pre> +</blockquote> + +<p> NOTES: </p> + +<ul> + +<li> <p> Line 9: On Solaris < 9, or Postfix < 2.10 on any +Solaris version, use inet: style sockets +instead of unix: style, as detailed in the "<a href="#greylist">Example: +greylist policy server</a>" section above. </p> + +<li> <p> Line 5: reject_unauth_destination is not needed here if +the mail relay policy is specified with smtpd_relay_restrictions +(available with Postfix 2.10 and later). </p> + +<li> <p> Line 6: Be sure to specify "check_sender_access" AFTER +"reject_unauth_destination" or else your system could become an +open mail relay. </p> + +<li> <p> Line 3: With Postfix 2.0 snapshot releases, +"reject_unlisted_recipient" is called "check_recipient_maps". +Postfix 2.1 understands both forms. </p> + +<li> <p> Line 3: The greylist database gets polluted quickly with +bogus addresses. It helps if you protect greylist lookups with +other restrictions that reject unknown senders and/or recipients. +</p> + +</ul> + +<h2><a name="all_mail">Greylisting all your mail</a></h2> + +<p> If you turn on greylisting for all mail you may want to make +exceptions for mailing lists that use one-time sender addresses, +because each message will be delayed due to greylisting, and the +one-time sender addresses can pollute your greylist database +relatively quickly. Instead of making exceptions, you can automatically +allowlist clients that survive greylisting repeatedly; this avoids +most of the delays and most of the database pollution problem. </p> + +<blockquote> +<pre> + 1 /etc/postfix/main.cf: + 2 smtpd_recipient_restrictions = + 3 reject_unlisted_recipient + 4 ... + 5 reject_unauth_destination + 6 check_sender_access hash:/etc/postfix/sender_access + 7 check_policy_service unix:private/policy + 8 ... + 9 +10 /etc/postfix/sender_access: +11 securityfocus.com OK +12 ... +</pre> +</blockquote> + +<p> NOTES: </p> + +<ul> + +<li> <p> Line 7: On Solaris < 9, or Postfix < 2.10 on any +Solaris version, use inet: style sockets +instead of unix: style, as detailed in the "<a href="#greylist">Example: +greylist policy server</a>" section above. </p> + +<li> <p> Line 5: reject_unauth_destination is not needed here if +the mail relay policy is specified with smtpd_relay_restrictions +(available with Postfix 2.10 and later). </p> + +<li> <p> Lines 6-7: Be sure to specify check_sender_access and +check_policy_service AFTER reject_unauth_destination or else your +system could become an open mail relay. </p> + +<li> <p> Line 3: The greylist database gets polluted quickly with +bogus addresses. It helps if you precede greylist lookups with +restrictions that reject unknown senders and/or recipients. </p> + +</ul> + +<h2><a name="maintenance">Routine greylist maintenance</a></h2> + +<p> The greylist database grows over time, because the greylist server +never removes database entries. If left unattended, the greylist +database will eventually run your file system out of space. </p> + +<p> When the status file size exceeds some threshold you can simply +rename or remove the file without adverse effects; Postfix +automatically creates a new file. In the worst case, new mail will +be delayed by an hour or so. To lessen the impact, rename or remove +the file in the middle of the night at the beginning of a weekend. +</p> + +<h2><a name="greylist_code">Example Perl greylist server</a></h2> + +<p> This is the Perl subroutine that implements the example greylist +policy. It is part of a general purpose sample policy server that +is distributed with the Postfix source as +examples/smtpd-policy/greylist.pl. </p> + +<pre> +# +# greylist status database and greylist time interval. DO NOT create the +# greylist status database in a world-writable directory such as /tmp +# or /var/tmp. DO NOT create the greylist database in a file system +# that can run out of space. +# +$database_name="/var/mta/greylist.db"; +$greylist_delay=60; + +# +# Auto-allowlist threshold. Specify 0 to disable, or the number of +# successful "come backs" after which a client is no longer subject +# to greylisting. +# +$auto_allowlist_threshold = 10; + +# +# Demo SMTPD access policy routine. The result is an action just like +# it would be specified on the right-hand side of a Postfix access +# table. Request attributes are available via the %attr hash. +# +sub smtpd_access_policy { + my($key, $time_stamp, $now); + + # Open the database on the fly. + open_database() unless $database_obj; + + # Search the auto-allowlist. + if ($auto_allowlist_threshold > 0) { + $count = read_database($attr{"client_address"}); + if ($count > $auto_allowlist_threshold) { + return "dunno"; + } + } + + # Lookup the time stamp for this client/sender/recipient. + $key = + lc $attr{"client_address"}."/".$attr{"sender"}."/".$attr{"recipient"}; + $time_stamp = read_database($key); + $now = time(); + + # If new request, add this client/sender/recipient to the database. + if ($time_stamp == 0) { + $time_stamp = $now; + update_database($key, $time_stamp); + } + + # The result can be any action that is allowed in a Postfix access(5) map. + # + # To label the mail, return ``PREPEND headername: headertext'' + # + # In case of success, return ``DUNNO'' instead of ``OK'', so that the + # check_policy_service restriction can be followed by other restrictions. + # + # In case of failure, return ``DEFER_IF_PERMIT optional text...'', + # so that mail can still be blocked by other access restrictions. + # + syslog $syslog_priority, "request age %d", $now - $time_stamp if $verbose; + if ($now - $time_stamp > $greylist_delay) { + # Update the auto-allowlist. + if ($auto_allowlist_threshold > 0) { + update_database($attr{"client_address"}, $count + 1); + } + return "dunno"; + } else { + return "defer_if_permit Service temporarily unavailable"; + } +} +</pre> + +</body> + +</html> diff --git a/proto/SMTPD_PROXY_README.html b/proto/SMTPD_PROXY_README.html new file mode 100644 index 0000000..710183b --- /dev/null +++ b/proto/SMTPD_PROXY_README.html @@ -0,0 +1,412 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Before-Queue Content Filter </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Before-Queue Content Filter </h1> + +<hr> + +<h2>WARNING </h2> + +<p> The before-queue content filtering feature described in this +document limits the amount of mail that a site can handle. See the +"<a href="#pros_cons">Pros and Cons</a>" section below for details. +</p> + +<h2>The Postfix before-queue content filter feature</h2> + +<p> As of version 2.1, the Postfix SMTP server can forward all +incoming mail to a content filtering proxy server that inspects all +mail BEFORE it is stored in the Postfix mail queue. It is roughly +equivalent in capabilities to the approach described in MILTER_README, +except that the latter uses a dedicated protocol instead of SMTP. + +<p> The before-queue content filter is meant to be used as follows: </p> + +<blockquote> + +<table> + +<tr> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> Internet </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <a href="smtpd.8.html">Postfix SMTP server</a> + </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <b>Before</b> <b>queue</b> <b>filter</b> </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <a href="smtpd.8.html">Postfix SMTP server</a> + </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <a href="cleanup.8.html">Postfix cleanup + server</a> </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> Postfix queue </td> + + <td align="center" valign="middle" width="5%"> <tt> -< </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <a href="smtp.8.html">smtp</a><br> <a + href="local.8.html">local</a><br> <a + href="virtual.8.html">virtual</a> </td> + +</tr> + +</table> + +</blockquote> + +<p> The before-queue content filter is not to be confused with the +approach described in the FILTER_README document, where mail is +filtered AFTER it is stored in the Postfix mail queue. </p> + +<p> This document describes the following topics: </p> + +<ul> + +<li><a href="#principles">Principles of operation</a> + +<li><a href="#pros_cons">Pros and cons of before-queue content filtering</a> + +<li><a href="#config">Configuring the Postfix SMTP pass-through +proxy feature</a> + +<li><a href="#parameters">Configuration parameters</a> + +<li><a href="#protocol">How Postfix talks to the before-queue content +filter</a> + +</ul> + +<h2><a name="principles">Principles of operation</a></h2> + +<p> As shown in the diagram above, the before-queue filter sits +between two Postfix SMTP server processes. </p> + +<ul> + +<li> <p> The before-filter Postfix SMTP server accepts connections from the +Internet and does the usual relay access control, SASL authentication, +TLS negotiation, +RBL lookups, rejecting non-existent sender or recipient addresses, +etc. </p> + +<li> <p> The before-queue filter receives unfiltered mail content from +Postfix and does one of the following: </p> + +<ol> + + <li> <p> Re-inject the mail back into Postfix via SMTP, perhaps + after changing its content and/or destination. </p> + + <li> <p> Discard or quarantine the mail. </p> + + <li> <p> Reject the mail by sending a suitable SMTP status code + back to Postfix. Postfix passes the status back to the remote + SMTP client. This way, Postfix does not have to send a bounce + message. </p> + +</ol> + +<li> <p>The after-filter Postfix SMTP server receives mail from the +content filter. From then on Postfix processes the mail as usual. </p> + +</ul> + +<p> The before-queue content filter described here works just like +the after-queue content filter described in the FILTER_README +document. In many cases you can use the same software, within the +limitations as discussed in the "<a href="#pros_cons">Pros and +Cons</a>" section below. </p> + +<h2><a name="pros_cons">Pros and cons of before-queue content +filtering</a></h2> + +<ul> + +<li> <p> Pro: Postfix can reject mail before the incoming SMTP mail +transfer completes, so that Postfix does not have to send rejected +mail back to the sender (which is usually forged anyway). Mail +that is not accepted remains the responsibility of the remote SMTP +client. </p> + +<li> <p> Con: The remote SMTP client expects an SMTP reply within +a deadline. As the system load increases, fewer and fewer CPU +cycles remain available to answer within the deadline, and eventually +you either have to stop accepting mail or you have to stop filtering +mail. It is for this reason that the before-queue content filter +limits the amount of mail that a site can handle. </p> + +<li> <p> Con: Content filtering software can use lots of memory +resources. You have to reduce the number of simultaneous content +filter processes so that a burst of mail will not drive your system +into the ground. </p> + +<ul> + +<li> <p> With Postfix versions 2.7 and later, SMTP clients will +experience an increase in the delay between the time the client +sends "end-of-message" and the time the Postfix SMTP server replies +(here, the number of before-filter SMTP server processes can be +larger than the number of filter processes). </p> + +<li> <p> With Postfix versions before 2.7, SMTP clients will +experience an increase in the delay before they can receive service +(here, the number of before-filter SMTP server processes is always +equal to the number of filter processes). </p> + +</ul> + +</ul> + +<h2><a name="config">Configuring the Postfix SMTP pass-through +proxy feature</a></h2> + +<p> In the following example, the before-filter Postfix SMTP server +gives mail to a content filter that listens on localhost port 10025. +The after-filter Postfix SMTP server receives mail from the content +filter via localhost port 10026. From then on mail is processed as +usual. </p> + +<p> The content filter itself is not described here. You can use +any filter that is SMTP enabled. For non-SMTP capable content +filtering software, Bennett Todd's SMTP proxy implements a nice +Perl-based framework. See: +https://web.archive.org/web/20151022025756/http://bent.latency.net/smtpprox/ +or https://github.com/jnorell/smtpprox/ </p> + +<blockquote> + +<table border="0"> + +<tr> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> Internet </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <a href="smtpd.8.html">Postfix SMTP server on + port 25</a> </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> filter on localhost port 10025 </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <a href="smtpd.8.html">Postfix SMTP server on + localhost port 10026</a> </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> <a href="cleanup.8.html">Postfix cleanup + server</a> </td> + + <td align="center" valign="middle" width="5%"> <tt> -> </tt> </td> + + <td bgcolor="#f0f0ff" align="center" valign="middle" + width="10%"> Postfix incoming queue </td> + +</tr> + +</table> + +</blockquote> + +<p> This is configured by editing the master.cf file: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + # ============================================================= + # service type private unpriv chroot wakeup maxproc command + # (yes) (yes) (yes) (never) (100) + # ============================================================= + # + # Before-filter SMTP server. Receive mail from the network and + # pass it to the content filter on localhost port 10025. + # + smtp inet n - n - 20 smtpd + -o smtpd_proxy_filter=127.0.0.1:10025 + -o smtpd_client_connection_count_limit=10 + # Postfix 2.7 and later performance feature. + # -o smtpd_proxy_options=speed_adjust + # + # After-filter SMTP server. Receive mail from the content filter + # on localhost port 10026. + # + 127.0.0.1:10026 inet n - n - - smtpd + -o smtpd_authorized_xforward_hosts=127.0.0.0/8 + -o smtpd_client_restrictions= + -o smtpd_helo_restrictions= + -o smtpd_sender_restrictions= + # Postfix 2.10 and later: specify empty smtpd_relay_restrictions. + -o smtpd_relay_restrictions= + -o smtpd_recipient_restrictions=permit_mynetworks,reject + -o smtpd_data_restrictions= + -o mynetworks=127.0.0.0/8 + -o receive_override_options=no_unknown_recipient_checks +</pre> +</blockquote> + +<p> Note: do not specify spaces around the "=" or "," characters. </p> + +<p> The before-filter SMTP server entry is a modified version of the +default Postfix SMTP server entry that is normally configured at +the top of the master.cf file: </p> + +<ul> + + <li> <p> The number of SMTP sessions is reduced from the default + 100 to only 20. This prevents a burst of mail from running your + system into the ground with too many content filter processes. </p> + + <li> <p> The "-o smtpd_client_connection_count_limit=10" prevents + one SMTP client from using up all 20 SMTP server processes. + This limit is not necessary if you receive all mail from a + trusted relay host. </p> + + <p> Note: this setting is available in Postfix version 2.2 and + later. Earlier Postfix versions will ignore it. </p> + + <li> <p> The "-o smtpd_proxy_filter=127.0.0.1:10025" tells the + before-filter SMTP server that it should give incoming mail to + the content filter that listens on localhost TCP port 10025. + + <li> <p> The "-o smtpd_proxy_options=speed_adjust" tells the + before-filter SMTP server that it should receive an entire email + message before it connects to a content filter. This reduces + the number of simultaneous filter processes. </p> + + <p> NOTE 1: When this option is turned on, a content filter must + not <i>selectively</i> reject recipients of a multi-recipient + message. Rejecting all recipients is OK, as is accepting all + recipients. </p> + + <p> NOTE 2: This feature increases the minimum amount of free + queue space by $message_size_limit. The extra space is needed + to save the message to a temporary file. </p> + + <li> <p> Postfix ≥ 2.3 supports both TCP and UNIX-domain filters. + The above filter could be specified as "inet:127.0.0.1:10025". + To specify a UNIX-domain filter, specify "unix:<i>pathname</i>". + A relative pathname is interpreted relative to the Postfix queue + directory. </p> + +</ul> + +<p> The after-filter SMTP server is a new master.cf entry: </p> + +<ul> + + <li> <p> The "127.0.0.1:10026" makes the after-filter SMTP + server listen + on the localhost address only, without exposing it to the + network. NEVER expose the after-filter SMTP server to the + Internet :-) </p> + + <li> <p> The "-o smtpd_authorized_xforward_hosts=127.0.0.0/8" + allows the after-filter SMTP server to receive remote SMTP + client information from the before-filter SMTP server, so that + the after-filter Postfix daemons log the remote SMTP client + information instead of logging localhost[127.0.0.1]. </p> + + <li> <p> The other after-filter SMTP server settings avoid + duplication of work that is already done in the "before filter" + SMTP server. </p> + +</ul> + +<p> By default, the filter has 100 seconds to do its work. If it +takes longer then Postfix gives up and reports an error to the +remote SMTP client. You can increase this time limit (see the <a href="#parameters">"Configuration +parameters"</a> section below) but doing so is pointless because you +can't control when the remote SMTP client times out. </p> + +<h2><a name="parameters">Configuration parameters</a></h2> + +<p> Parameters that control proxying: </p> + +<ul> + +<li> <p> smtpd_proxy_filter (syntax: host:port): The host and TCP +port of the before-queue content filter. When no host or host: +is specified here, localhost is assumed. </p> + +<li> <p> smtpd_proxy_timeout (default: 100s): Timeout for connecting +to the before-queue content filter and for sending and receiving +commands and data. All proxy errors are logged to the maillog +file. For privacy reasons, all the remote SMTP client sees is "451 +Error: queue file write error". It would not be right to disclose +internal details to strangers. </p> + +<li> <p> smtpd_proxy_ehlo (default: $myhostname): The hostname to +use when sending an EHLO command to the before-queue content filter. +</p> + +</ul> + +<h2><a name="protocol">How Postfix talks to the before-queue content +filter</a></h2> + +<p> The before-filter Postfix SMTP server connects to the content +filter, delivers one message, and disconnects. While sending mail +into the content filter, Postfix speaks ESMTP but uses no command +pipelining. Postfix generates its own EHLO, XFORWARD (for logging +the remote client IP address instead of localhost[127.0.0.1]), DATA +and QUIT commands, and forwards unmodified copies of all the MAIL +FROM and RCPT TO commands that the before-filter Postfix SMTP server +didn't reject itself. +Postfix sends no other SMTP commands. </p> + +<p> The content filter should accept the same MAIL FROM and RCPT +TO command syntax as the before-filter Postfix SMTP server, and +should forward the commands without modification to the after-filter +SMTP server. If the content filter or after-filter SMTP server +does not support all the ESMTP features that the before-filter +Postfix SMTP server supports, then the missing features must be +turned off in the before-filter Postfix SMTP server with the +smtpd_discard_ehlo_keywords parameter. </p> + +<p> When the filter rejects content, it should send a negative SMTP +response back to the before-filter Postfix SMTP server, and it +should abort the connection with the after-filter Postfix SMTP +server without completing the SMTP conversation with the after-filter +Postfix SMTP server. </p> + +</body> + +</html> diff --git a/proto/SMTPUTF8_README.html b/proto/SMTPUTF8_README.html new file mode 100644 index 0000000..c0e5608 --- /dev/null +++ b/proto/SMTPUTF8_README.html @@ -0,0 +1,399 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix SMTPUTF8 support</title> + +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT=""> +Postfix SMTPUTF8 support +</h1> + +<hr> + +<h2> Overview </h2> + +<p> This document describes Postfix support for Email Address +Internationalization (EAI) as defined in RFC 6531 (SMTPUTF8 extension), +RFC 6532 (Internationalized email headers) and RFC 6533 (Internationalized +delivery status notifications). Introduced with Postfix version +3.0, this fully supports UTF-8 email addresses and UTF-8 message +header values. </p> + +<p> Topics covered in this document: </p> + +<ul> + +<li><a href="#building">Building with/without SMTPUTF8 support</a> + +<li><a href="#enabling">Enabling Postfix SMTPUTF8 support</a> + +<li><a href="#using">Using Postfix SMTPUTF8 support</a> + +<li><a href="#detecting">SMTPUTF8 autodetection</a> + +<li><a href="#limitations">Limitations of the current implementation</a> + +<li><a href="#compatibility">Compatibility with pre-SMTPUTF8 environments</a> + +<li><a href="#idna2003">Compatibility with IDNA2003</a> + +<li><a href="#credits">Credits</a> + +</ul> + +<h2> <a name="building">Building Postfix with/without SMTPUTF8 support</a> </h2> + +<p> Postfix will build with SMTPUTF8 support if the ICU version +≥ 46 library and header files are installed on the system. The +package name varies with the OS distribution. The table shows package +names for a number of platforms at the time this text was written. +</p> + +<blockquote> + +<table border="1"> + +<tr> <th> OS Distribution </th> <th> Package </th> </tr> + +<tr> <td> FreeBSD, NetBSD, etc. </td> <td> icu </td> </tr> + +<tr> <td> Centos, Fedora, RHEL </td> <td> libicu-devel </td> </tr> + +<tr> <td> Debian, Ubuntu </td> <td> libicu-dev </td> </tr> + +</table> + +</blockquote> + +<p> To force Postfix to build without SMTPUTF8, specify: </p> + +<blockquote> +<pre> +$ <b>make makefiles CCARGS="-DNO_EAI ..."</b> +</pre> +</blockquote> + +<p> See the INSTALL document for more "make makefiles" options. </p> + +<h2> <a name="enabling">Enabling Postfix SMTPUTF8 support</a> </h2> + +<p> There is more to SMTPUTF8 than just Postfix itself. The rest +of your email infrastructure also needs to be able to handle UTF-8 +email addresses and message header values. This includes SMTPUTF8 +protocol support in SMTP-based content filters (Amavisd), LMTP +servers (Dovecot), and down-stream SMTP servers. </p> + +<p> Postfix SMTPUTF8 support is enabled by default, but it may be +disabled as part of a backwards-compatibility safety net (see the +COMPATIBILITY_README file). </p> + +<p> SMTPUTF8 support is enabled by setting the smtputf8_enable +parameter in main.cf:</p> + +<blockquote> +<pre> +# <b>postconf "smtputf8_enable = yes"</b> +# <b>postfix reload</b> +</pre> +</blockquote> + +<p> (With Postfix ≤ 3.1, you may also need to specify "<b>option_group += client</b>" in Postfix MySQL client files, to enable UTF8 support +in MySQL queries. This setting is the default as of Postfix 3.2.) </p> + +<p> With SMTPUTF8 support enabled, Postfix changes behavior with +respect to earlier Postfix releases: </p> + +<ul> + +<li> <p> UTF-8 is permitted in the myorigin parameter value. However, +the myhostname and mydomain parameters must currently specify +ASCII-only domain names. This limitation may be removed later. </p> + +<li> <p> UTF-8 is the only form of non-ASCII text that Postfix +supports in access tables, address rewriting tables, and other +tables that are indexed with an email address, hostname, or domain +name. </p> + +<li> <p> The header_checks-like and body_checks-like features are +not UTF-8 enabled, and therefore they do not enforce UTF-8 syntax +rules on inputs and outputs. The reason is that non-ASCII text may +be sent in encodings other than UTF-8, and that real email sometimes +contains malformed headers. Instead of skipping non-UTF-8 content, +Postfix should be able to filter it. You may try to enable UTF-8 +processing by starting a PCRE pattern with the sequence (*UTF8), +but this is will result in "message not accepted, try again later" +errors when the PCRE pattern matcher encounters non-UTF-8 input. +Other features that are not UTF-8 enabled are smtpd_command_filter, +smtp_reply_filter, the *_delivery_status_filter features, and the +*_dns_reply_filter features (the latter because DNS is by definition +an ASCII protocol). </p> + +<li> <p> The Postfix SMTP server announces SMTPUTF8 support in the +EHLO response. </p> + +<pre> +220 server.example.com ESMTP Postfix +<b>EHLO client.example.com</b> +250-server.example.com +250-PIPELINING +250-SIZE 10240000 +250-VRFY +250-ETRN +250-STARTTLS +250-AUTH PLAIN LOGIN +250-ENHANCEDSTATUSCODES +250-8BITMIME +250-DSN +250 SMTPUTF8 +</pre> + +<li> <p> The Postfix SMTP server accepts the SMTPUTF8 request in +MAIL FROM and VRFY commands. </p> + +<pre> +<b>MAIL FROM:<address> SMTPUTF8 ...</b> + +<b>VRFY address SMTPUTF8</b> +</pre> + +<li> <p> The Postfix SMTP client may issue the SMTPUTF8 request in +MAIL FROM commands. </p> + +<li> <p> The Postfix SMTP server accepts UTF-8 in email address +domains, but only after the remote SMTP client issues the +SMTPUTF8 request in MAIL FROM or VRFY commands. </p> + +</ul> + +<p> Postfix already permitted UTF-8 in message header values +and in address localparts. This does not change. </p> + +<h2> <a name="using">Using Postfix SMTPUTF8 support</a> </h2> + +<p> After Postfix SMTPUTF8 support is turned on, Postfix behavior +will depend on 1) whether a remote SMTP client requests SMTPUTF8 +support, 2) the presence of UTF-8 content in the message envelope +and headers, and 3) whether a down-stream SMTP (or LMTP) server +announces SMTPUTF8 support. </p> + +<ul> + +<li> <p> When the Postfix SMTP server receives a message WITHOUT +the SMTPUTF8 request, Postfix handles the message as it has always +done (at least that is the default, see autodetection below). +Specifically, the Postfix SMTP server does not accept UTF-8 in the +envelope sender domain name or envelope recipient domain name, and +the Postfix SMTP client does not issue the SMTPUTF8 request when +delivering that message to an SMTP or LMTP server that announces +SMTPUTF8 support (again, that is the default). Postfix will accept +UTF-8 in message header values and in the localpart of envelope +sender and recipient addresses, because it has always done that. +</p> + +<li> <p> When the Postfix SMTP server receives a message WITH the +SMTPUTF8 request, Postfix will issue the SMTPUTF8 request when +delivering that message to an SMTP or LMTP server that announces +SMTPUTF8 support. This is not configurable. </p> + +<li> <p> When a message is received with the SMTPUTF8 request, +Postfix will deliver the message to a non-SMTPUTF8 SMTP or LMTP +server ONLY if: </p> + + <ul> + + <li> <p> No message header value contains UTF-8. </p> + + <li> <p> The envelope sender address contains no UTF-8, </p> + + <li> <p> No envelope recipient address for that specific + SMTP/LMTP delivery transaction contains UTF-8. </p> + + <blockquote> <p> NOTE: Recipients in other email delivery + transactions for that same message may still contain UTF-8. + </p> </blockquote> + + </ul> + + <p> Otherwise, Postfix will return the recipient(s) for that + email delivery transaction as undeliverable. The delivery status + notification message will be an SMTPUTF8 message. It will therefore + be subject to the same restrictions as email that is received + with the SMTPUTF8 request. </p> + +<li> <p> When the Postfix SMTP server receives a message with the +SMTPUTF8 request, that request also applies after the message is +forwarded via a virtual or local alias, or $HOME/.forward file. +</p> + +</ul> + +<h2> <a name="detecting">SMTPUTF8 autodetection</a> </h2> + +<p> This section applies only to systems that have SMTPUTF8 support +turned on (smtputf8_enable = yes). </p> + +<p> For compatibility with pre-SMTPUTF8 environments, Postfix does +not automatically set the "SMTPUTF8 requested" flag on messages +from non-SMTPUTF8 clients that contain a UTF-8 header value or +UTF-8 address localpart. This would make such messages undeliverable +to non-SMTPUTF8 servers, and could be a barrier to SMTPUTF8 adoption. +</p> + +<p> By default, Postfix sets the "SMTPUTF8 requested" flag only on +address verification probes and on Postfix sendmail submissions +that contain UTF-8 in the sender address, UTF-8 in a recipient +address, or UTF-8 in a message header value. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtputf8_autodetect_classes = sendmail, verify +</pre> +</blockquote> + +<p> However, if you have a non-ASCII myorigin or mydomain setting, +or if you have a configuration that introduces UTF-8 addresses with +virtual aliases, canonical mappings, or BCC mappings, then you may +have to apply SMTPUTF8 autodetection to all email: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtputf8_autodetect_classes = all +</pre> +</blockquote> + +<p> This will, of course, also flag email that was received without +SMTPUTF8 request, but that contains UTF-8 in a sender address +localpart, receiver address localpart, or message header value. +Such email was not standards-compliant, but Postfix would have +delivered it if SMTPUTF8 support was disabled. </p> + +<h2> <a name="limitations">Limitations of the current implementation</a> +</h2> + +<p> The Postfix implementation is a work in progress; limitations +are steadily being removed. The text below describes the situation +at one point in time. </p> + +<h3> No automatic conversions between ASCII and UTF-8 domain names. </h3> + +<p> Some background: According to RFC 6530 and related documents, +an internationalized domain name can appear in two forms: the UTF-8 +form, and the ASCII (xn--mumble) form. An internationalized address +localpart must be encoded in UTF-8; the RFCs do not define an ASCII +alternative form. </p> + +<p> Postfix currently does not convert internationalized domain +names from UTF-8 into ASCII (or from ASCII into UTF-8) before using +domain names in SMTP commands and responses, before looking up +domain names in lists such as mydestination, relay_domains or in +lookup tables such as access tables, etc., before using domain names +in a policy daemon or Milter request, or before logging events. +</p> + +<p> Postfix does, however, casefold domain names and email addresses +before matching them against a Postfix configuration parameter or +lookup table. </p> + +<p> In order to use Postfix SMTPUTF8 support: </p> + +<ul> + +<li> <p> The Postfix parameters myhostname and mydomain must be in +ASCII form. One is a substring of the other, and the myhostname +value is used in SMTP commands and responses that require ASCII. +The parameter myorigin (added to local addresses without domain) +supports UTF-8. </p> + +<li> <p> You need to configure both the ASCII and UTF-8 forms of +an Internationalized domain name in Postfix parameters such as +mydestination and relay_domains, as well as lookup table search +keys. </p> + +<li> <p> Milters, content filters, policy servers and logfile +analysis tools need to be able to handle both the ASCII and UTF-8 +forms of Internationalized domain names. </p> + +</ul> + +<h2> <a name="compatibility">Compatibility with pre-SMTPUTF8 +environments</a> </h2> + +<h3> Mailing lists with UTF-8 and non-UTF-8 subscribers </h3> + +<p> With Postfix, there is no need to split mailing lists into UTF-8 and +non-UTF-8 members. Postfix will try to deliver the non-UTF8 subscribers +over "traditional" non-SMTPUTF8 sessions, as long as the message +has an ASCII envelope sender address and all-ASCII header values. +The mailing list manager may have to apply RFC 2047 encoding to +satisfy that last condition. </p> + +<h3> Pre-existing non-ASCII email flows </h3> + +<p> With "smtputf8_enable = no", Postfix handles email with non-ASCII +in address localparts (and in headers) as before. The vast majority +of email software is perfectly capable of handling such email, even +if pre-SMTPUTF8 standards do not support such practice. </p> + +<h3> Rejecting non-UTF8 addresses </h3> + +<p> With "smtputf8_enable = yes", Postfix +requires that non-ASCII address information is encoded in UTF-8 and +will reject other encodings such as ISO-8859. It is not practical +for Postfix to support multiple encodings at the same time. There +is no problem with RFC 2047 encodings such as "=?ISO-8859-1?Q?text?=", +because those use only characters from the ASCII characterset. </p> + +<h3> Rejecting non-ASCII addresses in non-SMTPUTF8 transactions </h3> + +<p> Setting "strict_smtputf8 = yes" in addition to "smtputf8_enable += yes" will enable stricter enforcement of the SMTPUTF8 protocol. +Specifically, the Postfix SMTP server will not only reject non-UTF8 +sender or recipient addresses, it will in addition accept UTF-8 +sender or recipient addresses only when the client requests an +SMTPUTF8 mail transaction. </p> + +<h2> <a name="idna2003">Compatibility with IDNA2003</a> </h2> + +<p> Postfix ≥ 3.2 by default disables the 'transitional' +compatibility between IDNA2003 and IDNA2008, when converting UTF-8 +domain names to/from the ASCII form that is used in DNS lookups. +This makes Postfix behavior consistent with current versions of the +Firefox and Chrome web browsers. Specify "enable_idna2003_compatibility += yes" to get the historical behavior. </p> + +<p> This affects the conversion of domain names that contain for +example the German sz (ß) and the Greek zeta (Ï‚). See +http://unicode.org/cldr/utility/idna.jsp for more examples. </p> + +<h2> <a name="credits">Credits</a> </h2> + +<ul> + +<li> <p> May 15, 2014: Arnt Gulbrandsen posted his patch for Unicode +email support. This work was sponsored by CNNIC. </p> + +<li> <p> July 15, 2014: Wietse integrated Arnt Gulbrandsen's code +and released Postfix with SMTPUTF8 support. </p> + +<li> <p> January 2015: Wietse added UTF-8 support for casefolding +in Postfix lookup tables and caseless string comparison in Postfix +list-based features. </p> + +</ul> + +</body> + +</html> + diff --git a/proto/SQLITE_README.html b/proto/SQLITE_README.html new file mode 100644 index 0000000..598f80c --- /dev/null +++ b/proto/SQLITE_README.html @@ -0,0 +1,114 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix SQLite Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix SQLite Howto</h1> + +<hr> + +<h2>Introduction</h2> + +<p> The Postfix sqlite map type allows you to hook up Postfix to a +SQLite database. This implementation allows for multiple sqlite +databases: you can use one for a virtual(5) table, one for an +access(5) table, and one for an aliases(5) table if you want. </p> + +<h2>Building Postfix with SQLite support</h2> + +<p> The Postfix SQLite client utilizes the sqlite3 library, +which can be obtained from: </p> + +<blockquote> + <p> http://www.sqlite.org/ </p> +</blockquote> + +<p> In order to build Postfix with sqlite map support, you will +need to add to CCARGS the flags -DHAS_SQLITE and -I with the directory +containing the sqlite header files, and you will need to add to +AUXLIBS the directory and name of the sqlite3 library, plus the +name of the standard POSIX thread library (pthread). For example: +</p> + +<blockquote> +<pre> +make -f Makefile.init makefiles \ + 'CCARGS=-DHAS_SQLITE -I/usr/local/include' \ + 'AUXLIBS_SQLITE=-L/usr/local/lib -lsqlite3 -lpthread' +</pre> +</blockquote> + +<p> If your SQLite shared library is in a directory that the RUN-TIME +linker does not know about, add a "-Wl,-R,/path/to/directory" option after +"-lsqlite3". </p> + +<p> Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_SQLITE. +With Postfix 3.0 and later, the old AUXLIBS variable still supports +building a statically-loaded SQLite database client, but only the new +AUXLIBS_SQLITE variable supports building a dynamically-loaded or +statically-loaded SQLite database client. </p> + +<blockquote> + +<p> Failure to use the AUXLIBS_SQLITE variable will defeat the purpose +of dynamic database client loading. Every Postfix executable file +will have SQLITE database library dependencies. And that was exactly +what dynamic database client loading was meant to avoid. </p> + +</blockquote> + +<p> Then, just run 'make'.</p> + +<h2>Using SQLite tables</h2> + +<p> Once Postfix is built with sqlite support, you can specify a +map type in main.cf like this: </p> + +<blockquote> +<pre> +alias_maps = sqlite:/etc/postfix/sqlite-aliases.cf +</pre> +</blockquote> + +<p> The file /etc/postfix/sqlite-aliases.cf specifies lots of +information telling Postfix how to reference the sqlite database. +For a complete description, see the sqlite_table(5) manual page. </p> + +<h2>Example: local aliases </h2> + +<pre> +# +# sqlite config file for local(8) aliases(5) lookups +# + +# Path to database +dbpath = /some/path/to/sqlite_database + +# See sqlite_table(5) for details. +query = SELECT forw_addr FROM mxaliases WHERE alias='%s' AND status='paid' +</pre> + +<h2>Credits</h2> + +<p> SQLite support was added with Postfix version 2.8. </p> + +<ul> + +<li>Implementation by Axel Steiner</li> +<li>Documentation by Jesus Garcia Crespo</li> + +</ul> + +</body> + +</html> diff --git a/proto/STANDARD_CONFIGURATION_README.html b/proto/STANDARD_CONFIGURATION_README.html new file mode 100644 index 0000000..b4f4efc --- /dev/null +++ b/proto/STANDARD_CONFIGURATION_README.html @@ -0,0 +1,851 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Standard Configuration Examples</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Standard Configuration Examples</h1> + +<hr> + +<h2>Purpose of this document</h2> + +<p> This document presents a number of typical Postfix configurations. +This document should be reviewed after you have followed the basic +configuration steps as described in the BASIC_CONFIGURATION_README +document. In particular, do not proceed here if you don't already +have Postfix working for local mail submission and for local mail +delivery. </p> + +<p> The first part of this document presents standard configurations +that each solve one specific problem. </p> + +<ul> + +<li><a href="#stand_alone">Postfix on a stand-alone Internet host</a> + +<li><a href="#null_client">Postfix on a null client</a> + +<li><a href="#local_network">Postfix on a local network</a> + +<li><a href="#firewall">Postfix email firewall/gateway</a> + +</ul> + +<p> The second part of this document presents additional configurations +for hosts in specific environments. </p> + +<ul> + +<li><a href="#some_local">Delivering some but not all accounts locally</a> + +<li><a href="#intranet">Running Postfix behind a firewall</a> + +<li><a href="#backup">Configuring Postfix as primary or backup MX host for a remote +site</a> + +<li><a href="#dialup">Postfix on a dialup machine</a> + +<li><a href="#fantasy">Postfix on hosts without a real +Internet hostname</a> + +</ul> + +<h2><a name="stand_alone">Postfix on a stand-alone Internet host</a></h2> + +<p> Postfix should work out of the box without change on a stand-alone +machine that has direct Internet access. At least, that is how +Postfix installs when you download the Postfix source code via +http://www.postfix.org/. </p> + +<p> You can use the command "<b>postconf -n</b>" to find out what +settings are overruled by your main.cf. Besides a few pathname +settings, few parameters should be set on a stand-alone box, beyond +what is covered in the BASIC_CONFIGURATION_README document: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # Optional: send mail as user@domainname instead of user@hostname. + #myorigin = $mydomain + + # Optional: specify NAT/proxy external address. + #proxy_interfaces = 1.2.3.4 + + # Alternative 1: don't relay mail from other hosts. + mynetworks_style = host + relay_domains = + + # Alternative 2: relay mail from local clients only. + # mynetworks = 192.168.1.0/28 + # relay_domains = +</pre> +</blockquote> + +<p> See also the section "<a href="#fantasy">Postfix on hosts without +a real Internet hostname</a>" if this is applicable to your configuration. +</p> + +<h2><a name="null_client">Postfix on a null client</a></h2> + +<p> A null client is a machine that can only send mail. It receives no +mail from the network, and it does not deliver any mail locally. A +null client typically uses POP, IMAP or NFS for mailbox access. </p> + +<p> In this example we assume that the Internet domain name is +"example.com" and that the machine is named "hostname.example.com". +As usual, the examples show only parameters that are not left at +their default settings. </p> + +<blockquote> +<pre> +1 /etc/postfix/main.cf: +2 myhostname = hostname.example.com +3 myorigin = $mydomain +4 relayhost = $mydomain +5 inet_interfaces = loopback-only +6 mydestination = +</pre> +</blockquote> + +<p> Translation: </p> + +<ul> + +<li> <p> Line 2: Set myhostname to hostname.example.com, in case +the machine name isn't set to a fully-qualified domain name (use +the command "postconf -d myhostname" to find out what the machine +name is). </p> + +<li> <p> Line 2: The myhostname value also provides the default +value for the mydomain parameter (here, "mydomain = example.com"). +</p> + +<li> <p> Line 3: Send mail as "user@example.com" (instead of +"user@hostname.example.com"), so that nothing ever has a reason +to send mail to "user@hostname.example.com". </p> + +<li> <p> Line 4: Forward all mail to the mail server that is +responsible for the "example.com" domain. This prevents mail from +getting stuck on the null client if it is turned off while some +remote destination is unreachable. Specify a real hostname +here if your "example.com" domain has no MX record. </p> + +<li> <p> Line 5: Do not accept mail from the network. </p> + +<li> <p> Line 6: Disable local mail delivery. All mail goes to +the mail server as specified in line 4. </p> + +</ul> + +<h2><a name="local_network">Postfix on a local network</a></h2> + +<p> This section describes a local area network environment of one +main server and multiple other systems that send and receive email. +As usual we assume that the Internet domain name is "example.com". +All systems are configured to send mail as "user@example.com", and +all systems receive mail for "user@hostname.example.com". The main +server also receives mail for "user@example.com". We call this +machine by the name of mailhost.example.com. </p> + +<p> A drawback of sending mail as "user@example.com" is that mail +for "root" and other system accounts is also sent to the central +mailhost. See the section "<a href="#some_local">Delivering some +but not all accounts locally</a>" below for possible solutions. +</p> + +<p> As usual, the examples show only parameters that are not left +at their default settings. </p> + +<p> First we present the non-mailhost configuration, because it is +the simpler one. This machine sends mail as "user@example.com" and +is the final destination for "user@hostname.example.com". </p> + +<blockquote> +<pre> +1 /etc/postfix/main.cf: +2 myorigin = $mydomain +3 mynetworks = 127.0.0.0/8 10.0.0.0/24 +4 relay_domains = +5 # Optional: forward all non-local mail to mailhost +6 #relayhost = $mydomain +</pre> +</blockquote> + +<p> Translation: </p> + +<ul> + +<li> <p> Line 2: Send mail as "user@example.com". </p> + +<li> <p> Line 3: Specify the trusted networks. </p> + +<li> <p> Line 4: This host does not relay mail from untrusted networks. </p> + +<li> <p> Line 6: This is needed if no direct Internet access is +available. See also below, "<a href="#firewall">Postfix behind +a firewall</a>". </p> + +</ul> + +<p> Next we present the mailhost configuration. This machine sends +mail as "user@example.com" and is the final destination for +"user@hostname.example.com" as well as "user@example.com". </p> + +<blockquote> +<pre> + 1 DNS: + 2 example.com IN MX 10 mailhost.example.com. + 3 + 4 /etc/postfix/main.cf: + 5 myorigin = $mydomain + 6 mydestination = $myhostname localhost.$mydomain localhost $mydomain + 7 mynetworks = 127.0.0.0/8 10.0.0.0/24 + 8 relay_domains = + 9 # Optional: forward all non-local mail to firewall +10 #relayhost = [firewall.example.com] +</pre> +</blockquote> + +<p> Translation: </p> + +<ul> + +<li> <p> Line 2: Send mail for the domain "example.com" to the +machine mailhost.example.com. Remember to specify the "." at the +end of the line. </p> + +<li> <p> Line 5: Send mail as "user@example.com". </p> + +<li> <p> Line 6: This host is the final mail destination for the +"example.com" domain, in addition to the names of the machine +itself. </p> + +<li> <p> Line 7: Specify the trusted networks. </p> + +<li> <p> Line 8: This host does not relay mail from untrusted networks. </p> + +<li> <p> Line 10: This is needed only when the mailhost has to +forward non-local mail via a mail server on a firewall. The +<tt>[]</tt> forces Postfix to do no MX record lookups. </p> + +</ul> + +<p> In an environment like this, users access their mailbox in one +or more of the following ways: + +<ul> + +<li> <p> Mailbox access via NFS or equivalent. </p> + +<li> <p> Mailbox access via POP or IMAP. </p> + +<li> <p> Mailbox on the user's preferred machine. </p> + +</ul> + +<p> In the latter case, each user has an alias on the mailhost that +forwards mail to her preferred machine: </p> + +<blockquote> +<pre> +/etc/aliases: + joe: joe@joes.preferred.machine + jane: jane@janes.preferred.machine +</pre> +</blockquote> + +<p> On some systems the alias database is not in /etc/aliases. To +find out the location for your system, execute the command "<b>postconf +alias_maps</b>". </p> + +<p> Execute the command "<b>newaliases</b>" whenever you change +the aliases file. </p> + +<h2><a name="firewall">Postfix email firewall/gateway</a></h2> + +<p> The idea is to set up a Postfix email firewall/gateway that +forwards mail for "example.com" to an inside gateway machine but +rejects mail for "anything.example.com". There is only one problem: +with "relay_domains = example.com", the firewall normally also +accepts mail for "anything.example.com". That would not be right. +</p> + +<p> Note: this example requires Postfix version 2.0 and later. To find +out what Postfix version you have, execute the command "<b>postconf +mail_version</b>". </p> + +<p> The solution is presented in multiple parts. This first part +gets rid of local mail delivery on the firewall, making the firewall +harder to break. </p> + +<blockquote> +<pre> +1 /etc/postfix/main.cf: +2 myorigin = example.com +3 mydestination = +4 local_recipient_maps = +5 local_transport = error:local mail delivery is disabled +6 +7 /etc/postfix/master.cf: +8 Comment out the local delivery agent +</pre> +</blockquote> + +<p> Translation: </p> + +<ul> + +<li> <p> Line 2: Send mail from this machine as "user@example.com", +so that no reason exists to send mail to "user@firewall.example.com". +</p> + +<li> <p> Lines 3-8: Disable local mail delivery on the firewall +machine. </p> + +</ul> + +<p> For the sake of technical correctness the firewall must be able +to receive mail for postmaster@[firewall ip address]. Reportedly, +some things actually expect this ability to exist. The second part +of the solution therefore adds support for postmaster@[firewall ip +address], and as a bonus we do abuse@[firewall ip address] as well. +All the mail to these two accounts is forwarded to an inside address. +</p> + +<blockquote> +<pre> +1 /etc/postfix/main.cf: +2 virtual_alias_maps = hash:/etc/postfix/virtual +3 +4 /etc/postfix/virtual: +5 postmaster postmaster@example.com +6 abuse abuse@example.com +</pre> +</blockquote> + +<p> Translation: </p> + +<ul> + +<li> <p> Because mydestination is empty (see the previous example), +only address literals matching $inet_interfaces or $proxy_interfaces +are deemed local. So "localpart@[a.d.d.r]" can be matched as simply +"localpart" in canonical(5) and virtual(5). This avoids the need to +specify firewall IP addresses in Postfix configuration files. </p> + +</ul> + +<p> The last part of the solution does the email forwarding, which +is the real purpose of the firewall email function. </p> + +<blockquote> +<pre> + 1 /etc/postfix/main.cf: + 2 mynetworks = 127.0.0.0/8 12.34.56.0/24 + 3 relay_domains = example.com + 4 parent_domain_matches_subdomains = + 5 debug_peer_list smtpd_access_maps +<br> + 6a # Postfix 2.10 and later support separate relay control and + 7a # spam control. + 8a smtpd_relay_restrictions = + 9a permit_mynetworks reject_unauth_destination +10a smtpd_recipient_restrictions = ...spam blocking rules.... +<br> + 6b # Older configurations combine relay control and spam control. To + 7b # use this with Postfix ≥ 2.10 specify "smtpd_relay_restrictions=". + 8b smtpd_recipient_restrictions = + 9b permit_mynetworks reject_unauth_destination +10b ...spam blocking rules.... +<br> +11 relay_recipient_maps = hash:/etc/postfix/relay_recipients +12 transport_maps = hash:/etc/postfix/transport +13 +14 /etc/postfix/relay_recipients: +15 user1@example.com x +16 user2@example.com x +17 . . . +18 +19 /etc/postfix/transport: +20 example.com smtp:[inside-gateway.example.com] +</pre> +</blockquote> + +<p> Translation: </p> + +<ul> + +<li><p> Lines 1-10: Accept mail from local systems in $mynetworks, +and accept mail from outside for "user@example.com" but not for +"user@anything.example.com". The magic is in lines 4-5. </p> + +<li> <p> Lines 11, 13-16: Define the list of valid addresses in the +"example.com" domain that can receive mail from the Internet. This +prevents the mail queue from filling up with undeliverable +MAILER-DAEMON messages. If you can't maintain a list of valid +recipients then you must specify "relay_recipient_maps =" (that +is, an empty value), or you must specify an "@example.com x" +wild-card in the relay_recipients table. </p> + +<li> <p> Lines 12, 19-20: Route mail for "example.com" to the inside +gateway machine. The <tt>[]</tt> forces Postfix to do no MX lookup. +</p> + +</ul> + +<p>Specify <b>dbm</b> instead of <b>hash</b> if your system uses +<b>dbm</b> files instead of <b>db</b> files. To find out what lookup +tables Postfix supports, use the command "<b>postconf -m</b>". </p> + +<p> Execute the command "<b>postmap /etc/postfix/relay_recipients</b>" +whenever you change the relay_recipients table. </p> + +<p> Execute the command "<b>postmap /etc/postfix/transport</b>" +whenever you change the transport table. </p> + +<p> In some installations, there may be separate instances of Postfix +processing inbound and outbound mail on a multi-homed firewall. The +inbound Postfix instance has an SMTP server listening on the external +firewall interface, and the outbound Postfix instance has an SMTP server +listening on the internal interface. In such a configuration is it is +tempting to configure $inet_interfaces in each instance with just the +corresponding interface address. </p> + +<p> In most cases, using inet_interfaces in this way will not work, +because as documented in the $inet_interfaces reference manual, the +smtp(8) delivery agent will also use the specified interface address +as the source address for outbound connections and will be unable to +reach hosts on "the other side" of the firewall. The symptoms are that +the firewall is unable to connect to hosts that are in fact up. See the +inet_interfaces parameter documentation for suggested work-arounds.</p> + +<h2><a name="some_local">Delivering some but not all accounts +locally</a></h2> + +<p> A drawback of sending mail as "user@example.com" (instead of +"user@hostname.example.com") is that mail for "root" and other +system accounts is also sent to the central mailhost. In order to +deliver such accounts locally, you can set up virtual aliases as +follows: </p> + +<blockquote> +<pre> +1 /etc/postfix/main.cf: +2 virtual_alias_maps = hash:/etc/postfix/virtual +3 +4 /etc/postfix/virtual: +5 root root@localhost +6 . . . +</pre> +</blockquote> + +<p> Translation: </p> + +<ul> + +<li> <p> Line 5: As described in the virtual(5) manual page, the +bare name "root" matches "root@site" when "site" is equal to +$myorigin, when "site" is listed in $mydestination, or when it +matches $inet_interfaces or $proxy_interfaces. </p> + +</ul> + +<p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after +editing the file. </p> + +<h2><a name="intranet">Running Postfix behind a firewall</a></h2> + +<p> The simplest way to set up Postfix on a host behind a firewalled +network is to send all mail to a gateway host, and to let that mail +host take care of internal and external forwarding. Examples of that +are shown in the <a href="#local_network">local area network</a> +section above. A more sophisticated approach is to send only external +mail to the gateway host, and to send intranet mail directly. </p> + +<p> Note: this example requires Postfix version 2.0 and later. To find +out what Postfix version you have, execute the command "<b>postconf +mail_version</b>". </p> + +<p> The following example presents additional configuration. You +need to combine this with basic configuration information as +discussed in the first half of this document. </p> + +<blockquote> +<pre> + 1 /etc/postfix/main.cf: + 2 transport_maps = hash:/etc/postfix/transport + 3 relayhost = + 4 # Optional for a machine that isn't "always on" + 5 #fallback_relay = [gateway.example.com] + 6 + 7 /etc/postfix/transport: + 8 # Internal delivery. + 9 example.com : +10 .example.com : +11 # External delivery. +12 * smtp:[gateway.example.com] +</pre> +</blockquote> + +<p> Translation: </p> + +<ul> + +<li> <p> Lines 2, 7-12: Request that intranet mail is delivered +directly, and that external mail is given to a gateway. Obviously, +this example assumes that the organization uses DNS MX records +internally. The <tt>[]</tt> forces Postfix to do no MX lookup. +</p> + +<li> <p> Line 3: IMPORTANT: do not specify a relayhost in main.cf. +</p> + +<li> <p> Line 5: This prevents mail from being stuck in the queue +when the machine is turned off. Postfix tries to deliver mail +directly, and gives undeliverable mail to a gateway. </p> + +</ul> + +<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses +<b>dbm</b> files instead of <b>db</b> files. To find out what lookup +tables Postfix supports, use the command "<b>postconf -m</b>". </p> + +<p> Execute the command "<b>postmap /etc/postfix/transport</b>" whenever +you edit the transport table. </p> + +<h2><a name="backup">Configuring Postfix as primary or backup MX host for a remote site</a></h2> + +<p> This section presents additional configuration. You need to +combine this with basic configuration information as discussed in the +first half of this document. </p> + +<p> When your system is SECONDARY MX host for a remote site this +is all you need: </p> + +<blockquote> +<pre> + 1 DNS: + 2 the.backed-up.domain.tld IN MX 100 your.machine.tld. + 3 + 4 /etc/postfix/main.cf: + 5 relay_domains = . . . the.backed-up.domain.tld +<br> + 6a # Postfix 2.10 and later support separate relay control and + 7a # spam control. + 8a smtpd_relay_restrictions = + 9a permit_mynetworks reject_unauth_destination +10a smtpd_recipient_restrictions = ...spam blocking rules.... +<br> + 6b # Older configurations combine relay control and spam control. To + 7b # use this with Postfix ≥ 2.10 specify "smtpd_relay_restrictions=". + 8b smtpd_recipient_restrictions = + 9b permit_mynetworks reject_unauth_destination +10b ...spam blocking rules.... +<br> +11 # You must specify your NAT/proxy external address. +12 #proxy_interfaces = 1.2.3.4 +13 +14 relay_recipient_maps = hash:/etc/postfix/relay_recipients +15 +16 /etc/postfix/relay_recipients: +17 user1@the.backed-up.domain.tld x +18 user2@the.backed-up.domain.tld x +19 . . . +</pre> +</blockquote> + +<p> When your system is PRIMARY MX host for a remote site you +need the above, plus: </p> + +<blockquote> +<pre> +20 /etc/postfix/main.cf: +21 transport_maps = hash:/etc/postfix/transport +22 +23 /etc/postfix/transport: +24 the.backed-up.domain.tld relay:[their.mail.host.tld] +</pre> +</blockquote> + +<p> Important notes: + +<ul> + +<li><p>Do not list the.backed-up.domain.tld in mydestination.</p> + +<li><p>Do not list the.backed-up.domain.tld in virtual_alias_domains.</p> + +<li><p>Do not list the.backed-up.domain.tld in virtual_mailbox_domains.</p> + +<li> <p> Lines 1-9: Forward mail from the Internet for +"the.backed-up.domain.tld" to the primary MX host for that domain. +</p> + +<li> <p> Line 12: This is a must if Postfix receives mail via a +NAT relay or proxy that presents a different IP address to the +world than the local machine. </p> + +<li> <p> Lines 14-18: Define the list of valid addresses in the +"the.backed-up.domain.tld" domain. This prevents your mail queue +from filling up with undeliverable MAILER-DAEMON messages. If you +can't maintain a list of valid recipients then you must specify +"relay_recipient_maps =" (that is, an empty value), or you must +specify an "@the.backed-up.domain.tld x" wild-card in the +relay_recipients table. </p> + +<li> <p> Line 24: The <tt>[]</tt> forces Postfix to do no MX lookup. </p> + +</ul> + +<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses +<b>dbm</b> files instead of <b>db</b> files. To find out what lookup +tables Postfix supports, use the command "<b>postconf -m</b>". </p> + +<p> Execute the command "<b>postmap /etc/postfix/transport</b>" +whenever you change the transport table. </p> + +<p> NOTE for Postfix < 2.2: Do not use the fallback_relay feature +when relaying mail +for a backup or primary MX domain. Mail would loop between the +Postfix MX host and the fallback_relay host when the final destination +is unavailable. </p> + +<ul> + +<li> In main.cf specify "<tt>relay_transport = relay</tt>", + +<li> In master.cf specify "<tt>-o fallback_relay =</tt>" at the +end of the <tt>relay</tt> entry. + +<li> In transport maps, specify "<tt>relay:<i>nexthop...</i></tt>" +as the right-hand side for backup or primary MX domain entries. + +</ul> + +<p> These are default settings in Postfix version 2.2 and later. +</p> + +<h2><a name="dialup">Postfix on a dialup machine</a></h2> + +<p> This section applies to dialup connections that are down most +of the time. For dialup connections that are up 24x7, see the <a +href="#local_network">local area network</a> section above. </p> + +<p> This section presents additional configuration. You need to +combine this with basic configuration information as discussed in the +first half of this document. </p> + +<p> If you do not have your own hostname and IP address (usually +with dialup, cable TV or DSL connections) then you should also +study the section on "<a href="#fantasy">Postfix on hosts without +a real Internet hostname</a>". </p> + +<ul> + +<li> Route all outgoing mail to your network provider. + +<p> If your machine is disconnected most of the time, there isn't +a lot of opportunity for Postfix to deliver mail to hard-to-reach +corners of the Internet. It's better to give the mail to a machine +that is connected all the time. In the example below, the <tt>[]</tt> +prevents Postfix from trying to look up DNS MX records. </p> + +<pre> +/etc/postfix/main.cf: + relayhost = [smtprelay.someprovider.com] +</pre> + +<li> <p><a name="spontaneous_smtp">Disable spontaneous SMTP mail +delivery (if using on-demand dialup IP only).</a> </p> + +<p> Normally, Postfix attempts to deliver outbound mail at its convenience. +If your machine uses on-demand dialup IP, this causes your system +to place a telephone call whenever you submit new mail, and whenever +Postfix retries to deliver delayed mail. To prevent such telephone +calls from being placed, disable spontaneous SMTP mail deliveries. </p> + +<pre> +/etc/postfix/main.cf: + defer_transports = smtp (Only for on-demand dialup IP hosts) +</pre> + +<li> <p>Disable SMTP client DNS lookups (dialup LAN only).</p> + +<pre> +/etc/postfix/main.cf: + disable_dns_lookups = yes (Only for on-demand dialup IP hosts) +</pre> + +<li> Flush the mail queue whenever the Internet link is established. + +<p> Put the following command into your PPP or SLIP dialup scripts: </p> + +<pre> +/usr/sbin/sendmail -q (whenever the Internet link is up) +</pre> + +<p> The exact location of the Postfix sendmail command is system-specific. +Use the command "<b>postconf sendmail_path</b>" to find out where the +Postfix sendmail command is located on your machine. </p> + +<p> In order to find out if the mail queue is flushed, use something +like: </p> + +<pre> +#!/bin/sh + +# Start mail deliveries. +/usr/sbin/sendmail -q + +# Allow deliveries to start. +sleep 10 + +# Loop until all messages have been tried at least once. +while mailq | grep '^[^ ]*\*' >/dev/null +do + sleep 10 +done +</pre> + +<p> If you have disabled <a href="#spontaneous_smtp">spontaneous +SMTP mail delivery</a>, you also need to run the "<b>sendmail -q</b>" +command every now and then while the dialup link is up, so that +newly-posted mail is flushed from the queue. </p> + +</ul> + +<h2><a name="fantasy">Postfix on hosts without a real Internet +hostname</a></h2> + +<p> This section is for hosts that don't have their own Internet +hostname. Typically these are systems that get a dynamic IP address +via DHCP or via dialup. Postfix will let you send and receive mail +just fine between accounts on a machine with a fantasy name. However, +you cannot use a fantasy hostname in your email address when sending +mail into the Internet, because no-one would be able to reply to +your mail. In fact, more and more sites refuse mail addresses with +non-existent domain names. </p> + +<p> Note: the following information is Postfix version dependent. +To find out what Postfix version you have, execute the command +"<b>postconf mail_version</b>". </p> + +<h3>Solution 1: Postfix version 2.2 and later </h3> + +<p> Postfix 2.2 uses the generic(5) address mapping to replace +local fantasy email addresses by valid Internet addresses. This +mapping happens ONLY when mail leaves the machine; not when you +send mail between users on the same machine. </p> + +<p> The following example presents additional configuration. You +need to combine this with basic configuration information as +discussed in the first half of this document. </p> + +<blockquote> +<pre> +1 /etc/postfix/main.cf: +2 smtp_generic_maps = hash:/etc/postfix/generic +3 +4 /etc/postfix/generic: +5 his@localdomain.local hisaccount@hisisp.example +6 her@localdomain.local heraccount@herisp.example +7 @localdomain.local hisaccount+local@hisisp.example +</pre> +</blockquote> + +<p> When mail is sent to a remote host via SMTP: </p> + +<ul> + +<li> <p> Line 5 replaces <i>his@localdomain.local</i> by his ISP +mail address, </p> + +<li> <p> Line 6 replaces <i>her@localdomain.local</i> by her ISP +mail address, and </p> + +<li> <p> Line 7 replaces other local addresses by his ISP account, +with an address extension of +<i>local</i> (this example assumes +that the ISP supports "+" style address extensions). </p> + +</ul> + +<p>Specify <b>dbm</b> instead of <b>hash</b> if your system uses +<b>dbm</b> files instead of <b>db</b> files. To find out what lookup +tables Postfix supports, use the command "<b>postconf -m</b>". </p> + +<p> Execute the command "<b>postmap /etc/postfix/generic</b>" +whenever you change the generic table. </p> + +<h3>Solution 2: Postfix version 2.1 and earlier </h3> + +<p> The solution with older Postfix systems is to use valid +Internet addresses where possible, and to let Postfix map valid +Internet addresses to local fantasy addresses. With this, you can +send mail to the Internet and to local fantasy addresses, including +mail to local fantasy addresses that don't have a valid Internet +address of their own.</p> + +<p> The following example presents additional configuration. You +need to combine this with basic configuration information as +discussed in the first half of this document. </p> + +<blockquote> +<pre> + 1 /etc/postfix/main.cf: + 2 myhostname = hostname.localdomain + 3 mydomain = localdomain + 4 + 5 canonical_maps = hash:/etc/postfix/canonical + 6 + 7 virtual_alias_maps = hash:/etc/postfix/virtual + 8 + 9 /etc/postfix/canonical: +10 your-login-name your-account@your-isp.com +11 +12 /etc/postfix/virtual: +13 your-account@your-isp.com your-login-name +</pre> +</blockquote> + +<p> Translation: </p> + +<ul> + +<li> <p> Lines 2-3: Substitute your fantasy hostname here. Do not +use a domain name that is already in use by real organizations +on the Internet. See RFC 2606 for examples of domain +names that are guaranteed not to be owned by anyone. </p> + +<li> <p> Lines 5, 9, 10: This provides the mapping from +"your-login-name@hostname.localdomain" to "your-account@your-isp.com". +This part is required. </p> + +<li> <p> Lines 7, 12, 13: Deliver mail for "your-account@your-isp.com" +locally, instead of sending it to the ISP. This part is not required +but is convenient. + +</ul> + +<p>Specify <b>dbm</b> instead of <b>hash</b> if your system uses +<b>dbm</b> files instead of <b>db</b> files. To find out what lookup +tables Postfix supports, use the command "<b>postconf -m</b>". </p> + +<p> Execute the command "<b>postmap /etc/postfix/canonical</b>" +whenever you change the canonical table. </p> + +<p> Execute the command "<b>postmap /etc/postfix/virtual</b>" +whenever you change the virtual table. </p> + +</body> + +</html> diff --git a/proto/STRESS_README.html b/proto/STRESS_README.html new file mode 100644 index 0000000..30fa5f2 --- /dev/null +++ b/proto/STRESS_README.html @@ -0,0 +1,566 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Stress-Dependent Configuration</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +Stress-Dependent Configuration</h1> + +<hr> + +<h2>Overview </h2> + +<p> This document describes the symptoms of Postfix SMTP server +overload. It presents permanent main.cf changes to avoid overload +during normal operation, and temporary main.cf changes to cope with +an unexpected burst of mail. This document makes specific suggestions +for Postfix 2.5 and later which support stress-adaptive behavior, +and for earlier Postfix versions that don't. </p> + +<p> Topics covered in this document: </p> + +<ul> + +<li><a href="#overload"> Symptoms of Postfix SMTP server overload </a> + +<li><a href="#adapt"> Automatic stress-adaptive behavior </a> + +<li><a href="#concurrency"> Service more SMTP clients at the same time </a> + +<li><a href="#time"> Spend less time per SMTP client </a> + +<li><a href="#hangup"> Disconnect suspicious SMTP clients </a> + +<li><a href="#legacy"> Temporary measures for older Postfix releases </a> + +<li><a href="#feature"> Detecting support for stress-adaptive behavior </a> + +<li><a href="#forcing"> Forcing stress-adaptive behavior on or off </a> + +<li><a href="#other"> Other measures to off-load zombies </a> + +<li><a href="#credits"> Credits </a> + +</ul> + +<h2><a name="overload"> Symptoms of Postfix SMTP server overload </a></h2> + +<p> Under normal conditions, the Postfix SMTP server responds +immediately when an SMTP client connects to it; the time to deliver +mail is noticeable only with large messages. Performance degrades +dramatically when the number of SMTP clients exceeds the number of +Postfix SMTP server processes. When an SMTP client connects while +all Postfix SMTP server processes are busy, the client must wait +until a server process becomes available. </p> + +<p> SMTP server overload may be caused by a surge of legitimate +mail (example: a DNS registrar opens a new zone for registrations), +by mistake (mail explosion caused by a forwarding loop) or by malice +(worm outbreak, botnet, or other illegitimate activity). </p> + +<p> Symptoms of Postfix SMTP server overload are: </p> + +<ul> + +<li> <p> Remote SMTP clients experience a long delay before Postfix +sends the "220 hostname.example.com ESMTP Postfix" greeting. </p> + +<ul> + +<li> <p> NOTE: Broken DNS configurations can also cause lengthy +delays before Postfix sends "220 hostname.example.com ...". These +delays also exist when Postfix is NOT overloaded. </p> + +<li> <p> NOTE: To avoid "overload" delays for end-user mail +clients, enable the "submission" service entry in master.cf (present +since Postfix 2.1), and tell users to connect to this instead of +the public SMTP service. </p> + +</ul> + +<li> <p> The Postfix SMTP server logs an increased number of "lost +connection after CONNECT" events. This happens because remote SMTP +clients disconnect before Postfix answers the connection. </p> + +<ul> + +<li> <p> NOTE: A portscan for open SMTP ports can also result in +"lost connection ..." logfile messages. </p> + +</ul> + +<li> <p> Postfix 2.3 and later logs a warning that all server ports +are busy: </p> + +<pre> +Oct 3 20:39:27 spike postfix/master[28905]: warning: service "smtp" + (25) has reached its process limit "30": new clients may experience + noticeable delays +Oct 3 20:39:27 spike postfix/master[28905]: warning: to avoid this + condition, increase the process count in master.cf or reduce the + service time per client +Oct 3 20:39:27 spike postfix/master[28905]: warning: see + <a href="http://www.postfix.org/STRESS_README.html">http://www.postfix.org/STRESS_README.html</a> for examples of + stress-adapting configuration settings +</pre> + +</ul> + +<p> Legitimate mail that doesn't get through during an episode of +Postfix SMTP server overload is not necessarily lost. It should +still arrive once the situation returns to normal, as long as the +overload condition is temporary. </p> + +<h2><a name="adapt"> Automatic stress-adaptive behavior </a></h2> + +<p> Postfix version 2.5 introduces automatic stress-adaptive behavior. +It works as follows. When a "public" network service such as the +SMTP server runs into an "all server ports are busy" condition, the +Postfix master(8) daemon logs a warning, restarts the service +(without interrupting existing network sessions), and runs the +service with "-o stress=yes" on the server process command line: +</p> + +<blockquote> +<pre> +80821 ?? S 0:00.24 smtpd -n smtp -t inet -u -c -o stress=yes +</pre> +</blockquote> + +<p> Normally, the Postfix master(8) daemon runs such a service with +"-o stress=" on the command line (i.e. with an empty parameter +value): </p> + +<blockquote> +<pre> +83326 ?? S 0:00.28 smtpd -n smtp -t inet -u -c -o stress= +</pre> +</blockquote> + +<p> You won't see "-o stress" command-line parameters with services +that have local clients only. These include services internal to +Postfix such as the queue manager, and services that listen on a +loopback interface only, such as after-filter SMTP services. </p> + +<p> The "stress" parameter value is the key to making main.cf +parameter settings stress adaptive. The following settings are the +default with Postfix 2.6 and later. </p> + +<blockquote> +<pre> +1 smtpd_timeout = ${stress?{10}:{300}}s +2 smtpd_hard_error_limit = ${stress?{1}:{20}} +3 smtpd_junk_command_limit = ${stress?{1}:{100}} +4 # Parameters added after Postfix 2.6: +5 smtpd_per_record_deadline = ${stress?{yes}:{no}} +6 smtpd_starttls_timeout = ${stress?{10}:{300}}s +7 address_verify_poll_count = ${stress?{1}:{3}} +</pre> +</blockquote> + +<p> Postfix versions before 3.0 use the older form ${stress?x}${stress:y} +instead of the newer form ${stress?{x}:{y}}. </p> + +<p> The syntax of ${name?{value}:{value}}, ${name?value} and +${name:value} is explained at the beginning of the postconf(5) +manual page. </p> + +<p> Translation: <p> + +<ul> + +<li> <p> Line 1: under conditions of stress, use an smtpd_timeout +value of 10 seconds instead of the default 300 seconds. Experience +on the postfix-users list from a variety of sysadmins shows that +reducing the "normal" smtpd_timeout to 60s is unlikely to affect +legitimate clients. However, it is unlikely to become the Postfix +default because it's not RFC compliant. Setting smtpd_timeout to +10s or even 5s under stress will still allow most +legitimate clients to connect and send mail, but may delay mail +from some clients. No mail should be lost, as long as this measure +is used only temporarily. </p> + +<li> <p> Line 2: under conditions of stress, use an smtpd_hard_error_limit +of 1 instead of the default 20. This disconnects clients +after a single error, giving other clients a chance to connect. +However, this may cause significant delays with legitimate mail, +such as a mailing list that contains a few no-longer-active user +names that didn't bother to unsubscribe. No mail should be lost, +as long as this measure is used only temporarily. </p> + +<li> <p> Line 3: under conditions of stress, use an +smtpd_junk_command_limit of 1 instead of the default 100. This +prevents clients from keeping connections open by repeatedly +sending HELO, EHLO, NOOP, RSET, VRFY or ETRN commands. </p> + +<li> <p> Line 5: under conditions of stress, change the behavior +of smtpd_timeout and smtpd_starttls_timeout, from a time limit per +read or write system call, to a time limit to send or receive a +complete record (an SMTP command line, SMTP response line, SMTP +message content line, or TLS protocol message). </p> + +<li> <p> Line 6: under conditions of stress, reduce the time limit +for TLS protocol handshake messages to 10 seconds, from the default +value of 300 seconds. See also the smtpd_timeout discussion above. +</p> + +<li> <p> Line 7: under conditions of stress, do not wait up to 6 +seconds for the completion of an address verification probe. If the +result is not already in the address verification cache, reply +immediately with $unverified_recipient_tempfail_action or +$unverified_sender_tempfail_action. No mail should be lost, as long +as this measure is used only temporarily. </p> + +</ul> + +<p> NOTE: Please keep in mind that the stress-adaptive feature is +a fairly desperate measure to keep <b>some</b> legitimate mail +flowing under overload conditions. If a site is reaching the SMTP +server process limit when there isn't an attack or bot flood +occurring, then either the process limit needs to be raised or more +hardware needs to be added. </p> + +<h2><a name="concurrency"> Service more SMTP clients at the same time </a> </h2> + +<p> This section and the ones that follow discuss permanent measures +against mail server overload. </p> + +<p> One measure to avoid the "all server processes busy" condition +is to service more SMTP clients simultaneously. For this you need +to increase the number of Postfix SMTP server processes. This will +improve the +responsiveness for remote SMTP clients, as long as the server machine +has enough hardware and software resources to run the additional +processes, and as long as the file system can keep up with the +additional load. </p> + +<ul> + +<li> <p> You increase the number of SMTP server processes either +by increasing the default_process_limit in main.cf (line 3 below), +or by increasing the SMTP server's "maxproc" field in master.cf +(line 10 below). Either way, you need to issue a "postfix reload" +command to make the change effective. </p> + +<li> <p> Process limits above 1000 require Postfix version 2.4 or +later, and an operating system that supports kernel-based event +filters (BSD kqueue(2), Linux epoll(4), or Solaris /dev/poll). +</p> + +<li> <p> More processes use more memory. You can reduce the Postfix +memory footprint by using cdb: +lookup tables instead of Berkeley DB's hash: or btree: tables. </p> + +<pre> + 1 /etc/postfix/main.cf: + 2 # Raise the global process limit, 100 since Postfix 2.0. + 3 default_process_limit = 200 + 4 + 5 /etc/postfix/master.cf: + 6 # ============================================================= + 7 # service type private unpriv chroot wakeup maxproc command + 8 # ============================================================= + 9 # Raise the SMTP service process limit only. +10 smtp inet n - n - 200 smtpd +</pre> + +<li> <p> NOTE: older versions of the SMTPD_POLICY_README document +contain a mistake: they configure a fixed number of policy daemon +processes. When you raise the SMTP server's "maxproc" field in +master.cf, SMTP server processes will report problems when connecting +to policy server processes, because there aren't enough of them. +Examples of errors are "connection refused" or "operation timed +out". </p> + +<p> To fix, edit master.cf and specify a zero "maxproc" field +in all policy server entries; see line 6 in the example below. +Issue a "postfix reload" command to make the change effective. </p> + +<pre> +1 /etc/postfix/master.cf: +2 # ============================================================= +3 # service type private unpriv chroot wakeup maxproc command +4 # ============================================================= +5 # Disable the policy service process limit. +6 policy unix - n n - 0 spawn +7 user=nobody argv=/some/where/policy-server +</pre> + +</ul> + +<h2><a name="time"> Spend less time per SMTP client </a></h2> + +<p> When increasing the number of SMTP server processes is not +practical, you can improve Postfix server responsiveness by eliminating +delays. When Postfix spends less time per SMTP session, the same +number of SMTP server processes can service more clients in a given +amount of time. </p> + +<ul> + +<li> <p> Eliminate non-functional RBL lookups (blocklists that are +no longer in operation). These lookups can degrade performance. +Postfix logs a warning when an RBL server does not respond. </p> + +<li> <p> Eliminate redundant RBL lookups (people often use multiple +Spamhaus RBLs that include each other). To find out whether RBLs +include other RBLs, look up the websites that document the RBL's +policies. </p> + +<li> <p> Eliminate header_checks and body_checks, and keep just a few +emergency patterns to block the latest worm explosion or backscatter +mail. See BACKSCATTER_README for examples of the latter. + +<li> <p> Group your header_checks and body_checks patterns to avoid +unnecessary pattern matching operations: + +<pre> + 1 /etc/postfix/header_checks: + 2 if /^Subject:/ + 3 /^Subject: virus found in mail from you/ reject + 4 /^Subject: ..other../ reject + 5 endif + 6 + 7 if /^Received:/ + 8 /^Received: from (postfix\.org) / reject forged client name in received header: $1 + 9 /^Received: from ..other../ reject .... +10 endif +</pre> + +</ul> + +<h2><a name="hangup"> Disconnect suspicious SMTP clients </a></h2> + +<p> Under conditions of overload you can improve Postfix SMTP server +responsiveness by hanging up on suspicious clients, so that other +clients get a chance to talk to Postfix. </p> + +<ul> + +<li> <p> Use "521" SMTP reply codes (Postfix 2.6 and later) or "421" +(Postfix 2.3-2.5) to hang up on clients that that match botnet-related +RBLs (see next bullet) or that match selected non-RBL restrictions +such as SMTP access maps. The Postfix SMTP server will reject mail +and disconnect without waiting for the remote SMTP client to send +a QUIT command. </p> + +<li> <p> To hang up connections from denylisted zombies, you can +set specific Postfix SMTP server reject codes for specific RBLs, +and for individual responses from specific RBLs. We'll use +zen.spamhaus.org as an example; by the time you read this document, +details may have changed. Right now, their documents say that a +response of 127.0.0.10 or 127.0.0.11 indicates a dynamic client IP +address, which means that the machine is probably running a bot of +some kind. To give a 521 response instead of the default 554 +response, use something like: </p> + +<pre> + 1 /etc/postfix/main.cf: + 2 smtpd_client_restrictions = + 3 permit_mynetworks + 4 reject_rbl_client zen.spamhaus.org=127.0.0.10 + 5 reject_rbl_client zen.spamhaus.org=127.0.0.11 + 6 reject_rbl_client zen.spamhaus.org + 7 + 8 rbl_reply_maps = hash:/etc/postfix/rbl_reply_maps + 9 +10 /etc/postfix/rbl_reply_maps: +11 # With Postfix 2.3-2.5 use "421" to hang up connections. +12 zen.spamhaus.org=127.0.0.10 521 4.7.1 Service unavailable; +13 $rbl_class [$rbl_what] blocked using +14 $rbl_domain${rbl_reason?; $rbl_reason} +15 +16 zen.spamhaus.org=127.0.0.11 521 4.7.1 Service unavailable; +17 $rbl_class [$rbl_what] blocked using +18 $rbl_domain${rbl_reason?; $rbl_reason} +</pre> + +<p> Although the above example shows three RBL lookups (lines 4-6), +Postfix will only do a single DNS query, so it does not affect the +performance. </p> + +<li> <p> With Postfix 2.3-2.5, use reply code 421 (521 will not +cause Postfix to disconnect). The down-side of replying with 421 +is that it works only for zombies and other malware. If the client +is running a real MTA, then it may connect again several times until +the mail expires in its queue. When this is a problem, stick with +the default 554 reply, and use "smtpd_hard_error_limit = 1" as +described below. </p> + +<li> <p> You can automatically turn on the above overload measure +with Postfix 2.5 and later, or with earlier releases that contain +the stress-adaptive behavior source code patch from the mirrors +listed at http://www.postfix.org/download.html. Simply replace line +above 8 with: </p> + +<pre> + 8 rbl_reply_maps = ${stress?hash:/etc/postfix/rbl_reply_maps} +</pre> + +</ul> + +<p> More information about automatic stress-adaptive behavior is +in section "<a href="#adapt">Automatic stress-adaptive behavior</a>". +</p> + +<h2><a name="legacy"> Temporary measures for older Postfix releases </a></h2> + +<p> See the section "<a href="#adapt">Automatic stress-adaptive +behavior</a>" if you are running Postfix version 2.5 or later, or +if you have applied the source code patch for stress-adaptive +behavior from the mirrors listed at http://www.postfix.org/download.html. +</p> + +<p> The following measures can be applied temporarily during overload. +They still allow <b>most</b> legitimate clients to connect and send +mail, but may affect some legitimate clients. </p> + +<ul> + +<li> <p> Reduce smtpd_timeout (default: 300s). Experience on the +postfix-users list from a variety of sysadmins shows that reducing +the "normal" smtpd_timeout to 60s is unlikely to affect legitimate +clients. However, it is unlikely to become the Postfix default +because it's not RFC compliant. Setting smtpd_timeout to 10s (line +2 below) or even 5s under stress will still allow <b>most</b> +legitimate clients to connect and send mail, but may delay mail +from some clients. No mail should be lost, as long as this measure +is used only temporarily. </p> + +<li> <p> Reduce smtpd_hard_error_limit (default: 20). Setting this +to 1 under stress (line 3 below) helps by disconnecting clients +after a single error, giving other clients a chance to connect. +However, this may cause significant delays with legitimate mail, +such as a mailing list that contains a few no-longer-active user +names that didn't bother to unsubscribe. No mail should be lost, +as long as this measure is used only temporarily. </p> + +<li> <p> Use an smtpd_junk_command_limit of 1 instead of the default +100. This prevents clients from keeping idle connections open by +repeatedly sending NOOP or RSET commands. </p> + +</ul> + +<blockquote> +<pre> +1 /etc/postfix/main.cf: +2 smtpd_timeout = 10 +3 smtpd_hard_error_limit = 1 +4 smtpd_junk_command_limit = 1 +</pre> +</blockquote> + +<p> With these measures, no mail should be lost, as long +as these measures are used only temporarily. The next section of +this document introduces a way to automate this process. </p> + +<h2><a name="feature"> Detecting support for stress-adaptive behavior </a></h2> + +<p> To find out if your Postfix installation supports stress-adaptive +behavior, use the "ps" command, and look for the smtpd processes. +Postfix has stress-adaptive support when you see "-o stress=" or +"-o stress=yes" command-line options. Remember that Postfix never +enables stress-adaptive behavior on servers that listen on local +addresses only. </p> + +<p> The following example is for FreeBSD or Linux. On Solaris, HP-UX +and other System-V flavors, use "ps -ef" instead of "ps ax". </p> + +<blockquote> +<pre> +$ ps ax|grep smtpd +83326 ?? S 0:00.28 smtpd -n smtp -t inet -u -c -o stress= +84345 ?? Ss 0:00.11 /usr/bin/perl /usr/libexec/postfix/smtpd-policy.pl +</pre> +</blockquote> + +<p> You can't use postconf(1) to detect stress-adaptive support. +The postconf(1) command ignores the existence of the stress parameter +in main.cf, because the parameter has no effect there. Command-line +"-o parameter" settings always take precedence over main.cf parameter +settings. <p> + +<p> If you configure stress-adaptive behavior in main.cf when it +isn't supported, nothing bad will happen. The processes will run +as if the stress parameter always has an empty value. </p> + +<h2><a name="forcing"> Forcing stress-adaptive behavior on or off </a></h2> + +<p> You can manually force stress-adaptive behavior on, by adding +a "-o stress=yes" command-line option in master.cf. This can be +useful for testing overrides on the SMTP service. Issue "postfix +reload" to make the change effective. </p> + +<p> Note: setting the stress parameter in main.cf has no effect for +services that accept remote connections. </p> + +<blockquote> +<pre> +1 /etc/postfix/master.cf: +2 # ============================================================= +3 # service type private unpriv chroot wakeup maxproc command +4 # ============================================================= +5 # +6 smtp inet n - n - - smtpd +7 -o stress=yes +8 -o . . . +</pre> +</blockquote> + +<p> To permanently force stress-adaptive behavior off with a specific +service, specify "-o stress=" on its master.cf command line. This +may be desirable for the "submission" service. Issue "postfix reload" +to make the change effective. </p> + +<p> Note: setting the stress parameter in main.cf has no effect for +services that accept remote connections. </p> + +<blockquote> +<pre> +1 /etc/postfix/master.cf: +2 # ============================================================= +3 # service type private unpriv chroot wakeup maxproc command +4 # ============================================================= +5 # +6 submission inet n - n - - smtpd +7 -o stress= +8 -o . . . +</pre> +</blockquote> + +<h2><a name="other"> Other measures to off-load zombies </a> </h2> + +<p> The postscreen(8) daemon, introduced with Postfix 2.8, provides +additional protection against mail server overload. One postscreen(8) +process handles multiple inbound SMTP connections, and decides which +clients may talk to a Postfix SMTP server process. By keeping +spambots away, postscreen(8) leaves more SMTP server processes +available for legitimate clients, and delays the onset of server +overload conditions. </p> + +<h2><a name="credits"> Credits </a></h2> + +<ul> + +<li> Thanks to the postfix-users mailing list members for sharing +early experiences with the stress-adaptive feature. + +<li> The RBL example and several other paragraphs of text were +adapted from postfix-users postings by Noel Jones. + +<li> Wietse implemented stress-adaptive behavior as the smallest +possible patch while he should be working on other things. + +</ul> + +</body> </html> diff --git a/proto/TLS_LEGACY_README.html b/proto/TLS_LEGACY_README.html new file mode 100644 index 0000000..dacf1c1 --- /dev/null +++ b/proto/TLS_LEGACY_README.html @@ -0,0 +1,1606 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix legacy TLS Support </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix legacy TLS Support +</h1> + +<hr> + +<h2> NOTE </h2> + +<p> This document describes an old TLS user interface that is based +on a third-party TLS patch by Lutz Jänicke. As of Postfix +version 2.3, the old user interface still exists to allow migration +from earlier Postfix releases, but its functionality is frozen. </p> + +<h2> What Postfix TLS support does for you </h2> + +<p> Transport Layer Security (TLS, formerly called SSL) provides +certificate-based authentication and encrypted sessions. An +encrypted session protects the information that is transmitted with +SMTP mail or with SASL authentication. + +<p> Postfix version 2.2 introduces support for TLS as described in +RFC 3207. TLS Support for older Postfix versions was available as +an add-on patch. The section "<a href="#compat">Compatibility with +Postfix < 2.2 TLS support</a>" below discusses the differences +between these implementations. </p> + +<p> Topics covered in this document: </p> + +<ul> + +<li><a href="#how">How Postfix TLS support works</a> + +<li><a href="#build_tls">Building Postfix with TLS support</a> + +<li><a href="#server_tls">SMTP Server specific settings</a> + +<li> <a href="#client_tls">SMTP Client specific settings</a> + +<li><a href="#tlsmgr_controls"> TLS manager specific settings </a> + +<li><a href="#problems"> Reporting problems </a> + +<li><a href="#compat">Compatibility with Postfix < 2.2 TLS support</a> + +<li><a href="#credits"> Credits </a> + +</ul> + +<p> And last but not least, for the impatient: </p> + +<ul> + +<li><a href="#quick-start">Getting started, quick and dirty</a> + +</ul> + +<h2><a name="how">How Postfix TLS support works</a></h2> + +<p> The diagram below shows the main elements of the Postfix TLS +architecture and their relationships. Colored boxes with numbered +names represent Postfix daemon programs. Other colored boxes +represent storage elements. </p> + +<ul> + +<li> <p> The smtpd(8) server implements the SMTP over TLS server +side. </p> + +<li> <p> The smtp(8) client implements the SMTP over TLS client +side. </p> + +<li> <p> The tlsmgr(8) server maintains the pseudo-random number +generator (PRNG) that seeds the TLS engines in the smtpd(8) server +and smtp(8) client processes, and maintains the TLS session key +cache files. </p> + +</ul> + +<table> + +<tr> <td>Network<tt>-> </tt> </td> <td align="center" +bgcolor="#f0f0ff"> <br> <a href="smtpd.8.html">smtpd(8)</a> <br> </td> <td colspan="2"> + +<tt> <---seed---<br><br><-session-> </tt> </td> <td +align="center" bgcolor="#f0f0ff"> <br> <a href="tlsmgr.8.html">tlsmgr(8)</a> <br> </td> +<td colspan="3"> <tt> ---seed---><br> <br><-session-> + +</tt> </td> <td align="center" bgcolor="#f0f0ff"> <br> <a href="smtp.8.html">smtp(8)</a> <br> + </td> <td> <tt> -></tt>Network </td> </tr> + +<tr> <td colspan="3"> </td> <td align="right"> <table> <tr> <td> + +</td> <td> / </td> </tr> <tr> <td> / </td> <td> </td> </tr> </table> +</td> <td align="center"> |<br> |</td> <td align="left"> <table> + +<tr> <td> \ </td> <td> </td> </tr> <tr> <td> </td> <td> \ </td> +</tr> </table> </td> <td colspan="3"> </td> </tr> + +<tr> <td colspan="2"> </td> <td align="center" bgcolor="#f0f0ff"> +smtpd<br> session<br> key cache </td> <td> </td> <td align="center" +bgcolor="#f0f0ff"> PRNG<br> state <br>file </td> <td> </td> <td +align="center" bgcolor="#f0f0ff"> smtp<br> session<br> key cache +</td> + +<td colspan="2"> </td> </tr> + +</table> + +<h2><a name="build_tls">Building Postfix with TLS support</a></h2> + +<p> To build Postfix with TLS support, first we need to generate +the <tt>make(1)</tt> files with the necessary definitions. This is +done by invoking the command "<tt>make makefiles</tt>" in the Postfix +top-level directory and with arguments as shown next. </p> + +<p> <b> NOTE: Do not use Gnu TLS. It will spontaneously terminate +a Postfix daemon process with exit status code 2, instead of allowing +Postfix to 1) report the error to the maillog file, and to 2) provide +plaintext service where this is appropriate. </b> </p> + +<ul> + +<li> <p> If the OpenSSL include files (such as <tt>ssl.h</tt>) are +in directory <tt>/usr/include/openssl</tt>, and the OpenSSL libraries +(such as <tt>libssl.so</tt> and <tt>libcrypto.so</tt>) are in +directory <tt>/usr/lib</tt>: </p> + +<blockquote> +<pre> +% <b>make tidy</b> # if you have left-over files from a previous build +% <b>make makefiles CCARGS="-DUSE_TLS" AUXLIBS="-lssl -lcrypto"</b> +</pre> +</blockquote> + +<li> <p> If the OpenSSL include files (such as <tt>ssl.h</tt>) are +in directory <tt>/usr/local/include/openssl</tt>, and the OpenSSL +libraries (such as <tt>libssl.so</tt> and <tt>libcrypto.so</tt>) +are in directory <tt>/usr/local/lib</tt>: </p> + +<blockquote> +<pre> +% <b>make tidy</b> # if you have left-over files from a previous build +% <b>make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \ + AUXLIBS="-L/usr/local/lib -lssl -lcrypto" </b> +</pre> +</blockquote> + +<p> On Solaris, specify the <tt>-R</tt> option as shown below: + +<blockquote> +<pre> +% <b>make tidy</b> # if you have left-over files from a previous build +% <b>make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \ + AUXLIBS="-R/usr/local/lib -L/usr/local/lib -lssl -lcrypto" </b> +</pre> +</blockquote> + +</ul> + +<p> If you need to apply other customizations (such as Berkeley DB +databases, MySQL, PosgreSQL, LDAP or SASL), see the respective +Postfix README documents, and combine their "<tt>make makefiles</tt>" +instructions with the instructions above: </p> + +<blockquote> +<pre> +% <b>make tidy</b> # if you have left-over files from a previous build +% <b>make makefiles CCARGS="-DUSE_TLS \ + <i>(other -D or -I options)</i>" \ + AUXLIBS="-lssl -lcrypto \ + <i>(other -l options for libraries in /usr/lib)</i> \ + <i>(-L/path/name + -l options for other libraries)</i>"</b> +</pre> +</blockquote> + +<p> To complete the build process, see the Postfix INSTALL +instructions. Postfix has TLS support turned off by default, so +you can start using Postfix as soon as it is installed. </p> + +<h2><a name="server_tls">SMTP Server specific settings</a></h2> + +<p> Topics covered in this section: </p> + +<ul> + +<li><a href="#server_cert_key">Server-side certificate and private +key configuration </a> + +<li><a href="#server_logging"> Server-side TLS activity logging +</a> + +<li><a href="#server_enable">Enabling TLS in the Postfix SMTP server </a> + +<li><a href="#server_vrfy_client">Client certificate verification</a> + +<li><a href="#server_tls_auth">Supporting AUTH over TLS only</a> + +<li><a href="#server_tls_cache">Server-side TLS session cache</a> + +<li><a href="#server_access">Server access control</a> + +<li><a href="#server_cipher">Server-side cipher controls</a> + +<li><a href="#server_misc"> Miscellaneous server controls</a> + +</ul> + +<h3><a name="server_cert_key">Server-side certificate and private +key configuration </a> </h3> + +<p> In order to use TLS, the Postfix SMTP server needs a certificate +and a private key. Both must be in "pem" format. The private key +must not be encrypted, meaning: the key must be accessible without +a password. Both certificate and private key may be in the same +file. </p> + +<p> Both RSA and DSA certificates are supported. Typically you will +only have RSA certificates issued by a commercial CA. In addition, +the tools supplied with OpenSSL will by default issue RSA certificates. +You can have both at the same time, in which case the cipher used +determines which certificate is presented. For Netscape and OpenSSL +clients without special cipher choices, the RSA certificate is +preferred. </p> + +<p> In order for remote SMTP clients to check the Postfix SMTP +server certificates, the CA certificate (in case of a certificate +chain, all CA certificates) must be available. You should add +these certificates to the server certificate, the server certificate +first, then the issuing CA(s). </p> + +<p> Example: the certificate for "server.dom.ain" was issued by +"intermediate CA" which itself has a certificate issued by "root +CA". Create the server.pem file with: </p> + +<blockquote> +<pre> +% <b>cat server_cert.pem intermediate_CA.pem > server.pem</b> +</pre> +</blockquote> + +<p> A Postfix SMTP server certificate supplied here must be usable +as an SSL server certificate and hence pass the "openssl verify -purpose +sslserver ..." test. </p> + +<p> A client that trusts the root CA has a local copy of the root +CA certificate, so it is not necessary to include the root CA +certificate here. Leaving it out of the "server.pem" file reduces +the overhead of the TLS exchange. </p> + +<p> If you want the Postfix SMTP server to accept remote SMTP client +certificates issued by these CAs, append the root certificate to +$smtpd_tls_CAfile or install it in the $smtpd_tls_CApath directory. When +you configure trust in a root CA, it is not necessary to explicitly trust +intermediary CAs signed by the root CA, unless $smtpd_tls_ccert_verifydepth +is less than the number of CAs in the certificate chain for the clients +of interest. With a verify depth of 1 you can only verify certificates +directly signed by a trusted CA, and all trusted intermediary CAs need to +be configured explicitly. With a verify depth of 2 you can verify clients +signed by a root CA or a direct intermediary CA (so long as the client +is correctly configured to supply its intermediate CA certificate). </p> + +<p> RSA key and certificate examples: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_cert_file = /etc/postfix/server.pem + smtpd_tls_key_file = $smtpd_tls_cert_file +</pre> +</blockquote> + +<p> Their DSA counterparts: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_dcert_file = /etc/postfix/server-dsa.pem + smtpd_tls_dkey_file = $smtpd_tls_dcert_file +</pre> +</blockquote> + +<p> To verify a remote SMTP client certificate, the Postfix SMTP +server needs to trust the certificates of the issuing Certification +Authorities. These certificates in "pem" format can be stored in a +single $smtpd_tls_CAfile or in multiple files, one CA per file in +the $smtpd_tls_CApath directory. If you use a directory, don't forget +to create the necessary "hash" links with: </p> + +<blockquote> +<pre> +# <b>$OPENSSL_HOME/bin/c_rehash <i>/path/to/directory</i> </b> +</pre> +</blockquote> + +<p> The $smtpd_tls_CAfile contains the CA certificates of one or +more trusted CAs. The file is opened (with root privileges) before +Postfix enters the optional chroot jail and so need not be accessible +from inside the chroot jail. </p> + +<p> Additional trusted CAs can be specified via the $smtpd_tls_CApath +directory, in which case the certificates are read (with $mail_owner +privileges) from the files in the directory when the information +is needed. Thus, the $smtpd_tls_CApath directory needs to be +accessible inside the optional chroot jail. </p> + +<p> When you configure Postfix to request client certificates (by +setting $smtpd_tls_ask_ccert = yes), any certificates in +$smtpd_tls_CAfile are sent to the client, in order to allow it to +choose an identity signed by a CA you trust. If no $smtpd_tls_CAfile +is specified, no preferred CA list is sent, and the client is free +to choose an identity signed by any CA. Many clients use a fixed +identity regardless of the preferred CA list and you may be able +to reduce TLS negotiation overhead by installing client CA certificates +mostly or only in $smtpd_tls_CApath. In the latter case you need +not specify a $smtpd_tls_CAfile. </p> + +<p> Note, that unless client certificates are used to allow greater +access to TLS authenticated clients, it is best to not ask for +client certificates at all, as in addition to increased overhead +some clients (notably in some cases qmail) are unable to complete +the TLS handshake when client certificates are requested. </p> + +<p> Example: </p> +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_CAfile = /etc/postfix/CAcert.pem + smtpd_tls_CApath = /etc/postfix/certs +</pre> +</blockquote> + +<h3><a name="server_logging"> Server-side TLS activity logging </a> </h3> + +<p> To get additional information about Postfix SMTP server TLS +activity you can increase the loglevel from 0..4. Each logging +level also includes the information that is logged at a lower +logging level. </p> + +<blockquote> + +<table> + +<tr> <td> 0 </td> <td> Disable logging of TLS activity.</td> </tr> + +<tr> <td> 1 </td> <td> Log TLS handshake and certificate information. +</td> </tr> + +<tr> <td> 2 </td> <td> Log levels during TLS negotiation. </td> +</tr> + +<tr> <td> 3 </td> <td> Log hexadecimal and ASCII dump of TLS +negotiation process </td> </tr> + +<tr> <td> 4 </td> <td> Log hexadecimal and ASCII dump of complete +transmission after STARTTLS </td> </tr> + +</table> + +</blockquote> + +<p> Use loglevel 3 only in case of problems. Use of loglevel 4 is +strongly discouraged. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_loglevel = 0 +</pre> +</blockquote> + +<p> To include information about the protocol and cipher used as +well as the client and issuer CommonName into the "Received:" +message header, set the smtpd_tls_received_header variable to true. +The default is no, as the information is not necessarily authentic. +Only information recorded at the final destination is reliable, +since the headers may be changed by intermediate servers. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_received_header = yes +</pre> +</blockquote> + +<h3><a name="server_enable">Enabling TLS in the Postfix SMTP server </a> </h3> + +<p> By default, TLS is disabled in the Postfix SMTP server, so no +difference to plain Postfix is visible. Explicitly switch it on +using "smtpd_use_tls = yes". </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_use_tls = yes +</pre> +</blockquote> + +<p> With this, Postfix SMTP server announces STARTTLS support to +SMTP clients, but does not require that clients use TLS encryption. +</p> + +<p> Note: when an unprivileged user invokes "sendmail -bs", STARTTLS +is never offered due to insufficient privileges to access the server +private key. This is intended behavior. </p> + +<p> You can ENFORCE the use of TLS, so that the Postfix SMTP server +announces STARTTLS and accepts no mail without TLS encryption, by +setting "smtpd_enforce_tls = yes". According to RFC 2487 this MUST +NOT be applied in case of a publicly-referenced Postfix SMTP server. +This option is off by default and should only seldom be used. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_enforce_tls = yes +</pre> +</blockquote> + +<p> TLS is sometimes used in the non-standard "wrapper" mode where +a server always uses TLS, instead of announcing STARTTLS support +and waiting for clients to request TLS service. Some clients, namely +Outlook [Express] prefer the "wrapper" mode. This is true for OE +(Win32 < 5.0 and Win32 >=5.0 when run on a port<>25 +and OE (5.01 Mac on all ports). </p> + +<p> It is strictly discouraged to use this mode from main.cf. If +you want to support this service, enable a special port in master.cf +and specify "-o smtpd_tls_wrappermode = yes" as an smtpd(8) command +line option. Port 465 (smtps) was once chosen for this feature. +</p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + smtps inet n - n - - smtpd + -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes +</pre> +</blockquote> + +<h3><a name="server_vrfy_client">Client certificate verification</a> </h3> + +<p> To receive a remote SMTP client certificate, the Postfix SMTP +server must explicitly ask for one (any contents of $smtpd_tls_CAfile +are also sent to the client as a hint for choosing a certificate +from a suitable CA). Unfortunately, Netscape clients will either +complain if no matching client certificate is available or will +offer the user client a list of certificates to choose from. +Additionally some MTAs (notably some versions of qmail) are unable +to complete TLS negotiation when client certificates are requested, +and abort the SMTP session. So this option is "off" by default. +You will however need the certificate if you want to use certificate +based relaying with, for example, the permit_tls_clientcerts +feature. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_ask_ccert = no +</pre> +</blockquote> + +<p> You may also decide to REQUIRE a remote SMTP client certificate +before allowing TLS connections. This feature is included for +completeness, and implies "smtpd_tls_ask_ccert = yes". </p> + +<p> Please be aware, that this will inhibit TLS connections without +a proper client certificate and that it makes sense only when +non-TLS submission is disabled (smtpd_enforce_tls = yes). Otherwise, +clients could bypass the restriction by simply not using STARTTLS +at all. </p> + +<p> When TLS is not enforced, the connection will be handled as +if only "smtpd_tls_ask_ccert = yes" is specified, and a warning is +logged. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_req_ccert = no +</pre> +</blockquote> + +<p> A client certificate verification depth of 1 is sufficient if +the certificate is directly issued by a CA listed in the CA file. +The default value (5) should also suffice for longer chains (root +CA issues special CA which then issues the actual certificate...) +</p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_ccert_verifydepth = 5 +</pre> +</blockquote> + +<h3><a name="server_tls_auth">Supporting AUTH over TLS only</a></h3> + +<p> Sending AUTH data over an unencrypted channel poses a security +risk. When TLS layer encryption is required (smtpd_enforce_tls = +yes), the Postfix SMTP server will announce and accept AUTH only +after the TLS layer has been activated with STARTTLS. When TLS +layer encryption is optional (smtpd_enforce_tls = no), it may +however still be useful to only offer AUTH when TLS is active. To +maintain compatibility with non-TLS clients, the default is to +accept AUTH without encryption. In order to change this behavior, +set "smtpd_tls_auth_only = yes". </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_auth_only = no +</pre> +</blockquote> + +<h3><a name="server_tls_cache">Server-side TLS session cache</a> </h3> + +<p> The Postfix SMTP server and the remote SMTP client negotiate +a session, which takes some computer time and network bandwidth. +By default, this session information is cached only in the smtpd(8) +process actually using this session and is lost when the process +terminates. To share the session information between multiple +smtpd(8) processes, a persistent session cache can be used. You +can specify any database type that can store objects of several +kbytes and that supports the sequence operator. DBM databases are +not suitable because they can only store small objects. The cache +is maintained by the tlsmgr(8) process, so there is no problem with +concurrent access. Session caching is highly recommended, because +the cost of repeatedly negotiating TLS session keys is high.</p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_session_cache_database = btree:/etc/postfix/smtpd_scache +</pre> +</blockquote> + +<p> As of version 2.5, Postfix will no longer maintain this file +in a directory with non-Postfix ownership. As a migration aid, +attempts to open such files are redirected to the Postfix-owned +$data_directory, and a warning is logged. </p> + +<p> Cached Postfix SMTP server session information expires after +a certain amount of time. Postfix/TLS does not use the OpenSSL +default of 300s, but a longer time of 3600sec (=1 hour). RFC 2246 +recommends a maximum of 24 hours. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_session_cache_timeout = 3600s +</pre> +</blockquote> + +<h3><a name="server_access">Server access control</a> </h3> + +<p> Postfix TLS support introduces three additional features for +Postfix SMTP server access control: </p> + +<blockquote> + +<dl> + +<dt> permit_tls_clientcerts </dt> <dd> <p> Allow the remote SMTP +client SMTP request if the client certificate passes verification, +and if its fingerprint is listed in the list of client certificates +(see relay_clientcerts discussion below). </p> </dd> + +<dt> permit_tls_all_clientcerts </dt> <dd> <p> Allow the remote +client SMTP request if the client certificate passes verification. +</p> </dd> + +<dt> check_ccert_access type:table</dt> <dd> +<p> If the client certificate passes verification, use its fingerprint +as a key for the specified access(5) table. </p> </dd> + +</dl> + +</blockquote> + +<p> The permit_tls_all_clientcerts feature must be used with caution, +because it can result in too many access permissions. Use this +feature only if a special CA issues the client certificates, and +only if this CA is listed as a trusted CA. If other CAs are trusted, +any owner of a valid client certificate would be authorized. +The permit_tls_all_clientcerts feature can be practical for a +specially created email relay server. </p> + +<p> It is however recommended to stay with the permit_tls_clientcerts +feature and list all certificates via $relay_clientcerts, as +permit_tls_all_clientcerts does not permit any control when a +certificate must no longer be used (e.g. an employee leaving). </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_recipient_restrictions = + ... + permit_tls_clientcerts + reject_unauth_destination + ... +</pre> +</blockquote> + +<p> The Postfix list manipulation routines give special treatment +to whitespace and some other characters, making the use of certificate +names impractical. Instead we use the certificate fingerprints as +they are difficult to fake but easy to use for lookup. Postfix +lookup tables are in the form of (key, value) pairs. Since we only +need the key, the value can be chosen freely, e.g. the name of +the user or host.</p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + relay_clientcerts = hash:/etc/postfix/relay_clientcerts + +/etc/postfix/relay_clientcerts: + D7:04:2F:A7:0B:8C:A5:21:FA:31:77:E1:41:8A:EE:80 lutzpc.at.home +</pre> +</blockquote> + +<h3><a name="server_cipher">Server-side cipher controls</a> </h3> + +<p> To influence the Postfix SMTP server cipher selection scheme, +you can give cipherlist string. A detailed description would go +too far here; please refer to the OpenSSL documentation. If you +don't know what to do with it, simply don't touch it and leave the +(openssl-)compiled in default! </p> + +<p> DO NOT USE " to enclose the string, specify just the string!!! </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_cipherlist = DEFAULT +</pre> +</blockquote> + +<p> If you want to take advantage of ciphers with EDH, DH parameters +are needed. Instead of using the built-in DH parameters for both +1024bit and 512bit, it is better to generate "own" parameters, +since otherwise it would "pay" for a possible attacker to start a +brute force attack against parameters that are used by everybody. +For this reason, the parameters chosen are already different from +those distributed with other TLS packages. </p> + +<p> To generate your own set of DH parameters, use: </p> + +<blockquote> +<pre> +% <b>openssl gendh -out /etc/postfix/dh_1024.pem -2 -rand /var/run/egd-pool 1024</b> +% <b>openssl gendh -out /etc/postfix/dh_512.pem -2 -rand /var/run/egd-pool 512</b> +</pre> +</blockquote> + +<p> Examples: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_dh1024_param_file = /etc/postfix/dh_1024.pem + smtpd_tls_dh512_param_file = /etc/postfix/dh_512.pem +</pre> +</blockquote> + +<h3><a name="server_misc"> Miscellaneous server controls</a> </h3> + +<p> The smtpd_starttls_timeout parameter limits the time of Postfix +SMTP server write and read operations during TLS startup and shutdown +handshake procedures. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_starttls_timeout = 300s +</pre> +</blockquote> + +<h2> <a name="client_tls">SMTP Client specific settings</a> </h2> + +<p> Topics covered in this section: </p> + +<ul> + +<li><a href="#client_cert_key">Client-side certificate and private +key configuration </a> + +<li><a href="#client_logging"> Client-side TLS activity logging +</a> + +<li><a href="#client_tls_cache">Client-side TLS session cache</a> + +<li><a href="#client_tls_enable"> Enabling TLS in the Postfix SMTP client </a> + +<li><a href="#client_tls_require"> Requiring TLS encryption </a> + +<li><a href="#client_tls_nopeer"> Disabling server certificate verification </a> + +<li><a href="#client_tls_per_site"> Per-site TLS policies </a> + +<!-- +<li><a href="#client_tls_obs"> Obsolete per-site TLS policy support </a> +--> + +<li><a href="#client_tls_harden"> Closing a DNS loophole with <!-- legacy --> per-site TLS policies </a> + +<li><a href="#client_tls_discover"> Discovering servers that support TLS </a> + +<li><a href="#client_vrfy_server">Server certificate verification depth</a> + +<li> <a href="#client_cipher">Client-side cipher controls </a> + +<li> <a href="#client_misc"> Miscellaneous client controls </a> + +</ul> + +<h3><a name="client_cert_key">Client-side certificate and private +key configuration </a> </h3> + +<p> During TLS startup negotiation the Postfix SMTP client may present +a certificate to the remote SMTP server. The Netscape client is +rather clever here and lets the user select between only those +certificates that match CA certificates offered by the remote SMTP +server. As the Postfix SMTP client uses the "SSL_connect()" function +from the OpenSSL package, this is not possible and we have to choose +just one certificate. So for now the default is to use _no_ +certificate and key unless one is explicitly specified here. </p> + +<p> Both RSA and DSA certificates are supported. You can have both +at the same time, in which case the cipher used determines which +certificate is presented. </p> + +<p> It is possible for the Postfix SMTP client to use the same +key/certificate pair as the Postfix SMTP server. If a certificate +is to be presented, it must be in "pem" format. The private key +must not be encrypted, meaning: it must be accessible without +a password. Both parts (certificate and private key) may be in the +same file. </p> + +<p> In order for remote SMTP servers to verify the Postfix SMTP +client certificates, the CA certificate (in case of a certificate +chain, all CA certificates) must be available. You should add +these certificates to the client certificate, the client certificate +first, then the issuing CA(s). </p> + +<p> Example: the certificate for "client.example.com" was issued by +"intermediate CA" which itself has a certificate of "root CA". +Create the client.pem file with: </p> + +<blockquote> +<pre> +% <b>cat client_cert.pem intermediate_CA.pem > client.pem </b> +</pre> +</blockquote> + +<p> A Postfix SMTP client certificate supplied here must be usable +as an SSL client certificate and hence pass the "openssl verify -purpose +sslclient ..." test. </p> + +<p> A server that trusts the root CA has a local copy of the root +CA certificate, so it is not necessary to include the root CA +certificate here. Leaving it out of the "client.pem" file reduces +the overhead of the TLS exchange. </p> + +<p> If you want the Postfix SMTP client to accept remote SMTP server +certificates issued by these CAs, append the root certificate to +$smtp_tls_CAfile or install it in the $smtp_tls_CApath directory. When +you configure trust in a root CA, it is not necessary to explicitly trust +intermediary CAs signed by the root CA, unless $smtp_tls_scert_verifydepth +is less than the number of CAs in the certificate chain for the servers +of interest. With a verify depth of 1 you can only verify certificates +directly signed by a trusted CA, and all trusted intermediary CAs need to +be configured explicitly. With a verify depth of 2 you can verify servers +signed by a root CA or a direct intermediary CA (so long as the server +is correctly configured to supply its intermediate CA certificate). </p> + +<p> RSA key and certificate examples: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_cert_file = /etc/postfix/client.pem + smtp_tls_key_file = $smtp_tls_cert_file +</pre> +</blockquote> + +<p> Their DSA counterparts: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_dcert_file = /etc/postfix/client-dsa.pem + smtp_tls_dkey_file = $smtp_tls_dcert_file +</pre> +</blockquote> + +<p> To verify a remote SMTP server certificate, the Postfix SMTP +client needs to trust the certificates of the issuing Certification +Authorities. These certificates in "pem" format can be stored in a +single $smtp_tls_CAfile or in multiple files, one CA per file in +the $smtp_tls_CApath directory. If you use a directory, don't forget +to create the necessary "hash" links with: </p> + +<blockquote> +<pre> +# <b>$OPENSSL_HOME/bin/c_rehash <i>/path/to/directory</i> </b> +</pre> +</blockquote> + +<p> The $smtp_tls_CAfile contains the CA certificates of one or more +trusted CAs. The file is opened (with root privileges) before Postfix +enters the optional chroot jail and so need not be accessible from inside the +chroot jail. </p> + +<p> Additional trusted CAs can be specified via the $smtp_tls_CApath +directory, in which case the certificates are read (with $mail_owner +privileges) from the files in the directory when the information +is needed. Thus, the $smtp_tls_CApath directory needs to be accessible +inside the optional chroot jail. </p> + +<p> The choice between $smtp_tls_CAfile and $smtp_tls_CApath is +a space/time tradeoff. If there are many trusted CAs, the cost of +preloading them all into memory may not pay off in reduced access time +when the certificate is needed. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_CAfile = /etc/postfix/CAcert.pem + smtp_tls_CApath = /etc/postfix/certs +</pre> +</blockquote> + +<h3><a name="client_logging"> Client-side TLS activity logging </a> </h3> + +<p> To get additional information about Postfix SMTP client TLS +activity you can increase the loglevel from 0..4. Each logging +level also includes the information that is logged at a lower +logging level. </p> + +<blockquote> + +<table> + +<tr> <td> 0 </td> <td> Disable logging of TLS activity.</td> </tr> + +<tr> <td> 1 </td> <td> Log TLS handshake and certificate information. +</td> </tr> + +<tr> <td> 2 </td> <td> Log levels during TLS negotiation. </td> +</tr> + +<tr> <td> 3 </td> <td> Log hexadecimal and ASCII dump of TLS +negotiation process </td> </tr> + +<tr> <td> 4 </td> <td> Log hexadecimal and ASCII dump of complete +transmission after STARTTLS </td> </tr> + +</table> + +</blockquote> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_loglevel = 0 +</pre> +</blockquote> + +<h3><a name="client_tls_cache">Client-side TLS session cache</a> </h3> + +<p> The remote SMTP server and the Postfix SMTP client negotiate a +session, which takes some computer time and network bandwidth. By +default, this session information is cached only in the smtp(8) +process actually using this session and is lost when the process +terminates. To share the session information between multiple +smtp(8) processes, a persistent session cache can be used. You +can specify any database type that can store objects of several +kbytes and that supports the sequence operator. DBM databases are +not suitable because they can only store small objects. The cache +is maintained by the tlsmgr(8) process, so there is no problem with +concurrent access. Session caching is highly recommended, because +the cost of repeatedly negotiating TLS session keys is high. Future +Postfix SMTP servers may limit the number of sessions that a client +is allowed to negotiate per unit time.</p> + + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_session_cache_database = btree:/etc/postfix/smtp_scache +</pre> +</blockquote> + +<p> As of version 2.5, Postfix will no longer maintain this file +in a directory with non-Postfix ownership. As a migration aid, +attempts to open such files are redirected to the Postfix-owned +$data_directory, and a warning is logged. </p> + +<p> Cached Postfix SMTP client session information expires after +a certain amount of time. Postfix/TLS does not use the OpenSSL +default of 300s, but a longer time of 3600s (=1 hour). RFC 2246 +recommends a maximum of 24 hours. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_session_cache_timeout = 3600s +</pre> +</blockquote> + +<h3><a name="client_tls_enable"> Enabling TLS in the Postfix SMTP +client </a> </h3> + +<p> By default, TLS is disabled in the Postfix SMTP client, so no +difference to plain Postfix is visible. If you enable TLS, the +Postfix SMTP client will send STARTTLS when TLS support is announced +by the remote SMTP server. </p> + +<p> When the server accepts the STARTTLS command, but the subsequent +TLS handshake fails, and no other server is available, the Postfix SMTP +client defers the delivery attempt, and the mail stays in the queue. After +a handshake failure, the communications channel is in an indeterminate +state and cannot be used for non-TLS deliveries. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_use_tls = yes +</pre> +</blockquote> + +<h3><a name="client_tls_require"> Requiring TLS encryption </a> +</h3> + +<p> You can ENFORCE the use of TLS, so that the Postfix SMTP client +will not deliver mail over unencrypted connections. In this mode, +the remote SMTP server hostname must match the information in the +remote server certificate, and the server certificate must be issued +by a CA that is trusted by the Postfix SMTP client. If the remote +server certificate doesn't verify or the remote SMTP server hostname +doesn't match, and no other server is available, the delivery +attempt is deferred and the mail stays in the queue. </p> + +<p> The remote SMTP server hostname is verified against all names +provided as dNSNames +in the SubjectAlternativeName. If no dNSNames are specified, the +CommonName is checked. Verification may be turned off with the +smtp_tls_enforce_peername option which is discussed below. </p> + +<p> Enforcing the use of TLS is useful if you know that you will +only +connect to servers that support RFC 2487 _and_ that present server +certificates that meet the above requirements. An example would +be a client only sends email to one specific mailhub that offers +the necessary STARTTLS support. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_enforce_tls = yes +</pre> +</blockquote> + +<h3> <a name="client_tls_nopeer"> Disabling server certificate +verification </a> </h3> + +<p> As of RFC 2487 the requirements for hostname checking for MTA +clients are not set. When TLS is required (smtp_enforce_tls = yes), +the option smtp_tls_enforce_peername can be set to "no" to disable +strict remote SMTP server hostname checking. In this case, the mail +delivery will proceed regardless of the CommonName etc. listed in +the certificate. </p> + +<p> Despite the potential for eliminating "man-in-the-middle" and +other attacks, mandatory certificate/peername verification is not +viable as a default Internet mail delivery policy at this time. A +significant fraction of TLS enabled MTAs uses self-signed certificates, +or certificates that are signed by a private Certification Authority. +On a machine that delivers mail to the Internet, if you set +smtp_enforce_tls = yes, you should probably also set +smtp_tls_enforce_peername = no. You can use the per-site TLS +policies (see below) to enable full peer verification for specific +destinations that are known to have verifiable TLS server certificates. +</p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_enforce_tls = yes + smtp_tls_enforce_peername = no +</pre> +</blockquote> + +<h3> <a name="client_tls_per_site"> Per-site TLS policies </a> </h3> + +<p> A small fraction of servers offer STARTTLS but the negotiation +consistently fails, leading to mail aging out of the queue and +bouncing back to the sender. In such cases, you can use the per-site +policies to disable TLS for the problem sites. Alternatively, you +can enable TLS for just a few specific sites and not enable it for +all sites. </p> + +<!-- insert new-style TLS policy mechanism here + +<h3> <a name="client_tls_obs"> Obsolete per-site TLS policy support +</a> </h3> + +<p> This section describes an obsolete per-site TLS policy mechanism. +Unlike the newer mechanism it supports TLS policy lookup by server +hostname, and lacks control over what names can appear in server +certificates. Because of this, the obsolete mechanism is vulnerable +to false DNS hostname information in MX or CNAME records. These +attacks can be eliminated only with great difficulty. </p> + +--> + +<p> The smtp_tls_per_site table is searched for a policy that matches +the following information: </p> + +<blockquote> + +<dl> + +<dt> remote SMTP server hostname </dt> <dd> This is simply the DNS +name of the server that the Postfix SMTP client connects to; this +name may be obtained from other DNS lookups, such as MX lookups or +CNAME lookups. </dd> + +<dt> next-hop destination </dt> <dd> This is normally the domain +portion of the recipient address, but it may be overruled by +information from the transport(5) table, from the relayhost parameter +setting, or from the relay_transport setting. When it's not the +recipient domain, the next-hop destination can have the Postfix-specific +form "<tt>[name]</tt>", <tt>[name]:port</tt>", "<tt>name</tt>" or +"<tt>name:port</tt>". </dd> + +</dl> + +</blockquote> + +<p> When both the hostname lookup and the next-hop lookup succeed, +the host policy does not automatically override the next-hop policy. +Instead, precedence is given to either the more specific or the +more secure per-site policy as described below. </p> + +<p> The smtp_tls_per_site table uses a simple "<i>name whitespace +value</i>" format. Specify host names or next-hop destinations on +the left-hand side; no wildcards are allowed. On the right hand +side specify one of the following keywords: </p> + +<blockquote> + +<dl> + +<dt> NONE </dt> <dd> Don't use TLS at all. This overrides a less +specific <b>MAY</b> lookup result from the alternate host or next-hop +lookup key, and overrides the global smtp_use_tls, smtp_enforce_tls, +and smtp_tls_enforce_peername settings. </dd> + +<dt> MAY </dt> <dd> Try to use TLS if the server announces support, +otherwise use the unencrypted connection. This has less precedence +than a more specific result (including <b>NONE</b>) from the alternate +host or next-hop lookup key, and has less precedence than the more +specific global "smtp_enforce_tls = yes" or "smtp_tls_enforce_peername += yes". </dd> + +<dt> MUST_NOPEERMATCH </dt> <dd> Require TLS encryption, but do not +require that the remote SMTP server hostname matches the information +in the remote SMTP server certificate, or that the server certificate +was issued by a trusted CA. This overrides a less secure <b>NONE</b> +or a less specific <b>MAY</b> lookup result from the alternate host +or next-hop lookup key, and overrides the global smtp_use_tls, +smtp_enforce_tls and smtp_tls_enforce_peername settings. </dd> + +<dt> MUST </dt> <dd> Require TLS encryption, require that the remote +SMTP server hostname matches the information in the remote SMTP +server certificate, and require that the remote SMTP server certificate +was issued by a trusted CA. This overrides a less secure <b>NONE</b> +and <b>MUST_NOPEERMATCH</b> or a less specific <b>MAY</b> lookup +result from the alternate host or next-hop lookup key, and overrides +the global smtp_use_tls, smtp_enforce_tls and smtp_tls_enforce_peername +settings. </dd> + +</dl> + +</blockquote> + +<p> The precedences between global (main.cf) and per-site TLS +policies can be summarized as follows: </p> + +<ul> + +<li> <p> When neither the remote SMTP server hostname nor the +next-hop destination are found in the smtp_tls_per_site table, the +policy is based on smtp_use_tls, smtp_enforce_tls and +smtp_tls_enforce_peername. Note: "smtp_enforce_tls = yes" and +"smtp_tls_enforce_peername = yes" imply "smtp_use_tls = yes". </p> + +<li> <p> When both hostname and next-hop destination lookups produce +a result, the more specific per-site policy (NONE, MUST, etc.) +overrides the less specific one (MAY), and the more secure per-site +policy (MUST, etc.) overrides the less secure one (NONE). </p> + +<li> <p> After the per-site policy lookups are combined, the result +generally overrides the global policy. The exception is the less +specific <b>MAY</b> per-site policy, which is overruled by the more +specific global "smtp_enforce_tls = yes" with server certificate +verification as specified with the smtp_tls_enforce_peername +parameter. </p> + +</ul> + +<h3> <a name="client_tls_harden"> Closing a DNS loophole with +<!-- legacy --> per-site TLS policies </a> </h3> + +<p> As long as no secure DNS lookup mechanism is available, false +hostnames in MX or CNAME responses can change the server hostname +that Postfix uses for TLS policy lookup and server certificate +verification. Even with a perfect match between the server hostname +and the server certificate, there is no guarantee that Postfix is +connected to the right server. To avoid this loophole take the +following steps: </p> + +<ul> + +<li> <p> Eliminate MX lookups. Specify local transport(5) table +entries for sensitive domains with explicit smtp:[<i>mailhost</i>] +or smtp:[<i>mailhost</i>]:<i>port</i> destinations (you can assure +security of this table unlike DNS); in the smtp_tls_per_site table +specify the value <b>MUST</b> for the key [<i>mailhost</i>] or +smtp:[<i>mailhost</i>]:<i>port</i>. This prevents false hostname +information in DNS MX records from changing the server hostname +that Postfix uses for TLS policy lookup and server certificate +verification. </p> + +<li> <p> Disallow CNAME hostname overrides. In main.cf specify +"smtp_cname_overrides_servername = no". This prevents false hostname +information in DNS CNAME records from changing the server hostname +that Postfix uses for TLS policy lookup and server certificate +verification. This feature requires Postfix 2.2.9 or later. </p> + +</ul> + +<p> Example: </p> + +<blockquote> <pre> +/etc/postfix/main.cf: + smtp_tls_per_site = hash:/etc/postfix/tls_per_site + relayhost = [msa.example.net]:587 + +/etc/postfix/tls_per_site: + # relayhost exact nexthop match + [msa.example.net]:587 MUST + + # TLS should not be used with the <i>example.org</i> MX hosts. + example.org NONE + + # TLS should not be used with the host <i>smtp.example.com</i>. + [smtp.example.com] NONE +</pre> +</blockquote> + +<h3> <a name="client_tls_discover"> Discovering servers that support +TLS </a> </h3> + +<p> As we decide on a "per site" basis whether or not to use TLS, +it would be good to have a list of sites that offered "STARTTLS". +We can collect it ourselves with this option. </p> + +<p> If the smtp_tls_note_starttls_offer feature is enabled and a +server offers STARTTLS while TLS is not already enabled for that +server, the Postfix SMTP client logs a line as follows: </p> + +<blockquote> +<pre> +postfix/smtp[pid]: Host offered STARTTLS: [hostname.example.com] +</pre> +</blockquote> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_note_starttls_offer = yes +</pre> +</blockquote> + +<h3><a name="client_vrfy_server">Server certificate verification depth</a> </h3> + +<p> When verifying a remote SMTP server certificate, a verification +depth of 1 is sufficient if the certificate is directly issued by +a CA specified with smtp_tls_CAfile or smtp_tls_CApath. The default +value of 5 should also suffice for longer chains (root CA issues +special CA which then issues the actual certificate...) </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_scert_verifydepth = 5 +</pre> +</blockquote> + +<h3> <a name="client_cipher">Client-side cipher controls </a> </h3> + +<p> To influence the Postfix SMTP client cipher selection scheme, +you can give cipherlist string. A detailed description would go +too far here; please refer to the OpenSSL documentation. If you +don't know what to do with it, simply don't touch it and leave the +(openssl-)compiled in default! </p> + +<p> DO NOT USE " to enclose the string, specify just the string!!! </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_cipherlist = DEFAULT +</pre> +</blockquote> + +<h3> <a name="client_misc"> Miscellaneous client controls </a> </h3> + +<p> The smtp_starttls_timeout parameter limits the time of Postfix +SMTP client write and read operations during TLS startup and shutdown +handshake procedures. In case of problems the Postfix SMTP client +tries the next network address on the mail exchanger list, and +defers delivery if no alternative server is available. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_starttls_timeout = 300s +</pre> +</blockquote> + +<h2><a name="tlsmgr_controls"> TLS manager specific settings </a> </h2> + +<p> The security of cryptographic software such as TLS depends +critically on the ability to generate unpredictable numbers for +keys and other information. To this end, the tlsmgr(8) process +maintains a Pseudo Random Number Generator (PRNG) pool. This is +queried by the smtp(8) and smtpd(8) processes when they initialize. +By default, these daemons request 32 bytes, the equivalent to 256 +bits. This is more than sufficient to generate a 128bit (or 168bit) +session key. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + tls_daemon_random_bytes = 32 +</pre> +</blockquote> + +<p> In order to feed its in-memory PRNG pool, the tlsmgr(8) reads +entropy from an external source, both at startup and during run-time. +Specify a good entropy source, like EGD or /dev/urandom; be sure +to only use non-blocking sources (on OpenBSD, use /dev/arandom +when tlsmgr(8) complains about /dev/urandom timeout errors). +If the entropy source is not a +regular file, you must prepend the source type to the source name: +"dev:" for a device special file, or "egd:" for a source with EGD +compatible socket interface. </p> + +<p> Examples (specify only one in main.cf): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + tls_random_source = dev:/dev/urandom + tls_random_source = egd:/var/run/egd-pool +</pre> +</blockquote> + +<p> By default, tlsmgr(8) reads 32 bytes from the external entropy +source at each seeding event. This amount (256bits) is more than +sufficient for generating a 128bit symmetric key. With EGD and +device entropy sources, the tlsmgr(8) limits the amount of data +read at each step to 255 bytes. If you specify a regular file as +entropy source, a larger amount of data can be read. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + tls_random_bytes = 32 +</pre> +</blockquote> + +<p> In order to update its in-memory PRNG pool, the tlsmgr(8) +queries the external entropy source again after a pseudo-random +amount of time. The time is calculated using the PRNG, and is +between 0 and the maximal time specified with tls_random_reseed_period. +The default maximal time interval is 1 hour. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + tls_random_reseed_period = 3600s +</pre> +</blockquote> + +<p> The tlsmgr(8) process saves the PRNG state to a persistent +exchange file at regular times and when the process terminates, so +that it can recover the PRNG state the next time it starts up. +This file is created when it does not exist. Its default location +is under the Postfix configuration directory, which is not the +proper place for information that is modified by Postfix. Instead, +the file location should probably be on the /var partition (but +<b>not</b> inside the chroot jail). </p> + +<p> Examples: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + tls_random_exchange_name = /etc/postfix/prng_exch + tls_random_prng_update_period = 3600s +</pre> +</blockquote> + +<h2><a name="quick-start">Getting started, quick and dirty</a></h2> + +<p> The following steps will get you started quickly. Because you +sign your own Postfix public key certificate, you get TLS encryption +but no TLS authentication. This is sufficient for testing, and +for exchanging email with sites that you have no trust relationship +with. For real authentication, your Postfix public key certificate +needs to be signed by a recognized Certification Authority, and +Postfix needs to be configured with a list of public key certificates +of Certification Authorities, so that Postfix can verify the public key +certificates of remote hosts. </p> + +<p> In the examples below, user input is shown in <b><tt>bold</tt></b> +font, and a "<tt>#</tt>" prompt indicates a super-user shell. </p> + +<ul> + +<li> <p> Become your own Certification Authority, so that you can +sign your own public keys. This example uses the CA.pl script that +ships with OpenSSL. By default, OpenSSL installs this as +<tt>/usr/local/ssl/misc/CA.pl</tt>, but your mileage may vary. +The script creates a private key in <tt>./demoCA/private/cakey.pem</tt> +and a public key in <tt>./demoCA/cacert.pem</tt>.</p> + +<blockquote> +<pre> +% <b>/usr/local/ssl/misc/CA.pl -newca</b> +CA certificate filename (or enter to create) + +Making CA certificate ... +Using configuration from /etc/ssl/openssl.cnf +Generating a 1024 bit RSA private key +....................++++++ +.....++++++ +writing new private key to './demoCA/private/cakey.pem' +Enter PEM pass phrase:<b>whatever</b> +</pre> +</blockquote> + +<li> <p> Create an unpassworded private key for host FOO and create +an unsigned public key certificate. </p> + +<blockquote> +<pre> +% <b>openssl req -new -nodes -keyout FOO-key.pem -out FOO-req.pem -days 365</b> +Using configuration from /etc/ssl/openssl.cnf +Generating a 1024 bit RSA private key +........................................++++++ +....++++++ +writing new private key to 'FOO-key.pem' +----- +You are about to be asked to enter information that will be incorporated +into your certificate request. +What you are about to enter is what is called a Distinguished Name or a DN. +There are quite a few fields but you can leave some blank +For some fields there will be a default value, +If you enter '.', the field will be left blank. +----- +Country Name (2 letter code) [AU]:<b>US</b> +State or Province Name (full name) [Some-State]:<b>New York</b> +Locality Name (eg, city) []:<b>Westchester</b> +Organization Name (eg, company) [Internet Widgits Pty Ltd]:<b>Porcupine</b> +Organizational Unit Name (eg, section) []: +Common Name (eg, YOUR name) []:<b>FOO</b> +Email Address []:<b>wietse@porcupine.org</b> + +Please enter the following 'extra' attributes +to be sent with your certificate request +A challenge password []:<b>whatever</b> +An optional company name []: +</pre> +</blockquote> + +<li> <p> Sign the public key certificate for host FOO with the +Certification Authority private key that we created a few +steps ago. </p> + +<blockquote> +<pre> +% <b>openssl ca -out FOO-cert.pem -infiles FOO-req.pem</b> +Uing configuration from /etc/ssl/openssl.cnf +Enter PEM pass phrase:<b>whatever</b> +Check that the request matches the signature +Signature ok +The Subjects Distinguished Name is as follows +countryName :PRINTABLE:'US' +stateOrProvinceName :PRINTABLE:'New York' +localityName :PRINTABLE:'Westchester' +organizationName :PRINTABLE:'Porcupine' +commonName :PRINTABLE:'FOO' +emailAddress :IA5STRING:'wietse@porcupine.org' +Certificate is to be certified until Nov 21 19:40:56 2005 GMT (365 days) +Sign the certificate? [y/n]:<b>y</b> + + +1 out of 1 certificate requests certified, commit? [y/n]<b>y</b> +Write out database with 1 new entries +Data Base Updated +</pre> +</blockquote> + +<li> <p> Install the host private key, the host public key certificate, +and the Certification Authority certificate files. This requires +super-user privileges. </p> + +<blockquote> +<pre> +# <b>cp demoCA/cacert.pem FOO-key.pem FOO-cert.pem /etc/postfix</b> +# <b>chmod 644 /etc/postfix/FOO-cert.pem /etc/postfix/cacert.pem</b> +# <b>chmod 400 /etc/postfix/FOO-key.pem</b> +</pre> +</blockquote> + +<li> <p> Configure Postfix, by adding the following to +<tt>/etc/postfix/main.cf </tt>. </p> + +<blockquote> +<pre> +smtp_tls_CAfile = /etc/postfix/cacert.pem +smtp_tls_cert_file = /etc/postfix/FOO-cert.pem +smtp_tls_key_file = /etc/postfix/FOO-key.pem +smtp_tls_session_cache_database = btree:/var/run/smtp_tls_session_cache +smtp_use_tls = yes +smtpd_tls_CAfile = /etc/postfix/cacert.pem +smtpd_tls_cert_file = /etc/postfix/FOO-cert.pem +smtpd_tls_key_file = /etc/postfix/FOO-key.pem +smtpd_tls_received_header = yes +smtpd_tls_session_cache_database = btree:/var/run/smtpd_tls_session_cache +smtpd_use_tls = yes +tls_random_source = dev:/dev/urandom +</pre> +</blockquote> + +</ul> + + +<h2> <a name="problems"> Reporting problems </a> </h2> + +<p> When reporting a problem, please be thorough in the report. +Patches, when possible, are greatly appreciated too. </p> + +<p> Please differentiate when possible between: </p> + +<ul> + +<li> Problems in the TLS code: <postfix_tls@aet.tu-cottbus.de> + +<li> Problems in vanilla Postfix: <postfix-users@postfix.org> + +</ul> + +<h2><a name="compat">Compatibility with Postfix < 2.2 TLS support</a></h2> + +<p> Postfix version 2.2 TLS support is based on the Postfix/TLS +patch by Lutz Jänicke, but differs in a few minor ways. </p> + +<ul> + +<li> <p> main.cf: Specify "btree" instead of "sdbm" for TLS +session cache databases. </p> + +<p> TLS session cache databases are now accessed only by the +tlsmgr(8) process, so there are no more concurrency issues. Although +Postfix has an sdbm client, the sdbm library (1000 +lines of code) is not included with Postfix. </p> + +<p> TLS session caches can use any database that can store objects +of several kbytes or more, and that implements the sequence operation. +In most cases, btree databases should be adequate. </p> + +<p> NOTE: You cannot use dbm databases. TLS session objects +are too large. </p> + +<li> <p> master.cf: Specify "unix" instead of "fifo" as +the tlsmgr service type. </p> + +<p> The smtp(8) and smtpd(8) processes now use a client-server +protocol in order to access the tlsmgr(8) pseudo-random number +generation (PRNG) pool, and in order to access the TLS session +cache databases. Such a protocol cannot be run across fifos. </p> + +<li> <p> smtp_tls_per_site: the MUST_NOPEERMATCH per-site policy +cannot override the global "smtp_tls_enforce_peername = yes" setting. +</p> + +<li> <p> smtp_tls_per_site: a combined (NONE + MAY) lookup result +for (hostname and next-hop destination) produces counter-intuitive +results for different main.cf settings. TLS is enabled with +"smtp_tls_enforce_peername = no", but it is disabled when both +"smtp_enforce_tls = yes" and "smtp_tls_enforce_peername = yes". +</p> + +</ul> + +<p> The smtp_tls_per_site limitations were removed by the end of +the Postfix 2.2 support cycle. </p> + +<h2><a name="credits">Credits </a> </h2> + +<ul> + +<li> TLS support for Postfix was originally developed by Lutz +Jänicke at Cottbus Technical University. + +<li> Wietse Venema adopted the code, did some restructuring, and +compiled this part of the documentation from Lutz's documents. + +<li> Victor Duchovni was instrumental with the re-implementation +of the smtp_tls_per_site code in terms of enforcement levels, which +simplified the implementation greatly. + +</ul> + +</body> + +</html> diff --git a/proto/TLS_README.html b/proto/TLS_README.html new file mode 100644 index 0000000..b53e71b --- /dev/null +++ b/proto/TLS_README.html @@ -0,0 +1,3252 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix TLS Support </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix TLS Support +</h1> + +<hr> + +<h2> What Postfix TLS support does for you </h2> + +<p> Transport Layer Security (TLS, formerly called SSL) provides +certificate-based authentication and encrypted sessions. An +encrypted session protects the information that is transmitted with +SMTP mail or with SASL authentication. </p> + +<p> NOTE: By turning on TLS support in Postfix, you not only get +the ability to encrypt mail and to authenticate remote SMTP clients +or servers. You also turn on hundreds of thousands of lines of +OpenSSL library code. Assuming that OpenSSL is written as carefully +as Wietse's own code, every 1000 lines introduces one additional bug +into Postfix. </p> + +<p> Topics covered in this document: </p> + +<ul> + +<li><a href="#how">How Postfix TLS support works</a> + +<li><a href="#server_tls">SMTP Server specific settings</a> + +<li> <a href="#client_tls">SMTP Client specific settings</a> + +<li><a href="#tlsmgr_controls"> TLS manager specific settings </a> + +<li><a href="#build_tls">Building Postfix with TLS support</a> + +<li><a href="#problems"> Reporting problems </a> + +<li><a href="#credits"> Credits </a> + +</ul> + +<p> And last but not least, for the impatient: </p> + +<ul> + +<li><a href="#quick-start">Getting started, quick and dirty</a> + +</ul> + +<h2><a name="how">How Postfix TLS support works</a></h2> + +<p> The diagram below shows the main elements of the Postfix TLS +architecture and their relationships. Colored boxes with numbered +names represent Postfix daemon programs. Other colored boxes +represent storage elements. </p> + +<ul> + +<li> <p> The smtpd(8) server implements the SMTP over TLS server +side. </p> + +<li> <p> The smtp(8) client implements the SMTP (and LMTP) over TLS +client side. </p> + +<li> <p> The tlsmgr(8) server maintains the pseudo-random number +generator (PRNG) that seeds the TLS engines in the smtpd(8) server +and smtp(8) client processes, and maintains the TLS session key +cache files. </p> + +</ul> + +<p> Not shown in the figure are the tlsproxy(8) server and the +postscreen(8) server. These use TLS in the same manner as smtpd(8). +</p> + +<table> + +<tr> <td>Network<tt>-> </tt> </td> <td align="center" +bgcolor="#f0f0ff"> <br> <a href="smtpd.8.html">smtpd(8)</a> <br> </td> <td colspan="2"> + +<tt> <---seed----<br><br><-key/cert-> </tt> </td> <td +align="center" bgcolor="#f0f0ff"> <br> <a href="tlsmgr.8.html">tlsmgr(8)</a> <br> </td> +<td colspan="3"> <tt> ----seed---><br> <br><-key/cert-> + +</tt> </td> <td align="center" bgcolor="#f0f0ff"> <br> <a href="smtp.8.html">smtp(8)</a> <br> + </td> <td> <tt> -></tt>Network </td> </tr> + +<tr> <td colspan="3"> </td> <td align="right"> <table> <tr> <td> + +</td> <td> / </td> </tr> <tr> <td> / </td> <td> </td> </tr> </table> +</td> <td align="center"> |<br> |</td> <td align="left"> <table> + +<tr> <td> \ </td> <td> </td> </tr> <tr> <td> </td> <td> \ </td> +</tr> </table> </td> <td colspan="3"> </td> </tr> + +<tr> <td colspan="2"> </td> <td align="center" bgcolor="#f0f0ff"> +smtpd<br> session<br> key cache </td> <td> </td> <td align="center" +bgcolor="#f0f0ff"> PRNG<br> state <br>file </td> <td> </td> <td +align="center" bgcolor="#f0f0ff"> smtp<br> session<br> key cache +</td> + +<td colspan="2"> </td> </tr> + +</table> + +<h2><a name="server_tls">SMTP Server specific settings</a></h2> + +<p> Topics covered in this section: </p> + +<ul> + +<li><a href="#server_cert_key">Server-side certificate and private +key configuration </a> + +<li><a href="#server_pfs">Server-side forward-secrecy configuration </a> + +<li><a href="#server_logging"> Server-side TLS activity logging +</a> + +<li><a href="#server_enable">Enabling TLS in the Postfix SMTP server </a> + +<li><a href="#server_vrfy_client">Client certificate verification</a> + +<li><a href="#server_tls_auth">Supporting AUTH over TLS only</a> + +<li><a href="#server_tls_cache">Server-side TLS session cache</a> + +<li><a href="#server_access">Server access control</a> + +<li><a href="#server_cipher">Server-side cipher controls</a> + +<li><a href="#server_misc"> Miscellaneous server controls</a> + +</ul> + +<h3><a name="server_cert_key">Server-side certificate and private +key configuration </a> </h3> + +<p> In order to use TLS, the Postfix SMTP server generally needs +a certificate and a private key. Both must be in "PEM" format. The +private key must not be encrypted, meaning: the key must be accessible +without a password. The certificate and private key may be in the same +file, in which case the certificate file should be owned by "root" and +not be readable by any other user. If the key is stored separately, +this access restriction applies to the key file only, and the +certificate file may be "world-readable". </p> + +<p> Public Internet MX hosts without certificates signed by a +well-known public CA must still generate, and be prepared to present +to most clients, a self-signed or private-CA signed certificate. +The remote SMTP client will generally not be able to verify the +self-signed certificate, but unless the client is running Postfix +or similar software, it will only negotiate TLS ciphersuites that +require a server certificate. </p> + +<p> For servers that are <b>not</b> public Internet MX hosts, Postfix +supports configurations with no certificates. This entails the use of +just the anonymous TLS ciphers, which are not supported by typical SMTP +clients. Since some clients may not fall back to plain text after a TLS +handshake failure, a certificate-less Postfix SMTP server will be unable +to receive email from some TLS-enabled clients. To avoid accidental +configurations with no certificates, Postfix enables certificate-less +operation only when the administrator explicitly sets +"smtpd_tls_cert_file = none". This ensures that new Postfix SMTP server +configurations will not accidentally enable TLS without certificates. </p> + +<p> Note that server certificates are <b>not</b> optional in TLS 1.3. To +run without certificates you'd have to disable the TLS 1.3 protocol by +including "<=TLSv1.2" (or, for Postfix < 3.6, "!TLSv1.3") in +"smtpd_tls_protocols" and perhaps also "smtpd_tls_mandatory_protocols". +It is simpler instead to just configure a certificate chain. +Certificate-less operation is not recommended. <p> + +<p> RSA, DSA and ECDSA (Postfix ≥ 2.6) certificates are supported. +Most sites only have RSA certificates. You can configure all three +at the same time, in which case the ciphersuite negotiated with the +remote SMTP client determines which certificate is used. If your +DNS zone is signed, and you want to publish DANE TLSA (RFC 6698, +RFC 7671, RFC 7672) records, these must match all of the configured +certificate chains. Since the best practice is to publish "3 1 1" +certificate associations, create a separate TLSA record to match +each public-key certificate digest. </p> + +<h4> Creating the server certificate file </h4> + +<p> To verify the Postfix SMTP server certificate, the remote SMTP +client must receive the issuing CA certificates via the TLS handshake +or via public-key infrastructure. This means that the Postfix server +public-key certificate file must include the server certificate +first, then the issuing CA(s) (bottom-up order). The Postfix SMTP +server certificate must be usable as an SSL server certificate and +hence pass the "<tt>openssl verify -purpose sslserver ...</tt>" test. +</p> + +<p> The examples that follow show how to create a server certificate +file. We assume that the certificate for "server.example.com" was +issued by "intermediate CA" which itself has a certificate issued +by "root CA". </p> + +<ul> + +<li> <p> With legacy public CA trust verification, you can omit the +root certificate from the "server.pem" certificate file. If the +client trusts the root CA, it will already have a local copy of the +root CA certificate. Omitting the root CA certificate reduces the +size of the server TLS handshake. </p> + +<blockquote> +<pre> +% <b>cat server_cert.pem intermediate_CA.pem > server.pem</b> +</pre> +</blockquote> + +<li> <p> If you publish DANE TLSA (RFC 6698, RFC 7671, RFC 7672) +"2 0 1" or "2 1 1" records to specify root CA certificate digests, +you must include the corresponding root CA certificates in the +"server.pem" certificate file. </p> + +<blockquote> +<pre> +% <b>cat server_cert.pem intermediate_CA.pem root.pem > server.pem</b> +</pre> +</blockquote> + +<p> Remote SMTP clients will be able to use the TLSA record you +publish (which only contains the certificate digest) only if they +have access to the corresponding certificate. Failure to verify +certificates per the server's published TLSA records will typically +cause the SMTP client to defer mail delivery. The foregoing also +applies to "2 0 2" and "2 1 2" TLSA records or any other digest of +a CA certificate, but it is expected that SHA256 will be by far the +most common digest for TLSA. </p> + +<p> As a best practice, publish "3 1 1" TLSA associations that specify +the SHA256 digest of the server's public key. These continue to work +unmodified when a certificate is renewed with the same public/private +key pair. </p> + +</ul> + +<p> For instructions on how to compute the digest of a certificate +or its public key for use in TLSA records, see the documentation of +the smtpd_tls_fingerprint_digest main.cf parameter. </p> + +<p> When a new key or certificate is generated, an additional TLSA +record with the new digest must be published in advance of the +actual deployment of the new key or certificate on the server. You +must allow sufficient time for any TLSA RRsets with only the old +digest to expire from DNS caches. The safest practice is to wait +until the DNSSEC signature on the previous TLSA RRset expires, and +only then switch the server to use new keys published in the updated +TLSA RRset. Once the new certificate trust chain and private key +are in effect, the DNS should be updated once again to remove the +old digest from the TLSA RRset. </p> + +<p> If you want the Postfix SMTP server to accept remote SMTP client +certificates issued by one or more root CAs, append the root +certificate to $smtpd_tls_CAfile or install it in the $smtpd_tls_CApath +directory. </p> + +<h4> Configuring the server certificate and key files </h4> + +<p> Example: Postfix ≥ 3.4 all-in-one chain file(s). One or more +chain files that start with a key that is immediately followed by the +corresponding certificate and any additional issuer certificates. A +single file can hold multiple <i>(key, cert, [chain])</i> sequences, one +per algorithm. It is typically simpler to keep the chain for each +algorithm in its own file. Most users are likely to deploy just a +single RSA chain, but with OpenSSL 1.1.1, it is possible to deploy up to +five chains, one each for RSA, ECDSA, ED25519, ED448, and even the +obsolete DSA. </p> + +<blockquote> +<pre> + # Postfix ≥ 3.4. Preferred configuration interface. Each file + # starts with the private key, followed by the corresponding + # certificate, and any intermediate issuer certificates. The root CA + # cert may also be needed when published as a DANE trust anchor. + # + smtpd_tls_chain_files = + /etc/postfix/rsa.pem, + /etc/postfix/ecdsa.pem, + /etc/postfix/ed25519.pem, + /etc/postfix/ed448.pem +</pre> +</blockquote> + +<p> You can also store the keys separately from their certificates, again +provided each is listed before the corresponding certificate chain. Storing a +key and its associated certificate chain in separate files is not recommended, +because this is prone to race conditions during key rollover, as there is no +way to update multiple files atomically. </p> + +<blockquote> +<pre> + # Postfix ≥ 3.4. + # Storing keys separately from the associated certificates is not + # recommended. + smtpd_tls_chain_files = + /etc/postfix/rsakey.pem, + /etc/postfix/rsacerts.pem, + /etc/postfix/ecdsakey.pem, + /etc/postfix/ecdsacerts.pem +</pre> +</blockquote> + +<p> The below examples show the legacy algorithm-specific configurations +for Postfix 3.3 and older. With Postfix ≤ 3.3, even if the key is +stored in the same file as the certificate, the file is read twice and a +(brief) race condition still exists during key rollover. While Postfix +≥ 3.4 avoids the race when the key and certificate are in the same +file, you should use the new "smtpd_tls_chain_files" interface shown +above. <p> + +<p> RSA key and certificate examples: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_cert_file = /etc/postfix/server.pem + smtpd_tls_key_file = $smtpd_tls_cert_file +</pre> +</blockquote> + +<p> Their DSA counterparts: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_dcert_file = /etc/postfix/server-dsa.pem + smtpd_tls_dkey_file = $smtpd_tls_dcert_file +</pre> +</blockquote> + +<p> Their ECDSA counterparts (Postfix ≥ 2.6 + OpenSSL ≥ 1.0.0): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # Some clients will not be ECDSA capable, so you will likely still need + # an RSA certificate and private key. + # + smtpd_tls_eccert_file = /etc/postfix/server-ecdsa.pem + smtpd_tls_eckey_file = $smtpd_tls_eccert_file +</pre> +</blockquote> + +<p> TLS without certificates for servers serving exclusively +anonymous-cipher capable clients: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # Not recommended: breaks TLS 1.3 and clients that don't support + # anonymous cipher suites. + smtpd_tls_cert_file = none +</pre> +</blockquote> + +<p> To verify a remote SMTP client certificate, the Postfix SMTP +server needs to trust the certificates of the issuing Certification +Authorities. These certificates in "PEM" format can be stored in a +single $smtpd_tls_CAfile or in multiple files, one CA per file in +the $smtpd_tls_CApath directory. If you use a directory, don't forget +to create the necessary "hash" links with: </p> + +<blockquote> +<pre> +# <b>$OPENSSL_HOME/bin/c_rehash <i>/path/to/directory</i> </b> +</pre> +</blockquote> + +<p> The $smtpd_tls_CAfile contains the CA certificates of one or +more trusted CAs. The file is opened (with root privileges) before +Postfix enters the optional chroot jail and so need not be accessible +from inside the chroot jail. </p> + +<p> Additional trusted CAs can be specified via the $smtpd_tls_CApath +directory, in which case the certificates are read (with $mail_owner +privileges) from the files in the directory when the information +is needed. Thus, the $smtpd_tls_CApath directory needs to be +accessible inside the optional chroot jail. </p> + +<p> When you configure the Postfix SMTP server to request <a +href="#server_vrfy_client">client certificates</a>, the DNs of Certification +Authorities in $smtpd_tls_CAfile are sent to the client, in order to allow +it to choose an identity signed by a CA you trust. If no $smtpd_tls_CAfile +is specified, no preferred CA list is sent, and the client is free to +choose an identity signed by any CA. Many clients use a fixed identity +regardless of the preferred CA list and you may be able to reduce TLS +negotiation overhead by installing client CA certificates mostly or +only in $smtpd_tls_CApath. In the latter case you need not specify a +$smtpd_tls_CAfile. </p> + +<p> Note, that unless client certificates are used to allow greater +access to TLS authenticated clients, it is best to not ask for +client certificates at all, as in addition to increased overhead +some clients (notably in some cases qmail) are unable to complete +the TLS handshake when client certificates are requested. </p> + +<p> Example: </p> +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_CAfile = /etc/postfix/CAcert.pem + smtpd_tls_CApath = /etc/postfix/certs +</pre> +</blockquote> + +<h3><a name="server_pfs"> Server-side forward-secrecy configuration </a> </h3> + +<p> If you want to take maximal advantage of ciphers that offer <a +href="FORWARD_SECRECY_README.html#dfn_fs">forward secrecy</a> see +the <a href="FORWARD_SECRECY_README.html#quick-start">Getting +started</a> section of <a +href="FORWARD_SECRECY_README.html">FORWARD_SECRECY_README</a>. The +full document conveniently presents all information about Postfix +forward secrecy support in one place: what forward secrecy is, how +to tweak settings, and what you can expect to see when Postfix uses +ciphers with forward secrecy. </p> + +<h3><a name="server_logging"> Server-side TLS activity logging </a> </h3> + +<p> To get additional information about Postfix SMTP server TLS +activity you can increase the log level from 0..4. Each logging +level also includes the information that is logged at a lower +logging level. </p> + +<blockquote> + +<table border="1"> + +<tr> <th> Level </th> <th> Postfix 2.9 and later</th> <th> Earlier +releases. </th> </tr> + +<tr> <td valign="top"> 0 </td> <td valign="top" colspan="2"> Disable +logging of TLS activity. </td> </tr> + +<tr> <td valign="top"> 1 </td> <td valign="top"> Log only a summary +message on TLS handshake completion — no logging of client +certificate trust-chain verification errors if client certificate +verification is not required. </td> <td valign="top"> Log the summary +message, peer certificate summary information and unconditionally log +trust-chain verification errors. </td> </tr> + +<tr> <td valign="top"> 2 </td> <td valign="top" colspan="2"> Also +log levels during TLS negotiation. </td> </tr> + +<tr> <td valign="top"> 3 </td> <td valign="top" colspan="2"> Also +log hexadecimal and ASCII dump of TLS negotiation process. </td> +</tr> + +<tr> <td valign="top"> 4 </td> <td valign="top" colspan="2"> Also +log hexadecimal and ASCII dump of complete transmission after +STARTTLS. </td></tr> + +</table> + +</blockquote> + +<p> Use log level 3 only in case of problems. Use of log level 4 is +strongly discouraged. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_loglevel = 0 +</pre> +</blockquote> + +<p> To include information about the protocol and cipher used as +well as the client and issuer CommonName into the "Received:" +message header, set the smtpd_tls_received_header variable to true. +The default is no, as the information is not necessarily authentic. +Only information recorded at the final destination is reliable, +since the headers may be changed by intermediate servers. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_received_header = yes +</pre> +</blockquote> + +<h3><a name="server_enable">Enabling TLS in the Postfix SMTP server </a> </h3> + +<p> By default, TLS is disabled in the Postfix SMTP server, so no +difference to plain Postfix is visible. Explicitly switch it on +with "smtpd_tls_security_level = may". </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_security_level = may +</pre> +</blockquote> + +<p> With this, the Postfix SMTP server announces STARTTLS support to +remote SMTP clients, but does not require that clients use TLS encryption. +</p> + +<p> Note: when an unprivileged user invokes "sendmail -bs", STARTTLS +is never offered due to insufficient privileges to access the Postfix +SMTP server +private key. This is intended behavior. </p> + +<p> <a name="server_enforce">You can ENFORCE the use of TLS</a>, +so that the Postfix SMTP server announces STARTTLS and accepts no +mail without TLS encryption, by setting +"smtpd_tls_security_level = encrypt". According to RFC 2487 this +MUST NOT be applied in case +of a publicly-referenced Postfix SMTP server. This option is off +by default and should only seldom be used. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_security_level = encrypt +</pre> +</blockquote> + +<p> TLS is also used in the "wrapper" mode where +a server always uses TLS, instead of announcing STARTTLS support +and waiting for remote SMTP clients to request TLS service. Some +clients, namely +Outlook [Express] prefer the "wrapper" mode. This is true for OE +(Win32 < 5.0 and Win32 >=5.0 when run on a port<>25 +and OE (5.01 Mac on all ports). </p> + +<p> It is strictly discouraged to use this mode from main.cf. If +you want to support this service, enable a special port in master.cf +and specify "-o smtpd_tls_wrappermode=yes" (note: no space around +the "=") as an smtpd(8) command line option. Port 465 (smtps) was +once chosen for this feature. +</p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + smtps inet n - n - - smtpd + -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes +</pre> +</blockquote> + +<h3><a name="server_vrfy_client">Client certificate verification</a> </h3> + +<p> To receive a remote SMTP client certificate, the Postfix SMTP +server must explicitly ask for one (any contents of $smtpd_tls_CAfile +are also sent to the client as a hint for choosing a certificate from +a suitable CA). Unfortunately, Netscape clients will either complain +if no matching client certificate is available or will offer the user +client a list of certificates to choose from. Additionally some MTAs +(notably some versions of qmail) are unable to complete TLS negotiation +when client certificates are requested, and abort the SMTP session. So +this option is "off" by default. You will however need the certificate +if you want to use certificate based relaying with, for example, the +permit_tls_clientcerts feature. A server that wants client certificates +must first present its own certificate. While Postfix by default +offers anonymous ciphers to remote SMTP clients, these are automatically +suppressed +when the Postfix SMTP server is configured to ask for client +certificates. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_ask_ccert = yes + smtpd_tls_security_level = may +</pre> +</blockquote> + +<p> When TLS is <a href="#server_enforce">enforced</a> you may also decide +to REQUIRE a remote SMTP client certificate for all TLS connections, +by setting "smtpd_tls_req_ccert = yes". This feature implies +"smtpd_tls_ask_ccert = yes". When TLS is not enforced, +"smtpd_tls_req_ccert = yes" is ignored and a warning is +logged. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_req_ccert = yes + smtpd_tls_security_level = encrypt +</pre> +</blockquote> + +<p> The client certificate verification depth is specified with the +main.cf smtpd_tls_ccert_verifydepth parameter. The default verification +depth is 9 (the OpenSSL default), for compatibility with Postfix +versions before 2.5 where smtpd_tls_ccert_verifydepth was ignored. +When you configure trust in a +root CA, it is not necessary to explicitly trust intermediary CAs signed +by the root CA, unless $smtpd_tls_ccert_verifydepth is less than the +number of CAs in the certificate chain for the clients of interest. With +a verify depth of 1 you can only verify certificates directly signed +by a trusted CA, and all trusted intermediary CAs need to be configured +explicitly. With a verify depth of 2 you can verify clients signed by a +root CA or a direct intermediary CA (so long as the client is correctly +configured to supply its intermediate CA certificate). </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_ccert_verifydepth = 2 +</pre> +</blockquote> + +<h3><a name="server_tls_auth">Supporting AUTH over TLS only</a></h3> + +<p> Sending AUTH data over an unencrypted channel poses a security +risk. When TLS layer encryption is required +("smtpd_tls_security_level = encrypt"), the Postfix SMTP server will +announce and accept AUTH only after the TLS layer has been activated +with STARTTLS. When TLS layer encryption is optional +("smtpd_tls_security_level = may"), it may however still be useful +to only offer AUTH when TLS is active. To maintain compatibility +with non-TLS clients, the default is to accept AUTH without encryption. +In order to change this behavior, set +"smtpd_tls_auth_only = yes". </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_auth_only = no +</pre> +</blockquote> + +<h3><a name="server_tls_cache">Server-side TLS session cache</a> </h3> + +<p> The Postfix SMTP server and the remote SMTP client negotiate a +session, which takes some computer time and network bandwidth. SSL +protocol versions other than SSLv2 support resumption of cached +sessions. Not only is this more CPU and bandwidth efficient, it +also reduces latency as only one network round-trip is used to +resume a session while it takes two round-trips to create a session +from scratch. </p> + +<p> Since Postfix uses multiple smtpd(8) service processes, an +in-memory cache is not sufficient for session re-use. Clients store +at most one cached session per server and are very unlikely to +repeatedly connect to the same server process. Thus session caching +in the Postfix SMTP server generally requires a shared cache (an +alternative available with Postfix ≥ 2.11 is described below). +</p> + +<p> To share the session information between multiple +smtpd(8) processes, a session cache database is used. You +can specify any database type that can store objects of several +kbytes and that supports the sequence operator. DBM databases are +not suitable because they can only store small objects. The cache +is maintained by the tlsmgr(8) process, so there is no problem with +concurrent access. Session caching is highly recommended, because +the cost of repeatedly negotiating TLS session keys is high.</p> + +<p> Starting with Postfix 2.11, linked with a compatible OpenSSL +library (at least 0.9.8h, preferably 1.0.0 or later) the Postfix +SMTP server supports RFC 5077 TLS session resumption without +server-side state when the remote SMTP client also supports RFC +5077. The session is encrypted by the server in a <i>session +ticket</i> returned to client for storage. When a client sends a +valid session ticket, the server decrypts it and resumes the session, +provided neither the ticket nor the session have expired. This +makes it possible to resume cached sessions without allocating space +for a shared database on the server. Consequently, for Postfix +≥ 2.11 the smtpd_tls_session_cache_database parameter should +generally be left empty. Session caching can be disabled by setting +the session cache timeout to zero, otherwise the timeout must be +at least 2 minutes and at most 100 days. </p> + +<p> Note, session tickets can only be negotiated if the client +disables SSLv2 and does not use the legacy SSLv2 compatible HELLO +message. This is true by default with the Postfix ≥ 2.6 SMTP +client. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache +</pre> +</blockquote> + +<p> Note: as of version 2.5, Postfix no longer uses root privileges +when opening this file. The file should now be stored under the +Postfix-owned data_directory. As a migration aid, an attempt to +open the file under a non-Postfix directory is redirected to the +Postfix-owned data_directory, and a warning is logged. </p> + +<p> Cached Postfix SMTP server session information expires after +a certain amount of time. Postfix/TLS does not use the OpenSSL +default of 300s, but a longer time of 3600sec (=1 hour). RFC 2246 +recommends a maximum of 24 hours. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_session_cache_timeout = 3600s +</pre> +</blockquote> + +<p> As of Postfix 2.11 this setting cannot exceed 100 days. If set +≤ 0, session caching is disabled. If set to a positive value +less than 2 minutes, the minimum value of 2 minutes is used instead. </p> + +<p> When the Postfix SMTP server does not save TLS sessions to an +external cache database, client-side session caching is unlikely +to be useful. To reduce waste of client resources, the Postfix SMTP server can +be configured to not issue TLS session ids. By default the Postfix +SMTP server always issues TLS session ids. This works around known +interoperability issues with some MUAs, and prevents possible +interoperability issues with other MTAs. </p> + +<p> Example: </p> + +<blockquote> +<pre> + smtpd_tls_always_issue_session_ids = no +</pre> +</blockquote> + +<h3><a name="server_access">Server access control</a> </h3> + +<p> Postfix TLS support introduces three additional features for +Postfix SMTP server access control: </p> + +<blockquote> + +<dl> + +<dt> permit_tls_clientcerts </dt> <dd> <p> Allow the remote SMTP +client request if the client certificate fingerprint or certificate +public key fingerprint (Postfix 2.9 and later) is listed in the +client certificate table (see relay_clientcerts discussion below). +</p> </dd> + +<dt> permit_tls_all_clientcerts </dt> <dd> <p> Allow the remote SMTP +client request if the client certificate passes trust chain verification. +Useful with private-label CAs that only issue certificates to trusted +clients (and not otherwise). </p> </dd> + +<dt> check_ccert_access type:table</dt> <dd> <p> Use the remote +SMTP client certificate fingerprint or public key fingerprint +(Postfix 2.9 and later) as the lookup key for the specified access(5) +table. </p> </dd> + +</dl> + +</blockquote> + +<p> The digest algorithm used to compute the client certificate +fingerprints is specified with the main.cf smtpd_tls_fingerprint_digest +parameter. The default algorithm is <b>sha256</b> with Postfix ≥ +3.6 and the <b>compatibility_level</b> set to 3.6 or higher. With +Postfix ≤ 3.5, the default algorithm is <b>md5</b>. The +best-practice algorithm is now <b>sha256</b>. Recent advances in hash +function cryptanalysis have led to md5 and sha1 being deprecated in +favor of sha256. However, as long as there are no known "second +pre-image" attacks against the older algorithms, their use in this +context, though not recommended, is still likely safe. </p> + +<p> The permit_tls_all_clientcerts feature must be used with caution, +because it can result in too many access permissions. Use this +feature only if a special CA issues the client certificates, and +only if this CA is listed as a trusted CA. If other CAs are trusted, +any owner of a valid client certificate would be authorized. +The permit_tls_all_clientcerts feature can be practical for a +specially created email relay server. </p> + +<p> It is however recommended to stay with the permit_tls_clientcerts +feature and list all certificates via $relay_clientcerts, as +permit_tls_all_clientcerts does not permit any control when a +certificate must no longer be used (e.g. an employee leaving). </p> + +<p> Example: </p> + +<blockquote> +<pre> +# With Postfix 2.10 and later, the mail relay policy is +# preferably specified under smtpd_relay_restrictions. +/etc/postfix/main.cf: + smtpd_relay_restrictions = + permit_mynetworks + permit_tls_clientcerts + reject_unauth_destination +</pre> + +<pre> +# Older configurations combine relay control and spam control under +# smtpd_recipient_restrictions. To use this example with Postfix ≥ +# 2.10 specify "smtpd_relay_restrictions=". +/etc/postfix/main.cf: + smtpd_recipient_restrictions = + permit_mynetworks + permit_tls_clientcerts + reject_unauth_destination + ...other rules... +</pre> +</blockquote> + +<p> Example: Postfix lookup tables are in the form of (key, value) +pairs. Since we only need the key, the value can be chosen freely, e.g. +the name of the user or host:</p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + relay_clientcerts = hash:/etc/postfix/relay_clientcerts + +/etc/postfix/relay_clientcerts: + D7:04:2F:A7:0B:8C:A5:21:FA:31:77:E1:41:8A:EE:80 lutzpc.at.home +</pre> +</blockquote> + +<p> To extract the public key fingerprint from an X.509 certificate, +you need to extract the public key from the certificate and compute +the appropriate digest of its DER (ASN.1) encoding. With OpenSSL +the "-pubkey" option of the "x509" command extracts the public +key always in "PEM" format. We pipe the result to another OpenSSL +command that converts the key to DER and then to the "dgst" command +to compute the fingerprint. </p> + +<p> Example: </p> +<blockquote> +<pre> +$ openssl x509 -in cert.pem -noout -pubkey | + openssl pkey -pubin -outform DER | + openssl dgst -sha256 -c +(stdin)= 64:3f:1f:f6:e5:1e:d4:2a:...:8b:fc:09:1a:61:98:b5:bc:7c:60:58 +</pre> +</blockquote> + +<h3><a name="server_cipher">Server-side cipher controls</a> </h3> + +<p> The Postfix SMTP server supports 5 distinct cipher grades as +specified by the smtpd_tls_mandatory_ciphers configuration parameter, +which determines the minimum cipher grade with mandatory TLS +encryption. The default minimum cipher grade for mandatory TLS is +"medium" which is essentially 128-bit encryption or better. The +smtpd_tls_ciphers parameter (Postfix ≥ 2.6) controls the minimum +cipher grade used with opportunistic TLS. Here, the default minimum +cipher grade is "medium" for Postfix releases after the middle of +2015, "export" for older Postfix releases. With Postfix < 2.6, +the minimum opportunistic TLS cipher grade is always "export". </p> + +<p> By default anonymous ciphers are enabled. They are automatically +disabled when remote SMTP client certificates are requested. If +clients are expected to always verify the Postfix SMTP +server certificate you may want to disable anonymous ciphers +by setting "smtpd_tls_mandatory_exclude_ciphers = aNULL" or +"smtpd_tls_exclude_ciphers = aNULL", as appropriate. One can't force +a remote SMTP client to check the server certificate, so excluding +anonymous ciphers is generally unnecessary. </p> + +<p> With mandatory and opportunistic TLS encryption, the Postfix +SMTP server by default disables SSLv2 and SSLv3 with Postfix releases +after the middle of 2015; older releases only disable SSLv2 for +mandatory TLS. The mandatory TLS protocol list is specified via the +smtpd_tls_mandatory_protocols configuration parameter. The +smtpd_tls_protocols parameter (Postfix ≥ 2.6) +controls the TLS protocols used with opportunistic TLS. </p> + +<p> Note that the OpenSSL library only supports protocol exclusion +(not inclusion). For this reason, Postfix can exclude only protocols +that are known at the time the Postfix software is written. If new +protocols are added to the OpenSSL library, they cannot be excluded +without corresponding changes to the Postfix source code. </p> + +<p> For a server that is not a public Internet MX host, Postfix +supports configurations with no <a href="#server_cert_key">server +certificates</a> that use <b>only</b> the anonymous ciphers. This is +enabled by explicitly setting "smtpd_tls_cert_file = none" +and not specifying an smtpd_tls_dcert_file or smtpd_tls_eccert_file. +Such configurations may not interoperate with some clients, and require +that TLSv1.3 be explicitly disabled. Therefore, they are not +recommended, it is better and simpler to just configure a suitable +certificate. </p> + +<p> Example, MSA that requires TLSv1.2 or higher, with high grade +ciphers: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_cert_file = /etc/postfix/cert.pem + smtpd_tls_key_file = /etc/postfix/key.pem + smtpd_tls_mandatory_ciphers = high + smtpd_tls_mandatory_exclude_ciphers = aNULL, MD5 + smtpd_tls_security_level = encrypt + # Preferred syntax with Postfix ≥ 3.6: + smtpd_tls_mandatory_protocols = >=TLSv1.2 + # Legacy syntax: + smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 +</pre> +</blockquote> + +<p> With Postfix ≥ 3.4, specify instead a single file that holds the +key followed by the corresponding certificate and any associated issuing +certificates, leaving the "smtpd_tls_cert_file" and "smtpd_tls_key_file" +and related DSA and ECDSA parameters empty. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_chain_files = /etc/postfix/rsachain.pem + smtpd_tls_cert_file = + smtpd_tls_key_file = + ... +</pre> +</blockquote> + +<p> If you want to take maximal advantage of ciphers that offer <a +href="FORWARD_SECRECY_README.html#dfn_fs">forward secrecy</a> see +the <a href="FORWARD_SECRECY_README.html#quick-start">Getting +started</a> section of <a +href="FORWARD_SECRECY_README.html">FORWARD_SECRECY_README</a>. The +full document conveniently presents all information about Postfix +forward secrecy support in one place: what forward secrecy is, how +to tweak settings, and what you can expect to see when Postfix uses +ciphers with forward secrecy. </p> + +<p> Postfix 2.8 and later, in combination with OpenSSL 0.9.7 and later +allows TLS servers to preempt the TLS client's cipher-suite preference list. +This is possible only with SSLv3 and later, as in SSLv2 the client +chooses the cipher-suite from a list supplied by the server. </p> + +<p> By default, the OpenSSL server selects the client's most preferred +cipher-suite that the server supports. With SSLv3 and later, the server +may choose its own most preferred cipher-suite that is supported (offered) +by the client. Setting "tls_preempt_cipherlist = yes" enables server +cipher-suite preferences. The default OpenSSL behavior applies with +"tls_preempt_cipherlist = no". </p> + +<p> While server cipher-suite selection may in some cases lead to +a more secure or performant cipher-suite choice, there is some risk +of interoperability issues. In the past, some SSL clients have +listed lower priority ciphers that they did not implement correctly. +If the server chooses a cipher that the client prefers less, it may +select a cipher whose client implementation is flawed. Most notably +Windows 2003 Microsoft Exchange servers have flawed implementations +of DES-CBC3-SHA, which OpenSSL considers stronger than RC4-SHA. +Enabling server cipher-suite selection may create interoperability +issues with Windows 2003 Microsoft Exchange clients. </p> + +<h3><a name="server_misc"> Miscellaneous server controls</a> </h3> + +<p> The smtpd_starttls_timeout parameter limits the time of Postfix +SMTP server write and read operations during TLS startup and shutdown +handshake procedures. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_starttls_timeout = 300s +</pre> +</blockquote> + +<p> With Postfix 2.8 and later, the tls_disable_workarounds parameter +specifies a list or bit-mask of default-enabled OpenSSL bug +work-arounds to disable. This may be necessary if one of the +work-arounds enabled by default in OpenSSL proves to pose a security +risk, or introduces an unexpected interoperability issue. The list +of enabled bug work-arounds is OpenSSL-release-specific. See the +tls_disable_workarounds parameter documentation for the list of +supported values.</p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + tls_disable_workarounds = 0xFFFFFFFF + tls_disable_workarounds = CVE-2010-4180 +</pre> +</blockquote> + +<p> With Postfix ≥ 2.11, the tls_ssl_options parameter specifies +a list or bit-mask of OpenSSL options to enable. Specify one or +more of the named options below, or a hexadecimal bitmask of options +found in the ssl.h file corresponding to the run-time OpenSSL +library. While it may be reasonable to turn off all bug workarounds +(see above), it is not a good idea to attempt to turn on all features. +See the tls_ssl_options parameter documentation for the list of +supported values. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + tls_ssl_options = no_ticket, no_compression +</pre> +</blockquote> + +<p> You should only enable features via the hexadecimal mask when +the need to control the feature is critical (to deal with a new +vulnerability or a serious interoperability problem). Postfix DOES +NOT promise backwards compatible behavior with respect to the mask +bits. A feature enabled via the mask in one release may be enabled +by other means in a later release, and the mask bit will then be +ignored. Therefore, use of the hexadecimal mask is only a temporary +measure until a new Postfix or OpenSSL release provides a better +solution. </p> + +<h2> <a name="client_tls">SMTP Client specific settings</a> </h2> + +<p> Topics covered in this section: </p> + +<ul> + +<li><a href="#client_tls_levels"> Configuring TLS in the SMTP/LMTP client </a> + +<li><a href="#client_logging"> Client-side TLS activity logging </a> + +<li><a href="#client_cert_key">Client-side certificate and private +key configuration </a> + +<li><a href="#client_tls_reuse">Client-side TLS connection reuse</a> + +<li><a href="#client_tls_cache">Client-side TLS session cache</a> + +<li><a href="#client_tls_limits"> Client TLS limitations </a> + +<li><a href="#client_tls_policy"> Per-destination TLS policy </a> + +<li><a href="#client_tls_discover"> Discovering servers that support TLS </a> + +<li><a href="#client_vrfy_server">Server certificate verification depth</a> + +<li> <a href="#client_cipher">Client-side cipher controls </a> + +<li> <a href="#client_smtps">Client-side SMTPS support </a> + +<li> <a href="#client_misc"> Miscellaneous client controls </a> + +</ul> + +<h3><a name="client_tls_levels"> Configuring TLS in the SMTP/LMTP client </a> +</h3> + +<p> Similar to the Postfix SMTP server, the Postfix SMTP/LMTP client +implements multiple TLS security levels. These levels are described +in more detail in the sections that follow.</p> + +<dl> +<dt><b>none</b></dt> +<dd><a href="#client_tls_none">No TLS.</a></dd> +<dt><b>may</b></dt> +<dd><a href="#client_tls_may">Opportunistic TLS.</a></dd> +<dt><b>encrypt</b></dt> +<dd><a href="#client_tls_encrypt">Mandatory TLS encryption.</a> +<dt><b>dane</b></dt> +<dd><a href="#client_tls_dane">Opportunistic DANE TLS.</a> +<dt><b>dane-only</b></dt> +<dd><a href="#client_tls_dane">Mandatory DANE TLS.</a> +<dt><b>fingerprint</b></dt> +<dd><a href="#client_tls_fprint">Certificate fingerprint verification.</a> +<dt><b>verify</b></dt> +<dd><a href="#client_tls_verify">Mandatory server certificate verification.</a> +<dt><b>secure</b></dt> +<dd><a href="#client_tls_secure">Secure-channel TLS.</a> +</dl> + +<h4><a name="client_lmtp_tls"> TLS support in the LMTP delivery agent </a> </h4> + +<p> The smtp(8) and lmtp(8) delivery agents are implemented by a +single dual-purpose program. Specifically, all the TLS features +described below apply +equally to SMTP and LMTP, after replacing the "smtp_" prefix of the each +parameter name with "lmtp_". + +<p> The Postfix LMTP delivery agent can communicate with LMTP servers +listening +on UNIX-domain sockets. When server certificate verification is enabled +and the server is listening on a UNIX-domain socket, the $myhostname +parameter is used to set the TLS verification <i>nexthop</i> and +<i>hostname</i>. </p> + +<p> NOTE: Opportunistic encryption of LMTP traffic over UNIX-domain +sockets or loopback TCP connections is futile. TLS is only useful +in this context when +it is mandatory, typically to allow at least one of the server or the +client to authenticate the other. The "null" cipher grade may be +appropriate in this context, when available on both client and server. +The "null" ciphers provide authentication without encryption. </p> + +<h4><a name="client_tls_none"> No TLS encryption </a> </h4> + +<p> At the "none" TLS security level, TLS encryption is +disabled. This is the default security level, and +can be configured explicitly by setting "smtp_tls_security_level = none". +For LMTP, use the corresponding "lmtp_" parameter. </p> + +<p> Per-destination settings may override this default setting, in which case +TLS is used selectively, only with destinations explicitly configured +for TLS. </p> + +<p> You can disable TLS for a subset of destinations, while leaving +it enabled for the rest. With the Postfix TLS <a +href="#client_tls_policy">policy table</a>, specify the "none" +security level. + +<h4><a name="client_tls_may"> Opportunistic TLS </a> </h4> + +<p> At the "may" TLS security level, TLS encryption is <i>opportunistic</i>. +The SMTP transaction is encrypted if the STARTTLS ESMTP feature +is supported by the server. Otherwise, messages are sent in the clear. +Opportunistic TLS can be configured by setting "smtp_tls_security_level = may". +For LMTP, use the corresponding "lmtp_" parameter. </p> + +<p> The "smtp_tls_ciphers" and "smtp_tls_protocols" configuration +parameters (Postfix ≥ 2.6) provide control over the cipher grade +and protocols used with opportunistic TLS. With earlier Postfix +releases, opportunistic TLS always uses the cipher grade "export" +and enables all protocols. </p> + +<p> With opportunistic TLS, mail delivery continues even if the +server certificate is untrusted or bears the wrong name. +When the TLS handshake fails for an opportunistic +TLS session, rather than give up on mail delivery, the Postfix SMTP +client retries the transaction +with TLS disabled. Trying an unencrypted connection makes +it possible to deliver mail to sites with non-interoperable server +TLS implementations. </p> + +<p> Opportunistic encryption is never used for LMTP over UNIX-domain +sockets. The communications channel is already confidential without +TLS, so the only potential benefit of TLS is authentication. Do not +configure opportunistic TLS for LMTP deliveries over UNIX-domain sockets. +Only configure TLS for LMTP over UNIX-domain sockets at the +<a href="#client_tls_encrypt">encrypt</a> security level or higher. +Attempts to configure opportunistic encryption of LMTP sessions will +be ignored with a warning written to the mail logs. </p> + +<p> You can enable opportunistic TLS just for selected destinations. With +the Postfix TLS <a href="#client_tls_policy">policy table</a>, +specify the "may" security level. </p> + +<p> This is the most common security level for TLS protected SMTP +sessions, stronger security is not generally available and, if needed, +is typically only configured on a per-destination basis. See the section +on TLS <a href="#client_tls_limits">limitations</a> above. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_security_level = may +</pre> +</blockquote> + +<h4><a name="client_tls_encrypt"> Mandatory TLS encryption </a> </h4> + +<p> At the "encrypt" TLS security level, messages are sent only +over TLS encrypted sessions. The SMTP transaction is aborted unless +the STARTTLS ESMTP feature is supported by the remote SMTP server. +If no suitable +servers are found, the message will be deferred. +Mandatory TLS encryption can be configured by setting +"smtp_tls_security_level = encrypt". Even though TLS +encryption is always used, mail delivery continues even if the server +certificate is untrusted or bears the wrong name. +For LMTP, use the corresponding "lmtp_" parameter. </p> + +<p> At this security level and higher, the smtp_tls_mandatory_protocols +and smtp_tls_mandatory_ciphers configuration parameters determine +the list of sufficiently secure SSL protocol versions and the minimum +cipher strength. If the protocol or cipher requirements are not +met, the mail transaction is aborted. The documentation for these +parameters includes useful interoperability and security guidelines. +</p> + +<p> Despite the potential for eliminating passive eavesdropping attacks, +mandatory TLS encryption is not viable as a default security level for +mail delivery to the public Internet. Some MX hosts do not support TLS at +all, and some of those that do have broken implementations. On a host +that delivers mail to the Internet, you should not configure mandatory +TLS encryption as the default security level. </p> + +<p> You can enable mandatory TLS encryption just for specific destinations. +With the Postfix TLS <a href="#client_tls_policy">policy +table</a>, specify the "encrypt" security level. +</p> + +<p> Examples: </p> + +<p> In the example below, traffic to <i>example.com</i> and its sub-domains +via the corresponding MX hosts always uses TLS. The SSLv2 protocol +will be disabled (the default setting of smtp_tls_mandatory_protocols +excludes SSLv2+3). Only high- or medium-strength (i.e. 128 bit or +better) ciphers will be used by default for all "encrypt" security +level sessions. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_policy_maps = hash:/etc/postfix/tls_policy + +/etc/postfix/tls_policy: + example.com encrypt + .example.com encrypt +</pre> +</blockquote> + +<p> In the next example, secure message submission is configured +via the MSA "<tt>[example.net]:587</tt>". TLS sessions are encrypted +without authentication, because this MSA does not possess an acceptable +certificate. This MSA is known to be capable of "TLSv1" and "high" grade +ciphers, so these are selected via the <a href="#client_tls_policy">policy +table</a>. </p> + +<p><b>Note:</b> the policy table lookup key is the verbatim next-hop +specification from the recipient domain, transport(5) table or relayhost +parameter, with any enclosing square brackets and optional port. Take +care to be consistent: the suffixes ":smtp" or ":25" or no port suffix +result in different policy table lookup keys, even though they are +functionally equivalent nexthop specifications. Use at most one of these +forms for all destinations. Below, the policy table has multiple keys, +just in case the transport table entries are not specified consistently. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_policy_maps = hash:/etc/postfix/tls_policy + +/etc/services: + submission 587/tcp msa # mail message submission + +/etc/postfix/tls_policy: + # Postfix ≥ 3.6 "protocols" syntax + [example.net]:587 encrypt protocols=>=TLSv1.2 ciphers=high + # Legacy "protocols" syntax + [example.net]:msa encrypt protocols=!SSLv2:!SSLv3 ciphers=high +</pre> +</blockquote> + +<h4><a name="client_tls_dane">DANE TLS authentication.</a> </h4> + +<p> The Postfix SMTP client supports two TLS security levels based +on DANE TLSA (RFC 6698, RFC 7671, RFC 7672) records. The opportunistic +"dane" level and the mandatory "dane-only" level. </p> + +<p> The "dane" level is a stronger form of <a +href="#client_tls_may">opportunistic</a> TLS that is resistant to +man in the middle and downgrade attacks when the destination domain +uses DNSSEC to publish DANE TLSA records for its MX hosts. If a +remote SMTP server has "usable" (see section 3 of RFC 7672) DANE +TLSA records, the server connection will be authenticated. When +DANE authentication fails, there is no fallback to unauthenticated +or plaintext delivery. </p> + +<p> If TLSA records are published for a given remote SMTP server +(implying TLS support), but are all "unusable" due to unsupported +parameters or malformed data, the Postfix SMTP client will use <a +href="#client_tls_encrypt">mandatory</a> unauthenticated TLS. +Otherwise, when no TLSA records are published, the Postfix SMTP +client behavior is the same as with <a href="#client_tls_may">may</a>. </p> + +<p> TLSA records must be published in DNSSEC validated DNS zones. +Any TLSA records in DNS zones not protected via DNSSEC are ignored. +The Postfix SMTP client will not look for TLSA records associated +with MX hosts whose "A" or "AAAA" records lie in an "insecure" DNS +zone. Such lookups have been observed to cause interoperability +issues with poorly implemented DNS servers, and are in any case not +expected to ever yield "secure" results, since that would require +a very unlikely DLV DNS trust anchor configured between the host +record and the associated "_25._tcp" child TLSA record. </p> + +<p> The "dane-only" level is a form of <a +href="#client_tls_secure">secure-channel</a> TLS based on the DANE PKI. +If "usable" TLSA records are present these are used to authenticate the +remote SMTP server. Otherwise, or when server certificate verification +fails, delivery via the server in question tempfails. </p> + +<p> At both security levels, the TLS policy for the destination is +obtained via TLSA records validated with DNSSEC. For TLSA policy +to be in effect, the destination domain's containing DNS zone must +be signed and the Postfix SMTP client's operating system must be +configured to send its DNS queries to a recursive DNS nameserver +that is able to validate the signed records. Each MX host's DNS +zone needs to also be signed, and needs to publish DANE TLSA (see +section 3 of RFC 7672) records that specify how that MX host's TLS +certificate is to be verified. </p> + +<p> TLSA records do not preempt the normal SMTP MX host +selection algorithm, if some MX hosts support TLSA and others do +not, TLS security will vary from delivery to delivery. It is up +to the domain owner to configure their MX hosts and their DNS +sensibly. To configure the Postfix SMTP client for DNSSEC lookups +see the documentation for the smtp_dns_support_level main.cf +parameter. The tls_dane_digests parameter controls the list of +supported digests. </p> + +<p> As explained in section 3 of RFC 7672, certificate usages "0" +and "1", which are intended to "constrain" existing Web-PKI trust, +are not supported with MTA-to-MTA SMTP. Rather, TLSA records with +usages "0" and "1" are treated as "unusable". </p> + +<p> The Postfix SMTP client supports only certificate usages "2" +and "3". Experimental support for silently mapping certificate +usage "1" to "3" has been withdrawn starting with Postfix 3.2. </p> + +<p> When usable TLSA records are obtained for the remote SMTP server +the Postfix SMTP client sends the SNI TLS extension in its SSL +client hello message. This may help the remote SMTP server live +up to its promise to provide a certificate that matches its TLSA +records. </p> + +<p> For purposes of protocol and cipher selection, the "dane" +security level is treated like a "mandatory" TLS security level, +and weak ciphers and protocols are disabled. Since DANE authenticates +server certificates the "aNULL" cipher-suites are transparently +excluded at this level, no need to configure this manually. RFC +7672 (DANE) TLS authentication is available with Postfix 2.11 and +later. </p> + +<p> When a DANE TLSA record specifies a trust-anchor (TA) certificate +(that is an issuing CA), the strategy used to verify the peername +of the server certificate is unconditionally "nexthop, hostname". +Both the nexthop domain and the hostname obtained from the +DNSSEC-validated MX lookup are safe from forgery and the server +certificate must contain at least one of these names. </p> + +<p> When a DANE TLSA record specifies an end-entity (EE) certificate, +(that is the actual server certificate), as with the fingerprint +security level below, no name checks or certificate expiration checks +are applied. The server certificate (or its public key) either matches +the DANE record or not. Server administrators should publish such +EE records in preference to all other types. </p> + +<p> The pre-requisites for DANE support in the Postfix SMTP client are: </p> +<ul> +<li> A <i>compile-time</i> OpenSSL library that supports the TLS SNI +extension and "SHA-2" message digests. +<li> A <i>compile-time</i> DNS resolver library that supports DNSSEC. +Postfix binaries built on an older system will not support DNSSEC even +if deployed on a system with an updated resolver library. +<li> The "smtp_dns_support_level" must be set to "dnssec". +<li> The "smtp_host_lookup" parameter must include "dns". +<li> A DNSSEC-validating recursive resolver (see note below). +</ul> +<p> The above client pre-requisites do not apply to the Postfix SMTP server. +It will support DANE provided it supports TLSv1 and its TLSA records are +published in a DNSSEC signed zone. To receive DANE secured mail for multiple +domains, use the same hostname to add the server to each domain's MX +records. The Postfix SMTP server supports SNI (Postfix 3.4 and later), +configured with tls_server_sni_maps. </p> + +<p> Note: The Postfix SMTP client's internal stub DNS resolver is +DNSSEC-aware, but it does not itself validate DNSSEC records, rather +it delegates DNSSEC validation to the operating system's configured +recursive DNS nameserver. The Postfix DNS client relies on a secure +channel to the resolver's cache for DNSSEC integrity, but does not +support TSIG to protect the transmission channel between itself and +the nameserver. Therefore, it is strongly recommended (DANE security +guarantee void otherwise) that each MTA run a local DNSSEC-validating +recursive resolver ("unbound" from nlnetlabs.nl is a reasonable +choice) listening on the loopback interface, and that the system +be configured to use <i>only</i> this local nameserver. The local +nameserver may forward queries to an upstream recursive resolver +on another host if desired. </p> + +<p> Note: When the operating system's recursive nameserver is not +local, enabling EDNS0 expanded DNS packet sizes and turning on the +DNSSEC "DO" bit in the DNS request and/or the new DNSSEC-specific +records returned in the nameserver's replies may cause problems +with older or buggy firewall and DNS server implementations. +Therefore, Postfix does not enable DNSSEC by default. Since MX +lookups happen before the security level is determined, DANE support +is disabled for all destinations unless you set "smtp_dns_support_level += dnssec". To enable DNSSEC lookups selectively, define a new +dedicated transport with a "-o smtp_dns_support_level=dnssec" +override in master.cf and route selected domains to that transport. +If DNSSEC proves to be sufficiently reliable for these domains, you +can enable it for all destinations by changing the global +smtp_dns_support_level in main.cf. </p> + +<p><b>Example</b>: "dane" security for selected destinations, with +opportunistic TLS by default. This is the recommended configuration +for early adopters. <p> +<ul> +<li> <p> The "example.com" destination uses DANE, but if TLSA records +are not present or are unusable, mail is deferred. </p> + +<li> <p> The "example.org" destination uses DANE if possible, but if no TLSA +records are found opportunistic TLS is used. </p> +</ul> + +<blockquote> +<pre> +main.cf: + indexed = ${default_database_type}:${config_directory}/ + # + # default: Opportunistic TLS with no DNSSEC lookups. + # + smtp_tls_security_level = may + smtp_dns_support_level = enabled + # + # Per-destination TLS policy + # + smtp_tls_policy_maps = ${indexed}tls_policy + # + # default_transport = smtp, but some destinations are special: + # + transport_maps = ${indexed}transport +</pre> +</blockquote> + +<blockquote> +<pre> +transport: + example.com dane + example.org dane +</pre> +</blockquote> + +<blockquote> +<pre> +tls_policy: + example.com dane-only +</pre> +</blockquote> + +<blockquote> +<pre> +master.cf: + dane unix - - n - - smtp + -o smtp_dns_support_level=dnssec + -o smtp_tls_security_level=dane +</pre> +</blockquote> + +<h4><a name="client_tls_fprint"> Certificate fingerprint verification </a> </h4> + +<p> At the <i>fingerprint</i> security level, no trusted Certification +Authorities are used or required. The certificate trust chain, +expiration date, etc., are not checked. Instead, the +smtp_tls_fingerprint_cert_match parameter or the "match" attribute +in the <a href="#client_tls_policy">policy</a> table lists the +remote SMTP server certificate fingerprint or public key fingerprint. +Certificate fingerprint verification is available with Postfix 2.5 +and later, public-key fingerprint support is available with Postfix +2.9 and later. </p> + +<p> If certificate fingerprints are exchanged securely, this is the +strongest, and least scalable security level. The administrator needs +to securely collect the fingerprints of the X.509 certificates of each +peer server, store them into a local file, and update this local file +whenever the peer server's public certificate changes. If public key +fingerprints are used in place of fingerprints of the entire certificate, +the fingerprints remain valid even after the certificate is renewed, +<b>provided</b> that the same public/private keys are used to obtain +the new certificate. </p> + +<p> Fingerprint verification may be feasible for an SMTP "VPN" connecting +a small number of branch offices over the Internet, or for secure +connections to a central mail hub. It works poorly if the remote SMTP +server is managed by a third party, and its public certificate changes +periodically without prior coordination with the verifying site. </p> + +<p> The digest algorithm used to calculate the fingerprint is +selected by the <b>smtp_tls_fingerprint_digest</b> parameter. In the <a +href="#client_tls_policy">policy</a> table multiple fingerprints can be +combined with a "|" delimiter in a single match attribute, or multiple +match attributes can be employed. The ":" character is not used as a +delimiter as it occurs between each pair of fingerprint (hexadecimal) +digits. </p> + +<p> The default algorithm is <b>sha256</b> with Postfix ≥ 3.6 +and the <b>compatibility_level</b> set to 3.6 or higher; with Postfix +≤ 3.5, the default algorithm is <b>md5</b>. The +best-practice algorithm is now <b>sha256</b>. Recent advances in hash +function cryptanalysis have led to md5 and sha1 being deprecated in +favor of sha256. However, as long as there are no known "second +pre-image" attacks against the older algorithms, their use in this +context, though not recommended, is still likely safe. </p> + +<p> Example: fingerprint TLS security with an internal mailhub. +Two matching fingerprints are listed. The relayhost may be multiple +physical hosts behind a load-balancer, each with its own private/public +key and self-signed certificate. Alternatively, a single relayhost may +be in the process of switching from one set of private/public keys to +another, and both keys are trusted just prior to the transition. </p> + +<blockquote> +<pre> + relayhost = [mailhub.example.com] + smtp_tls_security_level = fingerprint + smtp_tls_fingerprint_digest = sha256 + smtp_tls_fingerprint_cert_match = + 51:e9:af:2e:1e:40:1f:de:64:...:30:35:2d:09:16:31:5a:eb:82:76 + b6:b4:72:34:e2:59:cd:fb:c2:...:63:0d:4d:cc:2c:7d:84:de:e6:2f +</pre> +</blockquote> + +<p> Example: Certificate fingerprint verification with selected destinations. +As in the example above, we show two matching fingerprints: </p> +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_policy_maps = hash:/etc/postfix/tls_policy + smtp_tls_fingerprint_digest = sha256 +</pre> +</blockquote> +<blockquote> +<pre> +/etc/postfix/tls_policy: + example.com fingerprint + match=51:e9:af:2e:1e:40:1f:de:...:35:2d:09:16:31:5a:eb:82:76 + match=b6:b4:72:34:e2:59:cd:fb:...:0d:4d:cc:2c:7d:84:de:e6:2f +</pre> +</blockquote> + +<p> To extract the public key fingerprint from an X.509 certificate, +you need to extract the public key from the certificate and compute +the appropriate digest of its DER (ASN.1) encoding. With OpenSSL +the "-pubkey" option of the "x509" command extracts the public +key always in "PEM" format. We pipe the result to another OpenSSL +command that converts the key to DER and then to the "dgst" command +to compute the fingerprint. </p> + +<p> Example: </p> +<blockquote> +<pre> +$ openssl x509 -in cert.pem -noout -pubkey | + openssl pkey -pubin -outform DER | + openssl dgst -sha256 -c +(stdin)= 64:3f:1f:f6:e5:1e:d4:2a:56:...:09:1a:61:98:b5:bc:7c:60:58 +</pre> +</blockquote> + +<h4><a name="client_tls_verify"> Mandatory server certificate verification </a> </h4> + +<p> At the <i>verify</i> TLS security level, messages are sent only over +TLS encrypted sessions if the remote SMTP server certificate is +valid (not +expired or revoked, and signed by a trusted Certification Authority) +and where the server certificate name matches a known pattern. +Mandatory +server certificate verification can be configured by setting +"smtp_tls_security_level = verify". The +smtp_tls_verify_cert_match parameter can override the default +"hostname" certificate name matching strategy. Fine-tuning the +matching strategy is generally only appropriate for <a +href="#client_tls_secure">secure-channel</a> destinations. +For LMTP use the corresponding "lmtp_" parameters. </p> + +<p> If the server certificate chain is trusted (see smtp_tls_CAfile +and smtp_tls_CApath), any DNS names in the SubjectAlternativeName +certificate extension are used to verify the remote SMTP server name. +If no +DNS names are specified, the certificate CommonName is checked. +If you want mandatory encryption without server certificate +verification, see <a href="#client_tls_encrypt">above</a>. </p> + +<p> With Postfix ≥ 2.11 the "smtp_tls_trust_anchor_file" parameter +or more typically the corresponding per-destination "tafile" attribute +optionally modifies trust chain verification. If the parameter is +not empty the root CAs in CAfile and CApath are no longer trusted. +Rather, the Postfix SMTP client will only trust certificate-chains +signed by one of the trust-anchors contained in the chosen files. +The specified trust-anchor certificates and public keys are not +subject to expiration, and need not be (self-signed) root CAs. They +may, if desired, be intermediate certificates. Therefore, these +certificates also may be found "in the middle" of the trust chain +presented by the remote SMTP server, and any untrusted issuing +parent certificates will be ignored. </p> + +<p> Despite the potential for eliminating "man-in-the-middle" and other +attacks, mandatory certificate trust chain and subject name verification +is not viable as a default Internet mail delivery policy. Some MX hosts +do not support TLS at all, and a significant portion of TLS-enabled +MTAs use self-signed certificates, or certificates that are signed by +a private Certification Authority. On a machine that delivers mail to +the Internet, you should not configure mandatory server certificate +verification as a default policy. </p> + +<p> Mandatory server certificate verification as a default security +level may be appropriate if you know that you will only connect to +servers that support RFC 2487 <i>and</i> that present verifiable +server certificates. An example would be a client that sends all +email to a central mailhub that offers the necessary STARTTLS +support. In such cases, you can often use a <a +href="#client_tls_secure">secure-channel</a> configuration instead. +</p> + +<p> You can enable mandatory server certificate verification just +for specific destinations. With the Postfix TLS <a +href="#client_tls_policy">policy table</a>, specify the "verify" +security level. </p> + +<p> Example: </p> + +<p> In this example, the Postfix SMTP client encrypts all traffic to the +<i>example.com</i> domain. The peer hostname is verified, but +verification is vulnerable to DNS response forgery. Mail transmission +to <i>example.com</i> recipients uses "high" grade ciphers. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + indexed = ${default_database_type}:${config_directory}/ + smtp_tls_CAfile = ${config_directory}/CAfile.pem + smtp_tls_policy_maps = ${indexed}tls_policy + +/etc/postfix/tls_policy: + example.com verify ciphers=high +</pre> +</blockquote> + +<h4><a name="client_tls_secure"> Secure server certificate verification </a> </h4> + +<p> At the <i>secure</i> TLS security level, messages are sent only over +<i>secure-channel</i> TLS sessions where DNS forgery resistant server +certificate verification succeeds. If no suitable servers are found, the +message will be deferred. Postfix secure-channels +can be configured by setting "smtp_tls_security_level = secure". +The smtp_tls_secure_cert_match parameter can override the default +"nexthop, dot-nexthop" certificate match strategy. +For LMTP, use the corresponding "lmtp_" parameters. </p> + +<p> If the server certificate chain is trusted (see smtp_tls_CAfile and +smtp_tls_CApath), any DNS names in the SubjectAlternativeName certificate +extension are used to verify the remote SMTP server name. If no DNS names +are +specified, the CommonName is checked. If you want mandatory encryption +without server certificate verification, see <a +href="#client_tls_encrypt">above</a>. </p> + +<p> With Postfix ≥ 2.11 the "smtp_tls_trust_anchor_file" parameter +or more typically the corresponding per-destination "tafile" attribute +optionally modifies trust chain verification. If the parameter is +not empty the root CAs in CAfile and CApath are no longer trusted. +Rather, the Postfix SMTP client will only trust certificate-chains +signed by one of the trust-anchors contained in the chosen files. +The specified trust-anchor certificates and public keys are not +subject to expiration, and need not be (self-signed) root CAs. They +may, if desired, be intermediate certificates. Therefore, these +certificates also may be found "in the middle" of the trust chain +presented by the remote SMTP server, and any untrusted issuing +parent certificates will be ignored. </p> + +<p> Despite the potential for eliminating "man-in-the-middle" and other +attacks, mandatory secure server certificate verification is not +viable as a default Internet mail delivery policy. Some MX hosts +do not support TLS at all, and a significant portion of TLS-enabled +MTAs use self-signed certificates, or certificates that are signed +by a private Certification Authority. On a machine that delivers mail +to the Internet, you should not configure secure TLS verification +as a default policy. </p> + +<p> Mandatory secure server certificate verification as a default +security level may be appropriate if you know that you will only +connect to servers that support RFC 2487 <i>and</i> that present +verifiable server certificates. An example would be a client that +sends all email to a central mailhub that offers the necessary +STARTTLS support. </p> + +<p> You can enable secure TLS verification just for specific destinations. +With the Postfix TLS <a href="#client_tls_policy">policy table</a>, +specify the "secure" security level. </p> + +<p> Examples: </p> + +<ul> + +<li> <p> Secure-channel TLS without transport(5) table overrides: </p> + +<p> The Postfix SMTP client will encrypt all traffic and verify the +destination name +immune from forged DNS responses. MX lookups are still used to find +the hostnames of the SMTP servers for <i>example.com</i>, but these +hostnames are not used when +checking the names in the server certificate(s). Rather, the requirement +is that the MX hosts for <i>example.com</i> have trusted certificates +with a subject name of <i>example.com</i> or a sub-domain, see the +documentation for the smtp_tls_secure_cert_match parameter. </p> + +<p> The related domains <i>example.co.uk</i> and <i>example.co.jp</i> are +hosted on the same MX hosts as the primary <i>example.com</i> domain, and +traffic to these is secured by verifying the primary <i>example.com</i> +domain in the server certificates. This frees the server administrator +from needing the CA to sign certificates that list all the secondary +domains. The downside is that clients that want secure channels to the +secondary domains need explicit TLS <a href="#client_tls_policy">policy +table</a> entries. </p> + +<p> Note, there are two ways to handle related domains. The first is to +use the default routing for each domain, but add policy table entries +to override the expected certificate subject name. The second is to +override the next-hop in the transport table, and use a single policy +table entry for the common nexthop. We choose the first approach, +because it works better when domain ownership changes. With the second +approach we securely deliver mail to the wrong destination, with the +first approach, authentication fails and mail stays in the local queue, +the first approach is more appropriate in most cases. <p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_CAfile = /etc/postfix/CAfile.pem + smtp_tls_policy_maps = hash:/etc/postfix/tls_policy + +/etc/postfix/transport: + +/etc/postfix/tls_policy: + example.com secure + example.co.uk secure match=example.com:.example.com + example.co.jp secure match=example.com:.example.com +</pre> +</blockquote> + +<li> <p> Secure-channel TLS with transport(5) table overrides: <p> + +<p> In this case traffic to <i>example.com</i> and its related domains +is sent to a single logical gateway (to avoid a single point of failure, +its name may resolve to one or more load-balancer addresses, or to the +combined addresses of multiple physical hosts). All the physical hosts +reachable via the gateway's IP addresses have the logical gateway name +listed in their certificates. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_CAfile = /etc/postfix/CAfile.pem + transport_maps = hash:/etc/postfix/transport + smtp_tls_policy_maps = hash:/etc/postfix/tls_policy + +/etc/postfix/transport: + example.com smtp:[tls.example.com] + example.co.uk smtp:[tls.example.com] + example.co.jp smtp:[tls.example.com] + +/etc/postfix/tls_policy: + [tls.example.com] secure match=tls.example.com +</pre> +</blockquote> + +</ul> + +<h3><a name="client_logging"> Client-side TLS activity logging </a> </h3> + +<p> To get additional information about Postfix SMTP client TLS +activity you can increase the loglevel from 0..4. Each logging +level also includes the information that is logged at a lower +logging level. </p> + +<blockquote> + +<table border="1"> + +<tr> <th> Level </th> <th> Postfix 2.9 and later</th> <th> Earlier +releases. </th> </tr> + +<tr> <td valign="top"> 0 </td> <td valign="top" colspan="2"> Disable +logging of TLS activity. </td> </tr> + +<tr> <td valign="top"> 1 </td> <td valign="top"> Log only a summary +message on TLS handshake completion — no logging of remote SMTP +server certificate trust-chain verification errors if server certificate +verification is not required. </td> <td valign="top"> Log the summary +message and unconditionally log trust-chain verification errors. +</td> </tr> + +<tr> <td valign="top"> 2 </td> <td valign="top" colspan="2"> Also +log levels during TLS negotiation. </td> </tr> + +<tr> <td valign="top"> 3 </td> <td valign="top" colspan="2"> Also +log hexadecimal and ASCII dump of TLS negotiation process. </td> +</tr> + +<tr> <td valign="top"> 4 </td> <td valign="top" colspan="2"> Also +log hexadecimal and ASCII dump of complete transmission after +STARTTLS. </td> </tr> + +</table> + +</blockquote> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_loglevel = 0 +</pre> +</blockquote> + +<h3><a name="client_cert_key">Client-side certificate and private +key configuration </a> </h3> + +<p> Do not configure Postfix SMTP client certificates unless you <b>must</b> +present +client TLS certificates to one or more servers. Client certificates are +not usually needed, and can cause problems in configurations that work +well without them. The recommended setting is to let the defaults stand: </p> + +<blockquote> +<pre> + smtp_tls_cert_file = + smtp_tls_dcert_file = + smtp_tls_key_file = + smtp_tls_dkey_file = + # Postfix ≥ 2.6 + smtp_tls_eccert_file = + smtp_tls_eckey_file = + # Postfix ≥ 3.4 + smtp_tls_chain_files = +</pre> +</blockquote> + +<p> The best way to use the default settings is to comment out the above +parameters in main.cf if present. </p> + +<p> During TLS startup negotiation the Postfix SMTP client may present a +certificate to the remote SMTP server. Browsers typically let the user +select among the certificates that match the CA names indicated by the +remote SMTP server. The Postfix SMTP client does not yet have a mechanism +to select from multiple candidate certificates on the fly, and supports a +single set of certificates (at most one per public key algorithm). </p> + +<p> RSA, DSA and ECDSA (Postfix ≥ 2.6) certificates are supported. +You can configure all three at the same time, in which case the +cipher used determines which certificate is presented. </p> + +<p> It is possible for the Postfix SMTP client to use the same +key/certificate pair as the Postfix SMTP server. If a certificate +is to be presented, it must be in "PEM" format. The private key +must not be encrypted, meaning: it must be accessible without +a password. Both parts (certificate and private key) may be in the +same file. </p> + +<p> With OpenSSL 1.1.1 and Postfix ≥ 3.4 it is also possible to +configure Ed25519 and Ed448 certificates. Rather than add two more +pairs of key and certificate parameters, Postfix 3.4 introduces a new +"smtp_tls_chain_files" parameter which specifies all the configured +certificates at once, and handles files that hold both the key and the +associated certificates in one pass, thereby avoiding potential race +conditions during key rollover. </p> + +<p> To enable remote SMTP servers to verify the Postfix SMTP client +certificate, the issuing CA certificates must be made available to the +server. You should include the required certificates in the client +certificate file, the client certificate first, then the issuing +CA(s) (bottom-up order). </p> + +<p> Example: the certificate for "client.example.com" was issued by +"intermediate CA" which itself has a certificate issued by "root CA". +As the "root" super-user create the client.pem file with: </p> + +<blockquote> +<pre> +# <b>umask 077</b> +# <b>cat client_key.pem client_cert.pem intermediate_CA.pem > chain.pem </b> +</pre> +</blockquote> + +<p> A Postfix SMTP client certificate supplied here must be usable +as an SSL client certificate and hence pass the "openssl verify -purpose +sslclient ..." test. </p> + +<p> A server that trusts the root CA has a local copy of the root +CA certificate, so it is not necessary to include the root CA +certificate here. Leaving it out of the "chain.pem" file reduces +the overhead of the TLS exchange. </p> + +<p> If you want the Postfix SMTP client to accept remote SMTP server +certificates issued by these CAs, append the root certificate to +$smtp_tls_CAfile or install it in the $smtp_tls_CApath directory. </p> + +<p> Example: Postfix ≥ 3.4 all-in-one chain file(s). One or more +chain files that start with a key that is immediately followed by the +corresponding certificate and any additional issuer certificates. A +single file can hold multiple <i>(key, cert, [chain])</i> sequences, one +per algorithm. It is typically simpler to keep the chain for each +algorithm in its own file. Most users are likely to deploy at most a +single RSA chain, but with OpenSSL 1.1.1, it is possible to deploy up +five chains, one each for RSA, ECDSA, ED25519, ED448, and even the +obsolete DSA. </p> + +<blockquote> +<pre> + # Postfix ≥ 3.4. Preferred configuration interface. Each file + # starts with the private key, followed by the corresponding + # certificate, and any intermediate issuer certificates. + # + smtp_tls_chain_files = + /etc/postfix/rsa.pem, + /etc/postfix/ecdsa.pem, + /etc/postfix/ed25519.pem, + /etc/postfix/ed448.pem +</pre> +</blockquote> + +<p> You can also store the keys separately from their certificates, again +provided each is listed before the corresponding certificate chain. Storing a +key and its associated certificate chain in separate files is not recommended, +because this is prone to race conditions during key rollover, as there is no +way to update multiple files atomically. </p> + +<blockquote> +<pre> + # Postfix ≥ 3.4. + # Storing keys separately from the associated certificates is not + # recommended. + smtp_tls_chain_files = + /etc/postfix/rsakey.pem, + /etc/postfix/rsacerts.pem, + /etc/postfix/ecdsakey.pem, + /etc/postfix/ecdsacerts.pem +</pre> +</blockquote> + +<p> The below examples show the legacy algorithm-specific configurations +for Postfix 3.3 and older. With Postfix ≤ 3.3, even if the key is +stored in the same file as the certificate, the file is read twice and a +(brief) race condition still exists during key rollover. While Postfix +≥ 3.4 avoids the race when the key and certificate are in the same +file, you should use the new "smtp_tls_chain_files" interface shown +above. <p> + +<p> RSA key and certificate examples: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_cert_file = /etc/postfix/client.pem + smtp_tls_key_file = $smtp_tls_cert_file +</pre> +</blockquote> + +<p> Their DSA counterparts: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_dcert_file = /etc/postfix/client-dsa.pem + smtp_tls_dkey_file = $smtp_tls_dcert_file +</pre> +</blockquote> + +<p> Their ECDSA counterparts (Postfix ≥ 2.6 + OpenSSL ≥ 1.0.0): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_eccert_file = /etc/postfix/client-ecdsa.pem + smtp_tls_eckey_file = $smtp_tls_eccert_file +</pre> +</blockquote> + +<p> To verify a remote SMTP server certificate, the Postfix SMTP +client needs to trust the certificates of the issuing Certification +Authorities. These certificates in "pem" format can be stored in a +single $smtp_tls_CAfile or in multiple files, one CA per file in +the $smtp_tls_CApath directory. If you use a directory, don't forget +to create the necessary "hash" links with: </p> + +<blockquote> +<pre> +# <b>$OPENSSL_HOME/bin/c_rehash <i>/path/to/directory</i> </b> +</pre> +</blockquote> + +<p> The $smtp_tls_CAfile contains the CA certificates of one or more +trusted CAs. The file is opened (with root privileges) before Postfix +enters the optional chroot jail and so need not be accessible from inside the +chroot jail. </p> + +<p> Additional trusted CAs can be specified via the $smtp_tls_CApath +directory, in which case the certificates are read (with $mail_owner +privileges) from the files in the directory when the information +is needed. Thus, the $smtp_tls_CApath directory needs to be accessible +inside the optional chroot jail. </p> + +<p> The choice between $smtp_tls_CAfile and $smtp_tls_CApath is +a space/time tradeoff. If there are many trusted CAs, the cost of +preloading them all into memory may not pay off in reduced access time +when the certificate is needed. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_CAfile = /etc/postfix/CAcert.pem + smtp_tls_CApath = /etc/postfix/certs +</pre> +</blockquote> + +<h3><a name="client_tls_reuse">Client-side TLS connection reuse</a> </h3> + +<p> Historically, the Postfix SMTP client has supported multiple +deliveries per plaintext connection. Postfix 3.4 introduces support +for multiple deliveries per TLS-encrypted connection. Multiple +deliveries per connection improve mail delivery performance, +especially for destinations that throttle clients that don't combine +deliveries. </p> + +<p> To enable multiple deliveries per TLS connection, specify:</p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_connection_reuse = yes +</pre> +</blockquote> + +<p> Alternatively, specify the attribute "connection_reuse=yes" in +an smtp_tls_policy_maps entry. </p> + +<p> The implementation of TLS connection reuse relies on the same +scache(8) service as used for delivering plaintext SMTP mail, the +same tlsproxy(8) daemon as used by the postscreen(8) service, and +relies on the same hints from the qmgr(8) daemon. + +See "<a href="CONNECTION_CACHE_README.html">Postfix Connection +Cache</a>" for a description of the underlying connection reuse +infrastructure. </p> + +<p> Initial SMTP handshake:</p> +<pre> smtp(8) -> remote SMTP server</pre> + +<p> Reused SMTP/TLS connection, or new SMTP/TLS connection: </p> +<pre> smtp(8) -> tlsproxy(8) -> remote SMTP server </pre> + +<p> Cached SMTP/TLS connection:</p> +<pre> scache(8) -> tlsproxy(8) -> remote SMTP server</pre> + +<p> As of Postfix 3.4, TLS connection reuse is disabled by default. +This may change once the impact on over-all performance is understood. +</p> + +<h3><a name="client_tls_cache">Client-side TLS session cache</a> </h3> + +<p> The remote SMTP server and the Postfix SMTP client negotiate a +session, which takes some computer time and network bandwidth. By +default, this session information is cached only in the smtp(8) +process actually using this session and is lost when the process +terminates. To share the session information between multiple +smtp(8) processes, a persistent session cache can be used. You +can specify any database type that can store objects of several +kbytes and that supports the sequence operator. DBM databases are +not suitable because they can only store small objects. The cache +is maintained by the tlsmgr(8) process, so there is no problem with +concurrent access. Session caching is highly recommended, because +the cost of repeatedly negotiating TLS session keys is high. Future +Postfix SMTP servers may limit the number of sessions that a client +is allowed to negotiate per unit time.</p> + + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_scache +</pre> +</blockquote> + +<p> Note: as of version 2.5, Postfix no longer uses root privileges +when opening this file. The file should now be stored under the +Postfix-owned data_directory. As a migration aid, an attempt to +open the file under a non-Postfix directory is redirected to the +Postfix-owned data_directory, and a warning is logged. </p> + +<p> Cached Postfix SMTP client session information expires after +a certain amount of time. Postfix/TLS does not use the OpenSSL +default of 300s, but a longer time of 3600s (=1 hour). RFC 2246 +recommends a maximum of 24 hours. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_session_cache_timeout = 3600s +</pre> +</blockquote> + +<p> As of Postfix 2.11 this setting cannot exceed 100 days. If set +≤ 0, session caching is disabled. If set to a positive value +less than 2 minutes, the minimum value of 2 minutes is used instead. </p> + +<h3><a name="client_tls_limits"> Client TLS limitations </a> +</h3> + +<p> The security properties of TLS communication channels are +application specific. While the TLS protocol can provide a confidential, +tamper-resistant, mutually authenticated channel between client +and server, not all of these security features are applicable to every +communication. </p> + +<p> For example, while mutual TLS authentication between browsers and web +servers is possible, it is not practical, or even useful, for web-servers +that serve the public to verify the identity of every potential user. In +practice, most HTTPS transactions are asymmetric: the browser verifies +the HTTPS server's identity, but the user remains anonymous. Much of +the security policy is up to the client. If the client chooses to not +verify the server's name, the server is not aware of this. There are many +interesting browser security topics, but we shall not dwell +on them here. Rather, our goal is to understand the security features +of TLS in conjunction with SMTP. </p> + +<p> An important SMTP-specific observation is that a public MX host is +even more at the mercy of the SMTP client than is an HTTPS server. Not only +can it not enforce due care in the client's use of TLS, but it cannot even +enforce the use of TLS, because TLS support in SMTP clients is still the +exception rather than the rule. One cannot, in practice, limit access to +one's MX hosts to just TLS-enabled clients. Such a policy would result +in a vast reduction in one's ability to communicate by email with the +world at large. </p> + +<p> One may be tempted to try enforcing TLS for mail from specific +sending organizations, but this, too, runs into obstacles. One such +obstacle is that we don't know who is (allegedly) sending mail until +we see the "MAIL FROM:" SMTP command, and at that point, if TLS +is not already in use, a potentially sensitive sender address (and +with SMTP PIPELINING one or more of the recipients) has (have) already been +leaked in the clear. Another obstacle is that mail from the sender to +the recipient may be forwarded, and the forwarding organization may not +have any security arrangements with the final destination. Bounces also +need to be protected. These can only be identified by the IP address and +HELO name of the connecting client, and it is difficult to keep track +of all the potential IP addresses or HELO names of the outbound email +servers of the sending organization. </p> + +<p> Consequently, TLS security for mail delivery to public MX hosts is +almost entirely the client's responsibility. The server is largely a +passive enabler of TLS security, the rest is up to the client. While the +server has a greater opportunity to mandate client security policy when +it is a dedicated MSA that only handles outbound mail from trusted clients, +below we focus on the client security policy. </p> + +<p> On the SMTP client, there are further complications. When +delivering mail to a given domain, in contrast to HTTPS, one rarely +uses the domain name directly as the target host of the SMTP session. +More typically, one uses MX lookups — these are usually +unauthenticated — to obtain the domain's SMTP server hostname(s). +When, as is current practice, the client verifies the insecurely +obtained MX hostname, it is subject to a DNS man-in-the-middle +attack. </p> + +<p> Adoption of DNSSEC and RFC6698 (DANE) may gradually (as domains +implement DNSSEC and publish TLSA records for their MX hosts) address +the DNS man-in-the-middle risk and provide scalable key management +for SMTP with TLS. Postfix ≥ 2.11 supports the new <a +href="#client_tls_dane">dane</a> and <a href="#client_tls_dane">dane-only</a> +security levels that take advantage of these standards. </p> + +<p> If clients instead attempted to verify the recipient domain name, +an SMTP server for multiple domains would need to +list all its email domain names in its certificate, and generate a +new certificate each time a new domain were added. At least some CAs set +fairly low limits (20 for one prominent CA) on the number of names that +server certificates can contain. This approach is not consistent with +current practice and does not scale. </p> + +<p> It is regrettably the case that TLS <i>secure-channels</i> +(fully authenticated and immune to man-in-the-middle attacks) impose +constraints on the sending and receiving sites that preclude ubiquitous +deployment. One needs to manually configure this type of security for +each destination domain, and in many cases implement non-default TLS +<a href="#client_tls_policy">policy table</a> entries for additional +domains hosted at a common secured destination. For these reasons +secure-channel configurations +will never be the norm. For the generic domain with which you +have made no specific security arrangements, this security level is not +a good fit. </p> + +<p> Given that strong authentication is not generally possible, and that +verifiable certificates cost time and money, many servers that implement +TLS use self-signed certificates or private CAs. This further limits +the applicability of verified TLS on the public Internet. </p> + +<p> Historical note: while the documentation of these issues and many of the +related features were new with Postfix 2.3, the issue was well +understood before Postfix 1.0, when Lutz Jänicke was designing +the first unofficial Postfix TLS patch. See his original post <a +href="http://www.imc.org/ietf-apps-tls/mail-archive/msg00304.html">http://www.imc.org/ietf-apps-tls/mail-archive/msg00304.html</a> +and the first response <a +href="http://www.imc.org/ietf-apps-tls/mail-archive/msg00305.html">http://www.imc.org/ietf-apps-tls/mail-archive/msg00305.html</a>. +The problem is not even unique to SMTP or even TLS, similar issues exist +for secure connections via aliases for HTTPS and Kerberos. SMTP merely +uses indirect naming (via MX records) more frequently. </p> + +<h3> <a name="client_tls_policy"> TLS policy table </a> +</h3> + +<p> A small fraction of servers offer STARTTLS but the negotiation +consistently fails. As long as encryption is not mandatory, the +Postfix SMTP client retries the delivery immediately with TLS +disabled, without any need to explicitly disable TLS for the problem +destinations. </p> + +<p> The policy table is specified via the smtp_tls_policy_maps +parameter. This lists optional lookup tables with the Postfix SMTP client +TLS security policy by next-hop destination. </p> + +<p> The TLS policy table is indexed by the full next-hop destination, +which is either the recipient domain, or the verbatim next-hop +specified in the transport table, $local_transport, $virtual_transport, +$relay_transport or $default_transport. This includes any enclosing +square brackets and any non-default destination server port suffix. The +<a href="#client_lmtp_tls">LMTP</a> socket type prefix (inet: or unix:) +is not included in the lookup key. </p> + +<p> Only the next-hop domain, or $myhostname with LMTP over UNIX-domain +sockets, is used as the nexthop name for certificate verification. The +port and any enclosing square brackets are used in the table lookup key, +but are not used for server name verification. </p> + +<p> When the lookup key is a domain name without enclosing square brackets +or any <i>:port</i> suffix (typically the recipient domain), and the full +domain is not found in the table, just as with the transport(5) table, +the parent domain starting with a leading "." is matched recursively. This +allows one to specify a security policy for a recipient domain and all +its sub-domains. </p> + +<p> The lookup result is a security level, followed by an optional +list of whitespace and/or comma separated name=value attributes +that override related main.cf settings. The TLS security <a +href="#client_tls_levels">levels</a> are described above. Below, we +describe the corresponding table syntax: </p> + +<dl> + +<dt><b>none</b></dt> <dd><a href="#client_tls_none">No TLS</a>. No +additional attributes are supported at this level. </dd> + +<dt><b>may</b></dt> <dd><a href="#client_tls_may">Opportunistic TLS</a>. +The optional "ciphers", "exclude" and "protocols" attributes +(available for opportunistic TLS with Postfix ≥ 2.6) override the +"smtp_tls_ciphers", "smtp_tls_exclude_ciphers" and "smtp_tls_protocols" +configuration parameters. At this level and higher, the optional +"servername" attribute (available with Postfix ≥ 3.4) overrides the +global "smtp_tls_servername" parameter, enabling per-destination +configuration of the SNI extension sent to the remote SMTP server. </dd> + +<dt><b>encrypt</b></dt> <dd><a href="#client_tls_encrypt"> Mandatory encryption</a>. +Mail is delivered only if the remote SMTP server offers STARTTLS +and the TLS handshake succeeds. At this level and higher, the optional +"protocols" attribute overrides the main.cf smtp_tls_mandatory_protocols +parameter, the optional "ciphers" attribute overrides the +main.cf smtp_tls_mandatory_ciphers parameter, and the optional +"exclude" attribute (Postfix ≥ 2.6) overrides the main.cf +smtp_tls_mandatory_exclude_ciphers parameter. </dd> + +<dt><b>dane</b></dt> <dd><a href="#client_tls_dane">Opportunistic DANE TLS</a>. +The TLS policy for the destination is obtained via TLSA records in +DNSSEC. If no TLSA records are found, the effective security level +used is <a href="#client_tls_may">may</a>. If TLSA records are +found, but none are usable, the effective security level is <a +href="#client_tls_encrypt">encrypt</a>. When usable TLSA records +are obtained for the remote SMTP server, SSLv2+3 are automatically +disabled (see smtp_tls_mandatory_protocols), and the server certificate +must match the TLSA records. RFC 7672 (DANE) TLS authentication +and DNSSEC support is available with Postfix 2.11 and later. </dd> + +<dt><b>dane-only</b></dt> <dd><a href="#client_tls_dane">Mandatory DANE TLS</a>. +The TLS policy for the destination is obtained via TLSA records in +DNSSEC. If no TLSA records are found, or none are usable, no +connection is made to the server. When usable TLSA records are +obtained for the remote SMTP server, SSLv2+3 are automatically disabled +(see smtp_tls_mandatory_protocols), and the server certificate must +match the TLSA records. RFC 7672 (DANE) TLS authentication and +DNSSEC support is available with Postfix 2.11 and later. </dd> + +<dt><b>fingerprint</b></dt> <dd><a href="#client_tls_fprint">Certificate +fingerprint verification.</a> Available with Postfix 2.5 and +later. At this security level, there are no trusted Certification +Authorities. The certificate trust chain, expiration date, ... are +not checked. Instead, the optional <b>match</b> attribute, or else +the main.cf <b>smtp_tls_fingerprint_cert_match</b> parameter, lists +the server certificate fingerprints or public key fingerprints +(Postfix 2.9 and later). The +digest algorithm used to calculate fingerprints is selected by the +<b>smtp_tls_fingerprint_digest</b> parameter. Multiple fingerprints can +be combined with a "|" delimiter in a single match attribute, or multiple +match attributes can be employed. The ":" character is not used as a +delimiter as it occurs between each pair of fingerprint (hexadecimal) +digits. </dd> + +<dt><b>verify</b></dt> <dd><a href="#client_tls_verify">Mandatory +server certificate verification</a>. Mail is delivered only if the +TLS handshake succeeds, if the remote SMTP server certificate can +be validated (not expired or revoked, and signed by a trusted +Certification Authority), and if the server certificate name matches +the optional "match" attribute (or the main.cf smtp_tls_verify_cert_match +parameter value when no optional "match" attribute is specified). +With Postfix ≥ 2.11 the "tafile" attribute optionally modifies +trust chain verification in the same manner as the +"smtp_tls_trust_anchor_file" parameter. The "tafile" attribute +may be specified multiple times to load multiple trust-anchor +files. </dd> + +<dt><b>secure</b></dt> <dd><a href="#client_tls_secure">Secure certificate +verification.</a> Mail is delivered only if the TLS handshake succeeds, +and DNS forgery resistant remote SMTP certificate verification succeeds +(not expired or revoked, and signed by a trusted Certification Authority), +and if the server certificate name matches the optional "match" attribute +(or the main.cf smtp_tls_secure_cert_match parameter value when no optional +"match" attribute is specified). With Postfix ≥ 2.11 the "tafile" +attribute optionally modifies trust chain verification in the same manner +as the "smtp_tls_trust_anchor_file" parameter. The "tafile" attribute +may be specified multiple times to load multiple trust-anchor +files. </dd> + +</dl> + +<p> Notes: </p> + +<ul> + +<li> <p> The "match" attribute is especially useful to verify TLS +certificates for domains that are hosted on a shared server. In +that case, specify "match" rules for the shared server's name. +While secure verification can also be achieved with manual routing +overrides in Postfix transport(5) tables, that approach can deliver +mail to the wrong host when domains are assigned to new gateway +hosts. The "match" attribute approach avoids the problems of manual +routing overrides; mail is deferred if verification of a new MX +host fails. </p> + +<li> <p> When a policy table entry specifies multiple match patterns, +multiple match strategies, or multiple protocols, these must be +separated by colons. </p> + +<li> <p> The "exclude" attribute (Postfix ≥ 2.6) is used to disable +ciphers that cause handshake failures with a specific mandatory TLS +destination, without disabling the ciphers for all mandatory destinations. +Alternatively, you can exclude ciphers that cause issues with multiple +remote servers in main.cf, and selectively enable them on a per-destination +basis in the policy table by setting a shorter or empty exclusion list. The +per-destination "exclude" list preempts both the opportunistic and +mandatory security level exclusions, so that all excluded ciphers +can be enabled for known-good destinations. For non-mandatory TLS +destinations that exhibit cipher-specific problems, Postfix will fall +back to plain-text delivery. If plain-text is not acceptable make TLS +mandatory and exclude the problem ciphers. </p> + +</ul> + +<p> +Example: +</p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_policy_maps = hash:/etc/postfix/tls_policy + # Postfix 2.5 and later + smtp_tls_fingerprint_digest = sha256 +/etc/postfix/tls_policy: + example.edu none + example.mil may + example.gov encrypt ciphers=high + example.com verify match=hostname:dot-nexthop ciphers=high + example.net secure + .example.net secure match=.example.net:example.net + [mail.example.org]:587 secure match=nexthop + # Postfix 2.5 and later + [thumb.example.org] fingerprint + match=b6:b4:72:34:e2:59:cd:fb:...:0d:4d:cc:2c:7d:84:de:e6:2f + match=51:e9:af:2e:1e:40:1f:de:...:35:2d:09:16:31:5a:eb:82:76 + # Postfix ≥ 3.6 "protocols" syntax + example.info may protocols=>=TLSv1 ciphers=medium exclude=3DES + # Legacy protocols syntax + example.info may protocols=!SSLv2:!SSLv3 ciphers=medium exclude=3DES +</pre> +</blockquote> + +<p> <b>Note:</b> The "hostname" strategy if listed in a non-default setting +of smtp_tls_secure_cert_match or in the "match" attribute in the policy +table can render the "secure" level vulnerable to DNS forgery. Do not use +the "hostname" strategy for <a href="#client_tls_secure">secure-channel</a> +configurations in environments where DNS security is not assured. </p> + +<h3> <a name="client_tls_discover"> Discovering servers that support +TLS </a> </h3> + +<p> As we decide on a "per site" basis whether or not to use TLS, +it would be good to have a list of sites that offered "STARTTLS". +We can collect it ourselves with this option. </p> + +<p> If the smtp_tls_note_starttls_offer feature is enabled and a +server offers STARTTLS while TLS is not already enabled for that +server, the Postfix SMTP client logs a line as follows: </p> + +<blockquote> +<pre> +postfix/smtp[pid]: Host offered STARTTLS: [hostname.example.com] +</pre> +</blockquote> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_note_starttls_offer = yes +</pre> +</blockquote> + +<h3><a name="client_vrfy_server">Server certificate verification depth</a> </h3> + +<p> The server certificate verification depth is specified with the +main.cf smtp_tls_scert_verifydepth parameter. The default verification +depth is 9 (the OpenSSL default), for compatibility with Postfix +versions before 2.5 where smtp_tls_scert_verifydepth was ignored. +When you configure trust +in a root CA, it is not necessary to explicitly trust intermediary CAs +signed by the root CA, unless $smtp_tls_scert_verifydepth is less than the +number of CAs in the certificate chain for the servers of interest. With +a verify depth of 1 you can only verify certificates directly signed +by a trusted CA, and all trusted intermediary CAs need to be configured +explicitly. With a verify depth of 2 you can verify servers signed by a +root CA or a direct intermediary CA (so long as the server is correctly +configured to supply its intermediate CA certificate). </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_scert_verifydepth = 2 +</pre> +</blockquote> + +<h3> <a name="client_cipher">Client-side cipher controls </a> </h3> + +<p> The Postfix SMTP client supports 5 distinct cipher grades +as specified by the smtp_tls_mandatory_ciphers configuration +parameter. This setting controls the minimum acceptable SMTP client +TLS cipher grade for use with mandatory TLS encryption. The default +value "medium" is suitable for most destinations with which you may +want to enforce TLS, and is beyond the reach of today's cryptanalytic +methods. See smtp_tls_policy_maps for information on how to configure +ciphers on a per-destination basis. </p> + +<p> By default anonymous ciphers are allowed, and automatically +disabled when remote SMTP server certificates are verified. If you +want to +disable anonymous ciphers even at the "encrypt" security level, set +"smtp_tls_mandatory_exclude_ciphers = aNULL"; and to +disable anonymous ciphers even with opportunistic TLS, set +"smtp_tls_exclude_ciphers = aNULL". There is generally +no need to take these measures. Anonymous ciphers save bandwidth +and TLS session cache space, if certificates are ignored, there is +little point in requesting them. </p> + +<p> The "smtp_tls_ciphers" configuration parameter (Postfix ≥ 2.6) +provides control over the minimum cipher grade for opportunistic TLS. +The default minimum cipher grade for opportunistic TLS is "medium" +for Postfix releases after the middle of 2015, and "export" for +older releases. With Postfix < 2.6, the minimum opportunistic +TLS cipher grade is always "export". </p> + +<p> With mandatory and opportunistic TLS encryption, the Postfix +SMTP client will by default disable SSLv2 and SSLv3. The mandatory +TLS protocol list is specified via the +smtp_tls_mandatory_protocols configuration parameter. The corresponding +smtp_tls_protocols parameter (Postfix ≥ 2.6) controls +the TLS protocols used with opportunistic TLS. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_mandatory_ciphers = medium + smtp_tls_mandatory_exclude_ciphers = RC4, MD5 + smtp_tls_exclude_ciphers = aNULL + smtp_tls_ciphers = medium + # Preferred form with Postfix ≥ 3.6: + smtp_tls_mandatory_protocols = >=TLSv1.2 + smtp_tls_protocols = >=TLSv1 + # Legacy form for Postfix < 3.6: + smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 + smtp_tls_protocols = !SSLv2,!SSLv3 +</pre> +</blockquote> + +<h3> <a name="client_smtps">Client-side SMTPS support </a> </h3> + +<p> These sections show how to send mail to a server that does not +support STARTTLS, but that provides the SMTPS service +on TCP port 465. Depending on the Postfix version, some additional +tooling may be required. </p> + +<h4> Postfix ≥ 3.0 </h4> + +<p> The Postfix SMTP client has SMTPS support built-in as of version +3.0. Use one of the following examples, to send all remote mail, +or to send only some remote mail, to an SMTPS server. </p> + +<h5> Postfix ≥ 3.0: Sending all remote mail to an SMTPS server </h5> + +<p> The first example will send all remote mail over SMTPS through +a provider's server called "mail.example.com": </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # Client-side SMTPS requires "encrypt" or stronger. + smtp_tls_security_level = encrypt + smtp_tls_wrappermode = yes + # The [] suppress MX lookups. + relayhost = [mail.example.com]:465 +</pre> +</blockquote> + +<p> Use "postfix reload" to make the change effective. </p> + +<p> See SOHO_README for additional information about SASL authentication. +</p> + +<h5> Postfix ≥ 3.0: Sending only mail for a specific destination +via SMTPS </h5> + +<p> The second example will send only mail for "example.com" via +SMTPS. This time, Postfix uses a transport map to deliver only +mail for "example.com" via SMTPS: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + transport_maps = hash:/etc/postfix/transport + +/etc/postfix/transport: + example.com relay-smtps:example.com:465 + +/etc/postfix/master.cf: + relay-smtps unix - - n - - smtp + # Client-side SMTPS requires "encrypt" or stronger. + -o smtp_tls_security_level=encrypt + -o smtp_tls_wrappermode=yes +</pre> +</blockquote> + +<p> Use "postmap hash:/etc/postfix/transport" and "postfix reload" +to make the change effective. </p> + +<p> See SOHO_README for additional information about SASL +authentication. </p> + +<h4> Postfix < 3.0 </h4> + +<p> Although older Postfix SMTP client versions do not support TLS +wrapper mode, it is relatively easy to forward a connection through +the stunnel program if Postfix needs to deliver mail to some legacy +system that doesn't support STARTTLS. </p> + +<h5> Postfix < 3.0: Sending all remote mail to an SMTPS server </h5> + +<p> The first example uses SMTPS to send all remote mail to a +provider's mail server called "mail.example.com". </p> + +<p> A minimal stunnel.conf file is sufficient to set up a tunnel +from local port 11125 to the remote destination "mail.example.com" +and port "smtps". Postfix will later use this tunnel to connect to +the remote server. </p> + +<blockquote> +<pre> +/path/to/stunnel.conf: + [smtp-tls-wrapper] + accept = 11125 + client = yes + connect = mail.example.com:smtps +</pre> +</blockquote> + +<p> To test this tunnel, use: </p> + +<blockquote> +<pre> +$ telnet localhost 11125 +</pre> +</blockquote> + +<p> This should produce the greeting from the remote SMTP server +at mail.example.com. </p> + +<p> On the Postfix side, the relayhost feature sends all remote +mail through the local stunnel listener on port 11125: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + relayhost = [127.0.0.1]:11125 +</pre> +</blockquote> + +<p> Use "postfix reload" to make the change effective. </p> + +<p> See SOHO_README for additional information about SASL +authentication. </p> + +<h4> Postfix < 3.0: Sending only mail for a specific destination via SMTPS </h4> + +<p> The second example will use SMTPS to send only mail for +"example.com" via SMTPS. It uses the same stunnel configuration +file as the first example, so it won't be repeated here. </p> + +<p> This time, the Postfix side uses a transport map to direct only +mail for "example.com" through the tunnel: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + transport_maps = hash:/etc/postfix/transport + +/etc/postfix/transport: + example.com relay:[127.0.0.1]:11125 +</pre> +</blockquote> + +<p> Use "postmap hash:/etc/postfix/transport" and "postfix reload" +to make the change effective. </p> + +<p> See SOHO_README for additional information about SASL authentication. +</p> + +<h3> <a name="client_misc"> Miscellaneous client controls </a> </h3> + +<p> The smtp_starttls_timeout parameter limits the time of Postfix +SMTP client write and read operations during TLS startup and shutdown +handshake procedures. In case of problems the Postfix SMTP client +tries the next network address on the mail exchanger list, and +defers delivery if no alternative server is available. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_starttls_timeout = 300s +</pre> +</blockquote> + +<p> With Postfix 2.8 and later, the tls_disable_workarounds parameter +specifies a list or bit-mask of OpenSSL bug work-arounds to disable. This +may be necessary if one of the work-arounds enabled by default in +OpenSSL proves to pose a security risk, or introduces an unexpected +interoperability issue. Some bug work-arounds known to be problematic +are disabled in the default value of the parameter when linked with +an OpenSSL library that could be vulnerable. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + tls_disable_workarounds = 0xFFFFFFFF + tls_disable_workarounds = CVE-2010-4180, LEGACY_SERVER_CONNECT +</pre> +</blockquote> + +<p> Note: Disabling LEGACY_SERVER_CONNECT is not wise at this +time, lots of servers are still unpatched and Postfix is <a +href="http://www.postfix.org/wip.html#tls-renegotiation">not +significantly vulnerable</a> to the renegotiation issue in the TLS +protocol. </p> + +<p> With Postfix ≥ 2.11, the tls_ssl_options parameter specifies +a list or bit-mask of OpenSSL options to enable. Specify one or +more of the named options below, or a hexadecimal bitmask of options +found in the ssl.h file corresponding to the run-time OpenSSL +library. While it may be reasonable to turn off all bug workarounds +(see above), it is not a good idea to attempt to turn on all features. +</p> + +<p> A future version of OpenSSL may by default no longer allow +connections to servers that don't support secure renegotiation. +Since the exposure for SMTP is minimal, and some SMTP servers may +remain unpatched, you can add LEGACY_SERVER_CONNECT to the +options to restore the more permissive default of current OpenSSL +releases. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + tls_ssl_options = NO_TICKET, NO_COMPRESSION, LEGACY_SERVER_CONNECT +</pre> +</blockquote> + +<p> You should only enable features via the hexadecimal mask when +the need to control the feature is critical (to deal with a new +vulnerability or a serious interoperability problem). Postfix DOES +NOT promise backwards compatible behavior with respect to the mask +bits. A feature enabled via the mask in one release may be enabled +by other means in a later release, and the mask bit will then be +ignored. Therefore, use of the hexadecimal mask is only a temporary +measure until a new Postfix or OpenSSL release provides a better +solution. </p> + +<h2><a name="tlsmgr_controls"> TLS manager specific settings </a> </h2> + +<p> The security of cryptographic software such as TLS depends +critically on the ability to generate unpredictable numbers for +keys and other information. To this end, the tlsmgr(8) process +maintains a Pseudo Random Number Generator (PRNG) pool. This is +queried by the smtp(8) and smtpd(8) processes when they initialize. +By default, these daemons request 32 bytes, the equivalent to 256 +bits. This is more than sufficient to generate a 128bit (or 168bit) +session key. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + tls_daemon_random_bytes = 32 +</pre> +</blockquote> + +<p> In order to feed its in-memory PRNG pool, the tlsmgr(8) reads +entropy from an external source, both at startup and during run-time. +Specify a good entropy source, like EGD or /dev/urandom; be sure +to only use non-blocking sources (on OpenBSD, use /dev/arandom +when tlsmgr(8) complains about /dev/urandom timeout errors). +If the entropy source is not a +regular file, you must prepend the source type to the source name: +"dev:" for a device special file, or "egd:" for a source with EGD +compatible socket interface. </p> + +<p> Examples (specify only one in main.cf): </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + tls_random_source = dev:/dev/urandom + tls_random_source = egd:/var/run/egd-pool +</pre> +</blockquote> + +<p> By default, tlsmgr(8) reads 32 bytes from the external entropy +source at each seeding event. This amount (256bits) is more than +sufficient for generating a 128bit symmetric key. With EGD and +device entropy sources, the tlsmgr(8) limits the amount of data +read at each step to 255 bytes. If you specify a regular file as +entropy source, a larger amount of data can be read. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + tls_random_bytes = 32 +</pre> +</blockquote> + +<p> In order to update its in-memory PRNG pool, the tlsmgr(8) +queries the external entropy source again after a pseudo-random +amount of time. The time is calculated using the PRNG, and is +between 0 and the maximal time specified with tls_random_reseed_period. +The default maximal time interval is 1 hour. </p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + tls_random_reseed_period = 3600s +</pre> +</blockquote> + +<p> The tlsmgr(8) process saves the PRNG state to a persistent +exchange file at regular times and when the process terminates, so +that it can recover the PRNG state the next time it starts up. +This file is created when it does not exist. </p> + +<p> Examples: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + tls_random_exchange_name = /var/lib/postfix/prng_exch + tls_random_prng_update_period = 3600s +</pre> +</blockquote> + +<p> As of version 2.5, Postfix no longer uses root privileges when +opening this file. The file should now be stored under the Postfix-owned +data_directory. As a migration aid, an attempt to open the file +under a non-Postfix directory is redirected to the Postfix-owned +data_directory, and a warning is logged. If you wish to continue +using a pre-existing PRNG state file, move it to the data_directory +and change the ownership to the account specified with the mail_owner +parameter. </p> + +<p> With earlier Postfix versions the default file location +is under the Postfix configuration directory, which is not the +proper place for information that is modified by Postfix. </p> + +<h2><a name="quick-start">Getting started, quick and dirty</a></h2> + +<p> The following steps will get you started quickly. Because you +sign your own Postfix public key certificate, you get TLS encryption +but no TLS authentication. This is sufficient for testing, and +for exchanging email with sites that you have no trust relationship +with. For real authentication you need also enable DNSSEC record +signing for your domain and publish TLSA records and/or your Postfix +public key certificate needs to be signed by a recognized Certification +Authority. To authenticate the certificates of a remote host you +need a DNSSEC-validating local resolver and to enable <a +href="#client_tls_dane">DANE</a> authentication and/or configure +the Postfix SMTP client with a list of public key certificates of +Certification Authorities, but make sure to read about the <a +href="#client_tls_limits">limitations</a> of the latter approach. +</p> + +<p> In the examples below, user input is shown in <b><tt>bold</tt></b> +font, and a "<tt>#</tt>" prompt indicates a super-user shell. </p> + +<ul> + +<li> <p> <a href="#built-in">Quick-start TLS with Postfix ≥ 3.1</a>.</p> + +<li> <p> <a href="#self-signed">Self-signed server certificate</a>.</p> + +<li> <p> <a href="#private-ca">Private Certification Authority</a>. </p> + +</ul> + +<h3><a name="built-in">Quick-start TLS with Postfix ≥ 3.1</a></h3> + +<p> Postfix 3.1 provides built-in support for enabling TLS in the +SMTP client and server and for ongoing certificate and DANE TLSA +record management. + +<ul> +<li> <p> <a href="#quick-client">Quick-start TLS in the Postfix ≥ 3.1 SMTP client</a>. </p> +<li> <p> <a href="#quick-server">Quick-start TLS in the Postfix ≥ 3.1 SMTP server</a>. </p> +</ul> + +<h4> <a name="quick-client">Quick-start TLS in the Postfix ≥ 3.1 SMTP client</a>. </h4> + +<p> If you are using Postfix 3.1 or later, and your SMTP client TLS +settings are in their default state, you can enable <a +href="#client_tls_may">opportunistic</a> TLS in the SMTP client as +follows: </p> + +<blockquote> +<pre> +# postfix tls enable-client +# postfix reload +</pre> +</blockquote> + +<p> If some of the Postfix SMTP client TLS settings are not in their +default state, this will not make any changes, but will instead +suggest the minimal required settings for SMTP client TLS. The +"postfix reload" command is optional, it is only needed if you want +the settings to take effect right away. Note, this does not enable +trust in any public certification authorities, and does not configure +client TLS certificates as these are largely pointless with <a +href="#client_tls_may">opportunistic</a> TLS. </p> + +<p> There is not yet a turn-key command for enabling <a +href="#client_tls_dane">DANE</a> authentication. This is because +DANE requires changes to your <b>resolv.conf</b> file and a +corresponding DNSSEC-validating resolver local to the Postfix host, +these changes are difficult to automate in a portable way. </p> + +<p> If you're willing to revert your settings to the defaults and +switch to a "stock" opportunistic TLS configuration, then you can: +erase all the SMTP client TLS settings and then enable client TLS: </p> + +<blockquote> +<pre> +# postconf -X `postconf -nH | egrep '^smtp(_|_enforce_|_use_)tls'` +# postfix tls enable-client +# postfix reload +</pre> +</blockquote> + +<h4><a name="quick-server">Quick-start TLS in the Postfix ≥ 3.1 SMTP server</a>.</h4> + +<p> If you are using Postfix 3.1 or later, and your SMTP server TLS +settings are in their default state, you can enable +opportunistic TLS in the SMTP server as follows: </p> + +<blockquote> +<pre> +# postfix tls enable-server +# postfix reload +</pre> +</blockquote> + +<p> If some of the Postfix SMTP client TLS settings are not in their +default state, this will not make any changes, but will instead +suggest the minimal required settings for SMTP client TLS. The +"postfix reload" command is optional, it is only needed if you want +the settings to take effect right away. This will generate a +self-signed private key and certificate and enable TLS in the Postfix +SMTP server. </p> + +<p> If you're willing to revert your settings to the defaults and +switch to a "stock" server TLS configuration, then you can: erase +all the SMTP server TLS settings and then enable server TLS: </p> + +<blockquote> +<pre> +# postconf -X `postconf -nH | egrep '^smtpd(_|_enforce_|_use_)tls'` +# postfix tls enable-server +# postfix reload +</pre> +</blockquote> + +<p> Postfix ≥ 3.1 provides additional built-in support for ongoing +management of TLS in the SMTP server, via additional "postfix tls" +sub-commands. These make it easy to generate certificate signing +requests, create and deploy new keys and certificates, and generate +DANE TLSA records. See the postfix-tls(1) documentation for details. +</p> + +<h3><a name="self-signed">Self-signed server certificate</a></h3> + +<p> The following commands (credits: Viktor Dukhovni) generate and +install a 2048-bit RSA private key and 10-year self-signed certificate +for the local Postfix system. This requires super-user privileges. +(By using date-specific filenames for the certificate and key files, +and updating main.cf with new filenames, a potential race condition +in which the key and certificate might not match is avoided). +</p> + +<blockquote> +<pre> +# dir="$(postconf -h config_directory)" +# fqdn=$(postconf -h myhostname) +# case $fqdn in /*) fqdn=$(cat "$fqdn");; esac +# ymd=$(date +%Y-%m-%d) +# key="${dir}/key-${ymd}.pem"; rm -f "${key}" +# cert="${dir}/cert-${ymd}.pem"; rm -f "${cert}" +# (umask 077; openssl genrsa -out "${key}" 2048) && + openssl req -new -key "${key}" \ + -x509 -subj "/CN=${fqdn}" -days 3650 -out "${cert}" && + postconf -e \ + "smtpd_tls_cert_file = ${cert}" \ + "smtpd_tls_key_file = ${key}" \ + 'smtpd_tls_security_level = may' \ + 'smtpd_tls_received_header = yes' \ + 'smtpd_tls_loglevel = 1' \ + 'smtp_tls_security_level = may' \ + 'smtp_tls_loglevel = 1' \ + 'smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache' \ + 'tls_random_source = dev:/dev/urandom' +</pre> +</blockquote> + +<p> Note: the last command requires both single (') and double (") +quotes. </p> + +<p> The postconf(1) command above enables opportunistic TLS for +receiving and sending mail. It also enables logging of TLS connections +and recording of TLS use in the "Received" header. TLS session +caching is also enabled in the Postfix SMTP client. With Postfix +≥ 2.10, the SMTP server does not need an explicit session cache +since session reuse is better handled via RFC 5077 TLS session +tickets. </p> + +<h3><a name="private-ca">Private Certification Authority</a></h3> + +<ul> + +<li> <p> Become your own Certification Authority, so that you can +sign your own certificates, and so that your own systems can +authenticate certificates from your own CA. This example uses the +CA.pl script that ships with OpenSSL. On some systems, OpenSSL +installs this as <tt>/usr/local/openssl/misc/CA.pl</tt>. Some systems +install this as +part of a package named <tt>openssl-perl</tt> or something similar. +The script creates a private key in <tt>./demoCA/private/cakey.pem</tt> +and a public key in <tt>./demoCA/cacert.pem</tt>.</p> + +<blockquote> +<pre> +% <b>/usr/local/ssl/misc/CA.pl -newca</b> +CA certificate filename (or enter to create) + +Making CA certificate ... +Using configuration from /etc/ssl/openssl.cnf +Generating a 1024 bit RSA private key +....................++++++ +.....++++++ +writing new private key to './demoCA/private/cakey.pem' +Enter PEM pass phrase:<b>whatever</b> +</pre> +</blockquote> + +<li> <p> Create an unpassworded private key for host foo.porcupine.org and create +an unsigned public key certificate. </p> + +<blockquote> +<pre> +% <b>(umask 077; openssl req -new -newkey rsa:2048 -nodes -keyout foo-key.pem -out foo-req.pem)</b> +Using configuration from /etc/ssl/openssl.cnf +Generating a 2048 bit RSA private key +........................................++++++ +....++++++ +writing new private key to 'foo-key.pem' +----- +You are about to be asked to enter information that will be incorporated +into your certificate request. +What you are about to enter is what is called a Distinguished Name or a DN. +There are quite a few fields but you can leave some blank +For some fields there will be a default value, +If you enter '.', the field will be left blank. +----- +Country Name (2 letter code) [AU]:<b>US</b> +State or Province Name (full name) [Some-State]:<b>New York</b> +Locality Name (eg, city) []:<b>Westchester</b> +Organization Name (eg, company) [Internet Widgits Pty Ltd]:<b>Porcupine</b> +Organizational Unit Name (eg, section) []: +Common Name (eg, YOUR name) []:<b>foo.porcupine.org</b> +Email Address []:<b>wietse@porcupine.org</b> + +Please enter the following 'extra' attributes +to be sent with your certificate request +A challenge password []:<b>whatever</b> +An optional company name []: +</pre> +</blockquote> + +<li> <p> Sign the public key certificate for host foo.porcupine.org with the +Certification Authority private key that we created a few +steps ago. </p> + +<blockquote> +<pre> +% <b>openssl ca -out foo-cert.pem -days 365 -infiles foo-req.pem</b> +Using configuration from /etc/ssl/openssl.cnf +Enter PEM pass phrase:<b>whatever</b> +Check that the request matches the signature +Signature ok +The Subjects Distinguished Name is as follows +countryName :PRINTABLE:'US' +stateOrProvinceName :PRINTABLE:'New York' +localityName :PRINTABLE:'Westchester' +organizationName :PRINTABLE:'Porcupine' +commonName :PRINTABLE:'foo.porcupine.org' +emailAddress :IA5STRING:'wietse@porcupine.org' +Certificate is to be certified until Nov 21 19:40:56 2005 GMT (365 days) +Sign the certificate? [y/n]:<b>y</b> + + +1 out of 1 certificate requests certified, commit? [y/n]<b>y</b> +Write out database with 1 new entries +Data Base Updated +</pre> +</blockquote> + +<li> <p> Install the host private key, the host public key certificate, +and the Certification Authority certificate files. This requires +super-user privileges. </p> + +<p> The following commands assume that the key and certificate will +be installed for the local Postfix MTA. You will need to adjust the +commands if the Postfix MTA is on a different host. </p> + +<blockquote> +<pre> +# <b>cp demoCA/cacert.pem foo-key.pem foo-cert.pem /etc/postfix</b> +# <b>chmod 644 /etc/postfix/foo-cert.pem /etc/postfix/cacert.pem</b> +# <b>chmod 400 /etc/postfix/foo-key.pem</b> +</pre> +</blockquote> + +<li> <p> Configure Postfix, by adding the following to +<tt>/etc/postfix/main.cf </tt>. It is generally best to not configure +client certificates, unless there are servers which authenticate your mail +submission via client certificates. Often servers that perform TLS client +authentication will issue the required certificates signed by their own +CA. If you configure the client certificate and key incorrectly, you +will be unable to send mail to sites that request a client certificate, +but don't require them from all clients. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_CAfile = /etc/postfix/cacert.pem + smtp_tls_session_cache_database = + btree:/var/lib/postfix/smtp_tls_session_cache + smtp_tls_security_level = may + smtp_tls_loglevel = 1 + smtpd_tls_CAfile = /etc/postfix/cacert.pem + smtpd_tls_cert_file = /etc/postfix/foo-cert.pem + smtpd_tls_key_file = /etc/postfix/foo-key.pem + smtpd_tls_received_header = yes + smtpd_tls_session_cache_database = + btree:/var/lib/postfix/smtpd_tls_session_cache + tls_random_source = dev:/dev/urandom + smtpd_tls_security_level = may + smtpd_tls_loglevel = 1 +</pre> +</blockquote> + +</ul> + + +<h2><a name="build_tls">Building Postfix with TLS support</a></h2> + +<p> These instructions assume that you build Postfix from source +code as described in the INSTALL document. Some modification may +be required if you build Postfix from a vendor-specific source +package. </p> + +<p> To build Postfix with TLS support, first we need to generate +the <tt>make(1)</tt> files with the necessary definitions. This is +done by invoking the command "<tt>make makefiles</tt>" in the Postfix +top-level directory and with arguments as shown next. </p> + +<p> <b> NOTE: Do not use Gnu TLS. It will spontaneously terminate +a Postfix daemon process with exit status code 2, instead of allowing +Postfix to 1) report the error to the maillog file, and to 2) provide +plaintext service where this is appropriate. </b> </p> + +<ul> + +<li> <p> If the OpenSSL include files (such as <tt>ssl.h</tt>) are +in directory <tt>/usr/include/openssl</tt>, and the OpenSSL libraries +(such as <tt>libssl.so</tt> and <tt>libcrypto.so</tt>) are in +directory <tt>/usr/lib</tt>: </p> + +<blockquote> +<pre> +% <b>make tidy</b> # if you have left-over files from a previous build +% <b>make makefiles CCARGS="-DUSE_TLS" AUXLIBS="-lssl -lcrypto"</b> +</pre> +</blockquote> + +<li> <p> If the OpenSSL include files (such as <tt>ssl.h</tt>) are +in directory <tt>/usr/local/include/openssl</tt>, and the OpenSSL +libraries (such as <tt>libssl.so</tt> and <tt>libcrypto.so</tt>) +are in directory <tt>/usr/local/lib</tt>: </p> + +<blockquote> +<pre> +% <b>make tidy</b> # if you have left-over files from a previous build +% <b>make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \ + AUXLIBS="-L/usr/local/lib -lssl -lcrypto" </b> +</pre> +</blockquote> + +<p> If your OpenSSL shared library is in a directory that the RUN-TIME +linker does not know about, add a "-Wl,-R,/path/to/directory" option after +"-lcrypto". </p> + +<p> On Solaris, specify the <tt>-R</tt> option as shown below: + +<blockquote> +<pre> +% <b>make tidy</b> # if you have left-over files from a previous build +% <b>make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \ + AUXLIBS="-R/usr/local/lib -L/usr/local/lib -lssl -lcrypto" </b> +</pre> +</blockquote> + +</ul> + +<p> If you need to apply other customizations (such as Berkeley DB +databases, MySQL, PostgreSQL, LDAP or SASL), see the respective +Postfix README documents, and combine their "<tt>make makefiles</tt>" +instructions with the instructions above: </p> + +<blockquote> +<pre> +% <b>make tidy</b> # if you have left-over files from a previous build +% <b>make makefiles CCARGS="-DUSE_TLS \ + <i>(other -D or -I options)</i>" \ + AUXLIBS="-lssl -lcrypto \ + <i>(other -l options for libraries in /usr/lib)</i> \ + <i>(-L/path/name + -l options for other libraries)</i>"</b> +</pre> +</blockquote> + +<p> To complete the build process, see the Postfix INSTALL +instructions. Postfix has TLS support turned off by default, so +you can start using Postfix as soon as it is installed. </p> + +<h2> <a name="problems"> Reporting problems </a> </h2> + +<p> Problems are preferably reported via <postfix-users@postfix.org>. +See http://www.postfix.org/lists.html for subscription information. +When reporting a problem, please be thorough in the report. Patches, +when possible, are greatly appreciated too. </p> + +<h2><a name="credits">Credits </a> </h2> + +<ul> + +<li> TLS support for Postfix was originally developed by Lutz +Jänicke at Cottbus Technical University. + +<li> Wietse Venema adopted the code, did some restructuring, and +compiled this part of the documentation from Lutz's documents. + +<li> Victor Duchovni was instrumental with the re-implementation +of the smtp_tls_per_site code in terms of enforcement levels, which +simplified the implementation greatly. + +<li> Victor Duchovni implemented the fingerprint security level, +added more sanity checks, and separated TLS connection management +from security policy enforcement. The latter change simplified the +code that verifies certificate signatures, certificate names, and +certificate fingerprints. + +</ul> + +</body> + +</html> diff --git a/proto/TUNING_README.html b/proto/TUNING_README.html new file mode 100644 index 0000000..61b37bd --- /dev/null +++ b/proto/TUNING_README.html @@ -0,0 +1,704 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Performance Tuning</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" alt=""> +Postfix Performance Tuning</h1> + +<hr> + +<h2>Purpose of Postfix performance tuning </h2> + +<p> The hints and tips in this document help you improve the +performance of Postfix systems that already work. If your Postfix +system is unable to receive or deliver mail, then you need to solve +those problems first, using the DEBUG_README document as guidance. + +<p> For tuning external content filter performance, first read the +respective information in the FILTER_README and SMTPD_PROXY_README +documents. Then make sure to avoid latency in the content filter +code. As much as possible avoid performing queries against external +data sources with a high or highly variable delay. Your content +filter will run with a small concurrency to avoid CPU/memory +starvation, and if any latency creeps in, content filter throughput +will suffer. High volume environments should avoid RBL lookups, +complex database queries and so on. </p> + +<p>Topics on mail receiving performance: </p> + +<ul> + +<li> <a href="#server_tips">General mail receiving performance tips</a> + +<li> <a href="#speedup">Doing more work with your SMTP server processes</a> + +<li> <a href="#slowdown">Slowing down SMTP clients that make many errors</a> + +<li> <a href="#conn_limit">Measures against clients that make too many connections</a> + +</ul> + +<p>Topics on mail delivery performance: </p> + +<ul> + +<li> <a href="#mailing_tips">General mail delivery performance tips</a> + +<li> <a href="#hammer">Tuning the frequency of deferred mail delivery attempts</a> + +<li> <a href="#rope">Tuning the number of simultaneous deliveries</a> + +<li> <a href="#rcpts">Tuning the number of recipients per delivery</a> + +</ul> + +<p>Other Postfix performance tuning topics: </p> + +<ul> + +<li> <a href="#proc_limit">Tuning the number of Postfix processes</a> + +<li> <a href="#proc_sys">Tuning the number of processes on the system</a> + +<li> <a href="#file_limit">Tuning the number of open files or +sockets</a> + +</ul> + +<p> The following tools can be used to measure mail system performance +under artificial loads. They are normally not installed with Postfix. +</p> + +<ul> + +<li> <a href="smtp-source.1.html">smtp-source, SMTP/LMTP message +generator</a> + +<li> <a href="smtp-sink.1.html">smtp-sink, SMTP/LMTP message dump +</a> + +<li> <a href="qmqp-source.1.html">qmqp-source, QMQP message generator +</a> + +<li> <a href="qmqp-sink.1.html">qmqp-sink, QMQP message dump </a> + +</ul> + +<h2><a name="server_tips">General mail receiving performance +tips</a></h2> + +<ul> + +<li> <p> Read and understand the maildrop queue, incoming queue, +and active queue discussions in the QSHAPE_README document. </p> + +<li> <p> Run a local name server to reduce slow-down due to DNS +lookups. If you run multiple Postfix systems, point each local name +server to a shared forwarding server to reduce the number of lookups +across the upstream network link. </p> + +<li> <p> Eliminate unnecessary LDAP lookups, by specifying a domain +filter. This eliminates lookups for addresses in remote domains, +and eliminates lookups of partial addresses. See ldap_table(5) for +details. </p> + +</ul> + +<p> When Postfix responds slowly to SMTP clients: </p> + +<ul> + +<li> <p> <a href="DEBUG_README.html#logging">Look for obvious signs +of trouble</a> as described in the DEBUG_README document, and +eliminate those problems first. </p> + +<li> <p> Turn off your header_checks and body_checks patterns and +see if the problem goes away. </p> + +<li> <p> <a href="DEBUG_README.html#no_chroot">Turn off chroot +operation</a> as described in the DEBUG_README document and see +if the problem goes away. </p> + +<li> <p> If Postfix logs the SMTP client as "unknown" then you have +a name service problem: the name server is bad, or the resolv.conf +file contains bad information, or some packet filter is blocking +the DNS requests or replies. </p> + +<li> <p> If the number of smtpd(8) processes has reached the process +limit as specified in master.cf, new SMTP clients must wait until +a process becomes available. See the STRESS_README and POSTSCREEN_README +documents for measures that help to prevent SMTP server overload. </p> + +</ul> + +<h2><a name="speedup">Doing more work with your SMTP server +processes</a></h2> + +<p> With Postfix versions 2.0 and earlier, the smtpd(8) server +pauses before reporting an error to an SMTP client. The idea is +called tar pitting. However, these delays also slow down Postfix. +When the smtpd(8) server replies slowly, sessions take more time, +so that more smtpd(8) server processes are needed to handle the +load. When your Postfix smtpd(8) server process limit is reached, +new clients must wait until a server process becomes available. +This means that all clients experience poor performance. </p> + +<p> You can speed up the handling of smtpd(8) server error replies +by turning off the delay: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # Not needed with Postfix 2.1 + smtpd_error_sleep_time = 0 +</pre> +</blockquote> + +<p> With the above setting, Postfix 2.0 and earlier can serve more +SMTP clients with the same number SMTP server processes. The next +section describes how Postfix deals with clients that make a large +number of errors. </p> + +<h2><a name="slowdown"> Slowing down SMTP clients that make many errors</a></h2> + +<p> The Postfix smtpd(8) server maintains a per-session error count. +The error count is reset when a message is transferred successfully, +and is incremented when a client request is unrecognized or +unimplemented, when a client request violates <a +href="SMTPD_ACCESS_README.html">access restrictions</a>, or when +some other error happens. </p> + +<p> As the per-session error count increases, the smtpd(8) server +changes behavior and begins to insert delays into the responses. +The idea is to slow down a run-away client in order to limit resource +usage. The behavior is Postfix version dependent. </p> + +<p> IMPORTANT: These delays slow down Postfix, too. When too much +delay is configured, the number of simultaneous SMTP sessions will +increase until it reaches the smtpd(8) server process limit, and new +SMTP clients must wait until an smtpd(8) server process becomes available. +</p> + +<p> Postfix version 2.1 and later:</p> + +<ul> + +<li> <p> When the error count reaches $smtpd_soft_error_limit +(default: 10), the Postfix smtpd(8) server delays all non-error and +error responses by $smtpd_error_sleep_time seconds (default: 1 +second). </p> + +<li><p>When the error count reaches $smtpd_hard_error_limit +(default: 20) the Postfix smtpd(8) server breaks the connection. </p> + +</ul> + +<p> Postfix version 2.0 and earlier:</p> + +<ul> + +<li> <p> When the error count is less than $smtpd_soft_error_limit +(default: 10) the Postfix smtpd(8) server delays all error replies by +$smtpd_error_sleep_time (1 second with Postfix 2.0, 5 seconds with +Postfix 1.1 and earlier). </p> + +<li> <p> When the error count reaches $smtpd_soft_error_limit, +the Postfix smtpd(8) server delays all responses by "error count" +seconds or $smtpd_error_sleep_time, whichever is more. </p> + +<li><p>When the error count reaches $smtpd_hard_error_limit +(default: 20) the Postfix smtpd(8) server breaks the connection. </p> + +</ul> + +<h2><a name="conn_limit">Measures against clients that make too many connections</a></h2> + +<p> Note: these features use the Postfix anvil(8) service, introduced +with Postfix version 2.2. </p> + +<p> The Postfix smtpd(8) server can limit the number of simultaneous +connections from the same SMTP client, as well as the connection +rate and the rate of certain SMTP commands from the same client. +These statistics are maintained by the anvil(8) server (translation: +if anvil(8) breaks, then connection limits stop working). </p> + +<p> IMPORTANT: These limits must not be used to regulate legitimate +traffic: mail will suffer grotesque delays if you do so. The limits +are designed to protect the smtpd(8) server against abuse by +out-of-control clients. </p> + +<blockquote> + +<dl> + +<dt> smtpd_client_connection_count_limit (default: 50) </dt> <dd> +The maximum number of connections that an SMTP client may make +simultaneously. </dd> + +<dt> smtpd_client_connection_rate_limit (default: no limit) </dt> +<dd> The maximum number of connections that an SMTP client may make +in the time interval specified with anvil_rate_time_unit (default: +60s). </dd> + +<dt> smtpd_client_message_rate_limit (default: no limit) </dt> <dd> +The maximum number of message delivery requests that an SMTP client +may make in the time interval specified with anvil_rate_time_unit +(default: 60s). </dd> + +<dt> smtpd_client_recipient_rate_limit (default: no limit) </dt> +<dd> The maximum number of recipient addresses that an SMTP client +may specify in the time interval specified with anvil_rate_time_unit +(default: 60s). </dd> + +<dt> smtpd_client_new_tls_session_rate_limit (default: no limit) +</dt> <dd> The maximum number of new TLS sessions (without using +the TLS session cache) that an SMTP client may negotiate in the +time interval specified with anvil_rate_time_unit (default: 60s). +</dd> + +<dt> smtpd_client_auth_rate_limit (default: no limit) </dt> <dd> +The maximum number of AUTH commands that an SMTP client may send +in the time interval specified with anvil_rate_time_unit (default: +60s). Available in Postfix 3.1 and later. </dd> + +<dt> smtpd_client_event_limit_exceptions (default: $mynetworks) +</dt> <dd> SMTP clients that are excluded from connection and rate +limits specified above. </dd> + +</dl> + +</blockquote> + +<h2><a name="mailing_tips">General mail delivery performance tips</a></h2> + +<ul> + +<li> <p> Read and understand the maildrop queue, incoming queue, +active queue and deferred queue discussions in the QSHAPE_README +document. </p> + +<li> <p> In case of slow delivery, run the qshape tool as described +in the QSHAPE_README document. </p> + +<li> <p> Submit multiple recipients per message instead of submitting +messages with only a few recipients. </p> + +<li> <p> Submit mail via SMTP instead of /usr/sbin/sendmail. You +may have to adjust the smtpd_recipient_limit parameter setting. +</p> + +<li> <p> Don't overwhelm the disk with mail submissions. Optimize +the mail submission rate by tuning the number of parallel submissions +and/or by tuning the Postfix in_flow_delay parameter setting. </p> + +<li> <p> Run a local name server to reduce slow-down due to DNS +lookups. If you run multiple Postfix systems, point each local name +server to a shared forwarding server to reduce the number of lookups +across the upstream network link. </p> + +<li> <p> Reduce the smtp_connect_timeout and smtp_helo_timeout +values so that Postfix does not waste lots of time connecting +to non-responding remote SMTP servers. </p> + +<li> <p> Use a dedicated mail delivery transport for problematic +destinations, with reduced timeouts and with adjusted concurrency. +See "<a href="#rope">Tuning the number of simultaneous deliveries</a>" +below. +</p> + +<li> <p> Use a fallback_relay host for mail that cannot be delivered +upon the first attempt. This "graveyard" machine can use shorter +retry times for difficult to reach destinations. See "<a +href="#hammer">Tuning the frequency of deferred mail delivery +attempts</a>" below. </p> + +<li> <p> Speed up disk updates with a large (64MB) persistent write +cache. This allows disk updates to be sorted for optimal access +speed without compromising file system integrity when the system +crashes. </p> + +<li> <p> Use a solid-state disk (a persistent RAM disk). This +is an expensive solution that should be used in combination +with short SMTP timeouts and a fallback_relay "graveyard" +machine that delivers mail for problem destinations. </p> + +</ul> + +<h2><a name="rope">Tuning the number of simultaneous deliveries</a></h2> + +<p> Although Postfix can be configured to run 1000 SMTP client +processes at the same time, it is rarely desirable that it makes +1000 simultaneous connections to the same remote system. For this +reason, Postfix has safety mechanisms in place to avoid this +so-called "thundering herd" problem. </p> + +<p> The Postfix queue manager implements the analog of the TCP slow +start flow control strategy: when delivering to a site, send a +small number of messages first, then increase the concurrency as +long as all goes well; reduce concurrency in the face of congestion. +</p> + +<ul> + +<li> <p> The initial_destination_concurrency parameter (default: 5) +controls how many messages are initially sent to the same destination +before adapting delivery concurrency. Of course, this setting is +effective only as long as it does not exceed the process limit and +the destination concurrency limit for the specific mail transport +channel. </p> + +<li> <p> The default_destination_concurrency_limit parameter (default: +20) controls how many messages may be sent to the same destination +simultaneously. You can override this setting for specific message +delivery transports by taking the name of the master.cf entry +and appending "_destination_concurrency_limit". </p> + +</ul> + +<p> Examples of transport specific concurrency limits are: </p> + +<ul> + +<li> <p> The local_destination_concurrency_limit parameter (default: +2) controls how many messages are delivered simultaneously to the +same local recipient. The recommended limit is low because delivery +to the same mailbox must happen sequentially, so massive parallelism +is not useful. Another good reason to limit delivery concurrency +to the same recipient: if the recipient has an expensive shell +command in her .forward file, or if the recipient is a mailing list +manager, you don't want to run too many instances of those processes +at the same time. </p> + +<li> <p> The default smtp_destination_concurrency_limit of 20 seems +enough to noticeably load a system without bringing it to its knees. +Be careful when changing this to a much larger number. </p> + +</ul> + +<p> The above default values of the concurrency limits work well +in a broad range of situations. Knee-jerk changes to these parameters +in the face of congestion can actually make problems worse. +Specifically, large destination concurrencies should never be the +default. They should be used only for transports that deliver mail +to a small number of high volume domains. </p> + +<p> A common situation where high concurrency is called for is on +gateways relaying a high volume of mail between the Internet +and an intranet mail environment. Approximately half the mail +(assuming equal volumes inbound and outbound) will be destined +for the internal mail hubs. Since the internal mail hubs will be +receiving all external mail exclusively from the gateway, it is +reasonable to configure the gateway to make greater demands on the +capacity of the internal SMTP servers. </p> + +<p> The tuning of the inbound concurrency limits need not be trial +and error. A high volume capable mailhub should be able to easily +handle 50 or 100 (rather than the default 20) simultaneous connections, +especially if the gateway forwards to multiple MX hosts. When all +MX hosts are up and accepting connections in a timely fashion, +throughput will be high. If any MX host is down and completely +unresponsive, the average connection latency rises to at least 1/N +* $smtp_connect_timeout, if there are N MX hosts. This limits +throughput to at most the destination concurrency * N / +$smtp_connect_timeout. </p> + +<p> For example, with a destination concurrency of 100 and 2 MX +hosts, each host will handle up to 50 simultaneous connections. If +one MX host is down and the default SMTP connection timeout is 30s, +the throughput limit is 100 * 2 / 30 ~= 6 messages per second. This +suggests that high volume destinations with good connectivity and +multiple MX hosts need a lower connection timeout, values as low +as 5s or even 1s can be used to prevent congestion when one or +more, but not all MX hosts are down. </p> + +<p> If necessary, set a higher <i>transport</i>_destination_concurrency_limit +(in main.cf since this is a queue manager parameter) and a lower +smtp_connect_timeout (with a "-o" override in master.cf since +this parameter has no per-transport name) for the relay transport +and any transports dedicated for specific high volume destinations. +</p> + +<h2><a name="rcpts">Tuning the number of recipients per delivery</a></h2> + +<p> The default_destination_recipient_limit parameter (default: +50) controls how many recipients a Postfix delivery agent will send +with each copy of an email message. You can override this setting +for specific Postfix delivery agents. For example, +"uucp_destination_recipient_limit = 100" would limit the number of +recipients per UUCP delivery to 100. </p> + +<p> If an email message exceeds the recipient limit for some +destination, the Postfix queue manager breaks up the list of +recipients into smaller lists. Postfix will attempt to send multiple +copies of the message in parallel. </p> + +<p> IMPORTANT: Be careful when increasing the recipient limit per +message delivery; some SMTP servers abort the connection when they +run out of memory or when a hard recipient limit is reached, so +that the message will never be delivered. </p> + +<p> The smtpd_recipient_limit parameter (default: 1000) controls +how many recipients the Postfix smtpd(8) server will take per +delivery. The default limit is more than any reasonable SMTP client +would send. The limit exists to protect the local mail system +against a run-away client. </p> + +<h2><a name="hammer">Tuning the frequency of deferred mail delivery attempts</a></h2> + +<p> When a Postfix delivery agent (smtp(8), local(8), etc.) is +unable to deliver a message it may blame the message itself, or it +may blame the receiving party. </p> + +<ul> + +<li> <p> When the delivery agent blames the message, the queue +manager gives the queue file a time stamp into the future, so it +won't be looked at for a while. By default, the amount of time to +cool down is the amount of time that has passed since the message +arrived. This results in so-called exponential backoff behavior. +</p> + +<li> <p> When the delivery agent blames the receiving party (for +example a local recipient user, or a remote host), the queue manager +not only advances the queue file time stamp, but also puts the +receiving party on a "dead" list so that it will be skipped for +some amount of time. </p> + +</ul> + +<p> This process is governed by a bunch of little parameters. </p> + +<blockquote> + +<dl> + +<dt> queue_run_delay (default: 300 seconds; before Postfix 2.4: +1000s) </dt> <dd> How often +the queue manager scans the queue for deferred mail. </dd> + +<dt> minimal_backoff_time (default: 300 seconds; before Postfix +2.4: 1000s) </dt> <dd> The +minimal amount of time a message won't be looked at, and the minimal +amount of time to stay away from a "dead" destination. </dd> + +<dt> maximal_backoff_time (default: 4000 seconds) </dt> <dd> The +maximal amount of time a message won't be looked at after a delivery +failure. </dd> + +<dt> maximal_queue_lifetime (default: 5 days) </dt> <dd> How long +a message stays in the queue before it is sent back as undeliverable. +Specify 0 for mail that should be returned immediately after the +first unsuccessful delivery attempt. </dd> + +<dt> bounce_queue_lifetime (default: 5 days, available with Postfix +version 2.1 and later) </dt> <dd> How long a MAILER-DAEMON message +stays in the queue before it is considered undeliverable. Specify +0 for mail that should be tried only once. </dd> + +<dt> qmgr_message_recipient_limit (default: 20000) </dt> <dd> The +size of many in-memory queue manager data structures. Among others, +this parameter limits the size of the short-term, in-memory list +of "dead" destinations. Destinations that don't fit the list are +not added. </dd> + +<dt> <i>transport</i>_destination_concurrency_failed_cohort_limit +</dt> <dd> Controls when a destination is considered "dead". This +parameter is critical with a non-zero +<i>transport</i>_destination_rate_delay, with a reduced +<i>transport</i>_destination_concurrency_limit, or with +a reduced initial_destination_concurrency. </dd> + +</dl> + +</blockquote> + +<p> IMPORTANT: If you increase the frequency of deferred mail +delivery attempts, or if you flush the deferred mail queue frequently, +then you may find that Postfix mail delivery performance actually +becomes worse. The symptoms are as follows: </p> + +<ul> + +<li> <p> The active queue becomes saturated with mail that has +delivery problems. New mail enters the active queue only when +an old message is deferred. This is a slow process that usually +requires timing out one or more SMTP connections. </p> + +<li> <p> All available Postfix delivery agents become occupied +trying to connect to unreachable sites etc. New mail has to wait +until a delivery agent becomes available. This is a slow process +that usually requires timing out one or more SMTP connections. </p> + +</ul> + +<p> When mail is being deferred frequently, fixing the problem is +always better than increasing the frequency of delivery attempts. +However, if you can control only the delivery attempt frequency, +consider using a dedicated fallback_relay "graveyard" machine for +bad destinations, so that these destinations do not ruin the +performance of normal +mail deliveries. </p> + +<h2><a name="proc_limit">Tuning the number of Postfix processes</a></h2> + +<p> The default_process_limit configuration parameter gives direct +control over how many daemon processes Postfix will run. As of +Postfix 2.0 the default limit is 100 SMTP client processes, 100 +SMTP server processes, and so on. This may overwhelm systems with +little memory, as well as networks with low bandwidth. </p> + +<p> You can change the global process limit by specifying a +non-default default_process_limit in the main.cf file. For example, +to run up to 10 SMTP client processes, 10 SMTP server processes, +and so on: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + default_process_limit = 10 +</pre> +</blockquote> + +<p> You need to execute "postfix reload" to make the change effective. +This limit is enforced by the Postfix master(8) daemon which does +not automatically read main.cf when it changes. </p> + +<p> You can override the process limit for specific Postfix daemons +by editing the master.cf file. For example, if you do not wish to +receive 100 SMTP messages at the same time, but do not want to +change the process limits for other Postfix daemons, you could +specify: </p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + # ==================================================================== + # service type private unpriv chroot wakeup maxproc command + args + # (yes) (yes) (yes) (never) (100) + # ==================================================================== + . . . + smtp inet n - - - 10 smtpd + . . . +</pre> +</blockquote> + +<h2><a name="proc_sys">Tuning the number of processes on the system</a></h2> + +<ul> + +<li> <p> MacOS X will run out of process slots when you increase +Postfix process limits. The following works with OSX 10.4 and OSX +10.5. </p> + +<p> MacOS X kernel parameters can be specified in /etc/sysctl.conf. +</p> + +<pre> +/etc/sysctl.conf: + kern.maxproc=2048 + kern.maxprocperuid=2048 +</pre> + +<p> Unfortunately these can't simply be set on the fly with "sysctl +-w". You also have to set the following in /etc/launchd.conf so +that the root user after boot will have the right process limit +(2048). Otherwise you have to always run ulimit -u 2048 as root, +then start a user shell, and then start processes for things to +take effect. </p> + +<pre> +/etc/launchd.conf: + limit maxproc 2048 +</pre> + +<p> Once these are in place, reboot the system. After that, the limits will +stay in place. </p> + +</ul> + +<h2><a name="file_limit">Tuning the number of open files or sockets</a></h2> + +<p> When Postfix opens too many files or sockets, processes will +abort with fatal errors, and the system may log "file table full" +errors. </p> + +<ul> + +<li> <p> Depending on your Postfix and operating system versions +you may need to recompile Postfix if you need more than 1024 file +descriptors per process: </p> + +<ul> <li> <p> No recompilation is needed for Postfix version 2.4 +and later, when it was compiled for systems that support BSD kqueue(2) +(FreeBSD 4.1, NetBSD 2.0, OpenBSD 2.9), Solaris 8 /dev/poll, or +Linux 2.6 epoll(4). </p> + +<li> <p> Otherwise, Postfix needs to be recompiled to override the +default FD_SETSIZE value. </p> + +</ul> + +<li> <p> Reduce the number of processes as described under "<a +href="#proc_limit">Tuning the number of Postfix processes</a>" above. +Fewer processes need fewer open files and sockets. </p> + +<li> <p> Configure the kernel for more open files and sockets. +The details are extremely system dependent and change with the +operating system version. Be sure to verify the following information +with your system tuning guide: </p> + +<ul> + +<li> <p> Some FreeBSD kernel parameters can be specified in +/boot/loader.conf, and some can be specified in /etc/sysctl.conf +or changed with sysctl commands. +Which is which depends on the version. +</p> + +<pre> +kern.ipc.maxsockets="5000" +kern.ipc.nmbclusters="65536" +kern.maxproc="2048" +kern.maxfiles="16384" +kern.maxfilesperproc="16384" +</pre> + +<li> <p> Linux kernel parameters can be specified in /etc/sysctl.conf +or changed with sysctl commands: </p> + +<pre> +fs.file-max=16384 +kernel.threads-max=2048 +</pre> + +<li> <p> Solaris kernel parameters can be specified in /etc/system, +as described in the <a +href="http://www.science.uva.nl/pub/solaris/solaris2.html#q3.48">Solaris +FAQ</a> entry titled "How can I increase the number of file +descriptors per process?" </p> + +<pre> +* set hard limit on file descriptors +set rlim_fd_max = 4096 +* set soft limit on file descriptors +set rlim_fd_cur = 1024 +</pre> + +</ul> + +</ul> + +</body> + +</html> diff --git a/proto/UUCP_README.html b/proto/UUCP_README.html new file mode 100644 index 0000000..e677a77 --- /dev/null +++ b/proto/UUCP_README.html @@ -0,0 +1,200 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix and UUCP </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix and UUCP </h1> + +<hr> + +<h2><a name="uucp-tcp">Using UUCP over TCP</a></h2> + +<p> Despite a serious lack of sex-appeal, email via UUCP over TCP +is a practical option for sites without permanent Internet connections, +and for sites without a fixed IP address. For first-hand information, +see the following guides: </p> + +<ul> + +<li> Jim Seymour's guide for using UUCP over TCP at +http://jimsun.LinxNet.com/jdp/uucp_over_tcp/index.html, + +<li> Craig Sanders's guide for SSL-encrypted UUCP over TCP +using stunnel at http://taz.net.au/postfix/uucp/. + +</ul> + +Here's a graphical description of what this document is about: + +<blockquote> + +<table> + +<tr> <td> Local network <tt> <---> </tt> </td> + +<td bgcolor="#f0f0ff" align="center"><a href="#lan-uucp">LAN to<br> +UUCP<br> Gateway</a></td> + +<td> <tt> <--- </tt> UUCP <tt> ---> </tt> </td> + +<td bgcolor="#f0f0ff" align="center"><a href="#internet-uucp">Internet<br> +to UUCP<br> Gateway</a></td> + +<td> <tt> <---> </tt> Internet </td> </tr> + +</table> + +</blockquote> + +<p> And here's the table of contents of this document: </p> + +<ul> + +<li><a href="#internet-uucp">Setting up a Postfix Internet to UUCP +gateway</a> + +<li><a href="#lan-uucp">Setting up a Postfix LAN to UUCP +gateway</a> + +</ul> + +<h2><a name="internet-uucp">Setting up a Postfix Internet to UUCP +gateway</a></h2> + +<p> Here is how to set up a machine that sits on the Internet and +that forwards mail to a LAN that is connected via UUCP. See +the <a href="#lan-uucp">LAN to UUCP gateway</a> section for +the other side of the story. </p> + +<ul> + +<li> <p> You need an <b>rmail</b> program that extracts the sender +address from mail that arrives via UUCP, and that feeds the mail +into the Postfix <b>sendmail</b> command. Most UNIX systems come +with an <b>rmail</b> utility. If you're in a pinch, try the one +bundled with the Postfix source code in the <b>auxiliary/rmail</b> +directory. </p> + +<li> <p> Define a pipe(8) based mail delivery transport for delivery +via UUCP: </p> + +<pre> +/etc/postfix/master.cf: + uucp unix - n n - - pipe + flags=F user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) +</pre> + +<p> This runs the <b>uux</b> command to place outgoing mail into +the UUCP queue after replacing $nexthop by the next-hop hostname +(the receiving UUCP host) and after replacing $recipient by the +recipients. The pipe(8) delivery agent executes the <b>uux</b> +command without assistance from the shell, so there are no problems +with shell meta characters in command-line parameters. </p> + +<li> <p> Specify that mail for <i>example.com</i>, should be +delivered via UUCP, to a host named <i>uucp-host</i>: </p> + +<pre> +/etc/postfix/transport: + example.com uucp:uucp-host + .example.com uucp:uucp-host +</pre> + +<p> See the transport(5) manual page for more details. </p> + +<li> <p> Execute the command "<b>postmap /etc/postfix/transport</b>" +whenever you change the <b>transport</b> file. </p> + +<li> <p> Enable <b>transport</b> table lookups: </p> + +<pre> +/etc/postfix/main.cf: + transport_maps = hash:/etc/postfix/transport +</pre> + +<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses +<b>dbm</b> files instead of <b>db</b> files. To find out what map +types Postfix supports, use the command "<b>postconf -m</b>". </p> + +<li> <p> Add <i>example.com</i> to the list of domains that your site +is willing to relay mail for. </p> + +<pre> +/etc/postfix/main.cf: + relay_domains = example.com ...<i>other relay domains</i>... +</pre> + +<p> See the relay_domains configuration parameter description for +details. </p> + +<li> <p> Execute the command "<b>postfix reload</b>" to make the +changes effective. </p> + +</ul> + +<h2><a name="lan-uucp">Setting up a Postfix LAN to UUCP +gateway</a></h2> + +<p> Here is how to relay mail from a LAN via UUCP to the +Internet. See the <a href="#internet-uucp">Internet to UUCP +gateway</a> section for the other side of the story. </p> + +<ul> + +<li> <p> You need an <b>rmail</b> program that extracts the sender +address from mail that arrives via UUCP, and that feeds the mail +into the Postfix <b>sendmail</b> command. Most UNIX systems come +with an <b>rmail</b> utility. If you're in a pinch, try the one +bundled with the Postfix source code in the <b>auxiliary/rmail</b> +directory. </p> + +<li> <p> Specify that all remote mail must be sent via the <b>uucp</b> +mail transport to your UUCP gateway host, say, <i>uucp-gateway</i>: </p> + +<pre> +/etc/postfix/main.cf: + relayhost = uucp-gateway + default_transport = uucp +</pre> + +<p> Postfix 2.0 and later also allows the following more succinct form: </p> + +<pre> +/etc/postfix/main.cf: + default_transport = uucp:uucp-gateway +</pre> + +<li> <p> Define a pipe(8) based message delivery transport for mail +delivery via UUCP: </p> + +<pre> +/etc/postfix/master.cf: + uucp unix - n n - - pipe + flags=F user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) +</pre> + +<p> This runs the <b>uux</b> command to place outgoing mail into +the UUCP queue. It substitutes the next-hop hostname (<i>uucp-gateway</i>, +or whatever you specified) and the recipients before executing the +command. The <b>uux</b> command is executed without assistance +from the shell, so there are no problems with shell meta characters. +</p> + +<li> <p> Execute the command "<b>postfix reload</b>" to make the +changes effective. </p> + +</ul> + +</body> + +</html> diff --git a/proto/VERP_README.html b/proto/VERP_README.html new file mode 100644 index 0000000..e442c89 --- /dev/null +++ b/proto/VERP_README.html @@ -0,0 +1,289 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix VERP Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix VERP Howto</h1> + +<hr> + +<h2>Postfix VERP support</h2> + +<p> Postfix versions 1.1 and later support variable envelope return +path addresses on request. When VERP style delivery is requested, +each recipient of a message receives a customized copy of the +message, with his/her own recipient address encoded in the envelope +sender address. </p> + +<p> For example, when VERP style delivery is requested, Postfix +delivers mail from "<tt>owner-listname@origin</tt>" for a recipient +"<tt>user@domain</tt>", with a sender address that encodes the +recipient as follows: </p> + +<blockquote> +<pre> +owner-listname+user=domain@origin +</pre> +</blockquote> + +<p> Thus, undeliverable mail can reveal the undeliverable recipient +address without requiring the list owner to parse bounce messages. +</p> + +<p> The VERP concept was popularized by the qmail MTA and by the ezmlm +mailing list manager. See http://cr.yp.to/proto/verp.txt for the +ideas behind this concept. </p> + +<p> Topics covered in this document: </p> + +<ul> + +<li> <a href="#config"> Postfix VERP configuration parameters </a> + +<li> <a href="#majordomo"> Using VERP with majordomo etc. mailing lists </a> + +<li> <a href="#smtp"> VERP support in the Postfix SMTP server</a> + +<li> <a href="#sendmail"> VERP support in the Postfix sendmail command </a> + +<li> <a href="#qmqp"> VERP support in the Postfix QMQP server </a> + +</ul> + +<h2> <a name="config"> Postfix VERP configuration parameters </a> </h2> + +With Postfix, the whole process is controlled by four configuration +parameters. + +<dl> + +<dt> default_verp_delimiters (default value: +=) + + <dd> <p> What VERP delimiter characters Postfix uses when VERP + style delivery is requested but no explicit delimiters are + specified. </p> + +<dt> verp_delimiter_filter (default: -+=) + + <dd> <p> What characters Postfix accepts as VERP delimiter + characters on the sendmail command line and in SMTP commands. + Many characters must not be used as VERP delimiter characters, + either because they already have a special meaning in email + addresses (such as the @ or the %), because they are used as + part of a username or domain name (such as alphanumerics), or + because they are non-ASCII or control characters. And who + knows, some characters may tickle bugs in vulnerable software, + and we would not want that to happen. </p> </dd> + +<dt> smtpd_authorized_verp_clients (default value: none) + + <dd> <p> What SMTP clients are allowed to request VERP style + delivery. The Postfix QMQP server uses its own access control + mechanism, and local submission (via /usr/sbin/sendmail etc.) + is always authorized. To authorize a host, list its name, IP + address, subnet (net/mask) or parent .domain. </p> + + <p> With Postfix versions 1.1 and 2.0, this parameter is called + authorized_verp_clients (default: $mynetworks). </p> </dd> + +<dt> disable_verp_bounces (default: no) + + <dd> <p> Send one bounce report for multi-recipient VERP mail, + instead of one bounce report per recipient. The default, + one per recipient, is what ezmlm needs. </p> </dd> + +</dl> + +<h2> <a name="majordomo"> Using VERP with majordomo etc. mailing lists </a> </h2> + +<p> In order to make VERP useful with majordomo etc. mailing lists, +you would configure the list manager to submit mail according +to one of the following two forms: </p> + +<p> Postfix 2.3 and later: </p> + +<blockquote> +<pre> +% sendmail -XV -f owner-listname other-arguments... + +% sendmail -XV+= -f owner-listname other-arguments... +</pre> +</blockquote> + +<p> Postfix 2.2 and earlier (Postfix 2.3 understands the old syntax +for backwards compatibility, but will log a warning that reminds +you of the new syntax): </p> + +<blockquote> +<pre> +% sendmail -V -f owner-listname other-arguments... + +% sendmail -V+= -f owner-listname other-arguments... +</pre> +</blockquote> + +<p> The first form uses the default main.cf VERP delimiter characters. +The second form allows you to explicitly specify the VERP delimiter +characters. The example shows the recommended values. </p> + +<p> This text assumes that you have set up an owner-listname alias +that routes undeliverable mail to a real person: </p> + +<blockquote> +<pre> +/etc/aliases: + owner-listname: yourname+listname +</pre> +</blockquote> + +<p> In order to process bounces we are going to make extensive use +of address extension tricks. </p> + +<p> You need to tell Postfix that + is the separator between an +address and its optional address extension, that address extensions +are appended to .forward file names, and that address extensions +are to be discarded when doing alias expansions: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + recipient_delimiter = + + forward_path = $home/.forward${recipient_delimiter}${extension}, + $home/.forward + propagate_unmatched_extensions = canonical, virtual +</pre> +</blockquote> + +<p> (the last two parameter settings are default settings). </p> + +<p> You need to set up a file named .forward+listname with the +commands that process all the mail that is sent to the owner-listname +address: </p> + +<blockquote> +<pre> +~/.forward+listname: + "|/some/where/command ..." +</pre> +</blockquote> + +<p> With this set up, undeliverable mail for user@domain will be returned +to the following address: </p> + +<blockquote> +<pre> +owner-listname+user=domain@your.domain +</pre> +</blockquote> + +<p> which is processed by the command in your .forward+listname file. +The message should contain, among others, a To: header with the +encapsulated recipient sender address: </p> + +<blockquote> +<pre> +To: owner-listname+user=domain@your.domain +</pre> +</blockquote> + +<p> It is left as an exercise for the reader to parse the To: header +line and to pull out the user=domain part from the recipient address. +</p> + +<h2> <a name="smtp"> VERP support in the Postfix SMTP server </a> </h2> + +<p> The Postfix SMTP server implements a command XVERP to enable +VERP style delivery. The syntax allows two forms: </p> + +<blockquote> +<pre> +MAIL FROM:<sender@domain> XVERP + +MAIL FROM:<sender@domain> XVERP=+= +</pre> +</blockquote> + +<p> The first form uses the default main.cf VERP delimiters, the +second form overrides them explicitly. The values shown are the +recommended ones. </p> + +<p> You can use the smtpd_command_filter feature to append XVERP +to SMTP commands from legacy software. This requires Postfix 2.7 +or later. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_command_filter = pcre:/etc/postfix/append_verp.pcre + smtpd_authorized_verp_clients = $mynetworks + +/etc/postfix/append_verp.pcre: + /^(MAIL FROM:<listname@example\.com>.*)/ $1 XVERP +</pre> +</blockquote> + +<h2> <a name="sendmail"> VERP support in the Postfix sendmail command </a> </h2> + +<p> The Postfix sendmail command has a -V flag to request VERP style +delivery. Specify one of the following two forms: </p> + +<p> Postfix 2.3 and later:</p> +<blockquote> +<pre> +% sendmail -XV -f owner-listname .... + +% sendmail -XV+= -f owner-listname .... +</pre> +</blockquote> + +<p> Postfix 2.2 and earlier (Postfix 2.3 understands the old syntax +for backwards compatibility, but will log a warning that reminds +you of the new syntax): </p> + +<blockquote> +<pre> +% sendmail -V -f owner-listname .... + +% sendmail -V+= -f owner-listname .... +</pre> +</blockquote> + +<p> The first form uses the default main.cf VERP delimiters, the +second form overrides them explicitly. The values shown are the +recommended ones. </p> + +<h2> <a name="qmqp"> VERP support in the Postfix QMQP server </a> </h2> + +<p> When the Postfix QMQP server receives mail with an envelope +sender address of the form: </p> + +<blockquote> +<pre> +listname-@your.domain-@[] +</pre> +</blockquote> + +<p> Postfix generates sender addresses +"<tt>listname-user=domain@your.domain</tt>", using "-=" as the VERP +delimiters because qmail/ezmlm expect this. </p> + +<p> More generally, a sender address of "<tt>prefix@origin-@[]</tt>" +requests VERP style delivery with sender addresses of the form +"<tt>prefixuser=domain@origin</tt>". However, Postfix allows only +VERP delimiters that are specified with the verp_delimiter_filter +parameter. In particular, the "=" delimiter is required for qmail +compatibility (see the qmail addresses(5) manual page for details). + +</body> + +</html> diff --git a/proto/VIRTUAL_README.html b/proto/VIRTUAL_README.html new file mode 100644 index 0000000..1c5aecc --- /dev/null +++ b/proto/VIRTUAL_README.html @@ -0,0 +1,648 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Virtual Domain Hosting Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix +Virtual Domain Hosting Howto</h1> + +<hr> + +<h2>Purpose of this document</h2> + +<p> This document requires Postfix version 2.0 or later. </p> + +<p> This document gives an overview of how Postfix can be used for +hosting multiple Internet domains, both for final delivery on the +machine itself and for the purpose of forwarding to destinations +elsewhere. </p> + +<p> The text not only describes delivery mechanisms that are built +into Postfix, but also gives pointers for using non-Postfix mail +delivery software. </p> + +<p> The following topics are covered: </p> + +<ul> + +<li> <a href="#canonical">Canonical versus hosted versus other domains</a> + +<li> <a href="#local_vs_database">Local files versus network databases</a> + +<li> <a href="#local">As simple as can be: shared domains, +UNIX system accounts</a> + +<li> <a href="#virtual_alias">Postfix virtual ALIAS example: +separate domains, UNIX system accounts</a> + +<li> <a href="#virtual_mailbox">Postfix virtual MAILBOX example: +separate domains, non-UNIX accounts</a> + +<li> <a href="#in_virtual_other">Non-Postfix mailbox store: separate +domains, non-UNIX accounts</a> + +<li> <a href="#forwarding">Mail forwarding domains</a> + +<li> <a href="#mailing_lists">Mailing lists</a> + +<li> <a href="#autoreplies">Autoreplies</a> + +</ul> + +<h2><a name="canonical">Canonical versus hosted versus +other domains</a></h2> + +<p>Most Postfix systems are the <b>final destination</b> for only a +few domain names. These include the hostnames and [the IP addresses] +of the machine that Postfix runs on, and sometimes also include +the parent domain of the hostname. The remainder of this document +will refer to these domains as the canonical domains. They are +usually implemented with the Postfix local domain address class, +as defined in the ADDRESS_CLASS_README file.</p> + +<p> Besides the canonical domains, Postfix can be configured to be +the <b>final destination</b> for any number of additional domains. +These domains are called hosted, because they are not directly +associated with the name of the machine itself. Hosted domains are +usually implemented with the virtual alias domain address class +and/or with the virtual mailbox domain address class, as defined +in the ADDRESS_CLASS_README file. </p> + +<p> But wait! There is more. Postfix can be configured as a backup +MX host for other domains. In this case Postfix is <b>not the final +destination</b> for those domains. It merely queues the mail when +the primary MX host is down, and forwards the mail when the primary +MX host becomes available. This function is implemented with the +relay domain address class, as defined in the ADDRESS_CLASS_README +file. </p> + +<p> Finally, Postfix can be configured as a transit host for sending +mail across the internet. Obviously, Postfix is not the final destination +for such mail. This function is available only for authorized +clients and/or users, and is implemented by the default domain +address class, as defined in the ADDRESS_CLASS_README file. </p> + +<h2><a name="local_vs_database">Local files versus network databases</a></h2> + +<p> The examples in this text use table lookups from local files +such as DBM or Berkeley DB. These are easy to debug with the +<b>postmap</b> command: </p> + +<blockquote> +Example: <tt>postmap -q info@example.com hash:/etc/postfix/virtual</tt> +</blockquote> + +<p> See the documentation in LDAP_README, MYSQL_README and PGSQL_README +for how to replace local files by databases. The reader is strongly +advised to make the system work with local files before migrating +to network databases, and to use the <b>postmap</b> command to verify +that network database lookups produce the exact same results as +local file lookup. </p> + +<blockquote> +Example: <tt>postmap -q info@example.com ldap:/etc/postfix/virtual.cf</tt> +</blockquote> + +<h2><a name="local">As simple as can be: shared domains, UNIX system +accounts</a></h2> + +<p> The simplest method to host an additional domain is to add the +domain name to the domains listed in the Postfix mydestination +configuration parameter, and to add the user names to the UNIX +password file. </p> + +<p> This approach makes no distinction between canonical and hosted +domains. Each username can receive mail in every domain. </p> + +<p> In the examples we will use "example.com" as the domain that is +being hosted on the local Postfix machine. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + mydestination = $myhostname localhost.$mydomain ... example.com +</pre> +</blockquote> + +<p> The limitations of this approach are: </p> + +<ul> + +<li>A total lack of separation: mail for info@my.host.name is +delivered to the same UNIX system account as mail for info@example.com. + +<li> With users in the UNIX password file, administration of large +numbers of users becomes inconvenient. + +</ul> + +<p> The examples that follow provide solutions for both limitations. +</p> + +<h2><a name="virtual_alias">Postfix virtual ALIAS example: +separate domains, UNIX system accounts</a></h2> + +<p> With the approach described in this section, every hosted domain +can have its own info etc. email address. However, it still uses +UNIX system accounts for local mailbox deliveries. </p> + +<p> With virtual alias domains, each hosted address is aliased to +a local UNIX system account or to a remote address. The example +below shows how to use this mechanism for the example.com domain. +</p> + +<blockquote> +<pre> + 1 /etc/postfix/main.cf: + 2 virtual_alias_domains = example.com ...other hosted domains... + 3 virtual_alias_maps = hash:/etc/postfix/virtual + 4 + 5 /etc/postfix/virtual: + 6 postmaster@example.com postmaster + 7 info@example.com joe + 8 sales@example.com jane + 9 # Uncomment entry below to implement a catch-all address +10 # @example.com jim +11 ...virtual aliases for more domains... +</pre> +</blockquote> + +<p> Notes: </p> + +<ul> + +<li> <p> Line 2: the virtual_alias_domains setting tells Postfix +that example.com is a so-called virtual alias domain. If you omit +this setting then Postfix will reject mail (relay access denied) +or will not be able to deliver it (mail for example.com loops back +to myself). </p> + +<p> NEVER list a virtual alias domain name as a mydestination +domain! </p> + +<li> <p> Lines 3-8: the /etc/postfix/virtual file contains the virtual +aliases. With the example above, mail for postmaster@example.com +goes to the local postmaster, while mail for info@example.com goes +to the UNIX account joe, and mail for sales@example.com goes to +the UNIX account jane. Mail for all other addresses in example.com +is rejected with the error message "User unknown". </p> + +<li> <p> Line 10: the commented out entry (text after #) shows how +one would implement a catch-all virtual alias that receives mail +for every example.com address not listed in the virtual alias file. +This is not without risk. Spammers nowadays try to send mail from +(or mail to) every possible name that they can think of. A catch-all +mailbox is likely to receive many spam messages, and many bounces +for spam messages that were sent in the name of anything@example.com. +</p> + +</ul> + +<p>Execute the command "<b>postmap /etc/postfix/virtual</b>" after +changing the virtual file, and execute the command "<b>postfix +reload</b>" after changing the main.cf file. </p> + +<p> Note: virtual aliases can resolve to a local address or to a +remote address, or both. They don't have to resolve to UNIX system +accounts on your machine. </p> + +<p> More details about the virtual alias file are given in the +virtual(5) manual page, including multiple addresses on the right-hand +side. </p> + +<p> Virtual aliasing solves one problem: it allows each domain to +have its own info mail address. But there still is one drawback: +each virtual address is aliased to a UNIX system account. As you +add more virtual addresses you also add more UNIX system accounts. +The next section eliminates this problem. </p> + +<h2><a name="virtual_mailbox">Postfix virtual MAILBOX example: +separate domains, non-UNIX accounts</a></h2> + +<p> As a system hosts more and more domains and users, it becomes less +desirable to give every user their own UNIX system account.</p> + +<p> With the Postfix virtual(8) mailbox delivery agent, every +recipient address can have its own virtual mailbox. Unlike virtual +alias domains, virtual mailbox domains do not need the clumsy +translation from each recipient addresses into a different address, +and owners of a virtual mailbox address do not need to have a UNIX +system account.</p> + +<p> The Postfix virtual(8) mailbox delivery agent looks up the user +mailbox pathname, uid and gid via separate tables that are searched +with the recipient's mail address. Maildir style delivery is turned +on by terminating the mailbox pathname with "/".</p> + +<p> If you find the idea of multiple tables bothersome, remember +that you can migrate the information (once it works), to an SQL +database. If you take that route, be sure to review the <a +href="#local_vs_database"> "local files versus databases"</a> +section at the top of this document.</p> + +<p> Here is an example of a virtual mailbox domain "example.com": +</p> + +<blockquote> +<pre> + 1 /etc/postfix/main.cf: + 2 virtual_mailbox_domains = example.com ...more domains... + 3 virtual_mailbox_base = /var/mail/vhosts + 4 virtual_mailbox_maps = hash:/etc/postfix/vmailbox + 5 virtual_minimum_uid = 100 + 6 virtual_uid_maps = static:5000 + 7 virtual_gid_maps = static:5000 + 8 virtual_alias_maps = hash:/etc/postfix/virtual + 9 +10 /etc/postfix/vmailbox: +11 info@example.com example.com/info +12 sales@example.com example.com/sales/ +13 # Comment out the entry below to implement a catch-all. +14 # @example.com example.com/catchall +15 ...virtual mailboxes for more domains... +16 +17 /etc/postfix/virtual: +18 postmaster@example.com postmaster +</pre> +</blockquote> + +<p> Notes: </p> + +<ul> + +<li> <p> Line 2: The virtual_mailbox_domains setting tells Postfix +that example.com is a so-called virtual mailbox domain. If you omit +this setting then Postfix will reject mail (relay access denied) +or will not be able to deliver it (mail for example.com loops back +to myself). </p> + +<p> NEVER list a virtual MAILBOX domain name as a mydestination +domain! </p> + +<p> NEVER list a virtual MAILBOX domain name as a virtual ALIAS +domain! </p> + +<li> <p> Line 3: The virtual_mailbox_base parameter specifies a +prefix for all virtual mailbox pathnames. This is a safety mechanism +in case someone makes a mistake. It prevents mail from being +delivered all over the file system. </p> + +<li> <p> Lines 4, 10-15: The virtual_mailbox_maps parameter specifies +the lookup table with mailbox (or maildir) pathnames, indexed by +the virtual mail address. In this example, mail for info@example.com +goes to the mailbox at /var/mail/vhosts/example.com/info while mail +for sales@example.com goes to the maildir located at +/var/mail/vhosts/example.com/sales/. </p> + +<li> <p> Line 5: The virtual_minimum_uid specifies a lower bound +on the mailbox or maildir owner's UID. This is a safety mechanism +in case someone makes a mistake. It prevents mail from being written +to sensitive files. </p> + +<li> <p> Lines 6, 7: The virtual_uid_maps and virtual_gid_maps +parameters specify that all the virtual mailboxes are owned by a +fixed uid and gid 5000. If this is not what you want, specify +lookup tables that are searched by the recipient's mail address. +</p> + +<li> <p> Line 14: The commented out entry (text after #) shows how +one would implement a catch-all virtual mailbox address. Be prepared +to receive a lot of spam, as well as bounced spam that was sent in +the name of anything@example.com. </p> + +<p> NEVER put a virtual MAILBOX wild-card in the virtual ALIAS +file!! </p> + +<li> <p> Lines 8, 17, 18: As you see, it is possible to mix virtual +aliases with virtual mailboxes. We use this feature to redirect +mail for example.com's postmaster address to the local postmaster. +You can use the same mechanism to redirect an address to a remote +address. </p> + +<li> <p> Line 18: This example assumes that in main.cf, $myorigin +is listed under the mydestination parameter setting. If that is +not the case, specify an explicit domain name on the right-hand +side of the virtual alias table entries or else mail will go to +the wrong domain. </p> + +</ul> + +<p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after +changing the virtual file, execute "<b>postmap /etc/postfix/vmailbox</b>" +after changing the vmailbox file, and execute the command "<b>postfix +reload</b>" after changing the main.cf file. </p> + +<p> Note: mail delivery happens with the recipient's UID/GID +privileges specified with virtual_uid_maps and virtual_gid_maps. +Postfix 2.0 and earlier will not create mailDIRs in world-writable +parent directories; you must create them in advance before you can +use them. Postfix may be able to create mailBOX files by itself, +depending on parent directory write permissions, but it is safer +to create mailBOX files ahead of time. </p> + +<p> More details about the virtual mailbox delivery agent are given +in the virtual(8) manual page. </p> + +<h2><a name="in_virtual_other">Non-Postfix mailbox store: separate +domains, non-UNIX accounts</a></h2> + +<p> This is a variation on the Postfix virtual mailbox example. +Again, every hosted address can have its own mailbox. However, most +parameters that control the virtual(8) delivery agent are no longer +applicable: only virtual_mailbox_domains and virtual_mailbox_maps +stay in effect. These parameters are needed to reject mail for +unknown recipients. </p> + +<p> While non-Postfix software is being used for final delivery, +some Postfix concepts are still needed in order to glue everything +together. For additional background on this glue you may want to +take a look at the virtual mailbox domain class as defined in the +ADDRESS_CLASS_README file. </p> + +<p> The text in this section describes what things should look like +from Postfix's point of view. See CYRUS_README or MAILDROP_README +for specific information about Cyrus or about Courier maildrop. +</p> + +<p> Here is an example for a hosted domain example.com that delivers +to a non-Postfix delivery agent: </p> + +<blockquote> +<pre> + 1 /etc/postfix/main.cf: + 2 virtual_transport = ...see below... + 3 virtual_mailbox_domains = example.com ...more domains... + 4 virtual_mailbox_maps = hash:/etc/postfix/vmailbox + 5 virtual_alias_maps = hash:/etc/postfix/virtual + 6 + 7 /etc/postfix/vmailbox: + 8 info@example.com whatever + 9 sales@example.com whatever +10 # Comment out the entry below to implement a catch-all. +11 # Configure the mailbox store to accept all addresses. +12 # @example.com whatever +13 ...virtual mailboxes for more domains... +14 +15 /etc/postfix/virtual: +16 postmaster@example.com postmaster +</pre> +</blockquote> + +<p> Notes: </p> + +<ul> + +<li> <p> Line 2: With delivery to a non-Postfix mailbox store for +hosted domains, the virtual_transport parameter usually specifies +the Postfix LMTP client, or the name of a master.cf entry that +executes non-Postfix software via the pipe delivery agent. Typical +examples (use only one): </p> + +<blockquote> +<pre> +virtual_transport = lmtp:unix:/path/name (uses UNIX-domain socket) +virtual_transport = lmtp:hostname:port (uses TCP socket) +virtual_transport = maildrop: (uses pipe(8) to command) +</pre> +</blockquote> + +<p> Postfix comes ready with support for LMTP. And an example +maildrop delivery method is already defined in the default Postfix +master.cf file. See the MAILDROP_README document for more details. +</p> + +<li> <p> Line 3: The virtual_mailbox_domains setting tells Postfix +that example.com is delivered via the virtual_transport that was +discussed in the previous paragraph. If you omit this +virtual_mailbox_domains setting then Postfix will either reject +mail (relay access denied) or will not be able to deliver it (mail +for example.com loops back to myself). </p> + +<p> NEVER list a virtual MAILBOX domain name as a mydestination +domain! </p> + +<p> NEVER list a virtual MAILBOX domain name as a virtual ALIAS +domain! </p> + +<li> <p> Lines 4, 7-13: The virtual_mailbox_maps parameter specifies +the lookup table with all valid recipient addresses. The lookup +result value is ignored by Postfix. In the above example, +info@example.com +and sales@example.com are listed as valid addresses; other mail for +example.com is rejected with "User unknown" by the Postfix SMTP +server. It's left up to the non-Postfix delivery agent to reject +non-existent recipients from local submission or from local alias +expansion. If you intend to +use LDAP, MySQL or PgSQL instead of local files, be sure to review +the <a href="#local_vs_database"> "local files versus databases"</a> +section at the top of this document! </p> + +<li> <p> Line 12: The commented out entry (text after #) shows how +one would inform Postfix of the existence of a catch-all address. +Again, the lookup result is ignored by Postfix. </p> + +<p> NEVER put a virtual MAILBOX wild-card in the virtual ALIAS +file!! </p> + +<p> Note: if you specify a wildcard in virtual_mailbox_maps, then +you still need to configure the non-Postfix mailbox store to receive +mail for any address in that domain. </p> + +<li> <p> Lines 5, 15, 16: As you see above, it is possible to mix +virtual aliases with virtual mailboxes. We use this feature to +redirect mail for example.com's postmaster address to the local +postmaster. You can use the same mechanism to redirect any addresses +to a local or remote address. </p> + +<li> <p> Line 16: This example assumes that in main.cf, $myorigin +is listed under the mydestination parameter setting. If that is +not the case, specify an explicit domain name on the right-hand +side of the virtual alias table entries or else mail will go to +the wrong domain. </p> + +</ul> + +<p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after +changing the virtual file, execute "<b>postmap /etc/postfix/vmailbox</b>" +after changing the vmailbox file, and execute the command "<b>postfix +reload</b>" after changing the main.cf file. </p> + +<h2><a name="forwarding">Mail forwarding domains</a></h2> + +<p> Some providers host domains that have no (or only a few) local +mailboxes. The main purpose of these domains is to forward mail +elsewhere. The following example shows how to set up example.com +as a mail forwarding domain: </p> + +<blockquote> +<pre> + 1 /etc/postfix/main.cf: + 2 virtual_alias_domains = example.com ...other hosted domains... + 3 virtual_alias_maps = hash:/etc/postfix/virtual + 4 + 5 /etc/postfix/virtual: + 6 postmaster@example.com postmaster + 7 joe@example.com joe@somewhere + 8 jane@example.com jane@somewhere-else + 9 # Uncomment entry below to implement a catch-all address +10 # @example.com jim@yet-another-site +11 ...virtual aliases for more domains... +</pre> +</blockquote> + +<p> Notes: </p> + +<ul> + +<li> <p> Line 2: The virtual_alias_domains setting tells Postfix +that example.com is a so-called virtual alias domain. If you omit +this setting then Postfix will reject mail (relay access denied) +or will not be able to deliver it (mail for example.com loops back +to myself). </p> + +<p> NEVER list a virtual alias domain name as a mydestination +domain! </p> + +<li> <p> Lines 3-11: The /etc/postfix/virtual file contains the +virtual aliases. With the example above, mail for postmaster@example.com +goes to the local postmaster, while mail for joe@example.com goes +to the remote address joe@somewhere, and mail for jane@example.com +goes to the remote address jane@somewhere-else. Mail for all other +addresses in example.com is rejected with the error message "User +unknown". </p> + +<li> <p> Line 10: The commented out entry (text after #) shows how +one would implement a catch-all virtual alias that receives mail +for every example.com address not listed in the virtual alias file. +This is not without risk. Spammers nowadays try to send mail from +(or mail to) every possible name that they can think of. A catch-all +mailbox is likely to receive many spam messages, and many bounces +for spam messages that were sent in the name of anything@example.com. +</p> + +</ul> + +<p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after +changing the virtual file, and execute the command "<b>postfix +reload</b>" after changing the main.cf file. </p> + +<p> More details about the virtual alias file are given in the +virtual(5) manual page, including multiple addresses on the right-hand +side. </p> + +<h2><a name="mailing_lists">Mailing lists</a></h2> + +<p> The examples that were given above already show how to direct +mail for virtual postmaster addresses to a local postmaster. You +can use the same method to direct mail for any address to a local +or remote address. </p> + +<p> There is one major limitation: virtual aliases and virtual +mailboxes can't directly deliver to mailing list managers such as +majordomo. The solution is to set up virtual aliases that direct +virtual addresses to the local delivery agent: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + virtual_alias_maps = hash:/etc/postfix/virtual + +/etc/postfix/virtual: + listname-request@example.com listname-request + listname@example.com listname + owner-listname@example.com owner-listname + +/etc/aliases: + listname: "|/some/where/majordomo/wrapper ..." + owner-listname: ... + listname-request: ... +</pre> +</blockquote> + +<p> This example assumes that in main.cf, $myorigin is listed under +the mydestination parameter setting. If that is not the case, +specify an explicit domain name on the right-hand side of the +virtual alias table entries or else mail will go to the wrong +domain. </p> + +<p> More information about the Postfix local delivery agent can be +found in the local(8) manual page. </p> + +<p> Why does this example use a clumsy virtual alias instead of a +more elegant transport mapping? The reason is that mail for the +virtual mailing list would be rejected with "User unknown". In +order to make the transport mapping work one would still need a +bunch of virtual alias or virtual mailbox table entries. </p> + +<ul> + +<li> In case of a virtual alias domain, there would need to be one +identity mapping from each mailing list address to itself. + +<li> In case of a virtual mailbox domain, there would need to be +a dummy mailbox for each mailing list address. + +</ul> + +<h2><a name="autoreplies">Autoreplies</a></h2> + +<p> In order to set up an autoreply for virtual recipients while +still delivering mail as normal, set up a rule in a virtual alias +table: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + virtual_alias_maps = hash:/etc/postfix/virtual + +/etc/postfix/virtual: + user@domain.tld user@domain.tld, user@domain.tld@autoreply.mydomain.tld +</pre> +</blockquote> + +<p> This delivers mail to the recipient, and sends a copy of the +mail to the address that produces automatic replies. The address +can be serviced on a different machine, or it can be serviced +locally by setting up a transport map entry that pipes all mail +for autoreply.mydomain.tld into some script that sends an automatic +reply back to the sender. </p> + +<p> DO NOT list autoreply.mydomain.tld in mydestination! </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + transport_maps = hash:/etc/postfix/transport + +/etc/postfix/transport: + autoreply.mydomain.tld autoreply: + +/etc/postfix/master.cf: + # ============================================================= + # service type private unpriv chroot wakeup maxproc command + # (yes) (yes) (yes) (never) (100) + # ============================================================= + autoreply unix - n n - - pipe + flags= user=nobody argv=/path/to/autoreply $sender $mailbox +</pre> +</blockquote> + +<p> This invokes /path/to/autoreply with the sender address and +the user@domain.tld recipient address on the command line. </p> + +<p> For more information, see the pipe(8) manual page, and the +comments in the Postfix master.cf file. </p> + +</body> + +</html> diff --git a/proto/XCLIENT_README.html b/proto/XCLIENT_README.html new file mode 100644 index 0000000..6393c09 --- /dev/null +++ b/proto/XCLIENT_README.html @@ -0,0 +1,267 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix XCLIENT Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix XCLIENT Howto</h1> + +<hr> + +<h2>Purpose of the XCLIENT extension to SMTP</h2> + +<p> When an SMTP server announces support for the XCLIENT command, +an SMTP client may send information that overrides one or more +client-related session attributes. The XCLIENT command targets the +following problems: </p> + +<ol> + + <li> <p> Access control tests. SMTP server access rules are + difficult to verify when decisions can be triggered only by + remote clients. In order to facilitate access rule testing, + an authorized SMTP client test program needs the ability to + override the SMTP server's idea of the SMTP client hostname, + network address, and other client information, for the entire + duration of an SMTP session. </p> + + <li> <p> Client software that downloads mail from an up-stream + mail server and injects it into a local MTA via SMTP. In order + to take advantage of the local MTA's SMTP server access rules, + the client software needs the ability to override the SMTP + server's idea of the remote client name, client address and + other information. Such information can typically be extracted + from the up-stream mail server's Received: message header. </p> + + <li> <p> Post-filter access control and logging. With + Internet->filter->MTA style content filter applications, + the filter can be simplified if it can delegate decisions + concerning mail relay and other access control to the MTA. This + is especially useful when the filter acts as a transparent + proxy for SMTP commands. This requires that the filter can + override the MTA's idea of the SMTP client hostname, network + address, and other information. </p> + +</ol> + +<h2>XCLIENT Command syntax</h2> + +<p> An example client-server conversation is given at the end +of this document. </p> + +<p> In SMTP server EHLO replies, the keyword associated with this +extension is XCLIENT. It is followed by the names of the attributes +that the XCLIENT implementation supports. </p> + +<p> The XCLIENT command may be sent at any time, except in the +middle of a mail delivery transaction (i.e. between MAIL and DOT, +or MAIL and RSET). The XCLIENT command may be pipelined when the +server supports ESMTP command pipelining. To avoid triggering +spamware detectors, the command should be sent at the end of a +command group. </p> + +<p> The syntax of XCLIENT requests is described below. Upper case +and quoted strings specify terminals, lowercase strings specify +meta terminals, and SP is whitespace. Although command and attribute +names are shown in upper case, they are in fact case insensitive. +</p> + +<blockquote> +<p> + xclient-command = XCLIENT 1*( SP attribute-name"="attribute-value ) +</p> +<p> + attribute-name = ( NAME | ADDR | PORT | PROTO | HELO | LOGIN | DESTADDR | DESTPORT ) +</p> +<p> + attribute-value = xtext +</p> +</blockquote> + +<ul> + + <li> <p> Attribute values are xtext encoded as per RFC 1891. + </p> + + <li> <p> The NAME attribute specifies a remote SMTP client + hostname (not an SMTP client address), [UNAVAILABLE] when client + hostname lookup failed due to a permanent error, or [TEMPUNAVAIL] + when the lookup error condition was transient. </p> + + <li> <p> The ADDR attribute specifies a remote SMTP client + numerical IPv4 network address, an IPv6 address prefixed with + IPV6:, or [UNAVAILABLE] when the address information is + unavailable. Address information is not enclosed with []. </p> + + <li> <p> The PORT attribute specifies a remote SMTP client TCP + port number as a decimal number, or [UNAVAILABLE] when the + information is unavailable. </p> + + <li> <p> The PROTO attribute specifies either SMTP or ESMTP. + </p> + + <li> <p> The DESTADDR attribute specifies a local SMTP server + numerical IPv4 network address, an IPv6 address prefixed with + IPV6:, or [UNAVAILABLE] when the address information is + unavailable. Address information is not enclosed with []. </p> + + <li> <p> The DESTPORT attribute specifies a local SMTP server + TCP port number as a decimal number, or [UNAVAILABLE] when the + information is unavailable. </p> + + <li> <p> The HELO attribute specifies an SMTP HELO parameter + value, or the value [UNAVAILABLE] when the information is + unavailable. </p> + + <li> <p> The LOGIN attribute specifies a SASL login name, or + the value [UNAVAILABLE] when the information is unavailable. + </p> + +</ul> + +<p> Note 1: syntactically valid NAME and HELO attribute-value +elements can be up to 255 characters long. The client must not send +XCLIENT commands that exceed the 512 character limit for SMTP +commands. To avoid exceeding the limit the client should send the +information in multiple XCLIENT commands; for example, send NAME +and ADDR last, after HELO and PROTO. Once ADDR is sent, the client +is usually no longer authorized to send XCLIENT commands. </p> + +<p> Note 2: [UNAVAILABLE], [TEMPUNAVAIL] and IPV6: may be specified +in upper case, lower case or mixed case. </p> + +<p> Note 3: Postfix implementations prior to version 2.3 do not +xtext encode attribute values. Servers that wish to interoperate +with these older implementations should be prepared to receive +unencoded information. </p> + +<p> Note 4: Some Postfix implementations do not implement the PORT +or LOGIN attributes. </p> + +<h2>XCLIENT Server response</h2> + +<p> Upon receipt of a correctly formatted XCLIENT command, the +server resets state to the initial SMTP greeting protocol stage. +Depending on the outcome of optional access decisions, the server +responds with 220 or with a suitable rejection code. + +<p> For practical reasons it is not always possible to reset the +complete server state to the initial SMTP greeting protocol stage: +</p> + +<ul> + +<li> <p> TLS session information may not be reset, because turning off +TLS leaves the connection in an undefined state. Consequently, the +server may not announce STARTTLS when TLS is already active, and +access decisions may be influenced by client certificate information +that was received prior to the XCLIENT command. </p> + +<li> <p> The SMTP server must not reset attributes that were received +with the last XCLIENT command. This includes HELO or PROTO attributes. +</p> + +</ul> + +<p> NOTE: Postfix implementations prior to version 2.3 do not jump +back to the initial SMTP greeting protocol stage. These older +implementations will not correctly simulate connection-level access +decisions under some conditions. </p> + +<h2> XCLIENT server reply codes </h2> + +<blockquote> + +<table border="1" bgcolor="#f0f0ff"> + +<tr> <th> Code </th> <th> Meaning </th> </tr> + +<tr> <td> 220 </td> <td> success </td> </tr> + +<tr> <td> 421 </td> <td> unable to proceed, disconnecting </td> </tr> + +<tr> <td> 501 </td> <td> bad command parameter syntax </td> </tr> + +<tr> <td> 503 </td> <td> mail transaction in progress </td> </tr> + +<tr> <td> 550 </td> <td> insufficient authorization </td> </tr> + +<tr> <td> other </td> <td> connection rejected by connection-level +access decision </td> </tr> + +</table> + +</blockquote> + +<h2>XCLIENT Example</h2> + +<p> In the example, the client impersonates a mail originating +system by passing all SMTP client information via the XCLIENT +command. Information sent by the client is shown in bold font. +</p> + +<blockquote> +<pre> +220 server.example.com ESMTP Postfix +<b>EHLO client.example.com</b> +250-server.example.com +250-PIPELINING +250-SIZE 10240000 +250-VRFY +250-ETRN +250-XCLIENT NAME ADDR PROTO HELO +250 8BITMIME +<b>XCLIENT NAME=spike.porcupine.org ADDR=168.100.189.2</b> +220 server.example.com ESMTP Postfix +<b>EHLO spike.porcupine.org</b> +250-server.example.com +250-PIPELINING +250-SIZE 10240000 +250-VRFY +250-ETRN +250-XCLIENT NAME ADDR PROTO HELO +250 8BITMIME +<b>MAIL FROM:<wietse@porcupine.org></b> +250 Ok +<b>RCPT TO:<user@example.com></b> +250 Ok +<b>DATA</b> +354 End data with <CR><LF>.<CR><LF> +<b>. . .<i>message content</i>. . .</b> +<b>.</b> +250 Ok: queued as 763402AAE6 +<b>QUIT</b> +221 Bye +</pre> +</blockquote> + +<h2>Security</h2> + +<p> The XCLIENT command changes audit trails and/or SMTP client +access permissions. Use of this command must be restricted to +authorized SMTP clients. </p> + +<h2>SMTP connection caching</h2> + +<p> XCLIENT attributes persist until the end of an SMTP session. +If one session is used to deliver mail on behalf of different SMTP +clients, the XCLIENT attributes need to be reset as appropriate +before each MAIL FROM command. </p> + +<h2> References </h2> + +<p> Moore, K, "SMTP Service Extension for Delivery Status Notifications", +RFC 1891, January 1996. </p> + +</body> + +</html> diff --git a/proto/XFORWARD_README.html b/proto/XFORWARD_README.html new file mode 100644 index 0000000..1165e98 --- /dev/null +++ b/proto/XFORWARD_README.html @@ -0,0 +1,241 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix XFORWARD Howto</title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix XFORWARD Howto</h1> + +<hr> + +<h2>Purpose of the XFORWARD extension to SMTP</h2> + +<p> When an SMTP server announces support for the XFORWARD command, +an SMTP client may send information that overrides one or more +client-related logging attributes. The XFORWARD command targets +the following problem: </p> + +<ul> + + <li> <p> Logging after SMTP-based content filter. With the + deployment of Internet->MTA1->filter->MTA2 style + content filter applications, the logging of client and message + identifying information changes when MTA1 gives the mail to + the content filter. To simplify the interpretation of MTA2 + logging, it would help if MTA1 could forward remote client + and/or message identifying information through the content + filter to MTA2, so that the information could be logged as part + of mail handling transactions. </p> + +</ul> + +<p> This extension is implemented as a separate ESMTP command, and +can be used to transmit client or message attributes incrementally. +It is not implemented by passing additional parameters via the MAIL +FROM command, because doing so would require extending the MAIL +FROM command length limit by another 600 or more characters beyond +the space that is already needed to support other extensions such +as AUTH and DSN. </p> + +<h2>XFORWARD Command syntax</h2> + +<p> An example of a client-server conversation is given at the end +of this document. </p> + +<p> In SMTP server EHLO replies, the keyword associated with this +extension is XFORWARD. The keyword is followed by the names of the +attributes that the XFORWARD implementation supports. </p> + +<p> After receiving the server's announcement for XFORWARD support, +the client may send XFORWARD requests at any time except in +the middle of a mail delivery transaction (i.e. between MAIL and +RSET or DOT). The command may be pipelined when the server supports +ESMTP command pipelining. </p> + +<p> The syntax of XFORWARD requests is described below. Upper case +and quoted strings specify terminals, lowercase strings specify +meta terminals, and SP is whitespace. Although command and attribute +names are shown in upper case, they are in fact case insensitive. +</p> + +<blockquote> +<p> + xforward-command = XFORWARD 1*( SP attribute-name"="attribute-value ) +</p> +<p> + attribute-name = ( NAME | ADDR | PORT | PROTO | HELO | IDENT | SOURCE ) +</p> +<p> + attribute-value = xtext +</p> +</blockquote> + +<ul> + + <li> <p> Attribute values are xtext encoded as per RFC 1891. + </p> + + <li> <p> The NAME attribute specifies the up-stream hostname, + or [UNAVAILABLE] when the information is unavailable. The + hostname may be a non-DNS hostname. </p> + + <li> <p> The ADDR attribute specifies the up-stream network + address: a numerical IPv4 network address, an IPv6 address + prefixed with IPV6:, or [UNAVAILABLE] when the address information + is unavailable. Address information is not enclosed with []. + </p> + + <li> <p> The PORT attribute specifies an up-stream client TCP + port number in decimal, or [UNAVAILABLE] when the information + is unavailable. </p> + + <li> <p> The PROTO attribute specifies the mail protocol for + receiving mail from the up-stream host. This may be an SMTP or + non-SMTP protocol name of up to 64 characters, or [UNAVAILABLE] + when the information is unavailable. </p> + + <li> <p> The HELO attribute specifies the hostname that the + up-stream host announced itself with (not necessarily via the + SMTP HELO command), or [UNAVAILABLE] when the information is + unavailable. The hostname may be a non-DNS hostname. </p> + + <li> <p> The IDENT attribute specifies a local message identifier + on the up-stream host, or [UNAVAILABLE] when the information + is unavailable. The down-stream MTA may log this information + together with its own local message identifier to facilitate + message tracking across MTAs. </p> + + <li> <p> The SOURCE attribute specifies LOCAL when the message + was received from a source that is local with respect to the + up-stream host (for example, the message originated from the + up-stream host itself), REMOTE for all other mail, or [UNAVAILABLE] + when the information is unavailable. The down-stream MTA may + decide to enable features such as header munging or address + qualification with mail from local sources but not other sources. + </p> + +</ul> + +<p> Note 1: an attribute-value element must not be longer than +255 characters (specific attributes may impose shorter lengths). +After xtext decoding, attribute values must not contain control +characters, non-ASCII characters, whitespace, or other characters +that are special in message headers. </p> + +<p> Note 2: DNS hostnames can be up to 255 characters long. The +XFORWARD client implementation must not send XFORWARD commands that +exceed the 512 character limit for SMTP commands. </p> + +<p> Note 3: [UNAVAILABLE] may be specified in upper case, lower +case or mixed case. </p> + +<p> Note 4: Postfix implementations prior to version 2.3 do not +xtext encode attribute values. Servers that wish to interoperate +with these older implementations should be prepared to receive +unencoded information. </p> + +<h2> XFORWARD Server operation </h2> + +<p> The server maintains a set of XFORWARD attributes with forwarded +information, in addition the current SMTP session attributes. +Normally, all XFORWARD attributes are in the undefined state, and +the server uses the current SMTP session attributes for logging +purposes. </p> + +<p> Upon receipt of an initial XFORWARD command, the SMTP server +initializes all XFORWARD attributes to [UNAVAILABLE]. With each +valid XFORWARD command, the server updates XFORWARD attributes with +the specified values. </p> + +<p> The server must not mix client attributes from XFORWARD with +client attributes from the current SMTP session. </p> + +<p> At the end of each MAIL FROM transaction (i.e. RSET or DOT), +the server resets all XFORWARD attributes to the undefined state, +and is ready to receive another initial XFORWARD command. </p> + +<h2> XFORWARD Server reply codes </h2> + +<blockquote> + +<table bgcolor="#f0f0ff" border="1"> + +<tr> <th> Code </th> <th> Meaning </th> </tr> + +<tr> <td> 250 </td> <td> success </td> </tr> + +<tr> <td> 421 </td> <td> unable to proceed, disconnecting </td> </tr> + +<tr> <td> 501 </td> <td> bad command parameter syntax </td> </tr> + +<tr> <td> 503 </td> <td> mail transaction in progress </td> </tr> + +<tr> <td> 550 </td> <td> insufficient authorization </td> </tr> + +</table> + +</blockquote> + +<h2>XFORWARD Example</h2> + +<p> In the following example, information sent by the client is +shown in bold font. </p> + +<blockquote> +<pre> +220 server.example.com ESMTP Postfix +<b>EHLO client.example.com</b> +250-server.example.com +250-PIPELINING +250-SIZE 10240000 +250-VRFY +250-ETRN +250-XFORWARD NAME ADDR PROTO HELO +250 8BITMIME +<b>XFORWARD NAME=spike.porcupine.org ADDR=168.100.189.2 PROTO=ESMTP </b> +250 Ok +<b>XFORWARD HELO=spike.porcupine.org</b> +250 Ok +<b>MAIL FROM:<wietse@porcupine.org></b> +250 Ok +<b>RCPT TO:<user@example.com></b> +250 Ok +<b>DATA</b> +354 End data with <CR><LF>.<CR><LF> +<b>. . .<i>message content</i>. . .</b> +<b>.</b> +250 Ok: queued as 3CF6B2AAE8 +<b>QUIT</b> +221 Bye +</pre> +</blockquote> + +<h2>Security</h2> + +<p> The XFORWARD command changes audit trails. Use of this command +must be restricted to authorized clients. </p> + +<h2>SMTP connection caching</h2> + +<p> SMTP connection caching makes it possible to deliver multiple +messages within the same SMTP session. The XFORWARD attributes are +reset after the MAIL FROM transaction completes (after RSET or DOT), +so there is no risk of information leakage. </p> + +<h2> References </h2> + +<p> Moore, K, "SMTP Service Extension for Delivery Status Notifications", +RFC 1891, January 1996. </p> + +</body> + +</html> diff --git a/proto/access b/proto/access new file mode 100644 index 0000000..0fe2a89 --- /dev/null +++ b/proto/access @@ -0,0 +1,468 @@ +#++ +# NAME +# access 5 +# SUMMARY +# Postfix SMTP server access table +# SYNOPSIS +# \fBpostmap /etc/postfix/access\fR +# +# \fBpostmap -q "\fIstring\fB" /etc/postfix/access\fR +# +# \fBpostmap -q - /etc/postfix/access <\fIinputfile\fR +# DESCRIPTION +# This document describes access control on remote SMTP client +# information: host names, network addresses, and envelope +# sender or recipient addresses; it is implemented by the +# Postfix SMTP server. See \fBheader_checks\fR(5) or +# \fBbody_checks\fR(5) for access control on the content of +# email messages. +# +# Normally, the \fBaccess\fR(5) table is specified as a text file +# that serves as input to the \fBpostmap\fR(1) command. +# The result, an indexed file in \fBdbm\fR or \fBdb\fR format, +# is used for fast searching by the mail system. Execute the +# command "\fBpostmap /etc/postfix/access\fR" to rebuild an +# indexed file after changing the corresponding text file. +# +# When the table is provided via other means such as NIS, LDAP +# or SQL, the same lookups are done as for ordinary indexed files. +# +# Alternatively, the table can be provided as a regular-expression +# map where patterns are given as regular expressions, or lookups +# can be directed to a TCP-based server. In those cases, the lookups +# are done in a slightly different way as described below under +# "REGULAR EXPRESSION TABLES" or "TCP-BASED TABLES". +# CASE FOLDING +# .ad +# .fi +# The search string is folded to lowercase before database +# lookup. As of Postfix 2.3, the search string is not case +# folded with database types such as regexp: or pcre: whose +# lookup fields can match both upper and lower case. +# TABLE FORMAT +# .ad +# .fi +# The input format for the \fBpostmap\fR(1) command is as follows: +# .IP "\fIpattern action\fR" +# When \fIpattern\fR matches a mail address, domain or host address, +# perform the corresponding \fIaction\fR. +# .IP "blank lines and comments" +# Empty lines and whitespace-only lines are ignored, as +# are lines whose first non-whitespace character is a `#'. +# .IP "multi-line text" +# A logical line starts with non-whitespace text. A line that +# starts with whitespace continues a logical line. +# EMAIL ADDRESS PATTERNS +# .ad +# .fi +# With lookups from indexed files such as DB or DBM, or from networked +# tables such as NIS, LDAP or SQL, patterns are tried in the order as +# listed below: +# .IP \fIuser\fR@\fIdomain\fR +# Matches the specified mail address. +# .IP \fIdomain.tld\fR +# Matches \fIdomain.tld\fR as the domain part of an email address. +# .sp +# The pattern \fIdomain.tld\fR also matches subdomains, but only +# when the string \fBsmtpd_access_maps\fR is listed in the Postfix +# \fBparent_domain_matches_subdomains\fR configuration setting. +# .IP \fI.domain.tld\fR +# Matches subdomains of \fIdomain.tld\fR, but only when the +# string \fBsmtpd_access_maps\fR is not listed in the Postfix +# \fBparent_domain_matches_subdomains\fR configuration setting. +# .IP \fIuser\fR@ +# Matches all mail addresses with the specified user part. +# .PP +# Note: lookup of the null sender address is not possible with +# some types of lookup table. By default, Postfix uses \fB<>\fR +# as the lookup key for such addresses. The value is specified with +# the \fBsmtpd_null_access_lookup_key\fR parameter in the Postfix +# \fBmain.cf\fR file. +# EMAIL ADDRESS EXTENSION +# .fi +# .ad +# When a mail address localpart contains the optional recipient delimiter +# (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes: +# \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIdomain\fR, +# \fIuser+foo\fR@, and \fIuser\fR@. +# HOST NAME/ADDRESS PATTERNS +# .ad +# .fi +# With lookups from indexed files such as DB or DBM, or from networked +# tables such as NIS, LDAP or SQL, the following lookup patterns are +# examined in the order as listed: +# .IP \fIdomain.tld\fR +# Matches \fIdomain.tld\fR. +# .sp +# The pattern \fIdomain.tld\fR also matches subdomains, but only +# when the string \fBsmtpd_access_maps\fR is listed in the Postfix +# \fBparent_domain_matches_subdomains\fR configuration setting. +# .IP \fI.domain.tld\fR +# Matches subdomains of \fIdomain.tld\fR, but only when the +# string \fBsmtpd_access_maps\fR is not listed in the Postfix +# \fBparent_domain_matches_subdomains\fR configuration setting. +# .IP \fInet.work.addr.ess\fR +# .IP \fInet.work.addr\fR +# .IP \fInet.work\fR +# .IP \fInet\fR +# Matches a remote IPv4 host address or network address range. +# Specify one to four decimal octets separated by ".". Do not +# specify "[]" , "/", leading zeros, or hexadecimal forms. +# +# Network ranges are matched by repeatedly truncating the last +# ".octet" from a remote IPv4 host address string, until a +# match is found in the access table, or until further +# truncation is not possible. +# +# NOTE: use the \fBcidr\fR lookup table type to specify +# network/netmask patterns. See \fBcidr_table\fR(5) for details. +# .IP \fInet:work:addr:ess\fR +# .IP \fInet:work:addr\fR +# .IP \fInet:work\fR +# .IP \fInet\fR +# Matches a remote IPv6 host address or network address range. +# Specify three to eight hexadecimal octet pairs separated +# by ":", using the compressed form "::" for a sequence of +# zero-valued octet pairs. Do not specify "[]", "/", leading +# zeros, or non-compressed forms. +# +# A network range is matched by repeatedly truncating the +# last ":octetpair" from the compressed-form remote IPv6 host +# address string, until a match is found in the access table, +# or until further truncation is not possible. +# +# NOTE: use the \fBcidr\fR lookup table type to specify +# network/netmask patterns. See \fBcidr_table\fR(5) for details. +# +# IPv6 support is available in Postfix 2.2 and later. +# ACCEPT ACTIONS +# .ad +# .fi +# .IP \fBOK\fR +# Accept the address etc. that matches the pattern. +# .IP \fIall-numerical\fR +# An all-numerical result is treated as OK. This format is +# generated by address-based relay authorization schemes +# such as pop-before-smtp. +# .PP +# For other accept actions, see "OTHER ACTIONS" below. +# REJECT ACTIONS +# .ad +# .fi +# Postfix version 2.3 and later support enhanced status codes +# as defined in RFC 3463. +# When no code is specified at the beginning of the \fItext\fR +# below, Postfix inserts a default enhanced status code of "5.7.1" +# in the case of reject actions, and "4.7.1" in the case of +# defer actions. See "ENHANCED STATUS CODES" below. +# .IP "\fB4\fINN text\fR" +# .IP "\fB5\fINN text\fR" +# Reject the address etc. that matches the pattern, and respond with +# the numerical three-digit code and text. \fB4\fINN\fR means "try +# again later", while \fB5\fINN\fR means "do not try again". +# +# The following responses have special meaning for the Postfix +# SMTP server: +# .RS +# .IP "\fB421 \fItext\fR (Postfix 2.3 and later)" +# .IP "\fB521 \fItext\fR (Postfix 2.6 and later)" +# After responding with the numerical three-digit code and +# text, disconnect immediately from the SMTP client. This +# frees up SMTP server resources so that they can be made +# available to another SMTP client. +# .IP +# Note: The "521" response should be used only with botnets +# and other malware where interoperability is of no concern. +# The "send 521 and disconnect" behavior is NOT defined in +# the SMTP standard. +# .RE +# .IP "\fBREJECT \fIoptional text...\fR +# Reject the address etc. that matches the pattern. Reply with +# "\fB$access_map_reject_code \fIoptional text...\fR" when the +# optional text is +# specified, otherwise reply with a generic error response message. +# .IP "\fBDEFER \fIoptional text...\fR +# Reject the address etc. that matches the pattern. Reply with +# "\fB$access_map_defer_code \fIoptional text...\fR" when the +# optional text is +# specified, otherwise reply with a generic error response message. +# .sp +# This feature is available in Postfix 2.6 and later. +# .IP "\fBDEFER_IF_REJECT \fIoptional text...\fR +# Defer the request if some later restriction would result in a +# REJECT action. Reply with "\fB$access_map_defer_code 4.7.1 +# \fIoptional text...\fR" when the +# optional text is specified, otherwise reply with a generic error +# response message. +# .sp +# Prior to Postfix 2.6, the SMTP reply code is 450. +# .sp +# This feature is available in Postfix 2.1 and later. +# .IP "\fBDEFER_IF_PERMIT \fIoptional text...\fR +# Defer the request if some later restriction would result in +# an explicit or implicit PERMIT action. +# Reply with "\fB$access_map_defer_code 4.7.1 \fI optional +# text...\fR" when the +# optional text is specified, otherwise reply with a generic error +# response message. +# .sp +# Prior to Postfix 2.6, the SMTP reply code is 450. +# .sp +# This feature is available in Postfix 2.1 and later. +# .PP +# For other reject actions, see "OTHER ACTIONS" below. +# OTHER ACTIONS +# .ad +# .fi +# .IP \fIrestriction...\fR +# Apply the named UCE restriction(s) (\fBpermit\fR, \fBreject\fR, +# \fBreject_unauth_destination\fR, and so on). +# .IP "\fBBCC \fIuser@domain\fR" +# Send one copy of the message to the specified recipient. +# .sp +# If multiple BCC actions are specified within the same SMTP +# MAIL transaction, with Postfix 3.0 only the last action +# will be used. +# .sp +# This feature is available in Postfix 3.0 and later. +# \" .IP "\fBDELAY \fItime\fR" +# \" Place the message into the deferred queue, and delay the +# \" initial delivery attempt by \fItime\fR. The time value may +# \" be followed by a one-character suffix that specifies the +# \" time unit: s (seconds), m (minutes), h (hours), d (days), +# \" w (weeks). The default time unit is s (seconds). +# \" .sp +# \" Limitations: +# \" .RS +# \" .IP \(bu +# \" This action affects all the recipients of the message. +# \" .IP \(bu +# \" The delay value has no effect with remote file systems that +# \" don't correctly emulate UNIX local file system semantics. +# \" In that case, the delay will be half of $queue_run_delay +# \" on average. +# \" .IP \(bu +# \" Mail will still be delivered with "sendmail -q", "postfix +# \" flush" or "postqueue -f". +# \" .IP \(bu +# \" Delayed mail increases the amount of disk I/O during deferred +# \" queue scans. When large amounts of mail are queued for +# \" delayed delivery it may be preferable to use the HOLD feature +# \" instead. +# \" .RE +# \" .IP +# \" This feature is available in Postfix 2.3 and later. +# .IP "\fBDISCARD \fIoptional text...\fR +# Claim successful delivery and silently discard the message. +# Log the optional text if specified, otherwise log a generic +# message. +# .sp +# Note: this action currently affects all recipients of the message. +# To discard only one recipient without discarding the entire message, +# use the transport(5) table to direct mail to the discard(8) service. +# .sp +# This feature is available in Postfix 2.0 and later. +# .IP \fBDUNNO\fR +# Pretend that the lookup key was not found. This +# prevents Postfix from trying substrings of the lookup key +# (such as a subdomain name, or a network address subnetwork). +# .sp +# This feature is available in Postfix 2.0 and later. +# .IP "\fBFILTER \fItransport:destination\fR" +# After the message is queued, send the entire message through +# the specified external content filter. The \fItransport\fR +# name specifies the first field of a mail delivery agent +# definition in master.cf; the syntax of the next-hop +# \fIdestination\fR is described in the manual page of the +# corresponding delivery agent. More information about +# external content filters is in the Postfix FILTER_README +# file. +# .sp +# Note 1: do not use $\fInumber\fR regular expression +# substitutions for \fItransport\fR or \fIdestination\fR +# unless you know that the information has a trusted origin. +# .sp +# Note 2: this action overrides the main.cf \fBcontent_filter\fR +# setting, and affects all recipients of the message. In the +# case that multiple \fBFILTER\fR actions fire, only the last +# one is executed. +# .sp +# Note 3: the purpose of the FILTER command is to override +# message routing. To override the recipient's \fItransport\fR +# but not the next-hop \fIdestination\fR, specify an empty +# filter \fIdestination\fR (Postfix 2.7 and later), or specify +# a \fItransport:destination\fR that delivers through a +# different Postfix instance (Postfix 2.6 and earlier). Other +# options are using the recipient-dependent \fBtrans\%port\%_maps\fR +# or the sen\%der-dependent +# \fBsender\%_de\%pen\%dent\%_de\%fault\%_trans\%port\%_maps\fR +# features. +# .sp +# This feature is available in Postfix 2.0 and later. +# .IP "\fBHOLD \fIoptional text...\fR" +# Place the message on the \fBhold\fR queue, where it will +# sit until someone either deletes it or releases it for +# delivery. +# Log the optional text if specified, otherwise log a generic +# message. +# +# Mail that is placed on hold can be examined with the +# \fBpostcat\fR(1) command, and can be destroyed or released with +# the \fBpostsuper\fR(1) command. +# .sp +# Note: use "\fBpostsuper -r\fR" to release mail that was kept on +# hold for a significant fraction of \fB$maximal_queue_lifetime\fR +# or \fB$bounce_queue_lifetime\fR, or longer. Use "\fBpostsuper -H\fR" +# only for mail that will not expire within a few delivery attempts. +# .sp +# Note: this action currently affects all recipients of the message. +# .sp +# This feature is available in Postfix 2.0 and later. +# .IP "\fBPREPEND \fIheadername: headervalue\fR" +# Prepend the specified message header to the message. +# When more than one PREPEND action executes, the first +# prepended header appears before the second etc. prepended +# header. +# .sp +# Note: this action must execute before the message content +# is received; it cannot execute in the context of +# \fBsmtpd_end_of_data_restrictions\fR. +# .sp +# This feature is available in Postfix 2.1 and later. +# .IP "\fBREDIRECT \fIuser@domain\fR" +# After the message is queued, send the message to the specified +# address instead of the intended recipient(s). When multiple +# \fBREDIRECT\fR actions fire, only the last one takes effect. +# .sp +# Note: this action overrides the FILTER action, and currently +# overrides all recipients of the message. +# .sp +# This feature is available in Postfix 2.1 and later. +# .IP "\fBINFO \fIoptional text...\fR +# Log an informational record with the optional text, together +# with client information and if available, with helo, sender, +# recipient and protocol information. +# .sp +# This feature is available in Postfix 3.0 and later. +# .IP "\fBWARN \fIoptional text...\fR +# Log a warning with the optional text, together with client information +# and if available, with helo, sender, recipient and protocol information. +# .sp +# This feature is available in Postfix 2.1 and later. +# ENHANCED STATUS CODES +# .ad +# .fi +# Postfix version 2.3 and later support enhanced status codes +# as defined in RFC 3463. +# When an enhanced status code is specified in an access +# table, it is subject to modification. The following +# transformations are needed when the same access table is +# used for client, helo, sender, or recipient access restrictions; +# they happen regardless of whether Postfix replies to a MAIL +# FROM, RCPT TO or other SMTP command. +# .IP \(bu +# When a sender address matches a REJECT action, the Postfix +# SMTP server will transform a recipient DSN status (e.g., +# 4.1.1-4.1.6) into the corresponding sender DSN status, and +# vice versa. +# .IP \(bu +# When non-address information matches a REJECT action (such +# as the HELO command argument or the client hostname/address), +# the Postfix SMTP server will transform a sender or recipient +# DSN status into a generic non-address DSN status (e.g., +# 4.0.0). +# REGULAR EXPRESSION TABLES +# .ad +# .fi +# This section describes how the table lookups change when the table +# is given in the form of regular expressions. For a description of +# regular expression lookup table syntax, see \fBregexp_table\fR(5) +# or \fBpcre_table\fR(5). +# +# Each pattern is a regular expression that is applied to the entire +# string being looked up. Depending on the application, that string +# is an entire client hostname, an entire client IP address, or an +# entire mail address. Thus, no parent domain or parent network search +# is done, \fIuser@domain\fR mail addresses are not broken up into +# their \fIuser@\fR and \fIdomain\fR constituent parts, nor is +# \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR. +# +# Patterns are applied in the order as specified in the table, until a +# pattern is found that matches the search string. +# +# Actions are the same as with indexed file lookups, with +# the additional feature that parenthesized substrings from the +# pattern can be interpolated as \fB$1\fR, \fB$2\fR and so on. +# TCP-BASED TABLES +# .ad +# .fi +# This section describes how the table lookups change when lookups +# are directed to a TCP-based server. For a description of the TCP +# client/server lookup protocol, see \fBtcp_table\fR(5). +# This feature is not available up to and including Postfix version 2.4. +# +# Each lookup operation uses the entire query string once. +# Depending on the application, that string is an entire client +# hostname, an entire client IP address, or an entire mail address. +# Thus, no parent domain or parent network search is done, +# \fIuser@domain\fR mail addresses are not broken up into +# their \fIuser@\fR and \fIdomain\fR constituent parts, nor is +# \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR. +# +# Actions are the same as with indexed file lookups. +# EXAMPLE +# .ad +# .fi +# The following example uses an indexed file, so that the +# order of table entries does not matter. The example permits +# access by the client at address 1.2.3.4 but rejects all +# other clients in 1.2.3.0/24. Instead of \fBhash\fR lookup +# tables, some systems use \fBdbm\fR. Use the command +# "\fBpostconf -m\fR" to find out what lookup tables Postfix +# supports on your system. +# +# .nf +# .na +# /etc/postfix/main.cf: +# smtpd_client_restrictions = +# check_client_access hash:/etc/postfix/access +# +# /etc/postfix/access: +# 1.2.3 REJECT +# 1.2.3.4 OK +# .fi +# .ad +# +# Execute the command "\fBpostmap /etc/postfix/access\fR" after +# editing the file. +# BUGS +# The table format does not understand quoting conventions. +# SEE ALSO +# postmap(1), Postfix lookup table manager +# smtpd(8), SMTP server +# postconf(5), configuration parameters +# transport(5), transport:nexthop syntax +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# SMTPD_ACCESS_README, built-in SMTP server access control +# DATABASE_README, Postfix lookup table overview +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# AUTHOR(S) +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/aliases b/proto/aliases new file mode 100644 index 0000000..ed01ec0 --- /dev/null +++ b/proto/aliases @@ -0,0 +1,205 @@ +#++ +# NAME +# aliases 5 +# SUMMARY +# Postfix local alias database format +# SYNOPSIS +# .fi +# \fBnewaliases\fR +# DESCRIPTION +# The \fBaliases\fR(5) table provides a system-wide mechanism to +# redirect mail for local recipients. The redirections are +# processed by the Postfix \fBlocal\fR(8) delivery agent. +# +# Normally, the \fBaliases\fR(5) table is specified as a text file +# that serves as input to the \fBpostalias\fR(1) command. The +# result, an indexed file in \fBdbm\fR or \fBdb\fR format, is +# used for fast lookup by the mail system. Execute the command +# \fBnewaliases\fR in order to rebuild the indexed file after +# changing the Postfix alias database. +# +# When the table is provided via other means such as NIS, LDAP +# or SQL, the same lookups are done as for ordinary indexed files. +# +# Alternatively, the table can be provided as a regular-expression +# map where patterns are given as regular expressions. In +# this case, the lookups are done in a slightly different way +# as described below under "REGULAR EXPRESSION TABLES". +# +# Users can control delivery of their own mail by setting +# up \fB.forward\fR files in their home directory. +# Lines in per-user \fB.forward\fR files have the same syntax +# as the right-hand side of \fBaliases\fR(5) entries. +# +# The format of the alias database input file is as follows: +# .IP \(bu +# An alias definition has the form +# .sp +# .nf +# \fIname\fR: \fIvalue1\fR, \fIvalue2\fR, \fI...\fR +# .fi +# .IP \(bu +# Empty lines and whitespace-only lines are ignored, as +# are lines whose first non-whitespace character is a `#'. +# .IP \(bu +# A logical line starts with non-whitespace text. A line that +# starts with whitespace continues a logical line. +# .PP +# The \fIname\fR is a local address (no domain part). +# Use double quotes when the name contains any special characters +# such as whitespace, `#', `:', or `@'. The \fIname\fR is folded to +# lowercase, in order to make database lookups case insensitive. +# .PP +# In addition, when an alias exists for \fBowner-\fIname\fR, +# this will override the envelope sender address, so that +# delivery diagnostics are directed to \fBowner-\fIname\fR, +# instead of the originator of the message (for details, see +# \fBowner_request_special\fR, \fBexpand_owner_alias\fR and +# \fBreset_owner_alias\fR). +# This is typically used to direct delivery errors to the maintainer of +# a mailing list, who is in a better position to deal with mailing +# list delivery problems than the originator of the undelivered mail. +# .PP +# The \fIvalue\fR contains one or more of the following: +# .IP \fIaddress\fR +# Mail is forwarded to \fIaddress\fR, which is compatible +# with the RFC 822 standard. +# .IP \fI/file/name\fR +# Mail is appended to \fI/file/name\fR. See \fBlocal\fR(8) +# for details of delivery to file. +# Delivery is not limited to regular files. For example, to dispose +# of unwanted mail, deflect it to \fB/dev/null\fR. +# .IP "|\fIcommand\fR" +# Mail is piped into \fIcommand\fR. Commands that contain special +# characters, such as whitespace, should be enclosed between double +# quotes. See \fBlocal\fR(8) for details of delivery to command. +# .sp +# When the command fails, a limited amount of command output is +# mailed back to the sender. The file \fB/usr/include/sysexits.h\fR +# defines the expected exit status codes. For example, use +# \fB"|exit 67"\fR to simulate a "user unknown" error, and +# \fB"|exit 0"\fR to implement an expensive black hole. +# .IP \fB:include:\fI/file/name\fR +# Mail is sent to the destinations listed in the named file. +# Lines in \fB:include:\fR files have the same syntax +# as the right-hand side of alias entries. +# .sp +# A destination can be any destination that is described in this +# manual page. However, delivery to "|\fIcommand\fR" and +# \fI/file/name\fR is disallowed by default. To enable, edit the +# \fBallow_mail_to_commands\fR and \fBallow_mail_to_files\fR +# configuration parameters. +# ADDRESS EXTENSION +# .ad +# .fi +# When alias database search fails, and the recipient localpart +# contains the optional recipient delimiter (e.g., \fIuser+foo\fR), +# the search is repeated for the unextended address (e.g., \fIuser\fR). +# +# The \fBpropagate_unmatched_extensions\fR parameter controls +# whether an unmatched address extension (\fI+foo\fR) is +# propagated to the result of table lookup. +# CASE FOLDING +# .ad +# .fi +# The local(8) delivery agent always folds the search string +# to lowercase before database lookup. +# REGULAR EXPRESSION TABLES +# .ad +# .fi +# This section describes how the table lookups change when the table +# is given in the form of regular expressions. For a description of +# regular expression lookup table syntax, see \fBregexp_table\fR(5) +# or \fBpcre_table\fR(5). NOTE: these formats do not use ":" at the +# end of a pattern. +# +# Each regular expression is applied to the entire search +# string. Thus, a search string \fIuser+foo\fR is not broken +# up into \fIuser\fR and \fIfoo\fR. +# +# Regular expressions are applied in the order as specified +# in the table, until a regular expression is found that +# matches the search string. +# +# Lookup results are the same as with indexed file lookups. +# For security reasons there is no support for \fB$1\fR, +# \fB$2\fR etc. substring interpolation. +# SECURITY +# .ad +# .fi +# The \fBlocal\fR(8) delivery agent disallows regular expression +# substitution of $1 etc. in \fBalias_maps\fR, because that +# would open a security hole. +# +# The \fBlocal\fR(8) delivery agent will silently ignore +# requests to use the \fBproxymap\fR(8) server within +# \fBalias_maps\fR. Instead it will open the table directly. +# Before Postfix version 2.2, the \fBlocal\fR(8) delivery +# agent will terminate with a fatal error. +# CONFIGURATION PARAMETERS +# .ad +# .fi +# The following \fBmain.cf\fR parameters are especially relevant. +# The text below provides only a parameter summary. See +# \fBpostconf\fR(5) for more details including examples. +# .IP "\fBalias_database (see 'postconf -d' output)\fR" +# The alias databases for \fBlocal\fR(8) delivery that are updated with +# "\fBnewaliases\fR" or with "\fBsendmail -bi\fR". +# .IP "\fBalias_maps (see 'postconf -d' output)\fR" +# The alias databases that are used for \fBlocal\fR(8) delivery. +# .IP "\fBallow_mail_to_commands (alias, forward)\fR" +# Restrict \fBlocal\fR(8) mail delivery to external commands. +# .IP "\fBallow_mail_to_files (alias, forward)\fR" +# Restrict \fBlocal\fR(8) mail delivery to external files. +# .IP "\fBexpand_owner_alias (no)\fR" +# When delivering to an alias "\fIaliasname\fR" that has an +# "owner-\fIaliasname\fR" companion alias, set the envelope sender +# address to the expansion of the "owner-\fIaliasname\fR" alias. +# .IP "\fBpropagate_unmatched_extensions (canonical, virtual)\fR" +# What address lookup tables copy an address extension from the lookup +# key to the lookup result. +# .IP "\fBowner_request_special (yes)\fR" +# Enable special treatment for owner-\fIlistname\fR entries in the +# \fBaliases\fR(5) file, and don't split owner-\fIlistname\fR and +# \fIlistname\fR-request address localparts when the recipient_delimiter +# is set to "-". +# .IP "\fBrecipient_delimiter (empty)\fR" +# The set of characters that can separate an email address +# localpart, user name, or a .forward file name from its extension. +# .PP +# Available in Postfix version 2.3 and later: +# .IP "\fBfrozen_delivered_to (yes)\fR" +# Update the \fBlocal\fR(8) delivery agent's idea of the Delivered-To: +# address (see prepend_delivered_header) only once, at the start of +# a delivery attempt; do not update the Delivered-To: address while +# expanding aliases or .forward files. +# STANDARDS +# RFC 822 (ARPA Internet Text Messages) +# SEE ALSO +# local(8), local delivery agent +# newaliases(1), create/update alias database +# postalias(1), create/update alias database +# postconf(5), configuration parameters +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# AUTHOR(S) +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/aliases0 b/proto/aliases0 new file mode 100644 index 0000000..b00a3e1 --- /dev/null +++ b/proto/aliases0 @@ -0,0 +1,38 @@ +# +# Sample aliases file. Install in the location as specified by the +# output from the command "postconf alias_maps". Typical path names +# are /etc/aliases or /etc/mail/aliases. +# +# >>>>>>>>>> The program "newaliases" must be run after +# >> NOTE >> this file is updated for any changes to +# >>>>>>>>>> show through to Postfix. +# + +# Person who should get root's mail. Don't receive mail as root! +#root: you + +# Basic system aliases -- these MUST be present +MAILER-DAEMON: postmaster +postmaster: root + +# General redirections for pseudo accounts +bin: root +daemon: root +named: root +nobody: root +uucp: root +www: root +ftp-bugs: root +postfix: root + +# Put your local aliases here. + +# Well-known aliases +manager: root +dumper: root +operator: root +abuse: postmaster + +# trap decode to catch security attacks +decode: root + diff --git a/proto/bounce b/proto/bounce new file mode 100644 index 0000000..e7f5815 --- /dev/null +++ b/proto/bounce @@ -0,0 +1,214 @@ +#++ +# NAME +# bounce 5 +# SUMMARY +# Postfix bounce message template format +# SYNOPSIS +# \fBbounce_template_file = /etc/postfix/bounce.cf\fR +# +# \fBpostconf -b\fR [\fItemplate_file\fR] +# DESCRIPTION +# The Postfix \fBbounce\fR(8) server produces delivery status +# notification (DSN) messages for undeliverable mail, delayed +# mail, successful delivery or address verification requests. +# +# By default, these notifications are generated from built-in +# templates with message headers and message text. Sites can +# override the built-in information by specifying a bounce +# template file with the \fBbounce_template_file\fR configuration +# parameter. +# +# This document describes the general procedure to create a +# bounce template file, followed by the specific details of +# bounce template formats. +# GENERAL PROCEDURE +# .ad +# .fi +# To create a customized bounce template file, create a +# temporary +# copy of the file \fB/etc/postfix/bounce.cf.default\fR and +# edit the temporary file. +# +# To preview the results of $\fIname\fR expansions in the +# template text, use the command +# +# .nf +# \fBpostconf -b\fR \fItemporary_file\fR +# .fi +# +# Errors in the template will be reported to the standard +# error stream and to the syslog daemon. +# +# While previewing the text, be sure to pay particular attention +# to the expansion of time value parameters that appear in +# the delayed mail notification text. +# +# Once the result is satisfactory, copy the template to the +# Postfix configuration directory and specify in main.cf +# something like: +# +# .nf +# /etc/postfix/main.cf: +# bounce_template_file = /etc/postfix/bounce.cf +# .fi +# TEMPLATE FILE FORMAT +# .ad +# .fi +# The template file can specify templates for failed mail, +# delayed mail, successful delivery or for address verification. +# These templates are named \fBfailure_template\fR, +# \fBdelay_template\fR, \fBsuccess_template\fR and +# \fBverify_template\fR, respectively. You can but do not +# have to specify all four templates in a bounce template +# file. +# +# Each template starts with "\fItemplate_name\fB = <<EOF\fR" +# and ends with a line that contains the word "\fBEOF\fR" +# only. You can change the word EOF, but you can't enclose +# it in quotes as with the shell or with Perl (\fItemplate_name\fB +# = <<'EOF'\fR). Here is an example: +# +# .nf +# # The failure template is used for undeliverable mail. +# +# failure_template = <<EOF +# Charset: us-ascii +# From: MAILER-DAEMON (Mail Delivery System) +# Subject: Undelivered Mail Returned to Sender +# Postmaster-Subject: Postmaster Copy: Undelivered Mail +# +# This is the mail system at host $myhostname. +# +# I'm sorry to have to inform you that your message could not +# be delivered to one or more recipients. It's attached below. +# +# For further assistance, please send mail to postmaster. +# +# If you do so, please include this problem report. You can +# delete your own text from the attached returned message. +# +# The mail system +# EOF +# .fi +# .PP +# The usage and specification of bounce templates is +# subject to the following restrictions: +# .IP \(bu +# No special meaning is given to the backslash character or +# to leading whitespace; these are always taken literally. +# .IP \(bu +# Inside the << context, the "$" character is special. To +# produce a "$" character as output, specify "$$". +# .IP \(bu +# Outside the << context, lines beginning with "#" are ignored, +# as are empty lines, and lines consisting of whitespace only. +# .PP +# Examples of all templates can be found in the file +# \fBbounce.cf.default\fR in the Postfix configuration +# directory. +# TEMPLATE HEADER FORMAT +# .ad +# .fi +# The first portion of a bounce template consists of optional +# template headers. Some become message headers in the +# delivery status notification; some control the formatting +# of that notification. Headers not specified in a template +# will be left at their default value. +# +# The following headers are supported: +# .IP \fBCharset:\fR +# The MIME character set of the template message text. See +# the "TEMPLATE MESSAGE TEXT FORMAT" description below. +# .IP \fBFrom:\fR +# The sender address in the message header of the delivery +# status notification. +# .IP \fBSubject:\fR +# The subject in the message header of the delivery status +# notification that is returned to the sender. +# .IP \fBPostmaster-Subject:\fR +# The subject that will be used in Postmaster copies of +# undeliverable or delayed mail notifications. These copies +# are sent under control of the notify_classes configuration +# parameter. +# .PP +# The usage and specification of template message headers is +# subject to the following restrictions: +# .IP \(bu +# Template message header names can be specified in upper +# case, lower case or mixed case. Postfix always produces +# bounce message header labels of the form "\fBFrom:\fR" and +# "\fBSubject:\fR". +# .IP \(bu +# Template message headers must not span multiple lines. +# .IP \(bu +# Template message headers do not support $parameter expansions. +# .IP \(bu +# Template message headers must contain ASCII characters only, +# and must not contain ASCII null characters. +# TEMPLATE MESSAGE TEXT FORMAT +# .ad +# .fi +# The second portion of a bounce template consists of message +# text. As the above example shows, template message text may +# contain main.cf $parameters. Besides the parameters that are +# defined in main.cf, the following parameters are treated +# specially depending on the suffix that is appended to their +# name. +# .IP \fBdelay_warning_time_\fIsuffix\fR +# Expands into the value of the \fBdelay_warning_time\fR +# parameter, expressed in the time unit specified by +# \fIsuffix\fR, which is one of \fBseconds\fR, \fBminutes\fR, +# \fBhours\fB, \fBdays\fR, or \fBweeks\fR. +# .IP \fBmaximal_queue_lifetime_\fIsuffix\fR +# Expands into the value of the \fBmaximal_queue_lifetime\fR +# parameter, expressed in the time unit specified by +# \fIsuffix\fR. See above under \fBdelay_warning_time\fR for +# possible \fIsuffix\fR values. +# .IP \fBmydomain\fR +# Expands into the value of the \fBmydomain\fR parameter. +# With "smtputf8_enable = yes", this replaces ACE labels +# (xn--mumble) with their UTF-8 equivalent. +# .sp +# This feature is available in Postfix 3.0. +# .IP \fBmyhostname\fR +# Expands into the value of the \fBmyhostname\fR parameter. +# With "smtputf8_enable = yes", this replaces ACE labels +# (xn--mumble) with their UTF-8 equivalent. +# .sp +# This feature is available in Postfix 3.0. +# .PP +# The usage and specification of template message text is +# subject to the following restrictions: +# .IP \(bu +# The template message text is not sent in Postmaster copies +# of delivery status notifications. +# .IP \(bu +# If the template message text contains non-ASCII characters, +# Postfix requires that the \fBCharset:\fR template header +# is updated. Specify an appropriate superset of US-ASCII. +# A superset is needed because Postfix appends ASCII text +# after the message template when it sends a delivery status +# notification. +# SEE ALSO +# bounce(8), Postfix delivery status notifications +# postconf(5), configuration parameters +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# HISTORY +# .ad +# .fi +# The Postfix bounce template format was originally developed by +# Nicolas Riendeau. +# AUTHOR(S) +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/canonical b/proto/canonical new file mode 100644 index 0000000..6364d3e --- /dev/null +++ b/proto/canonical @@ -0,0 +1,273 @@ +#++ +# NAME +# canonical 5 +# SUMMARY +# Postfix canonical table format +# SYNOPSIS +# \fBpostmap /etc/postfix/canonical\fR +# +# \fBpostmap -q "\fIstring\fB" /etc/postfix/canonical\fR +# +# \fBpostmap -q - /etc/postfix/canonical <\fIinputfile\fR +# DESCRIPTION +# The optional \fBcanonical\fR(5) table specifies an address mapping for +# local and non-local addresses. The mapping is used by the +# \fBcleanup\fR(8) daemon, before mail is stored into the +# queue. The address mapping is recursive. +# +# Normally, the \fBcanonical\fR(5) table is specified as a text file +# that serves as input to the \fBpostmap\fR(1) command. +# The result, an indexed file in \fBdbm\fR or \fBdb\fR format, +# is used for fast searching by the mail system. Execute the command +# "\fBpostmap /etc/postfix/canonical\fR" to rebuild an indexed +# file after changing the corresponding text file. +# +# When the table is provided via other means such as NIS, LDAP +# or SQL, the same lookups are done as for ordinary indexed files. +# +# Alternatively, the table can be provided as a regular-expression +# map where patterns are given as regular expressions, or lookups +# can be directed to a TCP-based server. In those cases, the lookups +# are done in a slightly different way as described below under +# "REGULAR EXPRESSION TABLES" or "TCP-BASED TABLES". +# +# By default the \fBcanonical\fR(5) mapping affects both message +# header addresses (i.e. addresses that appear inside messages) +# and message envelope addresses (for example, the addresses +# that are used in SMTP protocol commands). This is controlled with +# the \fBcanonical_classes\fR parameter. +# +# NOTE: Postfix versions 2.2 and later rewrite message headers +# from remote SMTP clients only if the client matches the +# local_header_rewrite_clients parameter, or if the +# remote_header_rewrite_domain configuration parameter specifies +# a non-empty value. To get the behavior before Postfix 2.2, +# specify "local_header_rewrite_clients = static:all". +# +# Typically, one would use the \fBcanonical\fR(5) table to replace login +# names by \fIFirstname.Lastname\fR, or to clean up addresses produced +# by legacy mail systems. +# +# The \fBcanonical\fR(5) mapping is not to be confused with \fIvirtual +# alias\fR support or with local aliasing. To change the destination +# but not the headers, use the \fBvirtual\fR(5) or \fBaliases\fR(5) +# map instead. +# CASE FOLDING +# .ad +# .fi +# The search string is folded to lowercase before database +# lookup. As of Postfix 2.3, the search string is not case +# folded with database types such as regexp: or pcre: whose +# lookup fields can match both upper and lower case. +# TABLE FORMAT +# .ad +# .fi +# The input format for the \fBpostmap\fR(1) command is as follows: +# .IP "\fIpattern address\fR" +# When \fIpattern\fR matches a mail address, replace it by the +# corresponding \fIaddress\fR. +# .IP "blank lines and comments" +# Empty lines and whitespace-only lines are ignored, as +# are lines whose first non-whitespace character is a `#'. +# .IP "multi-line text" +# A logical line starts with non-whitespace text. A line that +# starts with whitespace continues a logical line. +# TABLE SEARCH ORDER +# .ad +# .fi +# With lookups from indexed files such as DB or DBM, or from networked +# tables such as NIS, LDAP or SQL, each \fIuser\fR@\fIdomain\fR +# query produces a sequence of query patterns as described below. +# +# Each query pattern is sent to each specified lookup table +# before trying the next query pattern, until a match is +# found. +# .IP "\fIuser\fR@\fIdomain address\fR" +# Replace \fIuser\fR@\fIdomain\fR by \fIaddress\fR. This form +# has the highest precedence. +# .sp +# This is useful to clean up addresses produced by legacy mail systems. +# It can also be used to produce \fIFirstname.Lastname\fR style +# addresses, but see below for a simpler solution. +# .IP "\fIuser address\fR" +# Replace \fIuser\fR@\fIsite\fR by \fIaddress\fR when \fIsite\fR is +# equal to $\fBmyorigin\fR, when \fIsite\fR is listed in +# $\fBmydestination\fR, or when it is listed in $\fBinet_interfaces\fR +# or $\fBproxy_interfaces\fR. +# .sp +# This form is useful for replacing login names by +# \fIFirstname.Lastname\fR. +# .IP "@\fIdomain address\fR" +# Replace other addresses in \fIdomain\fR by \fIaddress\fR. +# This form has the lowest precedence. +# .sp +# Note: @\fIdomain\fR is a wild-card. When this form is applied +# to recipient addresses, the Postfix SMTP server accepts +# mail for any recipient in \fIdomain\fR, regardless of whether +# that recipient exists. This may turn your mail system into +# a backscatter source: Postfix first accepts mail for +# non-existent recipients and then tries to return that mail +# as "undeliverable" to the often forged sender address. +# .sp +# To avoid backscatter with mail for a wild-card domain, +# replace the wild-card mapping with explicit 1:1 mappings, +# or add a reject_unverified_recipient restriction for that +# domain: +# +# .nf +# smtpd_recipient_restrictions = +# ... +# reject_unauth_destination +# check_recipient_access +# inline:{example.com=reject_unverified_recipient} +# unverified_recipient_reject_code = 550 +# .fi +# +# In the above example, Postfix may contact a remote server +# if the recipient is rewritten to a remote address. +# RESULT ADDRESS REWRITING +# .ad +# .fi +# The lookup result is subject to address rewriting: +# .IP \(bu +# When the result has the form @\fIotherdomain\fR, the +# result becomes the same \fIuser\fR in \fIotherdomain\fR. +# .IP \(bu +# When "\fBappend_at_myorigin=yes\fR", append "\fB@$myorigin\fR" +# to addresses without "@domain". +# .IP \(bu +# When "\fBappend_dot_mydomain=yes\fR", append +# "\fB.$mydomain\fR" to addresses without ".domain". +# ADDRESS EXTENSION +# .fi +# .ad +# When a mail address localpart contains the optional recipient delimiter +# (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes: +# \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR, +# \fIuser\fR, and @\fIdomain\fR. +# +# The \fBpropagate_unmatched_extensions\fR parameter controls whether +# an unmatched address extension (\fI+foo\fR) is propagated to the +# result of table lookup. +# REGULAR EXPRESSION TABLES +# .ad +# .fi +# This section describes how the table lookups change when the table +# is given in the form of regular expressions. For a description of +# regular expression lookup table syntax, see \fBregexp_table\fR(5) +# or \fBpcre_table\fR(5). +# +# Each pattern is a regular expression that is applied to the entire +# address being looked up. Thus, \fIuser@domain\fR mail addresses are not +# broken up into their \fIuser\fR and \fI@domain\fR constituent parts, +# nor is \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR. +# +# Patterns are applied in the order as specified in the table, until a +# pattern is found that matches the search string. +# +# Results are the same as with indexed file lookups, with +# the additional feature that parenthesized substrings from the +# pattern can be interpolated as \fB$1\fR, \fB$2\fR and so on. +# TCP-BASED TABLES +# .ad +# .fi +# This section describes how the table lookups change when lookups +# are directed to a TCP-based server. For a description of the TCP +# client/server lookup protocol, see \fBtcp_table\fR(5). +# This feature is not available up to and including Postfix version 2.4. +# +# Each lookup operation uses the entire address once. Thus, +# \fIuser@domain\fR mail addresses are not broken up into their +# \fIuser\fR and \fI@domain\fR constituent parts, nor is +# \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR. +# +# Results are the same as with indexed file lookups. +# BUGS +# The table format does not understand quoting conventions. +# CONFIGURATION PARAMETERS +# .ad +# .fi +# The following \fBmain.cf\fR parameters are especially relevant. +# The text below provides only a parameter summary. See +# \fBpostconf\fR(5) for more details including examples. +# .IP "\fBcanonical_classes (envelope_sender, envelope_recipient, header_sender, header_recipient)\fR" +# What addresses are subject to canonical_maps address mapping. +# .IP "\fBcanonical_maps (empty)\fR" +# Optional address mapping lookup tables for message headers and +# envelopes. +# .IP "\fBrecipient_canonical_maps (empty)\fR" +# Optional address mapping lookup tables for envelope and header +# recipient addresses. +# .IP "\fBsender_canonical_maps (empty)\fR" +# Optional address mapping lookup tables for envelope and header +# sender addresses. +# .IP "\fBpropagate_unmatched_extensions (canonical, virtual)\fR" +# What address lookup tables copy an address extension from the lookup +# key to the lookup result. +# .PP +# Other parameters of interest: +# .IP "\fBinet_interfaces (all)\fR" +# The network interface addresses that this mail system receives +# mail on. +# .IP "\fBlocal_header_rewrite_clients (permit_inet_interfaces)\fR" +# Rewrite message header addresses in mail from these clients and +# update incomplete addresses with the domain name in $myorigin or +# $mydomain; either don't rewrite message headers from other clients +# at all, or rewrite message headers and update incomplete addresses +# with the domain specified in the remote_header_rewrite_domain +# parameter. +# .IP "\fBproxy_interfaces (empty)\fR" +# The network interface addresses that this mail system receives mail +# on by way of a proxy or network address translation unit. +# .IP "\fBmasquerade_classes (envelope_sender, header_sender, header_recipient)\fR" +# What addresses are subject to address masquerading. +# .IP "\fBmasquerade_domains (empty)\fR" +# Optional list of domains whose subdomain structure will be stripped +# off in email addresses. +# .IP "\fBmasquerade_exceptions (empty)\fR" +# Optional list of user names that are not subjected to address +# masquerading, even when their addresses match $masquerade_domains. +# .IP "\fBmydestination ($myhostname, localhost.$mydomain, localhost)\fR" +# The list of domains that are delivered via the $local_transport +# mail delivery transport. +# .IP "\fBmyorigin ($myhostname)\fR" +# The domain name that locally-posted mail appears to come +# from, and that locally posted mail is delivered to. +# .IP "\fBowner_request_special (yes)\fR" +# Enable special treatment for owner-\fIlistname\fR entries in the +# \fBaliases\fR(5) file, and don't split owner-\fIlistname\fR and +# \fIlistname\fR-request address localparts when the recipient_delimiter +# is set to "-". +# .IP "\fBremote_header_rewrite_domain (empty)\fR" +# Don't rewrite message headers from remote clients at all when +# this parameter is empty; otherwise, rewrite message headers and +# append the specified domain name to incomplete addresses. +# SEE ALSO +# cleanup(8), canonicalize and enqueue mail +# postmap(1), Postfix lookup table manager +# postconf(5), configuration parameters +# virtual(5), virtual aliasing +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# ADDRESS_REWRITING_README, address rewriting guide +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# AUTHOR(S) +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/cidr_table b/proto/cidr_table new file mode 100644 index 0000000..9eed9ce --- /dev/null +++ b/proto/cidr_table @@ -0,0 +1,176 @@ +#++ +# NAME +# cidr_table 5 +# SUMMARY +# format of Postfix CIDR tables +# SYNOPSIS +# \fBpostmap -q "\fIstring\fB" cidr:/etc/postfix/\fIfilename\fR +# +# \fBpostmap -q - cidr:/etc/postfix/\fIfilename\fB <\fIinputfile\fR +# DESCRIPTION +# The Postfix mail system uses optional lookup tables. +# These tables are usually in \fBdbm\fR or \fBdb\fR format. +# Alternatively, lookup tables can be specified in CIDR +# (Classless Inter-Domain Routing) form. In this case, each +# input is compared against a list of patterns. When a match +# is found, the corresponding result is returned and the search +# is terminated. +# +# To find out what types of lookup tables your Postfix system +# supports use the "\fBpostconf -m\fR" command. +# +# To test lookup tables, use the "\fBpostmap -q\fR" command as +# described in the SYNOPSIS above. +# TABLE FORMAT +# .ad +# .fi +# The general form of a Postfix CIDR table is: +# .IP "\fIpattern result\fR" +# When a search string matches the specified \fIpattern\fR, use +# the corresponding \fIresult\fR value. The \fIpattern\fR must be +# in \fInetwork/prefix\fR or \fInetwork_address\fR form (see +# ADDRESS PATTERN SYNTAX below). +# .IP "\fB!\fIpattern result\fR" +# When a search string does not match the specified \fIpattern\fR, +# use the specified \fIresult\fR value. The \fIpattern\fR must +# be in \fInetwork/prefix\fR or \fInetwork_address\fR form (see +# ADDRESS PATTERN SYNTAX below). +# .sp +# This feature is available in Postfix 3.2 and later. +# .IP "\fBif \fIpattern\fR" +# .IP "\fBendif\fR" +# When a search string matches the specified \fIpattern\fR, match +# that search string against the patterns between \fBif\fR and +# \fBendif\fR. The \fIpattern\fR must be in \fInetwork/prefix\fR or +# \fInetwork_address\fR form (see ADDRESS PATTERN SYNTAX below). The +# \fBif\fR..\fBendif\fR can nest. +# .sp +# Note: do not prepend whitespace to text between +# \fBif\fR..\fBendif\fR. +# .sp +# This feature is available in Postfix 3.2 and later. +# .IP "\fBif !\fIpattern\fR" +# .IP "\fBendif\fR" +# When a search string does not match the specified \fIpattern\fR, +# match that search string against the patterns between \fBif\fR and +# \fBendif\fR. The \fIpattern\fR must be in \fInetwork/prefix\fR or +# \fInetwork_address\fR form (see ADDRESS PATTERN SYNTAX below). The +# \fBif\fR..\fBendif\fR can nest. +# .sp +# Note: do not prepend whitespace to text between +# \fBif\fR..\fBendif\fR. +# .sp +# This feature is available in Postfix 3.2 and later. +# .IP "blank lines and comments" +# Empty lines and whitespace-only lines are ignored, as +# are lines whose first non-whitespace character is a `#'. +# .IP "multi-line text" +# A logical line starts with non-whitespace text. A line that +# starts with whitespace continues a logical line. +# TABLE SEARCH ORDER +# .ad +# .fi +# Patterns are applied in the order as specified in the table, until a +# pattern is found that matches the search string. +# ADDRESS PATTERN SYNTAX +# .ad +# .fi +# Postfix CIDR tables are pattern-based. A pattern is either +# a \fInetwork_address\fR which requires an exact match, or a +# \fInetwork_address/prefix_length\fR where the \fIprefix_length\fR +# part specifies the length of the \fInetwork_address\fR prefix +# that must be matched (the other bits in the \fInetwork_address\fR +# part must be zero). +# +# An IPv4 network address is a sequence of four decimal octets +# separated by ".", and an IPv6 network address is a sequence +# of three to eight hexadecimal octet pairs separated by ":" +# or "::", where the latter is short-hand for a sequence of +# one or more all-zero octet pairs. The pattern 0.0.0.0/0 +# matches every IPv4 address, and ::/0 matches every IPv6 +# address. IPv6 support is available in Postfix 2.2 and +# later. +# +# Before comparisons are made, lookup keys and table entries +# are converted from string to binary. Therefore, IPv6 patterns +# will be matched regardless of leading zeros (a leading zero in +# an IPv4 address octet indicates octal notation). +# +# Note: address information may be enclosed inside "[]" but +# this form is not required. +# INLINE SPECIFICATION +# .ad +# .fi +# The contents of a table may be specified in the table name +# (Postfix 3.7 and later). +# The basic syntax is: +# +# .nf +# main.cf: +# \fIparameter\fR \fB= .. cidr:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } ..\fR +# +# master.cf: +# \fB.. -o { \fIparameter\fR \fB= .. cidr:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR +# .fi +# +# Postfix ignores whitespace after '{' and before '}', and +# writes each \fIrule\fR as one text line to an in-memory +# file: +# +# .nf +# in-memory file: +# rule-1 +# rule-2 +# .. +# .fi +# +# Postfix parses the result as if it is a file in /etc/postfix. +# +# Note: if a rule contains \fB$\fR, specify \fB$$\fR to keep +# Postfix from trying to do \fI$name\fR expansion as it +# evaluates a parameter value. +# EXAMPLE SMTPD ACCESS MAP +# .nf +# /etc/postfix/main.cf: +# smtpd_client_restrictions = ... cidr:/etc/postfix/client.cidr ... +# +# /etc/postfix/client.cidr: +# # Rule order matters. Put more specific allowlist entries +# # before more general denylist entries. +# 192.168.1.1 OK +# 192.168.0.0/16 REJECT +# 2001:db8::1 OK +# 2001:db8::/32 REJECT +# .fi +# SEE ALSO +# postmap(1), Postfix lookup table manager +# regexp_table(5), format of regular expression tables +# pcre_table(5), format of PCRE tables +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# HISTORY +# CIDR table support was introduced with Postfix version 2.1. +# AUTHOR(S) +# The CIDR table lookup code was originally written by: +# Jozsef Kadlecsik +# KFKI Research Institute for Particle and Nuclear Physics +# POB. 49 +# 1525 Budapest, Hungary +# +# Adopted and adapted by: +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/generic b/proto/generic new file mode 100644 index 0000000..fdeb1ea --- /dev/null +++ b/proto/generic @@ -0,0 +1,239 @@ +#++ +# NAME +# generic 5 +# SUMMARY +# Postfix generic table format +# SYNOPSIS +# \fBpostmap /etc/postfix/generic\fR +# +# \fBpostmap -q "\fIstring\fB" /etc/postfix/generic\fR +# +# \fBpostmap -q - /etc/postfix/generic <\fIinputfile\fR +# DESCRIPTION +# The optional \fBgeneric\fR(5) table specifies an address +# mapping that applies when mail is delivered. This is the +# opposite of \fBcanonical\fR(5) mapping, which applies when +# mail is received. +# +# Typically, one would use the \fBgeneric\fR(5) table on a +# system that does not have a valid Internet domain name and +# that uses something like \fIlocaldomain.local\fR instead. +# The \fBgeneric\fR(5) table is then used by the \fBsmtp\fR(8) +# client to transform local mail addresses into valid Internet +# mail addresses when mail has to be sent across the Internet. +# See the EXAMPLE section at the end of this document. +# +# The \fBgeneric\fR(5) mapping affects both message header +# addresses (i.e. addresses that appear inside messages) and +# message envelope addresses (for example, the addresses that +# are used in SMTP protocol commands). +# +# Normally, the \fBgeneric\fR(5) table is specified as a +# text file that serves as input to the \fBpostmap\fR(1) +# command. The result, an indexed file in \fBdbm\fR or +# \fBdb\fR format, is used for fast searching by the mail +# system. Execute the command "\fBpostmap /etc/postfix/generic\fR" +# to rebuild an indexed file after changing the corresponding +# text file. +# +# When the table is provided via other means such as NIS, LDAP +# or SQL, the same lookups are done as for ordinary indexed files. +# +# Alternatively, the table can be provided as a regular-expression +# map where patterns are given as regular expressions, or lookups +# can be directed to a TCP-based server. In those cases, the lookups +# are done in a slightly different way as described below under +# "REGULAR EXPRESSION TABLES" or "TCP-BASED TABLES". +# CASE FOLDING +# .ad +# .fi +# The search string is folded to lowercase before database +# lookup. As of Postfix 2.3, the search string is not case +# folded with database types such as regexp: or pcre: whose +# lookup fields can match both upper and lower case. +# TABLE FORMAT +# .ad +# .fi +# The input format for the \fBpostmap\fR(1) command is as follows: +# .IP "\fIpattern result\fR" +# When \fIpattern\fR matches a mail address, replace it by the +# corresponding \fIresult\fR. +# .IP "blank lines and comments" +# Empty lines and whitespace-only lines are ignored, as +# are lines whose first non-whitespace character is a `#'. +# .IP "multi-line text" +# A logical line starts with non-whitespace text. A line that +# starts with whitespace continues a logical line. +# TABLE SEARCH ORDER +# .ad +# .fi +# With lookups from indexed files such as DB or DBM, or from networked +# tables such as NIS, LDAP or SQL, each \fIuser\fR@\fIdomain\fR +# query produces a sequence of query patterns as described below. +# +# Each query pattern is sent to each specified lookup table +# before trying the next query pattern, until a match is +# found. +# .IP "\fIuser\fR@\fIdomain address\fR" +# Replace \fIuser\fR@\fIdomain\fR by \fIaddress\fR. This form +# has the highest precedence. +# .IP "\fIuser address\fR" +# Replace \fIuser\fR@\fIsite\fR by \fIaddress\fR when \fIsite\fR is +# equal to $\fBmyorigin\fR, when \fIsite\fR is listed in +# $\fBmydestination\fR, or when it is listed in $\fBinet_interfaces\fR +# or $\fBproxy_interfaces\fR. +# .IP "@\fIdomain address\fR" +# Replace other addresses in \fIdomain\fR by \fIaddress\fR. +# This form has the lowest precedence. +# RESULT ADDRESS REWRITING +# .ad +# .fi +# The lookup result is subject to address rewriting: +# .IP \(bu +# When the result has the form @\fIotherdomain\fR, the +# result becomes the same \fIuser\fR in \fIotherdomain\fR. +# .IP \(bu +# When "\fBappend_at_myorigin=yes\fR", append "\fB@$myorigin\fR" +# to addresses without "@domain". +# .IP \(bu +# When "\fBappend_dot_mydomain=yes\fR", append +# "\fB.$mydomain\fR" to addresses without ".domain". +# ADDRESS EXTENSION +# .fi +# .ad +# When a mail address localpart contains the optional recipient delimiter +# (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes: +# \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR, +# \fIuser\fR, and @\fIdomain\fR. +# +# The \fBpropagate_unmatched_extensions\fR parameter controls whether +# an unmatched address extension (\fI+foo\fR) is propagated to the +# result of table lookup. +# REGULAR EXPRESSION TABLES +# .ad +# .fi +# This section describes how the table lookups change when the table +# is given in the form of regular expressions. For a description of +# regular expression lookup table syntax, see \fBregexp_table\fR(5) +# or \fBpcre_table\fR(5). +# +# Each pattern is a regular expression that is applied to the entire +# address being looked up. Thus, \fIuser@domain\fR mail addresses are not +# broken up into their \fIuser\fR and \fI@domain\fR constituent parts, +# nor is \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR. +# +# Patterns are applied in the order as specified in the table, until a +# pattern is found that matches the search string. +# +# Results are the same as with indexed file lookups, with +# the additional feature that parenthesized substrings from the +# pattern can be interpolated as \fB$1\fR, \fB$2\fR and so on. +# TCP-BASED TABLES +# .ad +# .fi +# This section describes how the table lookups change when lookups +# are directed to a TCP-based server. For a description of the TCP +# client/server lookup protocol, see \fBtcp_table\fR(5). +# This feature is available in Postfix 2.5 and later. +# +# Each lookup operation uses the entire address once. Thus, +# \fIuser@domain\fR mail addresses are not broken up into their +# \fIuser\fR and \fI@domain\fR constituent parts, nor is +# \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR. +# +# Results are the same as with indexed file lookups. +# EXAMPLE +# .ad +# .fi +# The following shows a generic mapping with an indexed file. +# When mail is sent to a remote host via SMTP, this replaces +# \fIhis@localdomain.local\fR by his ISP mail address, replaces +# \fIher@localdomain.local\fR by her ISP mail address, and +# replaces other local addresses by his ISP account, with +# an address extension of \fI+local\fR (this example assumes +# that the ISP supports "+" style address extensions). +# +# .na +# .nf +# /etc/postfix/main.cf: +# smtp_generic_maps = hash:/etc/postfix/generic +# +# /etc/postfix/generic: +# his@localdomain.local hisaccount@hisisp.example +# her@localdomain.local heraccount@herisp.example +# @localdomain.local hisaccount+local@hisisp.example +# +# .ad +# .fi +# Execute the command "\fBpostmap /etc/postfix/generic\fR" +# whenever the table is changed. Instead of \fBhash\fR, some +# systems use \fBdbm\fR database files. To find out what +# tables your system supports use the command "\fBpostconf +# -m\fR". +# BUGS +# The table format does not understand quoting conventions. +# CONFIGURATION PARAMETERS +# .ad +# .fi +# The following \fBmain.cf\fR parameters are especially relevant. +# The text below provides only a parameter summary. See +# \fBpostconf\fR(5) for more details including examples. +# .IP "\fBsmtp_generic_maps (empty)\fR" +# Optional lookup tables that perform address rewriting in the +# Postfix SMTP client, typically to transform a locally valid address into +# a globally valid address when sending mail across the Internet. +# .IP "\fBpropagate_unmatched_extensions (canonical, virtual)\fR" +# What address lookup tables copy an address extension from the lookup +# key to the lookup result. +# .PP +# Other parameters of interest: +# .IP "\fBinet_interfaces (all)\fR" +# The network interface addresses that this mail system receives +# mail on. +# .IP "\fBproxy_interfaces (empty)\fR" +# The network interface addresses that this mail system receives mail +# on by way of a proxy or network address translation unit. +# .IP "\fBmydestination ($myhostname, localhost.$mydomain, localhost)\fR" +# The list of domains that are delivered via the $local_transport +# mail delivery transport. +# .IP "\fBmyorigin ($myhostname)\fR" +# The domain name that locally-posted mail appears to come +# from, and that locally posted mail is delivered to. +# .IP "\fBowner_request_special (yes)\fR" +# Enable special treatment for owner-\fIlistname\fR entries in the +# \fBaliases\fR(5) file, and don't split owner-\fIlistname\fR and +# \fIlistname\fR-request address localparts when the recipient_delimiter +# is set to "-". +# SEE ALSO +# postmap(1), Postfix lookup table manager +# postconf(5), configuration parameters +# smtp(8), Postfix SMTP client +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# ADDRESS_REWRITING_README, address rewriting guide +# DATABASE_README, Postfix lookup table overview +# STANDARD_CONFIGURATION_README, configuration examples +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# HISTORY +# A genericstable feature appears in the Sendmail MTA. +# +# This feature is available in Postfix 2.2 and later. +# AUTHOR(S) +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/header_checks b/proto/header_checks new file mode 100644 index 0000000..1aa6f5a --- /dev/null +++ b/proto/header_checks @@ -0,0 +1,520 @@ +#++ +# NAME +# header_checks 5 +# SUMMARY +# Postfix built-in content inspection +# SYNOPSIS +# .nf +# \fBheader_checks = pcre:/etc/postfix/header_checks\fR +# \fBmime_header_checks = pcre:/etc/postfix/mime_header_checks\fR +# \fBnested_header_checks = pcre:/etc/postfix/nested_header_checks\fR +# \fBbody_checks = pcre:/etc/postfix/body_checks\fR +# .sp +# \fBmilter_header_checks = pcre:/etc/postfix/milter_header_checks\fR +# .sp +# \fBsmtp_header_checks = pcre:/etc/postfix/smtp_header_checks\fR +# \fBsmtp_mime_header_checks = pcre:/etc/postfix/smtp_mime_header_checks\fR +# \fBsmtp_nested_header_checks = pcre:/etc/postfix/smtp_nested_header_checks\fR +# \fBsmtp_body_checks = pcre:/etc/postfix/smtp_body_checks\fR +# .sp +# \fBpostmap -q "\fIstring\fB" pcre:/etc/postfix/\fIfilename\fR +# \fBpostmap -q - pcre:/etc/postfix/\fIfilename\fR <\fIinputfile\fR +# .fi +# DESCRIPTION +# This document describes access control on the content of +# message headers and message body lines; it is implemented +# by the Postfix \fBcleanup\fR(8) server before mail is queued. +# See \fBaccess\fR(5) for access control on remote SMTP client +# information. +# +# Each message header or message body line is compared against +# a list of patterns. +# When a match is found the corresponding action is executed, and +# the matching process is repeated for the next message header or +# message body line. +# +# Note: message headers are examined one logical header at a time, +# even when a message header spans multiple lines. Body lines are +# always examined one line at a time. +# +# For examples, see the EXAMPLES section at the end of this +# manual page. +# +# Postfix header or body_checks are designed to stop a flood of mail +# from worms or viruses; they do not decode attachments, and they do +# not unzip archives. See the documents referenced below in the README +# FILES section if you need more sophisticated content analysis. +# FILTERS WHILE RECEIVING MAIL +# .ad +# .fi +# Postfix implements the following four built-in content +# inspection classes while receiving mail: +# .IP "\fBheader_checks\fR (default: empty)" +# These are applied to initial message headers (except for +# the headers that are processed with \fBmime_header_checks\fR). +# .IP "\fBmime_header_checks\fR (default: \fB$header_checks\fR)" +# These are applied to MIME related message headers only. +# .sp +# This feature is available in Postfix 2.0 and later. +# .IP "\fBnested_header_checks\fR (default: \fB$header_checks\fR)" +# These are applied to message headers of attached email +# messages (except for the headers that are processed with +# \fBmime_header_checks\fR). +# .sp +# This feature is available in Postfix 2.0 and later. +# .IP \fBbody_checks\fR +# These are applied to all other content, including multi-part +# message boundaries. +# .sp +# With Postfix versions before 2.0, all content after the initial +# message headers is treated as body content. +# FILTERS AFTER RECEIVING MAIL +# .ad +# .fi +# Postfix supports a subset of the built-in content inspection +# classes after the message is received: +# .IP "\fBmilter_header_checks\fR (default: empty)" +# These are applied to headers that are added with Milter +# applications. +# .sp +# This feature is available in Postfix 2.7 and later. +# FILTERS WHILE DELIVERING MAIL +# .ad +# .fi +# Postfix supports all four content inspection classes while +# delivering mail via SMTP. +# .IP "\fBsmtp_header_checks\fR (default: empty)" +# .IP "\fBsmtp_mime_header_checks\fR (default: empty)" +# .IP "\fBsmtp_nested_header_checks\fR (default: empty)" +# .IP "\fBsmtp_body_checks\fR (default: empty)" +# These features are available in Postfix 2.5 and later. +# COMPATIBILITY +# .ad +# .fi +# With Postfix version 2.2 and earlier specify "\fBpostmap +# -fq\fR" to query a table that contains case sensitive +# patterns. By default, regexp: and pcre: patterns are case +# insensitive. +# TABLE FORMAT +# .ad +# .fi +# This document assumes that header and body_checks rules are specified +# in the form of Postfix regular expression lookup tables. Usually the +# best performance is obtained with \fBpcre\fR (Perl Compatible Regular +# Expression) tables. The \fBregexp\fR (POSIX regular +# expressions) tables are usually slower, but more widely +# available. +# Use the command "\fBpostconf -m\fR" to find out what lookup table +# types your Postfix system supports. +# +# The general format of Postfix regular expression tables is +# given below. +# For a discussion of specific pattern or flags syntax, +# see \fBpcre_table\fR(5) or \fBregexp_table\fR(5), respectively. +# .IP "\fB/\fIpattern\fB/\fIflags action\fR" +# When /\fIpattern\fR/ matches the input string, execute +# the corresponding \fIaction\fR. See below for a list +# of possible actions. +# .IP "\fB!/\fIpattern\fB/\fIflags action\fR" +# When /\fIpattern\fR/ does \fBnot\fR match the input string, +# execute the corresponding \fIaction\fR. +# .IP "\fBif /\fIpattern\fB/\fIflags\fR" +# .IP "\fBendif\fR" +# If the input string matches /\fIpattern\fR/, then match that +# input string against the patterns between \fBif\fR and +# \fBendif\fR. The \fBif\fR..\fBendif\fR can nest. +# .sp +# Note: do not prepend whitespace to patterns inside +# \fBif\fR..\fBendif\fR. +# .IP "\fBif !/\fIpattern\fB/\fIflags\fR" +# .IP "\fBendif\fR" +# If the input string does not match /\fIpattern\fR/, then +# match that input string against the patterns between \fBif\fR +# and \fBendif\fR. The \fBif\fR..\fBendif\fR can nest. +# .IP "blank lines and comments" +# Empty lines and whitespace-only lines are ignored, as +# are lines whose first non-whitespace character is a `#'. +# .IP "multi-line text" +# A pattern/action line starts with non-whitespace text. A line that +# starts with whitespace continues a logical line. +# TABLE SEARCH ORDER +# .ad +# .fi +# For each line of message input, the patterns are applied in the +# order as specified in the table. When a pattern is found that matches +# the input line, the corresponding action is executed and then the +# next input line is inspected. +# TEXT SUBSTITUTION +# .ad +# .fi +# Substitution of substrings from the matched expression into the +# \fIaction\fR +# string is possible using the conventional Perl syntax +# (\fB$1\fR, \fB$2\fR, etc.). +# The macros in the result string may need to be written as \fB${n}\fR +# or \fB$(n)\fR if they aren't followed by whitespace. +# +# Note: since negated patterns (those preceded by \fB!\fR) return a +# result when the expression does not match, substitutions are not +# available for negated patterns. +# ACTIONS +# .ad +# .fi +# Action names are case insensitive. They are shown in upper case +# for consistency with other Postfix documentation. +# .IP "\fBBCC \fIuser@domain\fR" +# Add the specified address as a BCC recipient, and inspect +# the next input line. The address +# must have a local part and domain part. The number of BCC +# addresses that can be added is limited only by the amount +# of available storage space. +# +# Note 1: the BCC address is added as if it was specified with +# NOTIFY=NONE. The sender will not be notified when the BCC +# address is undeliverable, as long as all down-stream software +# implements RFC 3461. +# +# Note 2: this ignores duplicate addresses (with the same +# delivery status notification options). +# .sp +# This feature is available in Postfix 3.0 and later. +# .sp +# This feature is not supported with smtp header/body checks. +# \" .IP "\fBDELAY \fItime\fR" +# \" Place the message into the deferred queue, and delay the +# \" initial delivery attempt by \fItime\fR. The time value may +# \" be followed by a one-character suffix that specifies the +# \" time unit: s (seconds), m (minutes), h (hours), d (days), +# \" w (weeks). The default time unit is s (seconds). +# \" .sp +# \" Limitations: +# \" .RS +# \" .IP \(bu +# \" This action affects all the recipients of the message. +# \" .IP \(bu +# \" The delay value has no effect with remote file systems that +# \" don't correctly emulate UNIX local file system semantics. +# \" In that case, the delay will be half of $queue_run_delay +# \" on average. +# \" .IP \(bu +# \" Mail will still be delivered with "sendmail -q", "postfix +# \" flush" or "postqueue -f". +# \" .IP \(bu +# \" Delayed mail increases the amount of disk I/O during deferred +# \" queue scans. When large amounts of mail are queued for +# \" delayed delivery it may be preferable to use the HOLD feature +# \" instead. +# \" .RE +# \" .IP +# \" This feature is available in Postfix 2.3 and later. +# .IP "\fBDISCARD \fIoptional text...\fR" +# Claim successful delivery and silently discard the message. +# Do not inspect the remainder of the input message. +# Log the optional text if specified, otherwise log a generic +# message. +# .sp +# Note: this action disables further header or body_checks inspection +# of the current message and affects all recipients. +# To discard only one recipient without discarding the entire message, +# use the transport(5) table to direct mail to the discard(8) service. +# .sp +# This feature is available in Postfix 2.0 and later. +# .sp +# This feature is not supported with smtp header/body checks. +# .IP \fBDUNNO\fR +# Pretend that the input line did not match any pattern, and inspect the +# next input line. This action can be used to shorten the table search. +# .sp +# For backwards compatibility reasons, Postfix also accepts +# \fBOK\fR but it is (and always has been) treated as \fBDUNNO\fR. +# .sp +# This feature is available in Postfix 2.1 and later. +# .IP "\fBFILTER \fItransport:destination\fR" +# Override the content_filter parameter setting, and inspect +# the next input line. +# After the message is queued, send the entire message through +# the specified external content filter. The \fItransport\fR +# name specifies the first field of a mail delivery agent +# definition in master.cf; the syntax of the next-hop +# \fIdestination\fR is described in the manual page of the +# corresponding delivery agent. More information about +# external content filters is in the Postfix FILTER_README +# file. +# .sp +# Note 1: do not use $\fInumber\fR regular expression +# substitutions for \fItransport\fR or \fIdestination\fR +# unless you know that the information has a trusted origin. +# .sp +# Note 2: this action overrides the main.cf \fBcontent_filter\fR +# setting, and affects all recipients of the message. In the +# case that multiple \fBFILTER\fR actions fire, only the last +# one is executed. +# .sp +# Note 3: the purpose of the FILTER command is to override +# message routing. To override the recipient's \fItransport\fR +# but not the next-hop \fIdestination\fR, specify an empty +# filter \fIdestination\fR (Postfix 2.7 and later), or specify +# a \fItransport:destination\fR that delivers through a +# different Postfix instance (Postfix 2.6 and earlier). Other +# options are using the recipient-dependent \fBtrans\%port\%_maps\fR +# or the sen\%der-dependent +# \fBsender\%_de\%pen\%dent\%_de\%fault\%_trans\%port\%_maps\fR +# features. +# .sp +# This feature is available in Postfix 2.0 and later. +# .sp +# This feature is not supported with smtp header/body checks. +# .IP "\fBHOLD \fIoptional text...\fR" +# Arrange for the message to be placed on the \fBhold\fR queue, +# and inspect the next input line. The message remains on \fBhold\fR +# until someone either deletes it or releases it for delivery. +# Log the optional text if specified, otherwise log a generic +# message. +# +# Mail that is placed on hold can be examined with the +# \fBpostcat\fR(1) command, and can be destroyed or released with +# the \fBpostsuper\fR(1) command. +# .sp +# Note: use "\fBpostsuper -r\fR" to release mail that was kept on +# hold for a significant fraction of \fB$maximal_queue_lifetime\fR +# or \fB$bounce_queue_lifetime\fR, or longer. Use "\fBpostsuper -H\fR" +# only for mail that will not expire within a few delivery attempts. +# .sp +# Note: this action affects all recipients of the message. +# .sp +# This feature is available in Postfix 2.0 and later. +# .sp +# This feature is not supported with smtp header/body checks. +# .IP \fBIGNORE\fR +# Delete the current line from the input, and inspect +# the next input line. See \fBSTRIP\fR for an alternative +# that logs the action. +# .IP "\fBINFO \fIoptional text...\fR +# Log an "info:" record with the \fIoptional text...\fR (or +# log a generic text), and inspect the next input line. This +# action is useful for routine logging or for debugging. +# .sp +# This feature is available in Postfix 2.8 and later. +# .IP "\fBPASS \fIoptional text...\fR" +# Log a "pass:" record with the \fIoptional text...\fR (or +# log a generic text), and turn off header, body, and Milter +# inspection for the remainder of this message. +# .sp +# Note: this feature relies on trust in information that is +# easy to forge. +# .sp +# This feature is available in Postfix 3.2 and later. +# .sp +# This feature is not supported with smtp header/body checks. +# .IP "\fBPREPEND \fItext...\fR" +# Prepend one line with the specified text, and inspect the next +# input line. +# .sp +# Notes: +# .RS +# .IP \(bu +# The prepended text is output on a separate line, immediately +# before the input that triggered the \fBPREPEND\fR action. +# .IP \(bu +# The prepended text is not considered part of the input +# stream: it is not subject to header/body checks or address +# rewriting, and it does not affect the way that Postfix adds +# missing message headers. +# .IP \(bu +# When prepending text before a message header line, the prepended +# text must begin with a valid message header label. +# .IP \(bu +# This action cannot be used to prepend multi-line text. +# .RE +# .IP +# This feature is available in Postfix 2.1 and later. +# .sp +# This feature is not supported with milter_header_checks. +# .IP "\fBREDIRECT \fIuser@domain\fR" +# Write a message redirection request to the queue file, and +# inspect the next input line. After the message is queued, +# it will be sent to the specified address instead of the +# intended recipient(s). +# .sp +# Note: this action overrides the \fBFILTER\fR action, and affects +# all recipients of the message. If multiple \fBREDIRECT\fR actions +# fire, only the last one is executed. +# .sp +# This feature is available in Postfix 2.1 and later. +# .sp +# This feature is not supported with smtp header/body checks. +# .IP "\fBREPLACE \fItext...\fR" +# Replace the current line with the specified text, and inspect the next +# input line. +# .sp +# This feature is available in Postfix 2.2 and later. The +# description below applies to Postfix 2.2.2 and later. +# .sp +# Notes: +# .RS +# .IP \(bu +# When replacing a message header line, the replacement text +# must begin with a valid header label. +# .IP \(bu +# The replaced text remains part of the input stream. Unlike +# the result from the \fBPREPEND\fR action, a replaced message +# header may be subject to address rewriting and may affect +# the way that Postfix adds missing message headers. +# .RE +# .IP "\fBREJECT \fIoptional text...\fR +# Reject the entire message. Do not inspect the remainder of +# the input message. Reply with \fIoptional text...\fR when +# the optional text is specified, otherwise reply with a +# generic error message. +# .sp +# Note: this action disables further header or body_checks inspection +# of the current message and affects all recipients. +# .sp +# Postfix version 2.3 and later support enhanced status codes. +# When no code is specified at the beginning of \fIoptional +# text...\fR, Postfix inserts a default enhanced status code of +# "5.7.1". +# .sp +# This feature is not supported with smtp header/body checks. +# .IP "\fBSTRIP \fIoptional text...\fR" +# Log a "strip:" record with the \fIoptional text...\fR (or +# log a generic text), delete the input line from the input, +# and inspect the next input line. See \fBIGNORE\fR for a +# silent alternative. +# .sp +# This feature is available in Postfix 3.2 and later. +# .IP "\fBWARN \fIoptional text...\fR +# Log a "warning:" record with the \fIoptional text...\fR (or +# log a generic text), and inspect the next input line. This +# action is useful for debugging and for testing a pattern +# before applying more drastic actions. +# BUGS +# Empty lines never match, because some map types mis-behave +# when given a zero-length search string. This limitation may +# be removed for regular expression tables in a future release. +# +# Many people overlook the main limitations of header and body_checks +# rules. +# .IP \(bu +# These rules operate on one logical message header or one body +# line at a time. A decision made for one line is not carried over +# to the next line. +# .IP \(bu +# If text in the message body is encoded +# (RFC 2045) then the rules need to be specified for the encoded +# form. +# .IP \(bu +# Likewise, when message headers are encoded (RFC +# 2047) then the rules need to be specified for the encoded +# form. +# .PP +# Message headers added by the \fBcleanup\fR(8) daemon itself +# are excluded from inspection. Examples of such message headers +# are \fBFrom:\fR, \fBTo:\fR, \fBMessage-ID:\fR, \fBDate:\fR. +# +# Message headers deleted by the \fBcleanup\fR(8) daemon will +# be examined before they are deleted. Examples are: \fBBcc:\fR, +# \fBContent-Length:\fR, \fBReturn-Path:\fR. +# CONFIGURATION PARAMETERS +# .ad +# .fi +# .IP \fBbody_checks\fR +# Lookup tables with content filter rules for message body lines. +# These filters see one physical line at a time, in chunks of +# at most \fB$line_length_limit\fR bytes. +# .IP \fBbody_checks_size_limit\fP +# The amount of content per message body segment (attachment) that is +# subjected to \fB$body_checks\fR filtering. +# .IP \fBheader_checks\fR +# .IP "\fBmime_header_checks\fR (default: \fB$header_checks\fR)" +# .IP "\fBnested_header_checks\fR (default: \fB$header_checks\fR)" +# Lookup tables with content filter rules for message header lines: +# respectively, these are applied to the initial message headers +# (not including MIME headers), to the MIME headers anywhere in +# the message, and to the initial headers of attached messages. +# .sp +# Note: these filters see one logical message header at a time, even +# when a message header spans multiple lines. Message headers that +# are longer than \fB$header_size_limit\fR characters are truncated. +# .IP \fBdisable_mime_input_processing\fR +# While receiving mail, give no special treatment to MIME related +# message headers; all text after the initial message headers is +# considered to be part of the message body. This means that +# \fBheader_checks\fR is applied to all the initial message headers, +# and that \fBbody_checks\fR is applied to the remainder of the +# message. +# .sp +# Note: when used in this manner, \fBbody_checks\fR will process +# a multi-line message header one line at a time. +# EXAMPLES +# .ad +# .fi +# Header pattern to block attachments with bad file name +# extensions. For convenience, the PCRE /x flag is specified, +# so that there is no need to collapse the pattern into a +# single line of text. The purpose of the [[:xdigit:]] +# sub-expressions is to recognize Windows CLSID strings. +# +# .na +# .nf +# /etc/postfix/main.cf: +# header_checks = pcre:/etc/postfix/header_checks.pcre +# +# /etc/postfix/header_checks.pcre: +# /^Content-(Disposition|Type).*name\es*=\es*"?([^;]*(\e.|=2E)( +# ade|adp|asp|bas|bat|chm|cmd|com|cpl|crt|dll|exe| +# hlp|ht[at]| +# inf|ins|isp|jse?|lnk|md[betw]|ms[cipt]|nws| +# \e{[[:xdigit:]]{8}(?:-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12}\e}| +# ops|pcd|pif|prf|reg|sc[frt]|sh[bsm]|swf| +# vb[esx]?|vxd|ws[cfh]))(\e?=)?"?\es*(;|$)/x +# REJECT Attachment name "$2" may not end with ".$4" +# .ad +# .fi +# +# Body pattern to stop a specific HTML browser vulnerability exploit. +# +# .na +# .nf +# /etc/postfix/main.cf: +# body_checks = regexp:/etc/postfix/body_checks +# +# /etc/postfix/body_checks: +# /^<iframe src=(3D)?cid:.* height=(3D)?0 width=(3D)?0>$/ +# REJECT IFRAME vulnerability exploit +# SEE ALSO +# cleanup(8), canonicalize and enqueue Postfix message +# pcre_table(5), format of PCRE lookup tables +# regexp_table(5), format of POSIX regular expression tables +# postconf(1), Postfix configuration utility +# postmap(1), Postfix lookup table management +# postsuper(1), Postfix janitor +# postcat(1), show Postfix queue file contents +# RFC 2045, base64 and quoted-printable encoding rules +# RFC 2047, message header encoding for non-ASCII text +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# CONTENT_INSPECTION_README, Postfix content inspection overview +# BUILTIN_FILTER_README, Postfix built-in content inspection +# BACKSCATTER_README, blocking returned forged mail +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# AUTHOR(S) +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/html2text.rc b/proto/html2text.rc new file mode 100644 index 0000000..9e8819f --- /dev/null +++ b/proto/html2text.rc @@ -0,0 +1,13 @@ +P.vspace.after = 1 +PRE.indent.left = 0 +UL.indents = 4 4 4 4 4 +OL.indents = 4 4 4 4 4 +DL.vspace.before = 0 +DL.vspace.after = 0 +DT.vspace.before = 0 +DT.indent.left = 0 +DD.indent.left = 4 +BLOCKQUOTE.indent.left = 4 +BLOCKQUOTE.indent.right = 0 +A.attributes.internal_link = NONE +A.attributes.external_link = NONE diff --git a/proto/ldap_table b/proto/ldap_table new file mode 100644 index 0000000..fe3626a --- /dev/null +++ b/proto/ldap_table @@ -0,0 +1,723 @@ +#++ +# NAME +# ldap_table 5 +# SUMMARY +# Postfix LDAP client configuration +# SYNOPSIS +# \fBpostmap -q "\fIstring\fB" ldap:/etc/postfix/\fIfilename\fR +# +# \fBpostmap -q - ldap:/etc/postfix/\fIfilename\fB <\fIinputfile\fR +# DESCRIPTION +# The Postfix mail system uses optional tables for address +# rewriting or mail routing. These tables are usually in +# \fBdbm\fR or \fBdb\fR format. +# +# Alternatively, lookup tables can be specified as LDAP databases. +# +# In order to use LDAP lookups, define an LDAP source as a lookup +# table in main.cf, for example: +# +# .nf +# alias_maps = ldap:/etc/postfix/ldap-aliases.cf +# .fi +# +# The file /etc/postfix/ldap-aliases.cf has the same format as +# the Postfix main.cf file, and can specify the parameters +# described below. An example is given at the end of this manual. +# +# This configuration method is available with Postfix version +# 2.1 and later. See the section "OBSOLETE MAIN.CF PARAMETERS" +# below for older Postfix versions. +# +# For details about LDAP SSL and STARTTLS, see the section +# on SSL and STARTTLS below. +# LIST MEMBERSHIP +# .ad +# .fi +# When using LDAP to store lists such as $mynetworks, +# $mydestination, $relay_domains, $local_recipient_maps, +# etc., it is important to understand that the table must +# store each list member as a separate key. The table lookup +# verifies the *existence* of the key. See "Postfix lists +# versus tables" in the DATABASE_README document for a +# discussion. +# +# Do NOT create tables that return the full list of domains +# in $mydestination or $relay_domains etc., or IP addresses +# in $mynetworks. +# +# DO create tables with each matching item as a key and with +# an arbitrary value. With LDAP databases it is not uncommon to +# return the key itself. +# +# For example, NEVER do this in a map defining $mydestination: +# +# .nf +# query_filter = domain=* +# result_attribute = domain +# .fi +# +# Do this instead: +# +# .nf +# query_filter = domain=%s +# result_attribute = domain +# .fi +# GENERAL LDAP PARAMETERS +# .ad +# .fi +# In the text below, default values are given in parentheses. +# Note: don't use quotes in these variables; at least, not until the +# Postfix configuration routines understand how to deal with quoted +# strings. +# .IP "\fBserver_host (default: localhost)\fR" +# The name of the host running the LDAP server, e.g. +# +# .nf +# server_host = ldap.example.com +# .fi +# +# Depending on the LDAP client library you're using, it should +# be possible to specify multiple servers here, with the library +# trying them in order should the first one fail. It should also +# be possible to give each server in the list a different port +# (overriding \fBserver_port\fR below), by naming them like +# +# .nf +# server_host = ldap.example.com:1444 +# .fi +# +# With OpenLDAP, a (list of) LDAP URLs can be used to specify both +# the hostname(s) and the port(s): +# +# .nf +# server_host = ldap://ldap.example.com:1444 +# ldap://ldap2.example.com:1444 +# .fi +# +# All LDAP URLs accepted by the OpenLDAP library are supported, +# including connections over UNIX domain sockets, and LDAP SSL +# (the last one provided that OpenLDAP was compiled with support +# for SSL): +# +# .nf +# server_host = ldapi://%2Fsome%2Fpath +# ldaps://ldap.example.com:636 +# .fi +# .IP "\fBserver_port (default: 389)\fR" +# The port the LDAP server listens on, e.g. +# +# .nf +# server_port = 778 +# .fi +# .IP "\fBtimeout (default: 10 seconds)\fR" +# The number of seconds a search can take before timing out, e.g. +# +# .fi +# timeout = 5 +# .fi +# .IP "\fBsearch_base (No default; you must configure this)\fR" +# The RFC2253 base DN at which to conduct the search, e.g. +# +# .nf +# search_base = dc=your, dc=com +# .fi +# .IP +# With Postfix 2.2 and later this parameter supports the +# following '%' expansions: +# .RS +# .IP "\fB%%\fR" +# This is replaced by a literal '%' character. +# .IP "\fB%s\fR" +# This is replaced by the input key. +# RFC 2253 quoting is used to make sure that the input key +# does not add unexpected metacharacters. +# .IP "\fB%u\fR" +# When the input key is an address of the form user@domain, \fB%u\fR +# is replaced by the (RFC 2253) quoted local part of the address. +# Otherwise, \fB%u\fR is replaced by the entire search string. +# If the localpart is empty, the search is suppressed and returns +# no results. +# .IP "\fB%d\fR" +# When the input key is an address of the form user@domain, \fB%d\fR +# is replaced by the (RFC 2253) quoted domain part of the address. +# Otherwise, the search is suppressed and returns no results. +# .IP "\fB%[SUD]\fR" +# For the \fBsearch_base\fR parameter, the upper-case equivalents +# of the above expansions behave identically to their lower-case +# counter-parts. With the \fBresult_format\fR parameter (previously +# called \fBresult_filter\fR see the OTHER OBSOLETE FEATURES section +# and below), they expand to the corresponding components of input +# key rather than the result value. +# .IP "\fB%[1-9]\fR" +# The patterns %1, %2, ... %9 are replaced by the corresponding +# most significant component of the input key's domain. If the +# input key is \fIuser@mail.example.com\fR, then %1 is \fBcom\fR, +# %2 is \fBexample\fR and %3 is \fBmail\fR. If the input key is +# unqualified or does not have enough domain components to satisfy +# all the specified patterns, the search is suppressed and returns +# no results. +# .RE +# .IP "\fBquery_filter (default: mailacceptinggeneralid=%s)\fR" +# The RFC2254 filter used to search the directory, where \fB%s\fR +# is a substitute for the address Postfix is trying to resolve, +# e.g. +# +# .nf +# query_filter = (&(mail=%s)(paid_up=true)) +# .fi +# +# This parameter supports the following '%' expansions: +# .RS +# .IP "\fB%%\fR" +# This is replaced by a literal '%' character. (Postfix 2.2 and later). +# .IP "\fB%s\fR" +# This is replaced by the input key. +# RFC 2254 quoting is used to make sure that the input key +# does not add unexpected metacharacters. +# .IP "\fB%u\fR" +# When the input key is an address of the form user@domain, \fB%u\fR +# is replaced by the (RFC 2254) quoted local part of the address. +# Otherwise, \fB%u\fR is replaced by the entire search string. +# If the localpart is empty, the search is suppressed and returns +# no results. +# .IP "\fB%d\fR" +# When the input key is an address of the form user@domain, \fB%d\fR +# is replaced by the (RFC 2254) quoted domain part of the address. +# Otherwise, the search is suppressed and returns no results. +# .IP "\fB%[SUD]\fR" +# The upper-case equivalents of the above expansions behave in the +# \fBquery_filter\fR parameter identically to their lower-case +# counter-parts. With the \fBresult_format\fR parameter (previously +# called \fBresult_filter\fR see the OTHER OBSOLETE FEATURES section +# and below), they expand to the corresponding components of input +# key rather than the result value. +# .IP +# The above %S, %U and %D expansions are available with Postfix 2.2 +# and later. +# .IP "\fB%[1-9]\fR" +# The patterns %1, %2, ... %9 are replaced by the corresponding +# most significant component of the input key's domain. If the +# input key is \fIuser@mail.example.com\fR, then %1 is \fBcom\fR, +# %2 is \fBexample\fR and %3 is \fBmail\fR. If the input key is +# unqualified or does not have enough domain components to satisfy +# all the specified patterns, the search is suppressed and returns +# no results. +# .IP +# The above %1, ..., %9 expansions are available with Postfix 2.2 +# and later. +# .RE +# .IP +# The "domain" parameter described below limits the input +# keys to addresses in matching domains. When the "domain" +# parameter is non-empty, LDAP queries for unqualified +# addresses or addresses in non-matching domains are suppressed +# and return no results. +# +# NOTE: DO NOT put quotes around the \fBquery_filter\fR parameter. +# .IP "\fBresult_format (default: \fB%s\fR)\fR" +# Called \fBresult_filter\fR in Postfix releases prior to 2.2. +# Format template applied to result attributes. Most commonly used +# to append (or prepend) text to the result. This parameter supports +# the following '%' expansions: +# .RS +# .IP "\fB%%\fR" +# This is replaced by a literal '%' character. (Postfix 2.2 and later). +# .IP "\fB%s\fR" +# This is replaced by the value of the result attribute. When +# result is empty it is skipped. +# .IP "\fB%u\fR +# When the result attribute value is an address of the form +# user@domain, \fB%u\fR is replaced by the local part of the +# address. When the result has an empty localpart it is skipped. +# .IP "\fB%d\fR" +# When a result attribute value is an address of the form +# user@domain, \fB%d\fR is replaced by the domain part of +# the attribute value. When the result is unqualified it +# is skipped. +# .IP "\fB%[SUD1-9]\fR" +# The upper-case and decimal digit expansions interpolate +# the parts of the input key rather than the result. Their +# behavior is identical to that described with \fBquery_filter\fR, +# and in fact because the input key is known in advance, lookups +# whose key does not contain all the information specified in +# the result template are suppressed and return no results. +# .IP +# The above %S, %U, %D and %1, ..., %9 expansions are available with +# Postfix 2.2 and later. +# .RE +# .IP +# For example, using "result_format = smtp:[%s]" allows one +# to use a mailHost attribute as the basis of a transport(5) +# table. After applying the result format, multiple values +# are concatenated as comma separated strings. The expansion_limit +# and size_limit parameters explained below allow one to +# restrict the number of values in the result, which is +# especially useful for maps that should return a single +# value. +# +# The default value \fB%s\fR specifies that each +# attribute value should be used as is. +# +# This parameter was called \fBresult_filter\fR in Postfix +# releases prior to 2.2. If no "result_format" is specified, +# the value of "result_filter" will be used instead before +# resorting to the default value. This provides compatibility +# with old configuration files. +# +# NOTE: DO NOT put quotes around the result format! +# .IP "\fBdomain (default: no domain list)\fR" +# This is a list of domain names, paths to files, or +# "type:table" databases. When specified, only fully qualified search +# keys with a *non-empty* localpart and a matching domain +# are eligible for lookup: 'user' lookups, bare domain lookups +# and "@domain" lookups are not performed. This can significantly +# reduce the query load on the LDAP server. +# +# .nf +# domain = postfix.org, hash:/etc/postfix/searchdomains +# .fi +# +# It is best not to use LDAP to store the domains eligible +# for LDAP lookups. +# +# NOTE: DO NOT define this parameter for local(8) aliases. +# +# This feature is available in Postfix 1.0 and later. +# .IP "\fBresult_attribute (default: maildrop)\fR" +# The attribute(s) Postfix will read from any directory +# entries returned by the lookup, to be resolved to an email +# address. +# +# .nf +# result_attribute = mailbox, maildrop +# .fi +# +# Don't rely on the default value ("maildrop"). Set the +# result_attribute explicitly in all ldap table configuration +# files. This is particularly relevant when no result_attribute +# is applicable, e.g. cases in which leaf_result_attribute and/or +# terminal_result_attribute are used instead. The default value +# is harmless if "maildrop" is also listed as a leaf or terminal +# result attribute, but it is best to not leave this to chance. +# .IP "\fBspecial_result_attribute (default: empty)\fR" +# The attribute(s) of directory entries that can contain DNs +# or RFC 2255 LDAP URLs. If found, a recursive search +# is performed to retrieve the entry referenced by the DN, or +# the entries matched by the URL query. +# +# .nf +# special_result_attribute = memberdn +# .fi +# +# DN recursion retrieves the same result_attributes as the +# main query, including the special attributes for further +# recursion. +# +# URL processing retrieves only those attributes that are included +# in both the URL definition and as result attributes (ordinary, +# special, leaf or terminal) in the Postfix table definition. +# If the URL lists any of the table's special result attributes, +# these are retrieved and used recursively. A URL that does not +# specify any attribute selection, is equivalent (RFC 2255) to a +# URL that selects all attributes, in which case the selected +# attributes will be the full set of result attributes in the +# Postfix table. +# +# If an LDAP URL attribute-descriptor or the corresponding Postfix +# LDAP table result attribute (but not both) uses RFC 2255 sub-type +# options ("attr;option"), the attribute requested from the LDAP server +# will include the sub-type option. In all other cases, the URL +# attribute and the table attribute must match exactly. Attributes +# with options in both the URL and the Postfix table are requested +# only when the options are identical. LDAP attribute-descriptor +# options are very rarely used, most LDAP users will not +# need to concern themselves with this level of nuanced detail. +# .IP "\fBterminal_result_attribute (default: empty)\fR" +# When one or more terminal result attributes are found in an LDAP +# entry, all other result attributes are ignored and only the terminal +# result attributes are returned. This is useful for delegating expansion +# of group members to a particular host, by using an optional "maildrop" +# attribute on selected groups to route the group to a specific host, +# where the group is expanded, possibly via mailing-list manager or +# other special processing. +# +# .nf +# result_attribute = +# terminal_result_attribute = maildrop +# .fi +# +# When using terminal and/or leaf result attributes, the +# result_attribute is best set to an empty value when it is not +# used, or else explicitly set to the desired value, even if it is +# the default value "maildrop". +# +# This feature is available with Postfix 2.4 or later. +# .IP "\fBleaf_result_attribute (default: empty)\fR" +# When one or more special result attributes are found in a non-terminal +# (see above) LDAP entry, leaf result attributes are excluded from the +# expansion of that entry. This is useful when expanding groups and the +# desired mail address attribute(s) of the member objects obtained via +# DN or URI recursion are also present in the group object. To only +# return the attribute values from the leaf objects and not the +# containing group, add the attribute to the leaf_result_attribute list, +# and not the result_attribute list, which is always expanded. Note, +# the default value of "result_attribute" is not empty, you may want to +# set it explicitly empty when using "leaf_result_attribute" to expand +# the group to a list of member DN addresses. If groups have both +# member DN references AND attributes that hold multiple string valued +# rfc822 addresses, then the string attributes go in "result_attribute". +# The attributes that represent the email addresses of objects +# referenced via a DN (or LDAP URI) go in "leaf_result_attribute". +# +# .nf +# result_attribute = memberaddr +# special_result_attribute = memberdn +# terminal_result_attribute = maildrop +# leaf_result_attribute = mail +# .fi +# +# When using terminal and/or leaf result attributes, the +# result_attribute is best set to an empty value when it is not +# used, or else explicitly set to the desired value, even if it is +# the default value "maildrop". +# +# This feature is available with Postfix 2.4 or later. +# .IP "\fBscope (default: sub)\fR" +# The LDAP search scope: \fBsub\fR, \fBbase\fR, or \fBone\fR. +# These translate into LDAP_SCOPE_SUBTREE, LDAP_SCOPE_BASE, +# and LDAP_SCOPE_ONELEVEL. +# .IP "\fBbind (default: yes)\fR" +# Whether or how to bind to the LDAP server. Newer LDAP +# implementations don't require clients to bind, which saves +# time. Example: +# +# .nf +# # Don't bind +# bind = no +# # Use SIMPLE bind +# bind = yes +# # Use SASL bind +# bind = sasl +# .fi +# +# Postfix versions prior to 2.8 only support "bind = no" which +# means don't bind, and "bind = yes" which means do a SIMPLE bind. +# Postfix 2.8 and later also supports "bind = SASL" when compiled +# with LDAP SASL support as described in LDAP_README, it also adds +# the synonyms "bind = none" and "bind = simple" for "bind = no" +# and "bind = yes" respectively. See the SASL section below for +# additional parameters available with "bind = sasl". +# +# If you do need to bind, you might consider configuring +# Postfix to connect to the local machine on a port that's +# an SSL tunnel to your LDAP server. If your LDAP server +# doesn't natively support SSL, put a tunnel (wrapper, proxy, +# whatever you want to call it) on that system too. This +# should prevent the password from traversing the network in +# the clear. +# .IP "\fBbind_dn (default: empty)\fR" +# If you do have to bind, do it with this distinguished name. Example: +# +# .nf +# bind_dn = uid=postfix, dc=your, dc=com +# .fi +# With "bind = sasl" (see above) the DN may be optional for some SASL +# mechanisms, don't specify a DN if not needed. +# .IP "\fBbind_pw (default: empty)\fR" +# The password for the distinguished name above. If you have +# to use this, you probably want to make the map configuration +# file readable only by the Postfix user. When using the +# obsolete ldap:ldapsource syntax, with map parameters in +# main.cf, it is not possible to securely store the bind +# password. This is because main.cf needs to be world readable +# to allow local accounts to submit mail via the sendmail +# command. Example: +# +# .nf +# bind_pw = postfixpw +# .fi +# With "bind = sasl" (see above) the password may be optional +# for some SASL mechanisms, don't specify a password if not needed. +# .IP "\fBcache (IGNORED with a warning)\fR" +# .IP "\fBcache_expiry (IGNORED with a warning)\fR" +# .IP "\fBcache_size (IGNORED with a warning)\fR" +# The above parameters are NO LONGER SUPPORTED by Postfix. +# Cache support has been dropped from OpenLDAP as of release +# 2.1.13. +# .IP "\fBrecursion_limit (default: 1000)\fR" +# A limit on the nesting depth of DN and URL special result +# attribute evaluation. The limit must be a non-zero positive +# number. +# .IP "\fBexpansion_limit (default: 0)\fR" +# A limit on the total number of result elements returned +# (as a comma separated list) by a lookup against the map. +# A setting of zero disables the limit. Lookups fail with a +# temporary error if the limit is exceeded. Setting the +# limit to 1 ensures that lookups do not return multiple +# values. +# .IP "\fBsize_limit (default: $expansion_limit)\fR" +# A limit on the number of LDAP entries returned by any single +# LDAP search performed as part of the lookup. A setting of +# 0 disables the limit. Expansion of DN and URL references +# involves nested LDAP queries, each of which is separately +# subjected to this limit. +# +# Note: even a single LDAP entry can generate multiple lookup +# results, via multiple result attributes and/or multi-valued +# result attributes. This limit caps the per search resource +# utilization on the LDAP server, not the final multiplicity +# of the lookup result. It is analogous to the "-z" option +# of "ldapsearch". +# .IP "\fBdereference (default: 0)\fR" +# When to dereference LDAP aliases. (Note that this has +# nothing do with Postfix aliases.) The permitted values are +# those legal for the OpenLDAP/UM LDAP implementations: +# .RS +# .IP 0 +# never +# .IP 1 +# when searching +# .IP 2 +# when locating the base object for the search +# .IP 3 +# always +# .RE +# .IP +# See ldap.h or the ldap_open(3) or ldapsearch(1) man pages +# for more information. And if you're using an LDAP package +# that has other possible values, please bring it to the +# attention of the postfix-users@postfix.org mailing list. +# .IP "\fBchase_referrals (default: 0)\fR" +# Sets (or clears) LDAP_OPT_REFERRALS (requires LDAP version +# 3 support). +# .IP "\fBversion (default: 2)\fR" +# Specifies the LDAP protocol version to use. +# .IP "\fBdebuglevel (default: 0)\fR" +# What level to set for debugging in the OpenLDAP libraries. +# LDAP SASL PARAMETERS +# .ad +# .fi +# If you're using the OpenLDAP libraries compiled with SASL +# support, Postfix 2.8 and later built with LDAP SASL support +# as described in LDAP_README can authenticate to LDAP servers +# via SASL. +# +# This enables authentication to the LDAP server via mechanisms +# other than a simple password. The added flexibility has a cost: +# it is no longer practical to set an explicit timeout on the duration +# of an LDAP bind operation. Under adverse conditions, whether a SASL +# bind times out, or if it does, the duration of the timeout is +# determined by the LDAP and SASL libraries. +# +# It is best to use tables that use SASL binds via proxymap(8), this +# way the requesting process can time-out the proxymap request. This +# also lets you tailer the process environment by overriding the +# proxymap(8) import_environment setting in master.cf(5). Special +# environment settings may be needed to configure GSSAPI credential +# caches or other SASL mechanism specific options. The GSSAPI +# credentials used for LDAP lookups may need to be different than +# say those used for the Postfix SMTP client to authenticate to remote +# servers. +# +# Using SASL mechanisms requires LDAP protocol version 3, the default +# protocol version is 2 for backwards compatibility. You must set +# "version = 3" in addition to "bind = sasl". +# +# The following parameters are relevant to using LDAP with SASL +# .IP "\fBsasl_mechs (default: empty)\fR" +# Space separated list of SASL mechanism(s) to try. +# .IP "\fBsasl_realm (default: empty)\fR" +# SASL Realm to use, if applicable. +# .IP "\fBsasl_authz_id (default: empty)\fR" +# The SASL authorization identity to assert, if applicable. +# .IP "\fBsasl_minssf (default: 0)\fR" +# The minimum required sasl security factor required to establish a +# connection. +# LDAP SSL AND STARTTLS PARAMETERS +# .ad +# .fi +# If you're using the OpenLDAP libraries compiled with SSL +# support, Postfix can connect to LDAP SSL servers and can +# issue the STARTTLS command. +# +# LDAP SSL service can be requested by using a LDAP SSL URL +# in the server_host parameter: +# +# .nf +# server_host = ldaps://ldap.example.com:636 +# .fi +# +# STARTTLS can be turned on with the start_tls parameter: +# +# .nf +# start_tls = yes +# .fi +# +# Both forms require LDAP protocol version 3, which has to be set +# explicitly with: +# +# .nf +# version = 3 +# .fi +# +# If any of the Postfix programs querying the map is configured in +# master.cf to run chrooted, all the certificates and keys involved +# have to be copied to the chroot jail. Of course, the private keys +# should only be readable by the user "postfix". +# +# The following parameters are relevant to LDAP SSL and STARTTLS: +# .IP "\fBstart_tls (default: no)\fR" +# Whether or not to issue STARTTLS upon connection to the +# server. Don't set this with LDAP SSL (the SSL session is setup +# automatically when the TCP connection is opened). +# .IP "\fBtls_ca_cert_dir (No default; set either this or tls_ca_cert_file)\fR" +# Directory containing X509 Certification Authority certificates +# in PEM format which are to be recognized by the client in +# SSL/TLS connections. The files each contain one CA certificate. +# The files are looked up by the CA subject name hash value, +# which must hence be available. If more than one CA certificate +# with the same name hash value exist, the extension must be +# different (e.g. 9d66eef0.0, 9d66eef0.1 etc). The search is +# performed in the ordering of the extension number, regardless +# of other properties of the certificates. Use the c_rehash +# utility (from the OpenSSL distribution) to create the +# necessary links. +# .IP "\fBtls_ca_cert_file (No default; set either this or tls_ca_cert_dir)\fR" +# File containing the X509 Certification Authority certificates +# in PEM format which are to be recognized by the client in +# SSL/TLS connections. This setting takes precedence over +# tls_ca_cert_dir. +# .IP "\fBtls_cert (No default; you must set this)\fR" +# File containing client's X509 certificate to be used by +# the client in SSL/ TLS connections. +# .IP "\fBtls_key (No default; you must set this)\fR" +# File containing the private key corresponding to the above +# tls_cert. +# .IP "\fBtls_require_cert (default: no)\fR" +# Whether or not to request server's X509 certificate and +# check its validity when establishing SSL/TLS connections. +# The supported values are \fBno\fR and \fByes\fR. +# .sp +# With \fBno\fR, the server certificate trust chain is not checked, +# but with OpenLDAP prior to 2.1.13, the name in the server +# certificate must still match the LDAP server name. With OpenLDAP +# 2.0.0 to 2.0.11 the server name is not necessarily what you +# specified, rather it is determined (by reverse lookup) from the +# IP address of the LDAP server connection. With OpenLDAP prior to +# 2.0.13, subjectAlternativeName extensions in the LDAP server +# certificate are ignored: the server name must match the subject +# CommonName. The \fBno\fR setting corresponds to the \fBnever\fR +# value of \fBTLS_REQCERT\fR in LDAP client configuration files. +# .sp +# Don't use TLS with OpenLDAP 2.0.x (and especially with x <= 11) +# if you can avoid it. +# .sp +# With \fByes\fR, the server certificate must be issued by a trusted +# CA, and not be expired. The LDAP server name must match one of the +# name(s) found in the certificate (see above for OpenLDAP library +# version dependent behavior). The \fByes\fR setting corresponds to the +# \fBdemand\fR value of \fBTLS_REQCERT\fR in LDAP client configuration +# files. +# .sp +# The "try" and "allow" values of \fBTLS_REQCERT\fR have no equivalents +# here. They are not available with OpenLDAP 2.0, and in any case have +# questionable security properties. Either you want TLS verified LDAP +# connections, or you don't. +# .sp +# The \fByes\fR value only works correctly with Postfix 2.5 and later, +# or with OpenLDAP 2.0. Earlier Postfix releases or later OpenLDAP +# releases don't work together with this setting. Support for LDAP +# over TLS was added to Postfix based on the OpenLDAP 2.0 API. +# .IP "\fBtls_random_file (No default)\fR" +# Path of a file to obtain random bits from when /dev/[u]random +# is not available, to be used by the client in SSL/TLS +# connections. +# .IP "\fBtls_cipher_suite (No default)\fR" +# Cipher suite to use in SSL/TLS negotiations. +# EXAMPLE +# .ad +# .fi +# Here's a basic example for using LDAP to look up local(8) +# aliases. +# Assume that in main.cf, you have: +# +# .nf +# alias_maps = hash:/etc/aliases, +# ldap:/etc/postfix/ldap-aliases.cf +# .fi +# +# and in ldap:/etc/postfix/ldap-aliases.cf you have: +# +# .nf +# server_host = ldap.example.com +# search_base = dc=example, dc=com +# .fi +# +# Upon receiving mail for a local address "ldapuser" that +# isn't found in the /etc/aliases database, Postfix will +# search the LDAP server listening at port 389 on ldap.example.com. +# It will bind anonymously, search for any directory entries +# whose mailacceptinggeneralid attribute is "ldapuser", read +# the "maildrop" attributes of those found, and build a list +# of their maildrops, which will be treated as RFC822 addresses +# to which the message will be delivered. +# OBSOLETE MAIN.CF PARAMETERS +# .ad +# .fi +# For backwards compatibility with Postfix version 2.0 and earlier, +# LDAP parameters can also be defined in main.cf. Specify +# as LDAP source a name that doesn't begin with a slash or +# a dot. The LDAP parameters will then be accessible as the +# name you've given the source in its definition, an underscore, +# and the name of the parameter. For example, if the map is +# specified as "ldap:\fIldapsource\fR", the "server_host" +# parameter below would be defined in main.cf as +# "\fIldapsource\fR_server_host". +# +# Note: with this form, the passwords for the LDAP sources are +# written in main.cf, which is normally world-readable. Support +# for this form will be removed in a future Postfix version. +# OTHER OBSOLETE FEATURES +# .ad +# .fi +# For backwards compatibility with the pre +# 2.2 LDAP clients, \fBresult_filter\fR can for now be used instead +# of \fBresult_format\fR, when the latter parameter is not also set. +# The new name better reflects the function of the parameter. This +# compatibility interface may be removed in a future release. +# SEE ALSO +# postmap(1), Postfix lookup table manager +# postconf(5), configuration parameters +# mysql_table(5), MySQL lookup tables +# pgsql_table(5), PostgreSQL lookup tables +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# LDAP_README, Postfix LDAP client guide +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# AUTHOR(S) +# .ad +# .fi +# Carsten Hoeger, +# Hery Rakotoarisoa, +# John Hensley, +# Keith Stevenson, +# LaMont Jones, +# Liviu Daia, +# Manuel Guesdon, +# Mike Mattice, +# Prabhat K Singh, +# Sami Haahtinen, +# Samuel Tardieu, +# Victor Duchovni, +# and many others. +#-- diff --git a/proto/lmdb_table b/proto/lmdb_table new file mode 100644 index 0000000..5bbbc14 --- /dev/null +++ b/proto/lmdb_table @@ -0,0 +1,119 @@ +#++ +# NAME +# lmdb_table 5 +# SUMMARY +# Postfix LMDB adapter +# SYNOPSIS +# \fBpostmap lmdb:/etc/postfix/\fIfilename\fR +# .br +# \fBpostmap -i lmdb:/etc/postfix/\fIfilename\fB <\fIinputfile\fR +# +# \fBpostmap -d "\fIkey\fB" lmdb:/etc/postfix/\fIfilename\fR +# .br +# \fBpostmap -d - lmdb:/etc/postfix/\fIfilename\fB <\fIinputfile\fR +# +# \fBpostmap -q "\fIkey\fB" lmdb:/etc/postfix/\fIfilename\fR +# .br +# \fBpostmap -q - lmdb:/etc/postfix/\fIfilename\fB <\fIinputfile\fR +# DESCRIPTION +# The Postfix LMDB adapter provides access to a persistent, +# memory-mapped, key-value store. The database size is limited +# only by the size of the memory address space (typically 31 +# or 47 bits on 32-bit or 64-bit CPUs, respectively) and by +# the available file system space. +# REQUESTS +# .ad +# .fi +# The LMDB adapter supports all Postfix lookup table operations. +# This makes LMDB suitable for Postfix address rewriting, +# routing, access policies, caches, or any information that +# can be stored under a fixed lookup key. +# +# When a transaction fails due to a full database, Postfix +# resizes the database and retries the transaction. +# +# Postfix table lookups may generate partial search keys such +# as domain names without one or more subdomains, network +# addresses without one or more least-significant octets, or +# email addresses without the localpart, address extension +# or domain portion. This behavior is also found with, for +# example, btree:, hash:, or ldap: tables. +# +# Changes to an LMDB database do not trigger an automatic +# daemon restart, and do not require a daemon restart with +# "\fBpostfix reload\fR". +# RELIABILITY +# .ad +# .fi +# LMDB's copy-on-write architecture provides safe updates, +# at the cost of using more space than some other flat-file +# databases. Read operations are memory-mapped for speed. +# Write operations are not memory-mapped to avoid silent +# corruption due to stray pointer bugs. +# +# Multiple processes can safely update an LMDB database without +# serializing requests through the proxymap(8) service. This +# makes LMDB suitable as a shared cache for verify(8) or +# postscreen(8) services. +# SYNCHRONIZATION +# .ad +# .fi +# The Postfix LMDB adapter does not use LMDB's built-in locking +# scheme, because that would require world-writable lockfiles +# and would violate the Postfix security model. Instead, +# Postfix uses fcntl(2) locks with whole-file granularity. +# Programs that use LMDB's built-in locking protocol will +# corrupt a Postfix LMDB database or will read garbage. +# +# Every Postfix LMDB database read or write transaction must +# be protected from start to end with a shared or exclusive +# fcntl(2) lock. A writer may atomically downgrade an exclusive +# lock to a shared lock, but it must hold an exclusive lock +# while opening another write transaction. +# +# Note that fcntl(2) locks do not protect transactions within +# the same process against each other. If a program cannot +# avoid making simultaneous database requests, then it must +# protect its transactions with in-process locks, in addition +# to the per-process fcntl(2) locks. +# CONFIGURATION PARAMETERS +# .ad +# .fi +# Short-lived programs automatically pick up changes to +# main.cf. With long-running daemon programs, Use the command +# "\fBpostfix reload\fR" after a configuration change. +# .IP "\fBlmdb_map_size (16777216)\fR" +# The initial OpenLDAP LMDB database size limit in bytes. +# SEE ALSO +# postconf(1), Postfix supported lookup tables +# postmap(1), Postfix lookup table maintenance +# postconf(5), configuration parameters +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# LMDB_README, Postfix OpenLDAP LMDB howto +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# HISTORY +# LMDB support was introduced with Postfix version 2.11. +# AUTHOR(S) +# Howard Chu +# Symas Corporation +# +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/manual-format b/proto/manual-format new file mode 100644 index 0000000..2e34b9a --- /dev/null +++ b/proto/manual-format @@ -0,0 +1,21 @@ +Be consistent and improve the order later. + +NAME +DESCRIPTION +SECURITY +STANDARDS +DIAGNOSTICS +BUGS +ENVIRONMENT +CONFIGURATION PARAMETERS +FILES +SEE ALSO +daemons +commands +configuration files +master +syslogd +README FILES +LICENSE +HISTORY +AUTHOR(S) diff --git a/proto/master b/proto/master new file mode 100644 index 0000000..28040b6 --- /dev/null +++ b/proto/master @@ -0,0 +1,257 @@ +#++ +# NAME +# master 5 +# SUMMARY +# Postfix master process configuration file format +# DESCRIPTION +# The Postfix mail system is implemented by small number of +# (mostly) client commands that are invoked by users, and by +# a larger number of services that run in the background. +# +# Postfix services are implemented by daemon processes. These +# run in the background, started on-demand by the \fBmaster\fR(8) +# process. The master.cf configuration file defines how a +# client program connects to a service, and what daemon +# program runs when a service is requested. Most daemon +# processes are short-lived and terminate voluntarily after +# serving \fBmax_use\fR clients, or after inactivity for +# \fBmax_idle\fR or more units of time. +# +# All daemons specified here must speak a Postfix-internal +# protocol. In order to execute non-Postfix software use the +# \fBlocal\fR(8), \fBpipe\fR(8) or \fBspawn\fR(8) services, or +# execute the software with \fBinetd\fR(8) or equivalent. +# .PP +# After changing master.cf you must execute "\fBpostfix reload\fR" +# to reload the configuration. +# SYNTAX +# .ad +# .fi +# The general format of the master.cf file is as follows: +# .IP \(bu +# Empty lines and whitespace-only lines are ignored, as are +# lines whose first non-whitespace character is a `#'. +# .IP \(bu +# A logical line starts with non-whitespace text. A line that +# starts with whitespace continues a logical line. +# .IP \(bu +# Each logical line defines a single Postfix service. +# Each service is identified by its name and type as described +# below. When multiple lines specify the same service name +# and type, only the last one is remembered. Otherwise, the +# order of master.cf service definitions does not matter. +# .PP +# Each logical line consists of eight fields separated by +# whitespace. These are described below in the order as they +# appear in the master.cf file. +# +# Where applicable a field of "-" requests that the built-in +# default value be used. For boolean fields specify "y" or +# "n" to override the default value. +# .IP "\fBService name\fR" +# The service name syntax depends on the service type as +# described next. +# .IP "\fBService type\fR" +# Specify one of the following service types: +# .RS +# .IP \fBinet\fR +# The service listens on a TCP/IP socket and is accessible +# via the network. +# +# The service name is specified as \fIhost:port\fR, denoting +# the host and port on which new connections should be +# accepted. The host part (and colon) may be omitted. Either +# host or port may be given in symbolic form (see \fBhosts\fR(5) or +# \fBservices\fR(5)) or in numeric form (IP address or port number). +# Host information may be enclosed inside "[]"; this form +# is necessary only with IPv6 addresses. +# .sp +# Examples: a service named \fB127.0.0.1:smtp\fR or \fB::1:smtp\fR +# receives +# mail via the loopback interface only; and a service named +# \fB10025\fR accepts connections on TCP port 10025 via +# all interfaces configured with the \fBinet_interfaces\fR +# parameter. +# +# .sp +# Note: with Postfix version 2.2 and later specify +# "\fBinet_interfaces = loopback-only\fR" in main.cf, instead +# of hard-coding loopback IP address information in master.cf +# or in main.cf. +# .IP \fBunix\fR +# The service listens on a UNIX-domain stream socket and is +# accessible for local clients only. +# +# The service name is a pathname relative to the Postfix +# queue directory (pathname controlled with the \fBqueue_directory\fR +# configuration parameter in main.cf). +# .sp +# On Solaris 8 and earlier systems the \fBunix\fR type is +# implemented with streams sockets. +# .IP \fBunix-dgram\fR +# The service listens on a UNIX-domain datagram socket and is +# accessible for local clients only. +# +# The service name is a pathname relative to the Postfix +# queue directory (pathname controlled with the \fBqueue_directory\fR +# configuration parameter in main.cf). +# .IP "\fBfifo\fR (obsolete)" +# The service listens on a FIFO (named pipe) and is accessible +# for local clients only. +# +# The service name is a pathname relative to the Postfix +# queue directory (pathname controlled with the \fBqueue_directory\fR +# configuration parameter in main.cf). +# .IP \fBpass\fR +# The service listens on a UNIX-domain stream socket, and is +# accessible to local clients only. It receives one open +# connection (file descriptor passing) per connection request. +# +# The service name is a pathname relative to the Postfix +# queue directory (pathname controlled with the \fBqueue_directory\fR +# configuration parameter in main.cf). +# .sp +# On Solaris 8 and earlier systems the \fBpass\fR type is +# implemented with streams sockets. +# +# This feature is available as of Postfix version 2.5. +# .RE +# .IP "\fBPrivate (default: y)\fR" +# Whether a service is internal to Postfix (pathname starts +# with \fBprivate/\fR), or exposed through Postfix command-line +# tools (pathname starts with \fBpublic/\fR). +# Internet (type \fBinet\fR) services can't be private. +# .IP "\fBUnprivileged (default: y)\fR" +# Whether the service runs with root privileges or as the +# owner of the Postfix system (the owner name is controlled +# by the \fBmail_owner\fR configuration variable in the +# main.cf file). +# .sp +# The \fBlocal\fR(8), \fBpipe\fR(8), \fBspawn\fR(8), and +# \fBvirtual\fR(8) daemons require privileges. +# .IP "\fBChroot (default: Postfix >= 3.0: n, Postfix < 3.0: y)\fR" +# Whether or not the service runs chrooted to the mail queue +# directory (pathname is controlled by the \fBqueue_directory\fR +# configuration variable in the main.cf file). +# .sp +# Chroot should not be used with the \fBlocal\fR(8), +# \fBpipe\fR(8), \fBspawn\fR(8), and \fBvirtual\fR(8) daemons. +# Although the +# \fBproxymap\fR(8) server can run chrooted, doing so defeats +# most of the purpose of having that service in the first +# place. +# .sp +# The files in the examples/chroot-setup subdirectory of the +# Postfix source show how to set up a Postfix chroot environment +# on a variety of systems. See also BASIC_CONFIGURATION_README +# for issues related to running daemons chrooted. +# .IP "\fBWake up time (default: 0)\fR" +# Automatically wake up the named service after the specified +# number of seconds. The wake up is implemented by connecting +# to the service and sending a wake up request. A ? at the +# end of the wake-up time field requests that no wake up +# events be sent before the first time a service is used. +# Specify 0 for no automatic wake up. +# .sp +# The \fBpickup\fR(8), \fBqmgr\fR(8) and \fBflush\fR(8) +# daemons require a wake up timer. +# .IP "\fBProcess limit (default: $default_process_limit)\fR" +# The maximum number of processes that may execute this +# service simultaneously. Specify 0 for no process count limit. +# .sp +# NOTE: Some Postfix services must be configured as a +# single-process service (for example, \fBqmgr\fR(8)) and +# some services must be configured with no process limit (for +# example, \fBcleanup\fR(8)). These limits must not be +# changed. +# .IP "\fBCommand name + arguments\fR" +# The command to be executed. Characters that are special +# to the shell such as ">" or "|" have no special meaning +# here, and quotes cannot be used to protect arguments +# containing whitespace. To protect whitespace, use "{" +# and "}" as described below. +# .sp +# The command name is relative to the Postfix daemon directory +# (pathname is controlled by the \fBdaemon_directory\fR +# configuration variable). +# .sp +# The command argument syntax for specific commands is +# specified in the respective daemon manual page. +# .sp +# The following command-line options have the same effect for +# all daemon programs: +# .RS +# .IP \fB-D\fR +# Run the daemon under control by the command specified with +# the \fBdebugger_command\fR variable in the main.cf +# configuration file. See DEBUG_README for hints and tips. +# .IP "\fB-o { \fIname\fR = \fIvalue\fB }\fR (long form, Postfix >= 3.0)" +# .IP "\fB-o \fIname\fR=\fIvalue\fR (short form)" +# Override the named main.cf configuration parameter. The +# parameter value can refer to other parameters as \fI$name\fR +# etc., just like in main.cf. See \fBpostconf\fR(5) for +# syntax. +# .sp +# NOTE 1: With the "long form" shown above, whitespace +# after "{", around "=", and before "}" is ignored, and +# whitespace within the parameter value is preserved. +# .sp +# NOTE 2: with the "short form" shown above, do not specify +# whitespace around the "=" or in +# parameter values. To specify a parameter value that contains +# whitespace, use the long form described above, or use commas +# instead of spaces, or specify the value in main.cf. Example: +# .sp +# .nf +# /etc/postfix/master.cf: +# submission inet .... smtpd +# -o smtpd_xxx_yyy=$submission_xxx_yyy +# .sp +# /etc/postfix/main.cf +# submission_xxx_yyy = text with whitespace... +# .fi +# .sp +# NOTE 3: Over-zealous use of parameter overrides makes the +# Postfix configuration hard to understand and maintain. At +# a certain point, it might be easier to configure multiple +# instances of Postfix, instead of configuring multiple +# personalities via master.cf. +# .IP \fB-v\fR +# Increase the verbose logging level. Specify multiple \fB-v\fR +# options to make a Postfix daemon process increasingly verbose. +# .IP "Other command-line arguments" +# Specify "{" and "}" around command arguments that contain +# whitespace (Postfix 3.0 and later). Whitespace +# after "{" and before "}" is ignored. +# SEE ALSO +# master(8), process manager +# postconf(5), configuration parameters +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# BASIC_CONFIGURATION_README, basic configuration +# DEBUG_README, Postfix debugging +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# AUTHOR(S) +# Initial version by +# Magnus Baeck +# Lund Institute of Technology +# Sweden +# +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/memcache_table b/proto/memcache_table new file mode 100644 index 0000000..c97a9b4 --- /dev/null +++ b/proto/memcache_table @@ -0,0 +1,236 @@ +#++ +# NAME +# memcache_table 5 +# SUMMARY +# Postfix memcache client configuration +# SYNOPSIS +# \fBpostmap -q "\fIstring\fB" memcache:/etc/postfix/\fIfilename\fR +# +# \fBpostmap -q - memcache:/etc/postfix/\fIfilename\fB <\fIinputfile\fR +# DESCRIPTION +# The Postfix mail system uses optional tables for address +# rewriting or mail routing. These tables are usually in +# \fBdbm\fR or \fBdb\fR format. +# +# Alternatively, lookup tables can be specified as memcache +# instances. To use memcache lookups, define a memcache +# source as a lookup table in main.cf, for example: +# +# .nf +# virtual_alias_maps = memcache:/etc/postfix/memcache-aliases.cf +# .fi +# +# The file /etc/postfix/memcache-aliases.cf has the same +# format as the Postfix main.cf file, and specifies the +# parameters described below. +# +# The Postfix memcache client supports the lookup, update, +# delete and sequence (first/next) operations. The sequence +# operation requires a backup database that supports the +# operation. +# MEMCACHE MAIN PARAMETERS +# .ad +# .fi +# .IP "\fBmemcache (default: inet:localhost:11211)\fR" +# The memcache server (note: singular) that Postfix will try +# to connect to. For a TCP server specify "inet:" followed by +# a hostname or address, ":", and a port name or number. +# Specify an IPv6 address inside "[]". +# For a UNIX-domain server specify "unix:" followed by the +# socket pathname. Examples: +# +# .nf +# memcache = inet:memcache.example.com:11211 +# memcache = inet:127.0.0.1:11211 +# memcache = inet:[fc00:8d00:189::3]:11211 +# memcache = unix:/path/to/socket +# .fi +# +# NOTE: to access a UNIX-domain socket with the proxymap(8) +# server, the socket must be accessible by the unprivileged +# postfix user. +# .IP "\fBbackup (default: undefined)\fR" +# An optional Postfix database that provides persistent backup +# for the memcache database. The Postfix memcache client will +# update the memcache database whenever it looks up or changes +# information in the persistent database. Specify a Postfix +# "type:table" database. Examples: +# +# .nf +# # Non-shared postscreen cache. +# backup = btree:/var/lib/postfix/postscreen_cache_map +# +# # Shared postscreen cache for processes on the same host. +# backup = proxy:btree:/var/lib/postfix/postscreen_cache_map +# .fi +# +# Access to remote proxymap servers is under development. +# +# NOTE 1: When sharing a persistent \fBpostscreen\fR(8) or +# \fBverify\fR(8) cache, disable automatic cache cleanup (set +# *_cache_cleanup_interval = 0) except with one Postfix +# instance that will be responsible for cache cleanup. +# +# NOTE 2: When multiple tables share the same memcache +# database, each table should use the \fBkey_format\fR feature +# (see below) to prepend its own unique string to the lookup +# key. Otherwise, automatic \fBpostscreen\fR(8) or \fBverify\fR(8) +# cache cleanup may not work. +# +# NOTE 3: When the backup database is accessed with "proxy:" +# lookups, the full backup database name (including the +# "proxy:" prefix) must be specified in the proxymap server's +# proxy_read_maps or proxy_write_maps setting (depending on +# whether the access is read-only or read-write). +# .IP "\fBflags (default: 0)\fR" +# Optional flags that should be stored along with a memcache +# update. The flags are ignored when looking up information. +# .IP "\fBttl (default: 3600)\fR" +# The expiration time in seconds of memcache updates. +# +# NOTE 1: When using a memcache table as \fBpostscreen\fR(8) +# or \fBverify\fR(8) cache without persistent backup, specify +# a zero *_cache_cleanup_interval value with all Postfix +# instances that use the memcache, and specify the largest +# \fBpostscreen\fR(8) *_ttl value or \fBverify\fR(8) *_expire_time +# value as the memcache table's \fBttl\fR value. +# +# NOTE 2: According to memcache protocol documentation, a +# value greater than 30 days (2592000 seconds) specifies +# absolute UNIX +# time. Smaller values are relative to the time of the update. +# MEMCACHE KEY PARAMETERS +# .ad +# .fi +# .IP "\fBkey_format (default: %s)\fB" +# Format of the lookup and update keys that the Postfix +# memcache client sends to the memcache server. +# By default, these are the same as the lookup and update +# keys that the memcache client receives from Postfix +# applications. +# +# NOTE 1: The \fBkey_format\fR feature is not used for \fBbackup\fR +# database requests. +# +# NOTE 2: When multiple tables share the same memcache +# database, each table should prepend its own unique string +# to the lookup key. Otherwise, automatic \fBpostscreen\fR(8) +# or \fBverify\fR(8) cache cleanup may not work. +# +# Examples: +# +# .nf +# key_format = aliases:%s +# key_format = verify:%s +# key_format = postscreen:%s +# .fi +# +# The \fBkey_format\fR parameter supports the following '%' +# expansions: +# .RS +# .IP "\fB%%\fR" +# This is replaced by a literal '%' character. +# .IP "\fB%s\fR" +# This is replaced by the memcache client input key. +# .IP "\fB%u\fR" +# When the input key is an address of the form user@domain, +# \fB%u\fR is replaced by the SQL quoted local part of the +# address. Otherwise, \fB%u\fR is replaced by the entire +# search string. If the localpart is empty, a lookup is +# silently suppressed and returns no results (an update is +# skipped with a warning). +# .IP "\fB%d\fR" +# When the input key is an address of the form user@domain, +# \fB%d\fR is replaced by the domain part of the address. +# Otherwise, a lookup is silently suppressed and returns no +# results (an update is skipped with a warning). +# .IP "\fB%[SUD]\fR" +# The upper-case equivalents of the above expansions behave +# in the \fBkey_format\fR parameter identically to their +# lower-case counter-parts. +# .IP "\fB%[1-9]\fR" +# The patterns %1, %2, ... %9 are replaced by the corresponding +# most significant component of the input key's domain. If +# the input key is \fIuser@mail.example.com\fR, then %1 is +# \fBcom\fR, %2 is \fBexample\fR and %3 is \fBmail\fR. If the +# input key is unqualified or does not have enough domain +# components to satisfy all the specified patterns, a lookup +# is silently suppressed and returns no results (an update +# is skipped with a warning). +# .RE +# .IP "\fBdomain (default: no domain list)\fR" +# This feature can significantly reduce database server load. +# Specify a list of domain names, paths to files, or "type:table" +# databases. +# When specified, only fully qualified search keys with a +# *non-empty* localpart and a matching domain are eligible +# for lookup or update: bare 'user' lookups, bare domain +# lookups and "@domain" lookups are silently skipped (updates +# are skipped with a warning). Example: +# +# .nf +# domain = example.com, hash:/etc/postfix/searchdomains +# .fi +# MEMCACHE ERROR CONTROLS +# .ad +# .fi +# .IP "\fBdata_size_limit (default: 10240)\fR" +# The maximal memcache reply data length in bytes. +# .IP "\fBline_size_limit (default: 1024)\fR" +# The maximal memcache reply line length in bytes. +# .IP "\fBmax_try (default: 2)\fR" +# The number of times to try a memcache command before giving +# up. The memcache client does not retry a command when the +# memcache server accepts no connection. +# .IP "\fBretry_pause (default: 1)\fR" +# The time in seconds before retrying a failed memcache command. +# .IP "\fBtimeout (default: 2)\fR" +# The time limit for sending a memcache command and for +# receiving a memcache reply. +# BUGS +# The Postfix memcache client cannot be used for security-sensitive +# tables such as \fBalias_maps\fR (these may contain +# "\fI|command\fR and "\fI/file/name\fR" destinations), or +# \fBvirtual_uid_maps\fR, \fBvirtual_gid_maps\fR and +# \fBvirtual_mailbox_maps\fR (these specify UNIX process +# privileges or "\fI/file/name\fR" destinations). In a typical +# deployment a memcache database is writable by any process +# that can talk to the memcache server; in contrast, +# security-sensitive tables must never be writable by the +# unprivileged Postfix user. +# +# The Postfix memcache client requires additional configuration +# when used as \fBpostscreen\fR(8) or \fBverify\fR(8) cache. +# For details see the \fBbackup\fR and \fBttl\fR parameter +# discussions in the MEMCACHE MAIN PARAMETERS section above. +# SEE ALSO +# postmap(1), Postfix lookup table manager +# postconf(5), configuration parameters +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# MEMCACHE_README, Postfix memcache client guide +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# HISTORY +# .ad +# .fi +# Memcache support was introduced with Postfix version 2.9. +# AUTHOR(S) +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/mysql_table b/proto/mysql_table new file mode 100644 index 0000000..6870acf --- /dev/null +++ b/proto/mysql_table @@ -0,0 +1,401 @@ +#++ +# NAME +# mysql_table 5 +# SUMMARY +# Postfix MySQL client configuration +# SYNOPSIS +# \fBpostmap -q "\fIstring\fB" mysql:/etc/postfix/\fIfilename\fR +# +# \fBpostmap -q - mysql:/etc/postfix/\fIfilename\fB <\fIinputfile\fR +# DESCRIPTION +# The Postfix mail system uses optional tables for address +# rewriting or mail routing. These tables are usually in +# \fBdbm\fR or \fBdb\fR format. +# +# Alternatively, lookup tables can be specified as MySQL databases. +# In order to use MySQL lookups, define a MySQL source as a lookup +# table in main.cf, for example: +# .nf +# alias_maps = mysql:/etc/postfix/mysql-aliases.cf +# .fi +# +# The file /etc/postfix/mysql-aliases.cf has the same format as +# the Postfix main.cf file, and can specify the parameters +# described below. +# LIST MEMBERSHIP +# .ad +# .fi +# When using SQL to store lists such as $mynetworks, +# $mydestination, $relay_domains, $local_recipient_maps, +# etc., it is important to understand that the table must +# store each list member as a separate key. The table lookup +# verifies the *existence* of the key. See "Postfix lists +# versus tables" in the DATABASE_README document for a +# discussion. +# +# Do NOT create tables that return the full list of domains +# in $mydestination or $relay_domains etc., or IP addresses +# in $mynetworks. +# +# DO create tables with each matching item as a key and with +# an arbitrary value. With SQL databases it is not uncommon to +# return the key itself or a constant value. +# MYSQL PARAMETERS +# .ad +# .fi +# .IP "\fBhosts\fR" +# The hosts that Postfix will try to connect to and query from. +# Specify \fIunix:\fR for UNIX domain sockets, \fIinet:\fR for TCP +# connections (default). Examples: +# .nf +# hosts = inet:host1.some.domain inet:host2.some.domain:port +# hosts = host1.some.domain host2.some.domain:port +# hosts = unix:/file/name +# .fi +# +# The hosts are tried in random order, with all connections over +# UNIX domain sockets being tried before those over TCP. The +# connections are automatically closed after being idle for about +# 1 minute, and are re-opened as necessary. Postfix versions 2.0 +# and earlier do not randomize the host order. +# +# NOTE: if you specify localhost as a hostname (even if you +# prefix it with \fIinet:\fR), MySQL will connect to the default +# UNIX domain socket. In order to instruct MySQL to connect to +# localhost over TCP you have to specify +# .nf +# hosts = 127.0.0.1 +# .fi +# .IP "\fBuser, password\fR" +# The user name and password to log into the mysql server. +# Example: +# .nf +# user = someone +# password = some_password +# .fi +# .IP "\fBdbname\fR" +# The database name on the servers. Example: +# .nf +# dbname = customer_database +# .fi +# .IP "\fBquery\fR" +# The SQL query template used to search the database, where \fB%s\fR +# is a substitute for the address Postfix is trying to resolve, +# e.g. +# .nf +# query = SELECT replacement FROM aliases WHERE mailbox = '%s' +# .fi +# +# By default, every query must return a result set (instead +# of storing its results in a table); with "\fBrequire_result_set +# = no\fR" (Postfix 3.2 and later), the absence of a result +# set is treated as "not found". +# +# This parameter supports the following '%' expansions: +# .RS +# .IP "\fB%%\fR" +# This is replaced by a literal '%' character. +# .IP "\fB%s\fR" +# This is replaced by the input key. +# SQL quoting is used to make sure that the input key does not +# add unexpected metacharacters. +# .IP "\fB%u\fR" +# When the input key is an address of the form user@domain, \fB%u\fR +# is replaced by the SQL quoted local part of the address. +# Otherwise, \fB%u\fR is replaced by the entire search string. +# If the localpart is empty, the query is suppressed and returns +# no results. +# .IP "\fB%d\fR" +# When the input key is an address of the form user@domain, \fB%d\fR +# is replaced by the SQL quoted domain part of the address. +# Otherwise, the query is suppressed and returns no results. +# .IP "\fB%[SUD]\fR" +# The upper-case equivalents of the above expansions behave in the +# \fBquery\fR parameter identically to their lower-case counter-parts. +# With the \fBresult_format\fR parameter (see below), they expand the +# input key rather than the result value. +# .IP "\fB%[1-9]\fR" +# The patterns %1, %2, ... %9 are replaced by the corresponding +# most significant component of the input key's domain. If the +# input key is \fIuser@mail.example.com\fR, then %1 is \fBcom\fR, +# %2 is \fBexample\fR and %3 is \fBmail\fR. If the input key is +# unqualified or does not have enough domain components to satisfy +# all the specified patterns, the query is suppressed and returns +# no results. +# .RE +# .IP +# The \fBdomain\fR parameter described below limits the input +# keys to addresses in matching domains. When the \fBdomain\fR +# parameter is non-empty, SQL queries for unqualified addresses +# or addresses in non-matching domains are suppressed +# and return no results. +# +# This parameter is available with Postfix 2.2. In prior releases +# the SQL query was built from the separate parameters: +# \fBselect_field\fR, \fBtable\fR, \fBwhere_field\fR and +# \fBadditional_conditions\fR. The mapping from the old parameters +# to the equivalent query is: +# +# .nf +# SELECT [\fBselect_field\fR] +# FROM [\fBtable\fR] +# WHERE [\fBwhere_field\fR] = '%s' +# [\fBadditional_conditions\fR] +# .fi +# +# The '%s' in the \fBWHERE\fR clause expands to the escaped search string. +# With Postfix 2.2 these legacy parameters are used if the \fBquery\fR +# parameter is not specified. +# +# NOTE: DO NOT put quotes around the query parameter. +# .IP "\fBresult_format (default: \fB%s\fR)\fR" +# Format template applied to result attributes. Most commonly used +# to append (or prepend) text to the result. This parameter supports +# the following '%' expansions: +# .RS +# .IP "\fB%%\fR" +# This is replaced by a literal '%' character. +# .IP "\fB%s\fR" +# This is replaced by the value of the result attribute. When +# result is empty it is skipped. +# .IP "\fB%u\fR +# When the result attribute value is an address of the form +# user@domain, \fB%u\fR is replaced by the local part of the +# address. When the result has an empty localpart it is skipped. +# .IP "\fB%d\fR" +# When a result attribute value is an address of the form +# user@domain, \fB%d\fR is replaced by the domain part of +# the attribute value. When the result is unqualified it +# is skipped. +# .IP "\fB%[SUD1-9]\fR" +# The upper-case and decimal digit expansions interpolate +# the parts of the input key rather than the result. Their +# behavior is identical to that described with \fBquery\fR, +# and in fact because the input key is known in advance, queries +# whose key does not contain all the information specified in +# the result template are suppressed and return no results. +# .RE +# .IP +# For example, using "result_format = smtp:[%s]" allows one +# to use a mailHost attribute as the basis of a transport(5) +# table. After applying the result format, multiple values +# are concatenated as comma separated strings. The expansion_limit +# and parameter explained below allows one to restrict the number +# of values in the result, which is especially useful for maps that +# must return at most one value. +# +# The default value \fB%s\fR specifies that each result value should +# be used as is. +# +# This parameter is available with Postfix 2.2 and later. +# +# NOTE: DO NOT put quotes around the result format! +# .IP "\fBdomain (default: no domain list)\fR" +# This is a list of domain names, paths to files, or "type:table" +# databases. When specified, only fully qualified search keys +# with a *non-empty* localpart and a matching domain are +# eligible for lookup: 'user' lookups, bare domain lookups +# and "@domain" lookups are not performed. This can significantly +# reduce the query load on the MySQL server. +# .nf +# domain = postfix.org, hash:/etc/postfix/searchdomains +# .fi +# +# It is best not to use SQL to store the domains eligible +# for SQL lookups. +# +# This parameter is available with Postfix 2.2 and later. +# +# NOTE: DO NOT define this parameter for local(8) aliases, +# because the input keys are always unqualified. +# .IP "\fBexpansion_limit (default: 0)\fR" +# A limit on the total number of result elements returned +# (as a comma separated list) by a lookup against the map. +# A setting of zero disables the limit. Lookups fail with a +# temporary error if the limit is exceeded. Setting the +# limit to 1 ensures that lookups do not return multiple +# values. +# .IP "\fBoption_file\fR" +# Read options from the given file instead of the default my.cnf +# location. This reads options from the \fB[client]\fR option +# group, optionally followed by options from the group given +# with \fBoption_group\fR. +# .sp +# This parameter is available with Postfix 2.11 and later. +# .IP "\fBoption_group (default: Postfix >=3.2: client, <= 3.1: empty)\fR" +# Read options from the given group of the mysql options file, +# after reading options from the \fB[client]\fR group. +# .sp +# Postfix 3.2 and later read \fB[client]\fR option group +# settings by default. To disable this specify no \fBoption_file\fR +# and specify "\fBoption_group =\fR" (i.e. an empty value). +# .sp +# Postfix 3.1 and earlier don't read \fB[client]\fR option +# group settings unless a non-empty \fBoption_file\fR or +# \fBoption_group\fR value are specified. To enable this, +# specify, for example, "\fBoption_group = client\fR". +# .sp +# This parameter is available with Postfix 2.11 and later. +# .IP "\fBrequire_result_set (default: yes)\fR" +# If "\fByes\fR", require that every query returns a result +# set. If "\fBno\fR", treat the absence of a result set as +# "not found". +# .sp +# This parameter is available with Postfix 3.2 and later. +# .IP "\fBtls_cert_file\fR" +# File containing client's X509 certificate. +# .sp +# This parameter is available with Postfix 2.11 and later. +# .IP "\fBtls_key_file\fR" +# File containing the private key corresponding to \fBtls_cert_file\fR. +# .sp +# This parameter is available with Postfix 2.11 and later. +# .IP "\fBtls_CAfile\fR" +# File containing certificates for all of the X509 Certification +# Authorities the client will recognize. Takes precedence over +# \fBtls_CApath\fR. +# .sp +# This parameter is available with Postfix 2.11 and later. +# .IP "\fBtls_CApath\fR" +# Directory containing X509 Certification Authority certificates +# in separate individual files. +# .sp +# This parameter is available with Postfix 2.11 and later. +# .IP "\fBtls_verify_cert (default: no)\fR" +# Verify that the server's name matches the common name in the +# certificate. +# .sp +# This parameter is available with Postfix 2.11 and later. +# USING MYSQL STORED PROCEDURES +# .ad +# .fi +# Postfix 3.2 and later support calling a stored procedure +# instead of using a SELECT statement in the query, e.g. +# +# .nf +# \fBquery\fR = CALL lookup('%s') +# .fi +# +# The previously described '%' expansions can be used in the +# parameter(s) to the stored procedure. +# +# By default, every stored procedure call must return a result +# set, i.e. every code path must execute a SELECT statement +# that returns a result set (instead of storing its results +# in a table). With "\fBrequire_result_set = no\fR", the +# absence of a result set is treated as "not found". +# +# A stored procedure must not return multiple result sets. +# That is, there must be no code path that executes multiple +# SELECT statements that return a result (instead of storing +# their results in a table). +# +# The following is an example of a stored procedure returning +# a single result set: +# +# .nf +# CREATE [DEFINER=`user`@`host`] PROCEDURE +# `lookup`(IN `param` VARCHAR(255)) +# READS SQL DATA +# SQL SECURITY INVOKER +# BEGIN +# select goto from alias where address=param; +# END +# .fi +# OBSOLETE MAIN.CF PARAMETERS +# .ad +# .fi +# For compatibility with other Postfix lookup tables, MySQL +# parameters can also be defined in main.cf. In order to do that, +# specify as MySQL source a name that doesn't begin with a slash +# or a dot. The MySQL parameters will then be accessible as the +# name you've given the source in its definition, an underscore, +# and the name of the parameter. For example, if the map is +# specified as "mysql:\fImysqlname\fR", the parameter "hosts" +# would be defined in main.cf as "\fImysqlname\fR_hosts". +# +# Note: with this form, the passwords for the MySQL sources are +# written in main.cf, which is normally world-readable. Support +# for this form will be removed in a future Postfix version. +# OBSOLETE QUERY INTERFACE +# .ad +# .fi +# This section describes an interface that is deprecated as +# of Postfix 2.2. It is replaced by the more general \fBquery\fR +# interface described above. If the \fBquery\fR parameter +# is defined, the legacy parameters described here ignored. +# Please migrate to the new interface as the legacy interface +# may be removed in a future release. +# +# The following parameters can be used to fill in a +# SELECT template statement of the form: +# +# .nf +# SELECT [\fBselect_field\fR] +# FROM [\fBtable\fR] +# WHERE [\fBwhere_field\fR] = '%s' +# [\fBadditional_conditions\fR] +# .fi +# +# The specifier %s is replaced by the search string, and is +# escaped so if it contains single quotes or other odd characters, +# it will not cause a parse error, or worse, a security problem. +# .IP "\fBselect_field\fR" +# The SQL "select" parameter. Example: +# .nf +# \fBselect_field\fR = forw_addr +# .fi +# .IP "\fBtable\fR" +# The SQL "select .. from" table name. Example: +# .nf +# \fBtable\fR = mxaliases +# .fi +# .IP "\fBwhere_field\fR +# The SQL "select .. where" parameter. Example: +# .nf +# \fBwhere_field\fR = alias +# .fi +# .IP "\fBadditional_conditions\fR +# Additional conditions to the SQL query. Example: +# .nf +# \fBadditional_conditions\fR = AND status = 'paid' +# .fi +# SEE ALSO +# postmap(1), Postfix lookup table maintenance +# postconf(5), configuration parameters +# ldap_table(5), LDAP lookup tables +# pgsql_table(5), PostgreSQL lookup tables +# sqlite_table(5), SQLite lookup tables +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# MYSQL_README, Postfix MYSQL client guide +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# HISTORY +# MySQL support was introduced with Postfix version 1.0. +# AUTHOR(S) +# Original implementation by: +# Scott Cotton, Joshua Marcus +# IC Group, Inc. +# +# Further enhancements by: +# Liviu Daia +# Institute of Mathematics of the Romanian Academy +# P.O. BOX 1-764 +# RO-014700 Bucharest, ROMANIA +# +# Stored-procedure support by John Fawcett. +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/nisplus_table b/proto/nisplus_table new file mode 100644 index 0000000..2c8aefc --- /dev/null +++ b/proto/nisplus_table @@ -0,0 +1,89 @@ +#++ +# NAME +# nisplus_table 5 +# SUMMARY +# Postfix NIS+ client +# SYNOPSIS +# \fBpostmap -q "\fIstring\fB" "nisplus:[\fIname\fB=%s];\fIname.name.\fB"\fR +# +# \fBpostmap -q - "nisplus:[\fIname\fB=%s];\fIname.name.\fB" <\fIinputfile\fR +# DESCRIPTION +# The Postfix mail system uses optional lookup tables. +# These tables are usually in \fBdbm\fR or \fBdb\fR format. +# Alternatively, lookup tables can be specified as NIS+ +# databases. +# +# To find out what types of lookup tables your Postfix system +# supports use the "\fBpostconf -m\fR" command. +# +# To test Postfix NIS+ lookup tables, use the "\fBpostmap -q\fR" +# command as described in the SYNOPSIS above. +# QUERY SYNTAX +# .ad +# .fi +# Most of the NIS+ query is specified via the NIS+ map name. The +# general format of a Postfix NIS+ map name is as follows: +# +# .fi +# \fBnisplus:[\fIname\fB=%s];\fIname.name.name\fB.:\fIcolumn\fR +# .fi +# +# Postfix NIS+ map names differ from what one normally +# would use with commands such as \fBniscat\fR: +# .IP \(bu +# With each NIS+ table lookup, "\fB%s\fR" is replaced by a +# version of the lookup string. There can be only one +# "\fB%s\fR" instance in a Postfix NIS+ map name. +# .IP \(bu +# Postfix NIS+ map names use "\fB;\fR" instead of "\fB,\fR", +# because the latter character is special in the Postfix +# main.cf file. Postfix replaces "\fB;\fR" characters in +# the map name by "\fB,\fR" before making NIS+ queries. +# .IP \(bu +# The ":\fIcolumn\fR" part in the NIS+ map name is not part +# of the actual NIS+ query. Instead, it specifies the number +# of the table column that provides the lookup result. When +# no ":\fIcolumn\fR" is specified the first column (1) is used. +# EXAMPLE +# .ad +# .fi +# A NIS+ aliases map might be queried as follows: +# +# .nf +# alias_maps = dbm:/etc/mail/aliases, +# nisplus:[alias=%s];mail_aliases.org_dir.$mydomain.:1 +# .fi +# +# This queries the local aliases file before the NIS+ file. +# SEE ALSO +# postmap(1), Postfix lookup table manager +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# AUTHOR(S) +# Geoff Gibbs +# UK-HGMP-RC +# Hinxton +# Cambridge +# CB10 1SB, UK +# +# Adopted and adapted by: +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/pcre_table b/proto/pcre_table new file mode 100644 index 0000000..0f58c2b --- /dev/null +++ b/proto/pcre_table @@ -0,0 +1,248 @@ +#++ +# NAME +# pcre_table 5 +# SUMMARY +# format of Postfix PCRE tables +# SYNOPSIS +# \fBpostmap -q "\fIstring\fB" pcre:/etc/postfix/\fIfilename\fR +# +# \fBpostmap -q - pcre:/etc/postfix/\fIfilename\fB <\fIinputfile\fR +# +# \fBpostmap -hmq - pcre:/etc/postfix/\fIfilename\fB <\fIinputfile\fR +# +# \fBpostmap -bmq - pcre:/etc/postfix/\fIfilename\fB <\fIinputfile\fR +# DESCRIPTION +# The Postfix mail system uses optional tables for address +# rewriting, mail routing, or access control. These tables +# are usually in \fBdbm\fR or \fBdb\fR format. +# +# Alternatively, lookup tables can be specified in Perl Compatible +# Regular Expression form. In this case, each input is compared +# against a list of patterns. When a match is found, the +# corresponding result is returned and the search is terminated. +# +# To find out what types of lookup tables your Postfix system +# supports use the "\fBpostconf -m\fR" command. +# +# To test lookup tables, use the "\fBpostmap -q\fR" command +# as described in the SYNOPSIS above. Use "\fBpostmap -hmq +# -\fR <\fIfile\fR" for header_checks(5) patterns, and +# "\fBpostmap -bmq -\fR <\fIfile\fR" for body_checks(5) +# (Postfix 2.6 and later). +# +# This driver can be built with the pcre2 library (Postfix +# 3.7 and later), or with the legacy pcre library (all Postfix +# versions). +# COMPATIBILITY +# .ad +# .fi +# With Postfix version 2.2 and earlier specify "\fBpostmap +# -fq\fR" to query a table that contains case sensitive +# patterns. Patterns are case insensitive by default. +# TABLE FORMAT +# .ad +# .fi +# The general form of a PCRE table is: +# .IP "\fB/\fIpattern\fB/\fIflags result\fR" +# When \fIpattern\fR matches the input string, use +# the corresponding \fIresult\fR value. +# .IP "\fB!/\fIpattern\fB/\fIflags result\fR" +# When \fIpattern\fR does \fBnot\fR match the input string, use +# the corresponding \fIresult\fR value. +# .IP "\fBif /\fIpattern\fB/\fIflags\fR" +# .IP "\fBendif\fR" +# If the input string matches /\fIpattern\fR/, then match that +# input string against the patterns between \fBif\fR and +# \fBendif\fR. The \fBif\fR..\fBendif\fR can nest. +# .sp +# Note: do not prepend whitespace to patterns inside +# \fBif\fR..\fBendif\fR. +# .sp +# This feature is available in Postfix 2.1 and later. +# .IP "\fBif !/\fIpattern\fB/\fIflags\fR" +# .IP "\fBendif\fR" +# If the input string does not match /\fIpattern\fR/, then +# match that input string against the patterns between \fBif\fR +# and \fBendif\fR. The \fBif\fR..\fBendif\fR can nest. +# .sp +# Note: do not prepend whitespace to patterns inside +# \fBif\fR..\fBendif\fR. +# .sp +# This feature is available in Postfix 2.1 and later. +# .IP "blank lines and comments" +# Empty lines and whitespace-only lines are ignored, as +# are lines whose first non-whitespace character is a `#'. +# .IP "multi-line text" +# A logical line starts with non-whitespace text. A line that +# starts with whitespace continues a logical line. +# .PP +# Each pattern is a perl-like regular expression. The expression +# delimiter can be any non-alphanumeric character, except +# whitespace or characters +# that have special meaning (traditionally the forward slash is used). +# The regular expression can contain whitespace. +# +# By default, matching is case-insensitive, and newlines are not +# treated as special characters. The behavior is controlled by flags, +# which are toggled by appending one or more of the following +# characters after the pattern: +# .IP "\fBi\fR (default: on)" +# Toggles the case sensitivity flag. By default, matching is case +# insensitive. +# .IP "\fBm\fR (default: off)" +# Toggles the pcre MULTILINE flag. When this flag is on, the \fB^\fR +# and \fB$\fR metacharacters match immediately after and immediately +# before a newline character, respectively, in addition to +# matching at the start and end of the subject string. +# .IP "\fBs\fR (default: on)" +# Toggles the pcre DOTALL flag. When this flag is on, the \fB.\fR +# metacharacter matches the newline character. With +# Postfix versions prior to 2.0, the flag is off by +# default, which is inconvenient for multi-line message header +# matching. +# .IP "\fBx\fR (default: off)" +# Toggles the pcre extended flag. When this flag is on, whitespace +# characters in the pattern (other than in a character class) +# are ignored. To include a whitespace character as part of +# the pattern, escape it with backslash. +# .sp +# Note: do not use \fB#\fIcomment\fR after patterns. +# .IP "\fBA\fR (default: off)" +# Toggles the pcre ANCHORED flag. When this flag is on, +# the pattern is forced to be "anchored", that is, it is +# constrained to match only at the start of the string which +# is being searched (the "subject string"). This effect can +# also be achieved by appropriate constructs in the pattern +# itself. +# .IP "\fBE\fR (default: off)" +# Toggles the pcre DOLLAR_ENDONLY flag. When this flag is on, +# a \fB$\fR metacharacter in the pattern matches only at the +# end of the subject string. Without this flag, a dollar also +# matches immediately before the final character if it is a +# newline character (but not before any other newline +# characters). This flag is ignored if the pcre MULTILINE +# flag is set. +# .IP "\fBU\fR (default: off)" +# Toggles the pcre UNGREEDY flag. When this flag is on, +# the pattern matching engine inverts the "greediness" of +# the quantifiers so that they are not greedy by default, +# but become greedy if followed by "?". This flag can also +# set by a (?U) modifier within the pattern. +# .IP "\fBX\fR (default: off)" +# Toggles the pcre EXTRA flag. +# When this flag is on, any backslash in a pattern that is +# followed by a letter that has no special meaning causes an +# error, thus reserving these combinations for future expansion. +# +# This feature is not supported with PCRE2. +# SEARCH ORDER +# .ad +# .fi +# Patterns are applied in the order as specified in the table, until a +# pattern is found that matches the input string. +# +# Each pattern is applied to the entire input string. +# Depending on the application, that string is an entire client +# hostname, an entire client IP address, or an entire mail address. +# Thus, no parent domain or parent network search is done, and +# \fIuser@domain\fR mail addresses are not broken up into their +# \fIuser\fR and \fIdomain\fR constituent parts, nor is \fIuser+foo\fR +# broken up into \fIuser\fR and \fIfoo\fR. +# TEXT SUBSTITUTION +# .ad +# .fi +# Substitution of substrings (text that matches patterns +# inside "()") from the matched expression into the result +# string is requested with $1, $2, etc.; specify $$ to produce +# a $ character as output. +# The macros in the result string may need to be written as +# ${n} or $(n) if they aren't followed by whitespace. +# This feature does not support pcre2 substring names. +# +# Note: since negated patterns (those preceded by \fB!\fR) return a +# result when the expression does not match, substitutions are not +# available for negated patterns. +# INLINE SPECIFICATION +# .ad +# .fi +# The contents of a table may be specified in the table name +# (Postfix 3.7 and later). +# The basic syntax is: +# +# .nf +# main.cf: +# \fIparameter\fR \fB= .. pcre:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } ..\fR +# +# master.cf: +# \fB.. -o { \fIparameter\fR \fB= .. pcre:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR +# .fi +# +# Postfix ignores whitespace after '{' and before '}', and +# writes each \fIrule\fR as one text line to an in-memory +# file: +# +# .nf +# in-memory file: +# rule-1 +# rule-2 +# .. +# .fi +# +# Postfix parses the result as if it is a file in /etc/postfix. +# +# Note: if a rule contains \fB$\fR, specify \fB$$\fR to keep +# Postfix from trying to do \fI$name\fR expansion as it +# evaluates a parameter value. +# EXAMPLE SMTPD ACCESS MAP +# # Protect your outgoing majordomo exploders +# /^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead +# +# # Bounce friend@whatever, except when whatever is our domain (you would +# # be better just bouncing all friend@ mail - this is just an example). +# /^(friend@(?!my\\.domain$).*)$/ 550 Stick this in your pipe $1 +# +# # A multi-line entry. The text is sent as one line. +# # +# /^noddy@my\\.domain$/ +# \ 550 This user is a funny one. You really don't want to send mail to +# \ them as it only makes their head spin. +# EXAMPLE HEADER FILTER MAP +# /^Subject: make money fast/ REJECT +# /^To: friend@public\\.com/ REJECT +# EXAMPLE BODY FILTER MAP +# # First skip over base 64 encoded text to save CPU cycles. +# # Requires PCRE version 3. +# ~^[[:alnum:]+/]{60,}$~ OK +# +# # Put your own body patterns here. +# SEE ALSO +# postmap(1), Postfix lookup table manager +# postconf(5), configuration parameters +# regexp_table(5), format of POSIX regular expression tables +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# AUTHOR(S) +# The PCRE table lookup code was originally written by: +# Andrew McNamara +# andrewm@connect.com.au +# connect.com.au Pty. Ltd. +# Level 3, 213 Miller St +# North Sydney, NSW, Australia +# +# Adopted and adapted by: +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/pgsql_table b/proto/pgsql_table new file mode 100644 index 0000000..f5d9683 --- /dev/null +++ b/proto/pgsql_table @@ -0,0 +1,319 @@ +#++ +# NAME +# pgsql_table 5 +# SUMMARY +# Postfix PostgreSQL client configuration +# SYNOPSIS +# \fBpostmap -q "\fIstring\fB" pgsql:/etc/postfix/\fIfilename\fR +# +# \fBpostmap -q - pgsql:/etc/postfix/\fIfilename\fB <\fIinputfile\fR +# DESCRIPTION +# The Postfix mail system uses optional tables for address +# rewriting or mail routing. These tables are usually in +# \fBdbm\fR or \fBdb\fR format. +# +# Alternatively, lookup tables can be specified as PostgreSQL +# databases. In order to use PostgreSQL lookups, define a +# PostgreSQL source as a lookup table in main.cf, for example: +# .nf +# alias_maps = pgsql:/etc/postfix/pgsql-aliases.cf +# .fi +# +# The file /etc/postfix/pgsql-aliases.cf has the same format as +# the Postfix main.cf file, and can specify the parameters +# described below. +# LIST MEMBERSHIP +# .ad +# .fi +# When using SQL to store lists such as $mynetworks, +# $mydestination, $relay_domains, $local_recipient_maps, +# etc., it is important to understand that the table must +# store each list member as a separate key. The table lookup +# verifies the *existence* of the key. See "Postfix lists +# versus tables" in the DATABASE_README document for a +# discussion. +# +# Do NOT create tables that return the full list of domains +# in $mydestination or $relay_domains etc., or IP addresses +# in $mynetworks. +# +# DO create tables with each matching item as a key and with +# an arbitrary value. With SQL databases it is not uncommon to +# return the key itself or a constant value. +# PGSQL PARAMETERS +# .ad +# .fi +# .IP "\fBhosts\fR" +# The hosts that Postfix will try to connect to and query +# from. Besides a \fBpostgresql://\fR connection URI, this +# setting supports the historical forms \fBunix:/\fIpathname\fR +# for UNIX-domain sockets and \fBinet:\fIhost:port\fR for TCP +# connections, where the \fBunix:\fR and \fBinet:\fR prefixes +# are accepted and ignored for backwards compatibility. +# Examples: +# .nf +# hosts = postgresql://username@example.com/tablename?sslmode=require +# hosts = inet:host1.some.domain inet:host2.some.domain:port +# hosts = host1.some.domain host2.some.domain:port +# hosts = unix:/file/name +# .fi +# +# The hosts are tried in random order. The connections are +# automatically closed after being idle for about 1 minute, +# and are re-opened as necessary. +# .IP "\fBuser, password\fR" +# The user name and password to log into the pgsql server. +# Example: +# .nf +# user = someone +# password = some_password +# .fi +# .IP "\fBdbname\fR" +# The database name on the servers. Example: +# .nf +# dbname = customer_database +# .fi +# .IP "\fBquery\fR" +# The SQL query template used to search the database, where \fB%s\fR +# is a substitute for the address Postfix is trying to resolve, +# e.g. +# .nf +# query = SELECT replacement FROM aliases WHERE mailbox = '%s' +# .fi +# +# This parameter supports the following '%' expansions: +# .RS +# .IP "\fB%%\fR" +# This is replaced by a literal '%' character. (Postfix 2.2 and later) +# .IP "\fB%s\fR" +# This is replaced by the input key. +# SQL quoting is used to make sure that the input key does not +# add unexpected metacharacters. +# .IP "\fB%u\fR" +# When the input key is an address of the form user@domain, \fB%u\fR +# is replaced by the SQL quoted local part of the address. +# Otherwise, \fB%u\fR is replaced by the entire search string. +# If the localpart is empty, the query is suppressed and returns +# no results. +# .IP "\fB%d\fR" +# When the input key is an address of the form user@domain, \fB%d\fR +# is replaced by the SQL quoted domain part of the address. +# Otherwise, the query is suppressed and returns no results. +# .IP "\fB%[SUD]\fR" +# The upper-case equivalents of the above expansions behave in the +# \fBquery\fR parameter identically to their lower-case counter-parts. +# With the \fBresult_format\fR parameter (see below), they expand the +# input key rather than the result value. +# .IP +# The above %S, %U and %D expansions are available with Postfix 2.2 +# and later +# .IP "\fB%[1-9]\fR" +# The patterns %1, %2, ... %9 are replaced by the corresponding +# most significant component of the input key's domain. If the +# input key is \fIuser@mail.example.com\fR, then %1 is \fBcom\fR, +# %2 is \fBexample\fR and %3 is \fBmail\fR. If the input key is +# unqualified or does not have enough domain components to satisfy +# all the specified patterns, the query is suppressed and returns +# no results. +# .IP +# The above %1, ... %9 expansions are available with Postfix 2.2 +# and later +# .RE +# .IP +# The \fBdomain\fR parameter described below limits the input +# keys to addresses in matching domains. When the \fBdomain\fR +# parameter is non-empty, SQL queries for unqualified addresses +# or addresses in non-matching domains are suppressed +# and return no results. +# +# The precedence of this parameter has changed with Postfix 2.2, +# in prior releases the precedence was, from highest to lowest, +# \fBselect_function\fR, \fBquery\fR, \fBselect_field\fR, ... +# +# With Postfix 2.2 the \fBquery\fR parameter has highest precedence, +# see OBSOLETE QUERY INTERFACES below. +# +# NOTE: DO NOT put quotes around the \fBquery\fR parameter. +# .IP "\fBresult_format (default: \fB%s\fR)\fR" +# Format template applied to result attributes. Most commonly used +# to append (or prepend) text to the result. This parameter supports +# the following '%' expansions: +# .RS +# .IP "\fB%%\fR" +# This is replaced by a literal '%' character. +# .IP "\fB%s\fR" +# This is replaced by the value of the result attribute. When +# result is empty it is skipped. +# .IP "\fB%u\fR +# When the result attribute value is an address of the form +# user@domain, \fB%u\fR is replaced by the local part of the +# address. When the result has an empty localpart it is skipped. +# .IP "\fB%d\fR" +# When a result attribute value is an address of the form +# user@domain, \fB%d\fR is replaced by the domain part of +# the attribute value. When the result is unqualified it +# is skipped. +# .IP "\fB%[SUD1-9]\fR" +# The upper-case and decimal digit expansions interpolate +# the parts of the input key rather than the result. Their +# behavior is identical to that described with \fBquery\fR, +# and in fact because the input key is known in advance, queries +# whose key does not contain all the information specified in +# the result template are suppressed and return no results. +# .RE +# .IP +# For example, using "result_format = smtp:[%s]" allows one +# to use a mailHost attribute as the basis of a transport(5) +# table. After applying the result format, multiple values +# are concatenated as comma separated strings. The expansion_limit +# and parameter explained below allows one to restrict the number +# of values in the result, which is especially useful for maps that +# must return at most one value. +# +# The default value \fB%s\fR specifies that each result value should +# be used as is. +# +# This parameter is available with Postfix 2.2 and later. +# +# NOTE: DO NOT put quotes around the result format! +# .IP "\fBdomain (default: no domain list)\fR" +# This is a list of domain names, paths to files, or "type:table" +# databases. When specified, only fully qualified search +# keys with a *non-empty* localpart and a matching domain +# are eligible for lookup: 'user' lookups, bare domain lookups +# and "@domain" lookups are not performed. This can significantly +# reduce the query load on the PostgreSQL server. +# .nf +# domain = postfix.org, hash:/etc/postfix/searchdomains +# .fi +# +# It is best not to use SQL to store the domains eligible +# for SQL lookups. +# +# This parameter is available with Postfix 2.2 and later. +# +# NOTE: DO NOT define this parameter for local(8) aliases, +# because the input keys are always unqualified. +# .IP "\fBexpansion_limit (default: 0)\fR" +# A limit on the total number of result elements returned +# (as a comma separated list) by a lookup against the map. +# A setting of zero disables the limit. Lookups fail with a +# temporary error if the limit is exceeded. Setting the +# limit to 1 ensures that lookups do not return multiple +# values. +# OBSOLETE MAIN.CF PARAMETERS +# .ad +# .fi +# For compatibility with other Postfix lookup tables, PostgreSQL +# parameters can also be defined in main.cf. In order to do +# that, specify as PostgreSQL source a name that doesn't begin +# with a slash or a dot. The PostgreSQL parameters will then +# be accessible as the name you've given the source in its +# definition, an underscore, and the name of the parameter. For +# example, if the map is specified as "pgsql:\fIpgsqlname\fR", +# the parameter "hosts" would be defined in main.cf as +# "\fIpgsqlname\fR_hosts". +# +# Note: with this form, the passwords for the PostgreSQL sources +# are written in main.cf, which is normally world-readable. +# Support for this form will be removed in a future Postfix +# version. +# OBSOLETE QUERY INTERFACES +# .ad +# .fi +# This section describes query interfaces that are deprecated +# as of Postfix 2.2. Please migrate to the new \fBquery\fR +# interface as the old interfaces are slated to be phased +# out. +# .IP "\fBselect_function\fR" +# This parameter specifies a database function name. Example: +# .nf +# select_function = my_lookup_user_alias +# .fi +# +# This is equivalent to: +# .nf +# query = SELECT my_lookup_user_alias('%s') +# .fi +# +# This parameter overrides the legacy table-related fields (described +# below). With Postfix versions prior to 2.2, it also overrides the +# \fBquery\fR parameter. Starting with Postfix 2.2, the \fBquery\fR +# parameter has highest precedence, and the \fBselect_function\fR +# parameter is deprecated. +# .PP +# The following parameters (with lower precedence than the +# \fBselect_function\fR interface described above) can be used to +# build the SQL select statement as follows: +# +# .nf +# SELECT [\fBselect_field\fR] +# FROM [\fBtable\fR] +# WHERE [\fBwhere_field\fR] = '%s' +# [\fBadditional_conditions\fR] +# .fi +# +# The specifier %s is replaced with each lookup by the lookup key +# and is escaped so if it contains single quotes or other odd +# characters, it will not cause a parse error, or worse, a security +# problem. +# +# Starting with Postfix 2.2, this interface is obsoleted by the more +# general \fBquery\fR interface described above. If higher precedence +# the \fBquery\fR or \fBselect_function\fR parameters described above +# are defined, the parameters described here are ignored. +# .IP "\fBselect_field\fR" +# The SQL "select" parameter. Example: +# .nf +# \fBselect_field\fR = forw_addr +# .fi +# .IP "\fBtable\fR" +# The SQL "select .. from" table name. Example: +# .nf +# \fBtable\fR = mxaliases +# .fi +# .IP "\fBwhere_field\fR +# The SQL "select .. where" parameter. Example: +# .nf +# \fBwhere_field\fR = alias +# .fi +# .IP "\fBadditional_conditions\fR +# Additional conditions to the SQL query. Example: +# .nf +# \fBadditional_conditions\fR = AND status = 'paid' +# .fi +# SEE ALSO +# postmap(1), Postfix lookup table manager +# postconf(5), configuration parameters +# ldap_table(5), LDAP lookup tables +# mysql_table(5), MySQL lookup tables +# sqlite_table(5), SQLite lookup tables +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# PGSQL_README, Postfix PostgreSQL client guide +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# HISTORY +# PgSQL support was introduced with Postfix version 2.1. +# AUTHOR(S) +# Based on the MySQL client by: +# Scott Cotton, Joshua Marcus +# IC Group, Inc. +# +# Ported to PostgreSQL by: +# Aaron Sethman +# +# Further enhanced by: +# Liviu Daia +# Institute of Mathematics of the Romanian Academy +# P.O. BOX 1-764 +# RO-014700 Bucharest, ROMANIA +#-- diff --git a/proto/postconf.html.epilog b/proto/postconf.html.epilog new file mode 100644 index 0000000..46a20e9 --- /dev/null +++ b/proto/postconf.html.epilog @@ -0,0 +1,5 @@ +</dl> + +</body> + +</html> diff --git a/proto/postconf.html.prolog b/proto/postconf.html.prolog new file mode 100644 index 0000000..530d7b4 --- /dev/null +++ b/proto/postconf.html.prolog @@ -0,0 +1,105 @@ +<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> + +<head> + +<title>Postfix Configuration Parameters </title> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +</head> + +<body> + +<h1><img src="postfix-logo.jpg" width="203" height="98" alt="">Postfix Configuration Parameters </h1> + +<hr> + +<h2> Postfix main.cf file format </h2> + +<p> The Postfix main.cf configuration file specifies a very small +subset of all the parameters that control the operation of the +Postfix mail system. Parameters not explicitly specified are left +at their default values. </p> + +<p> The general format of the main.cf file is as follows: </p> + +<ul> + +<li> <p> Each logical line is in the form "parameter = value". +Whitespace around the "=" is ignored, as is whitespace at the end +of a logical line. </p> + +<li> <p> Empty lines and whitespace-only lines are ignored, as are +lines whose first non-whitespace character is a `#'. </p> + +<li> <p> A logical line starts with non-whitespace text. A line +that starts with whitespace continues a logical line. </p> + +<li> <p> A parameter value may refer to other parameters. </p> + +<ul> + +<li> <p> The expressions "$name" and "${name}" are recursively +replaced with the value of the named parameter. The parameter name +must contain only characters from the set [a-zA-Z0-9_]. +An undefined parameter value is replaced with the empty value. </p> + +<li> <p> The expressions "${name?value}" and "${name?{value}}" are +replaced with "value" when "$name" is non-empty. The parameter name +must contain only characters from the set [a-zA-Z0-9_]. These forms are +supported with Postfix versions ≥ 2.2 and ≥ 3.0, respectively. +</p> + +<li> <p> The expressions "${name:value}" and "${name:{value}}" are +replaced with "value" when "$name" is empty. The parameter name must +contain only characters from the set [a-zA-Z0-9_]. These forms are +supported with Postfix versions ≥ 2.2 and ≥ 3.0, respectively. +</p> + +<li> <p> The expression "${name?{value1}:{value2}}" is replaced +with "value1" when "$name" is non-empty, and with "value2" when +"$name" is empty. The "{}" is required for "value1", optional for +"value2". The parameter name must contain only characters from the +set [a-zA-Z0-9_]. This form is supported with Postfix versions +≥ 3.0. </p> + +<li> <p> The first item inside "${...}" may be a relational expression +of the form: "{value3} == {value4}". Besides the "==" (equality) +operator Postfix supports "!=" (inequality), "<", "≤", "≥", +and ">". The comparison is numerical when both operands are all +digits, otherwise the comparison is lexicographical. These forms +are supported with Postfix versions ≥ 3.0. </p> + +<li> <p> Each "value" is subject to recursive named parameter and +relational expression evaluation, except where noted. </p> + +<li> <p> Whitespace before or after each "{value}" is ignored. </p> + +<li> <p> Specify "$$" to produce a single "$" character. </p> + +<li> <p> The legacy form "$(...)" is equivalent to the preferred +form "${...}". </p> + +</ul> + +<li> <p> When the same parameter is defined multiple times, only +the last instance is remembered. </p> + +<li> <p> Otherwise, the order of main.cf parameter definitions does +not matter. </p> + +</ul> + +<p> The remainder of this document is a description of all Postfix +configuration parameters. Default values are shown after the +parameter name in parentheses, and can be looked up with the +"<b>postconf -d</b>" command. </p> + +<p> Note: this is not an invitation to make changes to Postfix +configuration parameters. Unnecessary changes are likely to impair +the operation of the mail system. </p> + +<dl> diff --git a/proto/postconf.man.epilog b/proto/postconf.man.epilog new file mode 100644 index 0000000..1392615 --- /dev/null +++ b/proto/postconf.man.epilog @@ -0,0 +1,23 @@ +.SH SEE ALSO +.na +.nf +postconf(1), Postfix configuration parameter maintenance +master(5), Postfix daemon configuration maintenance +.SH LICENSE +.ad +.fi +The Secure Mailer license must be distributed with this software. +.SH AUTHOR(S) +.na +.nf +Wietse Venema +IBM T.J. Watson Research +P.O. Box 704 +Yorktown Heights, NY 10598, USA +.sp +Wietse Venema +Google, Inc. +111 8th Avenue +New York, NY 10011, USA +.sp +Viktor Dukhovni diff --git a/proto/postconf.man.prolog b/proto/postconf.man.prolog new file mode 100644 index 0000000..64b1e97 --- /dev/null +++ b/proto/postconf.man.prolog @@ -0,0 +1,85 @@ +.TH POSTCONF 5 +.SH NAME +postconf +\- +Postfix configuration parameters +.SH SYNOPSIS +.na +.nf +\fBpostconf\fR \fIparameter\fR ... + +\fBpostconf \-e\fR "\fIparameter=value\fR" ... +.SH DESCRIPTION +.ad +.fi +The Postfix main.cf configuration file specifies parameters that +control the operation of the Postfix mail system. Typically the +file contains only a small subset of all parameters; parameters +not specified are left at their default values. +.PP +The general format of the main.cf file is as follows: +.IP \(bu +Each logical line has the form "parameter = value". +Whitespace around the "=" is ignored, as is whitespace at the +end of a logical line. +.IP \(bu +Empty lines and whitespace-only lines are ignored, as are lines +whose first non-whitespace character is a `#'. +.IP \(bu +A logical line starts with non-whitespace text. A line that starts +with whitespace continues a logical line. +.IP \(bu +A parameter value may refer to other parameters. +.RS +.IP \(bu +The expressions "$name" and "${name}" are recursively replaced with +the value of the named parameter. The parameter name must contain +only characters from the set [a-zA-Z0-9_]. An undefined parameter +value is replaced with the empty value. +.IP \(bu +The expressions "${name?value}" and "${name?{value}}" are replaced +with "value" when "$name" is non-empty. The parameter name must +contain only characters from the set [a-zA-Z0-9_]. These forms are +supported with Postfix versions >= 2.2 and >= 3.0, respectively. +.IP \(bu +The expressions "${name:value}" and "${name:{value}}" are replaced +with "value" when "$name" is empty. The parameter name must contain +only characters from the set [a-zA-Z0-9_]. These forms are supported +with Postfix versions >= 2.2 and >= 3.0, respectively. +.IP \(bu +The expression "${name?{value1}:{value2}}" is replaced with "value1" +when "$name" is non-empty, and with "value2" when "$name" is empty. +The "{}" is required for "value1", optional for "value2". The +parameter name must contain only characters from the set [a-zA-Z0-9_]. +This form is supported with Postfix versions >= 3.0. +.IP \(bu +The first item inside "${...}" may be a relational expression of the +form: "{value3} == {value4}". Besides the "==" (equality) operator +Postfix supports "!=" (inequality), "<", "<=", ">=", and ">". The +comparison is numerical when both operands are all digits, otherwise +the comparison is lexicographical. These forms are supported with +Postfix versions >= 3.0. +.IP \(bu +Each "value" is subject to recursive named parameter and relational +expression evaluation, except where noted. +.IP \(bu +Whitespace before or after each "{value}" is ignored. +.IP \(bu +Specify "$$" to produce a single "$" character. +.IP \(bu +The legacy form "$(...)" is equivalent to the preferred form "${...}". +.RE +.IP \(bu +When the same parameter is defined multiple times, only the last +instance is remembered. +.IP \(bu +Otherwise, the order of main.cf parameter definitions does not matter. +.PP +The remainder of this document is a description of all Postfix +configuration parameters. Default values are shown after the +parameter name in parentheses, and can be looked up with the +"\fBpostconf \-d\fR" command. +.PP +Note: this is not an invitation to make changes to Postfix +configuration parameters. Unnecessary changes can impair the +operation of the mail system. diff --git a/proto/postconf.proto b/proto/postconf.proto new file mode 100644 index 0000000..10b47cf --- /dev/null +++ b/proto/postconf.proto @@ -0,0 +1,18715 @@ +# This is the input file for automatically generating the postconf(5) +# manual page, the summaries of parameters in on-line manual pages, +# and for the postconf.5.html hyperlinked document. +# +# The following tools operate on information from this file: +# +# xpostconf +# Extracts specific parameter definitions from this file, or +# produces a sorted version of all the information in this +# document. +# +# postconf2html +# Adds parameter name +default headers. The result can be embedded +# into the postconf.5.html hyperlinked document. +# +# postconf2man +# Converts this file into something that can be embedded into +# the postconf(5) UNIX-style manual page. This tool knows only +# a limited subset of HTML as described below. +# +# postconf2src +# Converts this file result into something that can be embedded +# into Postfix source code files. +# +# The subset of HTML that you can use is limited by the postconf2man +# tool: +# +# * Supported HTML elements are: blockquote, ul, li, dl, dt, dd, +# p, pre, b, i, h, and the escapes for < <= >= >. Sorry, no +# tables. +# +# * HTML elements must be specified in lower case. +# +# * Lists cannot be nested. +# +# * The postconf2man tool leaves unrecognized HTML in place as a +# reminder that it is not supported. +# +# * Text between <!-- and --> is stripped out. The <!-- and --> +# must appear on separate lines. +# +# * Use <nroffescape .sp> to request an empty line in the middle +# of a block of text. This is needed with indented lists. +# +# * Blank lines are special for postconf2man: it replaces them by +# a "new paragraph" command. Don't put any blank lines inside +# <blockquote> text. Instead, put those blank lines between +# </blockquote> and <blockquote>. +# +# * Text after a blank line must start with an HTML element. +# +# Also: +# +# * All <dt> and <dd>text must be closed with </dt> and </dd>. +# +# * Use <blockquote><pre>..</pre></blockquote> for examples +# between narrative text, instead of indenting examples by hand. +# +# * Use <pre>..</pre> for the "Examples:" section at the end +# of a parameter description. +# +# The postlink tool automatically inserts hyperlinks for the following, +# so you must not hyperlink that information yourself: +# +# * Postfix manual pages +# * URLs +# * RFCs +# * Postfix configuration parameters +# * Postfix README files +# * Address classes and other terminology. +# +# The xpostconf and postconf2html tools expect the file format described +# in the comments below. The description includes the transformation +# that is done by the postconf2html tool. +# +# * The format of this file is blocks of text separated by one or +# more empty (or all whitespace) lines. +# +# * A text block that begins with %PARAM specifies a parameter name +# and its default value, separated by whitespace. The text in +# the blocks that follow is the parameter description. +# +# * The first line (text up to the first ". ") is used in Postfix +# on-line manual pages, in the one-line configuration parameter +# summaries. +# +# * A text block that begins with the "<" character is treated as +# literal HTML. For example, to specify a "dl" list element one +# would write: +# +# |<dt><b>name</b></dt> <dd> +# | +# |text that describes "name". +# | +# |</dd> ... +# +# As described below, the text that describes "name" will be +# enclosed with <p> and </p>. +# +# An "ul" list element would be written like this: +# +# |<li> text for this list element. +# +# * Any text block that does not begin with < is an error. + +%CLASS address-verification Address verification (Postfix 2.1 and later) + +<p> +Sender/recipient address verification is implemented by sending +probe email messages that are not actually delivered. This feature +is requested via the reject_unverified_sender and +reject_unverified_recipient access restrictions. The status of +verification probes is maintained by the address verification +service. See the file ADDRESS_VERIFICATION_README for information +about how to configure and operate the Postfix sender/recipient +address verification service. +</p> + +%CLASS smtpd-compatibility Compatibility controls + +%CLASS resource-control Resource controls + +%CLASS after-queue-filter After-queue content filter + +<p> +As of version 1.0, Postfix can be configured to send new mail to +an external content filter AFTER the mail is queued. This content +filter is expected to inject mail back into a (Postfix or other) +MTA for further delivery. See the FILTER_README document for +details. +</p> + +%CLASS before-queue-filter Before-queue content filter + +<p> +The Postfix SMTP server can be configured to send incoming mail to +a real-time SMTP-based content filter BEFORE mail is queued. This +content filter is expected to inject mail back into Postfix. See +the SMTPD_PROXY_README document for details on how to configure +and operate this feature. +</p> + +%CLASS basic-config Basic configuration parameters + +%CLASS smtpd-access-relay SMTP server access and relay control + +%CLASS smtpd-sasl SMTP server SASL authentication + +%CLASS unknown-recipients Rejecting mail for unknown recipients + +%CLASS smtpd-reply-code SMTP server response codes + +%CLASS other Other configuration parameters + +%PARAM access_map_reject_code 554 + +<p> +The numerical Postfix SMTP server response code for +an access(5) map "reject" action. +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +%PARAM access_map_defer_code 450 + +<p> +The numerical Postfix SMTP server response code for +an access(5) map "defer" action, including "defer_if_permit" +or "defer_if_reject". Prior to Postfix 2.6, the response +is hard-coded as "450". +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +<p> +This feature is available in Postfix 2.6 and later. +</p> + +%PARAM address_verify_default_transport $default_transport + +<p> +Overrides the default_transport parameter setting for address +verification probes. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM address_verify_local_transport $local_transport + +<p> +Overrides the local_transport parameter setting for address +verification probes. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM address_verify_map see "postconf -d" output + +<p> +Lookup table for persistent address verification status +storage. The table is maintained by the verify(8) service, and +is opened before the process releases privileges. +</p> + +<p> +The lookup table is persistent by default (Postfix 2.7 and later). +Specify an empty table name to keep the information in volatile +memory which is lost after "<b>postfix reload</b>" or "<b>postfix +stop</b>". This is the default with Postfix version 2.6 and earlier. +</p> + +<p> +Specify a location in a file system that will not fill up. If the +database becomes corrupted, the world comes to an end. To recover, +delete (NOT: truncate) the file and do "<b>postfix reload</b>". +</p> + +<p> Postfix daemon processes do not use root privileges when opening +this file (Postfix 2.5 and later). The file must therefore be +stored under a Postfix-owned directory such as the data_directory. +As a migration aid, an attempt to open the file under a non-Postfix +directory is redirected to the Postfix-owned data_directory, and a +warning is logged. </p> + +<p> +Examples: +</p> + +<pre> +address_verify_map = hash:/var/lib/postfix/verify +address_verify_map = btree:/var/lib/postfix/verify +</pre> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM address_verify_negative_cache yes + +<p> +Enable caching of failed address verification probe results. When +this feature is enabled, the cache may pollute quickly with garbage. +When this feature is disabled, Postfix will generate an address +probe for every lookup. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM address_verify_negative_expire_time 3d + +<p> +The time after which a failed probe expires from the address +verification cache. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is d (days). </p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM address_verify_negative_refresh_time 3h + +<p> +The time after which a failed address verification probe needs to +be refreshed. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is h (hours). </p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM address_verify_cache_cleanup_interval 12h + +<p> The amount of time between verify(8) address verification +database cleanup runs. This feature requires that the database +supports the "delete" and "sequence" operators. Specify a zero +interval to disable database cleanup. </p> + +<p> After each database cleanup run, the verify(8) daemon logs the +number of entries that were retained and dropped. A cleanup run is +logged as "partial" when the daemon terminates early after "<b>postfix +reload</b>", "<b>postfix stop</b>", or no requests for $max_idle +seconds. </p> + +<p> Specify a non-negative time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is h (hours). </p> + +<p> This feature is available in Postfix 2.7. </p> + +%PARAM address_verify_poll_count normal: 3, overload: 1 + +<p> +How many times to query the verify(8) service for the completion +of an address verification request in progress. +</p> + +<p> By default, the Postfix SMTP server polls the verify(8) service +up to three times under non-overload conditions, and only once when +under overload. With Postfix version 2.5 and earlier, the SMTP +server always polls the verify(8) service up to three times by +default. </p> + +<p> +Specify 1 to implement a crude form of greylisting, that is, always +defer the first delivery request for a new address. +</p> + +<p> +Examples: +</p> + +<pre> +# Postfix ≤ 2.6 default +address_verify_poll_count = 3 +# Poor man's greylisting +address_verify_poll_count = 1 +</pre> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM address_verify_poll_delay 3s + +<p> +The delay between queries for the completion of an address +verification request in progress. +</p> + +<p> +The default polling delay is 3 seconds. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM address_verify_positive_expire_time 31d + +<p> +The time after which a successful probe expires from the address +verification cache. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is d (days). </p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM address_verify_positive_refresh_time 7d + +<p> +The time after which a successful address verification probe needs +to be refreshed. The address verification status is not updated +when the probe fails (optimistic caching). +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is d (days). </p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM address_verify_relay_transport $relay_transport + +<p> +Overrides the relay_transport parameter setting for address +verification probes. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM address_verify_relayhost $relayhost + +<p> +Overrides the relayhost parameter setting for address verification +probes. This information can be overruled with the transport(5) table. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM address_verify_sender $double_bounce_sender + +<p> The sender address to use in address verification probes; prior +to Postfix 2.5 the default was "postmaster". To +avoid problems with address probes that are sent in response to +address probes, the Postfix SMTP server excludes the probe sender +address from all SMTPD access blocks. </p> + +<p> +Specify an empty value (address_verify_sender =) or <> if you want +to use the null sender address. Beware, some sites reject mail from +<>, even though RFCs require that such addresses be accepted. +</p> + +<p> +Examples: +</p> + +<pre> +address_verify_sender = <> +address_verify_sender = postmaster@my.domain +</pre> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM address_verify_transport_maps $transport_maps + +<p> +Overrides the transport_maps parameter setting for address verification +probes. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM address_verify_virtual_transport $virtual_transport + +<p> +Overrides the virtual_transport parameter setting for address +verification probes. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM alias_database see "postconf -d" output + +<p> +The alias databases for local(8) delivery that are updated with +"<b>newaliases</b>" or with "<b>sendmail -bi</b>". +</p> + +<p> +This is a separate configuration parameter because not all the +tables specified with $alias_maps have to be local files. +</p> + +<p> +Examples: +</p> + +<pre> +alias_database = hash:/etc/aliases +alias_database = hash:/etc/mail/aliases +</pre> + +%PARAM alias_maps see "postconf -d" output + +<p> +The alias databases that are used for local(8) delivery. See +aliases(5) for syntax details. +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +Note: these lookups are recursive. +</p> + +<p> +The default list is system dependent. On systems with NIS, the +default is to search the local alias database, then the NIS alias +database. +</p> + +<p> +If you change the alias database, run "<b>postalias /etc/aliases</b>" +(or wherever your system stores the mail alias file), or simply +run "<b>newaliases</b>" to build the necessary DBM or DB file. +</p> + +<p> +The local(8) delivery agent disallows regular expression substitution +of $1 etc. in alias_maps, because that would open a security hole. +</p> + +<p> +The local(8) delivery agent will silently ignore requests to use +the proxymap(8) server within alias_maps. Instead it will open the +table directly. Before Postfix version 2.2, the local(8) delivery +agent will terminate with a fatal error. +</p> + +<p> +Examples: +</p> + +<pre> +alias_maps = hash:/etc/aliases, nis:mail.aliases +alias_maps = hash:/etc/aliases +</pre> + +%PARAM allow_mail_to_commands alias, forward + +<p> +Restrict local(8) mail delivery to external commands. The default +is to disallow delivery to "|command" in :include: files (see +aliases(5) for the text that defines this terminology). +</p> + +<p> +Specify zero or more of: <b>alias</b>, <b>forward</b> or <b>include</b>, +in order to allow commands in aliases(5), .forward files or in +:include: files, respectively. +</p> + +<p> +Example: +</p> + +<pre> +allow_mail_to_commands = alias,forward,include +</pre> + +%PARAM allow_mail_to_files alias, forward + +<p> +Restrict local(8) mail delivery to external files. The default is +to disallow "/file/name" destinations in :include: files (see +aliases(5) for the text that defines this terminology). +</p> + +<p> +Specify zero or more of: <b>alias</b>, <b>forward</b> or <b>include</b>, +in order to allow "/file/name" destinations in aliases(5), .forward +files and in :include: files, respectively. +</p> + +<p> +Example: +</p> + +<pre> +allow_mail_to_files = alias,forward,include +</pre> + +%PARAM allow_min_user no + +<p> +Allow a sender or recipient address to have `-' as the first +character. By +default, this is not allowed, to avoid accidents with software that +passes email addresses via the command line. Such software +would not be able to distinguish a malicious address from a +bona fide command-line option. Although this can be prevented by +inserting a "--" option terminator into the command line, this is +difficult to enforce consistently and globally. </p> + +<p> As of Postfix version 2.5, this feature is implemented by +trivial-rewrite(8). With earlier versions this feature was implemented +by qmgr(8) and was limited to recipient addresses only. </p> + +%PARAM allow_percent_hack yes + +<p> +Enable the rewriting of the form "user%domain" to "user@domain". +This is enabled by default. +</p> + +<p> Note: as of Postfix version 2.2, message header address rewriting +happens only when one of the following conditions is true: </p> + +<ul> + +<li> The message is received with the Postfix sendmail(1) command, + +<li> The message is received from a network client that matches +$local_header_rewrite_clients, + +<li> The message is received from the network, and the +remote_header_rewrite_domain parameter specifies a non-empty value. + +</ul> + +<p> To get the behavior before Postfix version 2.2, specify +"local_header_rewrite_clients = static:all". </p> + +<p> +Example: +</p> + +<pre> +allow_percent_hack = no +</pre> + +%PARAM allow_untrusted_routing no + +<p> +Forward mail with sender-specified routing (user[@%!]remote[@%!]site) +from untrusted clients to destinations matching $relay_domains. +</p> + +<p> +By default, this feature is turned off. This closes a nasty open +relay loophole where a backup MX host can be tricked into forwarding +junk mail to a primary MX host which then spams it out to the world. +</p> + +<p> +This parameter also controls if non-local addresses with sender-specified +routing can match Postfix access tables. By default, such addresses +cannot match Postfix access tables, because the address is ambiguous. +</p> + +%PARAM always_bcc + +<p> +Optional address that receives a "blind carbon copy" of each message +that is received by the Postfix mail system. +</p> + +<p> +Note: with Postfix 2.3 and later the BCC address is added as if it +was specified with NOTIFY=NONE. The sender will not be notified +when the BCC address is undeliverable, as long as all down-stream +software implements RFC 3461. +</p> + +<p> +Note: with Postfix 2.2 and earlier the sender will be notified +when the BCC address is undeliverable. +</p> + +<p> Note: automatic BCC recipients are produced only for new mail. +To avoid mailer loops, automatic BCC recipients are not generated +after Postfix forwards mail internally, or after Postfix generates +mail itself. </p> + +%PARAM berkeley_db_create_buffer_size 16777216 + +<p> +The per-table I/O buffer size for programs that create Berkeley DB +hash or btree tables. Specify a byte count. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM berkeley_db_read_buffer_size 131072 + +<p> +The per-table I/O buffer size for programs that read Berkeley DB +hash or btree tables. Specify a byte count. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM best_mx_transport + +<p> +Where the Postfix SMTP client should deliver mail when it detects +a "mail loops back to myself" error condition. This happens when +the local MTA is the best SMTP mail exchanger for a destination +not listed in $mydestination, $inet_interfaces, $proxy_interfaces, +$virtual_alias_domains, or $virtual_mailbox_domains. By default, +the Postfix SMTP client returns such mail as undeliverable. +</p> + +<p> +Specify, for example, "best_mx_transport = local" to pass the mail +from the Postfix SMTP client to the local(8) delivery agent. You +can specify +any message delivery "transport" or "transport:nexthop" that is +defined in the master.cf file. See the transport(5) manual page +for the syntax and meaning of "transport" or "transport:nexthop". +</p> + +<p> +However, this feature is expensive because it ties up a Postfix +SMTP client process while the local(8) delivery agent is doing its +work. It is more efficient (for Postfix) to list all hosted domains +in a table or database. +</p> + +%PARAM biff yes + +<p> +Whether or not to use the local biff service. This service sends +"new mail" notifications to users who have requested new mail +notification with the UNIX command "biff y". +</p> + +<p> +For compatibility reasons this feature is on by default. On systems +with lots of interactive users, the biff service can be a performance +drain. Specify "biff = no" in main.cf to disable. +</p> + +%PARAM body_checks + +<p> Optional lookup tables for content inspection as specified in +the body_checks(5) manual page. </p> + +<p> Note: with Postfix versions before 2.0, these rules inspect +all content after the primary message headers. </p> + +%PARAM body_checks_size_limit 51200 + +<p> +How much text in a message body segment (or attachment, if you +prefer to use that term) is subjected to body_checks inspection. +The amount of text is limited to avoid scanning huge attachments. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM bounce_queue_lifetime 5d + +<p> +Consider a bounce message as undeliverable, when delivery fails +with a temporary error, and the time in the queue has reached the +bounce_queue_lifetime limit. By default, this limit is the same +as for regular mail. +</p> + +<p> Specify a non-negative time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is d (days). </p> + +<p> +Specify 0 when mail delivery should be tried only once. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM bounce_size_limit 50000 + +<p> The maximal amount of original message text that is sent in a +non-delivery notification. Specify a byte count. A message is +returned as either message/rfc822 (the complete original) or as +text/rfc822-headers (the headers only). With Postfix version 2.4 +and earlier, a message is always returned as message/rfc822 and is +truncated when it exceeds the size limit. +</p> + +<p> Notes: </p> + +<ul> + +<li> <p> If you increase this limit, then you should increase the +mime_nesting_limit value proportionally. </p> + +<li> <p> Be careful when making changes. Excessively large values +will result in the loss of non-delivery notifications, when a bounce +message size exceeds a local or remote MTA's message size limit. +</p> + +</ul> + +%PARAM canonical_maps + +<p> +Optional address mapping lookup tables for message headers and +envelopes. The mapping is applied to both sender and recipient +addresses, in both envelopes and in headers, as controlled +with the canonical_classes parameter. This is typically used +to clean up dirty addresses from legacy mail systems, or to replace +login names by Firstname.Lastname. The table format and lookups +are documented in canonical(5). For an overview of Postfix address +manipulations see the ADDRESS_REWRITING_README document. +</p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +Note: these lookups are recursive. +</p> + +<p> +If you use this feature, run "<b>postmap /etc/postfix/canonical</b>" to +build the necessary DBM or DB file after every change. The changes +will become visible after a minute or so. Use "<b>postfix reload</b>" +to eliminate the delay. +</p> + +<p> Note: with Postfix version 2.2, message header address mapping +happens only when message header address rewriting is enabled: </p> + +<ul> + +<li> The message is received with the Postfix sendmail(1) command, + +<li> The message is received from a network client that matches +$local_header_rewrite_clients, + +<li> The message is received from the network, and the +remote_header_rewrite_domain parameter specifies a non-empty value. + +</ul> + +<p> To get the behavior before Postfix version 2.2, specify +"local_header_rewrite_clients = static:all". </p> + +<p> +Examples: +</p> + +<pre> +canonical_maps = dbm:/etc/postfix/canonical +canonical_maps = hash:/etc/postfix/canonical +</pre> + +%PARAM canonical_classes envelope_sender, envelope_recipient, header_sender, header_recipient + +<p> What addresses are subject to canonical_maps address mapping. +By default, canonical_maps address mapping is applied to envelope +sender and recipient addresses, and to header sender and header +recipient addresses. </p> + +<p> Specify one or more of: envelope_sender, envelope_recipient, +header_sender, header_recipient </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM sender_canonical_classes envelope_sender, header_sender + +<p> What addresses are subject to sender_canonical_maps address +mapping. By default, sender_canonical_maps address mapping is +applied to envelope sender addresses, and to header sender addresses. +</p> + +<p> Specify one or more of: envelope_sender, header_sender </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM recipient_canonical_classes envelope_recipient, header_recipient + +<p> What addresses are subject to recipient_canonical_maps address +mapping. By default, recipient_canonical_maps address mapping is +applied to envelope recipient addresses, and to header recipient +addresses. </p> + +<p> Specify one or more of: envelope_recipient, header_recipient +</p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM command_directory see "postconf -d" output + +<p> +The location of all postfix administrative commands. +</p> + +%PARAM command_time_limit 1000s + +<p> +Time limit for delivery to external commands. This limit is used +by the local(8) delivery agent, and is the default time limit for +delivery by the pipe(8) delivery agent. +</p> + +<p> +Note: if you set this time limit to a large value you must update the +global ipc_timeout parameter as well. +</p> + +%PARAM daemon_directory see "postconf -d" output + +<p> +The directory with Postfix support programs and daemon programs. +These should not be invoked directly by humans. The directory must +be owned by root. +</p> + +%PARAM daemon_timeout 18000s + +<p> How much time a Postfix daemon process may take to handle a +request before it is terminated by a built-in watchdog timer. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM debug_peer_level 2 + +<p> The increment in verbose logging level when a nexthop destination, +remote client or server name or network address matches a pattern +given with the debug_peer_list parameter. </p> + +<p> Per-nexthop debug logging is available in Postfix 3.6 and later. </p> + +%PARAM debug_peer_list + +<p> Optional list of nexthop destination, remote client or server +name or network address patterns that, if matched, cause the verbose +logging level to increase by the amount specified in $debug_peer_level. +</p> + +<p> Per-nexthop debug logging is available in Postfix 3.6 and later. </p> + +<p> Specify domain names, network/netmask patterns, "/file/name" +patterns or "type:table" lookup tables. The right-hand side result +from "type:table" lookups is ignored. </p> + +<p> Pattern matching of domain names is controlled by the presence +or absence of "debug_peer_list" in the parent_domain_matches_subdomains +parameter value. </p> + +<p> +Examples: +</p> + +<pre> +debug_peer_list = 127.0.0.1 +debug_peer_list = example.com +</pre> + +%PARAM default_database_type see "postconf -d" output + +<p> +The default database type for use in newaliases(1), postalias(1) +and postmap(1) commands. On many UNIX systems the default type is +either <b>dbm</b> or <b>hash</b>. The default setting is frozen +when the Postfix system is built. +</p> + +<p> +Examples: +</p> + +<pre> +default_database_type = hash +default_database_type = dbm +</pre> + +%PARAM default_delivery_slot_cost 5 + +<p> +How often the Postfix queue manager's scheduler is allowed to +preempt delivery of one message with another. +</p> + +<p> +Each transport maintains a so-called "available delivery slot counter" +for each message. One message can be preempted by another one when +the other message can be delivered using no more delivery slots +(i.e., invocations of delivery agents) than the current message +counter has accumulated (or will eventually accumulate - see about +slot loans below). This parameter controls how often the counter is +incremented - it happens after each default_delivery_slot_cost +recipients have been delivered. +</p> + +<p> +The cost of 0 is used to disable the preempting scheduling completely. +The minimum value the scheduling algorithm can use is 2 - use it +if you want to maximize the message throughput rate. Although there +is no maximum, it doesn't make much sense to use values above say +50. +</p> + +<p> +The only reason why the value of 2 is not the default is the way +this parameter affects the delivery of mailing-list mail. In the +worst case, delivery can take somewhere between (cost+1/cost) +and (cost/cost-1) times more than if the preemptive scheduler was +disabled. The default value of 5 turns out to provide reasonable +message response times while making sure the mailing-list deliveries +are not extended by more than 20-25 percent even in the worst case. +</p> + +<p> Use <i>transport</i>_delivery_slot_cost to specify a +transport-specific override, where <i>transport</i> is the master.cf +name of the message delivery transport. +</p> + +<p> +Examples: +</p> + +<pre> +default_delivery_slot_cost = 0 +default_delivery_slot_cost = 2 +</pre> + +%PARAM default_destination_concurrency_limit 20 + +<p> +The default maximal number of parallel deliveries to the same +destination. This is the default limit for delivery via the lmtp(8), +pipe(8), smtp(8) and virtual(8) delivery agents. +With a per-destination recipient limit > 1, a destination is a domain, +otherwise it is a recipient. +</p> + +<p> Use <i>transport</i>_destination_concurrency_limit to specify a +transport-specific override, where <i>transport</i> is the master.cf +name of the message delivery transport. +</p> + +%PARAM default_destination_recipient_limit 50 + +<p> +The default maximal number of recipients per message delivery. +This is the default limit for delivery via the lmtp(8), pipe(8), +smtp(8) and virtual(8) delivery agents. +</p> + +<p> Setting this parameter to a value of 1 affects email deliveries +as follows:</p> + +<ul> + +<li> <p> It changes the meaning of the corresponding per-destination +concurrency limit, from concurrency of deliveries to the <i>same +domain</i> into concurrency of deliveries to the <i>same recipient</i>. +Different recipients are delivered in parallel, subject to the +process limits specified in master.cf. </p> + +<li> <p> It changes the meaning of the corresponding per-destination +rate delay, from the delay between deliveries to the <i>same +domain</i> into the delay between deliveries to the <i>same +recipient</i>. Again, different recipients are delivered in parallel, +subject to the process limits specified in master.cf. </p> + +<li> <p> It changes the meaning of other corresponding per-destination +settings in a similar manner, from settings for delivery to the +<i>same domain</i> into settings for delivery to the <i>same +recipient</i>. + +</ul> + +<p> Use <i>transport</i>_destination_recipient_limit to specify a +transport-specific override, where <i>transport</i> is the master.cf +name of the message delivery transport. +</p> + +%PARAM default_extra_recipient_limit 1000 + +<p> +The default value for the extra per-transport limit imposed on the +number of in-memory recipients. This extra recipient space is +reserved for the cases when the Postfix queue manager's scheduler +preempts one message with another and suddenly needs some extra +recipient slots for the chosen message in order to avoid performance +degradation. +</p> + +<p> Use <i>transport</i>_extra_recipient_limit to specify a +transport-specific override, where <i>transport</i> is the master.cf +name of the message delivery transport. +</p> + +%PARAM default_minimum_delivery_slots 3 + +<p> +How many recipients a message must have in order to invoke the +Postfix queue manager's scheduling algorithm at all. Messages +which would never accumulate at least this many delivery slots +(subject to slot cost parameter as well) are never preempted. +</p> + +<p> Use <i>transport</i>_minimum_delivery_slots to specify a +transport-specific override, where <i>transport</i> is the master.cf +name of the message delivery transport. +</p> + +%PARAM default_privs nobody + +<p> +The default rights used by the local(8) delivery agent for delivery +to an external file or command. These rights are used when delivery +is requested from an aliases(5) file that is owned by <b>root</b>, or +when delivery is done on behalf of <b>root</b>. <b>DO NOT SPECIFY A +PRIVILEGED USER OR THE POSTFIX OWNER</b>. +</p> + +%PARAM default_process_limit 100 + +<p> +The default maximal number of Postfix child processes that provide +a given service. This limit can be overruled for specific services +in the master.cf file. +</p> + +%PARAM default_rbl_reply see "postconf -d" output + +<p> +The default Postfix SMTP server response template for a request that is +rejected by an RBL-based restriction. This template can be overruled +by specific entries in the optional rbl_reply_maps lookup table. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +<p> +The template does not support Postfix configuration parameter $name +substitution. Instead, it supports exactly one level of $name +substitution for the following attributes: +</p> + +<dl> + +<dt><b>$client</b></dt> + +<dd>The client hostname and IP address, formatted as name[address]. </dd> + +<dt><b>$client_address</b></dt> + +<dd>The client IP address. </dd> + +<dt><b>$client_name</b></dt> + +<dd>The client hostname or "unknown". See reject_unknown_client_hostname +for more details. </dd> + +<dt><b>$reverse_client_name</b></dt> + +<dd>The client hostname from address->name lookup, or "unknown". +See reject_unknown_reverse_client_hostname for more details. </dd> + +#<dt><b>$forward_client_name</b></dt> +# +#<dd>The client hostname from address->name lookup followed by +#name->address lookup, or "unknown". See +#reject_unknown_forward_client_hostname for more details. </dd> + +<dt><b>$helo_name</b></dt> + +<dd>The hostname given in HELO or EHLO command or empty string. </dd> + +<dt><b>$rbl_class</b></dt> + +<dd>The denylisted entity type: Client host, Helo command, Sender +address, or Recipient address. </dd> + +<dt><b>$rbl_code</b></dt> + +<dd>The numerical SMTP response code, as specified with the +maps_rbl_reject_code configuration parameter. Note: The numerical +SMTP response code is required, and must appear at the start of the +reply. With Postfix version 2.3 and later this information may be followed +by an RFC 3463 enhanced status code. </dd> + +<dt><b>$rbl_domain</b></dt> + +<dd>The RBL domain where $rbl_what is denylisted. </dd> + +<dt><b>$rbl_reason</b></dt> + +<dd>The reason why $rbl_what is denylisted, or an empty string. </dd> + +<dt><b>$rbl_what</b></dt> + +<dd>The entity that is denylisted (an IP address, a hostname, a domain +name, or an email address whose domain was denylisted). </dd> + +<dt><b>$recipient</b></dt> + +<dd>The recipient address or <> in case of the null address. </dd> + +<dt><b>$recipient_domain</b></dt> + +<dd>The recipient domain or empty string. </dd> + +<dt><b>$recipient_name</b></dt> + +<dd>The recipient address localpart or <> in case of null address. </dd> + +<dt><b>$sender</b></dt> + +<dd>The sender address or <> in case of the null address. </dd> + +<dt><b>$sender_domain</b></dt> + +<dd>The sender domain or empty string. </dd> + +<dt><b>$sender_name</b></dt> + +<dd>The sender address localpart or <> in case of the null address. </dd> + +<dt><b>${name?value}</b></dt> + +<dt><b>${name?{value}}</b> (Postfix ≥ 3.0)</dt> + +<dd>Expands to <i>value</i> when <i>$name</i> is non-empty. </dd> + +<dt><b>${name:value}</b></dt> + +<dt><b>${name:{value}}</b> (Postfix ≥ 3.0)</dt> + +<dd>Expands to <i>value</i> when <i>$name</i> is empty. </dd> + +<dt><b>${name?{value1}:{value2}}</b> (Postfix ≥ 3.0)</dt> + +<dd>Expands to <i>value1</i> when <i>$name</i> is non-empty, +<i>value2</i> otherwise. </dd> + +</dl> + +<p> +Instead of $name you can also specify ${name} or $(name). +</p> + +<p> Note: when an enhanced status code is specified in an RBL reply +template, it is subject to modification. The following transformations +are needed when the same RBL reply template is used for client, +helo, sender, or recipient access restrictions. </p> + +<ul> + +<li> <p> When rejecting a sender address, the Postfix SMTP server +will transform a recipient DSN status (e.g., 4.1.1-4.1.6) into the +corresponding sender DSN status, and vice versa. </p> + +<li> <p> When rejecting non-address information (such as the HELO +command argument or the client hostname/address), the Postfix SMTP +server will transform a sender or recipient DSN status into a generic +non-address DSN status (e.g., 4.0.0). </p> + +</ul> + +%PARAM default_recipient_limit 20000 + +<p> +The default per-transport upper limit on the number of in-memory +recipients. These limits take priority over the global +qmgr_message_recipient_limit after the message has been assigned +to the respective transports. See also default_extra_recipient_limit +and qmgr_message_recipient_minimum. +</p> + +<p> Use <i>transport</i>_recipient_limit to specify a +transport-specific override, where <i>transport</i> is the master.cf +name of the message delivery transport. +</p> + +%PARAM default_recipient_refill_limit 100 + +<p> +The default per-transport limit on the number of recipients refilled at +once. When not all message recipients fit into memory at once, keep +loading more of them in batches of at least this many at a time. See also +$default_recipient_refill_delay, which may result in recipient batches +lower than this when this limit is too high for too slow deliveries. +</p> + +<p> Use <i>transport</i>_recipient_refill_limit to specify a +transport-specific override, where <i>transport</i> is the master.cf +name of the message delivery transport. +</p> + +<p> This feature is available in Postfix 2.4 and later. </p> + +%PARAM default_recipient_refill_delay 5s + +<p> +The default per-transport maximum delay between refilling recipients. +When not all message recipients fit into memory at once, keep loading +more of them at least once every this many seconds. This is used to +make sure the recipients are refilled in a timely manner even when +$default_recipient_refill_limit is too high for too slow deliveries. +</p> + +<p> Use <i>transport</i>_recipient_refill_delay to specify a +transport-specific override, where <i>transport</i> is the master.cf +name of the message delivery transport. +</p> + +<p> This feature is available in Postfix 2.4 and later. </p> + +%PARAM default_transport smtp + +<p> +The default mail delivery transport and next-hop destination for +destinations that do not match $mydestination, $inet_interfaces, +$proxy_interfaces, $virtual_alias_domains, $virtual_mailbox_domains, +or $relay_domains. This information can be overruled with the +sender_dependent_default_transport_maps parameter and with the +transport(5) table. </p> + +<p> +In order of decreasing precedence, the nexthop destination is taken +from $sender_dependent_default_transport_maps, $default_transport, +$sender_dependent_relayhost_maps, $relayhost, or from the recipient +domain. +</p> + +<p> +Specify a string of the form <i>transport:nexthop</i>, where <i>transport</i> +is the name of a mail delivery transport defined in master.cf. +The <i>:nexthop</i> destination is optional; its syntax is documented +in the manual page of the corresponding delivery agent. In the case of +SMTP or LMTP, specify one or more destinations separated by comma or +whitespace (with Postfix 3.5 and later). +</p> + +<p> +Example: +</p> + +<pre> +default_transport = uucp:relayhostname +</pre> + +%PARAM defer_code 450 + +<p> +The numerical Postfix SMTP server response code when a remote SMTP +client request is rejected by the "defer" restriction. +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +%PARAM defer_transports + +<p> +The names of message delivery transports that should not deliver mail +unless someone issues "<b>sendmail -q</b>" or equivalent. Specify zero +or more mail delivery transport names that appear in the +first field of master.cf. +</p> + +<p> +Example: +</p> + +<pre> +defer_transports = smtp +</pre> + +%PARAM deliver_lock_attempts 20 + +<p> +The maximal number of attempts to acquire an exclusive lock on a +mailbox file or bounce(8) logfile. +</p> + +%PARAM deliver_lock_delay 1s + +<p> +The time between attempts to acquire an exclusive lock on a mailbox +file or bounce(8) logfile. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM disable_vrfy_command no + +<p> +Disable the SMTP VRFY command. This stops some techniques used to +harvest email addresses. +</p> + +<p> +Example: +</p> + +<pre> +disable_vrfy_command = no +</pre> + +%PARAM double_bounce_sender double-bounce + +<p> The sender address of postmaster notifications that are generated +by the mail system. All mail to this address is silently discarded, +in order to terminate mail bounce loops. </p> + +%PARAM duplicate_filter_limit 1000 + +<p> The maximal number of addresses remembered by the address +duplicate filter for aliases(5) or virtual(5) alias expansion, or +for showq(8) queue displays. </p> + +%PARAM enable_original_recipient yes + +<p> Enable support for the original recipient address after an +address is rewritten to a different address (for example with +aliasing or with canonical mapping). </p> + +<p> The original recipient address is used as follows: </p> + +<dl> + +<dt> Final delivery </dt> <dd> With "enable_original_recipient = +yes", the original recipient address is stored in the <b>X-Original-To</b> +message header. This header may be used to distinguish between +different recipients that share the same mailbox. </dd> + +<dt> Recipient deduplication </dt> <dd> With "enable_original_recipient += yes", the cleanup(8) daemon performs duplicate recipient elimination +based on the content of (original recipient, maybe-rewritten +recipient) pairs. Otherwise, the cleanup(8) daemon performs duplicate +recipient elimination based only on the maybe-rewritten recipient +address. </dd> + +</dl> + +<p> Note: with Postfix ≤ 3.2 the "setting enable_original_recipient += <b>no</b>" breaks address verification for addresses that are +aliased or otherwise rewritten (Postfix is unable to store the +address verification result under the original probe destination +address; instead, it can store the result only under the rewritten +address). </p> + +<p> This feature is available in Postfix 2.1 and later. Postfix +version 2.0 behaves as if this parameter is always set to <b>yes</b>. +Postfix versions before 2.0 have no support for the original recipient +address. </p> + +%PARAM export_environment see "postconf -d" output + +<p> +The list of environment variables that a Postfix process will export +to non-Postfix processes. The TZ variable is needed for sane +time keeping on System-V-ish systems. +</p> + +<p> +Specify a list of names and/or name=value pairs, separated by +whitespace or comma. Specify "{ name=value }" to protect whitespace +or comma in parameter values (whitespace after the opening "{" and +before the closing "}" +is ignored). The form name=value is supported with Postfix version +2.1 and later; the use of {} is supported with Postfix 3.0 and +later. </p> + +<p> +Example: +</p> + +<pre> +export_environment = TZ PATH=/bin:/usr/bin +</pre> + +%PARAM smtp_fallback_relay $fallback_relay + +<p> +Optional list of relay hosts for SMTP destinations that can't be +found or that are unreachable. With Postfix 2.2 and earlier this +parameter is called fallback_relay. </p> + +<p> +By default, mail is returned to the sender when a destination is +not found, and delivery is deferred when a destination is unreachable. +</p> + +<p> With bulk email deliveries, it can be beneficial to run the +fallback relay MTA on the same host, so that it can reuse the sender +IP address. This speeds up deliveries that are delayed by IP-based +reputation systems (greylist, etc.). </p> + +<p> The fallback relays must be SMTP destinations. Specify a domain, +host, host:port, [host]:port, [address] or [address]:port; the form +[host] turns off MX lookups. If you specify multiple SMTP +destinations, Postfix will try them in the specified order. </p> + +<p> To prevent mailer loops between MX hosts and fall-back hosts, +Postfix version 2.2 and later will not use the fallback relays for +destinations that it is MX host for (assuming DNS lookup is turned on). +</p> + +%PARAM fallback_relay + +<p> +Optional list of relay hosts for SMTP destinations that can't be +found or that are unreachable. With Postfix 2.3 this parameter +is renamed to smtp_fallback_relay. </p> + +<p> +By default, mail is returned to the sender when a destination is +not found, and delivery is deferred when a destination is unreachable. +</p> + +<p> The fallback relays must be SMTP destinations. Specify a domain, +host, host:port, [host]:port, [address] or [address]:port; the form +[host] turns off MX lookups. If you specify multiple SMTP +destinations, Postfix will try them in the specified order. </p> + +<p> Note: before Postfix 2.2, do not use the fallback_relay feature +when relaying mail +for a backup or primary MX domain. Mail would loop between the +Postfix MX host and the fallback_relay host when the final destination +is unavailable. </p> + +<ul> + +<li> In main.cf specify "relay_transport = relay", + +<li> In master.cf specify "-o fallback_relay =" (i.e., empty) at +the end of the <tt>relay</tt> entry. + +<li> In transport maps, specify "relay:<i>nexthop...</i>" +as the right-hand side for backup or primary MX domain entries. + +</ul> + +<p> Postfix version 2.2 and later will not use the fallback_relay feature +for destinations that it is MX host for. +</p> + +%PARAM lmtp_fallback_relay + +<p> Optional list of relay hosts for LMTP destinations that can't be +found or that are unreachable. In main.cf elements are separated by +whitespace or commas. </p> + +<p> By default, mail is returned to the sender when a destination is not +found, and delivery is deferred when a destination is unreachable. </p> + +<p> The fallback relays must be TCP destinations, specified without +a leading "inet:" prefix. Specify a host or host:port. Since MX +lookups do not apply with LMTP, there is no need to use the "[host]" or +"[host]:port" forms. If you specify multiple LMTP destinations, Postfix +will try them in the specified order. </p> + +<p> +This feature is available in Postfix 3.1 and later. +</p> + +%PARAM fast_flush_domains $relay_domains + +<p> +Optional list of destinations that are eligible for per-destination +logfiles with mail that is queued to those destinations. +</p> + +<p> +By default, Postfix maintains "fast flush" logfiles only for +destinations that the Postfix SMTP server is willing to relay to +(i.e. the default is: "fast_flush_domains = $relay_domains"; see +the relay_domains parameter in the postconf(5) manual). +</p> + +<p> Specify a list of hosts or domains, "/file/name" patterns or +"type:table" lookup tables, separated by commas and/or whitespace. +Continue long lines by starting the next line with whitespace. A +"/file/name" pattern is replaced by its contents; a "type:table" +lookup table is matched when the domain or its parent domain appears +as lookup key. </p> + +<p> Pattern matching of domain names is controlled by the presence +or absence of "fast_flush_domains" in the parent_domain_matches_subdomains +parameter value. </p> + +<p> +Specify "fast_flush_domains =" (i.e., empty) to disable the feature +altogether. +</p> + +%PARAM fast_flush_purge_time 7d + +<p> +The time after which an empty per-destination "fast flush" logfile +is deleted. +</p> + +<p> +You can specify the time as a number, or as a number followed by +a letter that indicates the time unit: s=seconds, m=minutes, h=hours, +d=days, w=weeks. The default time unit is days. +</p> + +%PARAM fast_flush_refresh_time 12h + +<p> +The time after which a non-empty but unread per-destination "fast +flush" logfile needs to be refreshed. The contents of a logfile +are refreshed by requesting delivery of all messages listed in the +logfile. +</p> + +<p> +You can specify the time as a number, or as a number followed by +a letter that indicates the time unit: s=seconds, m=minutes, h=hours, +d=days, w=weeks. The default time unit is hours. +</p> + +%PARAM fork_attempts 5 + +<p> The maximal number of attempts to fork() a child process. </p> + +%PARAM fork_delay 1s + +<p> The delay between attempts to fork() a child process. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM execution_directory_expansion_filter see "postconf -d" output + +<p> Restrict the characters that the local(8) delivery agent allows +in $name expansions of $command_execution_directory. Characters +outside the allowed set are replaced by underscores. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM command_execution_directory + +<p> The local(8) delivery agent working directory for delivery to +external commands. Failure to change directory causes the delivery +to be deferred. </p> + +<p> The command_execution_directory value is not subject to Postfix +configuration parameter $name expansion. Instead, the following +$name expansions are done on command_execution_directory before the +directory is used. Expansion happens in the context +of the delivery request. The result of $name expansion is filtered +with the character set that is specified with the +execution_directory_expansion_filter parameter. </p> + +<dl> + +<dt><b>$user</b></dt> + +<dd>The recipient's username. </dd> + +<dt><b>$shell</b></dt> + +<dd>The recipient's login shell pathname. </dd> + +<dt><b>$home</b></dt> + +<dd>The recipient's home directory. </dd> + +<dt><b>$recipient</b></dt> + +<dd>The full recipient address. </dd> + +<dt><b>$extension</b></dt> + +<dd>The optional recipient address extension. </dd> + +<dt><b>$domain</b></dt> + +<dd>The recipient domain. </dd> + +<dt><b>$local</b></dt> + +<dd>The entire recipient localpart. </dd> + +<dt><b>$recipient_delimiter</b></dt> + +<dd>The address extension delimiter that was found in the recipient +address (Postfix 2.11 and later), or the system-wide recipient +address extension delimiter (Postfix 2.10 and earlier). </dd> + +<dt><b>${name?value}</b></dt> + +<dt><b>${name?{value}}</b> (Postfix ≥ 3.0)</dt> + +<dd>Expands to <i>value</i> when <i>$name</i> is non-empty. </dd> + +<dt><b>${name:value}</b></dt> + +<dt><b>${name:{value}}</b> (Postfix ≥ 3.0)</dt> + +<dd>Expands to <i>value</i> when <i>$name</i> is empty. </dd> + +<dt><b>${name?{value1}:{value2}}</b> (Postfix ≥ 3.0)</dt> + +<dd>Expands to <i>value1</i> when <i>$name</i> is non-empty, +<i>value2</i> otherwise. </dd> + +</dl> + +<p> +Instead of $name you can also specify ${name} or $(name). +</p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM forward_path see "postconf -d" output + +<p> The local(8) delivery agent search list for finding a .forward +file with user-specified delivery methods. The first file that is +found is used. </p> + +<p> The forward_path value is not subject to Postfix configuration +parameter $name expansion. Instead, the following $name expansions +are done on forward_path before the search actually happens. +The result of $name expansion is +filtered with the character set that is specified with the +forward_expansion_filter parameter. </p> + +<dl> + +<dt><b>$user</b></dt> + +<dd>The recipient's username. </dd> + +<dt><b>$shell</b></dt> + +<dd>The recipient's login shell pathname. </dd> + +<dt><b>$home</b></dt> + +<dd>The recipient's home directory. </dd> + +<dt><b>$recipient</b></dt> + +<dd>The full recipient address. </dd> + +<dt><b>$extension</b></dt> + +<dd>The optional recipient address extension. </dd> + +<dt><b>$domain</b></dt> + +<dd>The recipient domain. </dd> + +<dt><b>$local</b></dt> + +<dd>The entire recipient localpart. </dd> + +<dt><b>$recipient_delimiter</b></dt> + +<dd>The address extension delimiter that was found in the recipient +address (Postfix 2.11 and later), or the 'first' delimiter specified +with the system-wide recipient address extension delimiter (Postfix +3.5.22, 3.5.12, 3.7.8, 3.8.3 and later). Historically, this was +always the system-wide recipient +address extension delimiter (Postfix 2.10 and earlier). </dd> + +<dt><b>${name?value}</b></dt> + +<dt><b>${name?{value}}</b> (Postfix ≥ 3.0)</dt> + +<dd>Expands to <i>value</i> when <i>$name</i> is non-empty. </dd> + +<dt><b>${name:value}</b></dt> + +<dt><b>${name:{value}}</b> (Postfix ≥ 3.0)</dt> + +<dd>Expands to <i>value</i> when <i>$name</i> is empty. </dd> + +<dt><b>${name?{value1}:{value2}}</b> (Postfix ≥ 3.0)</dt> + +<dd>Expands to <i>value1</i> when <i>$name</i> is non-empty, +<i>value2</i> otherwise. </dd> + +</dl> + +<p> +Instead of $name you can also specify ${name} or $(name). +</p> + +<p> +Examples: +</p> + +<pre> +forward_path = /var/forward/$user +forward_path = + /var/forward/$user/.forward$recipient_delimiter$extension, + /var/forward/$user/.forward +</pre> + +%CLASS queue-hashing Queue directory hashing + +<p> +Queue directory hashing is a performance feature. Splitting one +queue directory across multiple subdirectory levels can speed up +file access by reducing the number of files per directory. +</p> + +<p> +Unfortunately, deeply hashing the incoming or deferred queue can +actually slow down the mail system (with a depth of 2, mailq with +an empty queue can take several seconds). +</p> + +<p> +Hashing must NOT be used with a world-writable maildrop directory. +Hashing MUST be used for the defer logfile directory, to avoid poor +performance when handling lots of deferred mail. +</p> + +%PARAM hash_queue_depth 1 + +<p> +The number of subdirectory levels for queue directories listed with +the hash_queue_names parameter. Queue hashing is implemented by +creating one or more levels of directories with one-character names. +Originally, these directory names were equal to the first characters +of the queue file name, with the hexadecimal representation of the +file creation time in microseconds. </p> + +<p> With long queue file names, queue hashing produces the same +results as with short names. The file creation time in microseconds +is converted into hexadecimal form before the result is used for +queue hashing. The base 16 encoding gives finer control over the +number of subdirectories than is possible with the base 52 encoding +of long queue file names. </p> + +<p> +After changing the hash_queue_names or hash_queue_depth parameter, +execute the command "<b>postfix reload</b>". +</p> + +%PARAM hash_queue_names deferred, defer + +<p> +The names of queue directories that are split across multiple +subdirectory levels. +</p> + +<p> Before Postfix version 2.2, the default list of hashed queues +was significantly larger. Claims about improvements in file system +technology suggest that hashing of the incoming and active queues +is no longer needed. Fewer hashed directories speed up the time +needed to restart Postfix. </p> + +<p> +After changing the hash_queue_names or hash_queue_depth parameter, +execute the command "<b>postfix reload</b>". +</p> + +%CLASS headerbody-checks Content inspection built-in features + +<p> +The Postfix cleanup(8) server has a limited ability to inspect +message headers and body content for signs of trouble. This is not +meant to be a substitute for content filters that do complex +processing such attachment decoding and unzipping. +</p> + +%PARAM header_checks + +<p> +Optional lookup tables for content inspection of primary non-MIME +message headers, as specified in the header_checks(5) manual page. +</p> + +%PARAM header_size_limit 102400 + +<p> +The maximal amount of memory in bytes for storing a message header. +If a header is larger, the excess is discarded. The limit is +enforced by the cleanup(8) server. +</p> + +%PARAM home_mailbox + +<p> +Optional pathname of a mailbox file relative to a local(8) user's +home directory. +</p> + +<p> +Specify a pathname ending in "/" for qmail-style delivery. +</p> + +<p> The precedence of local(8) delivery features from high to low +is: aliases, .forward files, mailbox_transport_maps, mailbox_transport, +mailbox_command_maps, mailbox_command, home_mailbox, mail_spool_directory, +fallback_transport_maps, fallback_transport and luser_relay. </p> + +<p> +Examples: +</p> + +<pre> +home_mailbox = Mailbox +home_mailbox = Maildir/ +</pre> + +%PARAM hopcount_limit 50 + +<p> +The maximal number of Received: message headers that is allowed +in the primary message headers. A message that exceeds the limit +is bounced, in order to stop a mailer loop. +</p> + +%PARAM ignore_mx_lookup_error no + +<p> Ignore DNS MX lookups that produce no response. By default, +the Postfix SMTP client defers delivery and tries again after some +delay. This behavior is required by the SMTP standard. </p> + +<p> +Specify "ignore_mx_lookup_error = yes" to force a DNS A record +lookup instead. This violates the SMTP standard and can result in +mis-delivery of mail. +</p> + +%PARAM import_environment see "postconf -d" output + +<p> The list of environment variables that a privileged Postfix +process will import from a non-Postfix parent process, or name=value +environment overrides. Unprivileged utilities will enforce the +name=value overrides, but otherwise will not change their process +environment. Examples of relevant environment variables: </p> + +<dl> + +<dt><b>TZ</b></dt> + +<dd>May be needed for sane time keeping on most System-V-ish systems. +</dd> + +<dt><b>DISPLAY</b></dt> + +<dd>Needed for debugging Postfix daemons with an X-windows debugger. </dd> + +<dt><b>XAUTHORITY</b></dt> + +<dd>Needed for debugging Postfix daemons with an X-windows debugger. </dd> + +<dt><b>MAIL_CONFIG</b></dt> + +<dd>Needed to make "<b>postfix -c</b>" work. </dd> + +</dl> + +<p> Specify a list of names and/or name=value pairs, separated by +whitespace or comma. Specify "{ name=value }" to protect whitespace +or comma in environment variable values (whitespace after the opening "{" and +before the closing "}" +is ignored). The form name=value is supported with Postfix version +2.1 and later; the use of {} is supported with Postfix 3.0 and +later. </p> + +%PARAM in_flow_delay 1s + +<p> Time to pause before accepting a new message, when the message +arrival rate exceeds the message delivery rate. This feature is +turned on by default (it's disabled on SCO UNIX due to an SCO bug). +</p> + +<p> +With the default 100 Postfix SMTP server process limit, "in_flow_delay += 1s" limits the mail inflow to 100 messages per second above the +number of messages delivered per second. +</p> + +<p> +Specify 0 to disable the feature. Valid delays are 0..10. +</p> + +%PARAM inet_interfaces all + +<p> The network interface addresses that this mail system receives +mail on. Specify "all" to receive mail on all network +interfaces (default), and "loopback-only" to receive mail +on loopback network interfaces only (Postfix version 2.2 and later). The +parameter also controls delivery of mail to <tt>user@[ip.address]</tt>. +</p> + +<p> +Note 1: you need to stop and start Postfix when this parameter changes. +</p> + +<p> Note 2: address information may be enclosed inside <tt>[]</tt>, +but this form is not required here. </p> + +<p> When inet_interfaces specifies just one IPv4 and/or IPv6 address +that is not a loopback address, the Postfix SMTP client will use +this address as the IP source address for outbound mail. Support +for IPv6 is available in Postfix version 2.2 and later. </p> + +<p> +On a multi-homed firewall with separate Postfix instances listening on the +"inside" and "outside" interfaces, this can prevent each instance from +being able to reach remote SMTP servers on the "other side" of the +firewall. Setting +smtp_bind_address to 0.0.0.0 avoids the potential problem for +IPv4, and setting smtp_bind_address6 to :: solves the problem +for IPv6. </p> + +<p> +A better solution for multi-homed firewalls is to leave inet_interfaces +at the default value and instead use explicit IP addresses in +the master.cf SMTP server definitions. This preserves the Postfix +SMTP client's +loop detection, by ensuring that each side of the firewall knows that the +other IP address is still the same host. Setting $inet_interfaces to a +single IPv4 and/or IPV6 address is primarily useful with virtual +hosting of domains on +secondary IP addresses, when each IP address serves a different domain +(and has a different $myhostname setting). </p> + +<p> +See also the proxy_interfaces parameter, for network addresses that +are forwarded to Postfix by way of a proxy or address translator. +</p> + +<p> +Examples: +</p> + +<pre> +inet_interfaces = all (DEFAULT) +inet_interfaces = loopback-only (Postfix version 2.2 and later) +inet_interfaces = 127.0.0.1 +inet_interfaces = 127.0.0.1, [::1] (Postfix version 2.2 and later) +inet_interfaces = 192.168.1.2, 127.0.0.1 +</pre> + +%PARAM inet_protocols see 'postconf -d output' + +<p> The Internet protocols Postfix will attempt to use when making +or accepting connections. Specify one or more of "ipv4" +or "ipv6", separated by whitespace or commas. The form +"all" is equivalent to "ipv4, ipv6" or "ipv4", depending +on whether the operating system implements IPv6. </p> + +<p> With Postfix 2.8 and earlier the default is "ipv4". For backwards +compatibility with these releases, the Postfix 2.9 and later upgrade +procedure appends an explicit "inet_protocols = ipv4" setting to +main.cf when no explicit setting is present. This compatibility +workaround will be phased out as IPv6 deployment becomes more common. +</p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +<p> Note: you MUST stop and start Postfix after changing this +parameter. </p> + +<p> On systems that pre-date IPV6_V6ONLY support (RFC 3493), an +IPv6 server will also accept IPv4 connections, even when IPv4 is +turned off with the inet_protocols parameter. On systems with +IPV6_V6ONLY support, Postfix will use separate server sockets for +IPv6 and IPv4, and each will accept only connections for the +corresponding protocol. </p> + +<p> When IPv4 support is enabled via the inet_protocols parameter, +Postfix will look up DNS type A records, and will convert +IPv4-in-IPv6 client IP addresses (::ffff:1.2.3.4) to their original +IPv4 form (1.2.3.4). The latter is needed on hosts that pre-date +IPV6_V6ONLY support (RFC 3493). </p> + +<p> When IPv6 support is enabled via the inet_protocols parameter, +Postfix will do DNS type AAAA record lookups. </p> + +<p> When both IPv4 and IPv6 support are enabled, the Postfix SMTP +client will choose the protocol as specified with the +smtp_address_preference parameter. Postfix versions before 2.8 +attempt to connect via IPv6 before attempting to use IPv4. </p> + +<p> +Examples: +</p> + +<pre> +inet_protocols = ipv4 +inet_protocols = all (DEFAULT) +inet_protocols = ipv6 +inet_protocols = ipv4, ipv6 +</pre> + +%PARAM initial_destination_concurrency 5 + +<p> +The initial per-destination concurrency level for parallel delivery +to the same destination. +With per-destination recipient limit > 1, a destination is a domain, +otherwise it is a recipient. +</p> + +<p> Use <i>transport</i>_initial_destination_concurrency to specify +a transport-specific override, where <i>transport</i> is the master.cf +name of the message delivery transport (Postfix 2.5 and later). </p> + +<p> +Warning: with concurrency of 1, one bad message can be enough to +block all mail to a site. +</p> + +%PARAM invalid_hostname_reject_code 501 + +<p> +The numerical Postfix SMTP server response code when the client +HELO or EHLO command parameter is rejected by the reject_invalid_helo_hostname +restriction. +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +%PARAM ipc_idle version dependent + +<p> +The time after which a client closes an idle internal communication +channel. The purpose is to allow Postfix daemon processes to +terminate voluntarily after they become idle. This is used, for +example, by the Postfix address resolving and rewriting clients. +</p> + +<p> With Postfix 2.4 the default value was reduced from 100s to 5s. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM ipc_timeout 3600s + +<p> +The time limit for sending or receiving information over an internal +communication channel. The purpose is to break out of deadlock +situations. If the time limit is exceeded the software aborts with a +fatal error. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM ipc_ttl 1000s + +<p> +The time after which a client closes an active internal communication +channel. The purpose is to allow Postfix daemon processes to +terminate voluntarily +after reaching their client limit. This is used, for example, by +the Postfix address resolving and rewriting clients. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM line_length_limit 2048 + +<p> Upon input, long lines are chopped up into pieces of at most +this length; upon delivery, long lines are reconstructed. </p> + +%PARAM lmtp_connect_timeout 0s + +<p> The Postfix LMTP client time limit for completing a TCP connection, or +zero (use the operating system built-in time limit). When no +connection can be made within the deadline, the LMTP client tries +the next address on the mail exchanger list. </p> + +<p> Specify a non-negative time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> +Example: +</p> + +<pre> +lmtp_connect_timeout = 30s +</pre> + +%PARAM lmtp_data_done_timeout 600s + +<p> The Postfix LMTP client time limit for sending the LMTP ".", +and for receiving the remote LMTP server response. When no response +is received within the deadline, a warning is logged that the mail +may be delivered multiple times. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM lmtp_data_init_timeout 120s + +<p> +The Postfix LMTP client time limit for sending the LMTP DATA command, +and +for receiving the remote LMTP server response. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM lmtp_data_xfer_timeout 180s + +<p> +The Postfix LMTP client time limit for sending the LMTP message +content. +When the connection stalls for more than $lmtp_data_xfer_timeout +the LMTP client terminates the transfer. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM lmtp_lhlo_timeout 300s + +<p> The Postfix LMTP client time limit for receiving the LMTP +greeting banner. When the remote LMTP server drops the connection +without sending a +greeting banner, or when it sends no greeting banner within the +deadline, the LMTP client tries the next address on the mail +exchanger list. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM lmtp_mail_timeout 300s + +<p> +The Postfix LMTP client time limit for sending the MAIL FROM command, +and for receiving the remote LMTP server response. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM lmtp_quit_timeout 300s + +<p> +The Postfix LMTP client time limit for sending the QUIT command, +and for receiving the remote LMTP server response. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM lmtp_rcpt_timeout 300s + +<p> +The Postfix LMTP client time limit for sending the RCPT TO command, +and for receiving the remote LMTP server response. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM lmtp_rset_timeout 20s + +<p> The Postfix LMTP client time limit for sending the RSET command, +and for receiving the remote LMTP server response. The LMTP client +sends RSET in +order to finish a recipient address probe, or to verify that a +cached connection is still alive. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM lmtp_send_xforward_command no + +<p> +Send an XFORWARD command to the remote LMTP server when the LMTP LHLO +server response announces XFORWARD support. This allows an lmtp(8) +delivery agent, used for content filter message injection, to +forward the name, address, protocol and HELO name of the original +client to the content filter and downstream LMTP server. +Before you change the value to yes, it is best to make sure that +your content filter supports this command. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM lmtp_skip_quit_response no + +<p> +Wait for the response to the LMTP QUIT command. +</p> + +%PARAM lmtp_xforward_timeout 300s + +<p> +The Postfix LMTP client time limit for sending the XFORWARD command, +and for receiving the remote LMTP server response. +</p> + +<p> +In case of problems the client does NOT try the next address on +the mail exchanger list. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM local_command_shell + +<p> +Optional shell program for local(8) delivery to non-Postfix commands. +By default, non-Postfix commands are executed directly; commands +are given to the default shell (typically, /bin/sh) only when they +contain shell meta characters or shell built-in commands. +</p> + +<p> "sendmail's restricted shell" (smrsh) is what most people will +use in order to restrict what programs can be run from e.g. .forward +files (smrsh is part of the Sendmail distribution). </p> + +<p> Note: when a shell program is specified, it is invoked even +when the command contains no shell built-in commands or meta +characters. </p> + +<p> +Example: +</p> + +<pre> +local_command_shell = /some/where/smrsh -c +local_command_shell = /bin/bash -c +</pre> + +%PARAM local_destination_concurrency_limit 2 + +<p> The maximal number of parallel deliveries via the local mail +delivery transport to the same recipient (when +"local_destination_recipient_limit = 1") or the maximal number of +parallel deliveries to the same local domain (when +"local_destination_recipient_limit > 1"). This limit is enforced by +the queue manager. The message delivery transport name is the first +field in the entry in the master.cf file. </p> + +<p> A low limit of 2 is recommended, just in case someone has an +expensive shell command in a .forward file or in an alias (e.g., +a mailing list manager). You don't want to run lots of those at +the same time. </p> + +%PARAM local_destination_recipient_limit 1 + +<p> The maximal number of recipients per message delivery via the +local mail delivery transport. This limit is enforced by the queue +manager. The message delivery transport name is the first field in +the entry in the master.cf file. </p> + +<p> Setting this parameter to a value > 1 changes the meaning of +local_destination_concurrency_limit from concurrency per recipient +into concurrency per domain. </p> + +%PARAM local_recipient_maps proxy:unix:passwd.byname $alias_maps + +<p> Lookup tables with all names or addresses of local recipients: +a recipient address is local when its domain matches $mydestination, +$inet_interfaces or $proxy_interfaces. Specify @domain as a +wild-card for domains that do not have a valid recipient list. +Technically, tables listed with $local_recipient_maps are used as +lists: Postfix needs to know only if a lookup string is found or +not, but it does not use the result from table lookup. </p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> +If this parameter is non-empty (the default), then the Postfix SMTP +server will reject mail for unknown local users. +</p> + +<p> +To turn off local recipient checking in the Postfix SMTP server, +specify "local_recipient_maps =" (i.e. empty). +</p> + +<p> +The default setting assumes that you use the default Postfix local +delivery agent for local delivery. You need to update the +local_recipient_maps setting if: +</p> + +<ul> + +<li>You redefine the local delivery agent in master.cf. + +<li>You redefine the "local_transport" setting in main.cf. + +<li>You use the "luser_relay", "mailbox_transport", or "fallback_transport" +feature of the Postfix local(8) delivery agent. + +</ul> + +<p> +Details are described in the LOCAL_RECIPIENT_README file. +</p> + +<p> +Beware: if the Postfix SMTP server runs chrooted, you need to access +the passwd file via the proxymap(8) service, in order to overcome +chroot access restrictions. The alternative, maintaining a copy of +the system password file in the chroot jail is not practical. +</p> + +<p> +Examples: +</p> + +<pre> +local_recipient_maps = +</pre> + +%PARAM local_transport local:$myhostname + +<p> The default mail delivery transport and next-hop destination +for final delivery to domains listed with mydestination, and for +[ipaddress] destinations that match $inet_interfaces or $proxy_interfaces. +This information can be overruled with the transport(5) table. </p> + +<p> +By default, local mail is delivered to the transport called "local", +which is just the name of a service that is defined the master.cf file. +</p> + +<p> +Specify a string of the form <i>transport:nexthop</i>, where <i>transport</i> +is the name of a mail delivery transport defined in master.cf. +The <i>:nexthop</i> destination is optional; its syntax is documented +in the manual page of the corresponding delivery agent. +</p> + +<p> +Beware: if you override the default local delivery agent then you +need to review the LOCAL_RECIPIENT_README document, otherwise the +SMTP server may reject mail for local recipients. +</p> + +%PARAM luser_relay + +<p> +Optional catch-all destination for unknown local(8) recipients. +By default, mail for unknown recipients in domains that match +$mydestination, $inet_interfaces or $proxy_interfaces is returned +as undeliverable. +</p> + +<p> +The luser_relay value is not subject to Postfix configuration +parameter $name expansion. Instead, the following $name expansions +are done: +</p> + +<dl> + +<dt><b>$domain</b></dt> + +<dd>The recipient domain. </dd> + +<dt><b>$extension</b></dt> + +<dd>The recipient address extension. </dd> + +<dt><b>$home</b></dt> + +<dd>The recipient's home directory. </dd> + +<dt><b>$local</b></dt> + +<dd>The entire recipient address localpart. </dd> + +<dt><b>$recipient</b></dt> + +<dd>The full recipient address. </dd> + +<dt><b>$recipient_delimiter</b></dt> + +<dd>The address extension delimiter that was found in the recipient +address (Postfix 2.11 and later), or the system-wide recipient +address extension delimiter (Postfix 2.10 and earlier). </dd> + +<dt><b>$shell</b></dt> + +<dd>The recipient's login shell. </dd> + +<dt><b>$user</b></dt> + +<dd>The recipient username. </dd> + +<dt><b>${name?value}</b></dt> + +<dt><b>${name?{value}}</b> (Postfix ≥ 3.0)</dt> + +<dd>Expands to <i>value</i> when <i>$name</i> is non-empty. </dd> + +<dt><b>${name:value}</b></dt> + +<dt><b>${name:{value}}</b> (Postfix ≥ 3.0)</dt> + +<dd>Expands to <i>value</i> when <i>$name</i> is empty. </dd> + +<dt><b>${name?{value1}:{value2}}</b> (Postfix ≥ 3.0)</dt> + +<dd>Expands to <i>value1</i> when <i>$name</i> is non-empty, +<i>value2</i> otherwise. </dd> + +</dl> + +<p> +Instead of $name you can also specify ${name} or $(name). +</p> + +<p> +Note: luser_relay works only for the Postfix local(8) delivery agent. +</p> + +<p> +Note: if you use this feature for accounts not in the UNIX password +file, then you must specify "local_recipient_maps =" (i.e. empty) +in the main.cf file, otherwise the Postfix SMTP server will reject mail +for non-UNIX accounts with "User unknown in local recipient table". +</p> + +<p> +Examples: +</p> + +<pre> +luser_relay = $user@other.host +luser_relay = $local@other.host +luser_relay = admin+$local +</pre> + +%PARAM mail_name Postfix + +<p> +The mail system name that is displayed in Received: headers, in +the SMTP greeting banner, and in bounced mail. +</p> + +%PARAM mail_owner postfix + +<p> +The UNIX system account that owns the Postfix queue and most Postfix +daemon processes. Specify the name of an unprivileged user account +that does not share a user or group ID with other accounts, and that +owns no other files +or processes on the system. In particular, don't specify nobody +or daemon. PLEASE USE A DEDICATED USER ID AND GROUP ID. +</p> + +<p> +When this parameter value is changed you need to re-run "<b>postfix +set-permissions</b>" (with Postfix version 2.0 and earlier: +"<b>/etc/postfix/post-install set-permissions</b>". +</p> + +%PARAM mail_spool_directory see "postconf -d" output + +<p> +The directory where local(8) UNIX-style mailboxes are kept. The +default setting depends on the system type. Specify a name ending +in / for maildir-style delivery. +</p> + +<p> +Note: maildir delivery is done with the privileges of the recipient. +If you use the mail_spool_directory setting for maildir style +delivery, then you must create the top-level maildir directory in +advance. Postfix will not create it. +</p> + +<p> +Examples: +</p> + +<pre> +mail_spool_directory = /var/mail +mail_spool_directory = /var/spool/mail +</pre> + +%PARAM mail_version see "postconf -d" output + +<p> +The version of the mail system. Stable releases are named +<i>major</i>.<i>minor</i>.<i>patchlevel</i>. Experimental releases +also include the release date. The version string can be used in, +for example, the SMTP greeting banner. +</p> + +%PARAM mailbox_command + +<p> +Optional external command that the local(8) delivery agent should +use for mailbox delivery. The command is run with the user ID and +the primary group ID privileges of the recipient. Exception: +command delivery for root executes with $default_privs privileges. +This is not a problem, because 1) mail for root should always be +aliased to a real user and 2) don't log in as root, use "su" instead. +</p> + +<p> +The following environment variables are exported to the command: +</p> + +<dl> + +<dt><b>CLIENT_ADDRESS</b></dt> + +<dd>Remote client network address. Available in Postfix version 2.2 and +later. </dd> + +<dt><b>CLIENT_HELO</b></dt> + +<dd>Remote client EHLO command parameter. Available in Postfix version 2.2 +and later.</dd> + +<dt><b>CLIENT_HOSTNAME</b></dt> + +<dd>Remote client hostname. Available in Postfix version 2.2 and later. +</dd> + +<dt><b>CLIENT_PROTOCOL</b></dt> + +<dd>Remote client protocol. Available in Postfix version 2.2 and later. +</dd> + +<dt><b>DOMAIN</b></dt> + +<dd>The domain part of the recipient address. </dd> + +<dt><b>EXTENSION</b></dt> + +<dd>The optional address extension. </dd> + +<dt><b>HOME</b></dt> + +<dd>The recipient home directory. </dd> + +<dt><b>LOCAL</b></dt> + +<dd>The recipient address localpart. </dd> + +<dt><b>LOGNAME</b></dt> + +<dd>The recipient's username. </dd> + +<dt><b>ORIGINAL_RECIPIENT</b></dt> + +<dd>The entire recipient address, before any address rewriting or +aliasing. </dd> + +<dt><b>RECIPIENT</b></dt> + +<dd>The full recipient address. </dd> + +<dt><b>SASL_METHOD</b></dt> + +<dd>SASL authentication method specified in the remote client AUTH +command. Available in Postfix version 2.2 and later. </dd> + +<dt><b>SASL_SENDER</b></dt> + +<dd>SASL sender address specified in the remote client MAIL FROM +command. Available in Postfix version 2.2 and later. </dd> + +<dt><b>SASL_USER</b></dt> + +<dd>SASL username specified in the remote client AUTH command. +Available in Postfix version 2.2 and later. </dd> + +<dt><b>SENDER</b></dt> + +<dd>The full sender address. </dd> + +<dt><b>SHELL</b></dt> + +<dd>The recipient's login shell. </dd> + +<dt><b>USER</b></dt> + +<dd>The recipient username. </dd> + +</dl> + +<p> +Unlike other Postfix configuration parameters, the mailbox_command +parameter is not subjected to $name substitutions. This is to make +it easier to specify shell syntax (see example below). +</p> + +<p> +If you can, avoid shell meta characters because they will force +Postfix to run an expensive shell process. If you're delivering +via "procmail" then running a shell won't make a noticeable difference +in the total cost. +</p> + +<p> +Note: if you use the mailbox_command feature to deliver mail +system-wide, you must set up an alias that forwards mail for root +to a real user. +</p> + +<p> The precedence of local(8) delivery features from high to low +is: aliases, .forward files, mailbox_transport_maps, mailbox_transport, +mailbox_command_maps, mailbox_command, home_mailbox, mail_spool_directory, +fallback_transport_maps, fallback_transport and luser_relay. </p> + +<p> +Examples: +</p> + +<pre> +mailbox_command = /some/where/procmail +mailbox_command = /some/where/procmail -a "$EXTENSION" +mailbox_command = /some/where/maildrop -d "$USER" + -f "$SENDER" "$EXTENSION" +</pre> + +%PARAM mailbox_size_limit 51200000 + +<p> The maximal size of any local(8) individual mailbox or maildir +file, or zero (no limit). In fact, this limits the size of any +file that is written to upon local delivery, including files written +by external commands that are executed by the local(8) delivery +agent. The value cannot exceed LONG_MAX (typically, a 32-bit or +64-bit signed integer). +</p> + +<p> +This limit must not be smaller than the message size limit. +</p> + +%PARAM maps_rbl_reject_code 554 + +<p> +The numerical Postfix SMTP server response code when a remote SMTP +client request is blocked by the reject_rbl_client, reject_rhsbl_client, +reject_rhsbl_reverse_client, reject_rhsbl_sender or +reject_rhsbl_recipient restriction. +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +%PARAM masquerade_classes envelope_sender, header_sender, header_recipient + +<p> +What addresses are subject to address masquerading. +</p> + +<p> +By default, address masquerading is limited to envelope sender +addresses, and to header sender and header recipient addresses. +This allows you to use address masquerading on a mail gateway while +still being able to forward mail to users on individual machines. +</p> + +<p> +Specify zero or more of: envelope_sender, envelope_recipient, +header_sender, header_recipient +</p> + +%PARAM masquerade_domains + +<p> +Optional list of domains whose subdomain structure will be stripped +off in email addresses. +</p> + +<p> +The list is processed left to right, and processing stops at the +first match. Thus, +</p> + +<blockquote> +<pre> +masquerade_domains = foo.example.com example.com +</pre> +</blockquote> + +<p> +strips "user@any.thing.foo.example.com" to "user@foo.example.com", +but strips "user@any.thing.else.example.com" to "user@example.com". +</p> + +<p> +A domain name prefixed with ! means do not masquerade this domain +or its subdomains. Thus, +</p> + +<blockquote> +<pre> +masquerade_domains = !foo.example.com example.com +</pre> +</blockquote> + +<p> +does not change "user@any.thing.foo.example.com" or "user@foo.example.com", +but strips "user@any.thing.else.example.com" to "user@example.com". +</p> + +<p> Note: with Postfix version 2.2, message header address masquerading +happens only when message header address rewriting is enabled: </p> + +<ul> + +<li> The message is received with the Postfix sendmail(1) command, + +<li> The message is received from a network client that matches +$local_header_rewrite_clients, + +<li> The message is received from the network, and the +remote_header_rewrite_domain parameter specifies a non-empty value. + +</ul> + +<p> To get the behavior before Postfix version 2.2, specify +"local_header_rewrite_clients = static:all". </p> + + +<p> +Example: +</p> + +<pre> +masquerade_domains = $mydomain +</pre> + +%PARAM masquerade_exceptions + +<p> +Optional list of user names that are not subjected to address +masquerading, even when their addresses match $masquerade_domains. +</p> + +<p> +By default, address masquerading makes no exceptions. +</p> + +<p> +Specify a list of user names, "/file/name" or "type:table" patterns, +separated by commas and/or whitespace. The list is matched left to +right, and the search stops on the first match. A "/file/name" +pattern is replaced +by its contents; a "type:table" lookup table is matched when a name +matches a lookup key (the lookup result is ignored). Continue long +lines by starting the next line with whitespace. Specify "!pattern" +to exclude a name from the list. The form "!/file/name" is supported +only in Postfix version 2.4 and later. </p> + +<p> +Examples: +</p> + +<pre> +masquerade_exceptions = root, mailer-daemon +masquerade_exceptions = root +</pre> + +%PARAM max_idle 100s + +<p> +The maximum amount of time that an idle Postfix daemon process waits +for an incoming connection before terminating voluntarily. This +parameter +is ignored by the Postfix queue manager and by other long-lived +Postfix daemon processes. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM max_use 100 + +<p> +The maximal number of incoming connections that a Postfix daemon +process will service before terminating voluntarily. This parameter +is ignored by the Postfix queue +manager and by other long-lived Postfix daemon processes. +</p> + +%PARAM maximal_backoff_time 4000s + +<p> +The maximal time between attempts to deliver a deferred message. +</p> + +<p> This parameter should be set to a value greater than or equal +to $minimal_backoff_time. See also $queue_run_delay. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM maximal_queue_lifetime 5d + +<p> +Consider a message as undeliverable, when delivery fails with a +temporary error, and the time in the queue has reached the +maximal_queue_lifetime limit. +</p> + +<p> Specify a non-negative time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is d (days). </p> + +<p> +Specify 0 when mail delivery should be tried only once. +</p> + +%PARAM lmdb_map_size 16777216 + +<p> +The initial OpenLDAP LMDB database size limit in bytes. Each time +a database becomes full, its size limit is doubled. +</p> + +<p> +This feature is available in Postfix 2.11 and later. +</p> + +%PARAM message_size_limit 10240000 + +<p> +The maximal size in bytes of a message, including envelope information. +The value cannot exceed LONG_MAX (typically, a 32-bit or 64-bit +signed integer). +</p> + +<p> Note: be careful when making changes. Excessively small values +will result in the loss of non-delivery notifications, when a bounce +message size exceeds the local or remote MTA's message size limit. +</p> + +%PARAM minimal_backoff_time 300s + +<p> +The minimal time between attempts to deliver a deferred message; +prior to Postfix 2.4 the default value was 1000s. +</p> + +<p> +This parameter also limits the time an unreachable destination is +kept in the short-term, in-memory, destination status cache. +</p> + +<p> This parameter should be set greater than or equal to +$queue_run_delay. See also $maximal_backoff_time. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM multi_recipient_bounce_reject_code 550 + +<p> +The numerical Postfix SMTP server response code when a remote SMTP +client request is blocked by the reject_multi_recipient_bounce +restriction. +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM mydestination $myhostname, localhost.$mydomain, localhost + +<p> The list of domains that are delivered via the $local_transport +mail delivery transport. By default this is the Postfix local(8) +delivery agent which looks up all recipients in /etc/passwd and +/etc/aliases. The SMTP server validates recipient addresses with +$local_recipient_maps and rejects non-existent recipients. See also +the local domain class in the ADDRESS_CLASS_README file. +</p> + +<p> +The default mydestination value specifies names for the local +machine only. On a mail domain gateway, you should also include +$mydomain. +</p> + +<p> +The $local_transport delivery method is also selected for mail +addressed to user@[the.net.work.address] of the mail system (the +IP addresses specified with the inet_interfaces and proxy_interfaces +parameters). +</p> + +<p> +Warnings: +</p> + +<ul> + +<li><p>Do not specify the names of virtual domains - those domains +are specified elsewhere. See VIRTUAL_README for more information. </p> + +<li><p>Do not specify the names of domains that this machine is +backup MX host for. See STANDARD_CONFIGURATION_README for how to +set up backup MX hosts. </p> + +<li><p>By default, the Postfix SMTP server rejects mail for recipients +not listed with the local_recipient_maps parameter. See the +postconf(5) manual for a description of the local_recipient_maps +and unknown_local_recipient_reject_code parameters. </p> + +</ul> + +<p> +Specify a list of host or domain names, "/file/name" or "type:table" +patterns, separated by commas and/or whitespace. A "/file/name" +pattern is replaced by its contents; a "type:table" lookup table +is matched when a name matches a lookup key (the lookup result is +ignored). Continue long lines by starting the next line with +whitespace. </p> + +<p> +Examples: +</p> + +<pre> +mydestination = $myhostname, localhost.$mydomain $mydomain +mydestination = $myhostname, localhost.$mydomain www.$mydomain, ftp.$mydomain +</pre> + +%PARAM mydomain see "postconf -d" output + +<p> +The internet domain name of this mail system. The default is to +use $myhostname minus the first component, or "localdomain" (Postfix +2.3 and later). $mydomain is used as +a default value for many other configuration parameters. +</p> + +<p> +Example: +</p> + +<pre> +mydomain = domain.tld +</pre> + +%PARAM myhostname see "postconf -d" output + +<p> +The internet hostname of this mail system. The default is to use +the fully-qualified domain name (FQDN) from gethostname(), or to +use the non-FQDN result from gethostname() and append ".$mydomain". +$myhostname is used as a default value for many other configuration +parameters. </p> + +<p> +Example: +</p> + +<pre> +myhostname = host.example.com +</pre> + +%PARAM mynetworks see "postconf -d" output + +<p> +The list of "trusted" remote SMTP clients that have more privileges than +"strangers". +</p> + +<p> +In particular, "trusted" SMTP clients are allowed to relay mail +through Postfix. See the smtpd_relay_restrictions parameter +description in the postconf(5) manual. +</p> + +<p> +You can specify the list of "trusted" network addresses by hand +or you can let Postfix do it for you (which is the default). +See the description of the mynetworks_style parameter for more +information. +</p> + +<p> +If you specify the mynetworks list by hand, +Postfix ignores the mynetworks_style setting. +</p> + +<p> Specify a list of network addresses or network/netmask patterns, +separated by commas and/or whitespace. Continue long lines by +starting the next line with whitespace. </p> + +<p> The netmask specifies the number of bits in the network part +of a host address. You can also specify "/file/name" or "type:table" +patterns. A "/file/name" pattern is replaced by its contents; a +"type:table" lookup table is matched when a table entry matches a +lookup string (the lookup result is ignored). </p> + +<p> The list is matched left to right, and the search stops on the +first match. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only +in Postfix version 2.4 and later. </p> + +<p> Note 1: Pattern matching of domain names is controlled by the +presence or absence of "mynetworks" in the parent_domain_matches_subdomains +parameter value. </p> + +<p> Note 2: IP version 6 address information must be specified inside +<tt>[]</tt> in the mynetworks value, and in files specified with +"/file/name". IP version 6 addresses contain the ":" character, +and would otherwise be confused with a "type:table" pattern. </p> + +<p> Note 3: CIDR ranges cannot be specified in hash tables. Use cidr +tables if CIDR ranges are used. </p> + +<p> Examples: </p> + +<pre> +mynetworks = 127.0.0.0/8 168.100.189.0/28 +mynetworks = !192.168.0.1, 192.168.0.0/28 +mynetworks = 127.0.0.0/8 168.100.189.0/28 [::1]/128 [2001:240:587::]/64 +mynetworks = $config_directory/mynetworks +mynetworks = hash:/etc/postfix/network_table +mynetworks = cidr:/etc/postfix/network_table.cidr +</pre> + +%PARAM myorigin $myhostname + +<p> +The domain name that locally-posted mail appears to come +from, and that locally posted mail is delivered to. The default, +$myhostname, is adequate for small sites. If you run a domain with +multiple machines, you should (1) change this to $mydomain and (2) +set up a domain-wide alias database that aliases each user to +user@that.users.mailhost. +</p> + +<p> +Example: +</p> + +<pre> +myorigin = $mydomain +</pre> + +%PARAM notify_classes resource, software + +<p> +The list of error classes that are reported to the postmaster. These +postmaster notifications do not replace user notifications. The +default is to report only the most serious problems. The paranoid +may wish to turn on the policy (UCE and mail relaying) and protocol +error (broken mail software) reports. +</p> + +<p> NOTE: postmaster notifications may contain confidential information +such as SASL passwords or message content. It is the system +administrator's responsibility to treat such information with care. +</p> + +<p> +The error classes are: +</p> + +<dl> + +<dt><b>bounce</b> (also implies <b>2bounce</b>)</dt> + +<dd>Send the postmaster copies of the headers of bounced mail, and +send transcripts of SMTP sessions when Postfix rejects mail. The +notification is sent to the address specified with the +bounce_notice_recipient configuration parameter (default: postmaster). +</dd> + +<dt><b>2bounce</b></dt> + +<dd>Send undeliverable bounced mail to the postmaster. The notification +is sent to the address specified with the 2bounce_notice_recipient +configuration parameter (default: postmaster). </dd> + +<dt><b>data</b></dt> + +<dd>Send the postmaster a transcript of the SMTP session with an +error because a critical data file was unavailable. The notification +is sent to the address specified with the error_notice_recipient +configuration parameter (default: postmaster). <br> This feature +is available in Postfix 2.9 and later. </dd> + +<dt><b>delay</b></dt> + +<dd>Send the postmaster copies of the headers of delayed mail (see +delay_warning_time). The +notification is sent to the address specified with the +delay_notice_recipient configuration parameter (default: postmaster). +</dd> + +<dt><b>policy</b></dt> + +<dd>Send the postmaster a transcript of the SMTP session when a +client request was rejected because of (UCE) policy. The notification +is sent to the address specified with the error_notice_recipient +configuration parameter (default: postmaster). </dd> + +<dt><b>protocol</b></dt> + +<dd>Send the postmaster a transcript of the SMTP session in case +of client or server protocol errors. The notification is sent to +the address specified with the error_notice_recipient configuration +parameter (default: postmaster). </dd> + +<dt><b>resource</b></dt> + +<dd>Inform the postmaster of mail not delivered due to resource +problems. The notification is sent to the address specified with +the error_notice_recipient configuration parameter (default: +postmaster). </dd> + +<dt><b>software</b></dt> + +<dd>Inform the postmaster of mail not delivered due to software +problems. The notification is sent to the address specified with +the error_notice_recipient configuration parameter (default: +postmaster). </dd> + +</dl> + +<p> +Examples: +</p> + +<pre> +notify_classes = bounce, delay, policy, protocol, resource, software +notify_classes = 2bounce, resource, software +</pre> + +%PARAM parent_domain_matches_subdomains see "postconf -d" output + +<p> +A list of Postfix features where the pattern "example.com" also +matches subdomains of example.com, +instead of requiring an explicit ".example.com" pattern. This is +planned backwards compatibility: eventually, all Postfix features +are expected to require explicit ".example.com" style patterns when +you really want to match subdomains. +</p> + +<p> The following Postfix feature names are supported. </p> + +<dl> + +<dt> Postfix version 1.0 and later</dt> + +<dd> +debug_peer_list, +fast_flush_domains, +mynetworks, +permit_mx_backup_networks, +relay_domains, +transport_maps +</dd> + +<dt> Postfix version 1.1 and later</dt> + +<dd> +qmqpd_authorized_clients, +<a href="SMTPD_ACCESS_README.html">smtpd_access_maps</a>, +</dd> + +<dt> Postfix version 2.8 and later </dt> + +<dd> +postscreen_access_list +</dd> + +<dt> Postfix version 3.0 and later </dt> + +<dd> +smtpd_client_event_limit_exceptions +</dd> + +</dl> + +%PARAM propagate_unmatched_extensions canonical, virtual + +<p> +What address lookup tables copy an address extension from the lookup +key to the lookup result. +</p> + +<p> +For example, with a virtual(5) mapping of "<i>joe@example.com => +joe.user@example.net</i>", the address "<i>joe+foo@example.com</i>" +would rewrite to "<i>joe.user+foo@example.net</i>". +</p> + +<p> +Specify zero or more of <b>canonical</b>, <b>virtual</b>, <b>alias</b>, +<b>forward</b>, <b>include</b> or <b>generic</b>. These cause +address extension +propagation with canonical(5), virtual(5), and aliases(5) maps, +with local(8) .forward and :include: file lookups, and with smtp(8) +generic maps, respectively. </p> + +<p> +Note: enabling this feature for types other than <b>canonical</b> +and <b>virtual</b> is likely to cause problems when mail is forwarded +to other sites, especially with mail that is sent to a mailing list +exploder address. +</p> + +<p> +Examples: +</p> + +<pre> +propagate_unmatched_extensions = canonical, virtual, alias, + forward, include +propagate_unmatched_extensions = canonical, virtual +</pre> + +%PARAM proxy_interfaces + +<p> +The network interface addresses that this mail system receives mail +on by way of a proxy or network address translation unit. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +<p> You must specify your "outside" proxy/NAT addresses when your +system is a backup MX host for other domains, otherwise mail delivery +loops will happen when the primary MX host is down. </p> + +<p> +Example: +</p> + +<pre> +proxy_interfaces = 1.2.3.4 +</pre> + +%PARAM qmgr_message_active_limit 20000 + +<p> +The maximal number of messages in the active queue. +</p> + +%PARAM qmgr_message_recipient_limit 20000 + +<p> The maximal number of recipients held in memory by the Postfix +queue manager, and the maximal size of the short-term, +in-memory "dead" destination status cache. </p> + +%PARAM qmgr_message_recipient_minimum 10 + +<p> +The minimal number of in-memory recipients for any message. This +takes priority over any other in-memory recipient limits (i.e., +the global qmgr_message_recipient_limit and the per transport +_recipient_limit) if necessary. The minimum value allowed for this +parameter is 1. +</p> + +%PARAM qmqpd_authorized_clients + +<p> +What remote QMQP clients are allowed to connect to the Postfix QMQP +server port. +</p> + +<p> +By default, no client is allowed to use the service. This is +because the QMQP server will relay mail to any destination. +</p> + +<p> +Specify a list of client patterns. A list pattern specifies a host +name, a domain name, an internet address, or a network/mask pattern, +where the mask specifies the number of bits in the network part. +When a pattern specifies a file name, its contents are substituted +for the file name; when a pattern is a "type:table" table specification, +table lookup is used instead. </p> + +<p> +Patterns are separated by whitespace and/or commas. In order to +reverse the result, precede a pattern with an +exclamation point (!). The form "!/file/name" is supported only +in Postfix version 2.4 and later. +</p> + +<p> Pattern matching of domain names is controlled by the presence +or absence of "qmqpd_authorized_clients" in the +parent_domain_matches_subdomains parameter value. </p> + +<p> +Example: +</p> + +<pre> +qmqpd_authorized_clients = !192.168.0.1, 192.168.0.0/24 +</pre> + +%PARAM qmqpd_error_delay 1s + +<p> +How long the Postfix QMQP server will pause before sending a negative +reply to the remote QMQP client. The purpose is to slow down confused +or malicious clients. +</p> + +<p> Specify a non-negative time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM qmqpd_timeout 300s + +<p> +The time limit for sending or receiving information over the network. +If a read or write operation blocks for more than $qmqpd_timeout +seconds the Postfix QMQP server gives up and disconnects. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM queue_minfree 0 + +<p> +The minimal amount of free space in bytes in the queue file system +that is needed to receive mail. This is currently used by the +Postfix SMTP server to decide if it will accept any mail at all. +</p> + +<p> +By default, the Postfix SMTP server rejects MAIL FROM commands when +the amount of free space is less than 1.5*$message_size_limit +(Postfix version 2.1 and later). +To specify a higher minimum free space limit, specify a queue_minfree +value that is at least 1.5*$message_size_limit. +</p> + +<p> +With Postfix versions 2.0 and earlier, a queue_minfree value of +zero means there is no minimum required amount of free space. +</p> + +%PARAM queue_run_delay 300s + +<p> +The time between deferred queue scans by the queue manager; +prior to Postfix 2.4 the default value was 1000s. +</p> + +<p> This parameter should be set less than or equal to +$minimal_backoff_time. See also $maximal_backoff_time. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM rbl_reply_maps + +<p> +Optional lookup tables with RBL response templates. The tables are +indexed by the RBL domain name. By default, Postfix uses the default +template as specified with the default_rbl_reply configuration +parameter. See there for a discussion of the syntax of RBL reply +templates. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM receive_override_options + +<p> Enable or disable recipient validation, built-in content +filtering, or address mapping. Typically, these are specified in +master.cf as command-line arguments for the smtpd(8), qmqpd(8) or +pickup(8) daemons. </p> + +<p> Specify zero or more of the following options. The options +override main.cf settings and are either implemented by smtpd(8), +qmqpd(8), or pickup(8) themselves, or they are forwarded to the +cleanup server. </p> + +<dl> + +<dt><b><a name="no_unknown_recipient_checks">no_unknown_recipient_checks</a></b></dt> + +<dd>Do not try to reject unknown recipients (SMTP server only). +This is typically specified AFTER an external content filter. +</dd> + +<dt><b><a name="no_address_mappings">no_address_mappings</a></b></dt> + +<dd>Disable canonical address mapping, virtual alias map expansion, +address masquerading, and automatic BCC (blind carbon-copy) +recipients. This is typically specified BEFORE an external content +filter. </dd> + +<dt><b><a name="no_header_body_checks">no_header_body_checks</a></b></dt> + +<dd>Disable header/body_checks. This is typically specified AFTER +an external content filter. </dd> + +<dt><b><a name="no_milters">no_milters</a></b></dt> + +<dd>Disable Milter (mail filter) applications. This is typically +specified AFTER an external content filter. </dd> + +</dl> + +<p> +Note: when the "BEFORE content filter" receive_override_options +setting is specified in the main.cf file, specify the "AFTER content +filter" receive_override_options setting in master.cf (and vice +versa). +</p> + +<p> +Examples: +</p> + +<pre> +receive_override_options = + no_unknown_recipient_checks, no_header_body_checks +receive_override_options = no_address_mappings +</pre> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM recipient_bcc_maps + +<p> +Optional BCC (blind carbon-copy) address lookup tables, indexed by +recipient address. The BCC address (multiple results are not +supported) is added when mail enters from outside of Postfix. +</p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> +The table search order is as follows: +</p> + +<ul> + +<li> Look up the "user+extension@domain.tld" address including the +optional address extension. + +<li> Look up the "user@domain.tld" address without the optional +address extension. + +<li> Look up the "user+extension" address local part when the +recipient domain equals $myorigin, $mydestination, $inet_interfaces +or $proxy_interfaces. + +<li> Look up the "user" address local part when the recipient domain +equals $myorigin, $mydestination, $inet_interfaces or $proxy_interfaces. + +<li> Look up the "@domain.tld" part. + +</ul> + +<p> +Note: with Postfix 2.3 and later the BCC address is added as if it +was specified with NOTIFY=NONE. The sender will not be notified +when the BCC address is undeliverable, as long as all down-stream +software implements RFC 3461. +</p> + +<p> +Note: with Postfix 2.2 and earlier the sender will unconditionally +be notified when the BCC address is undeliverable. +</p> + +<p> Note: automatic BCC recipients are produced only for new mail. +To avoid mailer loops, automatic BCC recipients are not generated +after Postfix forwards mail internally, or after Postfix generates +mail itself. </p> + +<p> +Example: +</p> + +<pre> +recipient_bcc_maps = hash:/etc/postfix/recipient_bcc +</pre> + +<p> +After a change, run "<b>postmap /etc/postfix/recipient_bcc</b>". +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM recipient_canonical_maps + +<p> +Optional address mapping lookup tables for envelope and header +recipient addresses. +The table format and lookups are documented in canonical(5). +</p> + +<p> +Note: $recipient_canonical_maps is processed before $canonical_maps. +</p> + +<p> +Example: +</p> + +<pre> +recipient_canonical_maps = hash:/etc/postfix/recipient_canonical +</pre> + +%PARAM recipient_delimiter + +<p> The set of characters that can separate an email address +localpart, user name, or a .forward file name from its extension. +For example, with "recipient_delimiter = +", the software tries +user+foo@example.com before trying user@example.com, user+foo before +trying user, and .forward+foo before trying .forward. </p> + +<p> More formally, an email address localpart or user name is +separated from its extension by the first character that matches +the recipient_delimiter set. The delimiter character and extension +may then be used to generate an extended .forward file name. This +implementation recognizes one delimiter character and one extension +per email address localpart or email address. With Postfix 2.10 and +earlier, the recipient_delimiter specifies a single character. </p> + +<p> See canonical(5), local(8), relocated(5) and virtual(5) for the +effects of recipient_delimiter on lookups in aliases, canonical, +virtual, and relocated maps, and see the propagate_unmatched_extensions +parameter for propagating an extension from one email address to +another. </p> + +<p> When used in command_execution_directory, forward_path, or +luser_relay, ${recipient_delimiter} is replaced with the actual +recipient delimiter that was found in the recipient email address +(Postfix 2.11 and later), or it is replaced with the main.cf +recipient_delimiter parameter value (Postfix 2.10 and earlier). +</p> + +<p> The recipient_delimiter is not applied to the mailer-daemon +address, the postmaster address, or the double-bounce address. With +the default "owner_request_special = yes" setting, the recipient_delimiter +is also not applied to addresses with the special "owner-" prefix +or the special "-request" suffix. </p> + +<p> +Examples: +</p> + +<pre> +# Handle Postfix-style extensions. +recipient_delimiter = + +</pre> + +<pre> +# Handle both Postfix and qmail extensions (Postfix 2.11 and later). +recipient_delimiter = +- +</pre> + +<pre> +# Use .forward for mail without address extension, and for mail with +# an unrecognized address extension. +forward_path = $home/.forward${recipient_delimiter}${extension}, + $home/.forward +</pre> + +%PARAM reject_code 554 + +<p> +The numerical Postfix SMTP server response code when a remote SMTP +client request is rejected by the "reject" restriction. +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +%PARAM relay_domains Postfix ≥ 3.0: empty, Postfix < 3.0: $mydestination + +<p> What destination domains (and subdomains thereof) this system +will relay mail to. For details about how +the relay_domains value is used, see the description of the +permit_auth_destination and reject_unauth_destination SMTP recipient +restrictions. </p> + +<p> Domains that match $relay_domains are delivered with the +$relay_transport mail delivery transport. The SMTP server validates +recipient addresses with $relay_recipient_maps and rejects non-existent +recipients. See also the relay domains address class in the +ADDRESS_CLASS_README file. </p> + +<p> Note: Postfix will not automatically forward mail for domains +that list this system as their primary or backup MX host. See the +permit_mx_backup restriction in the postconf(5) manual page. </p> + +<p> Specify a list of host or domain names, "/file/name" patterns +or "type:table" lookup tables, separated by commas and/or whitespace. +Continue long lines by starting the next line with whitespace. A +"/file/name" pattern is replaced by its contents; a "type:table" +lookup table is matched when a (parent) domain appears as lookup +key. Specify "!pattern" to exclude a domain from the list. The form +"!/file/name" is supported only in Postfix version 2.4 and later. +</p> + +<p> Pattern matching of domain names is controlled by the presence +or absence of "relay_domains" in the parent_domain_matches_subdomains +parameter value. </p> + +%PARAM relay_domains_reject_code 554 + +<p> +The numerical Postfix SMTP server response code when a client +request is rejected by the reject_unauth_destination recipient +restriction. +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +%PARAM relay_recipient_maps + +<p> Optional lookup tables with all valid addresses in the domains +that match $relay_domains. Specify @domain as a wild-card for +domains that have no valid recipient list, and become a source of +backscatter mail: Postfix accepts spam for non-existent recipients +and then floods innocent people with undeliverable mail. Technically, +tables +listed with $relay_recipient_maps are used as lists: Postfix needs +to know only if a lookup string is found or not, but it does not +use the result from the table lookup. </p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> +If this parameter is non-empty, then the Postfix SMTP server will reject +mail to unknown relay users. This feature is off by default. +</p> + +<p> +See also the relay domains address class in the ADDRESS_CLASS_README +file. +</p> + +<p> +Example: +</p> + +<pre> +relay_recipient_maps = hash:/etc/postfix/relay_recipients +</pre> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM relayhost + +<p> +The next-hop destination(s) for non-local mail; overrides non-local +domains in recipient addresses. This information is overruled with +relay_transport, sender_dependent_default_transport_maps, +default_transport, sender_dependent_relayhost_maps +and with the transport(5) table. +</p> + +<p> +On an intranet, specify the organizational domain name. If your +internal DNS uses no MX records, specify the name of the intranet +gateway host instead. +</p> + +<p> +In the case of SMTP or LMTP delivery, specify one or more destinations +in the form of a domain name, hostname, hostname:port, [hostname]:port, +[hostaddress] or [hostaddress]:port, separated by comma or whitespace. +The form [hostname] turns off MX lookups. Multiple destinations are +supported in Postfix 3.5 and later. +</p> + +<p> +If you're connected via UUCP, see the UUCP_README file for useful +information. +</p> + +<p> +Examples: +</p> + +<pre> +relayhost = $mydomain +relayhost = [gateway.example.com] +relayhost = mail1.example:587, mail2.example:587 +relayhost = [an.ip.add.ress] +</pre> + +%PARAM relocated_maps + +<p> +Optional lookup tables with new contact information for users or +domains that no longer exist. The table format and lookups are +documented in relocated(5). +</p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> +If you use this feature, run "<b>postmap /etc/postfix/relocated</b>" to +build the necessary DBM or DB file after change, then "<b>postfix +reload</b>" to make the changes visible. +</p> + +<p> +Examples: +</p> + +<pre> +relocated_maps = dbm:/etc/postfix/relocated +relocated_maps = hash:/etc/postfix/relocated +</pre> + +%PARAM require_home_directory no + +<p> +Require that a local(8) recipient's home directory exists +before mail delivery is attempted. By default this test is disabled. +It can be useful for environments that import home directories to +the mail server (IMPORTING HOME DIRECTORIES IS NOT RECOMMENDED). +</p> + +%PARAM resolve_dequoted_address yes + +<p> Resolve a recipient address safely instead of correctly, by +looking inside quotes. </p> + +<p> By default, the Postfix address resolver does not quote the +address localpart as per RFC 822, so that additional @ or % or ! +operators remain visible. This behavior is safe but it is also +technically incorrect. </p> + +<p> If you specify "resolve_dequoted_address = no", then +the Postfix +resolver will not know about additional @ etc. operators in the +address localpart. This opens opportunities for obscure mail relay +attacks with user@domain@domain addresses when Postfix provides +backup MX service for Sendmail systems. </p> + +%PARAM resolve_null_domain no + +<p> Resolve an address that ends in the "@" null domain as if the +local hostname were specified, instead of rejecting the address as +invalid. </p> + +<p> This feature is available in Postfix 2.1 and later. +Earlier versions always resolve the null domain as the local +hostname. </p> + +<p> The Postfix SMTP server uses this feature to reject mail from +or to addresses that end in the "@" null domain, and from addresses +that rewrite into a form that ends in the "@" null domain. </p> + +%PARAM sender_bcc_maps + +<p> Optional BCC (blind carbon-copy) address lookup tables, indexed +by sender address. The BCC address (multiple results are not +supported) is added when mail enters from outside of Postfix. </p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> +The table search order is as follows: +</p> + +<ul> + +<li> Look up the "user+extension@domain.tld" address including the +optional address extension. + +<li> Look up the "user@domain.tld" address without the optional +address extension. + +<li> Look up the "user+extension" address local part when the +sender domain equals $myorigin, $mydestination, $inet_interfaces +or $proxy_interfaces. + +<li> Look up the "user" address local part when the sender domain +equals $myorigin, $mydestination, $inet_interfaces or $proxy_interfaces. + +<li> Look up the "@domain.tld" part. + +</ul> + +<p> +Note: with Postfix 2.3 and later the BCC address is added as if it +was specified with NOTIFY=NONE. The sender will not be notified +when the BCC address is undeliverable, as long as all down-stream +software implements RFC 3461. +</p> + +<p> +Note: with Postfix 2.2 and earlier the sender will be notified +when the BCC address is undeliverable. +</p> + +<p> Note: automatic BCC recipients are produced only for new mail. +To avoid mailer loops, automatic BCC recipients are not generated +after Postfix forwards mail internally, or after Postfix generates +mail itself. </p> + +<p> +Example: +</p> + +<pre> +sender_bcc_maps = hash:/etc/postfix/sender_bcc +</pre> + +<p> +After a change, run "<b>postmap /etc/postfix/sender_bcc</b>". +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM sender_canonical_maps + +<p> +Optional address mapping lookup tables for envelope and header +sender addresses. +The table format and lookups are documented in canonical(5). +</p> + +<p> +Example: you want to rewrite the SENDER address "user@ugly.domain" +to "user@pretty.domain", while still being able to send mail to +the RECIPIENT address "user@ugly.domain". +</p> + +<p> +Note: $sender_canonical_maps is processed before $canonical_maps. +</p> + +<p> +Example: +</p> + +<pre> +sender_canonical_maps = hash:/etc/postfix/sender_canonical +</pre> + +%PARAM smtp_always_send_ehlo yes + +<p> +Always send EHLO at the start of an SMTP session. +</p> + +<p> +With "smtp_always_send_ehlo = no", the Postfix SMTP client sends +EHLO only when +the word "ESMTP" appears in the server greeting banner (example: +220 spike.porcupine.org ESMTP Postfix). +</p> + +%PARAM smtp_bind_address + +<p> +An optional numerical network address that the Postfix SMTP client +should bind to when making an IPv4 connection. +</p> + +<p> +This can be specified in the main.cf file for all SMTP clients, or +it can be specified in the master.cf file for a specific client, +for example: +</p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + smtp ... smtp -o smtp_bind_address=11.22.33.44 +</pre> +</blockquote> + +<p> See smtp_bind_address_enforce for how Postfix should handle +errors (Postfix 3.7 and later). </p> + +<p> Note 1: when inet_interfaces specifies no more than one IPv4 +address, and that address is a non-loopback address, it is +automatically used as the smtp_bind_address. This supports virtual +IP hosting, but can be a problem on multi-homed firewalls. See the +inet_interfaces documentation for more detail. </p> + +<p> Note 2: address information may be enclosed inside <tt>[]</tt>, +but this form is not required here. </p> + +%PARAM smtp_bind_address6 + +<p> +An optional numerical network address that the Postfix SMTP client +should bind to when making an IPv6 connection. +</p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +<p> +This can be specified in the main.cf file for all SMTP clients, or +it can be specified in the master.cf file for a specific client, +for example: +</p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + smtp ... smtp -o smtp_bind_address6=1:2:3:4:5:6:7:8 +</pre> +</blockquote> + +<p> See smtp_bind_address_enforce for how Postfix should handle +errors (Postfix 3.7 and later). </p> + +<p> Note 1: when inet_interfaces specifies no more than one IPv6 +address, and that address is a non-loopback address, it is +automatically used as the smtp_bind_address6. This supports virtual +IP hosting, but can be a problem on multi-homed firewalls. See the +inet_interfaces documentation for more detail. </p> + +<p> Note 2: address information may be enclosed inside <tt>[]</tt>, +but this form is not recommended here. </p> + +%PARAM smtp_connection_cache_time_limit 2s + +<p> When SMTP connection caching is enabled, the amount of time that +an unused SMTP client socket is kept open before it is closed. Do +not specify larger values without permission from the remote sites. +</p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_connection_reuse_time_limit 300s + +<p> The amount of time during which Postfix will use an SMTP +connection repeatedly. The timer starts when the connection is +initiated (i.e. it includes the connect, greeting and helo latency, +in addition to the latencies of subsequent mail delivery transactions). +</p> + +<p> This feature addresses a performance stability problem with +remote SMTP servers. This problem is not specific to Postfix: it +can happen when any MTA sends large amounts of SMTP email to a site +that has multiple MX hosts. </p> + +<p> The problem starts when one of a set of MX hosts becomes slower +than the rest. Even though SMTP clients connect to fast and slow +MX hosts with equal probability, the slow MX host ends up with more +simultaneous inbound connections than the faster MX hosts, because +the slow MX host needs more time to serve each client request. </p> + +<p> The slow MX host becomes a connection attractor. If one MX +host becomes N times slower than the rest, it dominates mail delivery +latency unless there are more than N fast MX hosts to counter the +effect. And if the number of MX hosts is smaller than N, the mail +delivery latency becomes effectively that of the slowest MX host +divided by the total number of MX hosts. </p> + +<p> The solution uses connection caching in a way that differs from +Postfix version 2.2. By limiting the amount of time during which a connection +can be used repeatedly (instead of limiting the number of deliveries +over that connection), Postfix not only restores fairness in the +distribution of simultaneous connections across a set of MX hosts, +it also favors deliveries over connections that perform well, which +is exactly what we want. </p> + +<p> The default reuse time limit, 300s, is comparable to the various +smtp transaction timeouts which are fair estimates of maximum excess +latency for a slow delivery. Note that hosts may accept thousands +of messages over a single connection within the default connection +reuse time limit. This number is much larger than the default Postfix +version 2.2 limit of 10 messages per cached connection. It may prove necessary +to lower the limit to avoid interoperability issues with MTAs that +exhibit bugs when many messages are delivered via a single connection. +A lower reuse time limit risks losing the benefit of connection +reuse when the average connection and mail delivery latency exceeds +the reuse time limit. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtp_connection_cache_destinations + +<p> Permanently enable SMTP connection caching for the specified +destinations. With SMTP connection caching, a connection is not +closed immediately after completion of a mail transaction. Instead, +the connection is kept open for up to $smtp_connection_cache_time_limit +seconds. This allows connections to be reused for other deliveries, +and can improve mail delivery performance. </p> + +<p> Specify a comma or white space separated list of destinations +or pseudo-destinations: </p> + +<ul> + +<li> if mail is sent without a relay host: a domain name (the +right-hand side of an email address, without the [] around a numeric +IP address), + +<li> if mail is sent via a relay host: a relay host name (without +[] or non-default TCP port), as specified in main.cf or in the +transport map, + +<li> if mail is sent via a UNIX-domain socket: a pathname (without +the unix: prefix), + +<li> a /file/name with domain names and/or relay host names as +defined above, + +<li> a "type:table" with domain names and/or relay host names on +the left-hand side. The right-hand side result from "type:table" +lookups is ignored. + +</ul> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_connection_cache_on_demand yes + +<p> Temporarily enable SMTP connection caching while a destination +has a high volume of mail in the active queue. With SMTP connection +caching, a connection is not closed immediately after completion +of a mail transaction. Instead, the connection is kept open for +up to $smtp_connection_cache_time_limit seconds. This allows +connections to be reused for other deliveries, and can improve mail +delivery performance. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_connect_timeout 30s + +<p> +The Postfix SMTP client time limit for completing a TCP connection, or +zero (use the operating system built-in time limit). +</p> + +<p> +When no connection can be made within the deadline, the Postfix +SMTP client +tries the next address on the mail exchanger list. Specify 0 to +disable the time limit (i.e. use whatever timeout is implemented by +the operating system). +</p> + +<p> Specify a non-negative time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM smtp_data_done_timeout 600s + +<p> +The Postfix SMTP client time limit for sending the SMTP ".", and +for receiving the remote SMTP server response. +</p> + +<p> +When no response is received within the deadline, a warning is +logged that the mail may be delivered multiple times. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM smtp_data_init_timeout 120s + +<p> +The Postfix SMTP client time limit for sending the SMTP DATA command, +and for receiving the remote SMTP server response. +</p> + +<p> +Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). +</p> + +%PARAM smtp_data_xfer_timeout 180s + +<p> +The Postfix SMTP client time limit for sending the SMTP message content. +When the connection makes no progress for more than $smtp_data_xfer_timeout +seconds the Postfix SMTP client terminates the transfer. +</p> + +<p> +Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). +</p> + +%PARAM smtp_defer_if_no_mx_address_found no + +<p> +Defer mail delivery when no MX record resolves to an IP address. +</p> + +<p> +The default (no) is to return the mail as undeliverable. With older +Postfix versions the default was to keep trying to deliver the mail +until someone fixed the MX record or until the mail was too old. +</p> + +<p> +Note: the Postfix SMTP client always ignores MX records with equal +or worse preference +than the local MTA itself. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM lmtp_destination_concurrency_limit $default_destination_concurrency_limit + +<p> The maximal number of parallel deliveries to the same destination +via the lmtp message delivery transport. This limit is enforced by +the queue manager. The message delivery transport name is the first +field in the entry in the master.cf file. </p> + +%PARAM lmtp_destination_recipient_limit $default_destination_recipient_limit + +<p> The maximal number of recipients per message for the lmtp +message delivery transport. This limit is enforced by the queue +manager. The message delivery transport name is the first field in +the entry in the master.cf file. </p> + +<p> Setting this parameter to a value of 1 changes the meaning of +lmtp_destination_concurrency_limit from concurrency per domain into +concurrency per recipient. </p> + +%PARAM relay_destination_concurrency_limit $default_destination_concurrency_limit + +<p> The maximal number of parallel deliveries to the same destination +via the relay message delivery transport. This limit is enforced +by the queue manager. The message delivery transport name is the +first field in the entry in the master.cf file. </p> + +<p> This feature is available in Postfix 2.0 and later. </p> + +%PARAM relay_destination_recipient_limit $default_destination_recipient_limit + +<p> The maximal number of recipients per message for the relay +message delivery transport. This limit is enforced by the queue +manager. The message delivery transport name is the first field in +the entry in the master.cf file. </p> + +<p> Setting this parameter to a value of 1 changes the meaning of +relay_destination_concurrency_limit from concurrency per domain +into concurrency per recipient. </p> + +<p> This feature is available in Postfix 2.0 and later. </p> + +%PARAM smtp_destination_concurrency_limit $default_destination_concurrency_limit + +<p> The maximal number of parallel deliveries to the same destination +via the smtp message delivery transport. This limit is enforced by +the queue manager. The message delivery transport name is the first +field in the entry in the master.cf file. </p> + +%PARAM smtp_destination_recipient_limit $default_destination_recipient_limit + +<p> The maximal number of recipients per message for the smtp +message delivery transport. This limit is enforced by the queue +manager. The message delivery transport name is the first field in +the entry in the master.cf file. </p> + +<p> Setting this parameter to a value of 1 changes the meaning of +smtp_destination_concurrency_limit from concurrency per domain +into concurrency per recipient. </p> + +%PARAM virtual_destination_concurrency_limit $default_destination_concurrency_limit + +<p> The maximal number of parallel deliveries to the same destination +via the virtual message delivery transport. This limit is enforced +by the queue manager. The message delivery transport name is the +first field in the entry in the master.cf file. </p> + +%PARAM virtual_destination_recipient_limit $default_destination_recipient_limit + +<p> The maximal number of recipients per message for the virtual +message delivery transport. This limit is enforced by the queue +manager. The message delivery transport name is the first field in +the entry in the master.cf file. </p> + +<p> Setting this parameter to a value of 1 changes the meaning of +virtual_destination_concurrency_limit from concurrency per domain +into concurrency per recipient. </p> + +%PARAM smtp_helo_name $myhostname + +<p> +The hostname to send in the SMTP HELO or EHLO command. +</p> + +<p> +The default value is the machine hostname. Specify a hostname or +[ip.add.re.ss]. +</p> + +<p> +This information can be specified in the main.cf file for all SMTP +clients, or it can be specified in the master.cf file for a specific +client, for example: +</p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + mysmtp ... smtp -o smtp_helo_name=foo.bar.com +</pre> +</blockquote> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM smtp_helo_timeout 300s + +<p> +The Postfix SMTP client time limit for sending the HELO or EHLO command, +and for receiving the initial remote SMTP server response. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM smtp_host_lookup dns + +<p> +What mechanisms the Postfix SMTP client uses to look up a host's +IP address. This parameter is ignored when DNS lookups are disabled +(see: disable_dns_lookups and smtp_dns_support_level). The "dns" +mechanism is always tried before "native" if both are listed. +</p> + +<p> +Specify one of the following: +</p> + +<dl> + +<dt><b>dns</b></dt> + +<dd>Hosts can be found in the DNS (preferred). </dd> + +<dt><b>native</b></dt> + +<dd>Use the native naming service only (nsswitch.conf, or equivalent +mechanism). </dd> + +<dt><b>dns, native</b></dt> + +<dd>Use the native service for hosts not found in the DNS. </dd> + +</dl> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM smtp_line_length_limit 998 + +<p> +The maximal length of message header and body lines that Postfix +will send via SMTP. This limit does not include the <CR><LF> +at the end of each line. Longer lines are broken by inserting +"<CR><LF><SPACE>", to minimize the damage to MIME +formatted mail. Specify zero to disable this limit. +</p> + +<p> +The Postfix limit of 998 characters not including <CR><LF> +is consistent with the SMTP limit of 1000 characters including +<CR><LF>. The Postfix limit was 990 with Postfix 2.8 +and earlier. +</p> + +%PARAM smtp_mail_timeout 300s + +<p> +The Postfix SMTP client time limit for sending the MAIL FROM command, +and for receiving the remote SMTP server response. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM smtp_mx_address_limit 5 + +<p> +The maximal number of MX (mail exchanger) IP addresses that can +result from Postfix SMTP client mail exchanger lookups, or zero (no +limit). Prior to +Postfix version 2.3, this limit was disabled by default. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM smtp_mx_session_limit 2 + +<p> The maximal number of SMTP sessions per delivery request before +the Postfix SMTP client +gives up or delivers to a fall-back relay host, or zero (no +limit). This restriction ignores sessions that fail to complete the +SMTP initial handshake (Postfix version 2.2 and earlier) or that fail to +complete the EHLO and TLS handshake (Postfix version 2.3 and later). </p> + +<p> This feature is available in Postfix 2.1 and later. </p> + +%PARAM smtp_never_send_ehlo no + +<p> Never send EHLO at the start of an SMTP session. See also the +smtp_always_send_ehlo parameter. </p> + +%PARAM smtp_pix_workaround_threshold_time 500s + +<p> How long a message must be queued before the Postfix SMTP client +turns on the PIX firewall "<CR><LF>.<CR><LF>" +bug workaround for delivery through firewalls with "smtp fixup" +mode turned on. </p> + +<p> Specify a non-negative time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> +By default, the workaround is turned off for mail that is queued +for less than 500 seconds. In other words, the workaround is normally +turned off for the first delivery attempt. +</p> + +<p> +Specify 0 to enable the PIX firewall +"<CR><LF>.<CR><LF>" bug workaround upon the +first delivery attempt. +</p> + +%PARAM smtp_quit_timeout 300s + +<p> +The Postfix SMTP client time limit for sending the QUIT command, +and for receiving the remote SMTP server response. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM smtp_quote_rfc821_envelope yes + +<p> +Quote addresses in Postfix SMTP client MAIL FROM and RCPT TO commands +as required +by RFC 5321. This includes putting quotes around an address localpart +that ends in ".". +</p> + +<p> +The default is to comply with RFC 5321. If you have to send mail to +a broken SMTP server, configure a special SMTP client in master.cf: +</p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + broken-smtp . . . smtp -o smtp_quote_rfc821_envelope=no +</pre> +</blockquote> + +<p> +and route mail for the destination in question to the "broken-smtp" +message delivery with a transport(5) table. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM smtp_rcpt_timeout 300s + +<p> +The Postfix SMTP client time limit for sending the SMTP RCPT TO +command, and for receiving the remote SMTP server response. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM smtp_sasl_auth_enable no + +<p> +Enable SASL authentication in the Postfix SMTP client. By default, +the Postfix SMTP client uses no authentication. +</p> + +<p> +Example: +</p> + +<pre> +smtp_sasl_auth_enable = yes +</pre> + +%PARAM smtp_sasl_password_maps + +<p> +Optional Postfix SMTP client lookup tables with one username:password +entry per sender, remote hostname or next-hop domain. Per-sender +lookup is done only when sender-dependent authentication is enabled. +If no username:password entry is found, then the Postfix SMTP client +will not attempt to authenticate to the remote host. +</p> + +<p> +The Postfix SMTP client opens the lookup table before going to +chroot jail, so you can leave the password file in /etc/postfix. +</p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +%PARAM smtp_sasl_security_options noplaintext, noanonymous + +<p> Postfix SMTP client SASL security options; as of Postfix 2.3 +the list of available +features depends on the SASL client implementation that is selected +with <b>smtp_sasl_type</b>. </p> + +<p> The following security features are defined for the <b>cyrus</b> +client SASL implementation: </p> + +<p> +Specify zero or more of the following: +</p> + +<dl> + +<dt><b>noplaintext</b></dt> + +<dd>Disallow methods that use plaintext passwords. </dd> + +<dt><b>noactive</b></dt> + +<dd>Disallow methods subject to active (non-dictionary) attack. +</dd> + +<dt><b>nodictionary</b></dt> + +<dd>Disallow methods subject to passive (dictionary) attack. </dd> + +<dt><b>noanonymous</b></dt> + +<dd>Disallow methods that allow anonymous authentication. </dd> + +<dt><b>mutual_auth</b></dt> + +<dd>Only allow methods that provide mutual authentication (not +available with SASL version 1). </dd> + +</dl> + +<p> +Example: +</p> + +<pre> +smtp_sasl_security_options = noplaintext +</pre> + +%PARAM smtp_sasl_mechanism_filter + +<p> +If non-empty, a Postfix SMTP client filter for the remote SMTP +server's list of offered SASL mechanisms. Different client and +server implementations may support different mechanism lists; by +default, the Postfix SMTP client will use the intersection of the +two. smtp_sasl_mechanism_filter specifies an optional third mechanism +list to intersect with. </p> + +<p> Specify mechanism names, "/file/name" patterns or "type:table" +lookup tables. The right-hand side result from "type:table" lookups +is ignored. Specify "!pattern" to exclude a mechanism name from the +list. The form "!/file/name" is supported only in Postfix version +2.4 and later. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +<p> +Examples: +</p> + +<pre> +smtp_sasl_mechanism_filter = plain, login +smtp_sasl_mechanism_filter = /etc/postfix/smtp_mechs +smtp_sasl_mechanism_filter = !gssapi, !login, static:rest +</pre> + +%PARAM smtp_send_xforward_command no + +<p> +Send the non-standard XFORWARD command when the Postfix SMTP server +EHLO response announces XFORWARD support. +</p> + +<p> +This allows a Postfix SMTP delivery agent, used for injecting mail +into +a content filter, to forward the name, address, protocol and HELO +name of the original client to the content filter and downstream +queuing SMTP server. This can produce more useful logging than +localhost[127.0.0.1] etc. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM smtp_skip_4xx_greeting yes + +<p> +Skip SMTP servers that greet with a 4XX status code (go away, try +again later). +</p> + +<p> +By default, the Postfix SMTP client moves on the next mail exchanger. +Specify +"smtp_skip_4xx_greeting = no" if Postfix should defer delivery +immediately. +</p> + +<p> This feature is available in Postfix 2.0 and earlier. +Later Postfix versions always skip remote SMTP servers that greet +with a +4XX status code. </p> + +%PARAM smtp_skip_5xx_greeting yes + +<p> +Skip remote SMTP servers that greet with a 5XX status code. +</p> + +<p> By default, the Postfix SMTP client moves on the next mail +exchanger. Specify "smtp_skip_5xx_greeting = no" if Postfix should +bounce the mail immediately. Caution: the latter behavior appears +to contradict RFC 2821. </p> + +%PARAM smtp_skip_quit_response yes + +<p> +Do not wait for the response to the SMTP QUIT command. +</p> + +%PARAM smtp_xforward_timeout 300s + +<p> +The Postfix SMTP client time limit for sending the XFORWARD command, +and for receiving the remote SMTP server response. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM authorized_verp_clients $mynetworks + +<p> What remote SMTP clients are allowed to specify the XVERP command. +This command requests that mail be delivered one recipient at a +time with a per recipient return address. </p> + +<p> By default, only trusted clients are allowed to specify XVERP. +</p> + +<p> This parameter was introduced with Postfix version 1.1. Postfix +version 2.1 renamed this parameter to smtpd_authorized_verp_clients +and changed the default to none. </p> + +<p> Specify a list of network/netmask patterns, separated by commas +and/or whitespace. The mask specifies the number of bits in the +network part of a host address. You can also specify hostnames or +.domain names (the initial dot causes the domain to match any name +below it), "/file/name" or "type:table" patterns. A "/file/name" +pattern is replaced by its contents; a "type:table" lookup table +is matched when a table entry matches a lookup string (the lookup +result is ignored). Continue long lines by starting the next line +with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later. </p> + +<p> Note: IP version 6 address information must be specified inside +<tt>[]</tt> in the authorized_verp_clients value, and in files +specified with "/file/name". IP version 6 addresses contain the +":" character, and would otherwise be confused with a "type:table" +pattern. </p> + +%PARAM smtpd_authorized_verp_clients $authorized_verp_clients + +<p> What remote SMTP clients are allowed to specify the XVERP command. +This command requests that mail be delivered one recipient at a +time with a per recipient return address. </p> + +<p> By default, no clients are allowed to specify XVERP. </p> + +<p> This parameter was renamed with Postfix version 2.1. The default value +is backwards compatible with Postfix version 2.0. </p> + +<p> Specify a list of network/netmask patterns, separated by commas +and/or whitespace. The mask specifies the number of bits in the +network part of a host address. You can also specify hostnames or +.domain names (the initial dot causes the domain to match any name +below it), "/file/name" or "type:table" patterns. A "/file/name" +pattern is replaced by its contents; a "type:table" lookup table +is matched when a table entry matches a lookup string (the lookup +result is ignored). Continue long lines by starting the next line +with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later. </p> + +<p> Note: IP version 6 address information must be specified inside +<tt>[]</tt> in the smtpd_authorized_verp_clients value, and in +files specified with "/file/name". IP version 6 addresses contain +the ":" character, and would otherwise be confused with a "type:table" +pattern. </p> + +%PARAM smtpd_authorized_xclient_hosts + +<p> +What remote SMTP clients are allowed to use the XCLIENT feature. This +command overrides remote SMTP client information that is used for access +control. Typical use is for SMTP-based content filters, fetchmail-like +programs, or SMTP server access rule testing. See the XCLIENT_README +document for details. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +<p> +By default, no clients are allowed to specify XCLIENT. +</p> + +<p> +Specify a list of network/netmask patterns, separated by commas +and/or whitespace. The mask specifies the number of bits in the +network part of a host address. You can also specify hostnames or +.domain names (the initial dot causes the domain to match any name +below it), "/file/name" or "type:table" patterns. A "/file/name" +pattern is replaced by its contents; a "type:table" lookup table +is matched when a table entry matches a lookup string (the lookup +result is ignored). Continue long lines by starting the next line +with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later. </p> + +<p> Note: IP version 6 address information must be specified inside +<tt>[]</tt> in the smtpd_authorized_xclient_hosts value, and in +files specified with "/file/name". IP version 6 addresses contain +the ":" character, and would otherwise be confused with a "type:table" +pattern. </p> + +%PARAM smtpd_authorized_xforward_hosts + +<p> +What remote SMTP clients are allowed to use the XFORWARD feature. This +command forwards information that is used to improve logging after +SMTP-based content filters. See the XFORWARD_README document for +details. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +<p> +By default, no clients are allowed to specify XFORWARD. +</p> + +<p> +Specify a list of network/netmask patterns, separated by commas +and/or whitespace. The mask specifies the number of bits in the +network part of a host address. You can also specify hostnames or +.domain names (the initial dot causes the domain to match any name +below it), "/file/name" or "type:table" patterns. A "/file/name" +pattern is replaced by its contents; a "type:table" lookup table +is matched when a table entry matches a lookup string (the lookup +result is ignored). Continue long lines by starting the next line +with whitespace. Specify "!pattern" to exclude an address or network +block from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later. </p> + +<p> Note: IP version 6 address information must be specified inside +<tt>[]</tt> in the smtpd_authorized_xforward_hosts value, and in +files specified with "/file/name". IP version 6 addresses contain +the ":" character, and would otherwise be confused with a "type:table" +pattern. </p> + +%PARAM smtpd_banner $myhostname ESMTP $mail_name + +<p> +The text that follows the 220 status code in the SMTP greeting +banner. Some people like to see the mail version advertised. By +default, Postfix shows no version. +</p> + +<p> +You MUST specify $myhostname at the start of the text. This is +required by the SMTP protocol. +</p> + +<p> +Example: +</p> + +<pre> +smtpd_banner = $myhostname ESMTP $mail_name ($mail_version) +</pre> + +%PARAM smtpd_client_connection_count_limit 50 + +<p> +How many simultaneous connections any client is allowed to +make to this service. By default, the limit is set to half +the default process limit value. +</p> + +<p> +To disable this feature, specify a limit of 0. +</p> + +<p> +WARNING: The purpose of this feature is to limit abuse. It must +not be used to regulate legitimate mail traffic. +</p> + +<p> +This feature is available in Postfix 2.2 and later. +</p> + +%PARAM smtpd_client_event_limit_exceptions $mynetworks + +<p> +Clients that are excluded from smtpd_client_*_count/rate_limit +restrictions. See the mynetworks parameter +description for the parameter value syntax. +</p> + +<p> +By default, clients in trusted networks are excluded. Specify a +list of network blocks, hostnames or .domain names (the initial +dot causes the domain to match any name below it). +</p> + +<p> Note: IP version 6 address information must be specified inside +<tt>[]</tt> in the smtpd_client_event_limit_exceptions value, and +in files specified with "/file/name". IP version 6 addresses +contain the ":" character, and would otherwise be confused with a +"type:table" pattern. </p> + +<p> Pattern matching of domain names is controlled by the presence +or absence of "smtpd_client_event_limit_exceptions" in the +parent_domain_matches_subdomains parameter value (Postfix 3.0 and +later). </p> + +<p> +This feature is available in Postfix 2.2 and later. +</p> + +%PARAM smtpd_client_connection_rate_limit 0 + +<p> +The maximal number of connection attempts any client is allowed to +make to this service per time unit. The time unit is specified +with the anvil_rate_time_unit configuration parameter. +</p> + +<p> +By default, a client can make as many connections per time unit as +Postfix can accept. +</p> + +<p> +To disable this feature, specify a limit of 0. +</p> + +<p> +WARNING: The purpose of this feature is to limit abuse. It must +not be used to regulate legitimate mail traffic. +</p> + +<p> +This feature is available in Postfix 2.2 and later. +</p> + +<p> +Example: +</p> + +<pre> +smtpd_client_connection_rate_limit = 1000 +</pre> + +%PARAM smtpd_client_message_rate_limit 0 + +<p> +The maximal number of message delivery requests that any client is +allowed to make to this service per time unit, regardless of whether +or not Postfix actually accepts those messages. The time unit is +specified with the anvil_rate_time_unit configuration parameter. +</p> + +<p> +By default, a client can send as many message delivery requests +per time unit as Postfix can accept. +</p> + +<p> +To disable this feature, specify a limit of 0. +</p> + +<p> +WARNING: The purpose of this feature is to limit abuse. It must +not be used to regulate legitimate mail traffic. +</p> + +<p> +This feature is available in Postfix 2.2 and later. +</p> + +<p> +Example: +</p> + +<pre> +smtpd_client_message_rate_limit = 1000 +</pre> + +%PARAM smtpd_client_recipient_rate_limit 0 + +<p> +The maximal number of recipient addresses that any client is allowed +to send to this service per time unit, regardless of whether or not +Postfix actually accepts those recipients. The time unit is specified +with the anvil_rate_time_unit configuration parameter. +</p> + +<p> +By default, a client can send as many recipient addresses per time +unit as Postfix can accept. +</p> + +<p> +To disable this feature, specify a limit of 0. +</p> + +<p> +WARNING: The purpose of this feature is to limit abuse. It must +not be used to regulate legitimate mail traffic. +</p> + +<p> +This feature is available in Postfix 2.2 and later. +</p> + +<p> +Example: +</p> + +<pre> +smtpd_client_recipient_rate_limit = 1000 +</pre> + +%PARAM smtpd_client_new_tls_session_rate_limit 0 + +<p> +The maximal number of new (i.e., uncached) TLS sessions that a +remote SMTP client is allowed to negotiate with this service per +time unit. The time unit is specified with the anvil_rate_time_unit +configuration parameter. +</p> + +<p> +By default, a remote SMTP client can negotiate as many new TLS +sessions per time unit as Postfix can accept. +</p> + +<p> +To disable this feature, specify a limit of 0. Otherwise, specify +a limit that is at least the per-client concurrent session limit, +or else legitimate client sessions may be rejected. +</p> + +<p> +WARNING: The purpose of this feature is to limit abuse. It must +not be used to regulate legitimate mail traffic. +</p> + +<p> +This feature is available in Postfix 2.3 and later. +</p> + +<p> +Example: +</p> + +<pre> +smtpd_client_new_tls_session_rate_limit = 100 +</pre> + +%PARAM smtpd_client_auth_rate_limit 0 + +<p> +The maximal number of AUTH commands that any client is allowed to +send to this service per time unit, regardless of whether or not +Postfix actually accepts those commands. The time unit is specified +with the anvil_rate_time_unit configuration parameter. +</p> + +<p> +By default, there is no limit on the number of AUTH commands that a +client may send. +</p> + +<p> +To disable this feature, specify a limit of 0. +</p> + +<p> +WARNING: The purpose of this feature is to limit abuse. It must +not be used to regulate legitimate mail traffic. +</p> + +<p> +This feature is available in Postfix 3.1 and later. +</p> + +%PARAM smtpd_client_restrictions + +<p> +Optional restrictions that the Postfix SMTP server applies in the +context of a client connection request. +See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access +restriction lists" for a discussion of evaluation context and time. +</p> + +<p> +The default is to allow all connection requests. +</p> + +<p> +Specify a list of restrictions, separated by commas and/or whitespace. +Continue long lines by starting the next line with whitespace. +Restrictions are applied in the order as specified; the first +restriction that matches wins. +</p> + +<p> +The following restrictions are specific to client hostname or +client network address information. +</p> + +<dl> + +<dt><b><a name="check_ccert_access">check_ccert_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd> By default use the remote SMTP client certificate fingerprint +or the public key +fingerprint (Postfix 2.9 and later) as the lookup key for the specified +access(5) database; with Postfix version 2.2, also require that the +remote SMTP client certificate is verified successfully. +The fingerprint digest algorithm is configurable via the +smtpd_tls_fingerprint_digest parameter (hard-coded as md5 prior to +Postfix version 2.5). This feature requires "smtpd_tls_ask_ccert += yes" and is available with Postfix version +2.2 and later. </dd> + +<dd> The default algorithm is <b>sha256</b> with Postfix ≥ 3.6 +and the <b>compatibility_level</b> set to 3.6 or higher. With Postfix +≤ 3.5, the default algorithm is <b>md5</b>. The best-practice +algorithm is now <b>sha256</b>. Recent advances in hash function +cryptanalysis have led to md5 and sha1 being deprecated in favor of +sha256. However, as long as there are no known "second pre-image" +attacks against the older algorithms, their use in this context, though +not recommended, is still likely safe. </dd> + +<dd> Alternatively, check_ccert_access accepts an explicit search +order (Postfix 3.5 and later). The default search order as described +above corresponds with: </dd> + +<dd> check_ccert_access { type:table, { search_order = cert_fingerprint, +pubkey_fingerprint } } </dd> + +<dd> The commas are optional. </dd> + +<dt><b><a name="check_client_access">check_client_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access database for the client hostname, +parent domains, client IP address, or networks obtained by stripping +least significant octets. See the access(5) manual page for details. </dd> + +<dt><b><a name="check_client_a_access">check_client_a_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the IP addresses for the +client hostname, and execute the corresponding action. Note: a result +of "OK" is not allowed for safety reasons. Instead, use DUNNO in order +to exclude specific hosts from denylists. This feature is available +in Postfix 3.0 and later. </dd> + +<dt><b><a name="check_client_mx_access">check_client_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the MX hosts for the +client hostname, and execute the corresponding action. If no MX +record is found, look up A or AAAA records, just like the Postfix +SMTP client would. Note: a result +of "OK" is not allowed for safety reasons. Instead, use DUNNO in order +to exclude specific hosts from denylists. This feature is available +in Postfix 2.7 and later. </dd> + +<dt><b><a name="check_client_ns_access">check_client_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the DNS servers for +the client hostname, and execute the corresponding action. Note: a +result of "OK" is not allowed for safety reasons. Instead, use DUNNO +in order to exclude specific hosts from denylists. This feature is +available in Postfix 2.7 and later. </dd> + +<dt><b><a name="check_reverse_client_hostname_access">check_reverse_client_hostname_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access database for the unverified reverse +client hostname, parent domains, client IP address, or networks +obtained by stripping least significant octets. See the access(5) +manual page for details. Note: a result of "OK" is not allowed for +safety reasons. Instead, use DUNNO in order to exclude specific +hosts from denylists. This feature is available in Postfix 2.6 +and later.</dd> + +<dt><b><a name="check_reverse_client_hostname_a_access">check_reverse_client_hostname_a_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the IP addresses for the +unverified reverse client hostname, and execute the corresponding +action. Note: a result of "OK" is not allowed for safety reasons. +Instead, use DUNNO in order to exclude specific hosts from denylists. +This feature is available in Postfix 3.0 and later. </dd> + +<dt><b><a name="check_reverse_client_hostname_mx_access">check_reverse_client_hostname_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the MX hosts for the +unverified reverse client hostname, and execute the corresponding +action. If no MX record is found, look up A or AAAA records, just +like the Postfix SMTP client would. +Note: a result of "OK" is not allowed for safety reasons. +Instead, use DUNNO in order to exclude specific hosts from denylists. +This feature is available in Postfix 2.7 and later. </dd> + +<dt><b><a name="check_reverse_client_hostname_ns_access">check_reverse_client_hostname_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the DNS servers for +the unverified reverse client hostname, and execute the corresponding +action. Note: a result of "OK" is not allowed for safety reasons. +Instead, use DUNNO in order to exclude specific hosts from denylists. +This feature is available in Postfix 2.7 and later. </dd> + +<dt><b><a name="check_sasl_access">check_sasl_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd> Use the remote SMTP client SASL user name as the lookup key for +the specified access(5) database. The lookup key has the form +"username@domainname" when the smtpd_sasl_local_domain parameter +value is non-empty. Unlike the check_client_access feature, +check_sasl_access does not perform matches of parent domains or IP +subnet ranges. This feature is available with Postfix version 2.11 +and later. </dd> + +<dt><b><a name="permit_inet_interfaces">permit_inet_interfaces</a></b></dt> + +<dd>Permit the request when the client IP address matches +$inet_interfaces. </dd> + +<dt><b><a name="permit_mynetworks">permit_mynetworks</a></b></dt> + +<dd>Permit the request when the client IP address matches any +network or network address listed in $mynetworks. </dd> + +<dt><b><a name="permit_sasl_authenticated">permit_sasl_authenticated</a></b></dt> + +<dd> Permit the request when the client is successfully +authenticated via the RFC 4954 (AUTH) protocol. </dd> + + +<dt><b><a name="permit_tls_all_clientcerts">permit_tls_all_clientcerts</a></b></dt> + +<dd> Permit the request when the remote SMTP client certificate is +verified successfully. This option must be used only if a special +CA issues the certificates and only this CA is listed as a trusted +CA. Otherwise, clients with a third-party certificate would also +be allowed to relay. Specify "tls_append_default_CA = no" when the +trusted CA is specified with smtpd_tls_CAfile or smtpd_tls_CApath, +to prevent Postfix from appending the system-supplied default CAs. +This feature requires "smtpd_tls_ask_ccert = yes" and is available +with Postfix version 2.2 and later.</dd> + +<dt><b><a name="permit_tls_clientcerts">permit_tls_clientcerts</a></b></dt> + +<dd>Permit the request when the remote SMTP client certificate +fingerprint or public key fingerprint (Postfix 2.9 and later) is +listed in $relay_clientcerts. +The fingerprint digest algorithm is configurable via the +smtpd_tls_fingerprint_digest parameter (hard-coded as md5 prior to +Postfix version 2.5). This feature requires "smtpd_tls_ask_ccert += yes" and is available with Postfix version 2.2 and later.</dd> + +<dd> The default algorithm is <b>sha256</b> with Postfix ≥ 3.6 +and the <b>compatibility_level</b> set to 3.6 or higher. With Postfix +≤ 3.5, the default algorithm is <b>md5</b>. The best-practice +algorithm is now <b>sha256</b>. Recent advances in hash function +cryptanalysis have led to md5 and sha1 being deprecated in favor of +sha256. However, as long as there are no known "second pre-image" +attacks against the older algorithms, their use in this context, though +not recommended, is still likely safe. </dd> + +<dt><b><a name="reject_rbl_client">reject_rbl_client <i>rbl_domain=d.d.d.d</i></a></b></dt> + +<dd>Reject the request when the reversed client network address is +listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> +(Postfix version 2.1 and later only). Each "<i>d</i>" is a number, +or a pattern inside "[]" that contains one or more ";"-separated +numbers or number..number ranges (Postfix version 2.8 and later). +If no "<i>=d.d.d.d</i>" is specified, reject the request when the +reversed client network address is listed with any A record under +<i>rbl_domain</i>. <br> +The maps_rbl_reject_code parameter specifies the response code for +rejected requests (default: 554), the default_rbl_reply parameter +specifies the default server reply, and the rbl_reply_maps parameter +specifies tables with server replies indexed by <i>rbl_domain</i>. +This feature is available in Postfix 2.0 and later. </dd> + +<dt><b><a name="permit_dnswl_client">permit_dnswl_client <i>dnswl_domain=d.d.d.d</i></a></b></dt> + +<dd>Accept the request when the reversed client network address is +listed with the A record "<i>d.d.d.d</i>" under <i>dnswl_domain</i>. +Each "<i>d</i>" is a number, or a pattern inside "[]" that contains +one or more ";"-separated numbers or number..number ranges. +If no "<i>=d.d.d.d</i>" is specified, accept the request when the +reversed client network address is listed with any A record under +<i>dnswl_domain</i>. <br> For safety, permit_dnswl_client is silently +ignored when it would override reject_unauth_destination. The +result is DEFER_IF_REJECT when allowlist lookup fails. This feature +is available in Postfix 2.8 and later. </dd> + +<dt><b><a name="reject_rhsbl_client">reject_rhsbl_client <i>rbl_domain=d.d.d.d</i></a></b></dt> + +<dd>Reject the request when the client hostname is listed with the +A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version +2.1 and later only). Each "<i>d</i>" is a number, or a pattern +inside "[]" that contains one or more ";"-separated numbers or +number..number ranges (Postfix version 2.8 and later). If no +"<i>=d.d.d.d</i>" is specified, reject the request when the client +hostname is listed with +any A record under <i>rbl_domain</i>. See the reject_rbl_client +description above for additional RBL related configuration parameters. +This feature is available in Postfix 2.0 and later; with Postfix +version 2.8 and later, reject_rhsbl_reverse_client will usually +produce better results. </dd> + +<dt><b><a name="permit_rhswl_client">permit_rhswl_client <i>rhswl_domain=d.d.d.d</i></a></b></dt> + +<dd>Accept the request when the client hostname is listed with the +A record "<i>d.d.d.d</i>" under <i>rhswl_domain</i>. Each "<i>d</i>" +is a number, or a pattern inside "[]" that contains one or more +";"-separated numbers or number..number ranges. If no +"<i>=d.d.d.d</i>" is specified, accept the request when the client +hostname is listed with any A record under <i>rhswl_domain</i>. +<br> Caution: client name allowlisting is fragile, since the client +name lookup can fail due to temporary outages. Client name +allowlisting should be used only to reduce false positives in e.g. +DNS-based blocklists, and not for making access rule exceptions. +<br> For safety, permit_rhswl_client is silently ignored when it +would override reject_unauth_destination. The result is DEFER_IF_REJECT +when allowlist lookup fails. This feature is available in Postfix +2.8 and later. </dd> + +<dt><b><a name="reject_rhsbl_reverse_client">reject_rhsbl_reverse_client <i>rbl_domain=d.d.d.d</i></a></b></dt> + +<dd>Reject the request when the unverified reverse client hostname +is listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>. +Each "<i>d</i>" is a number, or a pattern inside "[]" that contains +one or more ";"-separated numbers or number..number ranges. +If no "<i>=d.d.d.d</i>" is specified, reject the request when the +unverified reverse client hostname is listed with any A record under +<i>rbl_domain</i>. See the reject_rbl_client description above for +additional RBL related configuration parameters. This feature is +available in Postfix 2.8 and later. </dd> + +<dt><b><a name="reject_unknown_client_hostname">reject_unknown_client_hostname</a></b> (with Postfix < 2.3: reject_unknown_client)</dt> + +<dd>Reject the request when 1) the client IP address->name mapping +fails, or 2) the name->address mapping fails, or 3) the name->address +mapping does not match the client IP address. <br> This is a +stronger restriction than the reject_unknown_reverse_client_hostname +feature, which triggers only under condition 1) above. <br> The +unknown_client_reject_code parameter specifies the response code +for rejected requests (default: 450). The reply is always 450 in +case the address->name or name->address lookup failed due to +a temporary problem. </dd> + +<dt><b><a name="reject_unknown_reverse_client_hostname">reject_unknown_reverse_client_hostname</a></b></dt> + +<dd>Reject the request when the client IP address has no address->name +mapping. <br> This is a weaker restriction than the +reject_unknown_client_hostname feature, which requires not only +that the address->name and name->address mappings exist, but +also that the two mappings reproduce the client IP address. <br> +The unknown_client_reject_code parameter specifies the response +code for rejected requests (default: 450). The reply is always 450 +in case the address->name lookup failed due to a temporary +problem. <br> This feature is available in Postfix 2.3 and +later. </dd> + +#<dt><b><a name="reject_unknown_forward_client_hostname">reject_unknown_forward_client_hostname</a></b></dt> +# +#<dd>Reject the request when the client IP address has no address->name +#or name ->address mapping. <br> This is a weaker restriction +#than the reject_unknown_client_hostname feature, which requires not +#only that the address->name and name->address mappings exist, +#but also that the two mappings reproduce the client IP address. +#<br> The unknown_client_reject_code parameter specifies the response +#code for rejected requests (default: 450). The reply is always 450 +#in case the address->name or name ->address lookup failed due +#to a temporary problem. <br> This feature is available in Postfix +#version 2.3 and later. </dd> + +</dl> + +<p> +In addition, you can use any of the following <a name="generic"> +generic</a> restrictions. These restrictions are applicable in +any SMTP command context. +</p> + +<dl> + +<dt><b><a name="check_policy_service">check_policy_service <i>servername</i></a></b></dt> + +<dd>Query the specified policy server. See the SMTPD_POLICY_README +document for details. This feature is available in Postfix 2.1 +and later. </dd> + +<dt><b><a name="defer">defer</a></b></dt> + +<dd>Defer the request. The client is told to try again later. This +restriction is useful at the end of a restriction list, to make +the default policy explicit. <br> The defer_code parameter specifies +the SMTP server reply code (default: 450).</dd> + +<dt><b><a name="defer_if_permit">defer_if_permit</a></b></dt> + +<dd>Defer the request if some later restriction would result in an +explicit or implicit PERMIT action. This is useful when a denylisting +feature fails due to a temporary problem. This feature is available +in Postfix version 2.1 and later. </dd> + +<dt><b><a name="defer_if_reject">defer_if_reject</a></b></dt> + +<dd>Defer the request if some later restriction would result in a +REJECT action. This is useful when an allowlisting feature fails +due to a temporary problem. This feature is available in Postfix +version 2.1 and later. </dd> + +<dt><b><a name="permit">permit</a></b></dt> + +<dd>Permit the request. This restriction is useful at the end of +a restriction list, to make the default policy explicit.</dd> + +<dt><b><a name="reject_multi_recipient_bounce">reject_multi_recipient_bounce</a></b></dt> + +<dd>Reject the request when the envelope sender is the null address, +and the message has multiple envelope recipients. This usage has +rare but legitimate applications: under certain conditions, +multi-recipient mail that was posted with the DSN option NOTIFY=NEVER +may be forwarded with the null sender address. +<br> Note: this restriction can only work reliably +when used in smtpd_data_restrictions or +smtpd_end_of_data_restrictions, because the total number of +recipients is not known at an earlier stage of the SMTP conversation. +Use at the RCPT stage will only reject the second etc. recipient. +<br> +The multi_recipient_bounce_reject_code parameter specifies the +response code for rejected requests (default: 550). This feature +is available in Postfix 2.1 and later. </dd> + +<dt><b><a name="reject_plaintext_session">reject_plaintext_session</a></b></dt> + +<dd>Reject the request when the connection is not encrypted. This +restriction should not be used before the client has had a chance +to negotiate encryption with the AUTH or STARTTLS commands. +<br> +The plaintext_reject_code parameter specifies the response +code for rejected requests (default: 450). This feature is available +in Postfix 2.3 and later. </dd> + +<dt><b><a name="reject_unauth_pipelining">reject_unauth_pipelining</a></b></dt> + +<dd>Reject the request when the client sends SMTP commands ahead +of time where it is not allowed, or when the client sends SMTP +commands ahead of time without knowing that Postfix actually supports +ESMTP command pipelining. This stops mail from bulk mail software +that improperly uses ESMTP command pipelining in order to speed up +deliveries. +<br> With Postfix 2.6 and later, the SMTP server sets a per-session +flag whenever it detects illegal pipelining, including pipelined +HELO or EHLO commands. The reject_unauth_pipelining feature simply +tests whether the flag was set at any point in time during the +session. +<br> With older Postfix versions, reject_unauth_pipelining checks +the current status of the input read queue, and its usage is not +recommended in contexts other than smtpd_data_restrictions. </dd> + +<dt><b><a name="reject">reject</a></b></dt> + +<dd>Reject the request. This restriction is useful at the end of +a restriction list, to make the default policy explicit. The +reject_code configuration parameter specifies the response code for +rejected requests (default: 554).</dd> + +<dt><b><a name="sleep">sleep <i>seconds</i></a></b></dt> + +<dd>Pause for the specified number of seconds and proceed with +the next restriction in the list, if any. This may stop zombie +mail when used as: +<pre> +/etc/postfix/main.cf: + smtpd_client_restrictions = + sleep 1, reject_unauth_pipelining + smtpd_delay_reject = no +</pre> +This feature is available in Postfix 2.3. </dd> + +<dt><b><a name="warn_if_reject">warn_if_reject</a></b></dt> + +<dd> A safety net for testing. When "warn_if_reject" is placed +before a reject-type restriction, access table query, or +check_policy_service query, this logs a "reject_warning" message +instead of rejecting a request (when a reject-type restriction fails +due to a temporary error, this logs a "reject_warning" message for +any implicit "defer_if_permit" actions that would normally prevent +mail from being accepted by some later access restriction). This +feature has no effect on defer_if_reject restrictions. </dd> + +</dl> + +<p> +Other restrictions that are valid in this context: +</p> + +<ul> + +<li> SMTP command specific restrictions that are described under +the smtpd_helo_restrictions, smtpd_sender_restrictions or +smtpd_recipient_restrictions parameters. When helo, sender or +recipient restrictions are listed under smtpd_client_restrictions, +they have effect only with "smtpd_delay_reject = yes", so that +$smtpd_client_restrictions is evaluated at the time of the RCPT TO +command. + +</ul> + +<p> +Example: +</p> + +<pre> +smtpd_client_restrictions = permit_mynetworks, reject_unknown_client_hostname +</pre> + +%CLASS smtpd-tarpit Tarpit features + +<p> +When a remote SMTP client makes errors, the Postfix SMTP server +can insert delays before responding. This can help to slow down +run-away software. The behavior is controlled by an error counter +that counts the number of errors within an SMTP session that a +client makes without delivering mail. +</p> + +<ul> + +<li><p>When the error counter is less than $smtpd_soft_error_limit the +Postfix SMTP server replies immediately (Postfix version 2.0 and earlier +delay their 4xx or 5xx error response). </p> + +<li><p>When the error counter reaches $smtpd_soft_error_limit, the Postfix +SMTP server delays all its responses. </p> + +<li><p>When the error counter reaches $smtpd_hard_error_limit the Postfix +SMTP server breaks the connection. </p> + +</ul> + +%PARAM smtpd_error_sleep_time 1s + +<p>With Postfix version 2.1 and later: the SMTP server response delay after +a client has made more than $smtpd_soft_error_limit errors, and +fewer than $smtpd_hard_error_limit errors, without delivering mail. +</p> + +<p>With Postfix version 2.0 and earlier: the SMTP server delay +before sending a reject (4xx or 5xx) response, when the client has +made fewer than $smtpd_soft_error_limit errors without delivering +mail. When the client has made $smtpd_soft_error_limit or more errors, +delay all responses with the larger of (number of errors) seconds +or $smtpd_error_sleep_time. </p> + +<p> Specify a non-negative time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM smtpd_soft_error_limit 10 + +<p> +The number of errors a remote SMTP client is allowed to make without +delivering mail before the Postfix SMTP server slows down all its +responses. +</p> + +<ul> + +<li><p>With Postfix version 2.1 and later, when the error count +is > $smtpd_soft_error_limit, the Postfix SMTP server +delays all responses by $smtpd_error_sleep_time. </p> + +<li><p>With Postfix versions 2.0 and earlier, when the error count +is > $smtpd_soft_error_limit, the Postfix SMTP server delays all +responses by the larger of (number of errors) seconds or +$smtpd_error_sleep_time. </p> + +<li><p>With Postfix versions 2.0 and earlier, when the error count +is ≤ $smtpd_soft_error_limit, the Postfix SMTP server delays 4XX +and 5XX responses by $smtpd_error_sleep_time. </p> + +</ul> + +%PARAM smtpd_hard_error_limit normal: 20, overload: 1 + +<p> +The maximal number of errors a remote SMTP client is allowed to +make without delivering mail. The Postfix SMTP server disconnects +when the limit is reached. Normally the default limit is 20, but +it changes under overload to just 1. With Postfix 2.5 and earlier, +the SMTP server always allows up to 20 errors by default. +Valid values are greater than zero. + +</p> + +%PARAM smtpd_junk_command_limit normal: 100, overload: 1 + +<p> +The number of junk commands (NOOP, VRFY, ETRN or RSET) that a remote +SMTP client can send before the Postfix SMTP server starts to +increment the error counter with each junk command. The junk +command count is reset after mail is delivered. See also the +smtpd_error_sleep_time and smtpd_soft_error_limit configuration +parameters. Normally the default limit is 100, but it changes under +overload to just 1. With Postfix 2.5 and earlier, the SMTP server +always allows up to 100 junk commands by default. </p> + +%PARAM smtpd_recipient_overshoot_limit 1000 + +<p> The number of recipients that a remote SMTP client can send in +excess of the limit specified with $smtpd_recipient_limit, before +the Postfix SMTP server increments the per-session error count +for each excess recipient. </p> + +%PARAM smtpd_etrn_restrictions + +<p> +Optional restrictions that the Postfix SMTP server applies in the +context of a client ETRN command. +See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access +restriction lists" for a discussion of evaluation context and time. +</p> + +<p> +The Postfix ETRN implementation accepts only destinations that are +eligible for the Postfix "fast flush" service. See the ETRN_README +file for details. +</p> + +<p> +Specify a list of restrictions, separated by commas and/or whitespace. +Continue long lines by starting the next line with whitespace. +Restrictions are applied in the order as specified; the first +restriction that matches wins. +</p> + +<p> +The following restrictions are specific to the domain name information +received with the ETRN command. +</p> + +<dl> + +<dt><b><a name="check_etrn_access">check_etrn_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access database for the ETRN domain name +or its parent domains. See the access(5) manual page for details. +</dd> + +</dl> + +<p> +Other restrictions that are valid in this context: +</p> + +<ul> + +<li><a href="#generic">Generic</a> restrictions that can be used +in any SMTP command context, described under smtpd_client_restrictions. + +<li>SMTP command specific restrictions described under +smtpd_client_restrictions and smtpd_helo_restrictions. + +</ul> + +<p> +Example: +</p> + +<pre> +smtpd_etrn_restrictions = permit_mynetworks, reject +</pre> + +%PARAM smtpd_expansion_filter see "postconf -d" output + +<p> +What characters are allowed in $name expansions of RBL reply +templates. Characters not in the allowed set are replaced by "_". +Use C like escapes to specify special characters such as whitespace. +</p> + +<p> +The smtpd_expansion_filter value is not subject to Postfix configuration +parameter $name expansion. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM smtpd_forbidden_commands CONNECT GET POST regexp:{{/^[^A-Z]/ Bogus}} + +<p> +List of commands that cause the Postfix SMTP server to immediately +terminate the session with a 221 code. This can be used to disconnect +clients that obviously attempt to abuse the system. In addition to the +commands listed in this parameter, commands that follow the "Label:" +format of message headers will also cause a disconnect. With Postfix +versions 3.6 and earlier, the default value is "CONNECT GET POST". +</p> + +<p> +This feature is available in Postfix 2.2 and later. +</p> + +<p> +Support for inline regular expressions was added in Postfix version +3.7. See regexp_table(5) for a description of the syntax and features. +</p> + +%PARAM smtpd_helo_required no + +<p> +Require that a remote SMTP client introduces itself with the HELO +or EHLO command before sending the MAIL command or other commands +that require EHLO negotiation. +</p> + +<p> +Example: +</p> + +<pre> +smtpd_helo_required = yes +</pre> + +%PARAM smtpd_helo_restrictions + +<p> +Optional restrictions that the Postfix SMTP server applies in the +context of a client HELO command. +See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access +restriction lists" for a discussion of evaluation context and time. +</p> + +<p> +The default is to permit everything. +</p> + +<p> Note: specify "smtpd_helo_required = yes" to fully enforce this +restriction (without "smtpd_helo_required = yes", a client can +simply skip smtpd_helo_restrictions by not sending HELO or EHLO). +</p> + +<p> +Specify a list of restrictions, separated by commas and/or whitespace. +Continue long lines by starting the next line with whitespace. +Restrictions are applied in the order as specified; the first +restriction that matches wins. +</p> + +<p> +The following restrictions are specific to the hostname information +received with the HELO or EHLO command. +</p> + +<dl> + +<dt><b><a name="check_helo_access">check_helo_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the HELO or EHLO +hostname or parent domains, and execute the corresponding action. +Note: specify "smtpd_helo_required = yes" to fully enforce this +restriction (without "smtpd_helo_required = yes", a client can +simply skip check_helo_access by not sending HELO or EHLO). </dd> + +<dt><b><a name="check_helo_a_access">check_helo_a_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the IP addresses for +the HELO or EHLO hostname, and execute the corresponding action. +Note 1: a result of "OK" is not allowed for safety reasons. Instead, +use DUNNO in order to exclude specific hosts from denylists. Note +2: specify "smtpd_helo_required = yes" to fully enforce this +restriction (without "smtpd_helo_required = yes", a client can +simply skip check_helo_a_access by not sending HELO or EHLO). This +feature is available in Postfix 3.0 and later. +</dd> + +<dt><b><a name="check_helo_mx_access">check_helo_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the MX hosts for +the HELO or EHLO hostname, and execute the corresponding action. +If no MX record is found, look up A or AAAA records, just like the +Postfix SMTP client would. +Note 1: a result of "OK" is not allowed for safety reasons. Instead, +use DUNNO in order to exclude specific hosts from denylists. Note +2: specify "smtpd_helo_required = yes" to fully enforce this +restriction (without "smtpd_helo_required = yes", a client can +simply skip check_helo_mx_access by not sending HELO or EHLO). This +feature is available in Postfix 2.1 and later. +</dd> + +<dt><b><a name="check_helo_ns_access">check_helo_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the DNS servers +for the HELO or EHLO hostname, and execute the corresponding action. +Note 1: a result of "OK" is not allowed for safety reasons. Instead, +use DUNNO in order to exclude specific hosts from denylists. Note +2: specify "smtpd_helo_required = yes" to fully enforce this +restriction (without "smtpd_helo_required = yes", a client can +simply skip check_helo_ns_access by not sending HELO or EHLO). This +feature is available in Postfix 2.1 and later. +</dd> + +<dt><b><a name="reject_invalid_helo_hostname">reject_invalid_helo_hostname</a></b> (with Postfix < 2.3: reject_invalid_hostname)</dt> + +<dd>Reject the request when the HELO or EHLO hostname is malformed. +Note: specify "smtpd_helo_required = yes" to fully enforce +this restriction (without "smtpd_helo_required = yes", a client can simply +skip reject_invalid_helo_hostname by not sending HELO or EHLO). +<br> The invalid_hostname_reject_code specifies the response code +for rejected requests (default: 501).</dd> + +<dt><b><a name="reject_non_fqdn_helo_hostname">reject_non_fqdn_helo_hostname</a></b> (with Postfix < 2.3: reject_non_fqdn_hostname)</dt> + +<dd>Reject the request when the HELO or EHLO hostname is not in +fully-qualified domain or address literal form, as required by the +RFC. Note: specify +"smtpd_helo_required = yes" to fully enforce this restriction +(without "smtpd_helo_required = yes", a client can simply skip +reject_non_fqdn_helo_hostname by not sending HELO or EHLO). <br> +The non_fqdn_reject_code parameter specifies the response code for +rejected requests (default: 504).</dd> + +<dt><b><a name="reject_rhsbl_helo">reject_rhsbl_helo <i>rbl_domain=d.d.d.d</i></a></b></dt> + +<dd>Reject the request when the HELO or EHLO hostname is +listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> +(Postfix version 2.1 and later only). Each "<i>d</i>" is a number, +or a pattern inside "[]" that contains one or more ";"-separated +numbers or number..number ranges (Postfix version 2.8 and later). +If no "<i>=d.d.d.d</i>" is +specified, reject the request when the HELO or EHLO hostname is +listed with any A record under <i>rbl_domain</i>. See the +reject_rbl_client description for additional RBL related configuration +parameters. Note: specify "smtpd_helo_required = yes" to fully +enforce this restriction (without "smtpd_helo_required = yes", a +client can simply skip reject_rhsbl_helo by not sending HELO or +EHLO). This feature is available in Postfix 2.0 +and later. </dd> + +<dt><b><a name="reject_unknown_helo_hostname">reject_unknown_helo_hostname</a></b> (with Postfix < 2.3: reject_unknown_hostname)</dt> + +<dd>Reject the request when the HELO or EHLO hostname has no DNS A +or MX record. <br> The reply is specified with the +unknown_hostname_reject_code parameter (default: 450) or +unknown_helo_hostname_tempfail_action (default: defer_if_permit). +See the respective parameter descriptions for details. <br> +Note: specify "smtpd_helo_required = yes" to fully +enforce this restriction (without "smtpd_helo_required = yes", a +client can simply skip reject_unknown_helo_hostname by not sending +HELO or EHLO). </dd> + +</dl> + +<p> +Other restrictions that are valid in this context: +</p> + +<ul> + +<li> <a href="#generic">Generic</a> restrictions that can be used +in any SMTP command context, described under smtpd_client_restrictions. + +<li> Client hostname or network address specific restrictions +described under smtpd_client_restrictions. + +<li> SMTP command specific restrictions described under +smtpd_sender_restrictions or smtpd_recipient_restrictions. When +sender or recipient restrictions are listed under smtpd_helo_restrictions, +they have effect only with "smtpd_delay_reject = yes", so that +$smtpd_helo_restrictions is evaluated at the time of the RCPT TO +command. + +</ul> + +<p> +Examples: +</p> + +<pre> +smtpd_helo_restrictions = permit_mynetworks, reject_invalid_helo_hostname +smtpd_helo_restrictions = permit_mynetworks, reject_unknown_helo_hostname +</pre> + +%PARAM smtpd_history_flush_threshold 100 + +<p> +The maximal number of lines in the Postfix SMTP server command history +before it is flushed upon receipt of EHLO, RSET, or end of DATA. +</p> + +%PARAM smtpd_noop_commands + +<p> +List of commands that the Postfix SMTP server replies to with "250 +Ok", without doing any syntax checks and without changing state. +This list overrides any commands built into the Postfix SMTP server. +</p> + +%PARAM smtpd_proxy_ehlo $myhostname + +<p> +How the Postfix SMTP server announces itself to the proxy filter. +By default, the Postfix hostname is used. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM smtpd_proxy_options + +<p> +List of options that control how the Postfix SMTP server +communicates with a before-queue content filter. Specify zero or +more of the following, separated by comma or whitespace. </p> + +<dl> + +<dt><b>speed_adjust</b></dt> + +<dd> <p> Do not connect to a before-queue content filter until an entire +message has been received. This reduces the number of simultaneous +before-queue content filter processes. </p> + +<p> NOTE 1: A filter must not <i>selectively</i> reject recipients +of a multi-recipient message. Rejecting all recipients is OK, as +is accepting all recipients. </p> + +<p> NOTE 2: This feature increases the minimum amount of free queue +space by $message_size_limit. The extra space is needed to save the +message to a temporary file. </p> </dd> + +</dl> + +<p> +This feature is available in Postfix 2.7 and later. +</p> + +%CLASS smtpd-proxy SMTP Proxy filter + +<p> +As of Postfix version 2.1, the SMTP server can forward all incoming +mail to a content filtering proxy server that inspects all mail +BEFORE it is stored in the Postfix mail queue. +</p> + +<p> +WARNING: the proxy filter must reply within a fixed deadline or +else the remote SMTP client times out and mail duplication happens. +This becomes a problem as mail load increases so that fewer and +fewer CPU cycles remain available to mead the fixed deadline. +</p> + +%PARAM smtpd_proxy_filter + +<p> The hostname and TCP port of the mail filtering proxy server. +The proxy receives all mail from the Postfix SMTP server, and is +supposed to give the result to another Postfix SMTP server process. +</p> + +<p> Specify "host:port" or "inet:host:port" for a TCP endpoint, or +"unix:pathname" for a UNIX-domain endpoint. The host can be specified +as an IP address or as a symbolic name; no MX lookups are done. +When no "host" or "host:" is specified, the local machine is +assumed. Pathname interpretation is relative to the Postfix queue +directory. </p> + +<p> This feature is available in Postfix 2.1 and later. </p> + +<p> The "inet:" and "unix:" prefixes are available in Postfix 2.3 +and later. </p> + +%PARAM smtpd_proxy_timeout 100s + +<p> +The time limit for connecting to a proxy filter and for sending or +receiving information. When a connection fails the client gets a +generic error message while more detailed information is logged to +the maillog file. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM smtpd_recipient_limit 1000 + +<p> +The maximal number of recipients that the Postfix SMTP server +accepts per message delivery request. +</p> + +%PARAM smtpd_recipient_restrictions see "postconf -d" output + +<p> +Optional restrictions that the Postfix SMTP server applies in the +context of a client RCPT TO command, after smtpd_relay_restrictions. +See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access +restriction lists" for a discussion of evaluation context and time. +</p> + +<p> With Postfix versions before 2.10, the rules for relay permission +and spam blocking were combined under smtpd_recipient_restrictions, +resulting in error-prone configuration. As of Postfix 2.10, relay +permission rules are preferably implemented with smtpd_relay_restrictions, +so that a permissive spam blocking policy under +smtpd_recipient_restrictions will no longer result in a permissive +mail relay policy. </p> + +<p> For backwards compatibility, sites that migrate from Postfix +versions before 2.10 can set smtpd_relay_restrictions to the empty +value, and use smtpd_recipient_restrictions exactly as before. </p> + +<p> +IMPORTANT: Either the smtpd_relay_restrictions or the +smtpd_recipient_restrictions parameter must specify +at least one of the following restrictions. Otherwise Postfix will +refuse to receive mail: +</p> + +<blockquote> +<pre> +reject, reject_unauth_destination +</pre> +</blockquote> + +<blockquote> +<pre> +defer, defer_if_permit, defer_unauth_destination +</pre> +</blockquote> + +<p> +Specify a list of restrictions, separated by commas and/or whitespace. +Continue long lines by starting the next line with whitespace. +Restrictions are applied in the order as specified; the first +restriction that matches wins. +</p> + +<p> +The following restrictions are specific to the recipient address +that is received with the RCPT TO command. +</p> + +<dl> + +<dt><b><a name="check_recipient_access">check_recipient_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the resolved RCPT +TO address, domain, parent domains, or localpart@, and execute the +corresponding action. </dd> + +<dt><b><a name="check_recipient_a_access">check_recipient_a_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the IP addresses for +the RCPT TO domain, and execute the corresponding action. Note: +a result of "OK" is not allowed for safety reasons. Instead, use +DUNNO in order to exclude specific hosts from denylists. This +feature is available in Postfix 3.0 and later. </dd> + +<dt><b><a name="check_recipient_mx_access">check_recipient_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the MX hosts for +the RCPT TO domain, and execute the corresponding action. If no +MX record is found, look up A or AAAA records, just like the Postfix +SMTP client would. Note: +a result of "OK" is not allowed for safety reasons. Instead, use +DUNNO in order to exclude specific hosts from denylists. This +feature is available in Postfix 2.1 and later. </dd> + +<dt><b><a name="check_recipient_ns_access">check_recipient_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the DNS servers +for the RCPT TO domain, and execute the corresponding action. +Note: a result of "OK" is not allowed for safety reasons. Instead, +use DUNNO in order to exclude specific hosts from denylists. This +feature is available in Postfix 2.1 and later. </dd> + +<dt><b><a name="permit_auth_destination">permit_auth_destination</a></b></dt> + +<dd>Permit the request when one of the following is true: + +<ul> + +<li> Postfix is a mail forwarder: the resolved RCPT TO domain matches +$relay_domains or a subdomain thereof, and the address contains no +sender-specified routing (user@elsewhere@domain), + +<li> Postfix is the final destination: the resolved RCPT TO domain +matches $mydestination, $inet_interfaces, $proxy_interfaces, +$virtual_alias_domains, or $virtual_mailbox_domains, and the address +contains no sender-specified routing (user@elsewhere@domain). + +</ul></dd> + +<dt><b><a name="permit_mx_backup">permit_mx_backup</a></b></dt> + +<dd>Permit the request when the local mail system is a backup MX for +the RCPT TO domain, or when the domain is an authorized destination +(see permit_auth_destination for definition). + +<ul> + +<li> Safety: permit_mx_backup does not accept addresses that have +sender-specified routing information (example: user@elsewhere@domain). + +<li> Safety: permit_mx_backup can be vulnerable to mis-use when +access is not restricted with permit_mx_backup_networks. + +<li> Safety: as of Postfix version 2.3, permit_mx_backup no longer +accepts the address when the local mail system is a primary MX for +the recipient domain. Exception: permit_mx_backup accepts the address +when it specifies an authorized destination (see permit_auth_destination +for definition). + +<li> Limitation: mail may be rejected in case of a temporary DNS +lookup problem with Postfix prior to version 2.0. + +</ul></dd> + +<dt><b><a name="reject_non_fqdn_recipient">reject_non_fqdn_recipient</a></b></dt> + +<dd>Reject the request when the RCPT TO address specifies a +domain that is not in +fully-qualified domain form, as required by the RFC. <br> The +non_fqdn_reject_code parameter specifies the response code for +rejected requests (default: 504). </dd> + +<dt><b><a name="reject_rhsbl_recipient">reject_rhsbl_recipient <i>rbl_domain=d.d.d.d</i></a></b></dt> + +<dd>Reject the request when the RCPT TO domain is listed with the +A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version +2.1 and later only). Each "<i>d</i>" is a number, or a pattern +inside "[]" that contains one or more ";"-separated numbers or +number..number ranges (Postfix version 2.8 and later). If no +"<i>=d.d.d.d</i>" is specified, reject +the request when the RCPT TO domain is listed with +any A record under <i>rbl_domain</i>. <br> The maps_rbl_reject_code +parameter specifies the response code for rejected requests (default: +554); the default_rbl_reply parameter specifies the default server +reply; and the rbl_reply_maps parameter specifies tables with server +replies indexed by <i>rbl_domain</i>. This feature is available +in Postfix version 2.0 and later.</dd> + +<dt><b><a name="reject_unauth_destination">reject_unauth_destination</a></b></dt> + +<dd>Reject the request unless one of the following is true: + +<ul> + +<li> Postfix is a mail forwarder: the resolved RCPT TO domain matches +$relay_domains or a subdomain thereof, and contains no sender-specified +routing (user@elsewhere@domain), + +<li> Postfix is the final destination: the resolved RCPT TO domain +matches $mydestination, $inet_interfaces, $proxy_interfaces, +$virtual_alias_domains, or $virtual_mailbox_domains, and contains +no sender-specified routing (user@elsewhere@domain). + +</ul>The relay_domains_reject_code parameter specifies the response +code for rejected requests (default: 554). </dd> + +<dt><b><a name="defer_unauth_destination">defer_unauth_destination</a></b></dt> + +<dd> Reject the same requests as reject_unauth_destination, with a +non-permanent error code. This feature is available in Postfix +2.10 and later.</dd> + +<dt><b><a name="reject_unknown_recipient_domain">reject_unknown_recipient_domain</a></b></dt> + +<dd>Reject the request when Postfix is not final destination for +the recipient domain, and the RCPT TO domain has 1) no DNS MX and +no DNS A +record or 2) a malformed MX record such as a record with +a zero-length MX hostname (Postfix version 2.3 and later). <br> The +reply is specified with the unknown_address_reject_code parameter +(default: 450), unknown_address_tempfail_action (default: +defer_if_permit), or 556 (nullmx, Postfix 3.0 and +later). See the respective parameter descriptions for details. +</dd> + +<dt><b><a name="reject_unlisted_recipient">reject_unlisted_recipient</a></b> (with Postfix version 2.0: check_recipient_maps)</dt> + +<dd> Reject the request when the RCPT TO address is not listed in +the list of valid recipients for its domain class. See the +smtpd_reject_unlisted_recipient parameter description for details. +This feature is available in Postfix 2.1 and later.</dd> + +<dt><b><a name="reject_unverified_recipient">reject_unverified_recipient</a></b></dt> + +<dd>Reject the request when mail to the RCPT TO address is known +to bounce, or when the recipient address destination is not reachable. +Address verification information is managed by the verify(8) server; +see the ADDRESS_VERIFICATION_README file for details. <br> The +unverified_recipient_reject_code parameter specifies the numerical +response code when an address is known to bounce (default: 450, +change it to 550 when you are confident that it is safe to do so). +<br>The unverified_recipient_defer_code parameter specifies the +numerical response code when an address probe failed due to a +temporary problem (default: 450). <br> The +unverified_recipient_tempfail_action parameter specifies the action +after address probe failure due to a temporary problem (default: +defer_if_permit). <br> This feature breaks for aliased addresses +with "enable_original_recipient = no" (Postfix ≤ 3.2). <br> +This feature is available in Postfix 2.1 and later. </dd> + +</dl> + +<p> +Other restrictions that are valid in this context: +</p> + +<ul> + +<li><a href="#generic">Generic</a> restrictions that can be used +in any SMTP command context, described under smtpd_client_restrictions. + +<li>SMTP command specific restrictions described under +smtpd_client_restrictions, smtpd_helo_restrictions and +smtpd_sender_restrictions. + +</ul> + +<p> +Example: +</p> + +<pre> +# The Postfix before 2.10 default mail relay policy. Later Postfix +# versions implement this preferably with smtpd_relay_restrictions. +smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination +</pre> + +%PARAM smtpd_relay_restrictions permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination + +<p> Access restrictions for mail relay control that the Postfix +SMTP server applies in the context of the RCPT TO command, before +smtpd_recipient_restrictions. +See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access +restriction lists" for a discussion of evaluation context and time. +</p> + +<p> With Postfix versions before 2.10, the rules for relay permission +and spam blocking were combined under smtpd_recipient_restrictions, +resulting in error-prone configuration. As of Postfix 2.10, relay +permission rules are preferably implemented with smtpd_relay_restrictions, +so that a permissive spam blocking policy under +smtpd_recipient_restrictions will no longer result in a permissive +mail relay policy. </p> + +<p> For backwards compatibility, sites that migrate from Postfix +versions before 2.10 can set smtpd_relay_restrictions to the empty +value, and use smtpd_recipient_restrictions exactly as before. </p> + +<p> +By default, the Postfix SMTP server accepts: +</p> + +<ul> + +<li> Mail from clients whose IP address matches $mynetworks, or: + +<li> Mail from clients who are SASL authenticated, or: + +<li> Mail to remote destinations that match $relay_domains, except +for addresses that contain sender-specified routing +(user@elsewhere@domain), or: + +<li> Mail to local destinations that match $inet_interfaces +or $proxy_interfaces, $mydestination, $virtual_alias_domains, or +$virtual_mailbox_domains. + +</ul> + +<p> +IMPORTANT: Either the smtpd_relay_restrictions or the +smtpd_recipient_restrictions parameter must specify +at least one of the following restrictions. Otherwise Postfix will +refuse to receive mail: +</p> + +<blockquote> +<pre> +reject, reject_unauth_destination +</pre> +</blockquote> + +<blockquote> +<pre> +defer, defer_if_permit, defer_unauth_destination +</pre> +</blockquote> + +<p> +Specify a list of restrictions, separated by commas and/or whitespace. +Continue long lines by starting the next line with whitespace. +The same restrictions are available as documented under +smtpd_recipient_restrictions. +</p> + +<p> This feature is available in Postix 2.10 and later. </p> + +%CLASS sasl-auth SASL Authentication + +<p> +Postfix SASL support (RFC 4954) can be used to authenticate remote +SMTP clients to the Postfix SMTP server, and to authenticate the +Postfix SMTP client to a remote SMTP server. +See the SASL_README document for details. +</p> + +%PARAM smtpd_sasl_auth_enable no + +<p> +Enable SASL authentication in the Postfix SMTP server. By default, +the Postfix SMTP server does not use authentication. +</p> + +<p> +If a remote SMTP client is authenticated, the permit_sasl_authenticated +access restriction can be used to permit relay access, like this: +</p> + +<blockquote> +<pre> +# With Postfix 2.10 and later, the mail relay policy is +# preferably specified under smtpd_relay_restrictions. +smtpd_relay_restrictions = + permit_mynetworks, permit_sasl_authenticated, ... +</pre> + +<pre> +# With Postfix before 2.10, the relay policy can be +# specified only under smtpd_recipient_restrictions. +smtpd_recipient_restrictions = + permit_mynetworks, permit_sasl_authenticated, ... +</pre> +</blockquote> + +<p> To reject all SMTP connections from unauthenticated clients, +specify "smtpd_delay_reject = yes" (which is the default) and use: +</p> + +<blockquote> +<pre> +smtpd_client_restrictions = permit_sasl_authenticated, reject +</pre> +</blockquote> + +<p> +See the SASL_README file for SASL configuration and operation details. +</p> + +%PARAM smtpd_sasl_authenticated_header no + +<p> Report the SASL authenticated user name in the smtpd(8) Received +message header. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtpd_sasl_exceptions_networks + +<p> +What remote SMTP clients the Postfix SMTP server will not offer +AUTH support to. +</p> + +<p> +Some clients (Netscape 4 at least) have a bug that causes them to +require a login and password whenever AUTH is offered, whether it's +necessary or not. To work around this, specify, for example, +$mynetworks to prevent Postfix from offering AUTH to local clients. +</p> + +<p> +Specify a list of network/netmask patterns, separated by commas +and/or whitespace. The mask specifies the number of bits in the +network part of a host address. You can also specify "/file/name" or +"type:table" patterns. A "/file/name" pattern is replaced by its +contents; a "type:table" lookup table is matched when a table entry +matches a lookup string (the lookup result is ignored). Continue +long lines by starting the next line with whitespace. Specify +"!pattern" to exclude an address or network block from the list. +The form "!/file/name" is supported only in Postfix version 2.4 and +later. </p> + +<p> Note: IP version 6 address information must be specified inside +<tt>[]</tt> in the smtpd_sasl_exceptions_networks value, and in +files specified with "/file/name". IP version 6 addresses contain +the ":" character, and would otherwise be confused with a "type:table" +pattern. </p> + +<p> +Example: +</p> + +<pre> +smtpd_sasl_exceptions_networks = $mynetworks +</pre> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM smtpd_sasl_local_domain + +<p> +The name of the Postfix SMTP server's local SASL authentication +realm. +</p> + +<p> +By default, the local authentication realm name is the null string. +</p> + +<p> +Examples: +</p> + +<pre> +smtpd_sasl_local_domain = $mydomain +smtpd_sasl_local_domain = $myhostname +</pre> + +%PARAM smtpd_sasl_security_options noanonymous + +<p> Postfix SMTP server SASL security options; as of Postfix 2.3 +the list of available +features depends on the SASL server implementation that is selected +with <b>smtpd_sasl_type</b>. </p> + +<p> The following security features are defined for the <b>cyrus</b> +server SASL implementation: </p> + +<p> +Restrict what authentication mechanisms the Postfix SMTP server +will offer to the client. The list of available authentication +mechanisms is system dependent. +</p> + +<p> +Specify zero or more of the following: +</p> + +<dl> + +<dt><b>noplaintext</b></dt> + +<dd>Disallow methods that use plaintext passwords. </dd> + +<dt><b>noactive</b></dt> + +<dd>Disallow methods subject to active (non-dictionary) attack. </dd> + +<dt><b>nodictionary</b></dt> + +<dd>Disallow methods subject to passive (dictionary) attack. </dd> + +<dt><b>noanonymous</b></dt> + +<dd>Disallow methods that allow anonymous authentication. </dd> + +<dt><b>forward_secrecy</b></dt> + +<dd>Only allow methods that support forward secrecy (Dovecot only). +</dd> + +<dt><b>mutual_auth</b></dt> + +<dd>Only allow methods that provide mutual authentication (not available +with Cyrus SASL version 1). </dd> + +</dl> + +<p> +By default, the Postfix SMTP server accepts plaintext passwords but +not anonymous logins. +</p> + +<p> +Warning: it appears that clients try authentication methods in the +order as advertised by the server (e.g., PLAIN ANONYMOUS CRAM-MD5) +which means that if you disable plaintext passwords, clients will +log in anonymously, even when they should be able to use CRAM-MD5. +So, if you disable plaintext logins, disable anonymous logins too. +Postfix treats anonymous login as no authentication. +</p> + +<p> +Example: +</p> + +<pre> +smtpd_sasl_security_options = noanonymous, noplaintext +</pre> + +%PARAM smtpd_sender_login_maps + +<p> +Optional lookup table with the SASL login names that own the sender +(MAIL FROM) addresses. +</p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. With lookups from +indexed files such as DB or DBM, or from networked tables such as +NIS, LDAP or SQL, the following search operations are done with a +sender address of <i>user@domain</i>: </p> + +<dl> + +<dt> 1) <i>user@domain</i> </dt> + +<dd>This table lookup is always done and has the highest precedence. </dd> + +<dt> 2) <i>user</i> </dt> + +<dd>This table lookup is done only when the <i>domain</i> part of the +sender address matches $myorigin, $mydestination, $inet_interfaces +or $proxy_interfaces. </dd> + +<dt> 3) <i>@domain</i> </dt> + +<dd>This table lookup is done last and has the lowest precedence. </dd> + +</dl> + +<p> +In all cases the result of table lookup must be either "not found" +or a list of SASL login names separated by comma and/or whitespace. +</p> + +%PARAM smtpd_sender_restrictions + +<p> +Optional restrictions that the Postfix SMTP server applies in the +context of a client MAIL FROM command. +See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access +restriction lists" for a discussion of evaluation context and time. +</p> + +<p> +The default is to permit everything. +</p> + +<p> +Specify a list of restrictions, separated by commas and/or whitespace. +Continue long lines by starting the next line with whitespace. +Restrictions are applied in the order as specified; the first +restriction that matches wins. +</p> + +<p> +The following restrictions are specific to the sender address +received with the MAIL FROM command. +</p> + +<dl> + +<dt><b><a name="check_sender_access">check_sender_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the MAIL FROM +address, domain, parent domains, or localpart@, and execute the +corresponding action. </dd> + +<dt><b><a name="check_sender_a_access">check_sender_a_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the IP addresses for +the MAIL FROM domain, and execute the corresponding action. Note: +a result of "OK" is not allowed for safety reasons. Instead, use +DUNNO in order to exclude specific hosts from denylists. This +feature is available in Postfix 3.0 and later. </dd> + +<dt><b><a name="check_sender_mx_access">check_sender_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the MX hosts for +the MAIL FROM domain, and execute the corresponding action. If no +MX record is found, look up A or AAAA records, just like the Postfix +SMTP client would. Note: +a result of "OK" is not allowed for safety reasons. Instead, use +DUNNO in order to exclude specific hosts from denylists. This +feature is available in Postfix 2.1 and later. </dd> + +<dt><b><a name="check_sender_ns_access">check_sender_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> + +<dd>Search the specified access(5) database for the DNS servers +for the MAIL FROM domain, and execute the corresponding action. +Note: a result of "OK" is not allowed for safety reasons. Instead, +use DUNNO in order to exclude specific hosts from denylists. This +feature is available in Postfix 2.1 and later. </dd> + +<dt><b><a name="reject_authenticated_sender_login_mismatch">reject_authenticated_sender_login_mismatch</a></b></dt> + +<dd>Enforces the reject_sender_login_mismatch restriction for +authenticated clients only. This feature is available in +Postfix version 2.1 and later. </dd> + +<dt><b><a name="reject_known_sender_login_mismatch">reject_known_sender_login_mismatch</a></b></dt> + +<dd>Apply the reject_sender_login_mismatch restriction only to MAIL +FROM addresses that are known in $smtpd_sender_login_maps. This +feature is available in Postfix version 2.11 and later. </dd> + +<dt><b><a name="reject_non_fqdn_sender">reject_non_fqdn_sender</a></b></dt> + +<dd>Reject the request when the MAIL FROM address specifies a +domain that is not in +fully-qualified domain form as required by the RFC. <br> The +non_fqdn_reject_code parameter specifies the response code for +rejected requests (default: 504). </dd> + +<dt><b><a name="reject_rhsbl_sender">reject_rhsbl_sender <i>rbl_domain=d.d.d.d</i></a></b></dt> + +<dd>Reject the request when the MAIL FROM domain is listed with +the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix +version 2.1 and later only). Each "<i>d</i>" is a number, or a +pattern inside "[]" that contains one or more ";"-separated numbers +or number..number ranges (Postfix version 2.8 and later). If no +"<i>=d.d.d.d</i>" is specified, +reject the request when the MAIL FROM domain is +listed with any A record under <i>rbl_domain</i>. <br> The +maps_rbl_reject_code parameter specifies the response code for +rejected requests (default: 554); the default_rbl_reply parameter +specifies the default server reply; and the rbl_reply_maps parameter +specifies tables with server replies indexed by <i>rbl_domain</i>. +This feature is available in Postfix 2.0 and later.</dd> + +<dt><b><a name="reject_sender_login_mismatch">reject_sender_login_mismatch</a></b></dt> + +<dd>Reject the request when $smtpd_sender_login_maps specifies an +owner for the MAIL FROM address, but the client is not (SASL) logged +in as that MAIL FROM address owner; or when the client is (SASL) +logged in, but the client login name doesn't own the MAIL FROM +address according to $smtpd_sender_login_maps.</dd> + +<dt><b><a name="reject_unauthenticated_sender_login_mismatch">reject_unauthenticated_sender_login_mismatch</a></b></dt> + +<dd>Enforces the reject_sender_login_mismatch restriction for +unauthenticated clients only. This feature is available in +Postfix version 2.1 and later. </dd> + +<dt><b><a name="reject_unknown_sender_domain">reject_unknown_sender_domain</a></b></dt> + +<dd>Reject the request when Postfix is not the final destination for +the sender address, and the MAIL FROM domain has 1) no DNS MX and +no DNS A +record, or 2) a malformed MX record such as a record with +a zero-length MX hostname (Postfix version 2.3 and later). <br> The +reply is specified with the unknown_address_reject_code parameter +(default: 450), unknown_address_tempfail_action (default: +defer_if_permit), or 550 (nullmx, Postfix 3.0 and +later). See the respective parameter descriptions for details. +</dd> + +<dt><b><a name="reject_unlisted_sender">reject_unlisted_sender</a></b></dt> + +<dd>Reject the request when the MAIL FROM address is not listed in +the list of valid recipients for its domain class. See the +smtpd_reject_unlisted_sender parameter description for details. +This feature is available in Postfix 2.1 and later.</dd> + +<dt><b><a name="reject_unverified_sender">reject_unverified_sender</a></b></dt> + +<dd>Reject the request when mail to the MAIL FROM address is known to +bounce, or when the sender address destination is not reachable. +Address verification information is managed by the verify(8) server; +see the ADDRESS_VERIFICATION_README file for details. <br> The +unverified_sender_reject_code parameter specifies the numerical +response code when an address is known to bounce (default: 450, +change into 550 when you are confident that it is safe to do so). +<br>The unverified_sender_defer_code specifies the numerical response +code when an address probe failed due to a temporary problem +(default: 450). <br> The unverified_sender_tempfail_action parameter +specifies the action after address probe failure due to a temporary +problem (default: defer_if_permit). <br> This feature breaks for +aliased addresses with "enable_original_recipient = no" (Postfix +≤ 3.2). <br> This feature is available in Postfix 2.1 and later. +</dd> + +</dl> + +<p> +Other restrictions that are valid in this context: +</p> + +<ul> + +<li> <a href="#generic">Generic</a> restrictions that can be used +in any SMTP command context, described under smtpd_client_restrictions. + +<li> SMTP command specific restrictions described under +smtpd_client_restrictions and smtpd_helo_restrictions. + +<li> SMTP command specific restrictions described under +smtpd_recipient_restrictions. When recipient restrictions are listed +under smtpd_sender_restrictions, they have effect only with +"smtpd_delay_reject = yes", so that $smtpd_sender_restrictions is +evaluated at the time of the RCPT TO command. + +</ul> + +<p> +Examples: +</p> + +<pre> +smtpd_sender_restrictions = reject_unknown_sender_domain +smtpd_sender_restrictions = reject_unknown_sender_domain, + check_sender_access hash:/etc/postfix/access +</pre> + +%PARAM smtpd_timeout normal: 300s, overload: 10s + +<p> When the Postfix SMTP server wants to send an SMTP server +response, how long the Postfix SMTP server will wait for an underlying +network write operation to complete; and when the Postfix SMTP +server Postfix wants to receive an SMTP client request, how long +the Postfix SMTP server will wait for an underlying network read +operation to complete. See the smtpd_per_request_deadline for how +this time limit may be enforced (with Postfix 2.9-3.6 see +smtpd_per_record_deadline). </p> + +<p> Normally the default limit +is 300s, but it changes under overload to just 10s. With Postfix +2.5 and earlier, the SMTP server always uses a time limit of 300s +by default. +</p> + +<p> +Note: if you set SMTP time limits to very large values you may have +to update the global ipc_timeout parameter. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM soft_bounce no + +<p> +Safety net to keep mail queued that would otherwise be returned to +the sender. This parameter disables locally-generated bounces, +changes the handling of negative responses from remote servers, +content filters or plugins, +and prevents the Postfix SMTP server from rejecting mail permanently +by changing 5xx reply codes into 4xx. However, soft_bounce is no +cure for address rewriting mistakes or mail routing mistakes. +</p> + +<p> +Note: "soft_bounce = yes" is in some cases implemented by modifying +server responses. Therefore, the response that Postfix logs may +differ from the response that Postfix actually sends or receives. +</p> + +<p> +Example: +</p> + +<pre> +soft_bounce = yes +</pre> + +%PARAM stale_lock_time 500s + +<p> +The time after which a stale exclusive mailbox lockfile is removed. +This is used for delivery to file or mailbox. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM strict_rfc821_envelopes no + +<p> +Require that addresses received in SMTP MAIL FROM and RCPT TO +commands are enclosed with <>, and that those addresses do +not contain RFC 822 style comments or phrases. This stops mail +from poorly written software. +</p> + +<p> +By default, the Postfix SMTP server accepts RFC 822 syntax in MAIL +FROM and RCPT TO addresses. +</p> + +%PARAM swap_bangpath yes + +<p> +Enable the rewriting of "site!user" into "user@site". This is +necessary if your machine is connected to UUCP networks. It is +enabled by default. +</p> + +<p> Note: with Postfix version 2.2, message header address rewriting +happens only when one of the following conditions is true: </p> + +<ul> + +<li> The message is received with the Postfix sendmail(1) command, + +<li> The message is received from a network client that matches +$local_header_rewrite_clients, + +<li> The message is received from the network, and the +remote_header_rewrite_domain parameter specifies a non-empty value. + +</ul> + +<p> To get the behavior before Postfix version 2.2, specify +"local_header_rewrite_clients = static:all". </p> + +<p> +Example: +</p> + +<pre> +swap_bangpath = no +</pre> + +%PARAM syslog_facility mail + +<p> +The syslog facility of Postfix logging. Specify a facility as +defined in syslog.conf(5). The default facility is "mail". +</p> + +<p> +Warning: a non-default syslog_facility setting takes effect only +after a Postfix process has completed initialization. Errors during +process initialization will be logged with the default facility. +Examples are errors while parsing the command line arguments, and +errors while accessing the Postfix main.cf configuration file. +</p> + +%PARAM syslog_name see "postconf -d" output + +<p> +A prefix that is prepended to the process name in syslog +records, so that, for example, "smtpd" becomes "prefix/smtpd". +</p> + +<p> +Warning: a non-default syslog_name setting takes effect only after +a Postfix process has completed initialization. Errors during +process initialization will be logged with the default name. Examples +are errors while parsing the command line arguments, and errors +while accessing the Postfix main.cf configuration file. +</p> + +%PARAM transport_maps + +<p> +Optional lookup tables with mappings from recipient address to +(message delivery transport, next-hop destination). See transport(5) +for details. +</p> + +<p> +Specify zero or more "type:table" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. If you use this +feature with local files, run "<b>postmap /etc/postfix/transport</b>" +after making a change. </p> + +<p> Pattern matching of domain names is controlled by the presence +or absence of "transport_maps" in the parent_domain_matches_subdomains +parameter value. </p> + +<p> For safety reasons, as of Postfix 2.3 this feature does not +allow $number substitutions in regular expression maps. </p> + +<p> +Examples: +</p> + +<pre> +transport_maps = dbm:/etc/postfix/transport +transport_maps = hash:/etc/postfix/transport +</pre> + +%PARAM transport_retry_time 60s + +<p> +The time between attempts by the Postfix queue manager to contact +a malfunctioning message delivery transport. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM trigger_timeout 10s + +<p> +The time limit for sending a trigger to a Postfix daemon (for +example, the pickup(8) or qmgr(8) daemon). This time limit prevents +programs from getting stuck when the mail system is under heavy +load. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM unknown_address_reject_code 450 + +<p> +The numerical response code when the Postfix SMTP server rejects a +sender or recipient address because its domain is unknown. This +is one of the possible replies from the restrictions +reject_unknown_sender_domain and reject_unknown_recipient_domain. +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +%PARAM unknown_client_reject_code 450 + +<p> +The numerical Postfix SMTP server response code when a client +without valid address <=> name mapping is rejected by the +reject_unknown_client_hostname restriction. The SMTP server always replies +with 450 when the mapping failed due to a temporary error condition. +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +%PARAM unknown_hostname_reject_code 450 + +<p> +The numerical Postfix SMTP server response code when the hostname +specified with the HELO or EHLO command is rejected by the +reject_unknown_helo_hostname restriction. +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +%PARAM unknown_local_recipient_reject_code 550 + +<p> +The numerical Postfix SMTP server response code when a recipient +address is local, and $local_recipient_maps specifies a list of +lookup tables that does not match the recipient. A recipient +address is local when its domain matches $mydestination, +$proxy_interfaces or $inet_interfaces. +</p> + +<p> +The default setting is 550 (reject mail) but it is safer to initially +use 450 (try again later) so you have time to find out if your +local_recipient_maps settings are OK. +</p> + +<p> +Example: +</p> + +<pre> +unknown_local_recipient_reject_code = 450 +</pre> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM unverified_recipient_reject_code 450 + +<p> +The numerical Postfix SMTP server response when a recipient address +is rejected by the reject_unverified_recipient restriction. +</p> + +<p> +Unlike elsewhere in Postfix, you can specify 250 in order to +accept the address anyway. +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM unverified_recipient_defer_code 450 + +<p> +The numerical Postfix SMTP server response when a recipient address +probe fails due to a temporary error condition. +</p> + +<p> +Unlike elsewhere in Postfix, you can specify 250 in order to +accept the address anyway. +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +<p> +This feature is available in Postfix 2.6 and later. +</p> + +%PARAM unverified_sender_reject_code 450 + +<p> +The numerical Postfix SMTP server response code when a recipient +address is rejected by the reject_unverified_sender restriction. +</p> + +<p> +Unlike elsewhere in Postfix, you can specify 250 in order to +accept the address anyway. +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM unverified_sender_defer_code 450 + +<p> +The numerical Postfix SMTP server response code when a sender address +probe fails due to a temporary error condition. +</p> + +<p> +Unlike elsewhere in Postfix, you can specify 250 in order to +accept the address anyway. +</p> + +<p> +Do not change this unless you have a complete understanding of RFC 5321. +</p> + +<p> +This feature is available in Postfix 2.6 and later. +</p> + +%PARAM virtual_alias_domains $virtual_alias_maps + +<p> Postfix is the final destination for the specified list of virtual +alias domains, that is, domains for which all addresses are aliased +to addresses in other local or remote domains. The SMTP server +validates recipient addresses with $virtual_alias_maps and rejects +non-existent recipients. See also the virtual alias domain class +in the ADDRESS_CLASS_README file </p> + +<p> +This feature is available in Postfix 2.0 and later. The default +value is backwards compatible with Postfix version 1.1. +</p> + +<p> +The default value is $virtual_alias_maps so that you can keep all +information about virtual alias domains in one place. If you have +many users, it is better to separate information that changes more +frequently (virtual address -> local or remote address mapping) +from information that changes less frequently (the list of virtual +domain names). +</p> + +<p> Specify a list of host or domain names, "/file/name" or +"type:table" patterns, separated by commas and/or whitespace. A +"/file/name" pattern is replaced by its contents; a "type:table" +lookup table is matched when a table entry matches a host or domain name +(the lookup result is ignored). Continue long lines by starting +the next line with whitespace. Specify "!pattern" to exclude a host +or domain name from the list. The form "!/file/name" is supported +only in Postfix version 2.4 and later. </p> + +<p> +See also the VIRTUAL_README and ADDRESS_CLASS_README documents +for further information. +</p> + +<p> +Example: +</p> + +<pre> +virtual_alias_domains = virtual1.tld virtual2.tld +</pre> + +%PARAM virtual_alias_expansion_limit 1000 + +<p> +The maximal number of addresses that virtual alias expansion produces +from each original recipient. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM virtual_alias_maps $virtual_maps + +<p> +Optional lookup tables that alias specific mail addresses or domains +to other local or remote addresses. The table format and lookups +are documented in virtual(5). For an overview of Postfix address +manipulations see the ADDRESS_REWRITING_README document. +</p> + +<p> +This feature is available in Postfix 2.0 and later. The default +value is backwards compatible with Postfix version 1.1. +</p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +Note: these lookups are recursive. +</p> + +<p> +If you use this feature with indexed files, run "<b>postmap +/etc/postfix/virtual</b>" after changing the file. +</p> + +<p> +Examples: +</p> + +<pre> +virtual_alias_maps = dbm:/etc/postfix/virtual +virtual_alias_maps = hash:/etc/postfix/virtual +</pre> + +%PARAM virtual_alias_recursion_limit 1000 + +<p> +The maximal nesting depth of virtual alias expansion. Currently +the recursion limit is applied only to the left branch of the +expansion graph, so the depth of the tree can in the worst case +reach the sum of the expansion and recursion limits. This may +change in the future. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%CLASS trouble-shooting Trouble shooting + +<p> +The DEBUG_README document describes how to debug parts of the +Postfix mail system. The methods vary from making the software log +a lot of detail, to running some daemon processes under control of +a call tracer or debugger. +</p> + +%PARAM debugger_command + +<p> +The external command to execute when a Postfix daemon program is +invoked with the -D option. +</p> + +<p> +Use "command .. & sleep 5" so that the debugger can attach before +the process marches on. If you use an X-based debugger, be sure to +set up your XAUTHORITY environment variable before starting Postfix. +</p> + +<p> +Note: the command is subject to $name expansion, before it is +passed to the default command interpreter. Specify "$$" to +produce a single "$" character. +</p> + +<p> +Example: +</p> + +<pre> +debugger_command = + PATH=/usr/bin:/usr/X11R6/bin + ddd $daemon_directory/$process_name $process_id & sleep 5 +</pre> + +%PARAM 2bounce_notice_recipient postmaster + +<p> The recipient of undeliverable mail that cannot be returned to +the sender. This feature is enabled with the notify_classes +parameter. </p> + +%PARAM address_verify_service_name verify + +<p> +The name of the verify(8) address verification service. This service +maintains the status of sender and/or recipient address verification +probes, and generates probes on request by other Postfix processes. +</p> + +%PARAM alternate_config_directories + +<p> +A list of non-default Postfix configuration directories that may +be specified with "-c config_directory" on the command line (in the +case of sendmail(1), with the "-C" option), or via the MAIL_CONFIG +environment parameter. +</p> + +<p> +This list must be specified in the default Postfix main.cf file, +and will be used by set-gid Postfix commands such as postqueue(1) +and postdrop(1). +</p> + +<p> +Specify absolute pathnames, separated by comma or space. Note: $name +expansion is not supported. +</p> + +%PARAM append_at_myorigin yes + +<p> +With locally submitted mail, append the string "@$myorigin" to mail +addresses without domain information. With remotely submitted mail, +append the string "@$remote_header_rewrite_domain" instead. +</p> + +<p> +Note 1: this feature is enabled by default and must not be turned off. +Postfix does not support domain-less addresses. +</p> + +<p> Note 2: with Postfix version 2.2, message header address rewriting +happens only when one of the following conditions is true: </p> + +<ul> + +<li> The message is received with the Postfix sendmail(1) command, + +<li> The message is received from a network client that matches +$local_header_rewrite_clients, + +<li> The message is received from the network, and the +remote_header_rewrite_domain parameter specifies a non-empty value. + +</ul> + +<p> To get the behavior before Postfix version 2.2, specify +"local_header_rewrite_clients = static:all". </p> + +%PARAM append_dot_mydomain Postfix ≥ 3.0: no, Postfix < 3.0: yes + +<p> +With locally submitted mail, append the string ".$mydomain" to +addresses that have no ".domain" information. With remotely submitted +mail, append the string ".$remote_header_rewrite_domain" +instead. +</p> + +<p> +Note 1: this feature is enabled by default. If disabled, users will not be +able to send mail to "user@partialdomainname" but will have to +specify full domain names instead. +</p> + +<p> Note 2: with Postfix version 2.2, message header address rewriting +happens only when one of the following conditions is true: </p> + +<ul> + +<li> The message is received with the Postfix sendmail(1) command, + +<li> The message is received from a network client that matches +$local_header_rewrite_clients, + +<li> The message is received from the network, and the +remote_header_rewrite_domain parameter specifies a non-empty value. + +</ul> + +<p> To get the behavior before Postfix version 2.2, specify +"local_header_rewrite_clients = static:all". </p> + +%PARAM application_event_drain_time 100s + +<p> +How long the postkick(1) command waits for a request to enter the +Postfix daemon process input buffer before giving up. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM authorized_flush_users static:anyone + +<p> +List of users who are authorized to flush the queue. +</p> + +<p> +By default, all users are allowed to flush the queue. Access is +always granted if the invoking user is the super-user or the +$mail_owner user. Otherwise, the real UID of the process is looked +up in the system password file, and access is granted only if the +corresponding login name is on the access list. The username +"unknown" is used for processes whose real UID is not found in the +password file. </p> + +<p> +Specify a list of user names, "/file/name" or "type:table" patterns, +separated by commas and/or whitespace. The list is matched left to +right, and the search stops on the first match. A "/file/name" +pattern is replaced +by its contents; a "type:table" lookup table is matched when a name +matches a lookup key (the lookup result is ignored). Continue long +lines by starting the next line with whitespace. Specify "!pattern" +to exclude a name from the list. The form "!/file/name" is supported +only in Postfix version 2.4 and later. </p> + +<p> +This feature is available in Postfix 2.2 and later. +</p> + +%PARAM authorized_mailq_users static:anyone + +<p> +List of users who are authorized to view the queue. +</p> + +<p> +By default, all users are allowed to view the queue. Access is +always granted if the invoking user is the super-user or the +$mail_owner user. Otherwise, the real UID of the process is looked +up in the system password file, and access is granted only if the +corresponding login name is on the access list. The username +"unknown" is used for processes whose real UID is not found in the +password file. </p> + +<p> +Specify a list of user names, "/file/name" or "type:table" patterns, +separated by commas and/or whitespace. The list is matched left to +right, and the search stops on the first match. A "/file/name" +pattern is replaced +by its contents; a "type:table" lookup table is matched when a name +matches a lookup key (the lookup result is ignored). Continue long +lines by starting the next line with whitespace. Specify "!pattern" +to exclude a user name from the list. The form "!/file/name" is +supported only in Postfix version 2.4 and later. </p> + +<p> +This feature is available in Postfix 2.2 and later. +</p> + +%PARAM authorized_submit_users static:anyone + +<p> +List of users who are authorized to submit mail with the sendmail(1) +command (and with the privileged postdrop(1) helper command). +</p> + +<p> +By default, all users are allowed to submit mail. Otherwise, the +real UID of the process is looked up in the system password file, +and access is granted only if the corresponding login name is on +the access list. The username "unknown" is used for processes +whose real UID is not found in the password file. To deny mail +submission access to all users specify an empty list. </p> + +<p> +Specify a list of user names, "/file/name" or "type:table" patterns, +separated by commas and/or whitespace. The list is matched left to right, +and the search stops on the first match. A "/file/name" pattern is +replaced by its contents; +a "type:table" lookup table is matched when a name matches a lookup key +(the lookup result is ignored). Continue long lines by starting the +next line with whitespace. Specify "!pattern" to exclude a user +name from the list. The form "!/file/name" is supported only in +Postfix version 2.4 and later. </p> + +<p> +Example: +</p> + +<pre> +authorized_submit_users = !www, static:all +</pre> + +<p> +This feature is available in Postfix 2.2 and later. +</p> + +%PARAM backwards_bounce_logfile_compatibility yes + +<p> +Produce additional bounce(8) logfile records that can be read by +Postfix versions before 2.0. The current and more extensible "name = +value" format is needed in order to implement more sophisticated +functionality. +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM bounce_notice_recipient postmaster + +<p> +The recipient of postmaster notifications with the message headers +of mail that Postfix did not deliver and of SMTP conversation +transcripts of mail that Postfix did not receive. This feature is +enabled with the notify_classes parameter. </p> + +%PARAM bounce_service_name bounce + +<p> +The name of the bounce(8) service. This service maintains a record +of failed delivery attempts and generates non-delivery notifications. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM broken_sasl_auth_clients no + +<p> +Enable interoperability with remote SMTP clients that implement an obsolete +version of the AUTH command (RFC 4954). Examples of such clients +are MicroSoft Outlook Express version 4 and MicroSoft Exchange +version 5.0. +</p> + +<p> +Specify "broken_sasl_auth_clients = yes" to have Postfix advertise +AUTH support in a non-standard way. +</p> + +%PARAM cleanup_service_name cleanup + +<p> +The name of the cleanup(8) service. This service rewrites addresses +into the standard form, and performs canonical(5) address mapping +and virtual(5) aliasing. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM anvil_status_update_time 600s + +<p> +How frequently the anvil(8) connection and rate limiting server +logs peak usage information. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> +This feature is available in Postfix 2.2 and later. +</p> + +%PARAM enable_errors_to no + +<p> Report mail delivery errors to the address specified with the +non-standard Errors-To: message header, instead of the envelope +sender address (this feature is removed with Postfix version 2.2, is +turned off by default with Postfix version 2.1, and is always turned on +with older Postfix versions). </p> + +%PARAM extract_recipient_limit 10240 + +<p> +The maximal number of recipient addresses that Postfix will extract +from message headers when mail is submitted with "<b>sendmail -t</b>". +</p> + +<p> +This feature was removed in Postfix version 2.1. +</p> + +%PARAM anvil_rate_time_unit 60s + +<p> +The time unit over which client connection rates and other rates +are calculated. +</p> + +<p> +This feature is implemented by the anvil(8) service which is available +in Postfix version 2.2 and later. +</p> + +<p> +The default interval is relatively short. Because of the high +frequency of updates, the anvil(8) server uses volatile memory +only. Thus, information is lost whenever the process terminates. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM command_expansion_filter see "postconf -d" output + +<p> +Restrict the characters that the local(8) delivery agent allows in +$name expansions of $mailbox_command and $command_execution_directory. +Characters outside the +allowed set are replaced by underscores. +</p> + +%PARAM content_filter + +<p> After the message is queued, send the entire message to the +specified <i>transport:destination</i>. The <i>transport</i> name +specifies the first field of a mail delivery agent definition in +master.cf; the syntax of the next-hop <i>destination</i> is described +in the manual page of the corresponding delivery agent. More +information about external content filters is in the Postfix +FILTER_README file. </p> + +<p> Notes: </p> + +<ul> + +<li> <p> This setting has lower precedence than a FILTER action +that is specified in an access(5), header_checks(5) or body_checks(5) +table. </p> + +<li> <p> The meaning of an empty next-hop filter <i>destination</i> +is version dependent. Postfix 2.7 and later will use the recipient +domain; earlier versions will use $myhostname. Specify +"default_filter_nexthop = $myhostname" for compatibility with Postfix +2.6 or earlier, or specify a content_filter value with an explicit +next-hop <i>destination</i>. </p> + +</ul> + +%PARAM default_delivery_slot_discount 50 + +<p> +The default value for transport-specific _delivery_slot_discount +settings. +</p> + +<p> +This parameter speeds up the moment when a message preemption can +happen. Instead of waiting until the full amount of delivery slots +required is available, the preemption can happen when +<i>transport</i>_delivery_slot_discount percent of the required amount +plus <i>transport</i>_delivery_slot_loan still remains to be accumulated. +Note that the full amount will still have to be accumulated before +another preemption can take place later. +</p> + +<p> Use <i>transport</i>_delivery_slot_discount to specify a +transport-specific override, where <i>transport</i> is the master.cf +name of the message delivery transport. +</p> + +%PARAM default_delivery_slot_loan 3 + +<p> +The default value for transport-specific _delivery_slot_loan +settings. +</p> + +<p> +This parameter speeds up the moment when a message preemption can +happen. Instead of waiting until the full amount of delivery slots +required is available, the preemption can happen when +transport_delivery_slot_discount percent of the required amount +plus transport_delivery_slot_loan still remains to be accumulated. +Note that the full amount will still have to be accumulated before +another preemption can take place later. +</p> + +<p> Use <i>transport</i>_delivery_slot_loan to specify a +transport-specific override, where <i>transport</i> is the master.cf +name of the message delivery transport. +</p> + +%CLASS verp VERP Support + +<p> +With VERP style delivery, each recipient of a message receives a +customized copy of the message with his/her own recipient address +encoded in the envelope sender address. The VERP_README file +describes configuration and operation details of Postfix support +for variable envelope return path addresses. VERP style delivery +is requested with the SMTP XVERP command or with the "<b>sendmail +-V</b>" command-line option and is available in Postfix +1.1 and later. +</p> + +%PARAM default_verp_delimiters += + +<p> The two default VERP delimiter characters. These are used when +no explicit delimiters are specified with the SMTP XVERP command +or with the "<b>sendmail -XV</b>" command-line option (Postfix 2.2 +and earlier: <b>-V</b>). Specify characters that are allowed by the +verp_delimiter_filter setting. +</p> + +<p> +This feature is available in Postfix 1.1 and later. +</p> + +%PARAM defer_service_name defer + +<p> +The name of the defer service. This service is implemented by the +bounce(8) daemon and maintains a record +of failed delivery attempts and generates non-delivery notifications. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM delay_notice_recipient postmaster + +<p> +The recipient of postmaster notifications with the message headers +of mail that cannot be delivered within $delay_warning_time time +units. </p> + +<p> +See also: delay_warning_time, notify_classes. +</p> + +%PARAM delay_warning_time 0h + +<p> +The time after which the sender receives a copy of the message +headers of mail that is still queued. The confirm_delay_cleared +parameter controls sender notification when the delay clears up. +</p> + +<p> +To enable this feature, specify a non-zero time value (an integral +value plus an optional one-letter suffix that specifies the time +unit). +</p> + +<p> +Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is h (hours). +</p> + +<p> +See also: delay_notice_recipient, notify_classes, confirm_delay_cleared. +</p> + +%PARAM confirm_delay_cleared no + +<p> After sending a "your message is delayed" notification, inform +the sender when the delay clears up. This can result in a sudden +burst of notifications at the end of a prolonged network outage, +and is therefore disabled by default. </p> + +<p> See also: delay_warning_time. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM disable_dns_lookups no + +<p> +Disable DNS lookups in the Postfix SMTP and LMTP clients. When +disabled, hosts are looked up with the getaddrinfo() system +library routine which normally also looks in /etc/hosts. As of +Postfix 2.11, this parameter is deprecated; use smtp_dns_support_level +instead. +</p> + +<p> +DNS lookups are enabled by default. +</p> + +%CLASS mime MIME Processing + +<p> +MIME processing is available in Postfix as of version 2.0. Older +Postfix versions do not recognize MIME headers inside the message +body. +</p> + +%PARAM disable_mime_input_processing no + +<p> +Turn off MIME processing while receiving mail. This means that no +special treatment is given to Content-Type: message headers, and +that all text after the initial message headers is considered to +be part of the message body. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +<p> +Mime input processing is enabled by default, and is needed in order +to recognize MIME headers in message content. +</p> + +%PARAM disable_mime_output_conversion no + +<p> +Disable the conversion of 8BITMIME format to 7BIT format. Mime +output conversion is needed when the destination does not advertise +8BITMIME support. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM disable_verp_bounces no + +<p> +Disable sending one bounce report per recipient. +</p> + +<p> +The default, one per recipient, is what ezmlm needs. +</p> + +<p> +This feature is available in Postfix 1.1 and later. +</p> + +%PARAM dont_remove 0 + +<p> +Don't remove queue files and save them to the "saved" mail queue. +This is a debugging aid. To inspect the envelope information and +content of a Postfix queue file, use the postcat(1) command. +</p> + +%PARAM empty_address_recipient MAILER-DAEMON + +<p> +The recipient of mail addressed to the null address. Postfix does +not accept such addresses in SMTP commands, but they may still be +created locally as the result of configuration or software error. +</p> + +%PARAM error_notice_recipient postmaster + +<p> The recipient of postmaster notifications about mail delivery +problems that are caused by policy, resource, software or protocol +errors. These notifications are enabled with the notify_classes +parameter. </p> + +%PARAM error_service_name error + +<p> +The name of the error(8) pseudo delivery agent. This service always +returns mail as undeliverable. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM expand_owner_alias no + +<p> +When delivering to an alias "<i>aliasname</i>" that has an +"owner-<i>aliasname</i>" companion alias, set the envelope sender +address to the expansion of the "owner-<i>aliasname</i>" alias. +Normally, Postfix sets the envelope sender address to the name of +the "owner-<i>aliasname</i>" alias. +</p> + +%PARAM fallback_transport + +<p> +Optional message delivery transport that the local(8) delivery +agent should use for names that are not found in the aliases(5) +or UNIX password database. +</p> + +<p> The precedence of local(8) delivery features from high to low +is: aliases, .forward files, mailbox_transport_maps, mailbox_transport, +mailbox_command_maps, mailbox_command, home_mailbox, mail_spool_directory, +fallback_transport_maps, fallback_transport and luser_relay. </p> + +%PARAM fault_injection_code 0 + +<p> +Force specific internal tests to fail, to test the handling of +errors that are difficult to reproduce otherwise. +</p> + +%PARAM flush_service_name flush + +<p> +The name of the flush(8) service. This service maintains per-destination +logfiles with the queue file names of mail that is queued for those +destinations. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM forward_expansion_filter see "postconf -d" output + +<p> +Restrict the characters that the local(8) delivery agent allows in +$name expansions of $forward_path. Characters outside the +allowed set are replaced by underscores. +</p> + +%PARAM header_address_token_limit 10240 + +<p> +The maximal number of address tokens are allowed in an address +message header. Information that exceeds the limit is discarded. +The limit is enforced by the cleanup(8) server. +</p> + +%PARAM helpful_warnings yes + +<p> +Log warnings about problematic configuration settings, and provide +helpful suggestions. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM lmtp_cache_connection yes + +<p> +Keep Postfix LMTP client connections open for up to $max_idle +seconds. When the LMTP client receives a request for the same +connection the connection is reused. +</p> + +<p> This parameter is available in Postfix version 2.2 and earlier. +With Postfix version 2.3 and later, see lmtp_connection_cache_on_demand, +lmtp_connection_cache_destinations, or lmtp_connection_reuse_time_limit. +</p> + +<p> +The effectiveness of cached connections will be determined by the +number of remote LMTP servers in use, and the concurrency limit specified +for the Postfix LMTP client. Cached connections are closed under any of +the following conditions: +</p> + +<ul> + +<li> The Postfix LMTP client idle time limit is reached. This limit is +specified with the Postfix max_idle configuration parameter. + +<li> A delivery request specifies a different destination than the +one currently cached. + +<li> The per-process limit on the number of delivery requests is +reached. This limit is specified with the Postfix max_use +configuration parameter. + +<li> Upon the onset of another delivery request, the remote LMTP server +associated with the current session does not respond to the RSET +command. + +</ul> + +<p> +Most of these limitations have been with the Postfix +connection cache that is shared among multiple LMTP client +programs. +</p> + +%PARAM lmtp_sasl_auth_enable no + +<p> +Enable SASL authentication in the Postfix LMTP client. +</p> + +%PARAM lmtp_sasl_password_maps + +<p> +Optional Postfix LMTP client lookup tables with one username:password entry +per host or domain. If a remote host or domain has no username:password +entry, then the Postfix LMTP client will not attempt to authenticate +to the remote host. +</p> + +%PARAM lmtp_sasl_security_options noplaintext, noanonymous + +<p> SASL security options; as of Postfix 2.3 the list of available +features depends on the SASL client implementation that is selected +with <b>lmtp_sasl_type</b>. </p> + +<p> The following security features are defined for the <b>cyrus</b> +client SASL implementation: </p> + +<dl> + +<dt><b>noplaintext</b></dt> + +<dd>Disallow authentication methods that use plaintext passwords. </dd> + +<dt><b>noactive</b></dt> + +<dd>Disallow authentication methods that are vulnerable to non-dictionary +active attacks. </dd> + +<dt><b>nodictionary</b></dt> + +<dd>Disallow authentication methods that are vulnerable to passive +dictionary attacks. </dd> + +<dt><b>noanonymous</b></dt> + +<dd>Disallow anonymous logins. </dd> + +</dl> + +<p> +Example: +</p> + +<pre> +lmtp_sasl_security_options = noplaintext +</pre> + +%PARAM lmtp_tcp_port 24 + +<p> +The default TCP port that the Postfix LMTP client connects to. +Specify a symbolic name (see services(5)) or a numeric port. +</p> + +%PARAM smtp_tcp_port smtp + +<p> +The default TCP port that the Postfix SMTP client connects to. +Specify a symbolic name (see services(5)) or a numeric port. +</p> + +%PARAM mail_release_date see "postconf -d" output + +<p> +The Postfix release date, in "YYYYMMDD" format. +</p> + +%PARAM mailbox_command_maps + +<p> +Optional lookup tables with per-recipient external commands to use +for local(8) mailbox delivery. Behavior is as with mailbox_command. +</p> + +<p> The precedence of local(8) delivery features from high to low +is: aliases, .forward files, mailbox_transport_maps, mailbox_transport, +mailbox_command_maps, mailbox_command, home_mailbox, mail_spool_directory, +fallback_transport_maps, fallback_transport and luser_relay. </p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +%PARAM mailbox_delivery_lock see "postconf -d" output + +<p> +How to lock a UNIX-style local(8) mailbox before attempting delivery. +For a list of available file locking methods, use the "<b>postconf +-l</b>" command. +</p> + +<p> +This setting is ignored with <b>maildir</b> style delivery, +because such deliveries are safe without explicit locks. +</p> + +<p> +Note: The <b>dotlock</b> method requires that the recipient UID or +GID has write access to the parent directory of the mailbox file. +</p> + +<p> +Note: the default setting of this parameter is system dependent. +</p> + +%PARAM mailbox_transport + +<p> +Optional message delivery transport that the local(8) delivery +agent should use for mailbox delivery to all local recipients, +whether or not they are found in the UNIX passwd database. +</p> + +<p> The precedence of local(8) delivery features from high to low +is: aliases, .forward files, mailbox_transport_maps, mailbox_transport, +mailbox_command_maps, mailbox_command, home_mailbox, mail_spool_directory, +fallback_transport_maps, fallback_transport and luser_relay. </p> + +%PARAM mailq_path see "postconf -d" output + +<p> +Sendmail compatibility feature that specifies where the Postfix +mailq(1) command is installed. This command can be used to +list the Postfix mail queue. +</p> + +%PARAM manpage_directory see "postconf -d" output + +<p> +Where the Postfix manual pages are installed. +</p> + +%PARAM maps_rbl_domains + +<p> +Obsolete feature: use the reject_rbl_client feature instead. +</p> + +%PARAM mime_boundary_length_limit 2048 + +<p> +The maximal length of MIME multipart boundary strings. The MIME +processor is unable to distinguish between boundary strings that +do not differ in the first $mime_boundary_length_limit characters. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM mime_header_checks $header_checks + +<p> +Optional lookup tables for content inspection of MIME related +message headers, as described in the header_checks(5) manual page. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM mime_nesting_limit 100 + +<p> +The maximal recursion level that the MIME processor will handle. +Postfix refuses mail that is nested deeper than the specified limit. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM mynetworks_style Postfix ≥ 3.0: host, Postfix < 3.0: subnet + +<p> +The method to generate the default value for the mynetworks parameter. +This is the list of trusted networks for relay access control etc. +</p> + +<ul> + +<li><p>Specify "mynetworks_style = host" when Postfix should +"trust" only the local machine. </p> + +<li><p>Specify "mynetworks_style = subnet" when Postfix +should "trust" remote SMTP clients in the same IP subnetworks as the local +machine. On Linux, this works correctly only with interfaces +specified with the "ifconfig" or "ip" command. </p> + +<li><p>Specify "mynetworks_style = class" when Postfix should +"trust" remote SMTP clients in the same IP class A/B/C networks as the +local machine. Caution: this may cause +Postfix to "trust" your entire provider's network. Instead, specify +an explicit mynetworks list by hand, as described with the mynetworks +configuration parameter. </p> + +</ul> + +%PARAM nested_header_checks $header_checks + +<p> +Optional lookup tables for content inspection of non-MIME message +headers in attached messages, as described in the header_checks(5) +manual page. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM newaliases_path see "postconf -d" output + +<p> +Sendmail compatibility feature that specifies the location of the +newaliases(1) command. This command can be used to rebuild the +local(8) aliases(5) database. +</p> + +%PARAM non_fqdn_reject_code 504 + +<p> +The numerical Postfix SMTP server reply code when a client request +is rejected by the reject_non_fqdn_helo_hostname, reject_non_fqdn_sender +or reject_non_fqdn_recipient restriction. +</p> + +%PARAM owner_request_special yes + +<p> +Enable special treatment for owner-<i>listname</i> entries in the +aliases(5) file, and don't split owner-<i>listname</i> and +<i>listname</i>-request address localparts when the recipient_delimiter +is set to "-". This feature is useful for mailing lists. +</p> + +%PARAM permit_mx_backup_networks + +<p> +Restrict the use of the permit_mx_backup SMTP access feature to +only domains whose primary MX hosts match the listed networks. +The parameter value syntax is the same as with the mynetworks +parameter; note, however, that the default value is empty. </p> + +<p> Pattern matching of domain names is controlled by the presence +or absence of "permit_mx_backup_networks" in the +parent_domain_matches_subdomains parameter value. </p> + +%PARAM pickup_service_name pickup + +<p> +The name of the pickup(8) service. This service picks up local mail +submissions from the Postfix maildrop queue. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM prepend_delivered_header command, file, forward + +<p> The message delivery contexts where the Postfix local(8) delivery +agent prepends a Delivered-To: message header with the address +that the mail was delivered to. This information is used for mail +delivery loop detection. </p> + +<p> +By default, the Postfix local delivery agent prepends a Delivered-To: +header when forwarding mail and when delivering to file (mailbox) +and command. Turning off the Delivered-To: header when forwarding +mail is not recommended. +</p> + +<p> +Specify zero or more of <b>forward</b>, <b>file</b>, or <b>command</b>. +</p> + +<p> +Example: +</p> + +<pre> +prepend_delivered_header = forward +</pre> + +%PARAM process_name read-only + +<p> +The process name of a Postfix command or daemon process. +</p> + +%PARAM service_name read-only + +<p> The master.cf service name of a Postfix daemon process. This +can be used to distinguish the logging from different services that +use the same program name. </p> + +<p> Example master.cf entries: </p> + +<pre> +# Distinguish inbound MTA logging from submission and smtps logging. +smtp inet n - n - - smtpd +submission inet n - n - - smtpd + -o syslog_name=postfix/$service_name +smtps inet n - n - - smtpd + -o syslog_name=postfix/$service_name +</pre> + +<pre> +# Distinguish outbound MTA logging from inbound relay logging. +smtp unix - - n - - smtp +relay unix - - n - - smtp + -o syslog_name=postfix/$service_name +</pre> + +%PARAM process_id read-only + +<p> +The process ID of a Postfix command or daemon process. +</p> + +%PARAM process_id_directory pid + +<p> +The location of Postfix PID files relative to $queue_directory. +This is a read-only parameter. +</p> + +%PARAM proxy_read_maps see "postconf -d" output + +<p> +The lookup tables that the proxymap(8) server is allowed to +access for the read-only service. +</p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. +Table references that don't begin with proxy: are ignored. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM proxy_write_maps see "postconf -d" output + +<p> The lookup tables that the proxymap(8) server is allowed to +access for the read-write service. Postfix-owned local database +files should be stored under the Postfix-owned data_directory. +Table references that don't begin with proxy: are ignored. </p> + +<p> +This feature is available in Postfix 2.5 and later. +</p> + +%PARAM qmgr_clog_warn_time 300s + +<p> +The minimal delay between warnings that a specific destination is +clogging up the Postfix active queue. Specify 0 to disable. +</p> + +<p> Specify a non-negative time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> +This feature is enabled with the helpful_warnings parameter. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM qmgr_fudge_factor 100 + +<p> +Obsolete feature: the percentage of delivery resources that a busy +mail system will use up for delivery of a large mailing list +message. +</p> + +<p> +This feature exists only in the oqmgr(8) old queue manager. The +current queue manager solves the problem in a better way. +</p> + +%PARAM queue_directory see "postconf -d" output + +<p> +The location of the Postfix top-level queue directory. This is the +root directory of Postfix daemon processes that run chrooted. +</p> + +%PARAM queue_file_attribute_count_limit 100 + +<p> +The maximal number of (name=value) attributes that may be stored +in a Postfix queue file. The limit is enforced by the cleanup(8) +server. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM queue_service_name qmgr + +<p> +The name of the qmgr(8) service. This service manages the Postfix +queue and schedules delivery requests. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM html_directory see "postconf -d" output + +<p> +The location of Postfix HTML files that describe how to build, +configure or operate a specific Postfix subsystem or feature. +</p> + +%PARAM readme_directory see "postconf -d" output + +<p> +The location of Postfix README files that describe how to build, +configure or operate a specific Postfix subsystem or feature. +</p> + +%PARAM relay_transport relay + +<p> +The default mail delivery transport and next-hop destination for +remote delivery to domains listed with $relay_domains. In order of +decreasing precedence, the nexthop destination is taken from +$relay_transport, $sender_dependent_relayhost_maps, $relayhost, or +from the recipient domain. This information can be overruled with +the transport(5) table. +</p> + +<p> +Specify a string of the form <i>transport:nexthop</i>, where <i>transport</i> +is the name of a mail delivery transport defined in master.cf. +The <i>:nexthop</i> destination is optional; its syntax is documented +in the manual page of the corresponding delivery agent. +</p> + +<p> +See also the relay domains address class in the ADDRESS_CLASS_README +file. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM rewrite_service_name rewrite + +<p> +The name of the address rewriting service. This service rewrites +addresses to standard form and resolves them to a (delivery method, +next-hop host, recipient) triple. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM sample_directory /etc/postfix + +<p> +The name of the directory with example Postfix configuration files. +Starting with Postfix 2.1, these files have been replaced with the +postconf(5) manual page. +</p> + +%PARAM sender_based_routing no + +<p> +This parameter should not be used. It was replaced by sender_dependent_relayhost_maps +in Postfix version 2.3. +</p> + +%PARAM sendmail_path see "postconf -d" output + +<p> +A Sendmail compatibility feature that specifies the location of +the Postfix sendmail(1) command. This command can be used to +submit mail into the Postfix queue. +</p> + +%PARAM service_throttle_time 60s + +<p> +How long the Postfix master(8) waits before forking a server that +appears to be malfunctioning. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM setgid_group postdrop + +<p> +The group ownership of set-gid Postfix commands and of group-writable +Postfix directories. When this parameter value is changed you need +to re-run "<b>postfix set-permissions</b>" (with Postfix version 2.0 and +earlier: "<b>/etc/postfix/post-install set-permissions</b>". +</p> + +%PARAM show_user_unknown_table_name yes + +<p> +Display the name of the recipient table in the "User unknown" +responses. The extra detail makes troubleshooting easier but also +reveals information that is nobody else's business. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM showq_service_name showq + +<p> +The name of the showq(8) service. This service produces mail queue +status reports. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM smtp_pix_workaround_delay_time 10s + +<p> +How long the Postfix SMTP client pauses before sending +".<CR><LF>" in order to work around the PIX firewall +"<CR><LF>.<CR><LF>" bug. +</p> + +<p> +Choosing too short a time makes this workaround ineffective when +sending large messages over slow network connections. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +%PARAM smtp_randomize_addresses yes + +<p> +Randomize the order of equal-preference MX host addresses. This +is a performance feature of the Postfix SMTP client. +</p> + +%PARAM smtp_rset_timeout 20s + +<p> The Postfix SMTP client time limit for sending the RSET command, +and for receiving the remote SMTP server response. The SMTP client +sends RSET in +order to finish a recipient address probe, or to verify that a +cached session is still usable. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.1 and later. </p> + +%PARAM smtpd_data_restrictions + +<p> +Optional access restrictions that the Postfix SMTP server applies +in the context of the SMTP DATA command. +See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access +restriction lists" for a discussion of evaluation context and time. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +<p> +Specify a list of restrictions, separated by commas and/or whitespace. +Continue long lines by starting the next line with whitespace. +Restrictions are applied in the order as specified; the first +restriction that matches wins. +</p> + +<p> +The following restrictions are valid in this context: +</p> + +<ul> + +<li><a href="#generic">Generic</a> restrictions that can be used +in any SMTP command context, described under smtpd_client_restrictions. + +<li>SMTP command specific restrictions described under +smtpd_client_restrictions, smtpd_helo_restrictions, +smtpd_sender_restrictions or smtpd_recipient_restrictions. + +<li>However, no recipient information is available in the case of +multi-recipient mail. Acting on only one recipient would be misleading, +because any decision will affect all recipients equally. Acting on +all recipients would require a possibly very large amount of memory, +and would also be misleading for the reasons mentioned before. + +</ul> + +<p> +Examples: +</p> + +<pre> +smtpd_data_restrictions = reject_unauth_pipelining +smtpd_data_restrictions = reject_multi_recipient_bounce +</pre> + +%PARAM smtpd_end_of_data_restrictions + +<p> Optional access restrictions that the Postfix SMTP server +applies in the context of the SMTP END-OF-DATA command. +See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access +restriction lists" for a discussion of evaluation context and time. +</p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +<p> See smtpd_data_restrictions for details and limitations. </p> + +%PARAM smtpd_delay_reject yes + +<p> +Wait until the RCPT TO command before evaluating +$smtpd_client_restrictions, $smtpd_helo_restrictions and +$smtpd_sender_restrictions, or wait until the ETRN command before +evaluating $smtpd_client_restrictions and $smtpd_helo_restrictions. +</p> + +<p> +This feature is turned on by default because some clients apparently +mis-behave when the Postfix SMTP server rejects commands before +RCPT TO. +</p> + +<p> +The default setting has one major benefit: it allows Postfix to log +recipient address information when rejecting a client name/address +or sender address, so that it is possible to find out whose mail +is being rejected. +</p> + +%PARAM smtpd_null_access_lookup_key <> + +<p> +The lookup key to be used in SMTP access(5) tables instead of the +null sender address. +</p> + +%CLASS smtpd-policy SMTP server policy delegation + +<p> +The Postfix SMTP server has a number of built-in mechanisms to +block or accept mail at specific SMTP protocol stages. As of version +2.1 Postfix can be configured to delegate policy decisions to an +external server that runs outside Postfix. See the file +SMTPD_POLICY_README for more information. +</p> + +%PARAM smtpd_policy_service_max_idle 300s + +<p> +The time after which an idle SMTPD policy service connection is +closed. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM smtpd_policy_service_max_ttl 1000s + +<p> +The time after which an active SMTPD policy service connection is +closed. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM smtpd_policy_service_timeout 100s + +<p> +The time limit for connecting to, writing to, or receiving from a +delegated SMTPD policy server. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM smtpd_policy_service_request_limit 0 + +<p> +The maximal number of requests per SMTPD policy service connection, +or zero (no limit). Once a connection reaches this limit, the +connection is closed and the next request will be sent over a new +connection. This is a workaround to avoid error-recovery delays +with policy servers that cannot maintain a persistent connection. +</p> + +<p> +This feature is available in Postfix 3.0 and later. +</p> + +%PARAM smtpd_reject_unlisted_recipient yes + +<p> +Request that the Postfix SMTP server rejects mail for unknown +recipient addresses, even when no explicit reject_unlisted_recipient +access restriction is specified. This prevents the Postfix queue +from filling up with undeliverable MAILER-DAEMON messages. +</p> + +<p> An address is always considered "known" when it matches a +virtual(5) alias or a canonical(5) mapping. + +<ul> + +<li> The recipient domain matches $mydestination, $inet_interfaces +or $proxy_interfaces, but the recipient is not listed in +$local_recipient_maps, and $local_recipient_maps is not null. + +<li> The recipient domain matches $virtual_alias_domains but the +recipient is not listed in $virtual_alias_maps. + +<li> The recipient domain matches $virtual_mailbox_domains but the +recipient is not listed in $virtual_mailbox_maps, and $virtual_mailbox_maps +is not null. + +<li> The recipient domain matches $relay_domains but the recipient +is not listed in $relay_recipient_maps, and $relay_recipient_maps +is not null. + +</ul> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM smtpd_reject_unlisted_sender no + +<p> Request that the Postfix SMTP server rejects mail from unknown +sender addresses, even when no explicit reject_unlisted_sender +access restriction is specified. This can slow down an explosion +of forged mail from worms or viruses. </p> + +<p> An address is always considered "known" when it matches a +virtual(5) alias or a canonical(5) mapping. + +<ul> + +<li> The sender domain matches $mydestination, $inet_interfaces or +$proxy_interfaces, but the sender is not listed in +$local_recipient_maps, and $local_recipient_maps is not null. + +<li> The sender domain matches $virtual_alias_domains but the sender +is not listed in $virtual_alias_maps. + +<li> The sender domain matches $virtual_mailbox_domains but the +sender is not listed in $virtual_mailbox_maps, and $virtual_mailbox_maps +is not null. + +<li> The sender domain matches $relay_domains but the sender is +not listed in $relay_recipient_maps, and $relay_recipient_maps is +not null. + +</ul> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM smtpd_restriction_classes + +<p> +User-defined aliases for groups of access restrictions. The aliases +can be specified in smtpd_recipient_restrictions etc., and on the +right-hand side of a Postfix access(5) table. +</p> + +<p> +One major application is for implementing per-recipient UCE control. +See the RESTRICTION_CLASS_README document for other examples. +</p> + +%PARAM smtpd_sasl_application_name smtpd + +<p> +The application name that the Postfix SMTP server uses for SASL +server initialization. This +controls the name of the SASL configuration file. The default value +is <b>smtpd</b>, corresponding to a SASL configuration file named +<b>smtpd.conf</b>. +</p> + +<p> +This feature is available in Postfix 2.1 and 2.2. With Postfix 2.3 +it was renamed to smtpd_sasl_path. +</p> + +%PARAM strict_7bit_headers no + +<p> +Reject mail with 8-bit text in message headers. This blocks mail +from poorly written applications. +</p> + +<p> +This feature should not be enabled on a general purpose mail server, +because it is likely to reject legitimate email. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM strict_8bitmime no + +<p> +Enable both strict_7bit_headers and strict_8bitmime_body. +</p> + +<p> +This feature should not be enabled on a general purpose mail server, +because it is likely to reject legitimate email. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM strict_8bitmime_body no + +<p> +Reject 8-bit message body text without 8-bit MIME content encoding +information. This blocks mail from poorly written applications. +</p> + +<p> +Unfortunately, this also rejects majordomo approval requests when +the included request contains valid 8-bit MIME mail, and it rejects +bounces from mailers that do not MIME encapsulate 8-bit content +(for example, bounces from qmail or from old versions of Postfix). +</p> + +<p> +This feature should not be enabled on a general purpose mail server, +because it is likely to reject legitimate email. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM strict_mime_encoding_domain no + +<p> +Reject mail with invalid Content-Transfer-Encoding: information +for the message/* or multipart/* MIME content types. This blocks +mail from poorly written software. +</p> + +<p> +This feature should not be enabled on a general purpose mail server, +because it will reject mail after a single violation. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM sun_mailtool_compatibility no + +<p> +Obsolete SUN mailtool compatibility feature. Instead, use +"mailbox_delivery_lock = dotlock". +</p> + +%PARAM trace_service_name trace + +<p> +The name of the trace service. This service is implemented by the +bounce(8) daemon and maintains a record +of mail deliveries and produces a mail delivery report when verbose +delivery is requested with "<b>sendmail -v</b>". +</p> + +<p> +This feature is available in Postfix 2.1 and later. +</p> + +%PARAM undisclosed_recipients_header see "postconf -d" output + +<p> +Message header that the Postfix cleanup(8) server inserts when a +message contains no To: or Cc: message header. With Postfix 2.8 +and later, the default value is empty. With Postfix 2.4-2.7, +specify an empty value to disable this feature. </p> + +<p> Example: </p> + +<pre> +# Default value before Postfix 2.8. +# Note: the ":" and ";" are both required. +undisclosed_recipients_header = To: undisclosed-recipients:; +</pre> + +%PARAM unknown_relay_recipient_reject_code 550 + +<p> +The numerical Postfix SMTP server reply code when a recipient +address matches $relay_domains, and relay_recipient_maps specifies +a list of lookup tables that does not match the recipient address. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM unknown_virtual_alias_reject_code 550 + +<p> +The Postfix SMTP server reply code when a recipient address matches +$virtual_alias_domains, and $virtual_alias_maps specifies a list +of lookup tables that does not match the recipient address. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM unknown_virtual_mailbox_reject_code 550 + +<p> +The Postfix SMTP server reply code when a recipient address matches +$virtual_mailbox_domains, and $virtual_mailbox_maps specifies a list +of lookup tables that does not match the recipient address. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM verp_delimiter_filter -=+ + +<p> +The characters Postfix accepts as VERP delimiter characters on the +Postfix sendmail(1) command line and in SMTP commands. +</p> + +<p> +This feature is available in Postfix 1.1 and later. +</p> + +%PARAM virtual_gid_maps + +<p> +Lookup tables with the per-recipient group ID for virtual(8) mailbox +delivery. +</p> + +<p> This parameter is specific to the virtual(8) delivery agent. +It does not apply when mail is delivered with a different mail +delivery program. </p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> +In a lookup table, specify a left-hand side of "@domain.tld" to +match any user in the specified domain that does not have a specific +"user@domain.tld" entry. +</p> + +<p> +When a recipient address has an optional address extension +(user+foo@domain.tld), the virtual(8) delivery agent looks up +the full address first, and when the lookup fails, it looks up the +unextended address (user@domain.tld). +</p> + +<p> +Note 1: for security reasons, the virtual(8) delivery agent disallows +regular expression substitution of $1 etc. in regular expression +lookup tables, because that would open a security hole. +</p> + +<p> +Note 2: for security reasons, the virtual(8) delivery agent will +silently ignore requests to use the proxymap(8) server. Instead +it will open the table directly. Before Postfix version 2.2, the +virtual(8) delivery agent will terminate with a fatal error. +</p> + +%PARAM virtual_mailbox_base + +<p> +A prefix that the virtual(8) delivery agent prepends to all pathname +results from $virtual_mailbox_maps table lookups. This is a safety +measure to ensure that an out of control map doesn't litter the +file system with mailboxes. While virtual_mailbox_base could be +set to "/", this setting isn't recommended. +</p> + +<p> This parameter is specific to the virtual(8) delivery agent. +It does not apply when mail is delivered with a different mail +delivery program. </p> + +<p> +Example: +</p> + +<pre> +virtual_mailbox_base = /var/mail +</pre> + +%PARAM virtual_mailbox_domains $virtual_mailbox_maps + +<p> Postfix is the final destination for the specified list of domains; +mail is delivered via the $virtual_transport mail delivery transport. +By default this is the Postfix virtual(8) delivery agent. The SMTP +server validates recipient addresses with $virtual_mailbox_maps +and rejects mail for non-existent recipients. See also the virtual +mailbox domain class in the ADDRESS_CLASS_README file. </p> + +<p> This parameter expects the same syntax as the mydestination +configuration parameter. </p> + +<p> +This feature is available in Postfix 2.0 and later. The default +value is backwards compatible with Postfix version 1.1. +</p> + +%PARAM virtual_mailbox_limit 51200000 + +<p> +The maximal size in bytes of an individual virtual(8) mailbox or +maildir file, or zero (no limit). </p> + +<p> This parameter is specific to the virtual(8) delivery agent. +It does not apply when mail is delivered with a different mail +delivery program. </p> + +%PARAM virtual_mailbox_lock see "postconf -d" output + +<p> +How to lock a UNIX-style virtual(8) mailbox before attempting +delivery. For a list of available file locking methods, use the +"<b>postconf -l</b>" command. +</p> + +<p> This parameter is specific to the virtual(8) delivery agent. +It does not apply when mail is delivered with a different mail +delivery program. </p> + +<p> +This setting is ignored with <b>maildir</b> style delivery, because +such deliveries are safe without application-level locks. +</p> + +<p> +Note 1: the <b>dotlock</b> method requires that the recipient UID +or GID has write access to the parent directory of the recipient's +mailbox file. +</p> + +<p> +Note 2: the default setting of this parameter is system dependent. +</p> + +%PARAM virtual_mailbox_maps + +<p> +Optional lookup tables with all valid addresses in the domains that +match $virtual_mailbox_domains. +</p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> +In a lookup table, specify a left-hand side of "@domain.tld" to +match any user in the specified domain that does not have a specific +"user@domain.tld" entry. +</p> + +<p> +With the default "virtual_mailbox_domains = $virtual_mailbox_maps", +lookup tables also need entries with a left-hand side of "domain.tld" +to satisfy virtual_mailbox_domain lookups (the right-hand side is +required but will not be used). +</p> + +<p> The remainder of this text is specific to the virtual(8) delivery +agent. It does not apply when mail is delivered with a different +mail delivery program. </p> + +<p> +The virtual(8) delivery agent uses this table to look up the +per-recipient mailbox or maildir pathname. If the lookup result +ends in a slash ("/"), maildir-style delivery is carried out, +otherwise the path is assumed to specify a UNIX-style mailbox file. +Note that $virtual_mailbox_base is unconditionally prepended to +this path. +</p> + +<p> +When a recipient address has an optional address extension +(user+foo@domain.tld), the virtual(8) delivery agent looks up +the full address first, and when the lookup fails, it looks up the +unextended address (user@domain.tld). +</p> + +<p> +Note 1: for security reasons, the virtual(8) delivery agent disallows +regular expression substitution of $1 etc. in regular expression +lookup tables, because that would open a security hole. +</p> + +<p> +Note 2: for security reasons, the virtual(8) delivery agent will +silently ignore requests to use the proxymap(8) server. Instead +it will open the table directly. Before Postfix version 2.2, the +virtual(8) delivery agent will terminate with a fatal error. +</p> + +%PARAM virtual_minimum_uid 100 + +<p> +The minimum user ID value that the virtual(8) delivery agent accepts +as a result from $virtual_uid_maps table lookup. Returned +values less than this will be rejected, and the message will be +deferred. +</p> + +<p> This parameter is specific to the virtual(8) delivery agent. +It does not apply when mail is delivered with a different mail +delivery program. </p> + +%PARAM virtual_transport virtual + +<p> +The default mail delivery transport and next-hop destination for +final delivery to domains listed with $virtual_mailbox_domains. +This information can be overruled with the transport(5) table. +</p> + +<p> +Specify a string of the form <i>transport:nexthop</i>, where <i>transport</i> +is the name of a mail delivery transport defined in master.cf. +The <i>:nexthop</i> destination is optional; its syntax is documented +in the manual page of the corresponding delivery agent. +</p> + +<p> +This feature is available in Postfix 2.0 and later. +</p> + +%PARAM virtual_uid_maps + +<p> +Lookup tables with the per-recipient user ID that the virtual(8) +delivery agent uses while writing to the recipient's mailbox. +</p> + +<p> This parameter is specific to the virtual(8) delivery agent. +It does not apply when mail is delivered with a different mail +delivery program. </p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> +In a lookup table, specify a left-hand side of "@domain.tld" +to match any user in the specified domain that does not have a +specific "user@domain.tld" entry. +</p> + +<p> +When a recipient address has an optional address extension +(user+foo@domain.tld), the virtual(8) delivery agent looks up +the full address first, and when the lookup fails, it looks up the +unextended address (user@domain.tld). +</p> + +<p> +Note 1: for security reasons, the virtual(8) delivery agent disallows +regular expression substitution of $1 etc. in regular expression +lookup tables, because that would open a security hole. +</p> + +<p> +Note 2: for security reasons, the virtual(8) delivery agent will +silently ignore requests to use the proxymap(8) server. Instead +it will open the table directly. Before Postfix version 2.2, the +virtual(8) delivery agent will terminate with a fatal error. +</p> + +%PARAM config_directory see "postconf -d" output + +<p> The default location of the Postfix main.cf and master.cf +configuration files. This can be overruled via the following +mechanisms: </p> + +<ul> + +<li> <p> The MAIL_CONFIG environment variable (daemon processes +and commands). </p> + +<li> <p> The "-c" command-line option (commands only). </p> + +</ul> + +<p> With Postfix commands that run with set-gid privileges, a +config_directory override either requires root privileges, or it +requires that the directory is listed with the alternate_config_directories +parameter in the default main.cf file. </p> + +%PARAM virtual_maps + +<p> Optional lookup tables with a) names of domains for which all +addresses are aliased to addresses in other local or remote domains, +and b) addresses that are aliased to addresses in other local or +remote domains. Available before Postfix version 2.0. With Postfix +version 2.0 and later, this is replaced by separate controls: virtual_alias_domains +and virtual_alias_maps. </p> + +%PARAM smtp_discard_ehlo_keywords + +<p> A case insensitive list of EHLO keywords (pipelining, starttls, +auth, etc.) that the Postfix SMTP client will ignore in the EHLO +response from a remote SMTP server. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +<p> Notes: </p> + +<ul> + +<li> <p> Specify the <b>silent-discard</b> pseudo keyword to prevent +this action from being logged. </p> + +<li> <p> Use the smtp_discard_ehlo_keyword_address_maps feature to +discard EHLO keywords selectively. </p> + +</ul> + +%PARAM smtpd_discard_ehlo_keywords + +<p> A case insensitive list of EHLO keywords (pipelining, starttls, +auth, etc.) that the Postfix SMTP server will not send in the EHLO +response +to a remote SMTP client. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +<p> Notes: </p> + +<ul> + +<li> <p> Specify the <b>silent-discard</b> pseudo keyword to prevent +this action from being logged. </p> + +<li> <p> Use the smtpd_discard_ehlo_keyword_address_maps feature +to discard EHLO keywords selectively. </p> + +</ul> + +%PARAM smtp_discard_ehlo_keyword_address_maps + +<p> Lookup tables, indexed by the remote SMTP server address, with +case insensitive lists of EHLO keywords (pipelining, starttls, auth, +etc.) that the Postfix SMTP client will ignore in the EHLO response from a +remote SMTP server. See smtp_discard_ehlo_keywords for details. The +table is not indexed by hostname for consistency with +smtpd_discard_ehlo_keyword_address_maps. </p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_discard_ehlo_keyword_address_maps + +<p> Lookup tables, indexed by the remote SMTP client address, with +case insensitive lists of EHLO keywords (pipelining, starttls, auth, +etc.) that the Postfix SMTP server will not send in the EHLO response +to a +remote SMTP client. See smtpd_discard_ehlo_keywords for details. +The tables are not searched by hostname for robustness reasons. </p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM connection_cache_service_name scache + +<p> The name of the scache(8) connection cache service. This service +maintains a limited pool of cached sessions. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM connection_cache_ttl_limit 2s + +<p> The maximal time-to-live value that the scache(8) connection +cache server +allows. Requests that specify a larger TTL will be stored with the +maximum allowed TTL. The purpose of this additional control is to +protect the infrastructure against careless people. The cache TTL +is already bounded by $max_idle. </p> + +%PARAM connection_cache_status_update_time 600s + +<p> How frequently the scache(8) server logs usage statistics with +connection cache hit and miss rates for logical destinations and for +physical endpoints. </p> + +%PARAM remote_header_rewrite_domain + +<p> Don't rewrite message headers from remote clients at all when +this parameter is empty; otherwise, rewrite message headers and +append the specified domain name to incomplete addresses. The +local_header_rewrite_clients parameter controls what clients Postfix +considers local. </p> + +<p> Examples: </p> + +<p> The safe setting: append "domain.invalid" to incomplete header +addresses from remote SMTP clients, so that those addresses cannot +be confused with local addresses. </p> + +<blockquote> +<pre> +remote_header_rewrite_domain = domain.invalid +</pre> +</blockquote> + +<p> The default, purist, setting: don't rewrite headers from remote +clients at all. </p> + +<blockquote> +<pre> +remote_header_rewrite_domain = +</pre> +</blockquote> + +%PARAM local_header_rewrite_clients permit_inet_interfaces + +<p> Rewrite message header addresses in mail from these clients and +update incomplete addresses with the domain name in $myorigin or +$mydomain; either don't rewrite message headers from other clients +at all, or rewrite message headers and update incomplete addresses +with the domain specified in the remote_header_rewrite_domain +parameter. </p> + +<p> See the append_at_myorigin and append_dot_mydomain parameters +for details of how domain names are appended to incomplete addresses. +</p> + +<p> Specify a list of zero or more of the following: </p> + +<dl> + +<dt><b>permit_inet_interfaces</b></dt> + +<dd> Append the domain name in $myorigin or $mydomain when the +client IP address matches $inet_interfaces. This is enabled by +default. </dd> + +<dt><b>permit_mynetworks</b></dt> + +<dd> Append the domain name in $myorigin or $mydomain when the +client IP address matches any network or network address listed in +$mynetworks. This setting will not prevent remote mail header +address rewriting when mail from a remote client is forwarded by +a neighboring system. </dd> + +<dt><b>permit_sasl_authenticated </b></dt> + +<dd> Append the domain name in $myorigin or $mydomain when the +client is successfully authenticated via the RFC 4954 (AUTH) +protocol. </dd> + +<dt><b>permit_tls_clientcerts </b></dt> + +<dd> Append the domain name in $myorigin or $mydomain when the +remote SMTP client TLS certificate fingerprint or public key fingerprint +(Postfix 2.9 and later) is listed in $relay_clientcerts. +The fingerprint digest algorithm is configurable via the +smtpd_tls_fingerprint_digest parameter (hard-coded as md5 prior to +Postfix version 2.5). </dd> + +<dd> The default algorithm is <b>sha256</b> with Postfix ≥ 3.6 +and the <b>compatibility_level</b> set to 3.6 or higher. With Postfix +≤ 3.5, the default algorithm is <b>md5</b>. The best-practice +algorithm is now <b>sha256</b>. Recent advances in hash function +cryptanalysis have led to md5 and sha1 being deprecated in favor of +sha256. However, as long as there are no known "second pre-image" +attacks against the older algorithms, their use in this context, though +not recommended, is still likely safe. </dd> + +<dt><b>permit_tls_all_clientcerts </b></dt> + +<dd> Append the domain name in $myorigin or $mydomain when the +remote SMTP client TLS certificate is successfully verified, regardless of +whether it is listed on the server, and regardless of the certifying +authority. </dd> + +<dt><b><a name="check_address_map">check_address_map</a> <i><a href="DATABASE_README.html">type:table</a></i> </b></dt> + +<dt><b><i><a href="DATABASE_README.html">type:table</a></i> </b></dt> + +<dd> Append the domain name in $myorigin or $mydomain when the +client IP address matches the specified lookup table. +The lookup result is ignored, and no subnet lookup is done. This +is suitable for, e.g., pop-before-smtp lookup tables. </dd> + +</dl> + +<p> Examples: </p> + +<p> The Postfix < 2.2 backwards compatible setting: always rewrite +message headers, and always append my own domain to incomplete +header addresses. </p> + +<blockquote> +<pre> +local_header_rewrite_clients = static:all +</pre> +</blockquote> + +<p> The purist (and default) setting: rewrite headers only in mail +from Postfix sendmail and in SMTP mail from this machine. </p> + +<blockquote> +<pre> +local_header_rewrite_clients = permit_inet_interfaces +</pre> +</blockquote> + +<p> The intermediate setting: rewrite header addresses and append +$myorigin or $mydomain information only with mail from Postfix +sendmail, from local clients, or from authorized SMTP clients. </p> + +<p> Note: this setting will not prevent remote mail header address +rewriting when mail from a remote client is forwarded by a neighboring +system. </p> + +<blockquote> +<pre> +local_header_rewrite_clients = permit_mynetworks, + permit_sasl_authenticated permit_tls_clientcerts + check_address_map hash:/etc/postfix/pop-before-smtp +</pre> +</blockquote> + +%PARAM smtpd_tls_cert_file + +<p> File with the Postfix SMTP server RSA certificate in PEM format. +This file may also contain the Postfix SMTP server private RSA key. +With Postfix ≥ 3.4 the preferred way to configure server keys and +certificates is via the "smtpd_tls_chain_files" parameter. </p> + +<p> Public Internet MX hosts without certificates signed by a "reputable" +CA must generate, and be prepared to present to most clients, a +self-signed or private-CA signed certificate. The client will not be +able to authenticate the server, but unless it is running Postfix 2.3 or +similar software, it will still insist on a server certificate. </p> + +<p> For servers that are <b>not</b> public Internet MX hosts, Postfix +supports configurations with no certificates. This entails the use of +just the anonymous TLS ciphers, which are not supported by typical SMTP +clients. Since some clients may not fall back to plain text after a TLS +handshake failure, a certificate-less Postfix SMTP server will be unable +to receive email from some TLS-enabled clients. To avoid accidental +configurations with no certificates, Postfix enables certificate-less +operation only when the administrator explicitly sets +"smtpd_tls_cert_file = none". This ensures that new Postfix SMTP server +configurations will not accidentally enable TLS without certificates. </p> + +<p> Note that server certificates are not optional in TLS 1.3. To run +without certificates you'd have to disable the TLS 1.3 protocol by +including '!TLSv1.3' in "smtpd_tls_protocols" and perhaps also +"smtpd_tls_mandatory_protocols". It is simpler instead to just +configure a certificate chain. Certificate-less operation is not +recommended. <p> + +<p> Both RSA and DSA certificates are supported. When both types +are present, the cipher used determines which certificate will be +presented to the client. For Netscape and OpenSSL clients without +special cipher choices the RSA certificate is preferred. </p> + +<p> To enable a remote SMTP client to verify the Postfix SMTP server +certificate, the issuing CA certificates must be made available to the +client. You should include the required certificates in the server +certificate file, the server certificate first, then the issuing +CA(s) (bottom-up order). </p> + +<p> Example: the certificate for "server.example.com" was issued by +"intermediate CA" which itself has a certificate of "root CA". +Create the server.pem file with "cat server_cert.pem intermediate_CA.pem +root_CA.pem > server.pem". </p> + +<p> If you also want to verify client certificates issued by these +CAs, you can add the CA certificates to the smtpd_tls_CAfile, in which +case it is not necessary to have them in the smtpd_tls_cert_file, +smtpd_tls_dcert_file (obsolete) or smtpd_tls_eccert_file. </p> + +<p> A certificate supplied here must be usable as an SSL server certificate +and hence pass the "openssl verify -purpose sslserver ..." test. </p> + +<p> Example: </p> + +<pre> +smtpd_tls_cert_file = /etc/postfix/server.pem +</pre> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_tls_key_file $smtpd_tls_cert_file + +<p> File with the Postfix SMTP server RSA private key in PEM format. +This file may be combined with the Postfix SMTP server RSA certificate +file specified with $smtpd_tls_cert_file. With Postfix ≥ 3.4 the +preferred way to configure server keys and certificates is via the +"smtpd_tls_chain_files" parameter. </p> + +<p> The private key must be accessible without a pass-phrase, i.e. it +must not be encrypted. File permissions should grant read-only +access to the system superuser account ("root"), and no access +to anyone else. </p> + +%PARAM smtpd_tls_dcert_file + +<p> File with the Postfix SMTP server DSA certificate in PEM format. +This file may also contain the Postfix SMTP server private DSA key. +The DSA algorithm is obsolete and should not be used. </p> + +<p> See the discussion under smtpd_tls_cert_file for more details. +</p> + +<p> Example: </p> + +<pre> +smtpd_tls_dcert_file = /etc/postfix/server-dsa.pem +</pre> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_tls_dkey_file $smtpd_tls_dcert_file + +<p> File with the Postfix SMTP server DSA private key in PEM format. +This file may be combined with the Postfix SMTP server DSA certificate +file specified with $smtpd_tls_dcert_file. The DSA algorithm is obsolete +and should not be used. </p> + +<p> The private key must be accessible without a pass-phrase, i.e. it +must not be encrypted. File permissions should grant read-only +access to the system superuser account ("root"), and no access +to anyone else. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_tls_CAfile + +<p> A file containing (PEM format) CA certificates of root CAs trusted +to sign either remote SMTP client certificates or intermediate CA +certificates. These are loaded into memory before the smtpd(8) server +enters the chroot jail. If the number of trusted roots is large, consider +using smtpd_tls_CApath instead, but note that the latter directory must +be present in the chroot jail if the smtpd(8) server is chrooted. This +file may also be used to augment the server certificate trust chain, +but it is best to include all the required certificates directly in the +server certificate file. </p> + +<p> Specify "smtpd_tls_CAfile = /path/to/system_CA_file" to use ONLY +the system-supplied default Certification Authority certificates. +</p> + +<p> Specify "tls_append_default_CA = no" to prevent Postfix from +appending the system-supplied default CAs and trusting third-party +certificates. </p> + +<p> By default (see smtpd_tls_ask_ccert), client certificates are not +requested, and smtpd_tls_CAfile should remain empty. If you do make use +of client certificates, the distinguished names (DNs) of the Certification +Authorities listed in smtpd_tls_CAfile are sent to the remote SMTP client +in the client certificate request message. MUAs with multiple client +certificates may use the list of preferred Certification Authorities +to select the correct client certificate. You may want to put your +"preferred" CA or CAs in this file, and install other trusted CAs in +$smtpd_tls_CApath. </p> + +<p> Example: </p> + +<pre> +smtpd_tls_CAfile = /etc/postfix/CAcert.pem +</pre> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_tls_CApath + +<p> A directory containing (PEM format) CA certificates of root CAs +trusted to sign either remote SMTP client certificates or intermediate CA +certificates. Do not forget to create the necessary "hash" links with, +for example, "$OPENSSL_HOME/bin/c_rehash /etc/postfix/certs". To use +smtpd_tls_CApath in chroot mode, this directory (or a copy) must be +inside the chroot jail. </p> + +<p> Specify "smtpd_tls_CApath = /path/to/system_CA_directory" to +use ONLY the system-supplied default Certification Authority certificates. +</p> + +<p> Specify "tls_append_default_CA = no" to prevent Postfix from +appending the system-supplied default CAs and trusting third-party +certificates. </p> + +<p> By default (see smtpd_tls_ask_ccert), client certificates are +not requested, and smtpd_tls_CApath should remain empty. In contrast +to smtpd_tls_CAfile, DNs of Certification Authorities installed +in $smtpd_tls_CApath are not included in the client certificate +request message. MUAs with multiple client certificates may use the +list of preferred Certification Authorities to select the correct +client certificate. You may want to put your "preferred" CA or +CAs in $smtpd_tls_CAfile, and install the remaining trusted CAs in +$smtpd_tls_CApath. </p> + +<p> Example: </p> + +<pre> +smtpd_tls_CApath = /etc/postfix/certs +</pre> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_tls_loglevel 0 + +<p> Enable additional Postfix SMTP server logging of TLS activity. +Each logging level also includes the information that is logged at +a lower logging level. </p> + +<dl compact> + +<dt> </dt> <dd> 0 Disable logging of TLS activity. </dd> + +<dt> </dt> <dd> 1 Log only a summary message on TLS handshake completion +— no logging of client certificate trust-chain verification errors +if client certificate verification is not required. With Postfix 2.8 and +earlier, log the summary message, peer certificate summary information +and unconditionally log trust-chain verification errors. </dd> + +<dt> </dt> <dd> 2 Also log levels during TLS negotiation. </dd> + +<dt> </dt> <dd> 3 Also log hexadecimal and ASCII dump of TLS negotiation +process. </dd> + +<dt> </dt> <dd> 4 Also log hexadecimal and ASCII dump of complete +transmission after STARTTLS. </dd> + +</dl> + +<p> Do not use "smtpd_tls_loglevel = 2" or higher except in case +of problems. Use of loglevel 4 is strongly discouraged. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_tls_received_header no + +<p> Request that the Postfix SMTP server produces Received: message +headers that include information about the protocol and cipher used, +as well as the remote SMTP client CommonName and client certificate issuer +CommonName. This is disabled by default, as the information may +be modified in transit through other mail servers. Only information +that was recorded by the final destination can be trusted. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_use_tls no + +<p> Opportunistic TLS: announce STARTTLS support to remote SMTP clients, +but do not require that clients use TLS encryption. </p> + +<p> Note: when invoked via "<b>sendmail -bs</b>", Postfix will never offer +STARTTLS due to insufficient privileges to access the server private +key. This is intended behavior. </p> + +<p> This feature is available in Postfix 2.2 and later. With +Postfix 2.3 and later use smtpd_tls_security_level instead. </p> + +%PARAM smtpd_enforce_tls no + +<p> Mandatory TLS: announce STARTTLS support to remote SMTP clients, +and require that clients use TLS encryption. According to RFC 2487 +this MUST NOT be applied in case of a publicly-referenced SMTP +server. This option is therefore off by default. </p> + +<p> Note 1: "smtpd_enforce_tls = yes" implies "smtpd_tls_auth_only = yes". </p> + +<p> Note 2: when invoked via "<b>sendmail -bs</b>", Postfix will never offer +STARTTLS due to insufficient privileges to access the server private +key. This is intended behavior. </p> + +<p> This feature is available in Postfix 2.2 and later. With +Postfix 2.3 and later use smtpd_tls_security_level instead. </p> + +%PARAM smtpd_tls_wrappermode no + +<p> Run the Postfix SMTP server in TLS "wrapper" mode, +instead of using the STARTTLS command. </p> + +<p> If you want to support this service, enable a special port in +master.cf, and specify "-o smtpd_tls_wrappermode=yes" on the SMTP +server's command line. Port 465 (submissions/smtps) is reserved for +this purpose. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_tls_ask_ccert no + +<p> Ask a remote SMTP client for a client certificate. This +information is needed for certificate based mail relaying with, +for example, the permit_tls_clientcerts feature. </p> + +<p> Some clients such as Netscape will either complain if no +certificate is available (for the list of CAs in $smtpd_tls_CAfile) +or will offer multiple client certificates to choose from. This +may be annoying, so this option is "off" by default. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_tls_req_ccert no + +<p> With mandatory TLS encryption, require a trusted remote SMTP client +certificate in order to allow TLS connections to proceed. This +option implies "smtpd_tls_ask_ccert = yes". </p> + +<p> When TLS encryption is optional, this setting is ignored with +a warning written to the mail log. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_tls_ccert_verifydepth 9 + +<p> The verification depth for remote SMTP client certificates. A +depth of 1 is sufficient if the issuing CA is listed in a local CA +file. </p> + +<p> The default verification depth is 9 (the OpenSSL default) for +compatibility with earlier Postfix behavior. Prior to Postfix 2.5, +the default value was 5, but the limit was not actually enforced. If +you have set this to a lower non-default value, certificates with longer +trust chains may now fail to verify. Certificate chains with 1 or 2 +CAs are common, deeper chains are more rare and any number between 5 +and 9 should suffice in practice. You can choose a lower number if, +for example, you trust certificates directly signed by an issuing CA +but not any CAs it delegates to. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_tls_auth_only no + +<p> When TLS encryption is optional in the Postfix SMTP server, do +not announce or accept SASL authentication over unencrypted +connections. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_tls_session_cache_database + +<p> Name of the file containing the optional Postfix SMTP server +TLS session cache. Specify a database type that supports enumeration, +such as <b>btree</b> or <b>sdbm</b>; there is no need to support +concurrent access. The file is created if it does not exist. The smtpd(8) +daemon does not use this parameter directly, rather the cache is +implemented indirectly in the tlsmgr(8) daemon. This means that +per-smtpd-instance master.cf overrides of this parameter are not +effective. Note that each of the cache databases supported by tlsmgr(8) +daemon: $smtpd_tls_session_cache_database, $smtp_tls_session_cache_database +(and with Postfix 2.3 and later $lmtp_tls_session_cache_database), needs to be +stored separately. It is not at this time possible to store multiple +caches in a single database. </p> + +<p> Note: <b>dbm</b> databases are not suitable. TLS +session objects are too large. </p> + +<p> As of version 2.5, Postfix no longer uses root privileges when +opening this file. The file should now be stored under the Postfix-owned +data_directory. As a migration aid, an attempt to open the file +under a non-Postfix directory is redirected to the Postfix-owned +data_directory, and a warning is logged. </p> + + +<p> As of Postfix 2.11 the preferred mechanism for session resumption +is RFC 5077 TLS session tickets, which don't require server-side +storage. Consequently, for Postfix ≥ 2.11 this parameter should +generally be left empty. TLS session tickets require an OpenSSL +library (at least version 0.9.8h) that provides full support for +this TLS extension. See also smtpd_tls_session_cache_timeout. </p> + +<p> Example: </p> + +<pre> +smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache +</pre> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_tls_session_cache_timeout 3600s + +<p> The expiration time of Postfix SMTP server TLS session cache +information. A cache cleanup is performed periodically +every $smtpd_tls_session_cache_timeout seconds. As with +$smtpd_tls_session_cache_database, this parameter is implemented in the +tlsmgr(8) daemon and therefore per-smtpd-instance master.cf overrides +are not possible. </p> + +<p> As of Postfix 2.11 this setting cannot exceed 100 days. If set +≤ 0, session caching is disabled, not just via the database, but +also via RFC 5077 TLS session tickets, which don't require server-side +storage. If set to a positive value less than 2 minutes, the minimum +value of 2 minutes is used instead. TLS session tickets require +an OpenSSL library (at least version 0.9.8h) that provides full +support for this TLS extension. </p> + +<p> Specify a non-negative time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.2 and later, and updated +for TLS session ticket support in Postfix 2.11. </p> + +%PARAM relay_clientcerts + +<p> List of tables with remote SMTP client-certificate fingerprints or +public key fingerprints (Postfix 2.9 and later) for which the Postfix +SMTP server will allow access with the permit_tls_clientcerts +feature. The fingerprint digest algorithm is configurable via the +smtpd_tls_fingerprint_digest parameter (hard-coded as md5 prior to +Postfix version 2.5). </p> + +<p> The default algorithm is <b>sha256</b> with Postfix ≥ 3.6 +and the <b>compatibility_level</b> set to 3.6 or higher. With Postfix +≤ 3.5, the default algorithm is <b>md5</b>. The best-practice +algorithm is now <b>sha256</b>. Recent advances in hash function +cryptanalysis have led to md5 and sha1 being deprecated in favor of +sha256. However, as long as there are no known "second pre-image" +attacks against the older algorithms, their use in this context, though +not recommended, is still likely safe. </p> + +<p> Postfix lookup tables are in the form of (key, value) pairs. +Since we only need the key, the value can be chosen freely, e.g. +the name of the user or host: +D7:04:2F:A7:0B:8C:A5:21:FA:31:77:E1:41:8A:EE:80 lutzpc.at.home </p> + +<p> Example: </p> + +<pre> +relay_clientcerts = hash:/etc/postfix/relay_clientcerts +</pre> + +<p>For more fine-grained control, use check_ccert_access to select +an appropriate access(5) policy for each client. +See RESTRICTION_CLASS_README.</p> + +<p>This feature is available with Postfix version 2.2.</p> + +%PARAM smtpd_tls_cipherlist + +<p> Obsolete Postfix < 2.3 control for the Postfix SMTP server TLS +cipher list. It is easy to create interoperability problems by choosing +a non-default cipher list. Do not use a non-default TLS cipherlist for +MX hosts on the public Internet. Clients that begin the TLS handshake, +but are unable to agree on a common cipher, may not be able to send any +email to the SMTP server. Using a restricted cipher list may be more +appropriate for a dedicated MSA or an internal mailhub, where one can +exert some control over the TLS software and settings of the connecting +clients. </p> + +<p> <b>Note:</b> do not use "" quotes around the parameter value. </p> + +<p>This feature is available with Postfix version 2.2. It is not used with +Postfix 2.3 and later; use smtpd_tls_mandatory_ciphers instead. </p> + +%PARAM smtpd_tls_dh1024_param_file + +<p> File with DH parameters that the Postfix SMTP server should +use with non-export EDH ciphers. </p> + +<p> With Postfix ≥ 3.7, built with OpenSSL version is 3.0.0 or later, if the +parameter value is either empty or "<b>auto</b>", then the DH parameter +selection is delegated to the OpenSSL library, which selects appropriate +parameters based on the TLS handshake. This choice is likely to be the most +interoperable with SMTP clients using various TLS libraries, and custom local +parameters are no longer recommended when using Postfix ≥ 3.7 built against +OpenSSL 3.0.0. </p> + +<p> The best-practice choice of parameters uses a 2048-bit prime. This is fine, +despite the historical "1024" in the parameter name. Do not be tempted to use +much larger values, performance degrades quickly, and you may also cease to +interoperate with some mainstream SMTP clients. As of Postfix 3.1, the +compiled-in default prime is 2048-bits, and it is not strictly necessary, +though perhaps somewhat beneficial to generate custom DH parameters. </p> + +<p> Instead of using the exact same parameter sets as distributed +with other TLS packages, it is more secure to generate your own +set of parameters with something like the following commands: </p> + +<blockquote> +<pre> +openssl dhparam -out /etc/postfix/dh2048.pem 2048 +openssl dhparam -out /etc/postfix/dh1024.pem 1024 +# As of Postfix 3.6, export-grade 512-bit DH parameters are no longer +# supported or needed. +openssl dhparam -out /etc/postfix/dh512.pem 512 +</pre> +</blockquote> + +<p> It is safe to share the same DH parameters between multiple +Postfix instances. If you prefer, you can generate separate +parameters for each instance. </p> + +<p> If you want to take maximal advantage of ciphers that offer <a +href="FORWARD_SECRECY_README.html#dfn_fs">forward secrecy</a> see +the <a href="FORWARD_SECRECY_README.html#quick-start">Getting +started</a> section of <a +href="FORWARD_SECRECY_README.html">FORWARD_SECRECY_README</a>. The +full document conveniently presents all information about Postfix +"perfect" forward secrecy support in one place: what forward secrecy +is, how to tweak settings, and what you can expect to see when +Postfix uses ciphers with forward secrecy. </p> + +<p> Example: </p> + +<pre> +smtpd_tls_dh1024_param_file = /etc/postfix/dh2048.pem +</pre> + +<p>This feature is available in Postfix 2.2 and later.</p> + +%PARAM smtpd_tls_dh512_param_file + +<p> File with DH parameters that the Postfix SMTP server should +use with export-grade EDH ciphers. The default SMTP server cipher +grade is "medium" with Postfix releases after the middle of 2015, +and as a result export-grade cipher suites are by default not used. +</p> + +<p> With Postfix ≥ 3.6 export-grade Diffie-Hellman key exchange +is no longer supported, and this parameter is silently ignored. </p> + +<p> See also the discussion under the smtpd_tls_dh1024_param_file +configuration parameter. </p> + +<p> Example: </p> + +<pre> +smtpd_tls_dh512_param_file = /etc/postfix/dh_512.pem +</pre> + +<p>This feature is available in Postfix 2.2 and later, +but is ignored in Postfix 3.6 and later.</p> + +%PARAM smtpd_starttls_timeout see "postconf -d" output + +<p> The time limit for Postfix SMTP server write and read operations +during TLS startup and shutdown handshake procedures. The current +default value is stress-dependent. Before Postfix version 2.8, it +was fixed at 300s. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_tls_cert_file + +<p> File with the Postfix SMTP client RSA certificate in PEM format. +This file may also contain the Postfix SMTP client private RSA key, and +these may be the same as the Postfix SMTP server RSA certificate and key +file. With Postfix ≥ 3.4 the preferred way to configure client keys +and certificates is via the "smtp_tls_chain_files" parameter. </p> + +<p> Do not configure client certificates unless you <b>must</b> present +client TLS certificates to one or more servers. Client certificates are +not usually needed, and can cause problems in configurations that work +well without them. The recommended setting is to let the defaults stand: </p> + +<blockquote> +<pre> +smtp_tls_cert_file = +smtp_tls_key_file = +smtp_tls_eccert_file = +smtp_tls_eckey_file = +# Obsolete DSA parameters +smtp_tls_dcert_file = +smtp_tls_dkey_file = +# Postfix ≥ 3.4 interface +smtp_tls_chain_files = +</pre> +</blockquote> + +<p> The best way to use the default settings is to comment out the above +parameters in main.cf if present. </p> + +<p> To enable remote SMTP servers to verify the Postfix SMTP client +certificate, the issuing CA certificates must be made available to the +server. You should include the required certificates in the client +certificate file, the client certificate first, then the issuing +CA(s) (bottom-up order). </p> + +<p> Example: the certificate for "client.example.com" was issued by +"intermediate CA" which itself has a certificate issued by "root CA". +As the "root" super-user create the client.pem file with: </p> + +<blockquote> +<pre> +# <b>umask 077</b> +# <b>cat client_key.pem client_cert.pem intermediate_CA.pem > chain.pem </b> +</pre> +</blockquote> + +<p> If you also want to verify remote SMTP server certificates issued by +these CAs, you can add the CA certificates to the smtp_tls_CAfile, in +which case it is not necessary to have them in the smtp_tls_cert_file, +smtp_tls_dcert_file (obsolete) or smtp_tls_eccert_file. </p> + +<p> A certificate supplied here must be usable as an SSL client certificate +and hence pass the "openssl verify -purpose sslclient ..." test. </p> + +<p> Example: </p> + +<pre> +smtp_tls_cert_file = /etc/postfix/chain.pem +</pre> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_tls_key_file $smtp_tls_cert_file + +<p> File with the Postfix SMTP client RSA private key in PEM format. +This file may be combined with the Postfix SMTP client RSA certificate +file specified with $smtp_tls_cert_file. With Postfix ≥ 3.4 the +preferred way to configure client keys and certificates is via the +"smtp_tls_chain_files" parameter. </p> + +<p> The private key must be accessible without a pass-phrase, i.e. it +must not be encrypted. File permissions should grant read-only +access to the system superuser account ("root"), and no access +to anyone else. </p> + +<p> Example: </p> + +<pre> +smtp_tls_key_file = $smtp_tls_cert_file +</pre> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_tls_CAfile + +<p> A file containing CA certificates of root CAs trusted to sign +either remote SMTP server certificates or intermediate CA certificates. +These are loaded into memory before the smtp(8) client enters the +chroot jail. If the number of trusted roots is large, consider using +smtp_tls_CApath instead, but note that the latter directory must be +present in the chroot jail if the smtp(8) client is chrooted. This +file may also be used to augment the client certificate trust chain, +but it is best to include all the required certificates directly in +$smtp_tls_cert_file (or, Postfix ≥ 3.4 $smtp_tls_chain_files). </p> + +<p> Specify "smtp_tls_CAfile = /path/to/system_CA_file" to use +ONLY the system-supplied default Certification Authority certificates. +</p> + +<p> Specify "tls_append_default_CA = no" to prevent Postfix from +appending the system-supplied default CAs and trusting third-party +certificates. </p> + +<p> Example: </p> + +<pre> +smtp_tls_CAfile = /etc/postfix/CAcert.pem +</pre> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_tls_CApath + +<p> Directory with PEM format Certification Authority certificates +that the Postfix SMTP client uses to verify a remote SMTP server +certificate. Don't forget to create the necessary "hash" links +with, for example, "$OPENSSL_HOME/bin/c_rehash /etc/postfix/certs". +</p> + +<p> To use this option in chroot mode, this directory (or a copy) +must be inside the chroot jail. </p> + +<p> Specify "smtp_tls_CApath = /path/to/system_CA_directory" to +use ONLY the system-supplied default Certification Authority certificates. +</p> + +<p> Specify "tls_append_default_CA = no" to prevent Postfix from +appending the system-supplied default CAs and trusting third-party +certificates. </p> + +<p> Example: </p> + +<pre> +smtp_tls_CApath = /etc/postfix/certs +</pre> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_tls_loglevel 0 + +<p> Enable additional Postfix SMTP client logging of TLS activity. +Each logging level also includes the information that is logged at +a lower logging level. </p> + +<dl compact> + +<dt> </dt> <dd> 0 Disable logging of TLS activity. </dd> + +<dt> </dt> <dd> 1 Log only a summary message on TLS handshake completion +— no logging of remote SMTP server certificate trust-chain +verification errors if server certificate verification is not required. +With Postfix 2.8 and earlier, log the summary message and unconditionally +log trust-chain verification errors. </dd> + +<dt> </dt> <dd> 2 Also log levels during TLS negotiation. </dd> + +<dt> </dt> <dd> 3 Also log the hexadecimal and ASCII dump of the +TLS negotiation process. </dd> + +<dt> </dt> <dd> 4 Also log the hexadecimal and ASCII dump of complete +transmission after STARTTLS. </dd> + +</dl> + +<p> Do not use "smtp_tls_loglevel = 2" or higher except in case of +problems. Use of loglevel 4 is strongly discouraged. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_tls_session_cache_database + +<p> Name of the file containing the optional Postfix SMTP client +TLS session cache. Specify a database type that supports enumeration, +such as <b>btree</b> or <b>sdbm</b>; there is no need to support +concurrent access. The file is created if it does not exist. The smtp(8) +daemon does not use this parameter directly, rather the cache is +implemented indirectly in the tlsmgr(8) daemon. This means that +per-smtp-instance master.cf overrides of this parameter are not effective. +Note that each of the cache databases supported by tlsmgr(8) daemon: +$smtpd_tls_session_cache_database, $smtp_tls_session_cache_database +(and with Postfix 2.3 and later $lmtp_tls_session_cache_database), needs to +be stored separately. It is not at this time possible to store multiple +caches in a single database. </p> + +<p> Note: <b>dbm</b> databases are not suitable. TLS +session objects are too large. </p> + +<p> As of version 2.5, Postfix no longer uses root privileges when +opening this file. The file should now be stored under the Postfix-owned +data_directory. As a migration aid, an attempt to open the file +under a non-Postfix directory is redirected to the Postfix-owned +data_directory, and a warning is logged. </p> + +<p> Example: </p> + +<pre> +smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_scache +</pre> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_tls_session_cache_timeout 3600s + +<p> The expiration time of Postfix SMTP client TLS session cache +information. A cache cleanup is performed periodically +every $smtp_tls_session_cache_timeout seconds. As with +$smtp_tls_session_cache_database, this parameter is implemented in the +tlsmgr(8) daemon and therefore per-smtp-instance master.cf overrides +are not possible. </p> + +<p> As of Postfix 2.11 this setting cannot exceed 100 days. If set +≤ 0, session caching is disabled. If set to a positive value +less than 2 minutes, the minimum value of 2 minutes is used instead. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_use_tls no + +<p> Opportunistic mode: use TLS when a remote SMTP server announces +STARTTLS support, otherwise send the mail in the clear. Beware: +some SMTP servers offer STARTTLS even if it is not configured. With +Postfix < 2.3, if the TLS handshake fails, and no other server is +available, delivery is deferred and mail stays in the queue. If this +is a concern for you, use the smtp_tls_per_site feature instead. </p> + +<p> This feature is available in Postfix 2.2 and later. With +Postfix 2.3 and later use smtp_tls_security_level instead. </p> + +%PARAM smtp_enforce_tls no + +<p> Enforcement mode: require that remote SMTP servers use TLS +encryption, and never send mail in the clear. This also requires +that the remote SMTP server hostname matches the information in +the remote server certificate, and that the remote SMTP server +certificate was issued by a CA that is trusted by the Postfix SMTP +client. If the certificate doesn't verify or the hostname doesn't +match, delivery is deferred and mail stays in the queue. </p> + +<p> The server hostname is matched against all names provided as +dNSNames in the SubjectAlternativeName. If no dNSNames are specified, +the CommonName is checked. The behavior may be changed with the +smtp_tls_enforce_peername option. </p> + +<p> This option is useful only if you are definitely sure that you +will only connect to servers that support RFC 2487 _and_ that +provide valid server certificates. Typical use is for clients that +send all their email to a dedicated mailhub. </p> + +<p> This feature is available in Postfix 2.2 and later. With +Postfix 2.3 and later use smtp_tls_security_level instead. </p> + +%PARAM smtp_tls_enforce_peername yes + +<p> With mandatory TLS encryption, require that the remote SMTP +server hostname matches the information in the remote SMTP server +certificate. As of RFC 2487 the requirements for hostname checking +for MTA clients are not specified. </p> + +<p> This option can be set to "no" to disable strict peer name +checking. This setting has no effect on sessions that are controlled +via the smtp_tls_per_site table. </p> + +<p> Disabling the hostname verification can make sense in a closed +environment where special CAs are created. If not used carefully, +this option opens the danger of a "man-in-the-middle" attack (the +CommonName of this attacker will be logged). </p> + +<p> This feature is available in Postfix 2.2 and later. With +Postfix 2.3 and later use smtp_tls_security_level instead. </p> + +%PARAM smtp_tls_per_site + +<p> Optional lookup tables with the Postfix SMTP client TLS usage +policy by next-hop destination and by remote SMTP server hostname. +When both lookups succeed, the more specific per-site policy (NONE, +MUST, etc.) overrides the less specific one (MAY), and the more secure +per-site policy (MUST, etc.) overrides the less secure one (NONE). +With Postfix 2.3 and later smtp_tls_per_site is strongly discouraged: +use smtp_tls_policy_maps instead. </p> + +<p> Use of the bare hostname as the per-site table lookup key is +discouraged. Always use the full destination nexthop (enclosed in +[] with a possible ":port" suffix). A recipient domain or MX-enabled +transport next-hop with no port suffix may look like a bare hostname, +but is still a suitable <i>destination</i>. </p> + +<p> Specify a next-hop destination or server hostname on the left-hand +side; no wildcards are allowed. The next-hop destination is either +the recipient domain, or the destination specified with a transport(5) +table, the relayhost parameter, or the relay_transport parameter. +On the right hand side specify one of the following keywords: </p> + +<dl> + +<dt> NONE </dt> <dd> Don't use TLS at all. This overrides a less +specific <b>MAY</b> lookup result from the alternate host or next-hop +lookup key, and overrides the global smtp_use_tls, smtp_enforce_tls, +and smtp_tls_enforce_peername settings. </dd> + +<dt> MAY </dt> <dd> Try to use TLS if the server announces support, +otherwise use an unencrypted connection. This has less precedence +than a more specific result (including <b>NONE</b>) from the alternate +host or next-hop lookup key, and has less precedence than the more +specific global "smtp_enforce_tls = yes" or "smtp_tls_enforce_peername += yes". </dd> + +<dt> MUST_NOPEERMATCH </dt> <dd> Require TLS encryption, but do not +require that the remote SMTP server hostname matches the information +in the remote SMTP server certificate, or that the server certificate +was issued by a trusted CA. This overrides a less secure <b>NONE</b> +or a less specific <b>MAY</b> lookup result from the alternate host +or next-hop lookup key, and overrides the global smtp_use_tls, +smtp_enforce_tls and smtp_tls_enforce_peername settings. </dd> + +<dt> MUST </dt> <dd> Require TLS encryption, require that the remote +SMTP server hostname matches the information in the remote SMTP +server certificate, and require that the remote SMTP server certificate +was issued by a trusted CA. This overrides a less secure <b>NONE</b> +or <b>MUST_NOPEERMATCH</b> or a less specific <b>MAY</b> lookup +result from the alternate host or next-hop lookup key, and overrides +the global smtp_use_tls, smtp_enforce_tls and smtp_tls_enforce_peername +settings. </dd> + +</dl> + +<p> The above keywords correspond to the "none", "may", "encrypt" and +"verify" security levels for the new smtp_tls_security_level parameter +introduced in Postfix 2.3. Starting with Postfix 2.3, and independently +of how the policy is specified, the smtp_tls_mandatory_ciphers and +smtp_tls_mandatory_protocols parameters apply when TLS encryption +is mandatory. Connections for which encryption is optional typically +enable all "export" grade and better ciphers (see smtp_tls_ciphers +and smtp_tls_protocols). </p> + +<p> As long as no secure DNS lookup mechanism is available, false +hostnames in MX or CNAME responses can change the server hostname +that Postfix uses for TLS policy lookup and server certificate +verification. Even with a perfect match between the server hostname and +the server certificate, there is no guarantee that Postfix is connected +to the right server. See TLS_README (Closing a DNS loophole with obsolete +per-site TLS policies) for a possible work-around. </p> + +<p> This feature is available in Postfix 2.2 and later. With +Postfix 2.3 and later use smtp_tls_policy_maps instead. </p> + +%PARAM smtp_tls_scert_verifydepth 9 + +<p> The verification depth for remote SMTP server certificates. A depth +of 1 is sufficient if the issuing CA is listed in a local CA file. </p> + +<p> The default verification depth is 9 (the OpenSSL default) for +compatibility with earlier Postfix behavior. Prior to Postfix 2.5, +the default value was 5, but the limit was not actually enforced. If +you have set this to a lower non-default value, certificates with longer +trust chains may now fail to verify. Certificate chains with 1 or 2 +CAs are common, deeper chains are more rare and any number between 5 +and 9 should suffice in practice. You can choose a lower number if, +for example, you trust certificates directly signed by an issuing CA +but not any CAs it delegates to. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_tls_note_starttls_offer no + +<p> Log the hostname of a remote SMTP server that offers STARTTLS, +when TLS is not already enabled for that server. </p> + +<p> The logfile record looks like: </p> + +<pre> +postfix/smtp[pid]: Host offered STARTTLS: [name.of.host] +</pre> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_tls_cipherlist + +<p> Obsolete Postfix < 2.3 control for the Postfix SMTP client TLS +cipher list. As this feature applies to all TLS security levels, it is easy +to create interoperability problems by choosing a non-default cipher +list. Do not use a non-default TLS cipher list on hosts that deliver email +to the public Internet: you will be unable to send email to servers that +only support the ciphers you exclude. Using a restricted cipher list +may be more appropriate for an internal MTA, where one can exert some +control over the TLS software and settings of the peer servers. </p> + +<p> <b>Note:</b> do not use "" quotes around the parameter value. </p> + +<p> This feature is available in Postfix version 2.2. It is not used with +Postfix 2.3 and later; use smtp_tls_mandatory_ciphers instead. </p> + +%PARAM smtp_starttls_timeout 300s + +<p> Time limit for Postfix SMTP client write and read operations +during TLS startup and shutdown handshake procedures. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_tls_dkey_file $smtp_tls_dcert_file + +<p> File with the Postfix SMTP client DSA private key in PEM format. +This file may be combined with the Postfix SMTP client DSA certificate +file specified with $smtp_tls_dcert_file. The DSA algorithm is obsolete +and should not be used. </p> + +<p> The private key must be accessible without a pass-phrase, i.e. it +must not be encrypted. File permissions should grant read-only +access to the system superuser account ("root"), and no access +to anyone else. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_tls_dcert_file + +<p> File with the Postfix SMTP client DSA certificate in PEM format. +This file may also contain the Postfix SMTP client private DSA key. +The DSA algorithm is obsolete and should not be used. </p> + +<p> See the discussion under smtp_tls_cert_file for more details. +</p> + +<p> Example: </p> + +<pre> +smtp_tls_dcert_file = /etc/postfix/client-dsa.pem +</pre> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM tls_append_default_CA no + +<p> Append the system-supplied default Certification Authority +certificates to the ones specified with *_tls_CApath or *_tls_CAfile. +The default is "no"; this prevents Postfix from trusting third-party +certificates and giving them relay permission with +permit_tls_all_clientcerts. </p> + +<p> This feature is available in Postfix 2.4.15, 2.5.11, 2.6.8, +2.7.2 and later versions. Specify "tls_append_default_CA = yes" for +backwards compatibility, to avoid breaking certificate verification +with sites that don't use permit_tls_all_clientcerts. </p> + +%PARAM tls_random_exchange_name see "postconf -d" output + +<p> Name of the pseudo random number generator (PRNG) state file +that is maintained by tlsmgr(8). The file is created when it does +not exist, and its length is fixed at 1024 bytes. </p> + +<p> As of version 2.5, Postfix no longer uses root privileges when +opening this file, and the default file location was changed from +${config_directory}/prng_exch to ${data_directory}/prng_exch. As +a migration aid, an attempt to open the file under a non-Postfix +directory is redirected to the Postfix-owned data_directory, and a +warning is logged. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM tls_random_source see "postconf -d" output + +<p> The external entropy source for the in-memory tlsmgr(8) pseudo +random number generator (PRNG) pool. Be sure to specify a non-blocking +source. If this source is not a regular file, the entropy source +type must be prepended: egd:/path/to/egd_socket for a source with +EGD compatible socket interface, or dev:/path/to/device for a +device file. </p> + +<p> Note: on OpenBSD systems specify dev:/dev/arandom when dev:/dev/urandom +gives timeout errors. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM tls_random_bytes 32 + +<p> The number of bytes that tlsmgr(8) reads from $tls_random_source +when (re)seeding the in-memory pseudo random number generator (PRNG) +pool. The default of 32 bytes (256 bits) is good enough for 128bit +symmetric keys. If using EGD or a device file, a maximum of 255 +bytes is read. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM tls_random_reseed_period 3600s + +<p> The maximal time between attempts by tlsmgr(8) to re-seed the +in-memory pseudo random number generator (PRNG) pool from external +sources. The actual time between re-seeding attempts is calculated +using the PRNG, and is between 0 and the time specified. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM tls_random_prng_update_period 3600s + +<p> The time between attempts by tlsmgr(8) to save the state of +the pseudo random number generator (PRNG) to the file specified +with $tls_random_exchange_name. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM tls_daemon_random_bytes 32 + +<p> The number of pseudo-random bytes that an smtp(8) or smtpd(8) +process requests from the tlsmgr(8) server in order to seed its +internal pseudo random number generator (PRNG). The default of 32 +bytes (equivalent to 256 bits) is sufficient to generate a 128bit +(or 168bit) session key. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_sasl_tls_security_options $smtp_sasl_security_options + +<p> The SASL authentication security options that the Postfix SMTP +client uses for TLS encrypted SMTP sessions. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtpd_sasl_tls_security_options $smtpd_sasl_security_options + +<p> The SASL authentication security options that the Postfix SMTP +server uses for TLS encrypted SMTP sessions. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM smtp_generic_maps + +<p> Optional lookup tables that perform address rewriting in the +Postfix SMTP client, typically to transform a locally valid address into +a globally valid address when sending mail across the Internet. +This is needed when the local machine does not have its own Internet +domain name, but uses something like <i>localdomain.local</i> +instead. </p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> The table format and lookups are documented in generic(5); +examples are shown in the ADDRESS_REWRITING_README and +STANDARD_CONFIGURATION_README documents. </p> + +<p> This feature is available in Postfix 2.2 and later. </p> + +%PARAM message_reject_characters + +<p> The set of characters that Postfix will reject in message +content. The usual C-like escape sequences are recognized: <tt>\a +\b \f \n \r \t \v \<i>ddd</i></tt> (up to three octal digits) and +<tt>\\</tt>. </p> + +<p> Note 1: this feature does not recognize text that requires MIME +decoding. It inspects raw message content, just like header_checks +and body_checks. </p> + +<p> Note 2: this feature is disabled with "receive_override_options += no_header_body_checks". </p> + +<p> Example: </p> + +<pre> +message_reject_characters = \0 +</pre> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM message_strip_characters + +<p> The set of characters that Postfix will remove from message +content. The usual C-like escape sequences are recognized: <tt>\a +\b \f \n \r \t \v \<i>ddd</i></tt> (up to three octal digits) and +<tt>\\</tt>. </p> + +<p> Note 1: this feature does not recognize text that requires MIME +decoding. It inspects raw message content, just like header_checks +and body_checks. </p> + +<p> Note 2: this feature is disabled with "receive_override_options += no_header_body_checks". </p> + +<p> Example: </p> + +<pre> +message_strip_characters = \0 +</pre> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM frozen_delivered_to yes + +<p> Update the local(8) delivery agent's idea of the Delivered-To: +address (see prepend_delivered_header) only once, at the start of +a delivery attempt; do not update the Delivered-To: address while +expanding aliases or .forward files. </p> + +<p> This feature is available in Postfix 2.3 and later. With older +Postfix releases, the behavior is as if this parameter is set to +"no". The old setting can be expensive with deeply nested aliases +or .forward files. When an alias or .forward file changes the +Delivered-To: address, it ties up one queue file and one cleanup +process instance while mail is being forwarded. </p> + +%PARAM smtpd_peername_lookup yes + +<p> Attempt to look up the remote SMTP client hostname, and verify that +the name matches the client IP address. A client name is set to +"unknown" when it cannot be looked up or verified, or when name +lookup is disabled. Turning off name lookup reduces delays due to +DNS lookup and increases the maximal inbound delivery rate. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM delay_logging_resolution_limit 2 + +<p> The maximal number of digits after the decimal point when logging +sub-second delay values. Specify a number in the range 0..6. </p> + +<p> Large delay values are rounded off to an integral number of seconds; +delay values below the delay_logging_resolution_limit are logged +as "0", and delay values under 100s are logged with at most two-digit +precision. </p> + +<p> The format of the "delays=a/b/c/d" logging is as follows: </p> + +<ul> + +<li> a = time from message arrival to last active queue entry + +<li> b = time from last active queue entry to connection setup + +<li> c = time in connection setup, including DNS, EHLO and STARTTLS + +<li> d = time in message transmission + +</ul> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM bounce_template_file + +<p> Pathname of a configuration file with bounce message templates. +These override the built-in templates of delivery status notification +(DSN) messages for undeliverable mail, delayed mail, successful +delivery, or delivery verification. The bounce(5) manual page +describes how to edit and test template files. </p> + +<p> Template message body text may contain $name references to +Postfix configuration parameters. The result of $name expansion can +be previewed with "<b>postconf -b <i>file_name</i></b>" before the file +is placed into the Postfix configuration directory. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM sender_dependent_relayhost_maps + +<p> A sender-dependent override for the global relayhost parameter +setting. The tables are searched by the envelope sender address and +@domain. A lookup result of DUNNO terminates the search without +overriding the global relayhost parameter setting (Postfix 2.6 and +later). This information is overruled with relay_transport, +sender_dependent_default_transport_maps, default_transport and with +the transport(5) table. </p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> For safety reasons, this feature does not allow $number +substitutions in regular expression maps. </p> + +<p> +This feature is available in Postfix 2.3 and later. +</p> + +%PARAM empty_address_relayhost_maps_lookup_key <> + +<p> The sender_dependent_relayhost_maps search string that will be +used instead of the null sender address. </p> + +<p> This feature is available in Postfix 2.5 and later. With +earlier versions, sender_dependent_relayhost_maps lookups were +skipped for the null sender address. </p> + +%PARAM address_verify_sender_dependent_relayhost_maps $sender_dependent_relayhost_maps + +<p> +Overrides the sender_dependent_relayhost_maps parameter setting for address +verification probes. +</p> + +<p> +This feature is available in Postfix 2.3 and later. +</p> + +%PARAM smtp_sender_dependent_authentication no + +<p> +Enable sender-dependent authentication in the Postfix SMTP client; this is +available only with SASL authentication, and disables SMTP connection +caching to ensure that mail from different senders will use the +appropriate credentials. </p> + +<p> +This feature is available in Postfix 2.3 and later. +</p> + +%PARAM lmtp_lhlo_name $myhostname + +<p> +The hostname to send in the LMTP LHLO command. +</p> + +<p> +The default value is the machine hostname. Specify a hostname or +[ip.add.re.ss] or [ip:v6:add:re::ss]. +</p> + +<p> +This information can be specified in the main.cf file for all LMTP +clients, or it can be specified in the master.cf file for a specific +client, for example: +</p> + +<blockquote> +<pre> +/etc/postfix/master.cf: + mylmtp ... lmtp -o lmtp_lhlo_name=foo.bar.com +</pre> +</blockquote> + +<p> +This feature is available in Postfix 2.3 and later. +</p> + +%PARAM lmtp_discard_lhlo_keyword_address_maps + +<p> Lookup tables, indexed by the remote LMTP server address, with +case insensitive lists of LHLO keywords (pipelining, starttls, +auth, etc.) that the Postfix LMTP client will ignore in the LHLO +response +from a remote LMTP server. See lmtp_discard_lhlo_keywords for +details. The table is not indexed by hostname for consistency with +smtpd_discard_ehlo_keyword_address_maps. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_discard_lhlo_keywords + +<p> A case insensitive list of LHLO keywords (pipelining, starttls, +auth, etc.) that the Postfix LMTP client will ignore in the LHLO +response +from a remote LMTP server. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +<p> Notes: </p> + +<ul> + +<li> <p> Specify the <b>silent-discard</b> pseudo keyword to prevent +this action from being logged. </p> + +<li> <p> Use the lmtp_discard_lhlo_keyword_address_maps feature to +discard LHLO keywords selectively. </p> + +</ul> + +%PARAM lmtp_lhlo_timeout 300s + +<p> The Postfix LMTP client time limit for sending the LHLO command, +and for receiving the initial remote LMTP server response. </p> + +<p> Time units: s (seconds), m (minutes), h (hours), d (days), w +(weeks). The default time unit is s (seconds). </p> + +%PARAM lmtp_sasl_tls_security_options $lmtp_sasl_security_options + +<p> The LMTP-specific version of the smtp_sasl_tls_security_options +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_sasl_mechanism_filter + +<p> The LMTP-specific version of the smtp_sasl_mechanism_filter +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_bind_address + +<p> The LMTP-specific version of the smtp_bind_address configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_bind_address6 + +<p> The LMTP-specific version of the smtp_bind_address6 configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_host_lookup dns + +<p> The LMTP-specific version of the smtp_host_lookup configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_connection_cache_destinations + +<p> The LMTP-specific version of the smtp_connection_cache_destinations +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_per_site + +<p> The LMTP-specific version of the smtp_tls_per_site configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_generic_maps + +<p> The LMTP-specific version of the smtp_generic_maps configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_pix_workaround_threshold_time 500s + +<p> The LMTP-specific version of the smtp_pix_workaround_threshold_time +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_pix_workaround_delay_time 10s + +<p> The LMTP-specific version of the smtp_pix_workaround_delay_time +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_connection_reuse_time_limit 300s + +<p> The LMTP-specific version of the smtp_connection_reuse_time_limit +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_starttls_timeout 300s + +<p> The LMTP-specific version of the smtp_starttls_timeout configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_line_length_limit 990 + +<p> The LMTP-specific version of the smtp_line_length_limit +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_mx_address_limit 5 + +<p> The LMTP-specific version of the smtp_mx_address_limit configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_mx_session_limit 2 + +<p> The LMTP-specific version of the smtp_mx_session_limit configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_scert_verifydepth 9 + +<p> The LMTP-specific version of the smtp_tls_scert_verifydepth +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_skip_5xx_greeting yes + +<p> The LMTP-specific version of the smtp_skip_5xx_greeting +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_randomize_addresses yes + +<p> The LMTP-specific version of the smtp_randomize_addresses +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_quote_rfc821_envelope yes + +<p> The LMTP-specific version of the smtp_quote_rfc821_envelope +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_defer_if_no_mx_address_found no + +<p> The LMTP-specific version of the smtp_defer_if_no_mx_address_found +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_connection_cache_on_demand yes + +<p> The LMTP-specific version of the smtp_connection_cache_on_demand +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_use_tls no + +<p> The LMTP-specific version of the smtp_use_tls configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_enforce_tls no + +<p> The LMTP-specific version of the smtp_enforce_tls configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_security_level + +<p> The LMTP-specific version of the smtp_tls_security_level configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_enforce_peername yes + +<p> The LMTP-specific version of the smtp_tls_enforce_peername +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_note_starttls_offer no + +<p> The LMTP-specific version of the smtp_tls_note_starttls_offer +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_sender_dependent_authentication no + +<p> The LMTP-specific version of the smtp_sender_dependent_authentication +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM connection_cache_protocol_timeout 5s + +<p> Time limit for connection cache connect, send or receive +operations. The time limit is enforced in the client. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtpd_sasl_type cyrus + +<p> The SASL plug-in type that the Postfix SMTP server should use +for authentication. The available types are listed with the +"<b>postconf -a</b>" command. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtp_sasl_type cyrus + +<p> The SASL plug-in type that the Postfix SMTP client should use +for authentication. The available types are listed with the +"<b>postconf -A</b>" command. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + + +%PARAM lmtp_sasl_type cyrus + +<p> The SASL plug-in type that the Postfix LMTP client should use +for authentication. The available types are listed with the +"<b>postconf -A</b>" command. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtpd_sasl_path smtpd + +<p> Implementation-specific information that the Postfix SMTP server +passes through to +the SASL plug-in implementation that is selected with +<b>smtpd_sasl_type</b>. Typically this specifies the name of a +configuration file or rendezvous point. </p> + +<p> This feature is available in Postfix 2.3 and later. In earlier +releases it was called <b>smtpd_sasl_application_name</b>. </p> + +%PARAM smtpd_sasl_service smtp + +<p> The service name that is passed to the SASL plug-in that is +selected with <b>smtpd_sasl_type</b> and <b>smtpd_sasl_path</b>. +</p> + +<p> This feature is available in Postfix 2.11 and later. Prior +versions behave as if "<b>smtp</b>" is specified. </p> + +%PARAM smtpd_sasl_response_limit 12288 + +<p> The maximum length of a SASL client's response to a server challenge. +When the client's "initial response" is longer than the normal limit for +SMTP commands, the client must omit its initial response, and wait for an +empty server challenge; it can then send what would have been its "initial +response" as a response to the empty server challenge. RFC4954 requires the +server to accept client responses up to at least 12288 octets of +base64-encoded text. The default value is therefore also the minimum value +accepted for this parameter.</p> + +<p> This feature is available in Postfix 3.4 and later. Prior versions use +"line_length_limit", which may need to be raised to accommodate larger client +responses, as may be needed with GSSAPI authentication of Windows AD users +who are members of many groups. </p> + +%PARAM cyrus_sasl_config_path + +<p> Search path for Cyrus SASL application configuration files, +currently used only to locate the $smtpd_sasl_path.conf file. +Specify zero or more directories separated by a colon character, +or an empty value to use Cyrus SASL's built-in search path. </p> + +<p> This feature is available in Postfix 2.5 and later when compiled +with Cyrus SASL 2.1.22 or later. </p> + +%PARAM smtp_sasl_path + +<p> Implementation-specific information that the Postfix SMTP client +passes through to +the SASL plug-in implementation that is selected with +<b>smtp_sasl_type</b>. Typically this specifies the name of a +configuration file or rendezvous point. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_sasl_path + +<p> Implementation-specific information that is passed through to +the SASL plug-in implementation that is selected with +<b>lmtp_sasl_type</b>. Typically this specifies the name of a +configuration file or rendezvous point. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM plaintext_reject_code 450 + +<p> +The numerical Postfix SMTP server response code when a request +is rejected by the <b>reject_plaintext_session</b> restriction. +</p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM resolve_numeric_domain no + +<p> Resolve "user@ipaddress" as "user@[ipaddress]", instead of +rejecting the address as invalid. </p> + +<p> This feature is available in Postfix 2.3 and later. + +%PARAM mailbox_transport_maps + +<p> Optional lookup tables with per-recipient message delivery +transports to use for local(8) mailbox delivery, whether or not the +recipients are found in the UNIX passwd database. </p> + +<p> The precedence of local(8) delivery features from high to low +is: aliases, .forward files, mailbox_transport_maps, mailbox_transport, +mailbox_command_maps, mailbox_command, home_mailbox, mail_spool_directory, +fallback_transport_maps, fallback_transport and luser_relay. </p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> For safety reasons, this feature does not allow $number +substitutions in regular expression maps. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM fallback_transport_maps + +<p> Optional lookup tables with per-recipient message delivery +transports for recipients that the local(8) delivery agent could +not find in the aliases(5) or UNIX password database. </p> + +<p> The precedence of local(8) delivery features from high to low +is: aliases, .forward files, mailbox_transport_maps, mailbox_transport, +mailbox_command_maps, mailbox_command, home_mailbox, mail_spool_directory, +fallback_transport_maps, fallback_transport and luser_relay. </p> + +<p> For safety reasons, this feature does not allow $number +substitutions in regular expression maps. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtp_cname_overrides_servername version dependent + +<p> When the remote SMTP servername is a DNS CNAME, replace the +servername with the result from CNAME expansion for the purpose of +logging, SASL password lookup, TLS +policy decisions, or TLS certificate verification. The value "no" +hardens Postfix smtp_tls_per_site hostname-based policies against +false hostname information in DNS CNAME records, and makes SASL +password file lookups more predictable. This is the default setting +as of Postfix 2.3. </p> + +<p> When DNS CNAME records are validated with secure DNS lookups +(smtp_dns_support_level = dnssec), they are always allowed to +override the above servername (Postfix 2.11 and later). </p> + +<p> This feature is available in Postfix 2.2.9 and later. </p> + +%PARAM lmtp_cname_overrides_servername yes + +<p> The LMTP-specific version of the smtp_cname_overrides_servername +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtp_sasl_tls_verified_security_options $smtp_sasl_tls_security_options + +<p> The SASL authentication security options that the Postfix SMTP +client uses for TLS encrypted SMTP sessions with a verified server +certificate. </p> + +<p> When mail is sent to the public MX host for the recipient's +domain, server certificates are by default optional, and delivery +proceeds even if certificate verification fails. For delivery via +a submission service that requires SASL authentication, it may be +appropriate to send plaintext passwords only when the connection +to the server is strongly encrypted <b>and</b> the server identity +is verified. </p> + +<p> The smtp_sasl_tls_verified_security_options parameter makes it +possible to only enable plaintext mechanisms when a secure connection +to the server is available. Submission servers subject to this +policy must either have verifiable certificates or offer suitable +non-plaintext SASL mechanisms. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM lmtp_sasl_tls_verified_security_options $lmtp_sasl_tls_security_options + +<p> The LMTP-specific version of the +smtp_sasl_tls_verified_security_options configuration parameter. +See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_connection_cache_time_limit 2s + +<p> The LMTP-specific version of the +smtp_connection_cache_time_limit configuration parameter. +See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtpd_delay_open_until_valid_rcpt yes + +<p> Postpone the start of an SMTP mail transaction until a valid +RCPT TO command is received. Specify "no" to create a mail transaction +as soon as the Postfix SMTP server receives a valid MAIL FROM +command. </p> + +<p> With sites that reject lots of mail, the default setting reduces +the use of +disk, CPU and memory resources. The downside is that rejected +recipients are logged with NOQUEUE instead of a mail transaction +ID. This complicates the logfile analysis of multi-recipient mail. +</p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_cert_file + +<p> The LMTP-specific version of the smtp_tls_cert_file +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_key_file $lmtp_tls_cert_file + +<p> The LMTP-specific version of the smtp_tls_key_file +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_dcert_file + +<p> The LMTP-specific version of the smtp_tls_dcert_file +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_dkey_file $lmtp_tls_dcert_file + +<p> The LMTP-specific version of the smtp_tls_dkey_file +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_CAfile + +<p> The LMTP-specific version of the smtp_tls_CAfile +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_CApath + +<p> The LMTP-specific version of the smtp_tls_CApath +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_loglevel 0 + +<p> The LMTP-specific version of the smtp_tls_loglevel +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_session_cache_database + +<p> The LMTP-specific version of the smtp_tls_session_cache_database +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_session_cache_timeout 3600s + +<p> The LMTP-specific version of the smtp_tls_session_cache_timeout +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtp_tls_policy_maps + +<p> Optional lookup tables with the Postfix SMTP client TLS security +policy by next-hop destination; when a non-empty value is specified, +this overrides the obsolete smtp_tls_per_site parameter. See +TLS_README for a more detailed discussion of TLS security levels. +</p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> The TLS policy table is indexed by the full next-hop destination, +which is either the recipient domain, or the verbatim next-hop +specified in the transport table, $local_transport, $virtual_transport, +$relay_transport or $default_transport. This includes any enclosing +square brackets and any non-default destination server port suffix. The +LMTP socket type prefix (inet: or unix:) is not included in the lookup +key. </p> + +<p> Only the next-hop domain, or $myhostname with LMTP over UNIX-domain +sockets, is used as the nexthop name for certificate verification. The +port and any enclosing square brackets are used in the table lookup key, +but are not used for server name verification. </p> + +<p> When the lookup key is a domain name without enclosing square brackets +or any <i>:port</i> suffix (typically the recipient domain), and the full +domain is not found in the table, just as with the transport(5) table, +the parent domain starting with a leading "." is matched recursively. This +allows one to specify a security policy for a recipient domain and all +its sub-domains. </p> + +<p> The lookup result is a security level, followed by an optional list +of whitespace and/or comma separated name=value attributes that override +related main.cf settings. The TLS security levels in order of increasing +security are: </p> + +<dl> + +<dt><b><a href="TLS_README.html#client_tls_none">none</a></b></dt> +<dd>No TLS. No additional attributes are supported at this level. </dd> + +<dt><b><a href="TLS_README.html#client_tls_may">may</a></b></dt> +<dd>Opportunistic TLS. Since sending in the clear is acceptable, +demanding stronger than default TLS security merely reduces +interoperability. The optional "ciphers", "exclude", and "protocols" +attributes (available for opportunistic TLS with Postfix ≥ 2.6) +and "connection_reuse" attribute (Postfix ≥ 3.4) override the +"smtp_tls_ciphers", "smtp_tls_exclude_ciphers", "smtp_tls_protocols", +and +"smtp_tls_connection_reuse" configuration parameters. In the policy table, +multiple ciphers, protocols or excluded ciphers must be separated by colons, +as attribute values may not contain whitespace or commas. When opportunistic +TLS handshakes fail, Postfix retries the connection with TLS disabled. +This allows mail delivery to sites with non-interoperable TLS +implementations.</dd> + +<dt><b><a href="TLS_README.html#client_tls_encrypt">encrypt</a></b></dt> +<dd>Mandatory TLS encryption. At this level +and higher, the optional "protocols" attribute overrides the main.cf +smtp_tls_mandatory_protocols parameter, the optional "ciphers" attribute +overrides the main.cf smtp_tls_mandatory_ciphers parameter, the +optional "exclude" attribute (Postfix ≥ 2.6) overrides the main.cf +smtp_tls_mandatory_exclude_ciphers parameter, and the optional +"connection_reuse" attribute (Postfix ≥ 3.4) overrides the +main.cf smtp_tls_connection_reuse parameter. In the policy table, +multiple ciphers, protocols or excluded ciphers must be separated by colons, +as attribute values may not contain whitespace or commas. </dd> + +<dt><b><a href="TLS_README.html#client_tls_dane">dane</a></b></dt> +<dd>Opportunistic DANE TLS. The TLS policy for the destination is +obtained via TLSA records in DNSSEC. If no TLSA records are found, +the effective security level used is <a +href="TLS_README.html#client_tls_may">may</a>. If TLSA records are +found, but none are usable, the effective security level is <a +href="TLS_README.html#client_tls_encrypt">encrypt</a>. When usable +TLSA records are obtained for the remote SMTP server, the +server certificate must match the TLSA records. RFC 7672 (DANE) +TLS authentication and DNSSEC support is available with Postfix +2.11 and later. The optional "connection_reuse" attribute (Postfix +≥ 3.4) overrides the main.cf smtp_tls_connection_reuse parameter. +When the effective security level used is <a +href="TLS_README.html#client_tls_may">may</a>, the optional "ciphers", +"exclude", and "protocols" attributes (Postfix ≥ 2.6) override the +"smtp_tls_ciphers", "smtp_tls_exclude_ciphers", and "smtp_tls_protocols" +configuration parameters. +When the effective security level used is <a +href="TLS_README.html#client_tls_encrypt">encrypt</a>, the optional "ciphers", +"exclude", and "protocols" attributes (Postfix ≥ 2.6) override the +"smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and +"smtp_tls_mandatory_protocols" configuration parameters. +</dd> + +<dt><b><a href="TLS_README.html#client_tls_dane">dane-only</a></b></dt> +<dd>Mandatory DANE TLS. The TLS policy for the destination is +obtained via TLSA records in DNSSEC. If no TLSA records are found, +or none are usable, no connection is made to the server. When +usable TLSA records are obtained for the remote SMTP server, the +server certificate must match the TLSA records. RFC 7672 (DANE) TLS +authentication and DNSSEC support is available with Postfix 2.11 +and later. The optional "ciphers", "exclude", and "protocols" attributes +(Postfix ≥ 2.6) override the "smtp_tls_mandatory_ciphers", +"smtp_tls_mandatory_exclude_ciphers", and "smtp_tls_mandatory_protocols" +configuration parameters. The optional "connection_reuse" attribute +(Postfix ≥ 3.4) overrides the main.cf smtp_tls_connection_reuse parameter. +</dd> + +<dt><b><a href="TLS_README.html#client_tls_fprint">fingerprint</a></b></dt> +<dd>Certificate fingerprint +verification. Available with Postfix 2.5 and later. At this security +level, there are no trusted Certification Authorities. The certificate +trust chain, expiration date, ... are not checked. Instead, +the optional "match" attribute, or else the main.cf +<b>smtp_tls_fingerprint_cert_match</b> parameter, lists the certificate +fingerprints or the public key fingerprint (Postfix 2.9 and later) +of the valid server certificate. The digest +algorithm used to calculate the fingerprint is selected by the +<b>smtp_tls_fingerprint_digest</b> parameter. Multiple fingerprints can +be combined with a "|" delimiter in a single match attribute, or multiple +match attributes can be employed. The ":" character is not used as a +delimiter as it occurs between each pair of fingerprint (hexadecimal) +digits. The optional "ciphers", "exclude", and "protocols" attributes +(Postfix ≥ 2.6) override the "smtp_tls_mandatory_ciphers", +"smtp_tls_mandatory_exclude_ciphers", and "smtp_tls_mandatory_protocols" +configuration parameters. The optional "connection_reuse" attribute +(Postfix ≥ 3.4) overrides the main.cf smtp_tls_connection_reuse +parameter. </dd> + +<dt><b><a href="TLS_README.html#client_tls_verify">verify</a></b></dt> +<dd>Mandatory TLS verification. At this security +level, DNS MX lookups are trusted to be secure enough, and the name +verified in the server certificate is usually obtained indirectly via +unauthenticated DNS MX lookups. The optional "match" attribute overrides +the main.cf smtp_tls_verify_cert_match parameter. In the policy table, +multiple match patterns and strategies must be separated by colons. +In practice explicit control over matching is more common with the +"secure" policy, described below. The optional "ciphers", "exclude", +and "protocols" attributes (Postfix ≥ 2.6) override the +"smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and +"smtp_tls_mandatory_protocols" configuration parameters. The optional +"connection_reuse" attribute (Postfix ≥ 3.4) overrides the main.cf +smtp_tls_connection_reuse parameter. </dd> + +<dt><b><a href="TLS_README.html#client_tls_secure">secure</a></b></dt> +<dd>Secure-channel TLS. At this security level, DNS +MX lookups, though potentially used to determine the candidate next-hop +gateway IP addresses, are <b>not</b> trusted to be secure enough for TLS +peername verification. Instead, the default name verified in the server +certificate is obtained directly from the next-hop, or is explicitly +specified via the optional "match" attribute which overrides the +main.cf smtp_tls_secure_cert_match parameter. In the policy table, +multiple match patterns and strategies must be separated by colons. +The match attribute is most useful when multiple domains are supported by +a common server: the policy entries for additional domains specify matching +rules for the primary domain certificate. While transport table overrides +that route the secondary domains to the primary nexthop also allow secure +verification, they risk delivery to the wrong destination when domains +change hands or are re-assigned to new gateways. With the "match" +attribute approach, routing is not perturbed, and mail is deferred if +verification of a new MX host fails. The optional "ciphers", "exclude", +and "protocols" attributes (Postfix ≥ 2.6) override the +"smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and +"smtp_tls_mandatory_protocols" configuration parameters. The optional +"connection_reuse" attribute (Postfix ≥ 3.4) overrides the main.cf +smtp_tls_connection_reuse parameter. </dd> + +</dl> + +<p> +Example: +</p> + +<pre> +/etc/postfix/main.cf: + smtp_tls_policy_maps = hash:/etc/postfix/tls_policy + # Postfix 2.5 and later. + # + # The default digest is sha256 with Postfix ≥ 3.6 and + # compatibility level ≥ 3. + # + smtp_tls_fingerprint_digest = sha256 +</pre> + +<pre> +/etc/postfix/tls_policy: + example.edu none + example.mil may + example.gov encrypt protocols=TLSv1 + example.com verify ciphers=high + example.net secure + .example.net secure match=.example.net:example.net + [mail.example.org]:587 secure match=nexthop + # Postfix 2.5 and later + [thumb.example.org] fingerprint + match=b6:b4:72:34:e2:59:cd:...:c2:ca:63:0d:4d:cc:2c:7d:84:de:e6:2f + match=51:e9:af:2e:1e:40:1f:...:64:0a:30:35:2d:09:16:31:5a:eb:82:76 +</pre> + +<p> <b>Note:</b> The "hostname" strategy if listed in a non-default +setting of smtp_tls_secure_cert_match or in the "match" attribute +in the policy table can render the "secure" level vulnerable to +DNS forgery. Do not use the "hostname" strategy for secure-channel +configurations in environments where DNS security is not assured. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtp_tls_mandatory_protocols see "postconf -d" output + +<p> TLS protocols that the Postfix SMTP client will use with mandatory +TLS encryption. In main.cf the values are separated by whitespace, +commas or colons. In the policy table "protocols" attribute (see +smtp_tls_policy_maps) the only valid separator is colon. An empty value +means allow all protocols. </p> + +<p> The valid protocol names (see SSL_get_version(3)) are "SSLv2", +"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" and "TLSv1.3". Starting with +Postfix 3.6, the default value is ">=TLSv1", which sets TLS 1.0 as +the lowest supported TLS protocol version (see below). Older releases +use the "!" exclusion syntax, also described below. </p> + +<p> As of Postfix 3.6, the preferred way to limit the range of +acceptable protocols is to set a lowest acceptable TLS protocol version +and/or a highest acceptable TLS protocol version. To set the lower +bound include an element of the form: ">=<i>version</i>" where +<i>version</i> is a either one of the TLS protocol names listed above, +or a hexadecimal number corresponding to the desired TLS protocol +version (0301 for TLS 1.0, 0302 for TLS 1.1, etc.). For the upper +bound, use "<=<i>version</i>". There must be no whitespace between +the ">=" or "<=" symbols and the protocol name or number. </p> + +<p> Hexadecimal protocol numbers make it possible to specify protocol +bounds for TLS versions that are known to OpenSSL, but might not be +known to Postfix. They cannot be used with the legacy exclusion syntax. +Leading "0" or "0x" prefixes are supported, but not required. +Therefore, "301", "0301", "0x301" and "0x0301" are all equivalent to +"TLSv1". Hexadecimal versions unknown to OpenSSL will fail to set the +upper or lower bound, and a warning will be logged. Hexadecimal +versions should only be used when Postfix is linked with some future +version of OpenSSL that supports TLS 1.4 or later, but Postfix does not +yet support a symbolic name for that protocol version. </p> + +<p>Hexadecimal example (Postfix ≥ 3.6):</p> +<blockquote> +<pre> +# Allow only TLS 1.2 through (hypothetical) TLS 1.4, once supported +# in some future version of OpenSSL (presently a warning is logged). +smtp_tls_mandatory_protocols = >=TLSv1.2, <=0305 +# Allow only TLS 1.2 and up: +smtp_tls_mandatory_protocols = >=0x0303 +</pre> +</blockquote> + +<p> With Postfix < 3.6 there is no support for a minimum or maximum +version, and the protocol range is configured via protocol exclusions. +To require at least TLS 1.0, set "smtp_tls_mandatory_protocols = !SSLv2, +!SSLv3". Listing the protocols to include, rather than the protocols to +exclude, is supported, but not recommended. The exclusion syntax more +accurately matches the underlying OpenSSL interface. </p> + +<p> When using the exclusion syntax, take care to ensure that the range +of protocols supported by the Postfix SMTP client is contiguous. When +a protocol version is enabled, disabling any higher version implicitly +disables all versions above that higher version. Thus, for example: </p> + +<blockquote> +<pre> +smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1.1 +</pre> +</blockquote> + +<p> also disables any protocol versions higher than TLSv1.1 leaving +only "TLSv1" enabled. </p> + +<p> Support for "TLSv1.3" was introduced in OpenSSL 1.1.1. Disabling +this protocol via "!TLSv1.3" is supported since Postfix 3.4 (or patch +releases ≥ 3.0.14, 3.1.10, 3.2.7 and 3.3.2). </p> + +<p> While the vast majority of SMTP servers with DANE TLSA records now +support at least TLS 1.2, a few still only support TLS 1.0. If you use +"dane" or "dane-only" it is best not to disable TLSv1, except perhaps +via the policy table for destinations which you are sure will support +"TLSv1.2". </p> + +<p> See the documentation of the smtp_tls_policy_maps parameter and +TLS_README for more information about security levels. </p> + +<p> Example: </p> +<pre> +# Preferred syntax with Postfix ≥ 3.6: +smtp_tls_mandatory_protocols = >=TLSv1.2, <=TLSv1.3 +# Legacy syntax: +smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 +</pre> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtp_tls_verify_cert_match hostname + +<p> How the Postfix SMTP client verifies the server certificate +peername for the +"verify" TLS security level. In a "verify" TLS policy table +($smtp_tls_policy_maps) entry the optional "match" attribute +overrides this main.cf setting. </p> + +<p> This parameter specifies one or more patterns or strategies separated +by commas, whitespace or colons. In the policy table the only valid +separator is the colon character. </p> + +<p> Patterns specify domain names, or domain name suffixes: </p> + +<dl> + +<dt><i>example.com</i></dt> <dd> Match the <i>example.com</i> domain, +i.e. one of the names in the server certificate must be <i>example.com</i>. +Upper and lower case distinctions are ignored. </dd> + +<dt><i>.example.com</i></dt> +<dd> Match subdomains of the <i>example.com</i> domain, i.e. match +a name in the server certificate that consists of a non-zero number of +labels followed by a <i>.example.com</i> suffix. Case distinctions are +ignored.</dd> + +</dl> + +<p> Strategies specify a transformation from the next-hop domain +to the expected name in the server certificate: </p> + +<dl> + +<dt>nexthop</dt> +<dd> Match against the next-hop domain, which is either the recipient +domain, or the transport next-hop configured for the domain stripped of +any optional socket type prefix, enclosing square brackets and trailing +port. When MX lookups are not suppressed, this is the original nexthop +domain prior to the MX lookup, not the result of the MX lookup. For +LMTP delivery via UNIX-domain sockets, the verified next-hop name is +$myhostname. This strategy is suitable for use with the "secure" +policy. Case is ignored.</dd> + +<dt>dot-nexthop</dt> +<dd> As above, but match server certificate names that are subdomains +of the next-hop domain. Case is ignored.</dd> + +<dt>hostname</dt> <dd> Match against the hostname of the server, often +obtained via an unauthenticated DNS MX lookup. For LMTP delivery via +UNIX-domain sockets, the verified name is $myhostname. This matches +the verification strategy of the "MUST" keyword in the obsolete +smtp_tls_per_site table, and is suitable for use with the "verify" +security level. When the next-hop name is enclosed in square brackets +to suppress MX lookups, the "hostname" strategy is the same as the +"nexthop" strategy. Case is ignored.</dd> + +</dl> + +<p> +Sample main.cf setting: +</p> + +<pre> +smtp_tls_verify_cert_match = hostname, nexthop, dot-nexthop +</pre> + +<p> +Sample policy table override: +</p> + +<pre> +example.com verify match=hostname:nexthop +.example.com verify match=example.com:.example.com:hostname +</pre> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtp_tls_secure_cert_match nexthop, dot-nexthop + +<p> How the Postfix SMTP client verifies the server certificate +peername for the "secure" TLS security level. In a "secure" TLS policy table +($smtp_tls_policy_maps) entry the optional "match" attribute +overrides this main.cf setting. </p> + +<p> This parameter specifies one or more patterns or strategies separated +by commas, whitespace or colons. In the policy table the only valid +separator is the colon character. </p> + +<p> For a description of the pattern and strategy syntax see the +smtp_tls_verify_cert_match parameter. The "hostname" strategy should +be avoided in this context, as in the absence of a secure global DNS, using +the results of MX lookups in certificate verification is not immune to active +(man-in-the-middle) attacks on DNS. </p> + +<p> +Sample main.cf setting: +</p> + +<blockquote> +<pre> +smtp_tls_secure_cert_match = nexthop +</pre> +</blockquote> + +<p> +Sample policy table override: +</p> + +<blockquote> +<pre> +example.net secure match=example.com:.example.com +.example.net secure match=example.com:.example.com +</pre> +</blockquote> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_policy_maps + +<p> The LMTP-specific version of the smtp_tls_policy_maps +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_mandatory_protocols see postconf -d output + +<p> The LMTP-specific version of the smtp_tls_mandatory_protocols +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_verify_cert_match hostname + +<p> The LMTP-specific version of the smtp_tls_verify_cert_match +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_secure_cert_match nexthop + +<p> The LMTP-specific version of the smtp_tls_secure_cert_match +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtpd_tls_mandatory_protocols see "postconf -d" output + +<p> TLS protocols accepted by the Postfix SMTP server with mandatory TLS +encryption. If the list is empty, the server supports all available TLS +protocol versions. A non-empty value is a list of protocol names to +include or exclude, separated by whitespace, commas or colons. </p> + +<p> The valid protocol names (see SSL_get_version(3)) are "SSLv2", +"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" and "TLSv1.3". Starting with +Postfix 3.6, the default value is ">=TLSv1", which sets TLS 1.0 as +the lowest supported TLS protocol version (see below). Older releases +use the "!" exclusion syntax, also described below. </p> + +<p> As of Postfix 3.6, the preferred way to limit the range of +acceptable protocols is to set the lowest acceptable TLS protocol +version and/or the highest acceptable TLS protocol version. To set the +lower bound include an element of the form: ">=<i>version</i>" where +<i>version</i> is a either one of the TLS protocol names listed above, +or a hexadecimal number corresponding to the desired TLS protocol +version (0301 for TLS 1.0, 0302 for TLS 1.1, etc.). For the upper +bound, use "<=<i>version</i>". There must be no whitespace between +the ">=" or "<=" symbols and the protocol name or number. </p> + +<p> Hexadecimal protocol numbers make it possible to specify protocol +bounds for TLS versions that are known to OpenSSL, but might not be +known to Postfix. They cannot be used with the legacy exclusion syntax. +Leading "0" or "0x" prefixes are supported, but not required. +Therefore, "301", "0301", "0x301" and "0x0301" are all equivalent to +"TLSv1". Hexadecimal versions unknown to OpenSSL will fail to set the +upper or lower bound, and a warning will be logged. Hexadecimal +versions should only be used when Postfix is linked with some future +version of OpenSSL that supports TLS 1.4 or later, but Postfix does not +yet support a symbolic name for that protocol version. </p> + +<p>Hexadecimal example (Postfix ≥ 3.6):</p> +<blockquote> +<pre> +# Allow only TLS 1.2 through (hypothetical) TLS 1.4, once supported +# in some future version of OpenSSL (presently a warning is logged). +smtpd_tls_mandatory_protocols = >=TLSv1.2, <=0305 +# Allow only TLS 1.2 and up: +smtpd_tls_mandatory_protocols = >=0x0303 +</pre> +</blockquote> + +<p> With Postfix < 3.6 there is no support for a minimum or maximum +version, and the protocol range is configured via protocol exclusions. +To require at least TLS 1.0, set "smtpd_tls_mandatory_protocols = +!SSLv2, !SSLv3". Listing the protocols to include, rather than +protocols to exclude, is supported, but not recommended. The exclusion +form more accurately matches the underlying OpenSSL interface. </p> + +<p> Support for "TLSv1.3" was introduced in OpenSSL 1.1.1. Disabling +this protocol via "!TLSv1.3" is supported since Postfix 3.4 (or patch +releases ≥ 3.0.14, 3.1.10, 3.2.7 and 3.3.2). </p> + +<p> Example: </p> + +<pre> +# Preferred syntax with Postfix ≥ 3.6: +smtpd_tls_mandatory_protocols = >=TLSv1.2, <=TLSv1.3 +# Legacy syntax: +smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 +</pre> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtp_tls_security_level + +<p> The default SMTP TLS security level for the Postfix SMTP client. +When a non-empty value is specified, this overrides the obsolete +parameters smtp_use_tls, smtp_enforce_tls, and smtp_tls_enforce_peername; +when no value is specified for smtp_tls_enforce_peername or the obsolete +parameters, the default SMTP TLS security level is +<a href="TLS_README.html#client_tls_none">none</a>. </p> + +<p> Specify one of the following security levels: </p> + +<dl> + +<dt><b><a href="TLS_README.html#client_tls_none">none</a></b></dt> +<dd> No TLS. TLS will not be used unless enabled for specific +destinations via smtp_tls_policy_maps. </dd> + +<dt><b><a href="TLS_README.html#client_tls_may">may</a></b></dt> +<dd> Opportunistic TLS. Use TLS if this is supported by the remote +SMTP server, otherwise use plaintext. Since +sending in the clear is acceptable, demanding stronger than default TLS +security merely reduces interoperability. +The "smtp_tls_ciphers" and "smtp_tls_protocols" (Postfix ≥ 2.6) +configuration parameters provide control over the protocols and +cipher grade used with opportunistic TLS. With earlier releases the +opportunistic TLS cipher grade is always "export" and no protocols +are disabled. +When TLS handshakes fail, the connection is retried with TLS disabled. +This allows mail delivery to sites with non-interoperable TLS +implementations. </dd> + +<dt><b><a href="TLS_README.html#client_tls_encrypt">encrypt</a></b></dt> +<dd>Mandatory TLS encryption. Since a minimum +level of security is intended, it is reasonable to be specific about +sufficiently secure protocol versions and ciphers. At this security level +and higher, the main.cf parameters smtp_tls_mandatory_protocols and +smtp_tls_mandatory_ciphers specify the TLS protocols and minimum +cipher grade which the administrator considers secure enough for +mandatory encrypted sessions. This security level is not an appropriate +default for systems delivering mail to the Internet. </dd> + +<dt><b><a href="TLS_README.html#client_tls_dane">dane</a></b></dt> +<dd>Opportunistic DANE TLS. At this security level, the TLS policy +for the destination is obtained via DNSSEC. For TLSA policy to be +in effect, the destination domain's containing DNS zone must be +signed and the Postfix SMTP client's operating system must be +configured to send its DNS queries to a recursive DNS nameserver +that is able to validate the signed records. Each MX host's DNS +zone should also be signed, and should publish DANE TLSA (RFC 7672) +records that specify how that MX host's TLS certificate is to be +verified. TLSA records do not preempt the normal SMTP MX host +selection algorithm, if some MX hosts support TLSA and others do +not, TLS security will vary from delivery to delivery. It is up +to the domain owner to configure their MX hosts and their DNS +sensibly. To configure the Postfix SMTP client for DNSSEC lookups +see the documentation for the smtp_dns_support_level main.cf +parameter. When DNSSEC-validated TLSA records are not found the +effective tls security level is "may". When TLSA records are found, +but are all unusable the effective security level is "encrypt". For +purposes of protocol and cipher selection, the "dane" security level +is treated like a "mandatory" TLS security level, and weak ciphers +and protocols are disabled. Since DANE authenticates server +certificates the "aNULL" cipher-suites are transparently excluded +at this level, no need to configure this manually. RFC 7672 (DANE) +TLS authentication is available with Postfix 2.11 and later. </dd> + +<dt><b><a href="TLS_README.html#client_tls_dane">dane-only</a></b></dt> +<dd>Mandatory DANE TLS. This is just like "dane" above, but DANE +TLSA authentication is required. There is no fallback to "may" or +"encrypt" when TLSA records are missing or unusable. RFC 7672 +(DANE) TLS authentication is available with Postfix 2.11 and later. +</dd> + +<dt><b><a href="TLS_README.html#client_tls_fprint">fingerprint</a></b></dt> +<dd>Certificate fingerprint verification. +At this security level, there are no trusted Certification Authorities. +The certificate trust chain, expiration date, etc., are +not checked. Instead, the <b>smtp_tls_fingerprint_cert_match</b> +parameter lists the certificate fingerprint or public key fingerprint +(Postfix 2.9 and later) of the valid server certificate. The digest +algorithm used to calculate the fingerprint is selected by the +<b>smtp_tls_fingerprint_digest</b> parameter. Available with Postfix +2.5 and later. </dd> + +<dt><b><a href="TLS_README.html#client_tls_verify">verify</a></b></dt> +<dd>Mandatory TLS verification. At this security +level, DNS MX lookups are trusted to be secure enough, and the name +verified in the server certificate is usually obtained indirectly +via unauthenticated DNS MX lookups. The smtp_tls_verify_cert_match +parameter controls how the server name is verified. In practice explicit +control over matching is more common at the "secure" level, described +below. This security level is not an appropriate default for systems +delivering mail to the Internet. </dd> + +<dt><b><a href="TLS_README.html#client_tls_secure">secure</a></b></dt> +<dd>Secure-channel TLS. At this security level, +DNS MX lookups, though potentially used to determine the candidate +next-hop gateway IP addresses, are <b>not</b> trusted to be secure enough +for TLS peername verification. Instead, the default name verified in +the server certificate is obtained from the next-hop domain as specified +in the smtp_tls_secure_cert_match configuration parameter. The default +matching rule is that a server certificate matches when its name is equal +to or is a sub-domain of the nexthop domain. This security level is not +an appropriate default for systems delivering mail to the Internet. </dd> + +</dl> + +<p> +Examples: +</p> + +<pre> +# No TLS. Formerly: smtp_use_tls=no and smtp_enforce_tls=no. +smtp_tls_security_level = none +</pre> + +<pre> +# Opportunistic TLS. +smtp_tls_security_level = may +# Do not tweak opportunistic ciphers or protocols unless it is essential +# to do so (if a security vulnerability is found in the SSL library that +# can be mitigated by disabling a particular protocol or raising the +# cipher grade). +smtp_tls_ciphers = medium +smtp_tls_protocols = >=TLSv1 +# Legacy (Postfix < 3.6) syntax: +smtp_tls_protocols = !SSLv2, !SSLv3 +</pre> + +<pre> +# Mandatory (high-grade) TLS encryption. +smtp_tls_security_level = encrypt +smtp_tls_mandatory_ciphers = high +</pre> + +<pre> +# Authenticated TLS 1.2 or better matching the nexthop domain or a +# subdomain. +smtp_tls_security_level = secure +smtp_tls_mandatory_ciphers = high +smtp_tls_mandatory_protocols = >=TLSv1.2 +smtp_tls_secure_cert_match = nexthop, dot-nexthop +</pre> + +<pre> +# Certificate fingerprint verification (Postfix ≥ 2.5). +# The CA-less "fingerprint" security level only scales to a limited +# number of destinations. As a global default rather than a per-site +# setting, this is practical only when mail for all recipients is sent +# to a central mail hub. +relayhost = [mailhub.example.com] +smtp_tls_security_level = fingerprint +smtp_tls_mandatory_protocols = >=TLSv1.2 +smtp_tls_mandatory_ciphers = high +smtp_tls_fingerprint_cert_match = + 3D:95:34:51:...:40:99:C0:C1 + EC:3B:2D:B0:...:A3:9D:72:F6 +</pre> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtpd_milters + +<p> A list of Milter (mail filter) applications for new mail that +arrives via the Postfix smtpd(8) server. Specify space or comma as +separator. See the MILTER_README document for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM non_smtpd_milters + +<p> A list of Milter (mail filter) applications for new mail that +does not arrive via the Postfix smtpd(8) server. This includes local +submission via the sendmail(1) command line, new mail that arrives +via the Postfix qmqpd(8) server, and old mail that is re-injected +into the queue with "postsuper -r". Specify space or comma as a +separator. See the MILTER_README document for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM milter_protocol 6 + +<p> The mail filter protocol version and optional protocol extensions +for communication with a Milter application; prior to Postfix 2.6 +the default protocol is 2. Postfix +sends this version number during the initial protocol handshake. +It should match the version number that is expected by the mail +filter application (or by its Milter library). </p> + +<p>Protocol versions: </p> + +<dl compact> + +<dt>2</dt> <dd>Use Sendmail 8 mail filter protocol version 2 (default +with Sendmail version 8.11 .. 8.13 and Postfix version 2.3 .. +2.5).</dd> + +<dt>3</dt> <dd>Use Sendmail 8 mail filter protocol version 3.</dd> + +<dt>4</dt> <dd>Use Sendmail 8 mail filter protocol version 4.</dd> + +<dt>6</dt> <dd>Use Sendmail 8 mail filter protocol version 6 (default +with Sendmail version 8.14 and Postfix version 2.6).</dd> + +</dl> + +<p>Protocol extensions: </p> + +<dl compact> + +<dt>no_header_reply</dt> <dd> Specify this when the Milter application +will not reply for each individual message header.</dd> + +</dl> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM milter_default_action tempfail + +<p> The default action when a Milter (mail filter) response is +unavailable (for example, bad Postfix configuration or Milter +failure). Specify one of the following: </p> + +<dl compact> + +<dt>accept</dt> <dd>Proceed as if the mail filter was not present. +</dd> + +<dt>reject</dt> <dd>Reject all further commands in this session +with a permanent status code.</dd> + +<dt>tempfail</dt> <dd>Reject all further commands in this session +with a temporary status code. </dd> + +<dt>quarantine</dt> <dd>Like "accept", but freeze the message in +the "hold" queue. Available with Postfix 2.6 and later. </dd> + +</dl> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM milter_connect_timeout 30s + +<p> The time limit for connecting to a Milter (mail filter) +application, and for negotiating protocol options. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM milter_command_timeout 30s + +<p> The time limit for sending an SMTP command to a Milter (mail +filter) application, and for receiving the response. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM milter_content_timeout 300s + +<p> The time limit for sending message content to a Milter (mail +filter) application, and for receiving the response. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM milter_connect_macros see "postconf -d" output + +<p> The macros that are sent to Milter (mail filter) applications +after completion of an SMTP connection. See MILTER_README +for a list of available macro names and their meanings. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM milter_helo_macros see "postconf -d" output + +<p> The macros that are sent to Milter (mail filter) applications +after the SMTP HELO or EHLO command. See +MILTER_README for a list of available macro names and their meanings. +</p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM milter_mail_macros see "postconf -d" output + +<p> The macros that are sent to Milter (mail filter) applications +after the SMTP MAIL FROM command. See MILTER_README +for a list of available macro names and their meanings. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM milter_rcpt_macros see "postconf -d" output + +<p> The macros that are sent to Milter (mail filter) applications +after the SMTP RCPT TO command. See MILTER_README +for a list of available macro names and their meanings. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM milter_data_macros see "postconf -d" output + +<p> The macros that are sent to version 4 or higher Milter (mail +filter) applications after the SMTP DATA command. See MILTER_README +for a list of available macro names and their meanings. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM milter_end_of_header_macros see "postconf -d" output + +<p> The macros that are sent to Milter (mail filter) applications +after the end of the message header. See MILTER_README for a list +of available macro names and their meanings. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM milter_end_of_data_macros see "postconf -d" output + +<p> The macros that are sent to Milter (mail filter) applications +after the message end-of-data. See MILTER_README for a list of +available macro names and their meanings. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM milter_unknown_command_macros see "postconf -d" output + +<p> The macros that are sent to version 3 or higher Milter (mail +filter) applications after an unknown SMTP command. See MILTER_README +for a list of available macro names and their meanings. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM milter_macro_daemon_name $myhostname + +<p> The {daemon_name} macro value for Milter (mail filter) applications. +See MILTER_README for a list of available macro names and their +meanings. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM milter_macro_defaults + +<p> Optional list of <i>name=value</i> pairs that specify default +values for arbitrary macros that Postfix may send to Milter +applications. These defaults are used when there is no corresponding +information from the message delivery context. </p> + +<p> Specify <i>name=value</i> or <i>{name=value}</i> pairs separated +by comma or whitespace. Enclose a pair in "{}" when a value contains +comma or whitespace (this form ignores whitespace after the enclosing +"{", around the "=", and before the enclosing "}"). </p> + +<p> This feature is available in Postfix 3.1 and later. </p> + +%PARAM milter_macro_v $mail_name $mail_version + +<p> The {v} macro value for Milter (mail filter) applications. +See MILTER_README for a list of available macro names and their +meanings. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtpd_tls_mandatory_ciphers medium + +<p> The minimum TLS cipher grade that the Postfix SMTP server will +use with mandatory TLS encryption. The default grade ("medium") is +sufficiently strong that any benefit from globally restricting TLS +sessions to a more stringent grade is likely negligible, especially +given the fact that many implementations still do not offer any stronger +("high" grade) ciphers, while those that do, will always use "high" +grade ciphers. So insisting on "high" grade ciphers is generally +counter-productive. Allowing "export" or "low" ciphers is typically +not a good idea, as systems limited to just these are limited to +obsolete browsers. No known SMTP clients fail to support at least +one "medium" or "high" grade cipher. </p> + +<p> The following cipher grades are supported: </p> + +<dl> +<dt><b>export</b></dt> +<dd> Enable "EXPORT" grade or stronger OpenSSL ciphers. The +underlying cipherlist is specified via the tls_export_cipherlist +configuration parameter, which you are strongly encouraged not to +change. This choice is insecure and SHOULD NOT be used. </dd> + +<dt><b>low</b></dt> +<dd> Enable "LOW" grade or stronger OpenSSL ciphers. The underlying +cipherlist is specified via the tls_low_cipherlist configuration +parameter, which you are strongly encouraged not to change. This +choice is insecure and SHOULD NOT be used. </dd> + +<dt><b>medium</b></dt> +<dd> Enable "MEDIUM" grade or stronger OpenSSL ciphers. These use 128-bit +or longer symmetric bulk-encryption keys. This is the default minimum +strength for mandatory TLS encryption. The underlying cipherlist is +specified via the tls_medium_cipherlist configuration parameter, which +you are strongly encouraged not to change. </dd> + +<dt><b>high</b></dt> +<dd> Enable only "HIGH" grade OpenSSL ciphers. The +underlying cipherlist is specified via the tls_high_cipherlist +configuration parameter, which you are strongly encouraged to +not change. </dd> + +<dt><b>null</b></dt> +<dd> Enable only the "NULL" OpenSSL ciphers, these provide authentication +without encryption. This setting is only appropriate in the rare +case that all clients are prepared to use NULL ciphers (not normally +enabled in TLS clients). The underlying cipherlist is specified via the +tls_null_cipherlist configuration parameter, which you are strongly +encouraged not to change. </dd> + +</dl> + +<p> Cipher types listed in +smtpd_tls_mandatory_exclude_ciphers or smtpd_tls_exclude_ciphers are +excluded from the base definition of the selected cipher grade. See +smtpd_tls_ciphers for cipher controls that apply to opportunistic +TLS. </p> + +<p> The underlying cipherlists for grades other than "null" include +anonymous ciphers, but these are automatically filtered out if the +server is configured to ask for remote SMTP client certificates. You are very +unlikely to need to take any steps to exclude anonymous ciphers, they +are excluded automatically as required. If you must exclude anonymous +ciphers even when Postfix does not need or use peer certificates, set +"smtpd_tls_exclude_ciphers = aNULL". To exclude anonymous ciphers only +when TLS is enforced, set "smtpd_tls_mandatory_exclude_ciphers = aNULL". </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtpd_tls_exclude_ciphers + +<p> List of ciphers or cipher types to exclude from the SMTP server +cipher list at all TLS security levels. Excluding valid ciphers +can create interoperability problems. DO NOT exclude ciphers unless it +is essential to do so. This is not an OpenSSL cipherlist; it is a simple +list separated by whitespace and/or commas. The elements are a single +cipher, or one or more "+" separated cipher properties, in which case +only ciphers matching <b>all</b> the properties are excluded. </p> + +<p> Examples (some of these will cause problems): </p> + +<blockquote> +<pre> +smtpd_tls_exclude_ciphers = aNULL +smtpd_tls_exclude_ciphers = MD5, DES +smtpd_tls_exclude_ciphers = DES+MD5 +smtpd_tls_exclude_ciphers = AES256-SHA, DES-CBC3-MD5 +smtpd_tls_exclude_ciphers = kEDH+aRSA +</pre> +</blockquote> + +<p> The first setting disables anonymous ciphers. The next setting +disables ciphers that use the MD5 digest algorithm or the (single) DES +encryption algorithm. The next setting disables ciphers that use MD5 and +DES together. The next setting disables the two ciphers "AES256-SHA" +and "DES-CBC3-MD5". The last setting disables ciphers that use "EDH" +key exchange with RSA authentication. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtpd_tls_mandatory_exclude_ciphers + +<p> Additional list of ciphers or cipher types to exclude from the +Postfix SMTP server cipher list at mandatory TLS security levels. +This list +works in addition to the exclusions listed with smtpd_tls_exclude_ciphers +(see there for syntax details). </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtp_tls_mandatory_ciphers medium + +<p> The minimum TLS cipher grade that the Postfix SMTP client will +use with +mandatory TLS encryption. The default value "medium" is suitable +for most destinations with which you may want to enforce TLS, and +is beyond the reach of today's cryptanalytic methods. See +smtp_tls_policy_maps for information on how to configure ciphers +on a per-destination basis. </p> + +<p> The following cipher grades are supported: </p> + +<dl> +<dt><b>export</b></dt> +<dd> Enable "EXPORT" grade or better OpenSSL ciphers. The underlying +cipherlist is specified via the tls_export_cipherlist configuration +parameter, which you are strongly encouraged not to change. This +choice is insecure and SHOULD NOT be used. </dd> + +<dt><b>low</b></dt> +<dd> Enable "LOW" grade or better OpenSSL ciphers. The underlying +cipherlist is specified via the tls_low_cipherlist configuration +parameter, which you are strongly encouraged not to change. This +choice is insecure and SHOULD NOT be used. </dd> + +<dt><b>medium</b></dt> +<dd> Enable "MEDIUM" grade or better OpenSSL ciphers. +The underlying cipherlist is specified via the tls_medium_cipherlist +configuration parameter, which you are strongly encouraged not to change. +</dd> + +<dt><b>high</b></dt> +<dd> Enable only "HIGH" grade OpenSSL ciphers. This setting may +be appropriate when all mandatory TLS destinations (e.g. when all +mail is routed to a suitably capable relayhost) support at least one +"HIGH" grade cipher. The underlying cipherlist is specified via the +tls_high_cipherlist configuration parameter, which you are strongly +encouraged not to change. </dd> + +<dt><b>null</b></dt> +<dd> Enable only the "NULL" OpenSSL ciphers, these provide authentication +without encryption. This setting is only appropriate in the rare case +that all servers are prepared to use NULL ciphers (not normally enabled +in TLS servers). A plausible use-case is an LMTP server listening on a +UNIX-domain socket that is configured to support "NULL" ciphers. The +underlying cipherlist is specified via the tls_null_cipherlist +configuration parameter, which you are strongly encouraged not to +change. </dd> + +</dl> + +<p> The underlying cipherlists for grades other than "null" include +anonymous ciphers, but these are automatically filtered out if the +Postfix SMTP client is configured to verify server certificates. +You are very unlikely to need to take any steps to exclude anonymous +ciphers, they are excluded automatically as necessary. If you must +exclude anonymous ciphers at the "may" or "encrypt" security levels, +when the Postfix SMTP client does not need or use peer certificates, set +"smtp_tls_exclude_ciphers = aNULL". To exclude anonymous ciphers only when +TLS is enforced, set "smtp_tls_mandatory_exclude_ciphers = aNULL". </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtp_tls_exclude_ciphers + +<p> List of ciphers or cipher types to exclude from the Postfix +SMTP client cipher +list at all TLS security levels. This is not an OpenSSL cipherlist, it is +a simple list separated by whitespace and/or commas. The elements are a +single cipher, or one or more "+" separated cipher properties, in which +case only ciphers matching <b>all</b> the properties are excluded. </p> + +<p> Examples (some of these will cause problems): </p> + +<blockquote> +<pre> +smtp_tls_exclude_ciphers = aNULL +smtp_tls_exclude_ciphers = MD5, DES +smtp_tls_exclude_ciphers = DES+MD5 +smtp_tls_exclude_ciphers = AES256-SHA, DES-CBC3-MD5 +smtp_tls_exclude_ciphers = kEDH+aRSA +</pre> +</blockquote> + +<p> The first setting disables anonymous ciphers. The next setting +disables ciphers that use the MD5 digest algorithm or the (single) DES +encryption algorithm. The next setting disables ciphers that use MD5 and +DES together. The next setting disables the two ciphers "AES256-SHA" +and "DES-CBC3-MD5". The last setting disables ciphers that use "EDH" +key exchange with RSA authentication. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtp_tls_mandatory_exclude_ciphers + +<p> Additional list of ciphers or cipher types to exclude from the +Postfix SMTP client cipher list at mandatory TLS security levels. This list +works in addition to the exclusions listed with smtp_tls_exclude_ciphers +(see there for syntax details). </p> + +<p> Starting with Postfix 2.6, the mandatory cipher exclusions can be +specified on a per-destination basis via the TLS policy "exclude" +attribute. See smtp_tls_policy_maps for notes and examples. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM tls_high_cipherlist see "postconf -d" output + +<p> The OpenSSL cipherlist for "high" grade ciphers. This defines +the meaning of the "high" setting in smtpd_tls_ciphers, +smtpd_tls_mandatory_ciphers, smtp_tls_ciphers, smtp_tls_mandatory_ciphers, +lmtp_tls_ciphers, and lmtp_tls_mandatory_ciphers. You are strongly +encouraged not to change this setting. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM tls_medium_cipherlist see "postconf -d" output + +<p> The OpenSSL cipherlist for "medium" or higher grade ciphers. This +defines the meaning of the "medium" setting in smtpd_tls_ciphers, +smtpd_tls_mandatory_ciphers, smtp_tls_ciphers, smtp_tls_mandatory_ciphers, +lmtp_tls_ciphers, and lmtp_tls_mandatory_ciphers. This is the +default cipherlist for mandatory TLS encryption in the TLS client +(with anonymous ciphers disabled when verifying server certificates). +This is the default cipherlist for opportunistic TLS with Postfix +releases after the middle of 2015. You are strongly encouraged not +to change this setting. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM tls_low_cipherlist see "postconf -d" output + +<p> The OpenSSL cipherlist for "low" or higher grade ciphers. This defines +the meaning of the "low" setting in smtpd_tls_ciphers, +smtpd_tls_mandatory_ciphers, smtp_tls_ciphers, smtp_tls_mandatory_ciphers, +lmtp_tls_ciphers, and lmtp_tls_mandatory_ciphers. You are strongly +encouraged not to change this setting. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM tls_export_cipherlist see "postconf -d" output + +<p> The OpenSSL cipherlist for "export" or higher grade ciphers. This +defines the meaning of the "export" setting in smtpd_tls_ciphers, +smtpd_tls_mandatory_ciphers, smtp_tls_ciphers, smtp_tls_mandatory_ciphers, +lmtp_tls_ciphers, and lmtp_tls_mandatory_ciphers. With Postfix +releases before the middle of 2015 this is the default cipherlist +for the opportunistic ("may") TLS client security level and also +the default cipherlist for the SMTP server. You are strongly +encouraged not to change this setting. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM tls_null_cipherlist eNULL:!aNULL + +<p> The OpenSSL cipherlist for "NULL" grade ciphers that provide +authentication without encryption. This defines the meaning of the "null" +setting in smtpd_tls_mandatory_ciphers, smtp_tls_mandatory_ciphers and +lmtp_tls_mandatory_ciphers. You are strongly encouraged not to +change this setting. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_mandatory_ciphers medium + +<p> The LMTP-specific version of the smtp_tls_mandatory_ciphers +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_exclude_ciphers + +<p> The LMTP-specific version of the smtp_tls_exclude_ciphers +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM lmtp_tls_mandatory_exclude_ciphers + +<p> The LMTP-specific version of the smtp_tls_mandatory_exclude_ciphers +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtpd_tls_security_level + +<p> The SMTP TLS security level for the Postfix SMTP server; when +a non-empty value is specified, this overrides the obsolete parameters +smtpd_use_tls and smtpd_enforce_tls. This parameter is ignored with +"smtpd_tls_wrappermode = yes". </p> + +<p> Specify one of the following security levels: </p> + +<dl> + +<dt><b>none</b></dt> <dd> TLS will not be used. </dd> + +<dt><b>may</b></dt> <dd> Opportunistic TLS: announce STARTTLS support +to remote SMTP clients, but do not require that clients use TLS encryption. +</dd> + +<dt><b>encrypt</b></dt> <dd>Mandatory TLS encryption: announce +STARTTLS support to remote SMTP clients, and require that clients use TLS +encryption. According to RFC 2487 this MUST NOT be applied in case +of a publicly-referenced SMTP server. Instead, this option should +be used only on dedicated servers. </dd> + +</dl> + +<p> Note 1: the "fingerprint", "verify" and "secure" levels are not +supported here. +The Postfix SMTP server logs a warning and uses "encrypt" instead. +To verify remote SMTP client certificates, see TLS_README for a discussion +of the smtpd_tls_ask_ccert, smtpd_tls_req_ccert, and permit_tls_clientcerts +features. </p> + +<p> Note 2: The parameter setting "smtpd_tls_security_level = +encrypt" implies "smtpd_tls_auth_only = yes".</p> + +<p> Note 3: when invoked via "sendmail -bs", Postfix will never +offer STARTTLS due to insufficient privileges to access the server +private key. This is intended behavior.</p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM internal_mail_filter_classes + +<p> What categories of Postfix-generated mail are subject to +before-queue content inspection by non_smtpd_milters, header_checks +and body_checks. Specify zero or more of the following, separated +by whitespace or comma. </p> + +<dl> + +<dt><b>bounce</b></dt> <dd> Inspect the content of delivery +status notifications. </dd> + +<dt><b>notify</b></dt> <dd> Inspect the content of postmaster +notifications by the smtp(8) and smtpd(8) processes. </dd> + +</dl> + +<p> NOTE: It's generally not safe to enable content inspection of +Postfix-generated email messages. The user is warned. </p> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtpd_tls_always_issue_session_ids yes + +<p> Force the Postfix SMTP server to issue a TLS session id, even +when TLS session caching is turned off (smtpd_tls_session_cache_database +is empty). This behavior is compatible with Postfix < 2.3. </p> + +<p> With Postfix 2.3 and later the Postfix SMTP server can disable +session id generation when TLS session caching is turned off. This +keeps remote SMTP clients from caching sessions that almost certainly cannot +be re-used. </p> + +<p> By default, the Postfix SMTP server always generates TLS session +ids. This works around a known defect in mail client applications +such as MS Outlook, and may also prevent interoperability issues +with other MTAs. </p> + +<p> Example: </p> + +<pre> +smtpd_tls_always_issue_session_ids = no +</pre> + +<p> This feature is available in Postfix 2.3 and later. </p> + +%PARAM smtp_pix_workarounds disable_esmtp, delay_dotcrlf + +<p> A list that specifies zero or more workarounds for CISCO PIX +firewall bugs. These workarounds are implemented by the Postfix +SMTP client. Workaround names are separated by comma or space, and +are case insensitive. This parameter setting can be overruled with +per-destination smtp_pix_workaround_maps settings. </p> + +<dl> + +<dt><b>delay_dotcrlf</b><dd> Insert a delay before sending +".<CR><LF>" after the end of the message content. The +delay is subject to the smtp_pix_workaround_delay_time and +smtp_pix_workaround_threshold_time parameter settings. </dd> + +<dt><b>disable_esmtp</b><dd> Disable all extended SMTP commands: +send HELO instead of EHLO. </dd> + +</dl> + +<p> This feature is available in Postfix 2.4 and later. The default +settings are backwards compatible with earlier Postfix versions. +</p> + +%PARAM smtp_pix_workaround_maps + +<p> Lookup tables, indexed by the remote SMTP server address, with +per-destination workarounds for CISCO PIX firewall bugs. The table +is not indexed by hostname for consistency with +smtp_discard_ehlo_keyword_address_maps. </p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> This feature is available in Postfix 2.4 and later. </p> + +%PARAM lmtp_pix_workarounds + +<p> The LMTP-specific version of the smtp_pix_workaround +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.4 and later. </p> + +%PARAM smtp_tls_fingerprint_digest see "postconf -d" output + +<p> The message digest algorithm used to construct remote SMTP server +certificate fingerprints. At the "fingerprint" TLS security level +(<b>smtp_tls_security_level</b> = fingerprint), the server certificate is +verified by directly matching its certificate fingerprint or its public +key fingerprint (Postfix 2.9 and later). The fingerprint is the +message digest of the server certificate (or its public key) +using the selected +algorithm. With a digest algorithm resistant to "second pre-image" +attacks, it is not feasible to create a new public key and a matching +certificate (or public/private key-pair) that has the same fingerprint. </p> + +<p> The default algorithm is <b>sha256</b> with Postfix ≥ 3.6 +and the <b>compatibility_level</b> set to 3.6 or higher. With Postfix +≤ 3.5, the default algorithm is <b>md5</b>. </p> + +<p> The best-practice algorithm is now <b>sha256</b>. Recent advances in hash +function cryptanalysis have led to md5 and sha1 being deprecated in favor of +sha256. However, as long as there are no known "second pre-image" attacks +against the older algorithms, their use in this context, though not +recommended, is still likely safe. </p> + +<p> While additional digest algorithms are often available with OpenSSL's +libcrypto, only those used by libssl in SSL cipher suites are available to +Postfix. You'll likely find support for md5, sha1, sha256 and sha512. </p> + +<p> To find the fingerprint of a specific certificate file, with a +specific digest algorithm, run: +</p> + +<blockquote> +<pre> +$ openssl x509 -noout -fingerprint -<i>digest</i> -in <i>certfile</i>.pem +</pre> +</blockquote> + +<p> The text to the right of the "=" sign is the desired fingerprint. +For example: </p> + +<blockquote> +<pre> +$ openssl x509 -noout -fingerprint -sha256 -in cert.pem +SHA256 Fingerprint=D4:6A:AB:19:24:...:BB:A6:CB:66:82:C0:8E:9B:EE:29:A8:1A +</pre> +</blockquote> + +<p> To extract the public key fingerprint from an X.509 certificate, +you need to extract the public key from the certificate and compute +the appropriate digest of its DER (ASN.1) encoding. With OpenSSL +the "-pubkey" option of the "x509" command extracts the public +key always in "PEM" format. We pipe the result to another OpenSSL +command that converts the key to DER and then to the "dgst" command +to compute the fingerprint. </p> + +<p> The actual command to transform the key to DER format depends on the +version of OpenSSL used. As of OpenSSL 1.0.0, the "pkey" command supports +all key types. </p> +<blockquote> +<pre> +# OpenSSL ≥ 1.0 with SHA-256 fingerprints. +$ openssl x509 -in cert.pem -noout -pubkey | + openssl pkey -pubin -outform DER | + openssl dgst -sha256 -c +(stdin)= 64:3f:1f:f6:e5:1e:d4:2a:56:...:fc:09:1a:61:98:b5:bc:7c:60:58 +</pre> +</blockquote> + +<p> The Postfix SMTP server and client log the peer (leaf) certificate +fingerprint and the public key fingerprint when the TLS loglevel is 2 or +higher. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM smtp_tls_fingerprint_cert_match + +<p> List of acceptable remote SMTP server certificate fingerprints for +the "fingerprint" TLS security level (<b>smtp_tls_security_level</b> = +fingerprint). At this security level, Certification Authorities are not +used, and certificate expiration times are ignored. Instead, server +certificates are verified directly via their certificate fingerprint +or public key fingerprint (Postfix 2.9 and later). The fingerprint +is a message digest of the server certificate (or public key). The +digest algorithm is selected via the <b>smtp_tls_fingerprint_digest</b> +parameter. </p> + +<p> The colons between each pair of nibbles in the fingerprint value +are optional (Postfix ≥ 3.6). These were required in earlier +Postfix releases. </p> + +<p> When an <b>smtp_tls_policy_maps</b> table entry specifies the +"fingerprint" security level, any "match" attributes in that entry specify +the list of valid fingerprints for the corresponding destination. Multiple +fingerprints can be combined with a "|" delimiter in a single match +attribute, or multiple match attributes can be employed. </p> + +<p> Example: Certificate fingerprint verification with internal mailhub. +Two matching fingerprints are listed. The relayhost may be multiple +physical hosts behind a load-balancer, each with its own private/public +key and self-signed certificate. Alternatively, a single relayhost may +be in the process of switching from one set of private/public keys to +another, and both keys are trusted just prior to the transition. </p> + +<blockquote> +<pre> +relayhost = [mailhub.example.com] +smtp_tls_security_level = fingerprint +smtp_tls_fingerprint_digest = sha256 +smtp_tls_fingerprint_cert_match = + cd:fc:d8:db:f8:c4:82:96:6c:...:28:71:e8:f5:8d:a5:0d:9b:d4:a6 + dd:5c:ef:f5:c3:bc:64:25:36:...:99:36:06:ce:40:ef:de:2e:ad:a4 +</pre> +</blockquote> + +<p> Example: Certificate fingerprint verification with selected destinations. +As in the example above, we show two matching fingerprints: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_policy_maps = hash:/etc/postfix/tls_policy + smtp_tls_fingerprint_digest = sha256 +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/tls_policy: + example.com fingerprint + match=51:e9:af:2e:1e:40:1f:...:64:0a:30:35:2d:09:16:31:5a:eb:82:76 + match=b6:b4:72:34:e2:59:cd:...:c2:ca:63:0d:4d:cc:2c:7d:84:de:e6:2f +</pre> +</blockquote> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM lmtp_tls_fingerprint_cert_match + +<p> The LMTP-specific version of the smtp_tls_fingerprint_cert_match +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM lmtp_tls_fingerprint_digest see "postconf -d" output + +<p> The LMTP-specific version of the smtp_tls_fingerprint_digest +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM smtpd_tls_fingerprint_digest see "postconf -d" output + +<p> The message digest algorithm to construct remote SMTP client-certificate +fingerprints or public key fingerprints (Postfix 2.9 and later) for +<b>check_ccert_access</b> and <b>permit_tls_clientcerts</b>. </p> + +<p> The default algorithm is <b>sha256</b> with Postfix ≥ 3.6 +and the <b>compatibility_level</b> set to 3.6 or higher. With Postfix +≤ 3.5, the default algorithm is <b>md5</b>. </p> + +<p> The best-practice algorithm is now <b>sha256</b>. Recent advances in hash +function cryptanalysis have led to md5 and sha1 being deprecated in favor of +sha256. However, as long as there are no known "second pre-image" attacks +against the older algorithms, their use in this context, though not +recommended, is still likely safe. </p> + +<p> While additional digest algorithms are often available with OpenSSL's +libcrypto, only those used by libssl in SSL cipher suites are available to +Postfix. You'll likely find support for md5, sha1, sha256 and sha512. </p> + +<p> To find the fingerprint of a specific certificate file, with a +specific digest algorithm, run: </p> + +<blockquote> +<pre> +$ openssl x509 -noout -fingerprint -<i>digest</i> -in <i>certfile</i>.pem +</pre> +</blockquote> + +<p> The text to the right of "=" sign is the desired fingerprint. +For example: </p> + +<blockquote> +<pre> +$ openssl x509 -noout -fingerprint -sha256 -in cert.pem +SHA256 Fingerprint=D4:6A:AB:19:24:...:A6:CB:66:82:C0:8E:9B:EE:29:A8:1A +</pre> +</blockquote> + +<p> To extract the public key fingerprint from an X.509 certificate, +you need to extract the public key from the certificate and compute +the appropriate digest of its DER (ASN.1) encoding. With OpenSSL +the "-pubkey" option of the "x509" command extracts the public +key always in "PEM" format. We pipe the result to another OpenSSL +command that converts the key to DER and then to the "dgst" command +to compute the fingerprint. </p> + +<p> Example: </p> +<blockquote> +<pre> +$ openssl x509 -in cert.pem -noout -pubkey | + openssl pkey -pubin -outform DER | + openssl dgst -sha256 -c +(stdin)= 64:3f:1f:f6:e5:1e:d4:2a:56:8b:fc:09:1a:61:98:b5:bc:7c:60:58 +</pre> +</blockquote> + +<p> The Postfix SMTP server and client log the peer (leaf) certificate +fingerprint and public key fingerprint when the TLS loglevel is 2 or +higher. </p> + +<p> Example: client-certificate access table, with sha256 fingerprints: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_fingerprint_digest = sha256 + smtpd_client_restrictions = + check_ccert_access hash:/etc/postfix/access, + reject +</pre> +<pre> +/etc/postfix/access: + # Action folded to next line... + AF:88:7C:AD:51:95:6F:36:96:...:01:FB:2E:48:CD:AB:49:25:A2:3B + OK + 85:16:78:FD:73:6E:CE:70:E0:...:5F:0D:3C:C8:6D:C4:2C:24:59:E1 + permit_auth_destination +</pre> +</blockquote> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM lmtp_pix_workaround_maps + +<p> The LMTP-specific version of the smtp_pix_workaround_maps +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.4 and later. </p> + +%PARAM detect_8bit_encoding_header yes + +<p> Automatically detect 8BITMIME body content by looking at +Content-Transfer-Encoding: message headers; historically, this +behavior was hard-coded to be "always on". </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM send_cyrus_sasl_authzid no + +<p> When authenticating to a remote SMTP or LMTP server with the +default setting "no", send no SASL authoriZation ID (authzid); send +only the SASL authentiCation ID (authcid) plus the authcid's password. +</p> + +<p> The non-default setting "yes" enables the behavior of older +Postfix versions. These always send a SASL authzid that is equal +to the SASL authcid, but this causes interoperability problems +with some SMTP servers. </p> + +<p> This feature is available in Postfix 2.4.4 and later. </p> + +%PARAM smtpd_client_port_logging no + +<p> Enable logging of the remote SMTP client port in addition to +the hostname and IP address. The logging format is "host[address]:port". +</p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM qmqpd_client_port_logging no + +<p> Enable logging of the remote QMQP client port in addition to +the hostname and IP address. The logging format is "host[address]:port". +</p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM smtp_tls_protocols see postconf -d output + +<p> TLS protocols that the Postfix SMTP client will use with +opportunistic TLS encryption. In main.cf the values are separated by +whitespace, commas or colons. In the policy table "protocols" attribute +(see smtp_tls_policy_maps) the only valid separator is colon. An empty +value means allow all protocols. </p> + +<p> The valid protocol names (see SSL_get_version(3)) are "SSLv2", +"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" and "TLSv1.3". Starting with +Postfix 3.6, the default value is ">=TLSv1", which sets TLS 1.0 as +the lowest supported TLS protocol version (see below). Older releases +use the "!" exclusion syntax, also described below. </p> + +<p> As of Postfix 3.6, the preferred way to limit the range of +acceptable protocols is to set the lowest acceptable TLS protocol +version and/or the highest acceptable TLS protocol version. To set the +lower bound include an element of the form: ">=<i>version</i>" where +<i>version</i> is either one of the TLS protocol names listed above, +or a hexadecimal number corresponding to the desired TLS protocol +version (0301 for TLS 1.0, 0302 for TLS 1.1, etc.). For the upper +bound, use "<=<i>version</i>". There must be no whitespace between +the ">=" or "<=" symbols and the protocol name or number. </p> + +<p> Hexadecimal protocol numbers make it possible to specify protocol +bounds for TLS versions that are known to OpenSSL, but might not be +known to Postfix. They cannot be used with the legacy exclusion syntax. +Leading "0" or "0x" prefixes are supported, but not required. +Therefore, "301", "0301", "0x301" and "0x0301" are all equivalent to +"TLSv1". Hexadecimal versions unknown to OpenSSL will fail to set the +upper or lower bound, and a warning will be logged. Hexadecimal +versions should only be used when Postfix is linked with some future +version of OpenSSL that supports TLS 1.4 or later, but Postfix does not +yet support a symbolic name for that protocol version. </p> + +<p>Hexadecimal example (Postfix ≥ 3.6):</p> +<blockquote> +<pre> +# Allow only TLS 1.0 through (hypothetical) TLS 1.4, once supported +# in some future version of OpenSSL (presently a warning is logged). +smtp_tls_protocols = >=TLSv1, <=0305 +# Allow only TLS 1.0 and up: +smtp_tls_protocols = >=0x0301 +</pre> +</blockquote> + +<p> With Postfix < 3.6 there is no support for a minimum or maximum +version, and the protocol range is configured via protocol exclusions. +To require at least TLS 1.0, set "smtp_tls_protocols = !SSLv2, !SSLv3". +Listing the protocols to include, rather than protocols to exclude, is +supported, but not recommended. The exclusion form more accurately +matches the underlying OpenSSL interface. </p> + +<p> When using the exclusion syntax, take care to ensure that the range of +protocols advertised by an SSL/TLS client is contiguous. When a protocol +version is enabled, disabling any higher version implicitly disables all +versions above that higher version. Thus, for example: +</p> +<blockquote> +<pre> +smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1.1 +</pre> +</blockquote> +<p> also disables any protocols version higher than TLSv1.1 leaving +only "TLSv1" enabled. </p> + +<p> Support for "TLSv1.3" was introduced in OpenSSL 1.1.1. Disabling +this protocol via "!TLSv1.3" is supported since Postfix 3.4 (or patch +releases ≥ 3.0.14, 3.1.10, 3.2.7 and 3.3.2). </p> + +<p> Example: </p> +<pre> +# Preferred syntax with Postfix ≥ 3.6: +smtp_tls_protocols = >=TLSv1, <=TLSv1.3 +# Legacy syntax: +smtp_tls_protocols = !SSLv2, !SSLv3 +</pre> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM smtpd_tls_protocols see postconf -d output + +<p> TLS protocols accepted by the Postfix SMTP server with opportunistic +TLS encryption. If the list is empty, the server supports all available +TLS protocol versions. A non-empty value is a list of protocol names to +include or exclude, separated by whitespace, commas or colons. </p> + +<p> The valid protocol names (see SSL_get_version(3)) are "SSLv2", +"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" and "TLSv1.3". Starting with +Postfix 3.6, the default value is ">=TLSv1", which sets TLS 1.0 as +the lowest supported TLS protocol version (see below). Older releases +use the "!" exclusion syntax, also described below. </p> + +<p> As of Postfix 3.6, the preferred way to limit the range of +acceptable protocols is to set the lowest acceptable TLS protocol +version and/or the highest acceptable TLS protocol version. To set the +lower bound include an element of the form: ">=<i>version</i>" where +<i>version</i> is a either one of the TLS protocol names listed above, +or a hexadecimal number corresponding to the desired TLS protocol +version (0301 for TLS 1.0, 0302 for TLS 1.1, etc.). For the upper +bound, use "<=<i>version</i>". There must be no whitespace between +the ">=" or "<=" symbols and the protocol name or number. </p> + +<p> Hexadecimal protocol numbers make it possible to specify protocol +bounds for TLS versions that are known to OpenSSL, but might not be +known to Postfix. They cannot be used with the legacy exclusion syntax. +Leading "0" or "0x" prefixes are supported, but not required. +Therefore, "301", "0301", "0x301" and "0x0301" are all equivalent to +"TLSv1". Hexadecimal versions unknown to OpenSSL will fail to set the +upper or lower bound, and a warning will be logged. Hexadecimal +versions should only be used when Postfix is linked with some future +version of OpenSSL that supports TLS 1.4 or later, but Postfix does not +yet support a symbolic name for that protocol version. </p> + +<p>Hexadecimal example (Postfix ≥ 3.6):</p> +<blockquote> +<pre> +# Allow only TLS 1.0 through (hypothetical) TLS 1.4, once supported +# in some future version of OpenSSL (presently a warning is logged). +smtpd_tls_protocols = >=TLSv1, <=0305 +# Allow only TLS 1.0 and up: +smtpd_tls_protocols = >=0x0301 +</pre> +</blockquote> + +<p> With Postfix < 3.6 there is no support for a minimum or maximum +version, and the protocol range is configured via protocol exclusions. +To require at least TLS 1.0, set "smtpd_tls_protocols = !SSLv2, !SSLv3". +Listing the protocols to include, rather than protocols to exclude, is +supported, but not recommended. The exclusion form more accurately +matches the underlying OpenSSL interface. </p> + +<p> Support for "TLSv1.3" was introduced in OpenSSL 1.1.1. Disabling +this protocol via "!TLSv1.3" is supported since Postfix 3.4 (or patch +releases ≥ 3.0.14, 3.1.10, 3.2.7 and 3.3.2). </p> + +<p> Example: </p> +<pre> +# Preferred syntax with Postfix ≥ 3.6: +smtpd_tls_protocols = >=TLSv1, <=TLSv1.3 +# Legacy syntax: +smtpd_tls_protocols = !SSLv2, !SSLv3 +</pre> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM lmtp_tls_protocols see postconf -d output + +<p> The LMTP-specific version of the smtp_tls_protocols configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM smtp_tls_ciphers medium + +<p> The minimum TLS cipher grade that the Postfix SMTP client +will use with opportunistic TLS encryption. Cipher types listed in +smtp_tls_exclude_ciphers are excluded from the base definition of +the selected cipher grade. The default value is "medium" for +Postfix releases after the middle of 2015, "export" for older +releases. </p> + +<p> When TLS is mandatory the cipher grade is chosen via the +smtp_tls_mandatory_ciphers configuration parameter, see there for syntax +details. See smtp_tls_policy_maps for information on how to configure +ciphers on a per-destination basis. </p> + +<p> This feature is available in Postfix 2.6 and later. With earlier Postfix +releases only the smtp_tls_mandatory_ciphers parameter is implemented, +and opportunistic TLS always uses "export" or better (i.e. all) ciphers. </p> + +%PARAM smtpd_tls_ciphers medium + +<p> The minimum TLS cipher grade that the Postfix SMTP server +will use with opportunistic TLS encryption. Cipher types listed in +smtpd_tls_exclude_ciphers are excluded from the base definition of +the selected cipher grade. The default value is "medium" for Postfix +releases after the middle of 2015, "export" for older releases. +</p> + +<p> When TLS is mandatory the cipher grade is chosen via the +smtpd_tls_mandatory_ciphers configuration parameter, see there for syntax +details. </p> + +<p> This feature is available in Postfix 2.6 and later. With earlier Postfix +releases only the smtpd_tls_mandatory_ciphers parameter is implemented, +and opportunistic TLS always uses "export" or better (i.e. all) ciphers. </p> + +%PARAM lmtp_tls_ciphers medium + +<p> The LMTP-specific version of the smtp_tls_ciphers configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM tls_eecdh_auto_curves see "postconf -d" output + +<p> The prioritized list of elliptic curves supported by the Postfix +SMTP client and server. These curves are used by the Postfix SMTP +server when "smtpd_tls_eecdh_grade = auto". The selected curves +must be implemented by OpenSSL and be standardized for use in TLS +(RFC 8422). It is unwise to list only +"bleeding-edge" curves supported by a small subset of clients. The +default list is suitable for most users. </p> + +<p> Postfix skips curve names that are unknown to OpenSSL, or that +are known but not yet implemented. This makes it possible to +"anticipate" support for curves that should be used once they become +available. In particular, in some OpenSSL versions, the new RFC +8031 curves "X25519" and "X448" may be known by name, but ECDH +support for either or both may be missing. These curves may appear +in the default value of this parameter, even though they'll only +be usable with later versions of OpenSSL. </p> + +<p> This feature is available in Postfix 3.2 and later, when it is +compiled and linked with OpenSSL 1.0.2 or later on platforms where +EC algorithms have not been disabled by the vendor. </p> + +%PARAM tls_eecdh_strong_curve prime256v1 + +<p> The elliptic curve used by the Postfix SMTP server for sensibly +strong +ephemeral ECDH key exchange. This curve is used by the Postfix SMTP +server when "smtpd_tls_eecdh_grade = strong". The phrase "sensibly +strong" means approximately 128-bit security based on best known +attacks. The selected curve must be implemented by OpenSSL (as +reported by ecparam(1) with the "-list_curves" option) and be one +of the curves listed in Section 5.1.1 of RFC 8422. You should not +generally change this setting. Remote SMTP client implementations +must support this curve for EECDH key exchange to take place. It +is unwise to choose only "bleeding-edge" curves supported by only a +small subset of clients. </p> + +<p> The default "strong" curve is rated in NSA <a +href="https://web.archive.org/web/20160330034144/https://www.nsa.gov/ia/programs/suiteb_cryptography/">Suite +B</a> for information classified up to SECRET. </p> + +<p> Note: elliptic curve names are poorly standardized; different +standards groups are assigning different names to the same underlying +curves. The curve with the X9.62 name "prime256v1" is also known +under the SECG name "secp256r1", but OpenSSL does not recognize the +latter name. </p> + +<p> If you want to take maximal advantage of ciphers that offer <a +href="FORWARD_SECRECY_README.html#dfn_fs">forward secrecy</a> see +the <a href="FORWARD_SECRECY_README.html#quick-start">Getting +started</a> section of <a +href="FORWARD_SECRECY_README.html">FORWARD_SECRECY_README</a>. The +full document conveniently presents all information about Postfix +"perfect" forward secrecy support in one place: what forward secrecy +is, how to tweak settings, and what you can expect to see when +Postfix uses ciphers with forward secrecy. </p> + +<p> This feature is available in Postfix 2.6 and later, when it is +compiled and linked with OpenSSL 1.0.0 or later on platforms where +EC algorithms have not been disabled by the vendor. </p> + +%PARAM tls_eecdh_ultra_curve secp384r1 + +<p> The elliptic curve used by the Postfix SMTP server for maximally +strong +ephemeral ECDH key exchange. This curve is used by the Postfix SMTP +server when "smtpd_tls_eecdh_grade = ultra". The phrase "maximally +strong" means approximately 192-bit security based on best known attacks. +This additional strength comes at a significant computational cost, most +users should instead set "smtpd_tls_eecdh_grade = strong". The selected +curve must be implemented by OpenSSL (as reported by ecparam(1) with the +"-list_curves" option) and be one of the curves listed in Section 5.1.1 +of RFC 8422. You should not generally change this setting. Remote SMTP +client implementations must support this curve for EECDH key exchange +to take place. It is unwise to choose only "bleeding-edge" curves +supported by only a small subset of clients. </p> + +<p> This default "ultra" curve is rated in NSA <a +href="https://web.archive.org/web/20160330034144/https://www.nsa.gov/ia/programs/suiteb_cryptography/">Suite +B</a> for information classified up to TOP SECRET. </p> + +<p> If you want to take maximal advantage of ciphers that offer <a +href="FORWARD_SECRECY_README.html#dfn_fs">forward secrecy</a> see +the <a href="FORWARD_SECRECY_README.html#quick-start">Getting +started</a> section of <a +href="FORWARD_SECRECY_README.html">FORWARD_SECRECY_README</a>. The +full document conveniently presents all information about Postfix +"perfect" forward secrecy support in one place: what forward secrecy +is, how to tweak settings, and what you can expect to see when +Postfix uses ciphers with forward secrecy. </p> + +<p> This feature is available in Postfix 2.6 and later, when it is +compiled and linked with OpenSSL 1.0.0 or later on platforms where +EC algorithms have not been disabled by the vendor. </p> + +%PARAM smtpd_tls_eecdh_grade see "postconf -d" output + +<p> The Postfix SMTP server security grade for ephemeral elliptic-curve +Diffie-Hellman (EECDH) key exchange. As of Postfix 3.6, the value of +this parameter is always ignored, and Postfix behaves as though the +<b>auto</b> value (described below) was chosen. +</p> + +<p> The available choices are: </p> + +<dl> + +<dt><b>auto</b></dt> <dd> Use the most preferred curve that is +supported by both the client and the server. This setting requires +Postfix ≥ 3.2 compiled and linked with OpenSSL ≥ 1.0.2. This +is the default setting under the above conditions (and the only +setting used with Postfix ≥ 3.6). </dd> + +<dt><b>none</b></dt> <dd> Don't use EECDH. Ciphers based on EECDH key +exchange will be disabled. This is the default in Postfix versions +2.6 and 2.7. </dd> + +<dt><b>strong</b></dt> <dd> Use EECDH with approximately 128 bits of +security at a reasonable computational cost. This is the default in +Postfix versions 2.8–3.5. </dd> + +<dt><b>ultra</b></dt> <dd> Use EECDH with approximately 192 bits of +security at computational cost that is approximately twice as high +as 128 bit strength ECC. </dd> + +</dl> + +<p> If you want to take maximal advantage of ciphers that offer <a +href="FORWARD_SECRECY_README.html#dfn_fs">forward secrecy</a> see +the <a href="FORWARD_SECRECY_README.html#quick-start">Getting +started</a> section of <a +href="FORWARD_SECRECY_README.html">FORWARD_SECRECY_README</a>. The +full document conveniently presents all information about Postfix +"perfect" forward secrecy support in one place: what forward secrecy +is, how to tweak settings, and what you can expect to see when +Postfix uses ciphers with forward secrecy. </p> + +<p> This feature is available in Postfix 2.6 and later, when it is +compiled and linked with OpenSSL 1.0.0 or later on platforms +where EC algorithms have not been disabled by the vendor. </p> + +%PARAM smtpd_tls_eccert_file + +<p> File with the Postfix SMTP server ECDSA certificate in PEM format. +This file may also contain the Postfix SMTP server private ECDSA key. +With Postfix ≥ 3.4 the preferred way to configure server keys and +certificates is via the "smtpd_tls_chain_files" parameter. </p> + +<p> See the discussion under smtpd_tls_cert_file for more details. </p> + +<p> Example: </p> + +<pre> +smtpd_tls_eccert_file = /etc/postfix/ecdsa-scert.pem +</pre> + +<p> This feature is available in Postfix 2.6 and later, when Postfix is +compiled and linked with OpenSSL 1.0.0 or later. </p> + +%PARAM smtpd_tls_eckey_file $smtpd_tls_eccert_file + +<p> File with the Postfix SMTP server ECDSA private key in PEM format. +This file may be combined with the Postfix SMTP server ECDSA certificate +file specified with $smtpd_tls_eccert_file. With Postfix ≥ 3.4 the +preferred way to configure server keys and certificates is via the +"smtpd_tls_chain_files" parameter. </p> + +<p> The private key must be accessible without a pass-phrase, i.e. it +must not be encrypted. File permissions should grant read-only +access to the system superuser account ("root"), and no access +to anyone else. </p> + +<p> This feature is available in Postfix 2.6 and later, when Postfix is +compiled and linked with OpenSSL 1.0.0 or later. </p> + +%PARAM smtp_tls_eccert_file + +<p> File with the Postfix SMTP client ECDSA certificate in PEM format. +This file may also contain the Postfix SMTP client ECDSA private key. +With Postfix ≥ 3.4 the preferred way to configure client keys and +certificates is via the "smtp_tls_chain_files" parameter. </p> + +<p> See the discussion under smtp_tls_cert_file for more details. +</p> + +<p> Example: </p> + +<pre> +smtp_tls_eccert_file = /etc/postfix/ecdsa-ccert.pem +</pre> + +<p> This feature is available in Postfix 2.6 and later, when Postfix is +compiled and linked with OpenSSL 1.0.0 or later. </p> + +%PARAM smtp_tls_eckey_file $smtp_tls_eccert_file + +<p> File with the Postfix SMTP client ECDSA private key in PEM format. +This file may be combined with the Postfix SMTP client ECDSA certificate +file specified with $smtp_tls_eccert_file. With Postfix ≥ 3.4 the +preferred way to configure client keys and certificates is via the +"smtp_tls_chain_files" parameter. </p> + +<p> The private key must be accessible without a pass-phrase, i.e. it +must not be encrypted. File permissions should grant read-only +access to the system superuser account ("root"), and no access +to anyone else. </p> + +<p> This feature is available in Postfix 2.6 and later, when Postfix is +compiled and linked with OpenSSL 1.0.0 or later. </p> + +%PARAM lmtp_tls_eccert_file + +<p> The LMTP-specific version of the smtp_tls_eccert_file configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.6 and later, when Postfix is +compiled and linked with OpenSSL 1.0.0 or later. </p> + +%PARAM lmtp_tls_eckey_file + +<p> The LMTP-specific version of the smtp_tls_eckey_file configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.6 and later, when Postfix is +compiled and linked with OpenSSL 1.0.0 or later. </p> + +%PARAM smtp_header_checks + +<p> Restricted header_checks(5) tables for the Postfix SMTP client. +These tables are searched while mail is being delivered. Actions +that change the delivery time or destination are not available. +</p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM smtp_mime_header_checks + +<p> Restricted mime_header_checks(5) tables for the Postfix SMTP +client. These tables are searched while mail is being delivered. +Actions that change the delivery time or destination are not +available. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM smtp_nested_header_checks + +<p> Restricted nested_header_checks(5) tables for the Postfix SMTP +client. These tables are searched while mail is being delivered. +Actions that change the delivery time or destination are not +available. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM smtp_body_checks + +<p> Restricted body_checks(5) tables for the Postfix SMTP client. +These tables are searched while mail is being delivered. Actions +that change the delivery time or destination are not available. +</p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM destination_concurrency_feedback_debug no + +<p> Make the queue manager's feedback algorithm verbose for performance +analysis purposes. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM default_destination_concurrency_failed_cohort_limit 1 + +<p> How many pseudo-cohorts must suffer connection or handshake +failure before a specific destination is considered unavailable +(and further delivery is suspended). Specify zero to disable this +feature. A destination's pseudo-cohort failure count is reset each +time a delivery completes without connection or handshake failure +for that specific destination. </p> + +<p> A pseudo-cohort is the number of deliveries equal to a destination's +delivery concurrency. </p> + +<p> Use <i>transport</i>_destination_concurrency_failed_cohort_limit to specify +a transport-specific override, where <i>transport</i> is the master.cf +name of the message delivery transport. </p> + +<p> This feature is available in Postfix 2.5. The default setting +is compatible with earlier Postfix versions. </p> + +%PARAM default_destination_concurrency_negative_feedback 1 + +<p> The per-destination amount of delivery concurrency negative +feedback, after a delivery completes with a connection or handshake +failure. Feedback values are in the range 0..1 inclusive. With +negative feedback, concurrency is decremented at the beginning of +a sequence of length 1/feedback. This is unlike positive feedback, +where concurrency is incremented at the end of a sequence of length +1/feedback. </p> + +<p> As of Postfix version 2.5, negative feedback cannot reduce +delivery concurrency to zero. Instead, a destination is marked +dead (further delivery suspended) after the failed pseudo-cohort +count reaches $default_destination_concurrency_failed_cohort_limit +(or $<i>transport</i>_destination_concurrency_failed_cohort_limit). +To make the scheduler completely immune to connection or handshake +failures, specify a zero feedback value and a zero failed pseudo-cohort +limit. </p> + +<p> Specify one of the following forms: </p> + +<dl> + +<dt> <b><i>number</i> </b> </dt> + +<dt> <b><i>number</i> / <i>number</i> </b> </dt> + +<dd> Constant feedback. The value must be in the range 0..1 inclusive. +The default setting of "1" is compatible with Postfix versions +before 2.5, where a destination's delivery concurrency is throttled +down to zero (and further delivery suspended) after a single failed +pseudo-cohort. </dd> + +<dt> <b><i>number</i> / concurrency </b> </dt> + +<dd> Variable feedback of "<i>number</i> / (delivery concurrency)". +The <i>number</i> must be in the range 0..1 inclusive. With +<i>number</i> equal to "1", a destination's delivery concurrency +is decremented by 1 after each failed pseudo-cohort. </dd> + +<!-- + +<dt> <b><i>number</i> / sqrt_concurrency </b> </dt> + +<dd> Variable feedback of "<i>number</i> / sqrt(delivery concurrency)". +The <i>number</i> must be in the range 0..1 inclusive. This setting +may be removed in a future version. </dd> + +--> + +</dl> + +<p> A pseudo-cohort is the number of deliveries equal to a destination's +delivery concurrency. </p> + +<p> Use <i>transport</i>_destination_concurrency_negative_feedback +to specify a transport-specific override, where <i>transport</i> +is the master.cf +name of the message delivery transport. </p> + +<p> This feature is available in Postfix 2.5. The default setting +is compatible with earlier Postfix versions. </p> + +%PARAM default_destination_concurrency_positive_feedback 1 + +<p> The per-destination amount of delivery concurrency positive +feedback, after a delivery completes without connection or handshake +failure. Feedback values are in the range 0..1 inclusive. The +concurrency increases until it reaches the per-destination maximal +concurrency limit. With positive feedback, concurrency is incremented +at the end of a sequence with length 1/feedback. This is unlike +negative feedback, where concurrency is decremented at the start +of a sequence of length 1/feedback. </p> + +<p> Specify one of the following forms: </p> + +<dl> + +<dt> <b><i>number</i> </b> </dt> + +<dt> <b><i>number</i> / <i>number</i> </b> </dt> + +<dd> Constant feedback. The value must be in the range 0..1 +inclusive. The default setting of "1" is compatible with Postfix +versions before 2.5, where a destination's delivery concurrency +doubles after each successful pseudo-cohort. </dd> + +<dt> <b><i>number</i> / concurrency </b> </dt> + +<dd> Variable feedback of "<i>number</i> / (delivery concurrency)". +The <i>number</i> must be in the range 0..1 inclusive. With +<i>number</i> equal to "1", a destination's delivery concurrency +is incremented by 1 after each successful pseudo-cohort. </dd> + +<!-- + +<dt> <b><i>number</i> / sqrt_concurrency </b> </dt> + +<dd> Variable feedback of "<i>number</i> / sqrt(delivery concurrency)". +The <i>number</i> must be in the range 0..1 inclusive. This setting +may be removed in a future version. </dd> + +--> + +</dl> + +<p> A pseudo-cohort is the number of deliveries equal to a destination's +delivery concurrency. </p> + +<p> Use <i>transport</i>_destination_concurrency_positive_feedback +to specify a transport-specific override, where <i>transport</i> +is the master.cf name of the message delivery transport. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM transport_destination_concurrency_failed_cohort_limit $default_destination_concurrency_failed_cohort_limit + +<p> A transport-specific override for the +default_destination_concurrency_failed_cohort_limit parameter value, +where <i>transport</i> is the master.cf name of the message delivery +transport. </p> + +<p> Note: some <i>transport</i>_destination_concurrency_failed_cohort_limit +parameters will not show up in "postconf" command output before +Postfix version 2.9. This limitation applies to many parameters +whose name is a combination of a master.cf service name and a +built-in suffix (in this case: +"_destination_concurrency_failed_cohort_limit"). </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM transport_destination_concurrency_positive_feedback $default_destination_concurrency_positive_feedback + +<p> A transport-specific override for the +default_destination_concurrency_positive_feedback parameter value, +where <i>transport</i> is the master.cf name of the message delivery +transport. </p> + +<p> Note: some <i>transport</i>_destination_concurrency_positive_feedback +parameters will not show up in "postconf" command output before +Postfix version 2.9. This limitation applies to many parameters +whose name is a combination of a master.cf service name and a +built-in suffix (in this case: +"_destination_concurrency_positive_feedback"). </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM transport_destination_concurrency_negative_feedback $default_destination_concurrency_negative_feedback + +<p> A transport-specific override for the +default_destination_concurrency_negative_feedback parameter value, +where <i>transport</i> is the master.cf name of the message delivery +transport. </p> + +<p> Note: some <i>transport</i>_destination_concurrency_negative_feedback +parameters will not show up in "postconf" command output before +Postfix version 2.9. This limitation applies to many parameters +whose name is a combination of a master.cf service name and a +built-in suffix (in this case: +"_destination_concurrency_negative_feedback"). </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM transport_initial_destination_concurrency $initial_destination_concurrency + +<p> A transport-specific override for the initial_destination_concurrency +parameter value, where <i>transport</i> is the master.cf name of +the message delivery transport. </p> + +<p> Note: some <i>transport</i>_initial_destination_concurrency +parameters will not show up in "postconf" command output before +Postfix version 2.9. This limitation applies to many parameters +whose name is a combination of a master.cf service name and a +built-in suffix (in this case: "_initial_destination_concurrency"). +</p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM transport_destination_concurrency_limit $default_destination_concurrency_limit + +<p> A transport-specific override for the +default_destination_concurrency_limit parameter value, where +<i>transport</i> is the master.cf name of the message delivery +transport. </p> + +<p> Note: some <i>transport</i>_destination_concurrency_limit +parameters will not show up in "postconf" command output before +Postfix version 2.9. This limitation applies to many parameters +whose name is a combination of a master.cf service name and a +built-in suffix (in this case: "_destination_concurrency_limit"). +</p> + +%PARAM transport_destination_recipient_limit $default_destination_recipient_limit + +<p> A transport-specific override for the +default_destination_recipient_limit parameter value, where +<i>transport</i> is the master.cf name of the message delivery +transport. </p> + +<p> Note: some <i>transport</i>_destination_recipient_limit parameters +will not show up in "postconf" command output before Postfix version +2.9. This limitation applies to many parameters whose name is a +combination of a master.cf service name and a built-in suffix (in +this case: "_destination_recipient_limit"). </p> + +%PARAM transport_time_limit $command_time_limit + +<p> A transport-specific override for the command_time_limit parameter +value, where <i>transport</i> is the master.cf name of the message +delivery transport. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> Note: <i>transport</i>_time_limit parameters will not show up +in "postconf" command output before Postfix version 2.9. This +limitation applies to many parameters whose name is a combination +of a master.cf service name and a built-in suffix (in this case: +"_time_limit"). </p> + +%PARAM transport_delivery_slot_cost $default_delivery_slot_cost + +<p> A transport-specific override for the default_delivery_slot_cost +parameter value, where <i>transport</i> is the master.cf name of +the message delivery transport. </p> + +<p> Note: <i>transport</i>_delivery_slot_cost parameters will not +show up in "postconf" command output before Postfix version 2.9. +This limitation applies to many parameters whose name is a combination +of a master.cf service name and a built-in suffix (in this case: +"_delivery_slot_cost"). </p> + +%PARAM transport_delivery_slot_loan $default_delivery_slot_loan + +<p> A transport-specific override for the default_delivery_slot_loan +parameter value, where <i>transport</i> is the master.cf name of +the message delivery transport. </p> + +<p> Note: <i>transport</i>_delivery_slot_loan parameters will not +show up in "postconf" command output before Postfix version 2.9. +This limitation applies to many parameters whose name is a combination +of a master.cf service name and a built-in suffix (in this case: +"_delivery_slot_loan"). </p> + +%PARAM transport_delivery_slot_discount $default_delivery_slot_discount + +<p> A transport-specific override for the default_delivery_slot_discount +parameter value, where <i>transport</i> is the master.cf name of +the message delivery transport. </p> + +<p> Note: <i>transport</i>_delivery_slot_discount parameters will +not show up in "postconf" command output before Postfix version +2.9. This limitation applies to many parameters whose name is a +combination of a master.cf service name and a built-in suffix (in +this case: "_delivery_slot_discount"). </p> + +%PARAM transport_minimum_delivery_slots $default_minimum_delivery_slots + +<p> A transport-specific override for the default_minimum_delivery_slots +parameter value, where <i>transport</i> is the master.cf name of +the message delivery transport. </p> + +<p> Note: <i>transport</i>_minimum_delivery_slots parameters will +not show up in "postconf" command output before Postfix version +2.9. This limitation applies to many parameters whose name is a +combination of a master.cf service name and a built-in suffix (in +this case: "_minimum_delivery_slots"). </p> + +%PARAM transport_recipient_limit $default_recipient_limit + +<p> A transport-specific override for the default_recipient_limit +parameter value, where <i>transport</i> is the master.cf name of +the message delivery transport. </p> + +<p> Note: some <i>transport</i>_recipient_limit parameters will not +show up in "postconf" command output before Postfix version 2.9. +This limitation applies to many parameters whose name is a combination +of a master.cf service name and a built-in suffix (in this case: +"_recipient_limit"). </p> + +%PARAM transport_extra_recipient_limit $default_extra_recipient_limit + +<p> A transport-specific override for the default_extra_recipient_limit +parameter value, where <i>transport</i> is the master.cf name of +the message delivery transport. </p> + +<p> Note: <i>transport</i>_extra_recipient_limit parameters will +not show up in "postconf" command output before Postfix version +2.9. This limitation applies to many parameters whose name is a +combination of a master.cf service name and a built-in suffix (in +this case: "_extra_recipient_limit"). </p> + +%PARAM transport_recipient_refill_limit $default_recipient_refill_limit + +<p> A transport-specific override for the default_recipient_refill_limit +parameter value, where <i>transport</i> is the master.cf name of +the message delivery transport. </p> + +<p> Note: <i>transport</i>_recipient_refill_limit parameters will +not show up in "postconf" command output before Postfix version +2.9. This limitation applies to many parameters whose name is a +combination of a master.cf service name and a built-in suffix (in +this case: "_recipient_refill_limit"). </p> + +<p> This feature is available in Postfix 2.4 and later. </p> + +%PARAM transport_recipient_refill_delay $default_recipient_refill_delay + +<p> A transport-specific override for the default_recipient_refill_delay +parameter value, where <i>transport</i> is the master.cf name of +the message delivery transport. </p> + +<p> Note: <i>transport</i>_recipient_refill_delay parameters will +not show up in "postconf" command output before Postfix version +2.9. This limitation applies to many parameters whose name is a +combination of a master.cf service name and a built-in suffix (in +this case: "_recipient_refill_delay"). </p> + +<p> This feature is available in Postfix 2.4 and later. </p> + +%PARAM default_transport_rate_delay 0s + +<p> The default amount of delay that is inserted between individual +message deliveries over the same message delivery transport, +regardless of destination. Specify a non-zero value to rate-limit +those message deliveries to at most one per $default_transport_rate_delay. +</p> + +<p>Use <i>transport</i>_transport_rate_delay to specify a +transport-specific override, where the initial <i>transport</i> is +the master.cf name of the message delivery transport. </p> + +<p> Example: throttle outbound SMTP mail to at most 3 deliveries +per minute. </p> + +<pre> +/etc/postfix/main.cf: + smtp_transport_rate_delay = 20s +</pre> + +<p> To enable the delay, specify a non-zero time value (an integral +value plus an optional one-letter suffix that specifies the time +unit). </p> + +<p> Time units: s (seconds), m (minutes), h (hours), d (days), w +(weeks). The default time unit is s (seconds). </p> + +<p> NOTE: the delay is enforced by the queue manager. </p> + +<p> This feature is available in Postfix 3.1 and later. </p> + +%PARAM transport_transport_rate_delay $default_transport_rate_delay + +<p> A transport-specific override for the default_transport_rate_delay +parameter value, where the initial <i>transport</i> in the parameter +name is the master.cf name of the message delivery transport. </p> + +<p> Specify a non-negative time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> Note: <i>transport</i>_transport_rate_delay parameters will +not show up in "postconf" command output before Postfix version +2.9. This limitation applies to many parameters whose name is a +combination of a master.cf service name and a built-in suffix (in +this case: "_transport_rate_delay"). </p> + +%PARAM default_destination_rate_delay 0s + +<p> The default amount of delay that is inserted between individual +message deliveries to the same destination and over the same message +delivery transport. Specify a non-zero value to rate-limit those +message deliveries to at most one per $default_destination_rate_delay. +</p> + +<p> The resulting behavior depends on the value of the corresponding +per-destination recipient limit. + +</p> + +<ul> + +<li> <p> With a corresponding per-destination recipient limit > +1, the rate delay specifies the time between deliveries to the +<i>same domain</i>. Different domains are delivered in parallel, +subject to the process limits specified in master.cf. </p> + +<li> <p> With a corresponding per-destination recipient limit equal +to 1, the rate delay specifies the time between deliveries to the +<i>same recipient</i>. Different recipients are delivered in +parallel, subject to the process limits specified in master.cf. +</p> + +</ul> + +<p> To enable the delay, specify a non-zero time value (an integral +value plus an optional one-letter suffix that specifies the time +unit). </p> + +<p> Time units: s (seconds), m (minutes), h (hours), d (days), w +(weeks). The default time unit is s (seconds). </p> + +<p> NOTE: the delay is enforced by the queue manager. The delay +timer state does not survive "<b>postfix reload</b>" or "<b>postfix +stop</b>". +</p> + +<p> Use <i>transport</i>_destination_rate_delay to specify a +transport-specific override, where <i>transport</i> is the master.cf +name of the message delivery transport. +</p> + +<p> NOTE: with a non-zero _destination_rate_delay, specify a +<i>transport</i>_destination_concurrency_failed_cohort_limit of 10 +or more to prevent Postfix from deferring all mail for the same +destination after only one connection or handshake error. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM transport_destination_rate_delay $default_destination_rate_delay + +<p> A transport-specific override for the default_destination_rate_delay +parameter value, where <i>transport</i> is the master.cf name of +the message delivery transport. </p> + +<p> Note: some <i>transport</i>_destination_rate_delay parameters +will not show up in "postconf" command output before Postfix version +2.9. This limitation applies to many parameters whose name is a +combination of a master.cf service name and a built-in suffix (in +this case: "_destination_rate_delay"). </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM data_directory see "postconf -d" output + +<p> The directory with Postfix-writable data files (for example: +caches, pseudo-random numbers). This directory must be owned by +the mail_owner account, and must not be shared with non-Postfix +software. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM stress + +<p> This feature is documented in the STRESS_README document. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM smtp_sasl_auth_soft_bounce yes + +<p> When a remote SMTP server rejects a SASL authentication request +with a 535 reply code, defer mail delivery instead of returning +mail as undeliverable. The latter behavior was hard-coded prior to +Postfix version 2.5. </p> + +<p> Note: the setting "yes" overrides the global soft_bounce +parameter, but the setting "no" does not. </p> + +<p> Example: </p> + +<pre> +# Default as of Postfix 2.5 +smtp_sasl_auth_soft_bounce = yes +# The old hard-coded default +smtp_sasl_auth_soft_bounce = no +</pre> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM smtp_sasl_auth_cache_name + +<p> An optional table to prevent repeated SASL authentication +failures with the same remote SMTP server hostname, username and +password. Each table (key, value) pair contains a server name, a +username and password, and the full server response. This information +is stored when a remote SMTP server rejects an authentication attempt +with a 535 reply code. As long as the smtp_sasl_password_maps +information does not change, and as long as the smtp_sasl_auth_cache_name +information does not expire (see smtp_sasl_auth_cache_time) the +Postfix SMTP client avoids SASL authentication attempts with the +same server, username and password, and instead bounces or defers +mail as controlled with the smtp_sasl_auth_soft_bounce configuration +parameter. </p> + +<p> Use a per-destination delivery concurrency of 1 (for example, +"smtp_destination_concurrency_limit = 1", +"relay_destination_concurrency_limit = 1", etc.), otherwise multiple +delivery agents may experience a login failure at the same time. +</p> + +<p> The table must be accessed via the proxywrite service, i.e. the +map name must start with "proxy:". The table should be stored under +the directory specified with the data_directory parameter. </p> + +<p> This feature uses cryptographic hashing to protect plain-text +passwords, and requires that Postfix is compiled with TLS support. +</p> + +<p> Example: </p> + +<pre> +smtp_sasl_auth_cache_name = proxy:btree:/var/lib/postfix/sasl_auth_cache +</pre> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM smtp_sasl_auth_cache_time 90d + +<p> The maximal age of an smtp_sasl_auth_cache_name entry before it +is removed. </p> + +<p> Specify a non-negative time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is d (days). </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM lmtp_sasl_auth_soft_bounce yes + +<p> The LMTP-specific version of the smtp_sasl_auth_soft_bounce +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM lmtp_sasl_auth_cache_name + +<p> The LMTP-specific version of the smtp_sasl_auth_cache_name +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM lmtp_sasl_auth_cache_time 90d + +<p> The LMTP-specific version of the smtp_sasl_auth_cache_time +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM unverified_sender_reject_reason + +<p> The Postfix SMTP server's reply when rejecting mail with +reject_unverified_sender. Do not include the numeric SMTP reply +code or the enhanced status code. By default, the response includes +actual address verification details. + +<p> Example: </p> + +<pre> +unverified_sender_reject_reason = Sender address lookup failed +</pre> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM unverified_recipient_reject_reason + +<p> The Postfix SMTP server's reply when rejecting mail with +reject_unverified_recipient. Do not include the numeric SMTP reply +code or the enhanced status code. By default, the response includes +actual address verification details. + +<p> Example: </p> + +<pre> +unverified_recipient_reject_reason = Recipient address lookup failed +</pre> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM strict_mailbox_ownership yes + +<p> Defer delivery when a mailbox file is not owned by its recipient. +The default setting is not backwards compatible. </p> + +<p> This feature is available in Postfix 2.5.3 and later. </p> + +%PARAM proxymap_service_name proxymap + +<p> The name of the proxymap read-only table lookup service. This +service is normally implemented by the proxymap(8) daemon. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM proxywrite_service_name proxywrite + +<p> The name of the proxywrite read-write table lookup service. +This service is normally implemented by the proxymap(8) daemon. +</p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM master_service_disable + +<p> Selectively disable master(8) listener ports by service type +or by service name and type. Specify a list of service types +("inet", "unix", "fifo", or "pass") or "name/type" tuples, where +"name" is the first field of a master.cf entry and "type" is a +service type. As with other Postfix matchlists, a search stops at +the first match. Specify "!pattern" to exclude a service from the +list. By default, all master(8) listener ports are enabled. </p> + +<p> Note: this feature does not support "/file/name" or "type:table" +patterns, nor does it support wildcards such as "*" or "all". This +is intentional. </p> + +<p> Examples: </p> + +<pre> +# With Postfix 2.6..2.10 use '.' instead of '/'. +# Turn on all master(8) listener ports (the default). +master_service_disable = +# Turn off only the main SMTP listener port. +master_service_disable = smtp/inet +# Turn off all TCP/IP listener ports. +master_service_disable = inet +# Turn off all TCP/IP listener ports except "foo". +master_service_disable = !foo/inet, inet +</pre> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM tcp_windowsize 0 + +<p> An optional workaround for routers that break TCP window scaling. +Specify a value > 0 and < 65536 to enable this feature. With +Postfix TCP servers (smtpd(8), qmqpd(8)), this feature is implemented +by the Postfix master(8) daemon. </p> + +<p> To change this parameter without stopping Postfix, you need to +first terminate all Postfix TCP servers: </p> + +<blockquote> +<pre> +# postconf -e master_service_disable=inet +# postfix reload +</pre> +</blockquote> + +<p> This immediately terminates all processes that accept network +connections. Next, you enable Postfix TCP servers with the updated +tcp_windowsize setting: </p> + +<blockquote> +<pre> +# postconf -e tcp_windowsize=65535 master_service_disable= +# postfix reload +</pre> +</blockquote> + +<p> If you skip these steps with a running Postfix system, then the +tcp_windowsize change will work only for Postfix TCP clients (smtp(8), +lmtp(8)). </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM multi_instance_directories + +<p> An optional list of non-default Postfix configuration directories; +these directories belong to additional Postfix instances that share +the Postfix executable files and documentation with the default +Postfix instance, and that are started, stopped, etc., together +with the default Postfix instance. Specify a list of pathnames +separated by comma or whitespace. </p> + +<p> When $multi_instance_directories is empty, the postfix(1) command +runs in single-instance mode and operates on a single Postfix +instance only. Otherwise, the postfix(1) command runs in multi-instance +mode and invokes the multi-instance manager specified with the +multi_instance_wrapper parameter. The multi-instance manager in +turn executes postfix(1) commands for the default instance and for +all Postfix instances in $multi_instance_directories. </p> + +<p> Currently, this parameter setting is ignored except for the +default main.cf file. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM multi_instance_wrapper + +<p> The pathname of a multi-instance manager command that the +postfix(1) command invokes when the multi_instance_directories +parameter value is non-empty. The pathname may be followed by +initial command arguments separated by whitespace; shell +metacharacters such as quotes are not supported in this context. +</p> + +<p> The postfix(1) command invokes the manager command with the +postfix(1) non-option command arguments on the manager command line, +and with all installation configuration parameters exported into +the manager command process environment. The manager command in +turn invokes the postfix(1) command for individual Postfix instances +as "postfix -c <i>config_directory</i> <i>command</i>". </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM multi_instance_group + +<p> The optional instance group name of this Postfix instance. A +group identifies closely-related Postfix instances that the +multi-instance manager can start, stop, etc., as a unit. This +parameter is reserved for the multi-instance manager. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM multi_instance_name + +<p> The optional instance name of this Postfix instance. This name +becomes also the default value for the syslog_name parameter. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM multi_instance_enable no + +<p> Allow this Postfix instance to be started, stopped, etc., by a +multi-instance manager. By default, new instances are created in +a safe state that prevents them from being started inadvertently. +This parameter is reserved for the multi-instance manager. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM reject_tempfail_action defer_if_permit + +<p> The Postfix SMTP server's action when a reject-type restriction +fails due to a temporary error condition. Specify "defer" to defer +the remote SMTP client request immediately. With the default +"defer_if_permit" action, the Postfix SMTP server continues to look +for opportunities to reject mail, and defers the client request +only if it would otherwise be accepted. </p> + +<p> For finer control, see: unverified_recipient_tempfail_action, +unverified_sender_tempfail_action, unknown_address_tempfail_action, +and unknown_helo_hostname_tempfail_action. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM unverified_recipient_tempfail_action $reject_tempfail_action + +<p> The Postfix SMTP server's action when reject_unverified_recipient +fails due to a temporary error condition. Specify "defer" to defer +the remote SMTP client request immediately. With the default +"defer_if_permit" action, the Postfix SMTP server continues to look +for opportunities to reject mail, and defers the client request +only if it would otherwise be accepted. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM unverified_sender_tempfail_action $reject_tempfail_action + +<p> The Postfix SMTP server's action when reject_unverified_sender +fails due to a temporary error condition. Specify "defer" to defer +the remote SMTP client request immediately. With the default +"defer_if_permit" action, the Postfix SMTP server continues to look +for opportunities to reject mail, and defers the client request +only if it would otherwise be accepted. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM unknown_address_tempfail_action $reject_tempfail_action + +<p> The Postfix SMTP server's action when reject_unknown_sender_domain +or reject_unknown_recipient_domain fail due to a temporary error +condition. Specify "defer" to defer the remote SMTP client request +immediately. With the default "defer_if_permit" action, the Postfix +SMTP server continues to look for opportunities to reject mail, and +defers the client request only if it would otherwise be accepted. +</p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM unknown_helo_hostname_tempfail_action $reject_tempfail_action + +<p> The Postfix SMTP server's action when reject_unknown_helo_hostname +fails due to a temporary error condition. Specify "defer" to defer +the remote SMTP client request immediately. With the default +"defer_if_permit" action, the Postfix SMTP server continues to look +for opportunities to reject mail, and defers the client request +only if it would otherwise be accepted. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM postmulti_start_commands start + +<p> The postfix(1) commands that the postmulti(1) instance manager treats +as "start" commands. For these commands, disabled instances are "checked" +rather than "started", and failure to "start" a member instance of an +instance group will abort the start-up of later instances. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM postmulti_stop_commands see "postconf -d" output + +<p> The postfix(1) commands that the postmulti(1) instance manager treats +as "stop" commands. For these commands, disabled instances are skipped, +and enabled instances are processed in reverse order. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM postmulti_control_commands reload flush + +<p> The postfix(1) commands that the postmulti(1) instance manager +treats as "control" commands, that operate on running instances. For +these commands, disabled instances are skipped. </p> + +<p> This feature is available in Postfix 2.6 and later. </p> + +%PARAM lmtp_assume_final no + +<p> When a remote LMTP server announces no DSN support, assume that +the +server performs final delivery, and send "delivered" delivery status +notifications instead of "relayed". The default setting is backwards +compatible to avoid the infinitesimal possibility of breaking +existing LMTP-based content filters. </p> + +%PARAM always_add_missing_headers no + +<p> Always add (Resent-) From:, To:, Date: or Message-ID: headers +when not present. Postfix 2.6 and later add these headers only +when clients match the local_header_rewrite_clients parameter +setting. Earlier Postfix versions always add these headers; this +may break DKIM signatures that cover non-existent headers. +The undisclosed_recipients_header parameter setting determines +whether a To: header will be added. </p> + +%PARAM lmtp_header_checks + +<p> The LMTP-specific version of the smtp_header_checks configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM lmtp_mime_header_checks + +<p> The LMTP-specific version of the smtp_mime_header_checks +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM lmtp_nested_header_checks + +<p> The LMTP-specific version of the smtp_nested_header_checks +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM lmtp_body_checks + +<p> The LMTP-specific version of the smtp_body_checks configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.5 and later. </p> + +%PARAM milter_header_checks + +<p> Optional lookup tables for content inspection of message headers +that are produced by Milter applications. See the header_checks(5) +manual page available actions. Currently, PREPEND is not implemented. +</p> + +<p> The following example sends all mail that is marked as SPAM to +a spam handling machine. Note that matches are case-insensitive +by default. </p> + +<pre> +/etc/postfix/main.cf: + milter_header_checks = pcre:/etc/postfix/milter_header_checks +</pre> + +<pre> +/etc/postfix/milter_header_checks: + /^X-SPAM-FLAG:\s+YES/ FILTER mysmtp:sanitizer.example.com:25 +</pre> + +<p> The milter_header_checks mechanism could also be used for +allowlisting. For example it could be used to skip heavy content +inspection for DKIM-signed mail from known friendly domains. </p> + +<p> This feature is available in Postfix 2.7, and as an optional +patch for Postfix 2.6. </p> + +%PARAM postscreen_cache_map btree:$data_directory/postscreen_cache + +<p> Persistent storage for the postscreen(8) server decisions. </p> + +<p> To share a postscreen(8) cache between multiple postscreen(8) +instances, use "postscreen_cache_map = proxy:btree:/path/to/file". +This requires Postfix version 2.9 or later; earlier proxymap(8) +implementations don't support cache cleanup. For an alternative +approach see the memcache_table(5) manpage. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM smtpd_service_name smtpd + +<p> The internal service that postscreen(8) hands off allowed +connections to. In a future version there may be different +classes of SMTP service. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_post_queue_limit $default_process_limit + +<p> The number of clients that can be waiting for service from a +real Postfix SMTP server process. When this queue is full, all +clients will +receive a 421 response. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_pre_queue_limit $default_process_limit + +<p> The number of non-allowlisted clients that can be waiting for +a decision whether they will receive service from a real Postfix +SMTP server +process. When this queue is full, all non-allowlisted clients will +receive a 421 response. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_greet_ttl 1d + +<p> The amount of time that postscreen(8) will use the result from +a successful PREGREET test. During this time, the client IP address +is excluded from this test. The default is relatively short, because +a good client can immediately talk to a real Postfix SMTP server. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is d (days). </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_cache_retention_time 7d + +<p> The amount of time that postscreen(8) will cache an expired +temporary allowlist entry before it is removed. This prevents clients +from being logged as "NEW" just because their cache entry expired +an hour ago. It also prevents the cache from filling up with clients +that passed some deep protocol test once and never came back. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is d (days). </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_cache_cleanup_interval 12h + +<p> The amount of time between postscreen(8) cache cleanup runs. +Cache cleanup increases the load on the cache database and should +therefore not be run frequently. This feature requires that the +cache database supports the "delete" and "sequence" operators. +Specify a zero interval to disable cache cleanup. </p> + +<p> After each cache cleanup run, the postscreen(8) daemon logs the +number of entries that were retained and dropped. A cleanup run is +logged as "partial" when the daemon terminates early after "<b>postfix +reload</b>", "<b>postfix stop</b>", or no requests for $max_idle +seconds. </p> + +<p> Specify a non-negative time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is h (hours). </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_greet_wait normal: 6s, overload: 2s + +<p> The amount of time that postscreen(8) will wait for an SMTP +client to send a command before its turn, and for DNS blocklist +lookup results to arrive (default: up to 2 seconds under stress, +up to 6 seconds otherwise). <p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_dnsbl_sites + +<p>Optional list of DNS allow/denylist domains, filters and weight +factors. When the list is non-empty, the dnsblog(8) daemon will +query these domains with the IP addresses of remote SMTP clients, +and postscreen(8) will update an SMTP client's DNSBL score with +each non-error reply. </p> + +<p> Caution: when postscreen rejects mail, it replies with the DNSBL +domain name. Use the postscreen_dnsbl_reply_map feature to hide +"password" information in DNSBL domain names. </p> + +<p> When a client's score is equal to or greater than the threshold +specified with postscreen_dnsbl_threshold, postscreen(8) can drop +the connection with the remote SMTP client. </p> + +<p> Specify a list of domain=filter*weight entries, separated by +comma or whitespace. </p> + +<ul> + +<li> <p> When no "=filter" is specified, postscreen(8) will use any +non-error DNSBL reply. Otherwise, postscreen(8) uses only DNSBL +replies that match the filter. The filter has the form d.d.d.d, +where each d is a number, or a pattern inside [] that contains one +or more ";"-separated numbers or number..number ranges. </p> + +<li> <p> When no "*weight" is specified, postscreen(8) increments +the remote SMTP client's DNSBL score by 1. Otherwise, the weight must be +an integral number, and postscreen(8) adds the specified weight to +the remote SMTP client's DNSBL score. Specify a negative number for +allowlisting. </p> + +<li> <p> When one postscreen_dnsbl_sites entry produces multiple +DNSBL responses, postscreen(8) applies the weight at most once. +</p> + +</ul> + +<p> Examples: </p> + +<p> To use example.com as a high-confidence blocklist, and to +block mail with example.net and example.org only when both agree: +</p> + +<pre> +postscreen_dnsbl_threshold = 2 +postscreen_dnsbl_sites = example.com*2, example.net, example.org +</pre> + +<p> To filter only DNSBL replies containing 127.0.0.4: </p> + +<pre> +postscreen_dnsbl_sites = example.com=127.0.0.4 +</pre> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_dnsbl_action ignore + +<p>The action that postscreen(8) takes when a remote SMTP client's combined +DNSBL score is equal to or greater than a threshold (as defined +with the postscreen_dnsbl_sites and postscreen_dnsbl_threshold +parameters). Specify one of the following: </p> + +<dl> + +<dt> <b>ignore</b> (default) </dt> + +<dd> Ignore the failure of this test. Allow other tests to complete. +Repeat this test the next time the client connects. +This option is useful for testing and collecting statistics +without blocking mail. </dd> + +<dt> <b>enforce</b> </dt> + +<dd> Allow other tests to complete. Reject attempts to deliver mail +with a 550 SMTP reply, and log the helo/sender/recipient information. +Repeat this test the next time the client connects. </dd> + +<dt> <b>drop</b> </dt> + +<dd> Drop the connection immediately with a 521 SMTP reply. Repeat +this test the next time the client connects. </dd> + +</dl> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_greet_action ignore + +<p>The action that postscreen(8) takes when a remote SMTP client speaks +before its turn within the time specified with the postscreen_greet_wait +parameter. Specify one of the following: </p> + +<dl> + +<dt> <b>ignore</b> (default) </dt> + +<dd> Ignore the failure of this test. Allow other tests to complete. +Repeat this test the next time the client connects. +This option is useful for testing and collecting statistics +without blocking mail. </dd> + +<dt> <b>enforce</b> </dt> + +<dd> Allow other tests to complete. Reject attempts to deliver mail +with a 550 SMTP reply, and log the helo/sender/recipient information. +Repeat this test the next time the client connects. </dd> + +<dt> <b>drop</b> </dt> + +<dd> Drop the connection immediately with a 521 SMTP reply. Repeat +this test the next time the client connects. </dd> + +</dl> + +<p> In either case, postscreen(8) will not allowlist the remote SMTP client +IP address. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_access_list permit_mynetworks + +<p> Permanent allow/denylist for remote SMTP client IP addresses. +postscreen(8) searches this list immediately after a remote SMTP +client connects. Specify a comma- or whitespace-separated list of +commands (in upper or lower case) or lookup tables. The search stops +upon the first command that fires for the client IP address. </p> + +<dl> + +<dt> <b> permit_mynetworks </b> </dt> <dd> Allowlist the client and +terminate the search if the client IP address matches $mynetworks. +Do not subject the client to any before/after 220 greeting tests. +Pass the connection immediately to a Postfix SMTP server process. +<br> Pattern matching of domain names is controlled by the presence +or absence of "postscreen_access_list" in the +parent_domain_matches_subdomains parameter value. </dd> + +<dt> <b> type:table </b> </dt> <dd> Query the specified lookup +table. Each table lookup result is an access list, except that +access lists inside a table cannot specify type:table entries. <br> +To discourage the use of hash, btree, etc. tables, there is no +support for substring matching like smtpd(8). Use CIDR tables +instead. </dd> + +<dt> <b> permit </b> </dt> <dd> Allowlist the client and terminate +the search. Do not subject the client to any before/after 220 +greeting tests. Pass the connection immediately to a Postfix SMTP +server process. </dd> + +<dt> <b> reject </b> </dt> <dd> Denylist the client and terminate +the search. Subject the client to the action configured with the +postscreen_denylist_action configuration parameter. </dd> + +<dt> <b> dunno </b> </dt> <dd> All postscreen(8) access lists +implicitly have this command at the end. <br> When <b> dunno </b> +is executed inside a lookup table, return from the lookup table and +evaluate the next command. <br> When <b> dunno </b> is executed +outside a lookup table, terminate the search, and subject the client +to the configured before/after 220 greeting tests. </dd> + +</dl> + +<p> Example: </p> + +<pre> +/etc/postfix/main.cf: + postscreen_access_list = permit_mynetworks, + cidr:/etc/postfix/postscreen_access.cidr + # Postfix < 3.6 use postscreen_blacklist_action. + postscreen_denylist_action = enforce +</pre> + +<pre> +/etc/postfix/postscreen_access.cidr: + # Rules are evaluated in the order as specified. + # Denylist 192.168.* except 192.168.0.1. + 192.168.0.1 dunno + 192.168.0.0/16 reject +</pre> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_greet_banner $smtpd_banner + +<p> The <i>text</i> in the optional "220-<i>text</i>..." server +response that +postscreen(8) sends ahead of the real Postfix SMTP server's "220 +text..." response, in an attempt to confuse bad SMTP clients so +that they speak before their turn (pre-greet). Specify an empty +value to disable this feature. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_blacklist_action ignore + +<p> Renamed to postscreen_denylist_action in Postfix 3.6. </p> + +<p> This feature is available in Postfix 2.8 - 3.5. </p> + +%PARAM postscreen_denylist_action ignore + +<p> The action that postscreen(8) takes when a remote SMTP client is +permanently denylisted with the postscreen_access_list parameter. +Specify one of the following: </p> + +<dl> + +<dt> <b>ignore</b> (default) </dt> + +<dd> Ignore this result. Allow other tests to complete. Repeat +this test the next time the client connects. +This option is useful for testing and collecting statistics +without blocking mail. </dd> + +<dt> <b>enforce</b> </dt> + +<dd> Allow other tests to complete. Reject attempts to deliver mail +with a 550 SMTP reply, and log the helo/sender/recipient information. +Repeat this test the next time the client connects. </dd> + +<dt> <b>drop</b> </dt> + +<dd> Drop the connection immediately with a 521 SMTP reply. Repeat +this test the next time the client connects. </dd> + +</dl> + +<p> This feature is available in Postfix 3.6 and later. </p> + +<p> Available as postscreen_blacklist_action in Postfix 2.8 - 3.5. </p> + +%PARAM smtpd_command_filter + +<p> A mechanism to transform commands from remote SMTP clients. +This is a last-resort tool to work around client commands that break +interoperability with the Postfix SMTP server. Other uses involve +fault injection to test Postfix's handling of invalid commands. +</p> + +<p> Specify the name of a "type:table" lookup table. The search +string is the SMTP command as received from the remote SMTP client, +except that initial whitespace and the trailing <CR><LF> +are removed. The result value is executed by the Postfix SMTP +server. </p> + +<p> There is no need to use smtpd_command_filter for the following +cases: </p> + +<ul> + +<li> <p> Use "resolve_numeric_domain = yes" to accept +"<i>user@ipaddress</i>". </p> + +<li> <p> Postfix already accepts the correct form +"<i>user@[ipaddress]</i>". Use virtual_alias_maps or canonical_maps +to translate these into domain names if necessary. </p> + +<li> <p> Use "strict_rfc821_envelopes = no" to accept "RCPT TO:<<i>User +Name <user@example.com>></i>". Postfix will ignore the "<i>User +Name</i>" part and deliver to the <i><user@example.com></i> address. +</p> + +</ul> + +<p> Examples of problems that can be solved with the smtpd_command_filter +feature: </p> + +<pre> +/etc/postfix/main.cf: + smtpd_command_filter = pcre:/etc/postfix/command_filter +</pre> + +<pre> +/etc/postfix/command_filter: + # Work around clients that send malformed HELO commands. + /^HELO\s*$/ HELO domain.invalid +</pre> + +<pre> + # Work around clients that send empty lines. + /^\s*$/ NOOP +</pre> + +<pre> + # Work around clients that send RCPT TO:<'user@domain'>. + # WARNING: do not lose the parameters that follow the address. + /^(RCPT\s+TO:\s*<)'([^[:space:]]+)'(>.*)/ $1$2$3 +</pre> + +<pre> + # Append XVERP to MAIL FROM commands to request VERP-style delivery. + # See VERP_README for more information on how to use Postfix VERP. + /^(MAIL\s+FROM:\s*<listname@example\.com>.*)/ $1 XVERP +</pre> + +<pre> + # Bounce-never mail sink. Use notify_classes=bounce,resource,software + # to send bounced mail to the postmaster (with message body removed). + /^(RCPT\s+TO:\s*<.*>.*)\s+NOTIFY=\S+(.*)/ $1 NOTIFY=NEVER$2 + /^(RCPT\s+TO:.*)/ $1 NOTIFY=NEVER +</pre> + +<p> This feature is available in Postfix 2.7. </p> + +%PARAM smtp_reply_filter + +<p> A mechanism to transform replies from remote SMTP servers one +line at a time. This is a last-resort tool to work around server +replies that break interoperability with the Postfix SMTP client. +Other uses involve fault injection to test Postfix's handling of +invalid responses. </p> + +<p> Notes: </p> + +<ul> + +<li> <p> In the case of a multi-line reply, the Postfix SMTP client +uses the final reply line's numerical SMTP reply code and enhanced +status code. </p> + +<li> <p> The numerical SMTP reply code (XYZ) takes precedence over +the enhanced status code (X.Y.Z). When the enhanced status code +initial digit differs from the SMTP reply code initial digit, or +when no enhanced status code is present, the Postfix SMTP client +uses a generic enhanced status code (X.0.0) instead. </p> + +</ul> + +<p> Specify the name of a "type:table" lookup table. The search +string is a single SMTP reply line as received from the remote SMTP +server, except that the trailing <CR><LF> are removed. +When the lookup succeeds, the result replaces the single SMTP reply +line. </p> + +<p> Examples: </p> + +<pre> +/etc/postfix/main.cf: + smtp_reply_filter = pcre:/etc/postfix/reply_filter +</pre> + +<pre> +/etc/postfix/reply_filter: + # Transform garbage into "250-filler..." so that it looks like + # one line from a multi-line reply. It does not matter what we + # substitute here as long it has the right syntax. The Postfix + # SMTP client will use the final line's numerical SMTP reply + # code and enhanced status code. + !/^([2-5][0-9][0-9]($|[- ]))/ 250-filler for garbage +</pre> + +<p> This feature is available in Postfix 2.7. </p> + +%PARAM lmtp_reply_filter + +<p> The LMTP-specific version of the smtp_reply_filter +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.7 and later. </p> + +%PARAM smtp_tls_block_early_mail_reply no + +<p> Try to detect a mail hijacking attack based on a TLS protocol +vulnerability (CVE-2009-3555), where an attacker prepends malicious +HELO, MAIL, RCPT, DATA commands to a Postfix SMTP client TLS session. +The attack would succeed with non-Postfix SMTP servers that reply +to the malicious HELO, MAIL, RCPT, DATA commands after negotiating +the Postfix SMTP client TLS session. </p> + +<p> This feature is available in Postfix 2.7. </p> + +%PARAM lmtp_tls_block_early_mail_reply + +<p> The LMTP-specific version of the smtp_tls_block_early_mail_reply +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.7 and later. </p> + +%PARAM empty_address_default_transport_maps_lookup_key <> + +<p> The sender_dependent_default_transport_maps search string that +will be used instead of the null sender address. </p> + +<p> This feature is available in Postfix 2.7 and later. </p> + +%PARAM sender_dependent_default_transport_maps + +<p> A sender-dependent override for the global default_transport +parameter setting. The tables are searched by the envelope sender +address and @domain. A lookup result of DUNNO terminates the search +without overriding the global default_transport parameter setting. +This information is overruled with the transport(5) table. </p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> Note: this overrides default_transport, not transport_maps, and +therefore the expected syntax is that of default_transport, not the +syntax of transport_maps. Specifically, this does not support the +transport_maps syntax for null transport, null nexthop, or null +email addresses. </p> + +<p> For safety reasons, this feature does not allow $number +substitutions in regular expression maps. </p> + +<p> This feature is available in Postfix 2.7 and later. </p> + +%PARAM address_verify_sender_dependent_default_transport_maps $sender_dependent_default_transport_maps + +<p> Overrides the sender_dependent_default_transport_maps parameter +setting for address verification probes. </p> + +<p> This feature is available in Postfix 2.7 and later. </p> + +%PARAM default_filter_nexthop + +<p> When a content_filter or FILTER request specifies no explicit +next-hop destination, use $default_filter_nexthop instead; when +that value is empty, use the domain in the recipient address. +Specify "default_filter_nexthop = $myhostname" for compatibility +with Postfix version 2.6 and earlier, or specify an explicit next-hop +destination with each content_filter value or FILTER action. </p> + +<p> This feature is available in Postfix 2.7 and later. </p> + +%PARAM smtp_address_preference any + +<p> The address type ("ipv6", "ipv4" or "any") that the Postfix +SMTP client will try first, when a destination has IPv6 and IPv4 +addresses with equal MX preference. This feature has no effect +unless the inet_protocols setting enables both IPv4 and IPv6. </p> + +<p> Postfix SMTP client address preference has evolved. With Postfix +2.8 the default is "ipv6"; earlier implementations are hard-coded +to prefer IPv6 over IPv4. </p> + +<p> Notes for mail delivery between sites that have both IPv4 and +IPv6 connectivity: </p> + +<ul> + +<li> <p> The setting "smtp_address_preference = ipv6" is unsafe. +It can fail to deliver mail when there is an outage that affects +IPv6, while the destination is still reachable over IPv4. </p> + +<li> <p> The setting "smtp_address_preference = any" is safe. With +this, mail will eventually be delivered even if there is an outage +that affects IPv6 or IPv4, as long as it does not affect both. </p> + +</ul> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM lmtp_address_preference ipv6 + +<p> The LMTP-specific version of the smtp_address_preference +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM smtp_dns_resolver_options + +<p> DNS Resolver options for the Postfix SMTP client. Specify zero +or more of the following options, separated by comma or whitespace. +Option names are case-sensitive. Some options refer to domain names +that are specified in the file /etc/resolv.conf or equivalent. </p> + +<dl> + +<dt><b>res_defnames</b></dt> + +<dd> Append the current domain name to single-component names (those +that do not contain a "." character). This can produce incorrect +results, and is the hard-coded behavior prior to Postfix 2.8. </dd> + +<dt><b>res_dnsrch</b></dt> + +<dd> Search for host names in the current domain and in parent +domains. This can produce incorrect results and is therefore not +recommended. </dd> + +</dl> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM lmtp_dns_resolver_options + +<p> The LMTP-specific version of the smtp_dns_resolver_options +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM postscreen_dnsbl_threshold 1 + +<p> The inclusive lower bound for blocking a remote SMTP client, based on +its combined DNSBL score as defined with the postscreen_dnsbl_sites +parameter. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_dnsbl_whitelist_threshold 0 + +<p> Renamed to postscreen_dnsbl_allowlist_threshold in Postfix 3.6. </p> + +<p> This feature is available in Postfix 2.11 - 3.5. </p> + +%PARAM postscreen_dnsbl_allowlist_threshold 0 + +<p> Allow a remote SMTP client to skip "before" and "after 220 +greeting" protocol tests, based on its combined DNSBL score as +defined with the postscreen_dnsbl_sites parameter. </p> + +<p> Specify a negative value to enable this feature. When a client +passes the postscreen_dnsbl_allowlist_threshold without having +failed other tests, all pending or disabled tests are flagged as +completed with a time-to-live value equal to postscreen_dnsbl_ttl. +When a test was already completed, its time-to-live value is updated +if it was less than postscreen_dnsbl_ttl. </p> + +<p> This feature is available in Postfix 3.6 and later. </p> + +<p> Available as postscreen_dnsbl_whitelist_threshold in Postfix 2.11 +- 3.5. </p> + +%PARAM postscreen_command_count_limit 20 + +<p> The limit on the total number of commands per SMTP session for +postscreen(8)'s built-in SMTP protocol engine. This SMTP engine +defers or rejects all attempts to deliver mail, therefore there is +no need to enforce separate limits on the number of junk commands +and error commands. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_command_time_limit normal: 300s, overload: 10s + +<p> The time limit to read an entire command line with postscreen(8)'s +built-in SMTP protocol engine. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_dnsbl_ttl 1h + +<p> The amount of time that postscreen(8) will use the result from +a successful DNS-based reputation test before a client +IP address is required to pass that test again. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is h (hours). </p> + +<p> This feature is available in Postfix 2.8-3.0. It was +replaced by postscreen_dnsbl_max_ttl in Postfix 3.1. </p> + +%PARAM postscreen_dnsbl_min_ttl 60s + +<p> The minimum amount of time that postscreen(8) will use the +result from a successful DNS-based reputation test before a +client IP address is required to pass that test again. If the DNS +reply specifies a larger TTL value, that value will be used unless +it would be larger than postscreen_dnsbl_max_ttl. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 3.1. </p> + +%PARAM postscreen_dnsbl_max_ttl ${postscreen_dnsbl_ttl?{$postscreen_dnsbl_ttl}:{1}}h + +<p> The maximum amount of time that postscreen(8) will use the +result from a successful DNS-based reputation test before a +client IP address is required to pass that test again. If the DNS +reply specifies a shorter TTL value, that value will be used unless +it would be smaller than postscreen_dnsbl_min_ttl. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is h (hours). </p> + +<p> This feature is available in Postfix 3.1. The default setting +is backwards-compatible with older Postfix versions. </p> + +%PARAM postscreen_pipelining_action enforce + +<p> The action that postscreen(8) takes when a remote SMTP client +sends +multiple commands instead of sending one command and waiting for +the server to respond. Specify one of the following: </p> + +<dl> + +<dt> <b>ignore</b> </dt> + +<dd> Ignore the failure of this test. Allow other tests to complete. +Do <i>not</i> repeat this test before the result from some +other test expires. +This option is useful for testing and collecting statistics +without blocking mail permanently. </dd> + +<dt> <b>enforce</b> </dt> + +<dd> Allow other tests to complete. Reject attempts to deliver mail +with a 550 SMTP reply, and log the helo/sender/recipient information. +Repeat this test the next time the client connects. </dd> + +<dt> <b>drop</b> </dt> + +<dd> Drop the connection immediately with a 521 SMTP reply. Repeat +this test the next time the client connects. </dd> + +</dl> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_pipelining_ttl 30d + +<p> The amount of time that postscreen(8) will use the result from +a successful "pipelining" SMTP protocol test. During this time, the +client IP address is excluded from this test. The default is +long because a good client must disconnect after it passes the test, +before it can talk to a real Postfix SMTP server. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is d (days). </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_pipelining_enable no + +<p> Enable "pipelining" SMTP protocol tests in the postscreen(8) +server. These tests are expensive: a good client must disconnect +after it passes the test, before it can talk to a real Postfix SMTP +server. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_watchdog_timeout 10s + +<p> How much time a postscreen(8) process may take to respond to +a remote SMTP client command or to perform a cache operation before it +is terminated by a built-in watchdog timer. This is a safety +mechanism that prevents postscreen(8) from becoming non-responsive +due to a bug in Postfix itself or in system software. To avoid +false alarms and unnecessary cache corruption this limit cannot be +set under 10s. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_helo_required $smtpd_helo_required + +<p> Require that a remote SMTP client sends HELO or EHLO before +commencing a MAIL transaction. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_forbidden_commands $smtpd_forbidden_commands + +<p> List of commands that the postscreen(8) server considers in +violation of the SMTP protocol. See smtpd_forbidden_commands for +syntax, and postscreen_non_smtp_command_action for possible actions. +</p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_disable_vrfy_command $disable_vrfy_command + +<p> Disable the SMTP VRFY command in the postscreen(8) daemon. See +disable_vrfy_command for details. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_non_smtp_command_action drop + +<p> The action that postscreen(8) takes when a remote SMTP client sends +non-SMTP commands as specified with the postscreen_forbidden_commands +parameter. Specify one of the following: </p> + +<dl> + +<dt> <b>ignore</b> </dt> + +<dd> Ignore the failure of this test. Allow other tests to complete. +Do <i>not</i> repeat this test before the result from some +other test expires. +This option is useful for testing and collecting statistics +without blocking mail permanently. </dd> + +<dt> <b>enforce</b> </dt> + +<dd> Allow other tests to complete. Reject attempts to deliver mail +with a 550 SMTP reply, and log the helo/sender/recipient information. +Repeat this test the next time the client connects. </dd> + +<dt> <b>drop</b> </dt> + +<dd> Drop the connection immediately with a 521 SMTP reply. Repeat +this test the next time the client connects. This action is the +same as with the Postfix SMTP server's smtpd_forbidden_commands +feature. </dd> + +</dl> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_non_smtp_command_ttl 30d + +<p> The amount of time that postscreen(8) will use the result from +a successful "non_smtp_command" SMTP protocol test. During this +time, the client IP address is excluded from this test. The default +is long because a client must disconnect after it passes the test, +before it can talk to a real Postfix SMTP server. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is d (days). </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_non_smtp_command_enable no + +<p> Enable "non-SMTP command" tests in the postscreen(8) server. These +tests are expensive: a client must disconnect after it passes the +test, before it can talk to a real Postfix SMTP server. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_dnsbl_reply_map + +<p> A mapping from an actual DNSBL domain name which includes a secret +password, to the DNSBL domain name that postscreen will reply with +when it rejects mail. When no mapping is found, the actual DNSBL +domain will be used. </p> + +<p> For maximal stability it is best to use a file that is read +into memory such as pcre:, regexp: or texthash: (texthash: is similar +to hash:, except a) there is no need to run postmap(1) before the +file can be used, and b) texthash: does not detect changes after +the file is read). </p> + +<p> Example: </p> + +<pre> +/etc/postfix/main.cf: + postscreen_dnsbl_reply_map = texthash:/etc/postfix/dnsbl_reply +</pre> + +<pre> +/etc/postfix/dnsbl_reply: + secret.zen.spamhaus.org zen.spamhaus.org +</pre> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_dnsbl_timeout 10s + +<p> The time limit for DNSBL or DNSWL lookups. This is separate from +the timeouts in the dnsblog(8) daemon which are defined by system +resolver(3) routines. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 3.0. </p> +%PARAM postscreen_bare_newline_action ignore + +<p> The action that postscreen(8) takes when a remote SMTP client sends +a bare newline character, that is, a newline not preceded by carriage +return. Specify one of the following: </p> + +<dl> + +<dt> <b>ignore</b> </dt> + +<dd> Ignore the failure of this test. Allow other tests to complete. +Do <i>not</i> repeat this test before the result from some +other test expires. +This option is useful for testing and collecting statistics +without blocking mail permanently. </dd> + +<dt> <b>enforce</b> </dt> + +<dd> Allow other tests to complete. Reject attempts to deliver mail +with a 550 SMTP reply, and log the helo/sender/recipient information. +Repeat this test the next time the client connects. </dd> + +<dt> <b>drop</b> </dt> + +<dd> Drop the connection immediately with a 521 SMTP reply. Repeat +this test the next time the client connects. </dd> + +</dl> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_bare_newline_ttl 30d + +<p> The amount of time that postscreen(8) will use the result from +a successful "bare newline" SMTP protocol test. During this +time, the client IP address is excluded from this test. The default +is long because a remote SMTP client must disconnect after it passes +the test, +before it can talk to a real Postfix SMTP server. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is d (days). </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_bare_newline_enable no + +<p> Enable "bare newline" SMTP protocol tests in the postscreen(8) +server. These tests are expensive: a remote SMTP client must +disconnect after +it passes the test, before it can talk to a real Postfix SMTP server. +</p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM postscreen_client_connection_count_limit $smtpd_client_connection_count_limit + +<p> How many simultaneous connections any remote SMTP client is +allowed to have +with the postscreen(8) daemon. By default, this limit is the same +as with the Postfix SMTP server. Note that the triage process can +take several seconds, with the time spent in postscreen_greet_wait +delay, and with the time spent talking to the postscreen(8) built-in +dummy SMTP protocol engine. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM dnsblog_reply_delay 0s + +<p> A debugging aid to artificially delay DNS responses. </p> + +<p> This feature is available in Postfix 2.8. </p> + +%PARAM reset_owner_alias no + +<p> Reset the local(8) delivery agent's idea of the owner-alias +attribute, when delivering mail to a child alias that does not have +its own owner alias. </p> + +<p> This feature is available in Postfix 2.8 and later. With older +Postfix releases, the behavior is as if this parameter is set to +"yes". </p> + +<p> As documented in aliases(5), when an alias <i>name</i> has a +companion alias named owner-<i>name</i>, this will replace the +envelope sender address, so that delivery errors will be +reported to the owner alias instead of the sender. This configuration +is recommended for mailing lists. <p> + +<p> A less known property of the owner alias is that it also forces +the local(8) delivery agent to write local and remote addresses +from alias expansion to a new queue file, instead of attempting to +deliver mail to local addresses as soon as they come out of alias +expansion. </p> + +<p> Writing local addresses from alias expansion to a new queue +file allows for robust handling of temporary delivery errors: errors +with one local member have no effect on deliveries to other members +of the list. On the other hand, delivery to local addresses as +soon as they come out of alias expansion is fragile: a temporary +error with one local address from alias expansion will cause the +entire alias to be expanded repeatedly until the error goes away, +or until the message expires in the queue. In that case, a problem +with one list member results in multiple message deliveries to other +list members. </p> + +<p> The default behavior of Postfix 2.8 and later is to keep the +owner-alias attribute of the parent alias, when delivering mail to +a child alias that does not have its own owner alias. Then, local +addresses from that child alias will be written to a new queue file, +and a temporary error with one local address will not affect delivery +to other mailing list members. </p> + +<p> Unfortunately, older Postfix releases reset the owner-alias +attribute when delivering mail to a child alias that does not have +its own owner alias. To be precise, this resets only the decision +to create a new queue file, not the decision to override the envelope +sender address. The local(8) delivery agent then attempts to +deliver local addresses as soon as they come out of child alias +expansion. If delivery to any address from child alias expansion +fails with a temporary error condition, the entire mailing list may +be expanded repeatedly until the mail expires in the queue, resulting +in multiple deliveries of the same message to mailing list members. +</p> + +%PARAM qmgr_ipc_timeout 60s + +<p> The time limit for the queue manager to send or receive information +over an internal communication channel. The purpose is to break +out of deadlock situations. If the time limit is exceeded the +software either retries or aborts the operation. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM qmgr_daemon_timeout 1000s + +<p> How much time a Postfix queue manager process may take to handle +a request before it is terminated by a built-in watchdog timer. +</p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tls_preempt_cipherlist no + +<p> With SSLv3 and later, use the Postfix SMTP server's cipher +preference order instead of the remote client's cipher preference +order. </p> + +<p> By default, the OpenSSL server selects the client's most preferred +cipher that the server supports. With SSLv3 and later, the server may +choose its own most preferred cipher that is supported (offered) by +the client. Setting "tls_preempt_cipherlist = yes" enables server cipher +preferences. </p> + +<p> While server cipher selection may in some cases lead to a more secure +or performant cipher choice, there is some risk of interoperability +issues. In the past, some SSL clients have listed lower priority ciphers +that they did not implement correctly. If the server chooses a cipher +that the client prefers less, it may select a cipher whose client +implementation is flawed. Most notably Windows 2003 Microsoft +Exchange servers have flawed implementations of DES-CBC3-SHA, which +OpenSSL considers stronger than RC4-SHA. Enabling server cipher-suite +selection may create interoperability issues with Windows 2003 +Microsoft Exchange clients. </p> + +<p> This feature is available in Postfix 2.8 and later, in combination +with OpenSSL 0.9.7 and later. </p> + +%PARAM tls_disable_workarounds see "postconf -d" output + +<p> List or bit-mask of OpenSSL bug work-arounds to disable. </p> + +<p> The OpenSSL toolkit includes a set of work-arounds for buggy SSL/TLS +implementations. Applications, such as Postfix, that want to maximize +interoperability ask the OpenSSL library to enable the full set of +recommended work-arounds. </p> + +<p> From time to time, it is discovered that a work-around creates a +security issue, and should no longer be used. If upgrading OpenSSL +to a fixed version is not an option or an upgrade is not available +in a timely manner, or in closed environments where no buggy clients +or servers exist, it may be appropriate to disable some or all of the +OpenSSL interoperability work-arounds. This parameter specifies which +bug work-arounds to disable. </p> + +<p> If the value of the parameter is a hexadecimal long integer starting +with "0x", the bug work-arounds corresponding to the bits specified in +its value are removed from the <b>SSL_OP_ALL</b> work-around bit-mask +(see openssl/ssl.h and SSL_CTX_set_options(3)). You can specify more +bits than are present in SSL_OP_ALL, excess bits are ignored. Specifying +0xFFFFFFFF disables all bug-workarounds on a 32-bit system. This should +also be sufficient on 64-bit systems, until OpenSSL abandons support +for 32-bit systems and starts using the high 32 bits of a 64-bit +bug-workaround mask. </p> + +<p> Otherwise, the parameter is a white-space or comma separated list +of specific named bug work-arounds chosen from the list below. It +is possible that your OpenSSL version includes new bug work-arounds +added after your Postfix source code was last updated, in that case +you can only disable one of these via the hexadecimal syntax above. </p> + +<dl> + +<dt><b>CRYPTOPRO_TLSEXT_BUG</b></dt> <dd>New with GOST support in +OpenSSL 1.0.0.</dd> + +<dt><b>DONT_INSERT_EMPTY_FRAGMENTS</b></dt> <dd>See +SSL_CTX_set_options(3)</dd> + +<dt><b>LEGACY_SERVER_CONNECT</b></dt> <dd>See SSL_CTX_set_options(3)</dd> + +<dt><b>MICROSOFT_BIG_SSLV3_BUFFER</b></dt> <dd>See +SSL_CTX_set_options(3)</dd> + +<dt><b>MICROSOFT_SESS_ID_BUG</b></dt> <dd>See SSL_CTX_set_options(3)</dd> + +<dt><b>MSIE_SSLV2_RSA_PADDING</b></dt> <dd> also aliased as +<b>CVE-2005-2969</b>. Postfix 2.8 disables this work-around by +default with OpenSSL versions that may predate the fix. Fixed in +OpenSSL 0.9.7h and OpenSSL 0.9.8a.</dd> + +<dt><b>NETSCAPE_CHALLENGE_BUG</b></dt> <dd>See SSL_CTX_set_options(3)</dd> + +<dt><b>NETSCAPE_REUSE_CIPHER_CHANGE_BUG</b></dt> <dd> also aliased +as <b>CVE-2010-4180</b>. Postfix 2.8 disables this work-around by +default with OpenSSL versions that may predate the fix. Fixed in +OpenSSL 0.9.8q and OpenSSL 1.0.0c.</dd> + +<dt><b>SSLEAY_080_CLIENT_DH_BUG</b></dt> <dd>See +SSL_CTX_set_options(3)</dd> + +<dt><b>SSLREF2_REUSE_CERT_TYPE_BUG</b></dt> <dd>See +SSL_CTX_set_options(3)</dd> + +<dt><b>TLS_BLOCK_PADDING_BUG</b></dt> <dd>See SSL_CTX_set_options(3)</dd> + +<dt><b>TLS_D5_BUG</b></dt> <dd>See SSL_CTX_set_options(3)</dd> + +<dt><b>TLS_ROLLBACK_BUG</b></dt> <dd>See SSL_CTX_set_options(3). +This is disabled in OpenSSL 0.9.7 and later. Nobody should still +be using 0.9.6! </dd> + +<dt><b>TLSEXT_PADDING</b></dt><dd>Postfix ≥ 3.4. See SSL_CTX_set_options(3).</dd> + +</dl> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tls_legacy_public_key_fingerprints no + +<p> A temporary migration aid for sites that use certificate +<i>public-key</i> fingerprints with Postfix 2.9.0..2.9.5, which use +an incorrect algorithm. This parameter has no effect on the certificate +fingerprint support that is available since Postfix 2.2. </p> + +<p> Specify "tls_legacy_public_key_fingerprints = yes" temporarily, +pending a migration from configuration files with incorrect Postfix +2.9.0..2.9.5 certificate public-key finger prints, to the correct +fingerprints used by Postfix 2.9.6 and later. To compute the correct +certificate public-key fingerprints, see TLS_README. </p> + +<p> This feature is available in Postfix 2.9.6 and later. </p> + +%PARAM tlsproxy_watchdog_timeout 10s + +<p> How much time a tlsproxy(8) process may take to process local +or remote I/O before it is terminated by a built-in watchdog timer. +This is a safety mechanism that prevents tlsproxy(8) from becoming +non-responsive due to a bug in Postfix itself or in system software. +To avoid false alarms and unnecessary cache corruption this limit +cannot be set under 10s. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.8 and later </p> + +%PARAM postscreen_discard_ehlo_keywords $smtpd_discard_ehlo_keywords + +<p> A case insensitive list of EHLO keywords (pipelining, starttls, +auth, etc.) that the postscreen(8) server will not send in the EHLO +response to a remote SMTP client. See smtpd_discard_ehlo_keywords +for details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM postscreen_discard_ehlo_keyword_address_maps $smtpd_discard_ehlo_keyword_address_maps + +<p> Lookup tables, indexed by the remote SMTP client address, with +case insensitive lists of EHLO keywords (pipelining, starttls, auth, +etc.) that the postscreen(8) server will not send in the EHLO response +to a remote SMTP client. See smtpd_discard_ehlo_keywords for details. +The table is not searched by hostname for robustness reasons. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM postscreen_use_tls $smtpd_use_tls + +<p> Opportunistic TLS: announce STARTTLS support to remote SMTP clients, +but do not require that clients use TLS encryption. </p> + +<p> This feature is available in Postfix 2.8 and later. +Preferably, use postscreen_tls_security_level instead. </p> + +%PARAM postscreen_enforce_tls $smtpd_enforce_tls + +<p> Mandatory TLS: announce STARTTLS support to remote SMTP clients, and +require that clients use TLS encryption. See smtpd_postscreen_enforce_tls +for details. </p> + +<p> This feature is available in Postfix 2.8 and later. +Preferably, use postscreen_tls_security_level instead. </p> + +%PARAM postscreen_tls_security_level $smtpd_tls_security_level + +<p> The SMTP TLS security level for the postscreen(8) server; when +a non-empty value is specified, this overrides the obsolete parameters +postscreen_use_tls and postscreen_enforce_tls. See smtpd_tls_security_level +for details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_enforce_tls $smtpd_enforce_tls + +<p> Mandatory TLS: announce STARTTLS support to remote SMTP clients, and +require that clients use TLS encryption. See smtpd_enforce_tls for +further details. Use tlsproxy_tls_security_level instead. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_CAfile $smtpd_tls_CAfile + +<p> A file containing (PEM format) CA certificates of root CAs +trusted to sign either remote SMTP client certificates or intermediate +CA certificates. See smtpd_tls_CAfile for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_CApath $smtpd_tls_CApath + +<p> A directory containing (PEM format) CA certificates of root CAs +trusted to sign either remote SMTP client certificates or intermediate +CA certificates. See smtpd_tls_CApath for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_always_issue_session_ids $smtpd_tls_always_issue_session_ids + +<p> Force the Postfix tlsproxy(8) server to issue a TLS session id, +even when TLS session caching is turned off. See +smtpd_tls_always_issue_session_ids for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_ask_ccert $smtpd_tls_ask_ccert + +<p> Ask a remote SMTP client for a client certificate. See +smtpd_tls_ask_ccert for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_ccert_verifydepth $smtpd_tls_ccert_verifydepth + +<p> The verification depth for remote SMTP client certificates. A +depth of 1 is sufficient if the issuing CA is listed in a local CA +file. See smtpd_tls_ccert_verifydepth for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_cert_file $smtpd_tls_cert_file + +<p> File with the Postfix tlsproxy(8) server RSA certificate in PEM +format. This file may also contain the Postfix tlsproxy(8) server +private RSA key. See smtpd_tls_cert_file for further details. With +Postfix ≥ 3.4 the preferred way to configure tlsproxy server keys and +certificates is via the "tlsproxy_tls_chain_files" parameter. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_ciphers $smtpd_tls_ciphers + +<p> The minimum TLS cipher grade that the Postfix tlsproxy(8) server +will use with opportunistic TLS encryption. See smtpd_tls_ciphers +for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_dcert_file $smtpd_tls_dcert_file + +<p> File with the Postfix tlsproxy(8) server DSA certificate in PEM +format. This file may also contain the Postfix tlsproxy(8) server +private DSA key. DSA is obsolete and should not be used. See +smtpd_tls_dcert_file for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_dh1024_param_file $smtpd_tls_dh1024_param_file + +<p> File with DH parameters that the Postfix tlsproxy(8) server +should use with non-export EDH ciphers. See smtpd_tls_dh1024_param_file +for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_dh512_param_file $smtpd_tls_dh512_param_file + +<p> File with DH parameters that the Postfix tlsproxy(8) server +should use with export-grade EDH ciphers. See smtpd_tls_dh512_param_file +for further details. The default SMTP server cipher grade is +"medium" with Postfix releases after the middle of 2015, and as a +result export-grade cipher suites are by default not used. </p> + +<p> With Postfix ≥ 3.6 export-grade Diffie-Hellman key exchange +is no longer supported, and this parameter is silently ignored. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_dkey_file $smtpd_tls_dkey_file + +<p> File with the Postfix tlsproxy(8) server DSA private key in PEM +format. This file may be combined with the Postfix tlsproxy(8) server +DSA certificate file specified with $smtpd_tls_dcert_file. DSA is +obsolete and should not be used. See smtpd_tls_dkey_file for further +details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_eccert_file $smtpd_tls_eccert_file + +<p> File with the Postfix tlsproxy(8) server ECDSA certificate in PEM +format. This file may also contain the Postfix tlsproxy(8) server +private ECDSA key. See smtpd_tls_eccert_file for further details. With +Postfix ≥ 3.4 the preferred way to configure tlsproxy server keys and +certificates is via the "tlsproxy_tls_chain_files" parameter. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_eckey_file $smtpd_tls_eckey_file + +<p> File with the Postfix tlsproxy(8) server ECDSA private key in PEM +format. This file may be combined with the Postfix tlsproxy(8) server +ECDSA certificate file specified with $smtpd_tls_eccert_file. See +smtpd_tls_eckey_file for further details. With Postfix ≥ 3.4 the +preferred way to configure tlsproxy server keys and certificates is via +the "tlsproxy_tls_chain_files" parameter. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_eecdh_grade $smtpd_tls_eecdh_grade + +<p> The Postfix tlsproxy(8) server security grade for ephemeral +elliptic-curve Diffie-Hellman (EECDH) key exchange. See +smtpd_tls_eecdh_grade for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_exclude_ciphers $smtpd_tls_exclude_ciphers + +<p> List of ciphers or cipher types to exclude from the tlsproxy(8) +server cipher list at all TLS security levels. See +smtpd_tls_exclude_ciphers for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_fingerprint_digest $smtpd_tls_fingerprint_digest + +<p> The message digest algorithm to construct remote SMTP +client-certificate +fingerprints. See smtpd_tls_fingerprint_digest for further details. +</p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_key_file $smtpd_tls_key_file + +<p> File with the Postfix tlsproxy(8) server RSA private key in PEM +format. This file may be combined with the Postfix tlsproxy(8) server +RSA certificate file specified with $smtpd_tls_cert_file. See +smtpd_tls_key_file for further details. With Postfix ≥ 3.4 the +preferred way to configure tlsproxy server keys and certificates is via +the "tlsproxy_tls_chain_files" parameter. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_loglevel $smtpd_tls_loglevel + +<p> Enable additional Postfix tlsproxy(8) server logging of TLS +activity. Each logging level also includes the information that +is logged at a lower logging level. See smtpd_tls_loglevel for +further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_mandatory_ciphers $smtpd_tls_mandatory_ciphers + +<p> The minimum TLS cipher grade that the Postfix tlsproxy(8) server +will use with mandatory TLS encryption. See smtpd_tls_mandatory_ciphers +for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_mandatory_exclude_ciphers $smtpd_tls_mandatory_exclude_ciphers + +<p> Additional list of ciphers or cipher types to exclude from the +tlsproxy(8) server cipher list at mandatory TLS security levels. +See smtpd_tls_mandatory_exclude_ciphers for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_mandatory_protocols $smtpd_tls_mandatory_protocols + +<p> The SSL/TLS protocols accepted by the Postfix tlsproxy(8) server +with mandatory TLS encryption. If the list is empty, the server +supports all available SSL/TLS protocol versions. See +smtpd_tls_mandatory_protocols for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_protocols $smtpd_tls_protocols + +<p> List of TLS protocols that the Postfix tlsproxy(8) server will +exclude or include with opportunistic TLS encryption. See +smtpd_tls_protocols for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_req_ccert $smtpd_tls_req_ccert + +<p> With mandatory TLS encryption, require a trusted remote SMTP +client certificate in order to allow TLS connections to proceed. +See smtpd_tls_req_ccert for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_security_level $smtpd_tls_security_level + +<p> The SMTP TLS security level for the Postfix tlsproxy(8) server; +when a non-empty value is specified, this overrides the obsolete +parameters smtpd_use_tls and smtpd_enforce_tls. See +smtpd_tls_security_level for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_tls_session_cache_timeout $smtpd_tls_session_cache_timeout + +<p> Obsolete expiration time of Postfix tlsproxy(8) server TLS session +cache information. Since the cache is shared with smtpd(8) and managed +by tlsmgr(8), there is only one expiration time for the SMTP server cache +shared by all three services, namely smtpd_tls_session_cache_timeout. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_use_tls $smtpd_use_tls + +<p> Opportunistic TLS: announce STARTTLS support to remote SMTP clients, +but do not require that clients use TLS encryption. See smtpd_use_tls +for further details. Use tlsproxy_tls_security_level instead. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM smtpd_reject_footer + +<p> Optional information that is appended after each Postfix SMTP +server +4XX or 5XX response. </p> + +<p> The following example uses "\c" at the start of the template +(supported in Postfix 2.10 and later) to suppress the line break +between the reply text and the footer text. With earlier Postfix +versions, the footer text always begins on a new line, and the "\c" +is output literally. </p> + +<pre> +/etc/postfix/main.cf: + smtpd_reject_footer = \c. For assistance, call 800-555-0101. + Please provide the following information in your problem report: + time ($localtime), client ($client_address) and server + ($server_name). +</pre> + +<p> Server response: </p> + +<pre> + 550-5.5.1 <user@example> Recipient address rejected: User + unknown. For assistance, call 800-555-0101. Please provide the + following information in your problem report: time (Jan 4 15:42:00), + client (192.168.1.248) and server (mail1.example.com). +</pre> + +<p> Note: the above text is meant to make it easier to find the +Postfix logfile records for a failed SMTP session. The text itself +is not logged to the Postfix SMTP server's maillog file. </p> + +<p> Be sure to keep the text as short as possible. Long text may +be truncated before it is logged to the remote SMTP client's maillog +file, or before it is returned to the sender in a delivery status +notification. </p> + +<p> The template text is not subject to Postfix configuration +parameter $name expansion. Instead, this feature supports a limited +number of $name attributes in the footer text. These attributes are +replaced with their current value for the SMTP session. </p> + +<p> Note: specify $$name in footer text that is looked up from +regexp: or pcre:-based smtpd_reject_footer_maps, otherwise the +Postfix server will not use the footer text and will log a warning +instead. </p> + +<dl> + +<dt> <b>client_address</b> </dt> <dd> The Client IP address that +is logged in the maillog file. </dd> + +<dt> <b>client_port</b> </dt> <dd> The client TCP port that is +logged in the maillog file. </dd> + +<dt> <b>localtime</b> </dt> <dd> The server local time (Mmm dd +hh:mm:ss) that is logged in the maillog file. </dd> + +<dt> <b>server_name</b> </dt> <dd> The server's myhostname value. +This attribute is made available for sites with multiple MTAs +(perhaps behind a load-balancer), where the server name can help +the server support team to quickly find the right log files. </dd> + +</dl> + +<p> Notes: </p> + +<ul> + +<li> <p> NOT SUPPORTED are other attributes such as sender, recipient, +or main.cf parameters. </p> + +<li> <p> For safety reasons, text that does not match +$smtpd_expansion_filter is censored. </p> + +</ul> + +<p> This feature supports the two-character sequence \n as a request +for a line break in the footer text. Postfix automatically inserts +after each line break the three-digit SMTP reply code (and optional +enhanced status code) from the original Postfix reject message. +</p> + +<p> To work around mail software that mis-handles multi-line replies, +specify the two-character sequence \c at the start of the template. +This suppresses the line break between the reply text and the footer +text (Postfix 2.10 and later). </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM smtpd_reject_footer_maps + +<p> Lookup tables, indexed by the complete Postfix SMTP server 4xx or +5xx response, with reject footer templates. See smtpd_reject_footer +for details. </p> + +<p> +Specify zero or more "type:name" lookup tables, separated by +whitespace or comma. Tables will be searched in the specified order +until a match is found. +</p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM postscreen_expansion_filter see "postconf -d" output + +<p> List of characters that are permitted in postscreen_reject_footer +attribute expansions. See smtpd_expansion_filter for further +details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM postscreen_reject_footer $smtpd_reject_footer + +<p> Optional information that is appended after a 4XX or 5XX +postscreen(8) server +response. See smtpd_reject_footer for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM postscreen_reject_footer_maps $smtpd_reject_footer_maps + +<p> Optional lookup table for information that is appended after a 4XX +or 5XX postscreen(8) server response. See smtpd_reject_footer_maps for +further details. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM postscreen_command_filter $smtpd_command_filter + +<p> A mechanism to transform commands from remote SMTP clients. +See smtpd_command_filter for further details. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM dnsblog_service_name dnsblog + +<p> The name of the dnsblog(8) service entry in master.cf. This +service performs DNS allow/denylist lookups. </p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM tlsproxy_service_name tlsproxy + +<p> The name of the tlsproxy(8) service entry in master.cf. This +service performs plaintext <=> TLS ciphertext conversion. <p> + +<p> This feature is available in Postfix 2.8 and later. </p> + +%PARAM smtpd_per_record_deadline normal: no, overload: yes + +<p> Change the behavior of the smtpd_timeout and smtpd_starttls_timeout +time limits, from a +time limit per read or write system call, to a time limit to send +or receive a complete record (an SMTP command line, SMTP response +line, SMTP message content line, or TLS protocol message). This +limits the impact from hostile peers that trickle data one byte at +a time. </p> + +<p> Note: when per-record deadlines are enabled, a short timeout +may cause problems with TLS over very slow network connections. +The reasons are that a TLS protocol message can be up to 16 kbytes +long (with TLSv1), and that an entire TLS protocol message must be +sent or received within the per-record deadline. </p> + +<p> This feature is available in Postfix 2.9-3.6. With older +Postfix releases, the behavior is as if this parameter is set to +"no". Postfix 3.7 and later use smtpd_per_request_deadline. </p> + +%PARAM smtp_per_record_deadline no + +<p> Change the behavior of the smtp_*_timeout time limits, from a +time limit per read or write system call, to a time limit to send +or receive a complete record (an SMTP command line, SMTP response +line, SMTP message content line, or TLS protocol message). This +limits the impact from hostile peers that trickle data one byte at +a time. </p> + +<p> Note: when per-record deadlines are enabled, a short timeout +may cause problems with TLS over very slow network connections. +The reasons are that a TLS protocol message can be up to 16 kbytes +long (with TLSv1), and that an entire TLS protocol message must be +sent or received within the per-record deadline. </p> + +<p> This feature is available in Postfix 2.9-3.6. With older +Postfix releases, the behavior is as if this parameter is set to +"no". Postfix 3.7 and later use smtp_per_request_deadline. </p> + +%PARAM lmtp_per_record_deadline no + +<p> The LMTP-specific version of the smtp_per_record_deadline +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.9 and later. </p> + +%PARAM postscreen_whitelist_interfaces static:all + +<p> Renamed to postscreen_allowlist_interfaces in Postfix 3.6. </p> + +<p> This feature is available in Postfix 2.9 - 3.5. </p> + +%PARAM postscreen_allowlist_interfaces static:all + +<p> A list of local postscreen(8) server IP addresses where a +non-allowlisted remote SMTP client can obtain postscreen(8)'s temporary +allowlist status. This status is required before the client can +talk to a Postfix SMTP server process. By default, a client can +obtain postscreen(8)'s allowlist status on any local postscreen(8) +server IP address. </p> + +<p> When postscreen(8) listens on both primary and backup MX +addresses, the postscreen_allowlist_interfaces parameter can be +configured to give the temporary allowlist status only when a client +connects to a primary MX address. Once a client is allowlisted it +can talk to a Postfix SMTP server on any address. Thus, clients +that connect only to backup MX addresses will never become allowlisted, +and will never be allowed to talk to a Postfix SMTP server process. +</p> + +<p> Specify a list of network addresses or network/netmask patterns, +separated by commas and/or whitespace. The netmask specifies the +number of bits in the network part of a host address. Continue long +lines by starting the next line with whitespace. </p> + +<p> You can also specify "/file/name" or "type:table" patterns. A +"/file/name" pattern is replaced by its contents; a "type:table" +lookup table is matched when a table entry matches a lookup string +(the lookup result is ignored). </p> + +<p> The list is matched left to right, and the search stops on the +first match. Specify "!pattern" to exclude an address or network +block from the list. </p> + +<p> Note: IP version 6 address information must be specified inside +[] in the postscreen_allowlist_interfaces value, and in files +specified with "/file/name". IP version 6 addresses contain the +":" character, and would otherwise be confused with a "type:table" +pattern. </p> + +<p> Example: </p> + +<pre> +/etc/postfix/main.cf: + # Don't allowlist connections to the backup IP address. + # Postfix < 3.6 use postscreen_whitelist_interfaces. + postscreen_allowlist_interfaces = !168.100.189.8, static:all +</pre> + +<p> This feature is available in Postfix 3.6 and later. </p> + +<p> Available as postscreen_whitelist_interfaces in Postfix 2.9 - 3.5. </p> + +%PARAM postscreen_upstream_proxy_protocol + +<p> The name of the proxy protocol used by an optional before-postscreen +proxy agent. When a proxy agent is used, this protocol conveys local +and remote address and port information. Specify +"postscreen_upstream_proxy_protocol = haproxy" to enable the haproxy +protocol; version 2 is supported with Postfix 3.5 and later. <p> + +<p> This feature is available in Postfix 2.10 and later. </p> + +%PARAM postscreen_upstream_proxy_timeout 5s + +<p> The time limit for the proxy protocol specified with the +postscreen_upstream_proxy_protocol parameter. </p> + +<p> This feature is available in Postfix 2.10 and later. </p> + +%PARAM smtpd_upstream_proxy_protocol + +<p> The name of the proxy protocol used by an optional before-smtpd +proxy agent. When a proxy agent is used, this protocol conveys local +and remote address and port information. Specify +"smtpd_upstream_proxy_protocol = haproxy" to enable the haproxy +protocol; version 2 is supported with Postfix 3.5 and later. </p> + +<p> NOTE: To use the nginx proxy with smtpd(8), enable the XCLIENT +protocol with smtpd_authorized_xclient_hosts. This supports SASL +authentication in the proxy agent (Postfix 2.9 and later). <p> + +<p> This feature is available in Postfix 2.10 and later. </p> + +%PARAM smtpd_upstream_proxy_timeout 5s + +<p> The time limit for the proxy protocol specified with the +smtpd_upstream_proxy_protocol parameter. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.10 and later. </p> + +%PARAM enable_long_queue_ids no + +<p> Enable long, non-repeating, queue IDs (queue file names). The +benefit of non-repeating names is simpler logfile analysis and +easier queue migration (there is no need to run "postsuper" to +change queue file names that don't match their message file inode +number). </p> + +<p> Note: see below for how to convert long queue file names to +Postfix ≤ 2.8. </p> + +<p> Changing the parameter value to "yes" has the following effects: +</p> + +<ul> + +<li> <p> Existing queue file names are not affected. </p> + +<li> <p> New queue files are created with names such as 3Pt2mN2VXxznjll. +These are encoded in a 52-character alphabet that contains digits +(0-9), upper-case letters (B-Z) and lower-case letters (b-z). For +safety reasons the vowels (AEIOUaeiou) are excluded from the alphabet. +The name format is: 6 or more characters for the time in seconds, +4 characters for the time in microseconds, the 'z'; the remainder +is the file inode number encoded in the first 51 characters of the +52-character alphabet. </p> + +<li> <p> New messages have a Message-ID header with +<i>queueID</i>@<i>myhostname</i>. </p> + +<li> <p> The mailq (postqueue -p) output has a wider Queue ID column. +The number of whitespace-separated fields is not changed. <p> + +<li> <p> The hash_queue_depth algorithm uses the first characters +of the queue file creation time in microseconds, after conversion +into hexadecimal representation. This produces the same queue hashing +behavior as if the queue file name was created with "enable_long_queue_ids += no". </p> + +</ul> + +<p> Changing the parameter value to "no" has the following effects: +</p> + +<ul> + +<li> <p> Existing long queue file names are renamed to the short +form (while running "postfix reload" or "postsuper"). </p> + +<li> <p> New queue files are created with names such as C3CD21F3E90 +from a hexadecimal alphabet that contains digits (0-9) and upper-case +letters (A-F). The name format is: 5 characters for the time in +microseconds; the remainder is the file inode number. </p> + +<li> <p> New messages have a Message-ID header with +<i>YYYYMMDDHHMMSS.queueid</i>@<i>myhostname</i>, where +<i>YYYYMMDDHHMMSS</i> are the year, month, day, hour, minute and +second. + +<li> <p> The mailq (postqueue -p) output has the same format as +with Postfix ≤ 2.8. <p> + +<li> <p> The hash_queue_depth algorithm uses the first characters +of the queue file name, with the hexadecimal representation of the +file creation time in microseconds. </p> + +</ul> + +<p> Before migration to Postfix ≤ 2.8, the following commands +are required to convert long queue file names into short names: </p> + +<pre> +# postfix stop +# postconf enable_long_queue_ids=no +# postsuper +</pre> + +<p> Repeat the postsuper command until it reports no more queue file +name changes. </p> + +<p> This feature is available in Postfix 2.9 and later. </p> + +%PARAM sendmail_fix_line_endings always + +<p> Controls how the Postfix sendmail command converts email message +line endings from <CR><LF> into UNIX format (<LF>). +</p> + +<dl> + +<dt> <b>always</b> </dt> <dd> Always convert message lines ending +in <CR><LF>. This setting is the default with Postfix +2.9 and later. </dd> + +<dt> <b>strict</b> </dt> <dd> Convert message lines ending in +<CR><LF> only if the first input line ends in +<CR><LF>. This setting is backwards-compatible with +Postfix 2.8 and earlier. </dd> + +<dt> <b>never</b> </dt> <dd> Never convert message lines ending in +<CR><LF>. This setting exists for completeness only. +</dd> + +</dl> + +<p> This feature is available in Postfix 2.9 and later. </p> + +%PARAM smtp_send_dummy_mail_auth no + +<p> Whether or not to append the "AUTH=<>" option to the MAIL +FROM command in SASL-authenticated SMTP sessions. The default is +not to send this, to avoid problems with broken remote SMTP servers. +Before Postfix 2.9 the behavior is as if "smtp_send_dummy_mail_auth += yes". + +<p> This feature is available in Postfix 2.9 and later. </p> + +%PARAM lmtp_send_dummy_mail_auth no + +<p> The LMTP-specific version of the smtp_send_dummy_mail_auth +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.9 and later. </p> + +%PARAM address_verify_sender_ttl 0s + +<p> The time between changes in the time-dependent portion of address +verification probe sender addresses. The time-dependent portion is +appended to the localpart of the address specified with the +address_verify_sender parameter. This feature is ignored when the +probe sender addresses is the null sender, i.e. the address_verify_sender +value is empty or <>. </p> + +<p> Historically, the probe sender address was fixed. This has +caused such addresses to end up on spammer mailing lists, and has +resulted in wasted network and processing resources. </p> + +<p> To enable time-dependent probe sender addresses, specify a +non-zero time value. Specify a value of at least several hours, +to avoid problems with senders that use greylisting. Avoid nice +TTL values, to make the result less predictable. </p> + +<p> Specify a non-negative time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 2.9 and later. </p> + +%PARAM smtp_address_verify_target rcpt + +<p> In the context of email address verification, the SMTP protocol +stage that determines whether an email address is deliverable. +Specify one of "rcpt" or "data". The latter is needed with remote +SMTP servers that reject recipients after the DATA command. Use +transport_maps to apply this feature selectively: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + transport_maps = hash:/etc/postfix/transport +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/transport: + smtp-domain-that-verifies-after-data smtp-data-target: + lmtp-domain-that-verifies-after-data lmtp-data-target: +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/master.cf: + smtp-data-target unix - - n - - smtp + -o smtp_address_verify_target=data + lmtp-data-target unix - - n - - lmtp + -o lmtp_address_verify_target=data +</pre> +</blockquote> + +<p> Unselective use of the "data" target does no harm, but will +result in unnecessary "lost connection after DATA" events at remote +SMTP/LMTP servers. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM lmtp_address_verify_target rcpt + +<p> The LMTP-specific version of the smtp_address_verify_target +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM daemon_table_open_error_is_fatal no + +<p> How a Postfix daemon process handles errors while opening lookup +tables: gradual degradation or immediate termination. </p> + +<dl> + +<dt> <b> no </b> (default) </dt> <dd> <p> Gradual degradation: a +daemon process logs a message of type "error" and continues execution +with reduced functionality. Features that do not depend on the +unavailable table will work normally, while features that depend +on the table will result in a type "warning" message. <br> When +the notify_classes parameter value contains the "data" class, the +Postfix SMTP server and client will report transcripts of sessions +with an error because a table is unavailable. </p> </dd> + +<dt> <b> yes </b> (historical behavior) </dt> <dd> <p> Immediate +termination: a daemon process logs a type "fatal" message and +terminates immediately. This option reduces the number of possible +code paths through Postfix, and may therefore be slightly more +secure than the default. </p> </dd> + +</dl> + +<p> For the sake of sanity, the number of type "error" messages is +limited to 13 over the lifetime of a daemon process. </p> + +<p> This feature is available in Postfix 2.9 and later. </p> + +%PARAM smtpd_log_access_permit_actions + +<p> Enable logging of the named "permit" actions in SMTP server +access lists (by default, the SMTP server logs "reject" actions but +not "permit" actions). This feature does not affect conditional +actions such as "defer_if_permit". </p> + +<p> Specify a list of "permit" action names, "/file/name" or +"type:table" patterns, separated by commas and/or whitespace. The +list is matched left to right, and the search stops on the first +match. A "/file/name" pattern is replaced by its contents; a +"type:table" lookup table is matched when a name matches a lookup +key (the lookup result is ignored). Continue long lines by starting +the next line with whitespace. Specify "!pattern" to exclude a name +from the list. </p> + +<p> Examples: </p> + +<pre> +/etc/postfix/main.cf: + # Log all "permit" actions. + smtpd_log_access_permit_actions = static:all +</pre> + +<pre> +/etc/postfix/main.cf: + # Log "permit_dnswl_client" only. + smtpd_log_access_permit_actions = permit_dnswl_client +</pre> + +<p> This feature is available in Postfix 2.10 and later. </p> + +%PARAM smtp_dns_support_level + +<p> Level of DNS support in the Postfix SMTP client. With +"smtp_dns_support_level" left at its empty default value, the legacy +"disable_dns_lookups" parameter controls whether DNS is enabled in +the Postfix SMTP client, otherwise the legacy parameter is ignored. +</p> + +<p> Specify one of the following: </p> + +<dl> + +<dt><b>disabled</b></dt> + +<dd>Disable DNS lookups. No MX lookups are performed and hostname +to address lookups are unconditionally "native". This setting is +not appropriate for hosts that deliver mail to the public Internet. +Some obsolete how-to documents recommend disabling DNS lookups in +some configurations with content_filters. This is no longer required +and strongly discouraged. </dd> + +<dt><b>enabled</b></dt> + +<dd>Enable DNS lookups. Nexthop destination domains not enclosed +in "[]" will be subject to MX lookups. If "dns" and "native" are +included in the "smtp_host_lookup" parameter value, DNS will be +queried first to resolve MX-host A records, followed by "native" +lookups if no answer is found in DNS. </dd> + +<dt><b>dnssec</b></dt> + +<dd>Enable <a href="https://tools.ietf.org/html/rfc4033">DNSSEC</a> +lookups. The "dnssec" setting differs from the "enabled" setting +above in the following ways: <ul> <li>Any MX lookups will set +RES_USE_DNSSEC and RES_USE_EDNS0 to request DNSSEC-validated +responses. If the MX response is DNSSEC-validated the corresponding +hostnames are considered validated. <li> The address lookups of +validated hostnames are also validated, (provided of course +"smtp_host_lookup" includes "dns", see below). <li>Temporary +failures in DNSSEC-enabled hostname-to-address resolution block any +"native" lookups. Additional "native" lookups only happen when +DNSSEC lookups hard-fail (NODATA or NXDOMAIN). </ul> </dd> + +</dl> + +<p> The Postfix SMTP client considers non-MX "[nexthop]" and +"[nexthop]:port" destinations equivalent to statically-validated +MX records of the form "nexthop. IN MX 0 nexthop." Therefore, +with "dnssec" support turned on, validated hostname-to-address +lookups apply to the nexthop domain of any "[nexthop]" or +"[nexthop]:port" destination. This is also true for LMTP "inet:host" +and "inet:host:port" destinations, as LMTP hostnames are never +subject to MX lookups. </p> + +<p>The "dnssec" setting is recommended only if you plan to use the +<a href="TLS_README.html#client_tls_dane">dane</a> or <a +href="TLS_README.html#client_tls_dane">dane-only</a> TLS security +level, otherwise enabling DNSSEC support in Postfix offers no +additional security. Postfix DNSSEC support relies on an upstream +recursive nameserver that validates DNSSEC signatures. Such a DNS +server will always filter out forged DNS responses, even when Postfix +itself is not configured to use DNSSEC. </p> + +<p> When using Postfix DANE support the "smtp_host_lookup" parameter +should include "dns", as <a +href="https://tools.ietf.org/html/rfc7672">DANE</a> is not applicable +to hosts resolved via "native" lookups. </p> + +<p> As mentioned above, Postfix is not a validating <a +href="https://tools.ietf.org/html/rfc4035#section-4.9">stub +resolver</a>; it relies on the system's configured DNSSEC-validating +<a href="https://tools.ietf.org/html/rfc4035#section-3.2">recursive +nameserver</a> to perform all DNSSEC validation. Since this +nameserver's DNSSEC-validated responses will be fully trusted, it +is strongly recommended that the MTA host have a local DNSSEC-validating +recursive caching nameserver listening on a loopback address, and +be configured to use only this nameserver for all lookups. Otherwise, +Postfix may remain subject to man-in-the-middle attacks that forge +responses from the recursive nameserver</p> + +<p>DNSSEC support requires a version of Postfix compiled against a +reasonably-modern DNS resolver(3) library that implements the +RES_USE_DNSSEC and RES_USE_EDNS0 resolver options. </p> + +<p> This feature is available in Postfix 2.11 and later. </p> + +%PARAM lmtp_dns_support_level + +<p> The LMTP-specific version of the smtp_dns_support_level +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.11 and later. </p> + +%PARAM smtp_tls_trust_anchor_file + +<p> Zero or more PEM-format files with trust-anchor certificates +and/or public keys. If the parameter is not empty the root CAs in +CAfile and CApath are no longer trusted. Rather, the Postfix SMTP +client will only trust certificate-chains signed by one of the +trust-anchors contained in the chosen files. The specified +trust-anchor certificates and public keys are not subject to +expiration, and need not be (self-signed) root CAs. They may, if +desired, be intermediate certificates. Therefore, these certificates +also may be found "in the middle" of the trust chain presented by +the remote SMTP server, and any untrusted issuing parent certificates +will be ignored. Specify a list of pathnames separated by comma +or whitespace. </p> + +<p> Whether specified in main.cf, or on a per-destination basis, +the trust-anchor PEM file must be accessible to the Postfix SMTP +client in the chroot jail if applicable. The trust-anchor file +should contain only certificates and public keys, no private key +material, and must be readable by the non-privileged $mail_owner +user. This allows destinations to be bound to a set of specific +CAs or public keys without trusting the same CAs for all destinations. +</p> + +<p> The main.cf parameter supports single-purpose Postfix installations +that send mail to a fixed set of SMTP peers. At most sites, if +trust-anchor files are used at all, they will be specified on a +per-destination basis via the "tafile" attribute of the "verify" +and "secure" levels in smtp_tls_policy_maps. </p> + +<p> The underlying mechanism is in support of RFC 7672 (DANE TLSA), +which defines mechanisms for an SMTP client MTA to securely determine +server TLS certificates via DNS. </p> + +<p> If you want your trust anchors to be public keys, with OpenSSL +you can extract a single PEM public key from a PEM X.509 file +containing a single certificate, as follows: </p> + +<blockquote> +<pre> +$ openssl x509 -in cert.pem -out ta-key.pem -noout -pubkey +</pre> +</blockquote> + +<p> This feature is available in Postfix 2.11 and later. </p> + +%PARAM lmtp_tls_trust_anchor_file + +<p> The LMTP-specific version of the smtp_tls_trust_anchor_file +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.11 and later. </p> + +%PARAM tls_dane_trust_anchor_digest_enable yes + +<p> Enable support for RFC 6698 (DANE TLSA) DNS records that contain +digests of trust-anchors with certificate usage "2". Do not change +this setting from its default value. </p> + +<p> This feature is available in Postfix 2.11 through 3.1. It has +been withdrawn in Postfix 3.2, as trust-anchor TLSA records are now +widely used and have proved sufficiently reliable. Postfix 3.2 and +later ignore this configuration parameter and behaves as though it +were set to "yes". </p> + +%PARAM tls_wildcard_matches_multiple_labels yes + +<p> Match multiple DNS labels with "*" in wildcard certificates. +</p> + +<p> Some mail service providers prepend the customer domain name +to a base domain for which they have a wildcard TLS certificate. +For example, the MX records for example.com hosted by example.net +may be: </p> + +<blockquote> +<pre> +example.com. IN MX 0 example.com.mx1.example.net. +example.com. IN MX 0 example.com.mx2.example.net. +</pre> +</blockquote> + +<p> and the TLS certificate may be for "*.example.net". The "*" +then corresponds with multiple labels in the mail server domain +name. While multi-label wildcards are not widely supported, and +are not blessed by any standard, there is little to be gained by +disallowing their use in this context. </p> + +<p> Notes: <p> + +<ul> + +<li> <p> In a certificate name, the "*" is special only when it is +used as the first label. </p> + +<li> <p> While Postfix (2.11 or later) can match "*" with multiple +domain name labels, other implementations likely will not. </p> + +<li> <p> Earlier Postfix implementations behave as if +"tls_wildcard_matches_multiple_labels = no". </p> + +</ul> + +<p> This feature is available in Postfix 2.11 and later. </p> + +%PARAM tls_ssl_options + +<p> List or bit-mask of OpenSSL options to enable. </p> + +<p> The OpenSSL toolkit provides a set of options that applications +can enable to tune the OpenSSL behavior. Some of these work around +bugs in other implementations and are on by default. You can use +the tls_disable_workarounds parameter to selectively disable some +or all of the bug work-arounds, making OpenSSL more strict at the +cost of non-interoperability with SSL clients or servers that exhibit +the bugs. </p> + +<p> Other options are off by default, and typically enable or disable +features rather than bug work-arounds. These may be turned on (with +care) via the tls_ssl_options parameter. The value is a white-space +or comma separated list of named options chosen from the list below. +The names are not case-sensitive, you can use lower-case if you +prefer. The upper case values below match the corresponding macro +name in the ssl.h header file with the SSL_OP_ prefix removed. It +is possible that your OpenSSL version includes new options added +after your Postfix source code was last updated, in that case you +can only enable one of these via the hexadecimal syntax below. </p> + +<p> You should only enable features via the hexadecimal mask when +the need to control the feature is critical (to deal with a new +vulnerability or a serious interoperability problem). Postfix DOES +NOT promise backwards compatible behavior with respect to the mask +bits. A feature enabled via the mask in one release may be enabled +by other means in a later release, and the mask bit will then be +ignored. Therefore, use of the hexadecimal mask is only a temporary +measure until a new Postfix or OpenSSL release provides a better +solution. </p> + +<p> If the value of the parameter is a hexadecimal long integer +starting with "0x", the options corresponding to the bits specified +in its value are enabled (see openssl/ssl.h and SSL_CTX_set_options(3)). +You can only enable options not already controlled by other Postfix +settings. For example, you cannot disable protocols or enable +server cipher preference. Do not attempt to enable all features by +specifying 0xFFFFFFFF, this is unlikely to be a good idea. Some +bug work-arounds are also valid here, allowing them to be re-enabled +if/when they're no longer enabled by default. The supported values +include: </p> + +<dl> + +<dt><b>ENABLE_MIDDLEBOX_COMPAT</b></dt> <dd>Postfix ≥ 3.4. See +SSL_CTX_set_options(3).</dd> + +<dt><b>LEGACY_SERVER_CONNECT</b></dt> <dd>See SSL_CTX_set_options(3).</dd> + +<dt><b>NO_TICKET</b></dt> <dd>Enabled by default when needed in +fully-patched Postfix ≥ 2.7. Not needed at all for Postfix ≥ +2.11, unless for some reason you do not want to support TLS session +resumption. Best not set explicitly. See SSL_CTX_set_options(3).</dd> + +<dt><b>NO_COMPRESSION</b></dt> <dd>Disable SSL compression even if +supported by the OpenSSL library. Compression is CPU-intensive, +and compression before encryption does not always improve security. </dd> + +<dt><b>NO_RENEGOTIATION</b></dt> <dd>Postfix ≥ 3.4. This can +reduce opportunities for a potential CPU exhaustion attack. See +SSL_CTX_set_options(3).</dd> + +<dt><b>NO_SESSION_RESUMPTION_ON_RENEGOTIATION</b></dt> <dd>Postfix +≥ 3.4. See SSL_CTX_set_options(3).</dd> + +<dt><b>PRIORITIZE_CHACHA</b></dt> <dd>Postfix ≥ 3.4. See SSL_CTX_set_options(3).</dd> + +</dl> + +<p> This feature is available in Postfix 2.11 and later. </p> + +%PARAM tlsmgr_service_name tlsmgr + +<p> The name of the tlsmgr(8) service entry in master.cf. This +service maintains TLS session caches and other information in support +of TLS. </p> + +<p> This feature is available in Postfix 2.11 and later. </p> + +%PARAM lmtp_connection_reuse_count_limit 0 + +<p> The LMTP-specific version of the smtp_connection_reuse_count_limit +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.11 and later. </p> + +%PARAM smtp_connection_reuse_count_limit 0 + +<p> When SMTP connection caching is enabled, the number of times +that an SMTP session may be reused before it is closed, or zero (no +limit). With a reuse count limit of N, a connection is used up to +N+1 times. </p> + +<p> NOTE: This feature is unsafe. When a high-volume destination +has multiple inbound MTAs, then the slowest inbound MTA will attract +the most connections to that destination. This limitation does not +exist with the smtp_connection_reuse_time_limit feature. </p> + +<p> This feature is available in Postfix 2.11. </p> + +%PARAM lmtp_tls_force_insecure_host_tlsa_lookup no + +<p> The LMTP-specific version of the smtp_tls_force_insecure_host_tlsa_lookup +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 2.11 and later. </p> + +%PARAM smtp_tls_force_insecure_host_tlsa_lookup no + +<p> Lookup the associated DANE TLSA RRset even when a hostname is +not an alias and its address records lie in an unsigned zone. This +is unlikely to ever yield DNSSEC validated results, since child +zones of unsigned zones are also unsigned in the absence of DLV or +locally configured non-root trust-anchors. We anticipate that such +mechanisms will not be used for just the "_tcp" subdomain of a host. +Suppressing the TLSA RRset lookup reduces latency and avoids potential +interoperability problems with nameservers for unsigned zones that +are not prepared to handle the new TLSA RRset. </p> + +<p> This feature is available in Postfix 2.11. </p> + +%PARAM tls_dane_digest_agility on + +<p> Configure RFC7671 DANE TLSA digest algorithm agility. +Do not change this setting from its default value. </p> + +<p> See Section 8 of RFC7671 for correct key rotation procedures. </p> + +<p> This feature is available in Postfix 2.11 through 3.1. Postfix +3.2 and later ignore this configuration parameter and behave as +though it were set to "on". </p> + +%PARAM tls_dane_digests sha512 sha256 + +<p> DANE TLSA (RFC 6698, RFC 7671, RFC 7672) resource-record "matching +type" digest algorithms in descending preference order. All the +specified algorithms must be supported by the underlying OpenSSL +library, otherwise the Postfix SMTP client will not support DANE +TLSA security. </p> + +<p> Specify a list of digest names separated by commas and/or +whitespace. Each digest name may be followed by an optional +"=<number>" suffix. For example, "sha512" may instead be specified +as "sha512=2" and "sha256" may instead be specified as "sha256=1". +The optional number must match the <a +href="https://www.iana.org/assignments/dane-parameters/dane-parameters.xhtml#matching-types" +>IANA</a> assigned TLSA matching type number the algorithm in question. +Postfix will check this constraint for the algorithms it knows about. +Additional matching type algorithms registered with IANA can be added +with explicit numbers provided they are supported by OpenSSL. </p> + +<p> Invalid list elements are logged with a warning and disable DANE +support. TLSA RRs that specify digests not included in the list are +ignored with a warning. </p> + +<p> Note: It is unwise to omit sha256 from the digest list. This +digest algorithm is the only mandatory to implement digest algorithm +in RFC 6698, and many servers are expected to publish TLSA records +with just sha256 digests. Unless one of the standard digests is +seriously compromised and servers have had ample time to update their +TLSA records you should not omit any standard digests, just arrange +them in order from strongest to weakest. </p> + +<p> This feature is available in Postfix 2.11 and later. </p> + +%PARAM tls_session_ticket_cipher Postfix ≥ 3.0: aes-256-cbc, Postfix < 3.0: aes-128-cbc + +<p> Algorithm used to encrypt RFC5077 TLS session tickets. This +algorithm must use CBC mode, have a 128-bit block size, and must +have a key length between 128 and 256 bits. The default is +aes-256-cbc. Overriding the default to choose a different algorithm +is discouraged. </p> + +<p> Setting this parameter empty disables session ticket support +in the Postfix SMTP server. Another way to disable session ticket +support is via the tls_ssl_options parameter. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM tls_fast_shutdown_enable yes + +<p> A workaround for implementations that hang Postfix while shutting +down a TLS session, until Postfix times out. With this enabled, +Postfix will not wait for the remote TLS peer to respond to a TLS +'close' notification. This behavior is recommended for TLSv1.0 and +later. </p> + +%PARAM default_delivery_status_filter + +<p> Optional filter to replace the delivery status code or explanatory +text of successful or unsuccessful deliveries. This does not allow +the replacement of a successful status code (2.X.X) with an +unsuccessful status code (4.X.X or 5.X.X) or vice versa. </p> + +<p> Note: the (smtp|lmtp)_delivery_status_filter is applied only +once per recipient: when delivery is successful, when delivery is +rejected with 5XX, or when there are no more alternate MX or A +destinations. Use smtp_reply_filter or lmtp_reply_filter to inspect +responses for all delivery attempts. </p> + +<p> The following parameters can be used to implement a filter for +specific delivery agents: lmtp_delivery_status_filter, +local_delivery_status_filter, pipe_delivery_status_filter, +smtp_delivery_status_filter or virtual_delivery_status_filter. These +parameters support the same filter syntax as described here. </p> + +<p> Specify zero or more "type:table" lookup table names, separated +by comma or whitespace. For each successful or unsuccessful delivery +to a recipient, the tables are queried in the specified order with +one line of text that is structured as follows: </p> + +<blockquote> +enhanced-status-code SPACE explanatory-text +</blockquote> + +<p> The first table match wins. The lookup result must have the +same structure as the query, a successful status code (2.X.X) must +be replaced with a successful status code, an unsuccessful status +code (4.X.X or 5.X.X) must be replaced with an unsuccessful status +code, and the explanatory text field must be non-empty. Other results +will result in a warning. </p> + +<p> Example 1: convert specific soft TLS errors into hard errors, +by overriding the first number in the enhanced status code. </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_delivery_status_filter = pcre:/etc/postfix/smtp_dsn_filter +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/smtp_dsn_filter: + /^4(\.\d+\.\d+ TLS is required, but host \S+ refused to start TLS: .+)/ + 5$1 + /^4(\.\d+\.\d+ TLS is required, but was not offered by host .+)/ + 5$1 + # Do not change the following into hard bounces. They may + # result from a local configuration problem. + # 4.\d+.\d+ TLS is required, but our TLS engine is unavailable + # 4.\d+.\d+ TLS is required, but unavailable + # 4.\d+.\d+ Cannot start TLS: handshake failure +</pre> +</blockquote> + +<p> Example 2: censor the per-recipient delivery status text so +that it does not reveal the destination command or filename +when a remote sender requests confirmation of successful delivery. +</p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + local_delivery_status_filter = pcre:/etc/postfix/local_dsn_filter +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/local_dsn_filter: + /^(2\S+ delivered to file).+/ $1 + /^(2\S+ delivered to command).+/ $1 +</pre> +</blockquote> + +<p> Notes: </p> + +<ul> + +<li> <p> This feature will NOT override the soft_bounce safety net. </p> + +<li> <p> This feature will change the enhanced status code and text +that is logged to the maillog file, and that is reported to the +sender in delivery confirmation or non-delivery notifications. +</p> + +</ul> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM smtp_delivery_status_filter $default_delivery_status_filter + +<p> Optional filter for the smtp(8) delivery agent to change the +delivery status code or explanatory text of successful or unsuccessful +deliveries. See default_delivery_status_filter for details. </p> + +<p> NOTE: This feature modifies Postfix SMTP client error or non-error +messages that may or may not be derived from remote SMTP server +responses. In contrast, the smtp_reply_filter feature modifies +remote SMTP server responses only. </p> + +%PARAM lmtp_delivery_status_filter + +<p> The LMTP-specific version of the smtp_delivery_status_filter +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM pipe_delivery_status_filter $default_delivery_status_filter + +<p> Optional filter for the pipe(8) delivery agent to change the +delivery status code or explanatory text of successful or unsuccessful +deliveries. See default_delivery_status_filter for details. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM virtual_delivery_status_filter $default_delivery_status_filter + +<p> Optional filter for the virtual(8) delivery agent to change the +delivery status code or explanatory text of successful or unsuccessful +deliveries. See default_delivery_status_filter for details. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM local_delivery_status_filter $default_delivery_status_filter + +<p> Optional filter for the local(8) delivery agent to change the +status code or explanatory text of successful or unsuccessful +deliveries. See default_delivery_status_filter for details. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM shlib_directory see 'postconf -d' output + +<p> The location of Postfix dynamically-linked libraries +(libpostfix-*.so), and the default location of Postfix database +plugins (postfix-*.so) that have a relative pathname in the +dynamicmaps.cf file. The shlib_directory parameter defaults to +"no" when Postfix dynamically-linked libraries and database plugins +are disabled at compile time, otherwise it typically defaults to +/usr/lib/postfix or /usr/local/lib/postfix. </p> + +<p> Notes: </p> + +<ul> + +<li> <p> The directory specified with shlib_directory should contain +only Postfix-related files. Postfix dynamically-linked libraries +and database plugins should not be installed in a "public" system +directory such as /usr/lib or /usr/local/lib. Linking Postfix +dynamically-linked library files or database plugins into non-Postfix +programs is not supported. Postfix dynamically-linked libraries +and database plugins implement a Postfix-internal API that changes +without maintaining compatibility. </p> + +<li> <p> You can change the shlib_directory value after Postfix is +built. However, you may have to run ldconfig or equivalent to prevent +Postfix programs from failing because the libpostfix-*.so files are +not found. No ldconfig command is needed if you keep the libpostfix-*.so +files in the compiled-in default $shlib_directory location. </p> + +</ul> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM meta_directory see 'postconf -d' output + +<p> The location of non-executable files that are shared among +multiple Postfix instances, such as postfix-files, dynamicmaps.cf, +and the multi-instance template files main.cf.proto and master.cf.proto. +This directory should contain only Postfix-related files. Typically, +the meta_directory parameter has the same default as the config_directory +parameter (/etc/postfix or /usr/local/etc/postfix). </p> + +<p> For backwards compatibility with Postfix versions 2.6..2.11, +specify "meta_directory = $daemon_directory" in main.cf before +installing or upgrading Postfix, or specify "meta_directory = +/path/name" on the "make makefiles", "make install" or "make upgrade" +command line. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM smtpd_policy_service_default_action 451 4.3.5 Server configuration problem + +<p> The default action when an SMTPD policy service request fails. +Specify "DUNNO" to behave as if the failed SMTPD policy service +request was not sent, and to continue processing other access +restrictions, if any. </p> + +<p> Limitations: </p> + +<ul> + +<li> <p> This parameter may specify any value that would be a valid +SMTPD policy server response (or access(5) map lookup result). An +access(5) map or policy server in this parameter value may need to +be declared in advance with a restriction_class setting. </p> + +<li> <p> If the specified action invokes another check_policy_service +request, that request will have the built-in default action. </p> + +</ul> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM smtpd_policy_service_try_limit 2 + +<p> The maximal number of attempts to send an SMTPD policy service +request before giving up. Specify a value greater than zero. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM smtpd_policy_service_retry_delay 1s + +<p> The delay between attempts to resend a failed SMTPD policy +service request. Specify a value greater than zero. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM smtputf8_enable yes + +<p> Enable preliminary SMTPUTF8 support for the protocols described +in RFC 6531, RFC 6532, and RFC 6533. This requires that Postfix is +built to support these protocols. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM strict_smtputf8 no + +<p> Enable stricter enforcement of the SMTPUTF8 protocol. The Postfix +SMTP server accepts UTF8 sender or recipient addresses only when +the client requests an SMTPUTF8 mail transaction. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM smtputf8_autodetect_classes sendmail, verify + +<p> Detect that a message requires SMTPUTF8 support for the specified +mail origin classes. This is a workaround to avoid chicken-and-egg +problems during the initial SMTPUTF8 roll-out in environments with +pre-existing mail flows that contain UTF8. Those mail flows should +not break because Postfix suddenly refuses to deliver such mail +to down-stream MTAs that don't announce SMTPUTF8 support. </p> + +<p> The problem is that Postfix cannot rely solely on the sender's +declaration that a message requires SMTPUTF8 support, because UTF8 +may be introduced during local processing (for example, the client +hostname in Postfix's Received: header, adding @$myorigin or +.$mydomain to an incomplete address, address rewriting, alias +expansion, automatic BCC recipients, local forwarding, and changes +made by header checks or Milter applications). </p> + +<p> For now, the default is to enable "SMTPUTF8 required" autodetection +only for Postfix sendmail command-line submissions and address +verification probes. This may change once SMTPUTF8 support achieves +world domination. However, sites that add UTF8 content via local +processing (see above) should autodetect the need for SMTPUTF8 +support for all email.</p> + +<p> Specify one or more of the following: </p> + +<dl compact> + +<dt> <b> sendmail </b> </dt> <dd> Submission with the Postfix +sendmail(1) command. </dd> + +<dt> <b> smtpd </b> </dt> <dd> Mail received with the smtpd(8) +daemon. </dd> + +<dt> <b> qmqpd </b> </dt> <dd> Mail received with the qmqpd(8) +daemon. </dd> + +<dt> <b> forward </b> </dt> <dd> Local forwarding or aliasing. When +a message is received with "SMTPUTF8 required", then the forwarded +(aliased) message always has "SMTPUTF8 required". </dd> + +<dt> <b> bounce </b> </dt> <dd> Submission by the bounce(8) daemon. +When a message is received with "SMTPUTF8 required", then the +delivery status notification always has "SMTPUTF8 required". </dd> + +<dt> <b> notify </b> </dt> <dd> Postmaster notification from the +smtp(8) or smtpd(8) daemon. </dd> + +<dt> <b> verify </b> </dt> <dd> Address verification probe from the +verify(8) daemon. </dd> + +<dt> <b> all </b> </dt> <dd> Enable SMTPUTF8 autodetection for all +mail. </dd> + +</dl> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM compatibility_level 0 + +<p> A safety net that causes Postfix to run with backwards-compatible +default settings after an upgrade to a newer Postfix version. </p> + +<p> With backwards compatibility turned on (the main.cf compatibility_level +value is less than the Postfix built-in value), Postfix looks for +settings that are left at their implicit default value, and logs a +message when a backwards-compatible default setting is required. +</p> + +<blockquote> +<pre> +using backwards-compatible default setting <i>name=value</i> + to [accept a specific client request] +<nroffescape .sp> +using backwards-compatible default setting <i>name=value</i> + to [enable specific Postfix behavior] +</pre> +</blockquote> + +<p> See COMPATIBILITY_README for specific message details. If such +a message is logged in the context of a legitimate request, the +system administrator should make the backwards-compatible setting +permanent in main.cf or master.cf, for example: </p> + +<blockquote> +<pre> +# <b>postconf</b> <i>name=value</i> +# <b>postfix reload</b> +</pre> +</blockquote> + +<p> When no more backwards-compatible settings need to be made +permanent, the administrator should turn off backwards compatibility +by updating the compatibility_level setting in main.cf:</p> + +<blockquote> +<pre> +# <b>postconf compatibility_level=<i>N</i></b> +# <b>postfix reload</b> +</pre> +</blockquote> + +<p> For <i>N</i> specify the number that is logged in your postfix(1) +warning message: </p> + +<blockquote> +<pre> +warning: To disable backwards compatibility use "postconf + compatibility_level=<i>N</i>" and "postfix reload" +</pre> +</blockquote> + +<p> Starting with Postfix version 3.6, the compatibility level in +the above warning message is the Postfix version that introduced +the last incompatible change. The level is formatted as +<i>major.minor.patch</i>, where <i>patch</i> is usually omitted and +defaults to zero. Earlier compatibility levels are 0, 1 and 2. </p> + +<p> NOTE: this also introduces support for the "<level", +"<=level", and other operators to compare compatibility levels. +With the standard operators "<", "<=", etc., compatibility +level "3.10" would be smaller than "3.9" which is undesirable. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM message_drop_headers bcc, content-length, resent-bcc, return-path + +<p> Names of message headers that the cleanup(8) daemon will remove +after applying header_checks(5) and before invoking Milter applications. +The default setting is compatible with Postfix < 3.0. </p> + +<p> Specify a list of header names, separated by comma or space. +Names are matched in a case-insensitive manner. The list of supported +header names is limited only by available memory. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM smtpd_dns_reply_filter + +<p> Optional filter for Postfix SMTP server DNS lookup results. +See smtp_dns_reply_filter for details including an example. +</p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM lmtp_dns_reply_filter + +<p> Optional filter for Postfix LMTP client DNS lookup results. +See smtp_dns_reply_filter for details including an example. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +#%PARAM postscreen_dns_reply_filter +# +#<p> Optional filter for postscreen(8) DNS lookup results. +#See smtp_dns_reply_filter for details including an example. +#</p> +# +#<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM smtp_dns_reply_filter + +<p> Optional filter for Postfix SMTP client DNS lookup results. +Specify zero or more lookup tables. The lookup tables are searched +in the given order for a match with the DNS lookup result, converted +to the following form: </p> + +<pre> + <i>name ttl class type preference value</i> +</pre> + +<p> The <i>class</i> field is always "IN", the <i>preference</i> +field exists only for MX records, the names of hosts, domains, etc. +end in ".", and those names are in ASCII form (xn--mumble form in +the case of UTF8 names). </p> + +<p> When a match is found, the table lookup result specifies an +action. By default, the table query and the action name are +case-insensitive. Currently, only the <b>IGNORE</b> action is +implemented. </p> + +<p> Notes: </p> + +<ul> + +<li> <p> Postfix DNS reply filters have no effect on implicit DNS +lookups through nsswitch.conf or equivalent mechanisms. </p> + +<li> <p> The Postfix SMTP/LMTP client uses smtp_dns_reply_filter +and lmtp_dns_reply_filter only to discover a remote SMTP or LMTP +service (record types MX, A, AAAA, and TLSA). These lookups are +also made to implement the features reject_unverified_sender and +reject_unverified_recipient. </p> + +<li> <p> The Postfix SMTP/LMTP client defers mail delivery when +a filter removes all lookup results from a successful query. </p> + +<li> <p> Postfix SMTP server uses smtpd_dns_reply_filter only to +look up MX, A, AAAA, and TXT records to implement the features +reject_unknown_helo_hostname, reject_unknown_sender_domain, +reject_unknown_recipient_domain, reject_rbl_*, and reject_rhsbl_*. +</p> + +<li> <p> The Postfix SMTP server logs a warning or defers mail +delivery when a filter removes all lookup results from a successful +query. </p> + +</ul> + +<p> Example: ignore Google AAAA records in Postfix SMTP client DNS +lookups, because Google sometimes hard-rejects mail from IPv6 clients +with valid PTR etc. records. </p> + +<pre> +/etc/postfix/main.cf: + smtp_dns_reply_filter = pcre:/etc/postfix/smtp_dns_reply_filter +</pre> + +<pre> +/etc/postfix/smtp_dns_reply_filter: + # /domain ttl IN AAAA address/ action, all case-insensitive. + # Note: the domain name ends in ".". + /^\S+\.google\.com\.\s+\S+\s+\S+\s+AAAA\s+/ IGNORE +</pre> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM smtp_tls_wrappermode no + +<p> Request that the Postfix SMTP client connects using the +SUBMISSIONS/SMTPS protocol instead of using the STARTTLS command. </p> + +<p> This mode requires "smtp_tls_security_level = encrypt" or +stronger. </p> + +<p> Example: deliver all remote mail via a provider's server +"mail.example.com". </p> + +<pre> +/etc/postfix/main.cf: + # Client-side SMTPS requires "encrypt" or stronger. + smtp_tls_security_level = encrypt + smtp_tls_wrappermode = yes + # The [] suppress MX lookups. + relayhost = [mail.example.com]:465 +</pre> + +<p> More examples are in TLS_README, including examples for older +Postfix versions. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM lmtp_tls_wrappermode no + +<p> The LMTP-specific version of the smtp_tls_wrappermode configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 3.0 and later. </p> + +%PARAM smtp_tls_connection_reuse no + +<p> Try to make multiple deliveries per TLS-encrypted connection. +This uses the tlsproxy(8) service to encrypt an SMTP connection, +uses the scache(8) service to save that connection, and relies on +hints from the qmgr(8) daemon. </p> + +<p> See "<a href="TLS_README.html#client_tls_reuse">Client-side +TLS connection reuse</a>" for background details. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM lmtp_tls_connection_reuse no + +<p> The LMTP-specific version of the smtp_tls_connection_reuse configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM virtual_alias_address_length_limit 1000 + +<p> +The maximal length of an email address after virtual alias expansion. +This stops virtual aliasing loops that increase the address length +exponentially. +</p> + +<p> +This feature is available in Postfix 3.0 and later. +</p> + +%PARAM dns_ncache_ttl_fix_enable no + +<p> Enable a workaround for future libc incompatibility. The Postfix +implementation of RFC 2308 negative reply caching relies on the +promise that res_query() and res_search() invoke res_send(), which +returns the server response in an application buffer even if the +requested record does not exist. If this promise is broken, specify +"yes" to enable a workaround for DNS reputation lookups. </p> + +<p> +This feature is available in Postfix 3.1 and later. +</p> + +%PARAM smtpd_policy_service_policy_context + +<p> Optional information that the Postfix SMTP server specifies in +the "policy_context" attribute of a policy service request (originally, +to share the same service endpoint among multiple check_policy_service +clients). </p> + +<p> +This feature is available in Postfix 3.1 and later. +</p> + +%PARAM smtp_tls_dane_insecure_mx_policy see "postconf -d" output + +<p> The TLS policy for MX hosts with "secure" TLSA records when the +nexthop destination security level is <b>dane</b>, but the MX +record was found via an "insecure" MX lookup. The choices are: +</p> + +<dl> +<dt><b>may</b></dt> +<dd> The TLSA records will be ignored and TLS will be optional. If +the MX host does not appear to support STARTTLS, or the STARTTLS +handshake fails, mail may be sent in the clear. </dd> +<dt><b>encrypt</b></dt> +<dd> The TLSA records will signal a requirement to use TLS. While +TLS encryption will be required, authentication will not be performed. +</dd> +<dt><b>dane</b></dt> +<dd>The TLSA records will be used just as with "secure" MX records. +TLS encryption will be required, and, if at least one of the TLSA +records is "usable", authentication will be required. When +authentication succeeds, it will be logged only as "Trusted", not +"Verified", because the MX host name could have been forged. </dd> +</dl> + +<p> The default setting for Postfix ≥ 3.6 is "dane" with +"smtp_tls_security_level = dane", otherwise "may". This behavior +was backported to Postfix versions 3.5.9, 3.4.19, 3.3.16. 3.2.21. +With earlier Postfix versions the default setting was always "dane". +</p> + +<p> Though with "insecure" MX records an active attacker can +compromise SMTP transport security by returning forged MX records, +such attacks are "tamper-evident" since any forged MX hostnames +will be recorded in the mail logs. Attackers who place a high value +on staying hidden may be deterred from forging MX records. </p> + +<p> +This feature is available in Postfix 3.1 and later. The <b>may</b> +policy is backwards-compatible with earlier Postfix versions. +</p> + +%PARAM openssl_path openssl + +<p> +The location of the OpenSSL command line program openssl(1). This +is used by the "<b>postfix tls</b>" command to create private keys, +certificate signing requests, self-signed certificates, and to +compute public key digests for DANE TLSA records. In multi-instance +environments, this parameter is always determined from the configuration +of the default Postfix instance. +</p> + +<p> Example: </p> + +<blockquote> +<pre> +/etc/postfix/main.cf: + # NetBSD pkgsrc: + openssl_path = /usr/pkg/bin/openssl + # Local build: + openssl_path = /usr/local/bin/openssl +</pre> +</blockquote> + +<p> +This feature is available in Postfix 3.1 and later. +</p> + +%PARAM address_verify_pending_request_limit see "postconf -d" output + +<p> A safety limit that prevents address verification requests from +overwhelming the Postfix queue. By default, the number of pending +requests is limited to 1/4 of the active queue maximum size +(qmgr_message_active_limit). The queue manager enforces the limit +by tempfailing requests that exceed the limit. This affects only +unknown addresses and inactive addresses that have expired, because +the verify(8) daemon automatically refreshes an active address +before it expires. </p> + +<p> This feature is available in Postfix 3.1 and later. </p> + +%PARAM smtpd_milter_maps + +<p> Lookup tables with Milter settings per remote SMTP client IP +address. The lookup result overrides the smtpd_milters setting, +and has the same syntax. </p> + +<p> Note: lookup tables cannot return empty responses. Specify a +lookup result of DISABLE (case does not matter) to indicate that +Milter support should be disabled. </p> + +<p> Example to disable Milters for local clients: </p> + +<pre> +/etc/postfix/main.cf: + smtpd_milter_maps = cidr:/etc/postfix/smtpd_milter_map + smtpd_milters = inet:host:port, { inet:host:port, ... }, ... +</pre> + +<pre> +/etc/postfix/smtpd_milter_map: + # Disable Milters for local clients. + 127.0.0.0/8 DISABLE + 192.168.0.0/16 DISABLE + ::/64 DISABLE + 2001:db8::/32 DISABLE +</pre> + +<p> This feature is available in Postfix 3.2 and later. </p> + +%PARAM enable_idna2003_compatibility no + +<p> Enable 'transitional' compatibility between IDNA2003 and IDNA2008, +when converting UTF-8 domain names to/from the ASCII form that is +used for DNS lookups. Specify "yes" for compatibility with Postfix +≤ 3.1 (not recommended). This affects the conversion of domain +names that contain for example the German sz and the Greek zeta. +See http://unicode.org/cldr/utility/idna.jsp for more examples. +</p> + +<p> This feature is available in Postfix 3.2 and later. </p> + +%PARAM smtp_balance_inet_protocols yes + +<p> When a remote destination resolves to a combination of IPv4 and +IPv6 addresses, ensure that the Postfix SMTP client can try both +address types before it runs into the smtp_mx_address_limit. </p> + +<p> This avoids an interoperability problem when a destination resolves +to primarily IPv6 addresses, the smtp_address_limit feature eliminates +most or all IPv4 addresses, and the destination is not reachable over +IPv6. </p> + +<p> This feature is available in Postfix 3.3 and later. </p> + +%PARAM lmtp_balance_inet_protocols yes + +<p> The LMTP-specific version of the smtp_balance_inet_protocols +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 3.3 and later. </p> + +%PARAM header_from_format standard + +<p> The format of the Postfix-generated <b>From:</b> header. This +setting affects the appearance of 'full name' information when a +local program such as /bin/mail submits a message without a From: +header through the Postfix sendmail(1) command. </p> + +<p> Specify one of the following: </p> + +<dl> + +<dt><b>standard</b> (default)</dt> <dd> Produce a header formatted +as "<b>From:</b> <i>name</i><b> <</b><i>address</i><b>></b>". +This is the default as of Postfix 3.3.</dd> + +<dt><b>obsolete</b></dt> <dd>Produce a header formatted as "<b>From:</b> +<i>address</i> <b>(</b><i>name</i><b>)</b>". This is the behavior +prior to Postfix 3.3. </dd> + +</dl> + +<p> Notes: </p> + +<ul> + +<li> <p> Postfix generates the format "<b>From:</b> <i>address</i>" +when <i>name</i> information is unavailable or the envelope sender +address is empty. This is the same behavior as prior to Postfix +3.3. </p> + +<li> <p> In the <b>standard</b> form, the <i>name</i> will be quoted +if it contains <b>specials</b> as defined in RFC 5322, or the "!%" +address operators. </p> + +<li> <p> The Postfix sendmail(1) command gets <i>name</i> information +from the <b>-F</b> command-line option, from the <b>NAME</b> +environment variable, or from the UNIX password file. </p> + +</ul> + +<p> This feature is available in Postfix 3.3 and later. </p> + +%PARAM tlsproxy_client_CAfile $smtp_tls_CAfile + +<p> A file containing CA certificates of root CAs trusted to sign +either remote TLS server certificates or intermediate CA certificates. +See smtp_tls_CAfile for further details. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_CApath $smtp_tls_CApath + +<p> Directory with PEM format Certification Authority certificates +that the Postfix tlsproxy(8) client uses to verify a remote TLS +server certificate. See smtp_tls_CApath for further details. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_cert_file $smtp_tls_cert_file + +<p> File with the Postfix tlsproxy(8) client RSA certificate in PEM +format. See smtp_tls_cert_file for further details. The preferred way +to configure tlsproxy client keys and certificates is via the +"tlsproxy_client_chain_files" parameter. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_key_file $smtp_tls_key_file + +<p> File with the Postfix tlsproxy(8) client RSA private key in PEM +format. See smtp_tls_key_file for further details. The preferred way to +configure tlsproxy client keys and certificates is via the +"tlsproxy_client_chain_files" parameter. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_dcert_file $smtp_tls_dcert_file + +<p> File with the Postfix tlsproxy(8) client DSA certificate in PEM +format. See smtp_tls_dcert_file for further details. DSA is obsolete and +should not be used. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_dkey_file $smtp_tls_dkey_file + +<p> File with the Postfix tlsproxy(8) client DSA private key in PEM +format. See smtp_tls_dkey_file for further details. DSA is obsolete and +should not be used. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_eccert_file $smtp_tls_eccert_file + +<p> File with the Postfix tlsproxy(8) client ECDSA certificate in PEM +format. See smtp_tls_eccert_file for further details. The preferred way +to configure tlsproxy client keys and certificates is via the +"tlsproxy_client_chain_files" parameter. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_eckey_file $smtp_tls_eckey_file + +<p> File with the Postfix tlsproxy(8) client ECDSA private key in PEM +format. See smtp_tls_eckey_file for further details. The preferred way +to configure tlsproxy client keys and certificates is via the +"tlsproxy_client_chain_files" parameter. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_fingerprint_digest $smtp_tls_fingerprint_digest + +<p> The message digest algorithm used to construct remote TLS server +certificate fingerprints. See smtp_tls_fingerprint_digest for +further details. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_loglevel $smtp_tls_loglevel + +<p> Enable additional Postfix tlsproxy(8) client logging of TLS +activity. See smtp_tls_loglevel for further details. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_loglevel_parameter smtp_tls_loglevel + +<p> The name of the parameter that provides the tlsproxy_client_loglevel +value. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_scert_verifydepth $smtp_tls_scert_verifydepth + +<p> The verification depth for remote TLS server certificates. +See smtp_tls_scert_verifydepth for further details. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_level $smtp_tls_security_level + +<p> The default TLS security level for the Postfix tlsproxy(8) +client. See smtp_tls_security_level for further details. </p> + +<p> This feature is available in Postfix 3.4 - 3.6. It was +renamed to tlsproxy_client_security_level in Postfix 3.7. </p> + +%PARAM tlsproxy_client_security_level $smtp_tls_security_level + +<p> The default TLS security level for the Postfix tlsproxy(8) +client. See smtp_tls_security_level for further details. </p> + +<p> This feature is available in Postfix 3.7 and later. It +was previously called tlsproxy_client_level. </p> + +%PARAM tlsproxy_client_per_site $smtp_tls_per_site + +<p> Optional lookup tables with the Postfix tlsproxy(8) client TLS +usage policy by next-hop destination and by remote TLS server +hostname. See smtp_tls_per_site for further details. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_policy $smtp_tls_policy_maps + +<p> Optional lookup tables with the Postfix tlsproxy(8) client TLS +security policy by next-hop destination. See smtp_tls_policy_maps +for further details. </p> + +<p> This feature is available in Postfix 3.4 - 3.6. It was +renamed to tlsproxy_client_policy_maps in Postfix 3.7. </p> + +%PARAM tlsproxy_client_policy_maps $smtp_tls_policy_maps + +<p> Optional lookup tables with the Postfix tlsproxy(8) client TLS +security policy by next-hop destination. See smtp_tls_policy_maps +for further details. </p> + +<p> This feature is available in Postfix 3.7 and later. It +was previously called tlsproxy_client_policy. </p> + +%PARAM tlsproxy_client_use_tls $smtp_use_tls + +<p> Opportunistic mode: use TLS when a remote server announces TLS +support. See smtp_use_tls for further details. Use +tlsproxy_client_security_level instead. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_enforce_tls $smtp_enforce_tls + +<p> Enforcement mode: require that SMTP servers use TLS encryption. +See smtp_enforce_tls for further details. Use +tlsproxy_client_security_level instead. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM smtpd_tls_chain_files + +<p> List of one or more PEM files, each holding one or more private keys +directly followed by a corresponding certificate chain. The file names +are separated by commas and/or whitespace. This parameter obsoletes the +legacy algorithm-specific key and certificate file settings. When this +parameter is non-empty, the legacy parameters are ignored, and a warning +is logged if any are also non-empty. </p> + +<p> With the proliferation of multiple private key algorithms—which, +as of OpenSSL 1.1.1, include DSA (obsolete), RSA, ECDSA, Ed25519 +and Ed448—it is increasingly impractical to use separate +parameters to configure the key and certificate chain for each +algorithm. Therefore, Postfix now supports storing multiple keys and +corresponding certificate chains in a single file or in a set of files. + +<p> Each key must appear <b>immediately before</b> the corresponding +certificate, optionally followed by additional issuer certificates that +complete the certificate chain for that key. When multiple files are +specified, they are equivalent to a single file that is concatenated +from those files in the given order. Thus, while a key must always +precede its certificate and issuer chain, it can be in a separate file, +so long as that file is listed immediately before the file that holds +the corresponding certificate chain. Once all the files are +concatenated, the sequence of PEM objects must be: <i>key1, cert1, +[chain1], key2, cert2, [chain2], ..., keyN, certN, [chainN].</i> </p> + +<p> Storing the private key in the same file as the corresponding +certificate is more reliable. With the key and certificate in separate +files, there is a chance that during key rollover a Postfix process +might load a private key and certificate from separate files that don't +match. Various operational errors may even result in a persistent +broken configuration in which the certificate does not match the private +key. </p> + +<p> The file or files must contain at most one key of each type. If, +for example, two or more RSA keys and corresponding chains are listed, +depending on the version of OpenSSL either only the last one will be +used or a configuration error may be detected. Note that while +"Ed25519" and "Ed448" are considered separate algorithms, the various +ECDSA curves (typically one of prime256v1, secp384r1 or secp521r1) are +considered as different parameters of a single "ECDSA" algorithm, so it +is not presently possible to configure keys for more than one ECDSA +curve. </p> + +<p> RSA is still the most widely supported algorithm. Presently (late +2018), ECDSA support is common, but not yet universal, and Ed25519 and +Ed448 support is mostly absent. Therefore, an RSA key should generally +be configured, along with any additional keys for the other algorithms +when desired. </p> + +<p> +Example (separate files for each key and corresponding certificate chain): +</p> +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_chain_files = + ${config_directory}/ed25519.pem, + ${config_directory}/ed448.pem, + ${config_directory}/rsa.pem +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/ed25519.pem: + -----BEGIN PRIVATE KEY----- + MC4CAQAwBQYDK2VwBCIEIEJfbbO4BgBQGBg9NAbIJaDBqZb4bC4cOkjtAH+Efbz3 + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIBKzCB3qADAgECAhQaw+rflRreYuUZBp0HuNn/e5rMZDAFBgMrZXAwFDESMBAG + ... + nC0egv51YPDWxEHom4QA + -----END CERTIFICATE----- +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/ed448.pem: + -----BEGIN PRIVATE KEY----- + MEcCAQAwBQYDK2VxBDsEOQf+m0P+G0qi+NZ0RolyeiE5zdlPQR8h8y4jByBifpIe + LNler7nzHQJ1SLcOiXFHXlxp/84VZuh32A== + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIBdjCB96ADAgECAhQSv4oP972KypOZPNPF4fmsiQoRHzAFBgMrZXEwFDESMBAG + ... + pQcWsx+4J29e6YWH3Cy/CdUaexKP4RPCZDrPX7bk5C2BQ+eeYOxyThMA + -----END CERTIFICATE----- +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/rsa.pem: + -----BEGIN PRIVATE KEY----- + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDc4QusgkahH9rL + ... + ahQkZ3+krcaJvDSMgvu0tDc= + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIC+DCCAeCgAwIBAgIUIUkrbk1GAemPCT8i9wKsTGDH7HswDQYJKoZIhvcNAQEL + ... + Rirz15HGVNTK8wzFd+nulPzwUo6dH2IU8KazmyRi7OGvpyrMlm15TRE2oyE= + -----END CERTIFICATE----- +</pre> +</blockquote> + +<p> +Example (all keys and certificates in a single file): +</p> +<blockquote> +<pre> +/etc/postfix/main.cf: + smtpd_tls_chain_files = ${config_directory}/chains.pem +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/chains.pem: + -----BEGIN PRIVATE KEY----- + MC4CAQAwBQYDK2VwBCIEIEJfbbO4BgBQGBg9NAbIJaDBqZb4bC4cOkjtAH+Efbz3 + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIBKzCB3qADAgECAhQaw+rflRreYuUZBp0HuNn/e5rMZDAFBgMrZXAwFDESMBAG + ... + nC0egv51YPDWxEHom4QA + -----END CERTIFICATE----- + -----BEGIN PRIVATE KEY----- + MEcCAQAwBQYDK2VxBDsEOQf+m0P+G0qi+NZ0RolyeiE5zdlPQR8h8y4jByBifpIe + LNler7nzHQJ1SLcOiXFHXlxp/84VZuh32A== + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIBdjCB96ADAgECAhQSv4oP972KypOZPNPF4fmsiQoRHzAFBgMrZXEwFDESMBAG + ... + pQcWsx+4J29e6YWH3Cy/CdUaexKP4RPCZDrPX7bk5C2BQ+eeYOxyThMA + -----END CERTIFICATE----- + -----BEGIN PRIVATE KEY----- + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDc4QusgkahH9rL + ... + ahQkZ3+krcaJvDSMgvu0tDc= + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIC+DCCAeCgAwIBAgIUIUkrbk1GAemPCT8i9wKsTGDH7HswDQYJKoZIhvcNAQEL + ... + Rirz15HGVNTK8wzFd+nulPzwUo6dH2IU8KazmyRi7OGvpyrMlm15TRE2oyE= + -----END CERTIFICATE----- +</pre> +</blockquote> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM smtp_tls_chain_files + +<p> List of one or more PEM files, each holding one or more private keys +directly followed by a corresponding certificate chain. The file names +are separated by commas and/or whitespace. This parameter obsoletes the +legacy algorithm-specific key and certificate file settings. When this +parameter is non-empty, the legacy parameters are ignored, and a warning +is logged if any are also non-empty. </p> + +<p> With the proliferation of multiple private key algorithms—which, +as of OpenSSL 1.1.1, include DSA (obsolete), RSA, ECDSA, Ed25519 +and Ed448—it is increasingly impractical to use separate +parameters to configure the key and certificate chain for each +algorithm. Therefore, Postfix now supports storing multiple keys and +corresponding certificate chains in a single file or in a set of files. + +<p> Each key must appear <b>immediately before</b> the corresponding +certificate, optionally followed by additional issuer certificates that +complete the certificate chain for that key. When multiple files are +specified, they are equivalent to a single file that is concatenated +from those files in the given order. Thus, while a key must always +precede its certificate and issuer chain, it can be in a separate file, +so long as that file is listed immediately before the file that holds +the corresponding certificate chain. Once all the files are +concatenated, the sequence of PEM objects must be: <i>key1, cert1, +[chain1], key2, cert2, [chain2], ..., keyN, certN, [chainN].</i> </p> + +<p> Storing the private key in the same file as the corresponding +certificate is more reliable. With the key and certificate in separate +files, there is a chance that during key rollover a Postfix process +might load a private key and certificate from separate files that don't +match. Various operational errors may even result in a persistent +broken configuration in which the certificate does not match the private +key. </p> + +<p> The file or files must contain at most one key of each type. If, +for example, two or more RSA keys and corresponding chains are listed, +depending on the version of OpenSSL either only the last one will be +used or a configuration error may be detected. Note that while +"Ed25519" and "Ed448" are considered separate algorithms, the various +ECDSA curves (typically one of prime256v1, secp384r1 or secp521r1) are +considered as different parameters of a single "ECDSA" algorithm, so it +is not presently possible to configure keys for more than one ECDSA +curve. </p> + +<p> +Example (separate files for each key and corresponding certificate chain): +</p> +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_chain_files = + ${config_directory}/ed25519.pem, + ${config_directory}/ed448.pem, + ${config_directory}/rsa.pem +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/ed25519.pem: + -----BEGIN PRIVATE KEY----- + MC4CAQAwBQYDK2VwBCIEIEJfbbO4BgBQGBg9NAbIJaDBqZb4bC4cOkjtAH+Efbz3 + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIBKzCB3qADAgECAhQaw+rflRreYuUZBp0HuNn/e5rMZDAFBgMrZXAwFDESMBAG + ... + nC0egv51YPDWxEHom4QA + -----END CERTIFICATE----- +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/ed448.pem: + -----BEGIN PRIVATE KEY----- + MEcCAQAwBQYDK2VxBDsEOQf+m0P+G0qi+NZ0RolyeiE5zdlPQR8h8y4jByBifpIe + LNler7nzHQJ1SLcOiXFHXlxp/84VZuh32A== + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIBdjCB96ADAgECAhQSv4oP972KypOZPNPF4fmsiQoRHzAFBgMrZXEwFDESMBAG + ... + pQcWsx+4J29e6YWH3Cy/CdUaexKP4RPCZDrPX7bk5C2BQ+eeYOxyThMA + -----END CERTIFICATE----- +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/rsa.pem: + -----BEGIN PRIVATE KEY----- + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDc4QusgkahH9rL + ... + ahQkZ3+krcaJvDSMgvu0tDc= + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIC+DCCAeCgAwIBAgIUIUkrbk1GAemPCT8i9wKsTGDH7HswDQYJKoZIhvcNAQEL + ... + Rirz15HGVNTK8wzFd+nulPzwUo6dH2IU8KazmyRi7OGvpyrMlm15TRE2oyE= + -----END CERTIFICATE----- +</pre> +</blockquote> + +<p> +Example (all keys and certificates in a single file): +</p> +<blockquote> +<pre> +/etc/postfix/main.cf: + smtp_tls_chain_files = ${config_directory}/chains.pem +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/chains.pem: + -----BEGIN PRIVATE KEY----- + MC4CAQAwBQYDK2VwBCIEIEJfbbO4BgBQGBg9NAbIJaDBqZb4bC4cOkjtAH+Efbz3 + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIBKzCB3qADAgECAhQaw+rflRreYuUZBp0HuNn/e5rMZDAFBgMrZXAwFDESMBAG + ... + nC0egv51YPDWxEHom4QA + -----END CERTIFICATE----- + -----BEGIN PRIVATE KEY----- + MEcCAQAwBQYDK2VxBDsEOQf+m0P+G0qi+NZ0RolyeiE5zdlPQR8h8y4jByBifpIe + LNler7nzHQJ1SLcOiXFHXlxp/84VZuh32A== + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIBdjCB96ADAgECAhQSv4oP972KypOZPNPF4fmsiQoRHzAFBgMrZXEwFDESMBAG + ... + pQcWsx+4J29e6YWH3Cy/CdUaexKP4RPCZDrPX7bk5C2BQ+eeYOxyThMA + -----END CERTIFICATE----- + -----BEGIN PRIVATE KEY----- + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDc4QusgkahH9rL + ... + ahQkZ3+krcaJvDSMgvu0tDc= + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIC+DCCAeCgAwIBAgIUIUkrbk1GAemPCT8i9wKsTGDH7HswDQYJKoZIhvcNAQEL + ... + Rirz15HGVNTK8wzFd+nulPzwUo6dH2IU8KazmyRi7OGvpyrMlm15TRE2oyE= + -----END CERTIFICATE----- +</pre> +</blockquote> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM lmtp_tls_chain_files + +<p> The LMTP-specific version of the smtp_tls_chain_files configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_client_chain_files $smtp_tls_chain_files + +<p> Files with the Postfix tlsproxy(8) client keys and certificate +chains in PEM format. See smtp_tls_chain_files for further details. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tlsproxy_tls_chain_files $smtpd_tls_chain_files + +<p> Files with the Postfix tlsproxy(8) server keys and certificate +chains in PEM format. See smtpd_tls_chain_files for further details. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM tls_server_sni_maps + +<p> Optional lookup tables that map names received from remote SMTP +clients via the TLS Server Name Indication (SNI) extension to the +appropriate keys and certificate chains. This parameter is implemented +in the Postfix TLS library, and applies to both smtpd(8) and the SMTP +server mode of tlsproxy(8). </p> + +<p> When this parameter is non-empty, the Postfix SMTP server enables +SNI extension processing, and logs SNI values that are invalid or +don't match an entry in the specified tables. When an entry +does match, the SNI name is logged as part of the connection summary +at log levels 1 and higher. </p> + +<p> The lookup key is either the verbatim SNI domain name or an +ancestor domain prefixed with a leading dot. For internationalized +domains, the lookup key must be in IDNA 2008 A-label form (as +required in the TLS SNI extension). </p> + +<p> The syntax of the lookup value is the same as with the +smtp_tls_chain_files parameter (see there for additional details), +but here scoped to just TLS connections in which the client sends +a matching SNI domain name. </p> + +<p> Example: </p> +<blockquote> +<pre> +/etc/postfix/main.cf: + # + # The indexed SNI table must be created with "postmap -F" + # + indexed = ${default_database_type}:${config_directory}/ + tls_server_sni_maps = ${indexed}sni +</pre> +</blockquote> + +<blockquote> +<pre> +/etc/postfix/sni: + # + # The example.com domain has both an RSA and ECDSA certificate + # chain. The chain files MUST start with the private key, + # with the certificate chain next, starting with the leaf + # (server) certificate, and then the issuer certificates. + # + example.com /etc/postfix/sni-chains/rsa2048.example.com.pem, + /etc/postfix/sni-chains/ecdsa-p256.example.com.pem + # + # The example.net domain has a wildcard certificate, and two + # additional DNS names. So its certificate chain is also used + # with any subdomain, plus the additional names. + # + example.net /etc/postfix/sni-chains/example.net.pem + .example.net /etc/postfix/sni-chains/example.net.pem + example.info /etc/postfix/sni-chains/example.net.pem + example.org /etc/postfix/sni-chains/example.net.pem +</pre> +</blockquote> + +<p> Note that the SNI lookup tables should also have entries for +the domains that correspond to the Postfix SMTP server's default +certificate(s). This ensures that the remote SMTP client's TLS SNI +extension gets a positive response when it specifies one of the +Postfix SMTP server's default domains, and ensures that the Postfix +SMTP server will not log an SNI name mismatch for such a domain. +The Postfix SMTP server's default certificates are then only used +when the client sends no SNI or when it sends SNI with a domain +that the server knows no certificate(s) for. </p> + +<p> The mapping from an SNI domain name to a certificate chain is indirect. In +the input source files for "cdb", "hash", "btree" or other tables that are +converted to on-disk indexed files via postmap(1), the value specified for each +key is a list of filenames. When postmap(1) is used with the <b>-F</b> option, +the generated table stores for each lookup key the base64-encoded contents of +the associated files. When querying tables via <b>postmap -Fq</b>, the table +value is decoded from base64, yielding the original file content, plus a new +line. </p> + +<p> With "regexp", "pcre", "inline", "texthash", "static" and similar +tables that are interpreted at run-time, and don't have a separate +source format, the table value is again a list files, that are loaded +into memory when the table is opened. </p> + +<p> With tables whose content is managed outside of Postfix, such +as LDAP, MySQL, PostgreSQL, socketmap and tcp, the value must be a +concatenation of the desired PEM keys and certificate chains, that +is then further encoded to yield a single-line base64 string. +Creation of such tables and secure storage (the value includes +private key material) are outside the responsibility of Postfix. </p> + +<p> With "socketmap" and "tcp" the data will be transmitted in the clear, and +there is no query access control, so these are generally unsuitable for storing +SNI chains. With LDAP and SQL, you should restrict read access and use TLS to +protect the sensitive data in transit. </p> + +<p> Typically there is only one private key and its chain of certificates +starting with the "leaf" certificate corresponding to that key, and +continuing with the appropriate intermediate issuer CA certificates, +with each certificate ideally followed by its issuer. Servers +that have keys and certificates for more than one algorithm (e.g. +both an RSA key and an ECDSA key, or even RSA, ECDSA and Ed25519) +can use multiple chains concatenated together, with the key always +listed before the corresponding certificates. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM smtp_tls_servername + +<p> Optional name to send to the remote SMTP server in the TLS Server +Name Indication (SNI) extension. The SNI extension is always on when +DANE is used to authenticate the server, and in that case the SNI name +sent is the one required by RFC7672 and this parameter is ignored. </p> + +<p> Some SMTP servers use the received SNI name to select an appropriate +certificate chain to present to the client. While this may improve +interoperability with such servers, it may reduce interoperability with +other servers that choose to abort the connection when they don't have a +certificate chain configured for the requested name. Such servers +should select a default certificate chain and continue the handshake, +but some may not. Therefore, absent DANE, no SNI name is sent by +default. </p> + +<p> The SNI name must be either a valid DNS hostname, or else one of the +special values <b>hostname</b> or <b>nexthop</b>, which select either the +remote hostname or the nexthop domain respectively. DNS names for SNI must be +in A-label (punycode) form. Invalid DNS names log a configuration error +warning and mail delivery is deferred. </p> + +<p> Except when using a relayhost to forward all email, the only +sensible non-empty main.cf setting for this parameter is +<b>hostname</b>. Other non-empty values are only practical on a +per-destination basis via the <b>servername</b> attribute of the Postfix +TLS <a href="TLS_README.html#client_tls_policy">policy table</a>. When +in doubt, leave this parameter empty, and configure per-destination SNI +as needed. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM lmtp_tls_servername + +<p> The LMTP-specific version of the smtp_tls_servername configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM maillog_file + +<p> The name of an optional logfile that is written by the Postfix +postlogd(8) service. An empty value selects logging to syslogd(8). +Specify "/dev/stdout" to select logging to standard output. Stdout +logging requires that Postfix is started with "postfix start-fg". +</p> + +<p> Note 1: The maillog_file parameter value must contain a prefix +that is specified with the maillog_file_prefixes parameter. </p> + +<p> Note 2: Some Postfix non-daemon programs may still log information +to syslogd(8), before they have processed their configuration +parameters and command-line options. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM postlog_service_name postlog + +<p> The name of the postlogd(8) service entry in master.cf. +This service appends logfile records to the file specified +with the maillog_file parameter. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM postlogd_watchdog_timeout 10s + +<p> How much time a postlogd(8) process may take to process a request +before it is terminated by a built-in watchdog timer. This is a +safety mechanism that prevents postlogd(8) from becoming non-responsive +due to a bug in Postfix itself or in system software. This limit +cannot be set under 10s. </p> + +<p> Specify a non-zero time value (an integral value plus an optional +one-letter suffix that specifies the time unit). Time units: s +(seconds), m (minutes), h (hours), d (days), w (weeks). +The default time unit is s (seconds). </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM maillog_file_prefixes /var, /dev/stdout + +<p> A list of allowed prefixes for a maillog_file value. This is a +safety feature to contain the damage from a single configuration +mistake. Specify one or more prefix strings, separated by comma or +whitespace. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM maillog_file_compressor gzip + +<p> The program to run after rotating $maillog_file with "postfix +logrotate". The command is run with the rotated logfile name as its +first argument. </p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM maillog_file_rotate_suffix %Y%m%d-%H%M%S + +<p> The format of the suffix to append to $maillog_file while rotating +the file with "postfix logrotate". See strftime(3) for syntax. The +default suffix, YYYYMMDD-HHMMSS, allows logs to be rotated frequently. +</p> + +<p> This feature is available in Postfix 3.4 and later. </p> + +%PARAM info_log_address_format external + +<p> The email address form that will be used in non-debug logging +(info, warning, etc.). As of Postfix 3.5 when an address localpart +contains spaces or other special characters, the localpart will be +quoted, for example: </p> + +<blockquote> +<pre> + from=<"name with spaces"@example.com> +</pre> +</blockquote> + +<p> Older Postfix versions would log the internal (unquoted) form: </p> + +<blockquote> +<pre> + from=<name with spaces@example.com> +</pre> +</blockquote> + +<p> The external and internal forms are identical for the vast +majority of email addresses that contain no spaces or other special +characters in the localpart. </p> + +<p> The logging in external form is consistent with the address +form that Postfix 3.2 and later prefer for most table lookups. This +is therefore the more useful form for non-debug logging. </p> + +<p> Specify "<b>info_log_address_format = internal</b>" for backwards +compatibility. </p> + +<p> Postfix uses the unquoted form internally, because an attacker +can specify an email address in different forms by playing games +with quotes and backslashes. An attacker should not be able to use +such games to circumvent Postfix access policies. </p> + +<p> This feature is available in Postfix 3.5 and later. </p> + +%PARAM smtpd_sasl_mechanism_filter !external, static:rest + +<p> If non-empty, a filter for the SASL mechanism names that the +Postfix SMTP server will announce in the EHLO response. By default, +the Postfix SMTP server will not announce the EXTERNAL mechanism, +because Postfix support for that is not implemented. </p> + +<p> Specify mechanism names, "/file/name" patterns, or "type:table" +lookup tables, separated by comma or whitespace. The right-hand +side result from "type:table" lookups is ignored. Specify "!pattern" +to exclude a mechanism name from the list. </p> + +<p> +Examples: +</p> + +<pre> +smtpd_sasl_mechanism_filter = !external, !gssapi, static:rest +smtpd_sasl_mechanism_filter = login, plain +smtpd_sasl_mechanism_filter = /etc/postfix/smtpd_mechs +</pre> + +<p> This feature is available in Postfix 3.6 and later. </p> + +%PARAM dnssec_probe ns:. + +<p> The DNS query type (default: "ns") and DNS query name (default: +".") that Postfix may use to determine whether DNSSEC validation +is available. +</p> + +<p> Background: DNSSEC validation is needed for Postfix DANE support; +this ensures that Postfix receives TLSA records with secure TLS +server certificate info. When DNSSEC validation is unavailable, +mail deliveries using <i>opportunistic</i> DANE will not be protected +by server certificate info in TLSA records, and mail deliveries +using <i>mandatory</i> DANE will not be made at all. </p> + +<p> By default, a Postfix process will send a DNSSEC probe after +1) the process made a DNS query that requested DNSSEC validation, +2) the process did not receive a DNSSEC validated response to this +query or to an earlier query, and 3) the process did not already +send a DNSSEC probe. <p> + +<p> When the DNSSEC probe has no response, or when the response is +not DNSSEC validated, Postfix logs a warning that DNSSEC validation +may be unavailable. </p> + +<p> Example: </p> + +<pre> +warning: DNSSEC validation may be unavailable +warning: reason: dnssec_probe 'ns:.' received a response that is not DNSSEC validated +warning: reason: dnssec_probe 'ns:.' received no response: Server failure +</pre> + +<p> Possible reasons why DNSSEC validation may be unavailable: </p> + +<ul> + +<li> The local /etc/resolv.conf file specifies a DNS resolver that +does not validate DNSSEC signatures (that's +$queue_directory/etc/resolv.conf when a Postfix daemon runs in a +chroot jail). + +<li> The local system library does not pass on the "DNSSEC validated" +bit to Postfix, or Postfix does not know how to ask the library to +do that. + +</ul> + +<p> By default, the DNSSEC probe asks for the DNS root zone NS +records, because resolvers should always have that information +cached. If Postfix runs on a network where the DNS root zone is not +reachable, specify a different probe, or specify an empty dnssec_probe +value to disable the feature. </p> + +<p> This feature is available in Postfix 3.6 and later. It was backported +to Postfix versions 3.5.9, 3.4.19, 3.3.16. 3.2.21. </p> + +%PARAM local_login_sender_maps static:* + +<p> A list of lookup tables that are searched by the UNIX login name, +and that return a list of allowed envelope sender patterns separated +by space or comma. These sender patterns are enforced by the Postfix +postdrop(1) command. The default is backwards-compatible: +every user may specify any sender envelope address. </p> + +<p> When no UNIX login name is available, the postdrop(1) command will +prepend "<b>uid:</b>" to the numerical UID and use that instead. </p> + +<p> This feature ignores address extensions in the user-specified +envelope sender address. </p> + +<p> The following sender patterns are special; these cannot be used +as part of a longer pattern. </p> + +<dl compact> + +<dt> <b> * </b> <dd> This pattern allows any envelope sender address. +</dd> + +<dt> <b> <> </b> </dt> <dd> This pattern allows the empty +envelope sender address. See the +empty_address_local_login_sender_maps_lookup_key configuration +parameter. </dd> + +<dt> <b> @</b><i>domain</i> </dt> <dd> This pattern allows an +envelope sender address when the '<b>@</b>' and <i>domain</i> part +match. </dd> + +</dl> + +<p> Examples: </p> + +<pre> +/etc/postfix/main.cf: + # Allow root and postfix full control, anyone else can only + # send mail as themselves. Use "uid:" followed by the numerical + # UID when the UID has no entry in the UNIX password file. + local_login_sender_maps = + inline:{ { root = * }, { postfix = * } }, + pcre:/etc/postfix/login_senders +</pre> + +<pre> +/etc/postfix/login_senders: + # Allow both the bare username and the user@domain forms. + /(.+)/ $1 $1@example.com +</pre> + +<p> This feature is available in Postfix 3.6 and later. </p> + +%PARAM empty_address_local_login_sender_maps_lookup_key <> + +<p> +The lookup key to be used in local_login_sender_maps tables, instead +of the null sender address. +</p> + +<p> This feature is available in Postfix 3.6 and later. </p> + +%PARAM enable_threaded_bounces no + +<p> Enable non-delivery, success, and delay notifications that link +to the original message by including a References: and In-Reply-To: +header with the original Message-ID value. There are advantages and +disadvantages to consider. </p> + +<dl> + +<dt> <b> advantage </b> </dt> <dd> This allows mail readers to present +a delivery status notification in the same email thread as the original +message. </dd> + +<dt> <b> disadvantage </b> </dt> <dd> This makes it easy for users to +mistakenly delete the whole email thread (all related messages), +instead of deleting only the non-delivery notification. </dd> + +</dl> + +<p> This feature is available in Postfix 3.6 and later. </p> + +%PARAM smtpd_relay_before_recipient_restrictions see "postconf -d" output + +<p> Evaluate smtpd_relay_restrictions before smtpd_recipient_restrictions. +Historically, smtpd_relay_restrictions was evaluated after +smtpd_recipient_restrictions, contradicting documented behavior. </p> + +<p> Background: the smtpd_relay_restrictions feature is primarily +designed to enforce a mail relaying policy, while +smtpd_recipient_restrictions is primarily designed to enforce spam +blocking policy. Both are evaluated while replying to the RCPT TO +command, and both support the same features. </p> + +<p> This feature is available in Postfix 3.6 and later. </p> + +%PARAM respectful_logging see 'postconf -d' output + +<p> Avoid logging that implies white is better than black. Instead +use 'allowlist', 'denylist', and variations of those words. </p> + +<p> This feature is available in Postfix 3.6 and later. </p> + +%PARAM known_tcp_ports lmtp=24, smtp=25, smtps=submissions=465, submission=587 + +<p> Optional setting that avoids lookups in the services(5) database. +This feature was implemented to address inconsistencies in the name +of the port "465" service. The ABNF is: +</p> + +<blockquote> +<p> +known_tcp_ports = empty | name-to-port *("," name-to-port) <br> +name-to-port = 1*(service-name "=') port-number +</p> +</blockquote> + +<p> The comma is required. Whitespace is optional but it cannot appear +inside a service name or port number. </p> + +<p> This feature is available in Postfix 3.6 and later. </p> + +%PARAM smtpd_min_data_rate 500 + +<p> The minimum plaintext data transfer rate in bytes/second for +DATA and BDAT requests, when deadlines are enabled with +smtpd_per_request_deadline. After a read operation transfers N +plaintext message bytes (possibly after TLS decryption), and after +the DATA or BDAT request deadline is decremented by the elapsed +time of that read operation, the DATA or BDAT request deadline is +incremented by N/smtpd_min_data_rate seconds. However, the deadline +will never be incremented beyond the time limit specified with +smtpd_timeout. </p> + +<p> This feature is available in Postfix 3.7 and later. </p> + +%PARAM smtpd_per_request_deadline normal: no, overload: yes + +<p> Change the behavior of the smtpd_timeout and smtpd_starttls_timeout +time limits, from a time limit per plaintext or TLS read or write +call, to a combined time limit for receiving a complete SMTP request +and for sending a complete SMTP response. The deadline limits only +the time spent waiting for plaintext or TLS read or write calls, +not time spent elsewhere. The per-request deadline limits the impact +from hostile peers that trickle data one byte at a time. </p> + +<p> See smtpd_min_data_rate for how the per-request deadline is +managed during the DATA and BDAT phase. </p> + +<p> Note: when per-request deadlines are enabled, a short time limit +may cause problems with TLS over very slow network connections. The +reason is that a TLS protocol message can be up to 16 kbytes long +(with TLSv1), and that an entire TLS protocol message must be +transferred within the per-request deadline. </p> + +<p> This feature is available in Postfix 3.7 and later. A weaker +feature, called smtpd_per_record_deadline, is available with Postfix +2.9-3.6. With older Postfix releases, the behavior is as if this +parameter is set to "no". </p> + +<p> This feature is available in Postfix 3.7 and later. </p> + +%PARAM lmtp_min_data_rate 500 + +<p> The LMTP-specific version of the smtp_min_data_rate configuration +parameter. See there for details. </p> + +<p> This feature is available in Postfix 3.7 and later. </p> + +%PARAM lmtp_per_request_deadline no + +<p> The LMTP-specific version of the smtp_per_request_deadline +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 3.7 and later. </p> + +%PARAM smtp_min_data_rate 500 + +<p> The minimum plaintext data transfer rate in bytes/second for +DATA requests, when deadlines are enabled with smtp_per_request_deadline. +After a write operation transfers N plaintext message bytes (possibly +after TLS encryption), and after the DATA request deadline is +decremented by the elapsed time of that write operation, the DATA +request deadline is incremented by N/smtp_min_data_rate seconds. +However, the deadline will never be incremented beyond the time +limit specified with smtp_data_xfer_timeout. </p> + +<p> This feature is available in Postfix 3.7 and later. </p> + +%PARAM smtp_per_request_deadline no + +<p> Change the behavior of the smtp_*_timeout time limits, from a +time limit per plaintext or TLS read or write call, to a combined +time limit for sending a complete SMTP request and for receiving a +complete SMTP response. The deadline limits only the time spent +waiting for plaintext or TLS read or write calls, not time spent +elsewhere. The per-request deadline limits the impact from hostile +peers that trickle data one byte at a time. </p> + +<p> See smtp_min_data_rate for how the per-request deadline is +managed during the DATA phase. </p> + +<p> Note: when per-request deadlines are enabled, a short time limit +may cause problems with TLS over very slow network connections. The +reason is that a TLS protocol message can be up to 16 kbytes long +(with TLSv1), and that an entire TLS protocol message must be +transferred within the per-request deadline. </p> + +<p> This feature is available in Postfix 3.7 and later. A weaker +feature, called smtp_per_record_deadline, is available with Postfix +2.9-3.6. </p> + +<p> This feature is available in Postfix 3.7 and later. </p> + +%PARAM smtp_bind_address_enforce no + +<p> Defer delivery when the Postfix SMTP client cannot apply the +smtp_bind_address or smtp_bind_address6 setting. By default, the +Postfix SMTP client will continue delivery after logging a warning. +</p> + +<p> This feature is available in Postfix 3.7 and later. </p> + +%PARAM lmtp_bind_address_enforce + +<p> The LMTP-specific version of the smtp_bind_address_enforce +configuration parameter. See there for details. </p> + +<p> This feature is available in Postfix 3.7 and later. </p> + +%PARAM tls_config_name + +<p> The application name passed by Postfix to OpenSSL library +initialization functions. This name is used to select the desired +configuration "section" in the OpenSSL configuration file specified +via the tls_config_file parameter. When empty, or when the +selected name is not present in the configuration file, the default +application name ("openssl_conf") is used as a fallback. </p> + +<p> This feature is available in Postfix ≥ 3.9, 3.8.1, 3.7.6, +3.6.10, and 3.5.20. </p> + +%PARAM tls_config_file default + +<p> Optional configuration file with baseline OpenSSL settings. +OpenSSL loads any SSL settings found in the configuration file for +the selected application name (see tls_config_name) or else the +built-in application name "openssl_conf" when no application name is +specified, or no corresponding configuration section is present. +</p> + +<p> With OpenSSL releases 1.1.1 and 1.1.1a, applications (including +Postfix) can neither specify an alternative configuration file, nor +avoid loading the default configuration file. </p> + +<p> With OpenSSL 1.1.1b or later, this parameter may be set to one of: +</p> + +<dl> + +<dt> <b>default</b> (default) </dt> <dd> Load the system-wide +"openssl.cnf" configuration file. </dd> + +<dt> <b>none</b> (recommended, OpenSSL 1.1.1b or later only) </dt> +<dd> This setting disables loading of the system-wide "openssl.cnf" +file. </dd> + +<dt> <b><i>/absolute-path</i></b> (OpenSSL 1.1.1b or later only) </dt> +<dd> Load the configuration file specified by <i>/absolute-path</i>. +With this setting it is an error for the file to not contain any +settings for the selected tls_config_name. There is no fallback to +the default "openssl_conf" name. </dd> + +</dl> + +<p> Failures in processing of the built-in default configuration file, +are silently ignored. Any errors in loading a non-default configuration +file are detected by Postfix, and cause TLS support to be disabled. +</p> + +<p> The OpenSSL configuration file format is not documented here, +beyond giving two examples. <p> + +<p> Example: Default settings for all applications. </p> + +<blockquote> +<pre> +# The name 'openssl_conf' is the default application name +# The section name to the right of the '=' sign is arbitrary, +# any name will do, so long as it refers to the desired section. +# +# The name 'system_default' selects the settings applied internally +# by the SSL library as part of SSL object creation. Applications +# can then apply any additional settings of their choice. +# +# In this example, TLS versions prior to 1.2 are disabled by default. +# +openssl_conf = system_wide_settings +[system_wide_settings] +ssl_conf = ssl_library_settings +[ssl_library_settings] +system_default = initial_ssl_settings +[initial_ssl_settings] +MinProtocol = TLSv1.2 +</pre> +</blockquote> + +<p> Example: Custom settings for an application named "postfix". </p> + +<blockquote> +<pre> +# The mapping from an application name to the corresponding configuration +# section must appear near the top of the file, (in what is sometimes called +# the "default section") prior to the start of any explicitly named +# "[sections]". The named sections can appear in any order and don't nest. +# +postfix = postfix_settings +[postfix_settings] +ssl_conf = postfix_ssl_settings +[postfix_ssl_settings] +system_default = baseline_postfix_settings +[baseline_postfix_settings] +MinProtocol = TLSv1 +</pre> +</blockquote> + +<p> This feature is available in Postfix ≥ 3.9, 3.8.1, 3.7.6, +3.6.10, and 3.5.20. </p> + +%PARAM smtpd_forbid_bare_newline Postfix < 3.9: no + +<p> Reject or restrict input lines from an SMTP client that end in +<LF> instead of the standard <CR><LF>. Such line +endings are commonly allowed with UNIX-based SMTP servers, but they +violate RFC 5321, and allowing such line endings can make a server +vulnerable to <a href="https://www.postfix.org/smtp-smuggling.html"> +SMTP smuggling</a>. </p> + +<p> Specify one of the following values (case does not matter): </p> + +<dl compact> + +<dt> <b>normalize</b></dt> <dd> Require the standard +End-of-DATA sequence <CR><LF>.<CR><LF>. +Otherwise, allow command or message content lines ending in the +non-standard <LF>, and process them as if the client sent the +standard <CR><LF>. <br> <br> This maintains compatibility +with many legitimate SMTP client applications that send a mix of +standard and non-standard line endings, but will fail to receive +email from client implementations that do not terminate DATA content +with the standard End-of-DATA sequence +<CR><LF>.<CR><LF>. <br> <br> Such clients +can be excluded with smtpd_forbid_bare_newline_exclusions. </dd> + +<dt> <b>yes</b> </dt> <dd> Compatibility alias for <b>normalize</b>. </dd> + +<dt> <b>reject</b> </dt> <dd> Require the standard End-of-DATA +sequence <CR><LF>.<CR><LF>. Reject a command +or message content when a line contains bare <LF>, log a "bare +<LF> received" error, and reply with the SMTP status code in +$smtpd_forbid_bare_newline_reject_code. <br> <br> This will reject +email from SMTP clients that send any non-standard line endings +such as web applications, netcat, or load balancer health checks. +<br> <br> This will also reject email from services that use BDAT +to send MIME text containing a bare newline (RFC 3030 Section 3 +requires canonical MIME format for text message types, defined in +RFC 2045 Sections 2.7 and 2.8). <br> <br> Such clients can be +excluded with smtpd_forbid_bare_newline_exclusions (or, in the case +of BDAT violations, BDAT can be selectively disabled with +smtpd_discard_ehlo_keyword_address_maps, or globally disabled with +smtpd_discard_ehlo_keywords). </dd> + +<dt> <b>no</b> (default)</dt> <dd> Do not require the standard +End-of-DATA +sequence <CR><LF>.<CR><LF>. Always process +a bare <LF> as if the client sent <CR><LF>. This +option is fully backwards compatible, but is not recommended for +an Internet-facing SMTP server, because it is vulnerable to <a +href="https://www.postfix.org/smtp-smuggling.html"> SMTP smuggling</a>. +</dd> + +</dl> + +<p> Recommended settings: </p> + +<blockquote> +<pre> +# Require the standard End-of-DATA sequence <CR><LF>.<CR><LF>. +# Otherwise, allow bare <LF> and process it as if the client sent +# <CR><LF>. +# +# This maintains compatibility with many legitimate SMTP client +# applications that send a mix of standard and non-standard line +# endings, but will fail to receive email from client implementations +# that do not terminate DATA content with the standard End-of-DATA +# sequence <CR><LF>.<CR><LF>. +# +# Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions. +# The example below allowlists SMTP clients in trusted networks. +# +smtpd_forbid_bare_newline = normalize +smtpd_forbid_bare_newline_exclusions = $mynetworks +</pre> +</blockquote> + +<p> Alternative: </p> + +<blockquote> +<pre> +# Reject input lines that contain <LF> and log a "bare <LF> received" +# error. Require that input lines end in <CR><LF>, and require the +# standard End-of-DATA sequence <CR><LF>.<CR><LF>. +# +# This will reject email from SMTP clients that send any non-standard +# line endings such as web applications, netcat, or load balancer +# health checks. +# +# This will also reject email from services that use BDAT to send +# MIME text containing a bare newline (RFC 3030 Section 3 requires +# canonical MIME format for text message types, defined in RFC 2045 +# Sections 2.7 and 2.8). +# +# Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions. +# The example below allowlists SMTP clients in trusted networks. +# +smtpd_forbid_bare_newline = reject +smtpd_forbid_bare_newline_exclusions = $mynetworks +# +# Alternatively, in the case of BDAT violations, BDAT can be selectively +# disabled with smtpd_discard_ehlo_keyword_address_maps, or globally +# disabled with smtpd_discard_ehlo_keywords. +# +# smtpd_discard_ehlo_keyword_address_maps = cidr:/path/to/file +# /path/to/file: +# 10.0.0.0/24 chunking, silent-discard +# smtpd_discard_ehlo_keywords = chunking, silent-discard +</pre> +</blockquote> + +<p> This feature with settings <b>yes</b> and <b>no</b> is available +in Postfix 3.8.4, 3.7.9, 3.6.13, and 3.5.23. Additionally, the +settings <b>reject</b>, and <b>normalize</b> are available with +Postfix ≥ 3.9, 3.8.5, 3.7.10, 3.6.14, and 3.5.24. </p> + +%PARAM smtpd_forbid_bare_newline_exclusions $mynetworks + +<p> Exclude the specified clients from smtpd_forbid_bare_newline +enforcement. This setting uses the same syntax and parent-domain +matching behavior as mynetworks. </p> + +<p> This feature is available in Postfix ≥ 3.9, 3.8.4, 3.7.9, +3.6.13, and 3.5.23. </p> + +%PARAM smtpd_forbid_bare_newline_reject_code 550 + +<p> +The numerical Postfix SMTP server response code when rejecting a +request with "smtpd_forbid_bare_newline = reject". +Specify a 5XX status code (521 to disconnect). +</p> + +<p> This feature is available in Postfix ≥ 3.9, 3.8.5, 3.7.10, +3.6.14, and 3.5.24. </p> + +%PARAM cleanup_replace_stray_cr_lf yes + +<p> Replace each stray <CR> or <LF> character in message +content with a space character, to prevent outbound SMTP smuggling, +and to make the evaluation of Postfix-added DKIM or other signatures +independent from how a remote mail server handles such characters. +</p> + +<p> SMTP does not allow such characters unless they are part of a +<CR><LF> sequence, and different mail systems handle +such stray characters in an implementation-dependent manner. Stray +<CR> or <LF> characters could be used for outbound +SMTP smuggling, where an attacker uses a Postfix server to send +message content with a non-standard End-of-DATA sequence that +triggers inbound SMTP smuggling at a remote SMTP server.</p> + +<p> The replacement happens before all other content management, +and before Postfix may add a DKIM etc. signature; if the signature +were created first, the replacement could invalidate the signature. +</p> + +<p> In addition to preventing SMTP smuggling, replacing stray +<CR> or <LF> characters ensures that the result of +signature validation by later mail system will not depend on how +that mail system handles those stray characters in an +implementation-dependent manner. </p> + +<p> This feature is available in Postfix ≥ 3.9, 3.8.5, 3.7.10, +3.6.14, and 3.5.24. </p> + +%PARAM smtpd_forbid_unauth_pipelining Postfix ≥ 3.9: yes + +<p> Disconnect remote SMTP clients that violate RFC 2920 (or 5321) +command pipelining constraints. The server replies with "554 5.5.0 +Error: SMTP protocol synchronization" and logs the unexpected remote +SMTP client input. Specify "smtpd_forbid_unauth_pipelining = yes" +to enable. This feature is enabled by default with Postfix ≥ +3.9. </p> + +<p> This feature is available in Postfix ≥ 3.9, 3.8.1, 3.7.6, +3.6.10, and 3.5.20. </p> diff --git a/proto/postfix-wrapper b/proto/postfix-wrapper new file mode 100644 index 0000000..177282e --- /dev/null +++ b/proto/postfix-wrapper @@ -0,0 +1,290 @@ +#++ +# NAME +# postfix-wrapper 5 +# SUMMARY +# Postfix multi-instance API +# DESCRIPTION +# Support for managing multiple Postfix instances is available +# as of version 2.6. Instances share executable files and +# documentation, but have their own directories for configuration, +# queue and data files. +# +# This document describes how the familiar "postfix start" +# etc. user interface can be used to manage one or multiple +# Postfix instances, and gives details of an API to coordinate +# activities between the postfix(1) command and a multi-instance +# manager program. +# +# With multi-instance support, the default Postfix instance +# is always required. This instance is identified by the +# config_directory parameter's default value. +# GENERAL OPERATION +# .ad +# .fi +# Multi-instance support is backwards compatible: when you +# run only one Postfix instance, commands such as "postfix +# start" will not change behavior at all. +# +# Even with multiple Postfix instances, you can keep using +# the same postfix commands in boot scripts, upgrade procedures, +# and other places. The commands do more work, but humans are +# not forced to learn new tricks. +# +# For example, to start all Postfix instances, use: +# .IP +# # postfix start +# .PP +# Other postfix(1) commands also work as expected. For example, +# to find out what Postfix instances exist in a multi-instance +# configuration, use: +# .IP +# # postfix status +# .PP +# This enumerates the status of all Postfix instances within +# a multi-instance configuration. +# MANAGING AN INDIVIDUAL POSTFIX INSTANCE +# .ad +# .fi +# To manage a specific Postfix instance, specify its configuration +# directory on the postfix(1) command line: +# .IP +# # postfix -c \fI/path/to/config_directory command\fR +# .PP +# Alternatively, the postfix(1) command accepts the instance's +# configuration directory via the MAIL_CONFIG environment +# variable (the -c command-line option has higher precedence). +# +# Otherwise, the postfix(1) command will operate on all Postfix +# instances. +# ENABLING POSTFIX(1) MULTI-INSTANCE MODE +# .ad +# .fi +# By default, the postfix(1) command operates in single-instance +# mode. In this mode the command invokes the postfix-script +# file directly (currently installed in the daemon directory). +# This file contains the commands that start or stop one +# Postfix instance, that upgrade the configuration of one +# Postfix instance, and so on. +# +# When the postfix(1) command operates in multi-instance mode +# as discussed below, the command needs to execute start, +# stop, etc. commands for each Postfix instance. This +# multiplication of commands is handled by a multi-instance +# manager program. +# +# Turning on postfix(1) multi-instance mode goes as follows: +# in the default Postfix instance's main.cf file, 1) specify +# the pathname of a multi-instance manager program with the +# multi_instance_wrapper parameter; 2) populate the +# multi_instance_directories parameter with the configuration +# directory pathnames of additional Postfix instances. For +# example: +# .IP +# .nf +# /etc/postfix/main.cf: +# multi_instance_wrapper = $daemon_directory/postfix-wrapper +# multi_instance_directories = /etc/postfix-test +# .fi +# .PP +# The $daemon_directory/postfix-wrapper file implements a +# simple manager and contains instructions for creating Postfix +# instances by hand. The postmulti(1) command provides a +# more extensive implementation including support for life-cycle +# management. +# +# The multi_instance_directories and other main.cf parameters +# are listed below in the CONFIGURATION PARAMETERS section. +# +# In multi-instance mode, the postfix(1) command invokes the +# $multi_instance_wrapper command instead of the postfix-script +# file. This multi-instance manager in turn executes the +# postfix(1) command in single-instance mode for each Postfix +# instance. +# +# To illustrate the main ideas behind multi-instance operation, +# below is an example of a simple but useful multi-instance +# manager implementation: +# .IP +# .nf +# #!/bin/sh +# +# : ${command_directory?"do not invoke this command directly"} +# +# POSTCONF=$command_directory/postconf +# POSTFIX=$command_directory/postfix +# instance_dirs=\`$POSTCONF -h multi_instance_directories | +# sed 's/,/ /'\` || exit 1 +# +# err=0 +# for dir in $config_directory $instance_dirs +# do +# case "$1" in +# stop|abort|flush|reload|drain) +# test "\`$POSTCONF -c $dir -h multi_instance_enable\`" \e +# = yes || continue;; +# start) +# test "\`$POSTCONF -c $dir -h multi_instance_enable\`" \e +# = yes || { +# $POSTFIX -c $dir check || err=$? +# continue +# };; +# esac +# $POSTFIX -c $dir "$@" || err=$? +# done +# +# exit $err +# .fi +# PER-INSTANCE MULTI-INSTANCE MANAGER CONTROLS +# .ad +# .fi +# Each Postfix instance has its own main.cf file with parameters +# that control how the multi-instance manager operates on +# that instance. This section discusses the most important +# settings. +# +# The setting "multi_instance_enable = yes" allows the +# multi-instance manager to start (stop, etc.) the corresponding +# Postfix instance. For safety reasons, this setting is not +# the default. +# +# The default setting "multi_instance_enable = no" is useful +# for manual testing with "postfix -c \fI/path/name\fR start" +# etc. The multi-instance manager will not start such an +# instance, and it will skip commands such as "stop" or "flush" +# that require a running Postfix instance. The multi-instance +# manager will execute commands such as "check", "set-permissions" +# or "upgrade-configuration", and it will replace "start" by +# "check" so that problems will be reported even when the +# instance is disabled. +# MAINTAINING SHARED AND NON-SHARED FILES +# .ad +# .fi +# Some files are shared between Postfix instances, such as +# executables and manpages, and some files are per-instance, +# such as configuration files, mail queue files, and data +# files. See the NON-SHARED FILES section below for a list +# of per-instance files. +# +# Before Postfix multi-instance support was implemented, the +# executables, manpages, etc., have always been maintained +# as part of the default Postfix instance. +# +# With multi-instance support, we simply continue to do this. +# Specifically, a Postfix instance will not check or update +# shared files when that instance's config_directory value is +# listed with the default main.cf file's multi_instance_directories +# parameter. +# +# The consequence of this approach is that the default Postfix +# instance should be checked and updated before any other +# instances. +# MULTI-INSTANCE API SUMMARY +# .ad +# .fi +# Only the multi-instance manager implements support for the +# multi_instance_enable configuration parameter. The +# multi-instance manager will start only Postfix instances +# whose main.cf file has "multi_instance_enable = yes". A +# setting of "no" allows a Postfix instance to be tested by +# hand. +# +# The postfix(1) command operates on only one Postfix instance +# when the -c option is specified, or when MAIL_CONFIG is +# present in the process environment. This is necessary to +# terminate recursion. +# +# Otherwise, when the multi_instance_directories parameter +# value is non-empty, the postfix(1) command executes the +# command specified with the multi_instance_wrapper parameter, +# instead of executing the commands in postfix-script. +# +# The multi-instance manager skips commands such as "stop" +# or "reload" that require a running Postfix instance, when +# an instance does not have "multi_instance_enable = yes". +# This avoids false error messages. +# +# The multi-instance manager replaces a "start" command by +# "check" when a Postfix instance's main.cf file does not +# have "multi_instance_enable = yes". This substitution ensures +# that problems will be reported even when the instance is +# disabled. +# +# No Postfix command or script will update or check shared +# files when its config_directory value is listed in the +# default main.cf's multi_instance_directories parameter +# value. Therefore, the default instance should be checked +# and updated before any Postfix instances that depend on it. +# +# Set-gid commands such as postdrop(1) and postqueue(1) +# effectively append the multi_instance_directories parameter +# value to the legacy alternate_config_directories parameter +# value. The commands use this information to determine whether +# a -c option or MAIL_CONFIG environment setting specifies a +# legitimate value. +# +# The legacy alternate_config_directories parameter remains +# necessary for non-default Postfix instances that are running +# different versions of Postfix, or that are not managed +# together with the default Postfix instance. +# ENVIRONMENT VARIABLES +# .ad +# .fi +# .IP MAIL_CONFIG +# When present, this forces the postfix(1) command to operate +# only on the specified Postfix instance. This environment +# variable is exported by the postfix(1) -c option, so that +# postfix(1) commands in descendant processes will work +# correctly. +# CONFIGURATION PARAMETERS +# .ad +# .fi +# The text below provides only a parameter summary. See +# postconf(5) for more details. +# .IP "\fBmulti_instance_directories (empty)\fR" +# An optional list of non-default Postfix configuration directories; +# these directories belong to additional Postfix instances that share +# the Postfix executable files and documentation with the default +# Postfix instance, and that are started, stopped, etc., together +# with the default Postfix instance. +# .IP "\fBmulti_instance_wrapper (empty)\fR" +# The pathname of a multi-instance manager command that the +# \fBpostfix\fR(1) command invokes when the multi_instance_directories +# parameter value is non-empty. +# .IP "\fBmulti_instance_name (empty)\fR" +# The optional instance name of this Postfix instance. +# .IP "\fBmulti_instance_group (empty)\fR" +# The optional instance group name of this Postfix instance. +# .IP "\fBmulti_instance_enable (no)\fR" +# Allow this Postfix instance to be started, stopped, etc., by a +# multi-instance manager. +# NON-SHARED FILES +# .ad +# .fi +# .IP "\fBconfig_directory (see 'postconf -d' output)\fR" +# The default location of the Postfix main.cf and master.cf +# configuration files. +# .IP "\fBdata_directory (see 'postconf -d' output)\fR" +# The directory with Postfix-writable data files (for example: +# caches, pseudo-random numbers). +# .IP "\fBqueue_directory (see 'postconf -d' output)\fR" +# The location of the Postfix top-level queue directory. +# SEE ALSO +# postfix(1) Postfix control program +# postmulti(1) full-blown multi-instance manager +# $daemon_directory/postfix-wrapper simple multi-instance manager +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this +# software. +# AUTHOR(S) +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/regexp_table b/proto/regexp_table new file mode 100644 index 0000000..1c38472 --- /dev/null +++ b/proto/regexp_table @@ -0,0 +1,209 @@ +#++ +# NAME +# regexp_table 5 +# SUMMARY +# format of Postfix regular expression tables +# SYNOPSIS +# \fBpostmap -q "\fIstring\fB" regexp:/etc/postfix/\fIfilename\fR +# +# \fBpostmap -q - regexp:/etc/postfix/\fIfilename\fB <\fIinputfile\fR +# DESCRIPTION +# The Postfix mail system uses optional tables for address +# rewriting, mail routing, or access control. These tables +# are usually in \fBdbm\fR or \fBdb\fR format. +# +# Alternatively, lookup tables can be specified in POSIX regular +# expression form. In this case, each input is compared against a +# list of patterns. When a match is found, the corresponding +# result is returned and the search is terminated. +# +# To find out what types of lookup tables your Postfix system +# supports use the "\fBpostconf -m\fR" command. +# +# To test lookup tables, use the "\fBpostmap -q\fR" command +# as described in the SYNOPSIS above. Use "\fBpostmap -hmq +# -\fR <\fIfile\fR" for header_checks(5) patterns, and +# "\fBpostmap -bmq -\fR <\fIfile\fR" for body_checks(5) +# (Postfix 2.6 and later). +# COMPATIBILITY +# .ad +# .fi +# With Postfix version 2.2 and earlier specify "\fBpostmap +# -fq\fR" to query a table that contains case sensitive +# patterns. Patterns are case insensitive by default. +# TABLE FORMAT +# .ad +# .fi +# The general form of a Postfix regular expression table is: +# .IP "\fB/\fIpattern\fB/\fIflags result\fR" +# When \fIpattern\fR matches the input string, +# use the corresponding \fIresult\fR value. +# .IP "\fB!/\fIpattern\fB/\fIflags result\fR" +# When \fIpattern\fR does \fBnot\fR match the input string, +# use the corresponding \fIresult\fR value. +# .IP "\fBif /\fIpattern\fB/\fIflags\fR" +# .IP "\fBendif\fR" +# If the input string matches /\fIpattern\fR/, then match that +# input string against the patterns between \fBif\fR and +# \fBendif\fR. The \fBif\fR..\fBendif\fR can nest. +# .sp +# Note: do not prepend whitespace to patterns inside +# \fBif\fR..\fBendif\fR. +# .sp +# This feature is available in Postfix 2.1 and later. +# .IP "\fBif !/\fIpattern\fB/\fIflags\fR" +# .IP "\fBendif\fR" +# If the input string does not match /\fIpattern\fR/, then +# match that input string against the patterns between \fBif\fR +# and \fBendif\fR. The \fBif\fR..\fBendif\fR can nest. +# .sp +# Note: do not prepend whitespace to patterns inside +# \fBif\fR..\fBendif\fR. +# .sp +# This feature is available in Postfix 2.1 and later. +# .IP "blank lines and comments" +# Empty lines and whitespace-only lines are ignored, as +# are lines whose first non-whitespace character is a `#'. +# .IP "multi-line text" +# A logical line starts with non-whitespace text. A line that +# starts with whitespace continues a logical line. +# .PP +# Each pattern is a POSIX regular expression enclosed by a pair of +# delimiters. The regular expression syntax is documented in +# \fBre_format\fR(7) with 4.4BSD, in \fBregex\fR(5) with Solaris, and in +# \fBregex\fR(7) with Linux. Other systems may use other document names. +# +# The expression delimiter can be any non-alphanumerical +# character, except whitespace +# or characters that have special meaning (traditionally the forward +# slash is used). The regular expression can contain whitespace. +# +# By default, matching is case-insensitive, and newlines are not +# treated as special characters. The behavior is controlled by flags, +# which are toggled by appending one or more of the following +# characters after the pattern: +# .IP "\fBi\fR (default: on)" +# Toggles the case sensitivity flag. By default, matching is case +# insensitive. +# .IP "\fBm\fR (default: off)" +# Toggle the multi-line mode flag. When this flag is on, the \fB^\fR +# and \fB$\fR metacharacters match immediately after and immediately +# before a newline character, respectively, in addition to +# matching at the start and end of the input string. +# .IP "\fBx\fR (default: on)" +# Toggles the extended expression syntax flag. By default, support +# for extended expression syntax is enabled. +# TABLE SEARCH ORDER +# .ad +# .fi +# Patterns are applied in the order as specified in the table, until a +# pattern is found that matches the input string. +# +# Each pattern is applied to the entire input string. +# Depending on the application, that string is an entire client +# hostname, an entire client IP address, or an entire mail address. +# Thus, no parent domain or parent network search is done, and +# \fIuser@domain\fR mail addresses are not broken up into their +# \fIuser\fR and \fIdomain\fR constituent parts, nor is \fIuser+foo\fR +# broken up into \fIuser\fR and \fIfoo\fR. +# TEXT SUBSTITUTION +# .ad +# .fi +# Substitution of substrings (text that matches patterns +# inside "()") from the matched expression into the result +# string is requested with $1, $2, etc.; specify $$ to produce +# a $ character as output. +# The macros in the result string may need to be written as +# ${n} or $(n) if they aren't followed by whitespace. +# +# Note: since negated patterns (those preceded by \fB!\fR) return a +# result when the expression does not match, substitutions are not +# available for negated patterns. +# INLINE SPECIFICATION +# .ad +# .fi +# The contents of a table may be specified in the table name +# (Postfix 3.7 and later). +# The basic syntax is: +# +# .nf +# main.cf: +# \fIparameter\fR \fB= .. regexp:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } ..\fR +# +# master.cf: +# \fB.. -o { \fIparameter\fR \fB= .. regexp:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR +# .fi +# +# Postfix ignores whitespace after '{' and before '}', and +# writes each \fIrule\fR as one text line to an in-memory +# file: +# +# .nf +# in-memory file: +# rule-1 +# rule-2 +# .. +# .fi +# +# Postfix parses the result as if it is a file in /etc/postfix. +# +# Note: if a rule contains \fB$\fR, specify \fB$$\fR to keep +# Postfix from trying to do \fI$name\fR expansion as it +# evaluates a parameter value. +# EXAMPLE SMTPD ACCESS MAP +# # Disallow sender-specified routing. This is a must if you relay mail +# # for other domains. +# /[%!@].*[%!@]/ 550 Sender-specified routing rejected +# +# # Postmaster is OK, that way they can talk to us about how to fix +# # their problem. +# /^postmaster@/ OK +# +# # Protect your outgoing majordomo exploders +# if !/^owner-/ +# /^(.*)-outgoing@(.*)$/ 550 Use ${1}@${2} instead +# endif +# EXAMPLE HEADER FILTER MAP +# # These were once common in junk mail. +# /^Subject: make money fast/ REJECT +# /^To: friend@public\\.com/ REJECT +# EXAMPLE BODY FILTER MAP +# # First skip over base 64 encoded text to save CPU cycles. +# ~^[[:alnum:]+/]{60,}$~ OK +# +# # Put your own body patterns here. +# SEE ALSO +# postmap(1), Postfix lookup table manager +# pcre_table(5), format of PCRE tables +# cidr_table(5), format of CIDR tables +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# AUTHOR(S) +# The regexp table lookup code was originally written by: +# LaMont Jones +# lamont@hp.com +# +# That code was based on the PCRE dictionary contributed by: +# Andrew McNamara +# andrewm@connect.com.au +# connect.com.au Pty. Ltd. +# Level 3, 213 Miller St +# North Sydney, NSW, Australia +# +# Adopted and adapted by: +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/relocated b/proto/relocated new file mode 100644 index 0000000..a0a54ca --- /dev/null +++ b/proto/relocated @@ -0,0 +1,166 @@ +#++ +# NAME +# relocated 5 +# SUMMARY +# Postfix relocated table format +# SYNOPSIS +# \fBpostmap /etc/postfix/relocated\fR +# DESCRIPTION +# The optional \fBrelocated\fR(5) table provides the information that is +# used in "user has moved to \fInew_location\fR" bounce messages. +# +# Normally, the \fBrelocated\fR(5) table is specified as a text file +# that serves as input to the \fBpostmap\fR(1) command. +# The result, an indexed file in \fBdbm\fR or \fBdb\fR format, +# is used for fast searching by the mail system. Execute the command +# "\fBpostmap /etc/postfix/relocated\fR" to rebuild an indexed +# file after changing the corresponding relocated table. +# +# When the table is provided via other means such as NIS, LDAP +# or SQL, the same lookups are done as for ordinary indexed files. +# +# Alternatively, the table can be provided as a regular-expression +# map where patterns are given as regular expressions, or lookups +# can be directed to a TCP-based server. In those case, the lookups +# are done in a slightly different way as described below under +# "REGULAR EXPRESSION TABLES" or "TCP-BASED TABLES". +# +# Table lookups are case insensitive. +# CASE FOLDING +# .ad +# .fi +# The search string is folded to lowercase before database +# lookup. As of Postfix 2.3, the search string is not case +# folded with database types such as regexp: or pcre: whose +# lookup fields can match both upper and lower case. +# TABLE FORMAT +# .ad +# .fi +# The input format for the \fBpostmap\fR(1) command is as follows: +# .IP \(bu +# An entry has one of the following form: +# +# .nf +# \fIpattern new_location\fR +# .fi +# +# Where \fInew_location\fR specifies contact information such as +# an email address, or perhaps a street address or telephone number. +# .IP \(bu +# Empty lines and whitespace-only lines are ignored, as +# are lines whose first non-whitespace character is a `#'. +# .IP \(bu +# A logical line starts with non-whitespace text. A line that +# starts with whitespace continues a logical line. +# TABLE SEARCH ORDER +# .ad +# .fi +# With lookups from indexed files such as DB or DBM, or from networked +# tables such as NIS, LDAP or SQL, patterns are tried in the order as +# listed below: +# .IP \fIuser\fR@\fIdomain\fR +# Matches \fIuser\fR@\fIdomain\fR. This form has precedence over all +# other forms. +# .IP \fIuser\fR +# Matches \fIuser\fR@\fIsite\fR when \fIsite\fR is $\fBmyorigin\fR, +# when \fIsite\fR is listed in $\fBmydestination\fR, or when \fIsite\fR +# is listed in $\fBinet_interfaces\fR or $\fBproxy_interfaces\fR. +# .IP @\fIdomain\fR +# Matches other addresses in \fIdomain\fR. This form has the lowest +# precedence. +# ADDRESS EXTENSION +# .fi +# .ad +# When a mail address localpart contains the optional recipient delimiter +# (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes: +# \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR, +# \fIuser\fR, and @\fIdomain\fR. +# REGULAR EXPRESSION TABLES +# .ad +# .fi +# This section describes how the table lookups change when the table +# is given in the form of regular expressions or when lookups are +# directed to a TCP-based server. For a description of regular +# expression lookup table syntax, see \fBregexp_table\fR(5) or +# \fBpcre_table\fR(5). For a description of the TCP client/server +# table lookup protocol, see \fBtcp_table\fR(5). +# This feature is available in Postfix 2.5 and later. +# +# Each pattern is a regular expression that is applied to the entire +# address being looked up. Thus, \fIuser@domain\fR mail addresses are not +# broken up into their \fIuser\fR and \fI@domain\fR constituent parts, +# nor is \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR. +# +# Patterns are applied in the order as specified in the table, until a +# pattern is found that matches the search string. +# +# Results are the same as with indexed file lookups, with +# the additional feature that parenthesized substrings from the +# pattern can be interpolated as \fB$1\fR, \fB$2\fR and so on. +# TCP-BASED TABLES +# .ad +# .fi +# This section describes how the table lookups change when lookups +# are directed to a TCP-based server. For a description of the TCP +# client/server lookup protocol, see \fBtcp_table\fR(5). +# This feature is available in Postfix 2.5 and later. +# +# Each lookup operation uses the entire address once. Thus, +# \fIuser@domain\fR mail addresses are not broken up into their +# \fIuser\fR and \fI@domain\fR constituent parts, nor is +# \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR. +# +# Results are the same as with indexed file lookups. +# BUGS +# The table format does not understand quoting conventions. +# CONFIGURATION PARAMETERS +# .ad +# .fi +# The following \fBmain.cf\fR parameters are especially relevant. +# The text below provides only a parameter summary. See +# \fBpostconf\fR(5) for more details including examples. +# .IP "\fBrelocated_maps (empty)\fR" +# Optional lookup tables with new contact information for users or +# domains that no longer exist. +# .PP +# Other parameters of interest: +# .IP "\fBinet_interfaces (all)\fR" +# The network interface addresses that this mail system receives +# mail on. +# .IP "\fBmydestination ($myhostname, localhost.$mydomain, localhost)\fR" +# The list of domains that are delivered via the $local_transport +# mail delivery transport. +# .IP "\fBmyorigin ($myhostname)\fR" +# The domain name that locally-posted mail appears to come +# from, and that locally posted mail is delivered to. +# .IP "\fBproxy_interfaces (empty)\fR" +# The network interface addresses that this mail system receives mail +# on by way of a proxy or network address translation unit. +# SEE ALSO +# trivial-rewrite(8), address resolver +# postmap(1), Postfix lookup table manager +# postconf(5), configuration parameters +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# ADDRESS_REWRITING_README, address rewriting guide +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# AUTHOR(S) +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/socketmap_table b/proto/socketmap_table new file mode 100644 index 0000000..be01054 --- /dev/null +++ b/proto/socketmap_table @@ -0,0 +1,96 @@ +#++ +# NAME +# socketmap_table 5 +# SUMMARY +# Postfix socketmap table lookup client +# SYNOPSIS +# \fBpostmap -q "\fIstring\fB" socketmap:inet:\fIhost\fB:\fIport\fB:\fIname\fR +# .br +# \fBpostmap -q "\fIstring\fB" socketmap:unix:\fIpathname\fB:\fIname\fR +# +# \fBpostmap -q - socketmap:inet:\fIhost\fB:\fIport\fB:\fIname\fB <\fIinputfile\fR +# .br +# \fBpostmap -q - socketmap:unix:\fIpathname\fB:\fIname\fB <\fIinputfile\fR +# DESCRIPTION +# The Postfix mail system uses optional tables for address +# rewriting. mail routing or policy lookup. +# +# The Postfix socketmap client expects TCP endpoint names of +# the form \fBinet:\fIhost\fB:\fIport\fB:\fIname\fR, or +# UNIX-domain endpoints of the form \fBunix:\fIpathname\fB:\fIname\fR. +# In both cases, \fIname\fR specifies the name field in a +# socketmap client request (see "REQUEST FORMAT" below). +# PROTOCOL +# .ad +# .fi +# Socketmaps use a simple protocol: the client sends one +# request, and the server sends one reply. Each request and +# each reply are sent as one netstring object. +# REQUEST FORMAT +# .ad +# .fi +# The socketmap protocol supports only the lookup request. +# The request has the following form: +# +# .IP "\fB\fIname\fB <space> \fIkey\fR" +# Search the named socketmap for the specified key. +# .PP +# Postfix will not generate partial search keys such as domain +# names without one or more subdomains, network addresses +# without one or more least-significant octets, or email +# addresses without the localpart, address extension or domain +# portion. This behavior is also found with cidr:, pcre:, and +# regexp: tables. +# REPLY FORMAT +# .ad +# .fi +# The Postfix socketmap client requires that replies are not +# longer than 100000 characters (not including the netstring +# encapsulation). Replies must have the following form: +# .IP "\fBOK <space> \fIdata\fR" +# The requested data was found. +# .IP "\fBNOTFOUND <space>" +# The requested data was not found. +# .IP "\fBTEMP <space> \fIreason\fR" +# .IP "\fBTIMEOUT <space> \fIreason\fR" +# .IP "\fBPERM <space> \fIreason\fR" +# The request failed. The reason, if non-empty, is descriptive +# text. +# SECURITY +# This map cannot be used for security-sensitive information, +# because neither the connection nor the server are authenticated. +# SEE ALSO +# http://cr.yp.to/proto/netstrings.txt, netstring definition +# postconf(1), Postfix supported lookup tables +# postmap(1), Postfix lookup table manager +# regexp_table(5), format of regular expression tables +# pcre_table(5), format of PCRE tables +# cidr_table(5), format of CIDR tables +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# BUGS +# The protocol limits are not yet configurable. +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# HISTORY +# Socketmap support was introduced with Postfix version 2.10. +# AUTHOR(S) +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- + diff --git a/proto/sqlite_table b/proto/sqlite_table new file mode 100644 index 0000000..a4edf72 --- /dev/null +++ b/proto/sqlite_table @@ -0,0 +1,261 @@ +#++ +# NAME +# sqlite_table 5 +# SUMMARY +# Postfix SQLite configuration +# SYNOPSIS +# \fBpostmap -q "\fIstring\fB" sqlite:/etc/postfix/\fIfilename\fR +# +# \fBpostmap -q - sqlite:/etc/postfix/\fIfilename\fB <\fIinputfile\fR +# DESCRIPTION +# The Postfix mail system uses optional tables for address +# rewriting or mail routing. These tables are usually in +# \fBdbm\fR or \fBdb\fR format. +# +# Alternatively, lookup tables can be specified as SQLite databases. +# In order to use SQLite lookups, define an SQLite source as a lookup +# table in main.cf, for example: +# .nf +# alias_maps = sqlite:/etc/postfix/sqlite-aliases.cf +# .fi +# +# The file /etc/postfix/sqlite-aliases.cf has the same format as +# the Postfix main.cf file, and can specify the parameters +# described below. +# LIST MEMBERSHIP +# .ad +# .fi +# When using SQL to store lists such as $mynetworks, +# $mydestination, $relay_domains, $local_recipient_maps, +# etc., it is important to understand that the table must +# store each list member as a separate key. The table lookup +# verifies the *existence* of the key. See "Postfix lists +# versus tables" in the DATABASE_README document for a +# discussion. +# +# Do NOT create tables that return the full list of domains +# in $mydestination or $relay_domains etc., or IP addresses +# in $mynetworks. +# +# DO create tables with each matching item as a key and with +# an arbitrary value. With SQL databases it is not uncommon to +# return the key itself or a constant value. +# SQLITE PARAMETERS +# .ad +# .fi +# .IP "\fBdbpath\fR" +# The SQLite database file location. Example: +# .nf +# dbpath = customer_database +# .fi +# .IP "\fBquery\fR" +# The SQL query template used to search the database, where \fB%s\fR +# is a substitute for the address Postfix is trying to resolve, +# e.g. +# .nf +# query = SELECT replacement FROM aliases WHERE mailbox = '%s' +# .fi +# +# This parameter supports the following '%' expansions: +# .RS +# .IP "\fB%%\fR" +# This is replaced by a literal '%' character. +# .IP "\fB%s\fR" +# This is replaced by the input key. +# SQL quoting is used to make sure that the input key does not +# add unexpected metacharacters. +# .IP "\fB%u\fR" +# When the input key is an address of the form user@domain, \fB%u\fR +# is replaced by the SQL quoted local part of the address. +# Otherwise, \fB%u\fR is replaced by the entire search string. +# If the localpart is empty, the query is suppressed and returns +# no results. +# .IP "\fB%d\fR" +# When the input key is an address of the form user@domain, \fB%d\fR +# is replaced by the SQL quoted domain part of the address. +# Otherwise, the query is suppressed and returns no results. +# .IP "\fB%[SUD]\fR" +# The upper-case equivalents of the above expansions behave in the +# \fBquery\fR parameter identically to their lower-case counter-parts. +# With the \fBresult_format\fR parameter (see below), they expand the +# input key rather than the result value. +# .IP "\fB%[1-9]\fR" +# The patterns %1, %2, ... %9 are replaced by the corresponding +# most significant component of the input key's domain. If the +# input key is \fIuser@mail.example.com\fR, then %1 is \fBcom\fR, +# %2 is \fBexample\fR and %3 is \fBmail\fR. If the input key is +# unqualified or does not have enough domain components to satisfy +# all the specified patterns, the query is suppressed and returns +# no results. +# .RE +# .IP +# The \fBdomain\fR parameter described below limits the input +# keys to addresses in matching domains. When the \fBdomain\fR +# parameter is non-empty, SQL queries for unqualified addresses +# or addresses in non-matching domains are suppressed +# and return no results. +# +# This parameter is available with Postfix 2.2. In prior releases +# the SQL query was built from the separate parameters: +# \fBselect_field\fR, \fBtable\fR, \fBwhere_field\fR and +# \fBadditional_conditions\fR. The mapping from the old parameters +# to the equivalent query is: +# +# .nf +# SELECT [\fBselect_field\fR] +# FROM [\fBtable\fR] +# WHERE [\fBwhere_field\fR] = '%s' +# [\fBadditional_conditions\fR] +# .fi +# +# The '%s' in the \fBWHERE\fR clause expands to the escaped search string. +# With Postfix 2.2 these legacy parameters are used if the \fBquery\fR +# parameter is not specified. +# +# NOTE: DO NOT put quotes around the query parameter. +# .IP "\fBresult_format (default: \fB%s\fR)\fR" +# Format template applied to result attributes. Most commonly used +# to append (or prepend) text to the result. This parameter supports +# the following '%' expansions: +# .RS +# .IP "\fB%%\fR" +# This is replaced by a literal '%' character. +# .IP "\fB%s\fR" +# This is replaced by the value of the result attribute. When +# result is empty it is skipped. +# .IP "\fB%u\fR +# When the result attribute value is an address of the form +# user@domain, \fB%u\fR is replaced by the local part of the +# address. When the result has an empty localpart it is skipped. +# .IP "\fB%d\fR" +# When a result attribute value is an address of the form +# user@domain, \fB%d\fR is replaced by the domain part of +# the attribute value. When the result is unqualified it +# is skipped. +# .IP "\fB%[SUD1-9]\fR" +# The upper-case and decimal digit expansions interpolate +# the parts of the input key rather than the result. Their +# behavior is identical to that described with \fBquery\fR, +# and in fact because the input key is known in advance, queries +# whose key does not contain all the information specified in +# the result template are suppressed and return no results. +# .RE +# .IP +# For example, using "result_format = smtp:[%s]" allows one +# to use a mailHost attribute as the basis of a transport(5) +# table. After applying the result format, multiple values +# are concatenated as comma separated strings. The expansion_limit +# and parameter explained below allows one to restrict the number +# of values in the result, which is especially useful for maps that +# must return at most one value. +# +# The default value \fB%s\fR specifies that each result value should +# be used as is. +# +# This parameter is available with Postfix 2.2 and later. +# +# NOTE: DO NOT put quotes around the result format! +# .IP "\fBdomain (default: no domain list)\fR" +# This is a list of domain names, paths to files, or "type:table" +# databases. When specified, only fully qualified search +# keys with a *non-empty* localpart and a matching domain +# are eligible for lookup: 'user' lookups, bare domain lookups +# and "@domain" lookups are not performed. This can significantly +# reduce the query load on the SQLite server. +# .nf +# domain = postfix.org, hash:/etc/postfix/searchdomains +# .fi +# +# It is best not to use SQL to store the domains eligible +# for SQL lookups. +# +# This parameter is available with Postfix 2.2 and later. +# +# NOTE: DO NOT define this parameter for local(8) aliases, +# because the input keys are always unqualified. +# .IP "\fBexpansion_limit (default: 0)\fR" +# A limit on the total number of result elements returned +# (as a comma separated list) by a lookup against the map. +# A setting of zero disables the limit. Lookups fail with a +# temporary error if the limit is exceeded. Setting the +# limit to 1 ensures that lookups do not return multiple +# values. +# OBSOLETE MAIN.CF PARAMETERS +# .ad +# .fi +# For compatibility with other Postfix lookup tables, SQLite +# parameters can also be defined in main.cf. In order to do that, +# specify as SQLite source a name that doesn't begin with a slash +# or a dot. The SQLite parameters will then be accessible as the +# name you've given the source in its definition, an underscore, +# and the name of the parameter. For example, if the map is +# specified as "sqlite:\fIsqlitename\fR", the parameter "query" +# would be defined in main.cf as "\fIsqlitename\fR_query". +# OBSOLETE QUERY INTERFACE +# .ad +# .fi +# This section describes an interface that is deprecated as +# of Postfix 2.2. It is replaced by the more general \fBquery\fR +# interface described above. If the \fBquery\fR parameter +# is defined, the legacy parameters described here ignored. +# Please migrate to the new interface as the legacy interface +# may be removed in a future release. +# +# The following parameters can be used to fill in a +# SELECT template statement of the form: +# +# .nf +# SELECT [\fBselect_field\fR] +# FROM [\fBtable\fR] +# WHERE [\fBwhere_field\fR] = '%s' +# [\fBadditional_conditions\fR] +# .fi +# +# The specifier %s is replaced by the search string, and is +# escaped so if it contains single quotes or other odd characters, +# it will not cause a parse error, or worse, a security problem. +# .IP "\fBselect_field\fR" +# The SQL "select" parameter. Example: +# .nf +# \fBselect_field\fR = forw_addr +# .fi +# .IP "\fBtable\fR" +# The SQL "select .. from" table name. Example: +# .nf +# \fBtable\fR = mxaliases +# .fi +# .IP "\fBwhere_field\fR +# The SQL "select .. where" parameter. Example: +# .nf +# \fBwhere_field\fR = alias +# .fi +# .IP "\fBadditional_conditions\fR +# Additional conditions to the SQL query. Example: +# .nf +# \fBadditional_conditions\fR = AND status = 'paid' +# .fi +# SEE ALSO +# postmap(1), Postfix lookup table maintenance +# postconf(5), configuration parameters +# ldap_table(5), LDAP lookup tables +# mysql_table(5), MySQL lookup tables +# pgsql_table(5), PostgreSQL lookup tables +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# SQLITE_README, Postfix SQLITE howto +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# HISTORY +# SQLite support was introduced with Postfix version 2.8. +# AUTHOR(S) +# Original implementation by: +# Axel Steiner +#-- diff --git a/proto/stop b/proto/stop new file mode 100644 index 0000000..8682f8e --- /dev/null +++ b/proto/stop @@ -0,0 +1,1564 @@ +DHCP +DNS +IMAP +IP +ISP +MX +PPP +RC +README +RFC +Sendmail's +Wietse +cdb +cf +com +db +dbm +dialup +dns +domainname +download +firewalled +generic +grep +hostname +html +http +inet +intranet +ip +isp +janes +joes +localdomain +localhost +localpart +mailhost +mailq +mydestination +mydomain +myhostname +mynetworks +myorigin +newaliases +nullclient +org +postconf +postmap +relayhost +sbin +sendmail +smtp +smtpd +smtprelay +someprovider +subdomains +tld +unauth +usr +wietse +www +Bcc +Firstname +LDAP +LINUX +LMTP +Lastname +NIS +SQL +SYSV +Venema +bangpath +firstname +hosta +hostb +lastname +ldap +lmtp +luser +mysql +nis +otherdomain +otheruser +pcre +pgsql +privs +qmgr +qmqpd +regexp +std +sysadmin +userid +username +Autoreplies +CDB +DBM +Howto +MAILDROP +MYSQL +Maildir +MySQL +PGSQL +PgSQL +Postfix's +Spammers +UID +argv +autoreplies +autoreply +berkeley +chroot +com's +hostnames +internet +jim +listname +mailBOX +mailDIRs +maildir +maildrop +majordomo +maxproc +spam +uid +unix +unpriv +var +vhosts +vmailbox +vs +wildcard +AG +AHRlc +AUTH +AUXLIBS +BITMIME +CCARGS +DUSE +Daia +EHLO +ESMTP +ETRN +Franke +FreeBSD +Hoos +Linux +Liviu +MMIME +OTP +RedHat +RwYXNz +SASL +SASL's +Solaris +Strace +SuSE +UCE +ZXN +andrew +auth +auxprop +chrooted +cmu +conf +cpan +dGVzdAB +docs +edu +elses +exampleuser +ftp +ktrace +ld +lib +lsasl +maillog +mech +metamail +mmencode +passwd +perl +plaintext +plugin +plugins +printf +pwcheck +sasl +saslauthd +sasldb +sasldblistusers +saslpasswd +sql +su +symlink +tarball +testpass +CC +CONFIG +DDEF +DEF +DFD +DIR +Debian +FD +FILIO +FIONREAD +FREEBSD +GCC +HTML +IRIX +MAILQ +MANPAGE +MANPATH +MacOSX +NEWALIAS +NEXTSTEP +NetBSD +OPENSTEP +OSF +OSX +PCRE +Perl +PostgreSQL +SENDMAIL +SETSIZE +SUNOS +SUNWspro +SYSTEMTYPE +Sendmail +Slackware +SunOS +TLS +UX +ansic +bd +bi +bp +cc +ccs +cd +chmod +config +defs +egrep +ifdef +init +libexec +lndir +logfile +logfiles +mailserver +makedefs +manpage +mantools +mv +postdrop +postprocessing +postqueue +pre +pwd +qwhatever +readme +setenv +syslog +syslogd +util +DoS +Duchovni +FF +MTA +QSHAPE +Requeing +SYN +algonet +aristotle +backoff +bbde +bcc +bitmask +cn +extremepricecuts +fr +gjr +google +gotdns +gov +gzd +heyhihellothere +highvolume +hinet +hotmail +ids +malware +meri +misconfiguring +ms +msg +msn +nexthop +osn +paknet +pk +pleazerzoneprod +postsuper +qshape +reprocessing +setgid +sourceforge +spammers +timestamp +toppoint +transport's +transportname +undeliverables +uwasa +winnersdaily +worldnet +FAQ +MB +SMTPD +args +fd +fs +helo +ipc +maxfiles +maxfilesperproc +maxsockets +nl +nmbclusters +proc +rcpts +resolv +rlim +solaris +sysctl +Ctrl +ECC +XAUTHORITY +Xauthority +anonymize +cont +csh +gdb +loopback +ltrace +oqmgr +postfinger +sotruss +strace +tcpdump +BUILTIN +SPAM +website +HELO +Mozilla +Netscape +VirusWarning +dk +dkuug +spammer +txt +wtf +PERL +Rq +TEMPFAIL +XFORWARD +inetd +rm +smtpprox +sysexits +xforward +xxx +yyy +DSN +RBL +RCPT +ehlo +proxying +SPF +Whitelisting +XCLIENT +etrn +greylisting +rfc +unreplyable +websites +whitelisting +DUNNO +Greylisting +VRFY +aol +attr +bigfoot +chown +dunno +greylist +headername +headertext +lc +mkdir +mta +neohapsis +obj +pl +pobox +securityfocus +spf +tmp +ttl +AOL +VERP +btree +interruptus +mis +sender's +whitelist +rbl +spoofing +IDs +Oct +mx +nrcpt +qRdestination +qRdomain +sdestination +sdomain +LinxNet +SSL +Sanders's +Seymour's +au +jdp +jimsun +recipien +rmail +stunnel +taz +tcp +uux +dir +foobar +pag +postalias +proxymap +BerkeleyDB +DHAS +MBytes +UNIXWARE +UNIXes +bsd +condattr +fcntl +kBytes +ldb +linux +lpthread +mutex +mutexattr +pthread +setpshared +sleepycat +trylock +DN +Guesdon +Haahtinen +Hensley +Hery +Hoeger +KTH +Kerberos +LDAPv +LaMont +Linux's +Maildrops +Mattice +OpenLDAP +Prabhat +Rakotoarisoa +SDKs +STARTTLS +Sami +Tardieu +URL +accountingstaff +dc +defaultrecipient +dirsvcs +dn +hmmmm +kerberos +ldapuser +libdns +libldap +libldapssl +llber +lldap +mailacceptinggeneralid +mailacceptinggeneralids +maildrops +maillist +mylist +normaluser +objectclass +openldap +realuser +slapd +slurpd +someserver +theother +tls +umich +virtualaccount +wildcards +IC +addr +dbname +downloads +forw +libm +libz +lm +lmysqlclient +lz +mxaliases +mysqlclient +POSIX +ac +csx +lpcre +uk +Sethman +libpq +lpq +QMQP +XVERP +cr +ezmlm +prefixuser +qmail +qmqp +verp +yourname +yp +Procmail +Syslogd +devel +procmail +MTAs +Netapp +dotlock +DECstation +NOFILE +RLIMIT +Roques +getdtablesize +getrlimit +von +zsh +DRhu +Earnshaw +Maildrop +Mosemann +Tonni +someother +userdb +vmail +bv +dest +ination +makemap +postcat +postkick +postlock +postlog +postsomething +showq +BCC +CR +Cc +Helo +LF +LHLO +LOGNAME +MicroSoft +PID +PTR +RFCs +RSET +SCO +Subdomain +TZ +YYYYMMDD +admin +ain +aliasname +bitmime +cl +dequoted +faqs +fetchmail +fqdn +gethostbyname +gethostname +hopcount +hostaddress +ient +ifconfig +ish +lhlo +localparts +lockfile +mailtool +minfree +multipart +mydom +mysmtp +netmask +noactive +noanonymous +nodictionary +noplaintext +ns +nsswitch +octets +partialdomainname +patchlevel +pid +provider's +rcpt +relayhostname +ress +rfcs +rhsbl +rset +sendmail's +servername +smrsh +spams +ss +subdomain +uucphost +vrfy +xclient +xfer +ipaddress +gz +gzip +outputfile +umask +xargs +xvpf +Patrik +Rak +Rak's +emails +nqmgr +AAE +ADDR +CF +IPV +IPv +MTA's +SP +TEMPUNAVAIL +xtext +CIDR +FQDN +Hildebrandt +OpenBSD +Pflogsumm +Pflogsumm's +Zeikat +cidr +faq +howto +linxnet +mailhub +mpack +nt +pflogg +pflogsumm +recipie +spoofed +ACK +Ac +BDFORhqu +BSMTP +DNs +DOTALL +Dtv +Dv +ENDONLY +EOF +Fpath +Fsome +Gouaux +IFRAME +INET +INT +IPC +Idem +Jozsef +KFKI +Kadlecsik +MAILDIR +MC +MULTILINE +McNamara +Mirapoint +Modra +NN +NSW +NY +Nfinoprvw +ONELEVEL +OQMGR +OpenSSL +PEM +POSTALIAS +POSTCAT +POSTCONF +POSTDROP +POSTKICK +POSTLOCK +POSTLOG +POSTMAP +POSTQUEUE +POSTSUPER +PROXYMAP +Prindeville +Pty +QMAIL +QMGR +QMQPD +REGEXP +REQ +ROMANIA +RS +Requeue +SHOWQ +SIGHUP +SIGTERM +TARPIT +TX +URLs +Vxy +alnum +andrewm +awk +bH +bh +blackhole +bm +bs +cert +checkpointed +cid +cv +debuglevel +dhmlnv +dsn +eb +eef +ef +endif +eoctal +eol +ev +exe +exploders +fq +groupname +headervalue +hp +hqu +hu +ident +idx +iframe +inode +inputfile +kadlec +kfki +lamont +ldapi +ldaps +ldapsearch +ldapsource +localname +mailHost +mapname +maptype +metacharacter +metacharacters +mysqlname +netstring +oA +oAalias +oi +pgsqlname +postfixpw +psv +pw +qR +qRsite +qSsite +qinterval +queueid +regcomp +regex +requeue +requeued +requeues +rv +searchdomains +sitename +src +sytem +textfile +tr +unzip +usernames +vbs +vq +CERT +NOQUEUE +NS +Qmail +Tarpit +Verisign +Verisign's +dd +itd +AU +CAcert +CAfile +CApath +CAs +CNAME +CommonName +Cottbus +DH +DSA +EE +EGD +GMT +IA +Lutz +Lutz's +NOPEERMATCH +Nov +OPENSSL +PRNG +PosgreSQL +RSA +SubjectAlternativeName +Uing +Widgits +Wietse's +aet +cacert +ccert +certs +cipherlist +clientcerts +cnf +commonName +compat +cottbus +countryName +cp +dNSNames +dcert +demoCA +dh +dkey +dsa +eg +egd +emailAddress +exch +fifos +gendh +infiles +kbytes +keyout +lcrypto +libcrypto +libssl +localityName +loglevel +lssl +lutzpc +misc +newca +nicke +ok +openssl +organizationName +peername +pem +prng +req +scache +scert +sdbm +smtps +ssl +sslclient +sslserver +starttls +stateOrProvinceName +tlsmgr +unencrypted +unpassworded +urandom +verifydepth +wrappermode +AAAA +DNSBL +GETIFADDRS +Hagino +Huizer +Jaenicke's +Lutz +PLD +SIOCGIF +SIOCGLIF +Strik +Strik's +Tru +USAGI +compat +ff +ffff +getifaddrs +ichiro +ifndef +ipnet +ipv +itojun +netmasks +kluges +APPENDDEF +EOH +EOM +MSGIDUNKNOWN +Milters +SMFIS +SenderID +authen +confINCDIRS +confLIBDIRS +ctx +dnl +eoh +eom +getpriv +getsymval +gzcat +jobid +libmilter +ments +milters +mlfi +msgid +optionneg +portnumber +ptr +sid +smfi +smfilter +strcmp +tempfail +vx +wich +xf +xxxxx +yy +zz +AAAREADME +API +DAEMONs +DHE +DSL +DataBase +EMSTP +EST +HTTPS +JOBIDUNKNOWN +Jänicke +Koetter +Leandro +MSA +MUAs +Netinfo +ODRhu +Outlook's +PQexec +Procontrol +REJECTs +Requeuing +SDBM +SSLv +Santi +Sirainen +TCL +TEMPFAILs +TLSv +Tallon +Tinycdb +Tokarev +Wrobel +aNULL +agroup +alloc +antiantivirus +apps +arandom +arounds +auser +beb +bgroup +buser +callouts +cctx +cli +cname +corpit +cuser +ddd +dfc +dkim +dmS +domainkeys +duser +epoll +esmtp +exim +gssapi +heraccount +herisp +hisaccount +hisisp +ietf +imc +interoperate +keysize +koetter +kqueue +ldapgroup +libcdb +libdb +lpr +mailwrapper +mctx +memberaddr +memberdn +mjt +mlm +msa +myisp +myname +netinfo +nisplus +noatime +nopeer +obs +openspf +orig +passdb +patrick +preloading +rpm +saslfinger +securetls +spamware +systemtype +tinycdb +unencoded +uniquename +william +xxxxxxx +yulszqocfzsficvzzju +yyyyyy +zzzzzz +BC +DKIM +DomainKeys +Hmm +Jnicke +QAdGVzdHBhc +RBL's +RBLs +RST +SMTPS +Spamhaus +Ss +Ubuntu +blocklists +botnet +botnets +bx +cb +co +dest +foreach +int +jp +le +mind's +nqmgr's +overinflating +portscan +preemptions +ps +qf +refcount +ru +spamhaus +stddev +sysadmins +timeline +todo +tt +unsubscribe +wl +zen +Blocklist +DNSBLs +MailChannels +Postscreen +Spambots +WHITELISTED +blocklist +dnsbl +dnsblog +postscreen +postscreen's +spambots +spamd +texthash +ul +whitelisted +whitelists +Amavisd +MUA +Mailserver +SpamAssassin +barracudacentral +bl +spamcop +tlsproxy +AEIOUaeiou +AF +ASN +BB +CB +CBC +CRYPTOPRO +CTX +CVE +DER +DES +DNSSEC +Diffie +EC +ECDH +ECDSA +EDNS +EECDH +FB +GOST +Hellman +LMDB +MSIE +Mmm +NODATA +NXDOMAIN +Nexthop +OP +OTIFY +OpenSSL's +Postix +Pt +SECG +SSLEAY +SSLREF +SSLV +TLSEXT +VXxznjll +Whitelist +XYZ +YYYYMMDDHHMMSS +aRSA +authcid +authcid's +authentiCation +authoriZation +authzid +bc +blockquote +certfile +cfm +cipherlists +ciphertext +crypto +dane +defnames +dgst +dl +dnsrch +dnssec +dnswl +dotcrlf +dt +eNULL +eccert +ecdsa +eckey +ecparam +eecdh +fc +fixup +getaddrinfo +haproxy +headerbody +hh +hyperlinked +ia +kEDH +lmdb +localtime +mN +matchlists +md +mechs +memcache +mylmtp +nginx +noout +nsa +pkey +postlink +postmulti +proxywrite +pubin +pubkey +queueID +rsa +secp +stdin +tarpit +uncached +unzipping +windowsize +xpostconf +TLSA +tafile +VPN +Dukhovni +Exim +NIST +PFS +Snowden +Viktor +XP +cron +dhparam +inadvisably +ADH +AECDH +CN +DSS +ECDHE +GCM +Jnicke's +Kx +PKI +XXX +YYY +ZZZ +kEECDH +EXIM +DLV +IANA +RRs +RRset +RRsets +SNI +tlsa +TSIG +ciphersuite +ciphersuites +nlnetlabs +resolver's +tempfails +Chu +LMDB's +NDBM +dict +kbyte +llmdb +lockfiles +slmdb +DEVPOLL +DNO +EPOLL +GETPW +KQUEUE +MacOS +NISPLUS +SHLIB +SIGSETJMP +SQLITE +SQLite +deinstalling +dynamicmaps +gcc +getpwnam +getpwuid +ldconfig +libpostfix +longjmp +nonprod +setjmp +shlib +siglongjmp +sigsetjmp +sqlite +unversioned +versioned +DNSWL +cbc +ADDRCPT +Ae +AES +Arnt +ASLR +authz +authzTo +autodetect +autodetection +backend +backends +backscatter +BACKSCATTER +balancer +byname +cakey +casefold +casefolding +caseless +Centos +CFLAGS +changetype +characterset +CHGFROM +cmusaslsecretMECHNAME +CNNIC +concurrencies +cryptanalytic +cryptographic +cryptographically +customizations +cyrus +DB's +de +decrypts +deinstall +dev +DMARC +EAI +EDH +encodings +ENHANCEDSTATUSCODES +environ +esac +etcetera +exchanger +executables +Executables +filename +filenames +fPIC +fred +genrsa +GSSAPI +Gulbrandsen +Gulbrandsen's +helpdesk +icu +icuuc +imap +infeasible +interoperability +interoperable +invasiveness +jetmore +Jetmore +KERBEROS +kern +launchd +ldapadd +ldapdb +ldapmodify +libc +libicu +liblogin +libplain +libsasl +libsasl's +login +Login +LOGIN +logins +lookup +Lookup +lookups +Makefile +makefiles +Makefiles +mary +matcher +maxprocperuid +mdash +MECHNAME +Memcache +Mf +milter +Milter +misconfigured +multi +mux +namen +nameserver +nameserver's +ndash +ne +newkey +nicke's +NOOP +nroff +ntlm +NTLM +Ok +opendkim +OpenDKIM +OpenDMARC +optimizations +ou +outform +pam +param +pathname +pathnames +performant +pipelined +pipelining +PIPELINING +pipemap +Plaintext +postfix +Postfix +POSTSCREEN +Pre +prepend +PREPEND +PROTO +proxyuser +randmap +rc +REJ +REPLBODY +resultn +Rhein +RHEL +rimap +rpath +RPATH +runpath +runtime +SASLv +scalable +scanf +sha +SHA +SMFIC +SMFIP +SMFIR +SMTP +smtputf +SMTPUTF +socketdir +socketmap +startup +subdirectory +subnet +subnetworks +substring +sys +SYS +sysconfig +TCP +testsaslauthd +Timo +tradeoff +typechecks +typen +ulimit +undeliverable +Unencrypted +unionmap +uniqueIdentifier +unpatched +untrusted +Untrusted +unvailable +uri +userPassword +UTF +uucp +UUCP +wakeup +Westchester +whitespace +Wl +xFFFFFFFF +xn +xyy +xzz +ymd +INLINE +SNPRINTF +inline +mtime +snprintf +sprintf +allowlist +allowlisted +denylist +denylisted +ALLOWLIST +ALLOWLISTED +DENYLIST +DENYLISTED +epilog +prolog +proto +ICMP +NORANDOMIZE +wallclock +BDAT +IPL +yyyy +yyyymmdd +Incompat +Junod +gid +json +postlogd +proxied +raf diff --git a/proto/stop.double-cc b/proto/stop.double-cc new file mode 100644 index 0000000..1e9b3de --- /dev/null +++ b/proto/stop.double-cc @@ -0,0 +1,330 @@ +void void rewrite_proto stream + Strip trailing dot at end of domain but not dot dot or dot This + strip source routed addresses site site user domain +transport_lookup transport_lookup finds the channel and nexthop for the given + Typically the nexthop specifies a hostname hostname TCP Port or the +resolve_addr resolve_addr resolve address according to rule set + technically incorrect this is needed to stop user domain domain relay + needs white space but stuff stuff does not This is not a + where stuff stuff does not happen + Strip trailing dot at end of domain but not dot dot or at dot +XXX XXX Short cut invalid address forms + Connect via TCP to domain domain port port The default + Connect via TCP to domain domain port port The default +files files that are owned by the wrong user or files that have world write + name is is not defined + conditionally to value when name is is not +MUMBLE_TODO MUMBLE_TODO flags must not be cleared once raised The _TODO_TO_PASS and +psc_todo_tests psc_todo_tests overwrites all per session flag bits and + Either hand off the socket to a real SMTP engine or say bye bye +char char context +inet_pton inet_pton +void void psc_early_tests state +void void psc_smtpd_init void +void void psc_smtpd_tests state + IP postscreen_dnsbl_max_ttl postscreen_dnsbl_ttl postscreen_dnsbl_ttl 1 h + WARNING WARNING WARNING + WARNING WARNING WARNING + The event driven TLS I O implementation is founded on on line OpenSSL +unused unused + IP f command command + IP q command command + IP Q command command + IP r command command + IP s command command + TCP port port Both host and port may be +void void + reset_cmd_flags reset per command command flags + set_cmd_flags set per command command flags + Connect via TCP to host host port port The default + Connect via TCP to host host port port The default +argv argv command +time time of entry into active queue +peer peer entries +FD_SETSIZE FD_SETSIZE +FD_SETSIZE FD_SETSIZE +FD_SETSIZE FD_SETSIZE + var spool postfix incoming incoming queue + var spool postfix active active queue + var spool postfix deferred deferred queue +time time of entry into active queue +FD_SETSIZE FD_SETSIZE +FD_SETSIZE FD_SETSIZE +FD_SETSIZE FD_SETSIZE + var spool postfix incoming incoming queue + var spool postfix active active queue + var spool postfix deferred deferred queue +XXX XXX + WARNING WARNING WARNING + WARNING WARNING WARNING +NOTREACHED NOTREACHED + If not connected to stdin stdin must not be a terminal + WARNING WARNING WARNING + WARNING WARNING WARNING + WARNING WARNING WARNING + WARNING WARNING WARNING + WARNING WARNING WARNING + WARNING WARNING WARNING + WARNING WARNING WARNING + WARNING WARNING WARNING + If not connected to stdin stdin must not be a terminal +select select + If not connected to stdin stdin must not be a terminal + main main program +this this first +linkage linkage + Postfix master master cf file processing +select select + If not connected to stdin stdin must not be a terminal + response to stress level changes Doing so would would contaminate + IP CA_MAIL_SERVER_EXIT void void + If not connected to stdin stdin must not be a terminal +smtp_site_fail smtp_site_fail handles the case where the program fails to + We can t avoid copying copying lots of strings into VSTRING buffers +binding binding properties passivated +endpoint endpoint properties passivated +safety safety +XXX XXX + See src tls tls_level c and src tls tls h Levels above encrypt require +smtp_rcpt_done smtp_rcpt_done +smtp_rcpt_done smtp_rcpt_done +smtp_rcpt_done smtp_rcpt_done + Ignore out of protocol enhanced status codes codes that accompany 3XX + IP name name +void void +FALLTHROUGH FALLTHROUGH +HAS_PCRE HAS_PCRE +HAS_PCRE HAS_PCRE + any any + typedef DICT DICT_OPEN_FN const char int int +EDIT_FILE EDIT_FILE edit_file_open original_path output_flags output_mode +void void +nvtable_locate nvtable_locate returns a pointer to the entry that was stored +legacy legacy + for symlinks owned by root NEVER NEVER make exceptions for symlinks + sanitize sanitize db_get put del result + simple attr attr name colon attr value newline +void void htable_free table free_fn +void void htable_walk table action ptr +htable_locate htable_locate returns a pointer to the entry that was stored + IP CA_VSTREAM_POPEN_WAITPID_FN pid_t pid_t WAIT_STATUS_T int +optimization optimization +msg_fatal msg_fatal reports an unrecoverable error and terminates the program + compare compare the address family and network address or + numbers or number number ranges + v4pattern v4field v4field v4field v4field + v4pattern v4field v4field v4field v4field + v4pattern v4field v4field v4field v4field + v4seq_member v4octet v4octet v4octet + v4seq_member v4octet v4octet v4octet +Corruption Corruption + main main program +privileges privileges +DICT_THASH_OPEN_RETURN DICT_THASH_OPEN_RETURN + Fatal errors cannot open file file write error out of memory +found found +found found +XXX XXX maybe earlier +XXX XXX + verified RedHat 3 03 + Bits per byte byte in vector bit offset in byte bytes per set + echo echo text received on stdin + request request a bunch of timer events + Fatal errors cannot open file file write error out of memory +found found +found found + concatenate concatenate null terminated list of strings +void void context +void void binhash_free table free_fn +void void binhash_walk table action ptr +binhash_locate binhash_locate returns a pointer to the entry that was stored +width width precision separator + and whitespace characters must be replaced by XX XX being the + and whitespace characters and the by XX XX being the two digit + Fatal errors cannot open file file write error out of +privileges privileges + Example 00000000000000000000000000000001 01 80 10 80 lo + text text +void void +matched matched text +SUNOS5 SUNOS5 + casefold casefold text for caseless comparison + simple name string string simple name + attribute list attribute attribute attribute list + attribute list attribute attribute attribute list + attribute string string +string string ISO Latin 1 character set except the character + WARNING WARNING WARNING + WARNING WARNING WARNING + Example checking infrastructure for int int const int + Example variables with type int int const int +int int int_val + host port host host +host host port host host + host port host host + port port + host port host host + host port host host port port + host port host host port port + simple attr attr name null attr value null + IP CA_SLMDB_CTL_LONGJMP_FN void void int + IP CA_SLMDB_CTL_NOTIFY_FN void void int + IP CA_SLMDB_CTL_ASSERT_FN void void const char + DICT dict_static_open name name dict_flags +buffer buffer length +privileges privileges +key key length + simple attr attr name attr value newline + attr name any string without null or or newline + var spool postfix maildrop maildrop queue + WARNING WARNING WARNING + WARNING WARNING WARNING +lmdb lmdb supports concurrent writes and reads from different +private private +private private + var spool postfix private private class endpoints + var spool postfix public public class endpoints +messages messages put on hold +option option disables UTF 8 syntax checks on query keys and +option option disables UTF 8 syntax checks on query keys and +lmdb lmdb supports concurrent writes and reads from different +peer peer +void void +XXX XXX + relay loopholes with user domain domain when relaying mail to a + Strip one trailing dot but not dot dot +void void +headers headers after multipart boundary + by XX XX being the two digit uppercase hexadecimal equivalent +must must +request request completed unsuccessfully +DSN_BUF DSN_BUF dsb_create void +DSN_SPLIT DSN_SPLIT dsn_split dp def_dsn text + that registers operators such as level level that compare + var_maillog_file var_maillog_file import_service_path 0 + IP address address family information and the numerical TCP port +privileges privileges +void void rcpb_reset rcpb + The entire lookup key key +DSN DSN dsn_create status action reason dtype dtext mtype mname + When specified with a flush request request that +storage storage +message message size + starts with or or the prefix which will be used + with or or the prefix which will be used to obtain +strings strings with digits uppercase letters and lowercase +safe_strtoul safe_strtoul implements similar functionality as strtoul + typedef LOGIN_SENDER_MATCH LOGIN_SENDER_MATCH +LOGIN_SENDER_MATCH LOGIN_SENDER_MATCH login_sender_create +void void anvil_clnt_free anvil_clnt +privileges privileges + characters specified with special with x XX XX being +0000 0000 0000 007 F 0x xxxxxx +0000 0000 0000 007 F 0x xxxxxx + https github com aox aox blob master encodings utf cpp with +FALLTHROUGH FALLTHROUGH + Detail format is digit digit 1 3 digit 1 3 +encoding encoding domain +domain domain +domain domain +encoding encoding +XXX XXX EAI inspect encoded message global +domain domain +MBOX MBOX mbox_open path flags mode st user group lock_style + incomplete address address rewriting alias expansion automatic BCC +unquoted unquoted form then quoted + records data offset offset of the first REC_TYPE_NORM or REC_TYPE_CONT +DELIVER_REQUEST DELIVER_REQUEST deliver_request_read stream +MAIL_VERSION MAIL_VERSION mail_version_parse version_string why +dict_xx_open dict_xx_open result + When specified with a flush request request that +MAIL_STREAM MAIL_STREAM mail_stream_file queue class service mode + starts with or or the prefix which will be used to +hosts hosts on which databases reside + or maptype mapname search name name The search + with or or the prefix which will be used to obtain +the the message delivery record +MKMAP MKMAP mkmap_open type path open_flags dict_flags +BOUNCE_LOG BOUNCE_LOG bounce_log_open queue id flags mode + internal external external first +context context for queue file changes +sender sender transport +SMFIM_EOH SMFIM_EOH SMFIM_EOM +value value to string +RE RE +PCF_MASTER_ENT PCF_MASTER_ENT local_scope +to to instantiate legacy per dbms parameters and to examine + tls_digest_encode encode message digest binary blob as xx xx +logged logged +logged logged + DNS at the dane dane only and half dane security levels or be +void void tls_pre_jail_init TLS_ROLE +TLS_ROLE TLS_ROLE role +and and the protocol version floor ceiling given a list plist of + of the form name name hexvalue hexvalue If plist + of the form name name hexvalue hexvalue If plist +XXX XXX We re ignoring the function name do we want to log it + If the match is required unambiguous insist that that no other values + etc postfix canonical canonical mapping table + etc postfix virtual virtual mapping table +void void +regions regions with body content +SASLv2 SASLv2 s sasl_server_new takes two new parameters to specify local and +SASLv2 SASLv2 s sasl_client_new takes two new parameters to specify local and + All 5xx replies must have a 5 xx xx detail code + Truncate hostnames ending in dot but not dot dot + Truncate hostnames ending in dot but not dot dot + Truncate hostnames ending in dot but not dot dot + Truncate names ending in dot but not dot dot +200412 200412 + Reject mail to unknown addresses in local domains domains that +client client name +stuff stuff +counter counter +Milter Milter initialization status +USE_TLSPROXY USE_TLSPROXY +address address family +void void +probed probed if non zero the time the currently outstanding address probe was + recipient lists and some MUAs even specify word word address +VERP VERP +NOTREACHED NOTREACHED +NOTREACHED NOTREACHED +NOTREACHED NOTREACHED +NOTREACHED NOTREACHED +NOTREACHED NOTREACHED +NOTREACHED NOTREACHED +NOTREACHED NOTREACHED +key key +key key +key key +key key +key key +key key +key key +key key +key key +key key +key key +key key +key key +key key +key key +key key +key key + Fatal error error opening existing file +void void bounce_cleanup_unregister void + Fatal error error opening existing file +BOUNCE_TEMPLATES BOUNCE_TEMPLATES bounce_templates_create void +void void bounce_templates_free templates + Fatal error error opening existing file + also showq showq c +name name length +BOUNCE_INFO BOUNCE_INFO bounce_mail_init service queue_name queue_id encoding + Fatal error error opening existing file +more more useful and more consistent + Fatal error error opening existing file + Fatal error error opening existing file +XXX XXX + int compar DNS_RR DNS_RR +USE_FNV_32BIT USE_FNV_32BIT diff --git a/proto/stop.double-install-proto-text b/proto/stop.double-install-proto-text new file mode 100644 index 0000000..338286e --- /dev/null +++ b/proto/stop.double-install-proto-text @@ -0,0 +1,41 @@ +bind bind no +bind bind sasl +bind bind yes + command_directory command_directory + Content Disposition Type name es es e 2E + daemon_directory daemon_directory + data_directory data_directory +done done + echo 0 Error unknown type type for path in meta postfix files 1 2 + echo echo 0 Error name should be an absolute path name 1 2 +esac esac + eval echo n name name c + eval group group + eval owner owner +example example com uucp example +file contains only a small subset of all parameters parameters +group group + html_directory html_directory + IP domain address address + IP pattern address address + IP user address address + IP user domain address address + mail_owner mail_owner + mailq_path mailq_path + manpage_directory manpage_directory + meta_directory meta_directory + newaliases_path newaliases_path + nisplus name s name name name column + postmap q nisplus name s name name inputfile + postmap q string nisplus name s name name +postmaster postmaster root + queue_directory queue_directory + readme_directory readme_directory +root root you + sample_directory sample_directory + sendmail_path sendmail_path + server_host ldap ldap example com 1444 + setgid_group setgid_group + shlib_directory shlib_directory + user foo domain user domain domain +virtual virtual alias domain anything right hand content does not matter diff --git a/proto/stop.double-proto-html b/proto/stop.double-proto-html new file mode 100644 index 0000000..a7e7824 --- /dev/null +++ b/proto/stop.double-proto-html @@ -0,0 +1,247 @@ + 1 000 000 messages with good performance unlikely above that limit + 10 10 Mandatory configuration file edits + 11 11 To chroot or not to chroot + 12 12 Care and feeding of the Postfix system +14 rbl_domain rbl_reason rbl_reason +168 100 189 2 255 255 255 224 +18 rbl_domain rbl_reason rbl_reason + 1 ffff ffff ffff ffff ffff ffff ffff ffff +2001 240 587 0 2d0 b7ff fe88 2ca7 ffff ffff ffff ffff + 31 sasldb Accounts are stored stored in a Cyrus SASL Berkeley DB + 33 ldapdb Accounts are stored stored in an LDAP database + 4 yes yes yes never 100 +5 postmaster postmaster example com +5 root root localhost +6 abuse abuse example com +80821 S 0 00 24 smtpd n smtp t inet u c o stress yes +83326 S 0 00 28 smtpd n smtp t inet u c o stress +84345 Ss 0 00 11 usr bin perl usr libexec postfix smtpd policy pl + 8 SENDMAIL usr sbin sendmail G i NEVER NEVER NEVER use t here +address localpart as per RFC 822 so that additional or or +all all Maximum per destination delivery concurrency +and cost cost 1 times more than if the preemptive scheduler was + and sneak in the ten recipient mail Wait wait wait Could we Aren t + aNULL aNULL kEECDH kEDH RC4 eNULL EXPORT LOW STRENGTH +Arrival Date Sun 26 Nov 2006 17 01 01 0500 EST +attacks with user domain domain addresses when Postfix provides +authzTo authzTo dn regex uniqueIdentifier ou people dc example dc com + AUXLIBS AUXLIBS options for LDAP or TLS etc +blockquote blockquote + broken smtp smtp o smtp_quote_rfc821_envelope no +ccert_fingerprint C2 9D F4 87 71 73 73 D9 18 E7 C2 F3 C1 DA 6E 04 +command_directory command_directory + concurrency concurrency limit +config_directory config_directory +daemon_directory daemon_directory +data_directory data_directory +Date Sun 26 Nov 2006 17 01 01 0500 EST +dd dd Alternatively check_ccert_access accepts an explicit search +dd dd check_ccert_access type table search_order cert_fingerprint +dd dd The commas are optional dd +dd dd The default algorithm is b sha256 b with Postfix ge 3 6 + dd No TLS TLS will not be used unless enabled for specific +Dec 4 04 30 09 hostname postfix smtpd 58549 NOQUEUE reject + default_transport uucp uucp gateway + different client IP addresses Lookup results override the the global +Documentation Documentation is available as README files start with the file +done done +done done + dt b a name check_address_map check_address_map a i a href DATABASE_RE + dt b a name check_ccert_access check_ccert_access a i a href DATABASE_ + dt b a name check_client_a_access check_client_a_access a i a href DAT + dt b a name check_client_access check_client_access a i a href DATABAS + dt b a name check_client_mx_access check_client_mx_access a i a href D + dt b a name check_client_ns_access check_client_ns_access a i a href D + dt b a name check_etrn_access check_etrn_access a i a href DATABASE_RE + dt b a name check_helo_a_access check_helo_a_access a i a href DATABAS + dt b a name check_helo_access check_helo_access a i a href DATABASE_RE + dt b a name check_helo_mx_access check_helo_mx_access a i a href DATAB + dt b a name check_helo_ns_access check_helo_ns_access a i a href DATAB + dt b a name check_policy_service check_policy_service i servername i a + dt b a name check_recipient_a_access check_recipient_a_access a i a hre + dt b a name check_recipient_access check_recipient_access a i a href D + dt b a name check_recipient_mx_access check_recipient_mx_access a i a h + dt b a name check_recipient_ns_access check_recipient_ns_access a i a h + dt b a name check_sasl_access check_sasl_access a i a href DATABASE_RE + dt b a name check_sender_a_access check_sender_a_access a i a href DAT + dt b a name check_sender_access check_sender_access a i a href DATABAS + dt b a name check_sender_mx_access check_sender_mx_access a i a href D + dt b a name check_sender_ns_access check_sender_ns_access a i a href D + dt b a name defer defer a b dt + dt b a name defer_if_permit defer_if_permit a b dt + dt b a name defer_if_reject defer_if_reject a b dt + dt b a name defer_unauth_destination defer_unauth_destination a b dt + dt b a name no_address_mappings no_address_mappings a b dt + dt b a name no_header_body_checks no_header_body_checks a b dt + dt b a name no_milters no_milters a b dt + dt b a name no_unknown_recipient_checks no_unknown_recipient_checks a b + dt b a name permit_auth_destination permit_auth_destination a b dt + dt b a name permit_dnswl_client permit_dnswl_client i dnswl_domain d d d d + dt b a name permit_inet_interfaces permit_inet_interfaces a b dt + dt b a name permit_mx_backup permit_mx_backup a b dt + dt b a name permit_mynetworks permit_mynetworks a b dt + dt b a name permit permit a b dt + dt b a name permit_rhswl_client permit_rhswl_client i rhswl_domain d d d d + dt b a name permit_sasl_authenticated permit_sasl_authenticated a b dt + dt b a name permit_tls_all_clientcerts permit_tls_all_clientcerts a b + dt b a name permit_tls_clientcerts permit_tls_clientcerts a b dt + dt b a name reject_invalid_helo_hostname reject_invalid_helo_hostname a + dt b a name reject_multi_recipient_bounce reject_multi_recipient_bounce a + dt b a name reject_non_fqdn_helo_hostname reject_non_fqdn_helo_hostname a + dt b a name reject_non_fqdn_recipient reject_non_fqdn_recipient a b dt + dt b a name reject_non_fqdn_sender reject_non_fqdn_sender a b dt + dt b a name reject_plaintext_session reject_plaintext_session a b dt + dt b a name reject_rbl_client reject_rbl_client i rbl_domain d d d d i + dt b a name reject reject a b dt + dt b a name reject_rhsbl_client reject_rhsbl_client i rbl_domain d d d d + dt b a name reject_rhsbl_helo reject_rhsbl_helo i rbl_domain d d d d i + dt b a name reject_rhsbl_recipient reject_rhsbl_recipient i rbl_domain d d + dt b a name reject_rhsbl_reverse_client reject_rhsbl_reverse_client i rbl_ + dt b a name reject_rhsbl_sender reject_rhsbl_sender i rbl_domain d d d d + dt b a name reject_sender_login_mismatch reject_sender_login_mismatch a + dt b a name reject_unauth_destination reject_unauth_destination a b dt + dt b a name reject_unauth_pipelining reject_unauth_pipelining a b dt + dt b a name reject_unknown_client_hostname reject_unknown_client_hostname + dt b a name reject_unknown_helo_hostname reject_unknown_helo_hostname a + dt b a name reject_unknown_recipient_domain reject_unknown_recipient_domain + dt b a name reject_unknown_sender_domain reject_unknown_sender_domain a + dt b a name reject_unlisted_recipient reject_unlisted_recipient a b wi + dt b a name reject_unlisted_sender reject_unlisted_sender a b dt + dt b a name reject_unverified_recipient reject_unverified_recipient a b + dt b a name reject_unverified_sender reject_unverified_sender a b dt + dt b a name sleep sleep i seconds i a b dt + dt b a name warn_if_reject warn_if_reject a b dt +dt dt b i a href DATABASE_README html type table a i b dt +dt dt b i number i i number i b dt + dt dt dd 0 Disable logging of TLS activity dd + dt dt dd 1 Log only a summary message on TLS handshake completion + dt dt dd 2 Also log levels during TLS negotiation dd + dt dt dd 3 Also log hexadecimal and ASCII dump of TLS negotiation + dt dt dd 4 Also log hexadecimal and ASCII dump of complete + dude dude example com + eliminates the latency of the TCP handshake SYN SYN ACK ACK + example com uucp uucp host + example MAIL RCPT BDAT BDAT MAIL RCPT BDAT without ever having to + export MANPATH MANPATH pwd man MANPATH +fe80 1 2d0 b7ff fe88 2ca7 ffff ffff ffff ffff +fe80 5 1 ffff ffff ffff ffff +file allows for robust handling of temporary delivery errors errors +Filtered Filtered +for the file name when a pattern is a type table table specification +from host example com 192 168 0 2 TLSv1 with cipher cipher name +generic generic a restrictions These restrictions are applicable in + groups msn com 63 2 1 2 4 4 14 14 14 8 0 + highvolume com 4000 160 160 320 640 1280 1440 0 0 0 0 +host host port host port address or address port the form + http www umich edu dirsvcs ldap ldap html or OpenLDAP + id 84863BC0E5 Sun 26 Nov 2006 17 01 01 0500 EST + if concurrency concurrency limit + ifconfig en0 alias address netmask 255 255 255 255 + inet_addr_local inet_addr_local configured 2 IPv4 addresses + inet_addr_local inet_addr_local configured 4 IPv6 addresses +insiders_only insiders_only check_sender_access hash etc postfix insiders reject +in the form of a domain name hostname hostname port hostname port +into memory such as pcre regexp or texthash texthash is similar + jane jane janes preferred machine + joe joe joes preferred machine + Line 8 NEVER NEVER NEVER use the t command line option here It +listname listname request + lists sourceforge net 2313 2313 0 0 0 0 0 0 0 0 +local local 8 +local_only local_only +maildrop maildrop +maildrop maildrop owner cn root dc your dc com +make make makefiles CC opt ansic bin cc Ae HP UX +make make makefiles CC purify cc + man man man5 postconf 5 less +master_service_disable foo inet inet +multi_instance_enable multi_instance_enable +multi_instance_group multi_instance_group +multi_instance_name multi_instance_name +mydestination myhostname localhost mydomain mydomain + mydomain to an incomplete address address rewriting alias +mynetworks mynetworks 127 0 0 0 8 168 100 189 0 28 1 128 fe80 10 2001 240 587 +mynetworks mynetworks hash etc postfix network_table +Name lt user example com gt gt i Postfix will ignore the i User + name name port name or name port + NOTE Postfix 3 6 also introduces support for the level level +number number ranges Postfix version 2 8 and later If no +numbers or number number ranges Postfix version 2 8 and later +one or more separated numbers or number number ranges + openssl req new key key +or more separated numbers or number number ranges p +or number number ranges Postfix version 2 8 and later If no + ownership of system directories such as etc usr usr bin var + PARAM postscreen_dnsbl_max_ttl postscreen_dnsbl_ttl postscreen_dnsbl_ttl + patterns list multiple domain names as domain domain + p Note 2 address information may be enclosed inside tt tt + postfix 12345 12345 postfix no where no shell + Postfix 2 3 2 5 to hang up on clients that that match + Postfix has TWO sets of mail filters filters that are used for +Postfix Postfix can use an LDAP directory as a source for any of its lookups + Postfix Postfix passes the status back to the remote SMTP + Postfix Postfix will send the mail back to the sender address +pre pre +query_filter mailacceptinggeneralid s maildrop maildrop +queue_directory queue_directory +Received from localhost localhost 127 0 0 1 +Received Received from porcupine org +rejected rejected recipients are available on request by the Milter + rewrite 8 none none + Say we have ten recipient mail followed by two two recipient mails If + separated numbers or number number ranges If no +smtpd_recipient_restrictions smtpd_recipient_restrictions +smtpd_relay_restrictions smtpd_relay_restrictions +smtpd_relay_restrictions smtpd_relay_restrictions + smtpd_tls_mandatory_protocols SSLv2 SSLv3 TLSv1 TLSv1 1 +smtpd_tls_mandatory_protocols SSLv2 SSLv3 TLSv1 TLSv1 1 + smtp smtp o smtp_bind_address 11 22 33 44 + smtp smtp o smtp_bind_address6 1 2 3 4 5 6 7 8 + smtp_tls_mandatory_protocols SSLv2 SSLv3 TLSv1 TLSv1 1 +smtp_tls_mandatory_protocols SSLv2 SSLv3 TLSv1 TLSv1 1 + SSLv3 TLSv1 TLSv1 1 TLSv1 2 and TLSv1 3 Starting with + T 5 10 20 40 80 160 320 640 1280 1280 + T A 5 10 20 40 80 160 320 320 + The and match and literally Without the the + The matches literally Without the the would +Therefore 301 0301 0x301 and 0x0301 are all equivalent to + The syntax of name value value name value and name value +the the backed up domain tld domain This prevents your mail queue + tls_random_source dev dev urandom + tls_random_source dev dev urandom +tls_random_source dev dev urandom +TLS TLS support in the LMTP delivery agent + TLSv1 3 with cipher TLS_AES_256_GCM_SHA384 256 256 bits + to flush flush 8 Deferred +to host example com 192 168 0 2 25 TLSv1 with cipher cipher name + to server example TLSv1 3 with cipher TLS_AES_256_GCM_SHA384 256 256 bits + TOTAL 5000 200 200 400 800 1600 1000 200 200 200 200 +transport transport + tt tt in the authorized_verp_clients value and in files + tt tt in the mynetworks value and in files specified with + tt tt in the smtpd_authorized_verp_clients value and in + tt tt in the smtpd_authorized_xclient_hosts value and in + tt tt in the smtpd_authorized_xforward_hosts value and in + tt tt in the smtpd_client_event_limit_exceptions value and + tt tt in the smtpd_sasl_exceptions_networks value and in + tt tt p +two two recipient mails + uid cn cn auth +Unfiltered Unfiltered + unknown recipients in local domains domains that match mydestination + Use blockquote pre pre blockquote for examples + Use pre pre for the Examples section at the end +username username + user sourceforge net 7678 7678 0 0 0 0 0 0 0 0 + using TLSv1 3 with cipher TLS_AES_256_GCM_SHA384 256 256 bits + using TLSv1 with cipher cipher name +var var spool and so on This is especially an issue if you executed +With the standard operators lt lt etc compatibility + yes yes yes never 100 +zombie zombie tlsproxy 8 smtpd 8 + and 1 000 000 messages with good performance unlikely above that +dt dt b name value b Postfix ge 3 0 dt + dt dt dd 3 Also log the hexadecimal and ASCII dump of the + dt dt dd 4 Also log the hexadecimal and ASCII dump of complete + parametername stress something something Other + p Note on OpenBSD systems specify dev dev arandom when dev dev urandom diff --git a/proto/stop.spell-cc b/proto/stop.spell-cc new file mode 100644 index 0000000..9166298 --- /dev/null +++ b/proto/stop.spell-cc @@ -0,0 +1,1784 @@ +Aarnio +abcd +ABI +ABNF +abounce +accessor +ack +acked +acknowledgement +acl +ACL +adaptor +ADDCH +adddr +addenv +addn +Addr +addrbuf +ADDRFAMILY +addrinfo +ADDRINFO +addrs +adefer +adelay +adhoc +adomain +aes +af +AFS +Aho +ai +aierr +AIX +al +alg +algbits +algcode +allalnum +allascii +allbits +alldig +Allgemeine +ALLOC +allocator +Allowlist +allowlisting +ALLPERMS +ALLPKTS +allprint +Allright +allspace +alphanum +alphanumerics +androsyn +aox +ap +api +APIs +appl +APPL +ar +arg +argc +Argh +argi +argl +argp +Args +ARGS +ARGV +argvp +arpa +ARPA +aRv +ascii +aslo +ast +async +atol +atrace +ATTR +attrp +attrs +atype +Auch +auths +autoclass +Autodetect +Autodetection +automagically +AUTOUTF +AUXULIARY +AWK +Axel +Backoff +BADFLAGS +BADHINTS +balpar +basename +Basename +bdat +BDAT +bdehnoqv +BDFORXhqu +beh +bfFhimnNoprsuUvw +BH +BINARYMIME +binhash +BINHASH +BIOs +bitclean +BITCLEAN +bitmasks +bitrot +Bitrot +bitset +bitwise +Bitwise +blackholes +blocklisted +bona +bool +BOOL +booleans +br +bsmtp +BST +buf +BUF +BUFIZ +buflen +bufp +BUFSIZ +bufsize +BUFSIZE +bufstat +bugtraq +byuid +bzero +cachable +cacheable +canonicalization +canonicalize +Canonicalize +canonicalized +CANONNAME +CAPTURECOUNT +carriagecontrol +carriagereturn +Carsten +CASEF +Casefold +casefolded +casefoldx +casemapped +cC +ccerts +cdbm +CDBM +cdbq +CDE +certkey +certmatch +cfg +CFG +chainfiles +ChangeCipherSpec +charactersets +charset +checkdir +Chroot +CHROOT +chrooting +Ciphersuite +cleanenv +clearerr +clist +clnt +CLNT +clobbber +closefrom +closelog +CLR +clumsify +cmalloc +cmd +CMD +cmdp +cmds +cmp +cmsg +CMSG +CNAMEs +codepoint +Codepoint +codepoints +colocated +comingle +compar +COMPAT +comsat +COND +CONF +conn +const +Const +conv +cooldown +Coverity +cpio +cpp +cptr +CPTR +CPUs +CREAT +CRLF +ctable +CTABLE +ctext +ctime +ctl +CTL +ctype +CUID +curr +cvt +CWD +cz +da +datagram +datagrams +datalink +dbms +dbopen +dbpath +DCL +dcs +Dditvw +dealloc +deallocate +deallocates +deallocating +deallocation +debian +decapsulate +DECnet +decrypt +decryptable +decrypted +decrypting +DEFL +DEFLT +deflts +DEFNAME +DEFNAMES +DEFPATH +defport +DEFS +defval +del +delim +delims +deliverability +delrcpt +DELRCPT +denylisting +dequote +dereference +dereferencing +deserialization +Dest +DEST +DESTADDR +DESTPORT +destructor +df +DFFF +dfhHnopvx +DFL +DFXP +dgram +DGRAM +DHparams +dhs +Dik +dirent +dirname +dirs +DISCONN +DJB +DJBDNS +DJB's +dlen +dlfunc +DLL +DNSBLOG +DNSBNL +dNSName +DNSRCH +dnsxl +DNSXL +dom +dont +DONT +doproto +DORX +dotforward +dp +Driehuis +dsb +DSB +dsbuf +DSNs +dst +dtext +DTEXT +DTXT +dtype +DTYPE +dumpfile +dup +DUP +DUPFD +dups +dymap +EACCES +EADDRINUSE +EAGAIN +EBADF +ec +ECONNABORTED +ECONNREFUSED +ECONNRESET +eddd +EDQUOT +ee +EEXIST +EFBC +EFBDA +EFBIG +egid +Eindhoven +EINTR +EINVAL +Elektrotechnik +elif +else's +elsize +empt +emptive +Emtpy +emul +ENDIF +ENDIFs +endp +endpt +ENOBUFS +ENOENT +ENOMEM +ENOSPC +ENOTCONN +ent +ENT +entrancy +enum +ENUM +env +ENV +ENVFROM +envid +ENVID +ENVRCPT +eob +EOB +eod +eof +EOL +eother +EOVERFLOW +EPERM +epilog +EPIPE +EPROTO +epv +eq +EQ +ERANGE +errno +errstr +Eschborn +especials +ESTALE +et +ETIMEDOUT +eugid +EUGID +euid +EV +eval +EVAL +EVP +EXCHANGER +exchangers +execvp +expar +EXPN +expr +EXPR +extern +extpar +EXTPAR +FALLTHROUGH +FALLTRHOUGH +fam +Fawcett +fbck +fchmod +fclose +FCNTL +fdclose +FDD +FDEF +fdopen +fds +fdtable +feof +ferror +FFDHE +FFF +FFFE +FFFF +fflush +fg +fgetc +fgets +fh +fhHovx +fi +fide +fifo +FIFOs +filedes +fileno +filesystem +filesystems +filt +FILT +findenv +fixme +Fixme +FLD +fmt +fn +FN +FoldCase +fopen +forcetlsa +FOREACH +formatter +formfeed +Forststrasse +fovx +fp +fprint +fprintf +fpt +fpurge +fputc +fputs +fread +freeaddrinfo +fron +fscanf +fsck +fseek +fset +fsops +fsspace +fsstone +fstat +fsync +ftell +ftime +ftimeout +ftimeval +ftruncate +fu +fullname +fullwidth +func +FUNC +futimes +fwi +fwrite +gai +GECOS +Geoff +GETC +GETCHAR +getegid +getenv +geteuid +getgrnam +gethostbyaddr +GETHOSTBYNAME +getnameinfo +GETNAMEINFO +getopt +GETOPT +getpid +getpw +getsockopt +gettimeofday +getuid +ghostgun +giasbm +gid +GID +ging +github +GLIBC +glibc's +globals +gmtoff +gn +Goedel's +goto +GOTO +gotsigchld +gotsighup +grey +groupid +grr +Grr +halfdane +halfwidth +handoff +HaProxy +hardlink +hardlinks +hbc +HBC +hc +hdr +HDR +hdrs +HDRS +hdrval +HelloRetryRequest +helohost +herror +hexdump +hexvalue +hfrom +HFROM +HGMP +Hinxton +HMAC +honoured +hostaddr +HOSTADDR +hostmumble +Hostname +HOSTNAME +hostport +hostrr +hport +HPUX +HRR +htable +HTABLE +htonl +htons +https +HUP +ial +icgroup +ICT +IDENT +ideographic +idna +IDNA +ifdefs +IFF +ifinet +IFINET +IFMT +ifself +IGN +illumos +IMPL +INADDR +incr +INCR +indexable +Indexable +indirections +ing +INIT +initializations +initializer +inj +Inlined +inlining +instantiation +interruptible +intra +INTV +intval +inum +INVAL +ioctls +iostuff +iov +iovlen +ipaddr +IPD +ipmatch +IPPROTO +isalnum +ISALNUM +isascii +ISASCII +iscntrl +isjmp +ISMARKED +isprint +ISSET +issetuid +ISSOCK +ISXXX +iter +ITER +iterator's +iterators's +itty +Jaenicke +jbuf +JCL +jeffm +JIT +jmp +johhny +jq +json +JSON +KAME +Karlsruhe +kB +Keean +keepalive +keepalives +Kellerspeicherpegelanzeiger +Kernighan +keyfile +keyname +Kilani +killme +Kirch +koobera +Kouhei +Krahmer +lastl +latencies +lateron +ldapone +LDH +len +LEV +leven +lex +lexicals +lf +lflags +libbind +LIBC +libdata +libfuncs +libmaster +libmemcache +Libmilter +libname +libresolv +libtls +libunbound +libutil +lims +lineno +liveness +lnsl +LOCALDOMAIN +LOCALPART +Logfile +Logfiles +logmask +logopts +logrotate +logtag +logwriter +LOGWRITER +LONGJMP +longjump +Lookups +lowfd +lowfrom +lposix +lseek +lsm +LSM +lsocket +lstat +Lstat +ltype +lvalue +lvalues +lx +LY +macrps +MAILLOG +makedef +malloc +mallocs +mapnames +MAPNAMES +mapsize +maptypes +masq +masterp +matchlist +Matti +maxdepth +maxlen +MAXLEN +MaxProtocol +MAXSEG +maxsize +mbox +MBOX +mdalg +mdb +MDB +MECH +Meer +memcaches +memcat +memchr +memcmp +memcpy +memmove +memopen +memreopen +memset +MERCHANTABILITY +mesg +MESG +midna +MILTER +milter's +MILTERS +MinProtocol +minrate +minssf +Mis +misconfiguration +mkdirs +mkfifo +mkmap +MKMAP +mmap +MMNNFFPPS +mname +MNAME +Montegancedo +MQID +MRU +msgs +msk +mss +MSS +mtp +MTU +mtype +MTYPE +MUL +multf +multibyte +multiline +multiserver +multivalued +mutexes +Muuss +MVCC +mvect +MVECT +mxrr +MXs +myaddrinfo +mydest +mydomainname +myflock +MYFLOCK +myfree +mygroup +mymalloc +mymemdup +mypasswd +mypwcache +mypwd +mypwenter +mypwfree +mypwnam +mypwuid +myrand +myrealloc +mysqlsource +mysrand +mystrdup +mystrndup +mystrtok +mystrtokdq +mystrtokq +na +Nagle +Nagle's +nam +namaddr +namadr +NAMADR +namechecks +NAMELEN +namelength +nameser +namespace +namespaces +nameval +NAMEVAL +namme +nasties +natively +NATs +nbbio +NBBIO +nbool +NBOOL +nbytes +nc +ncache +Ncache +NCACHE +nd +ndbm +ndr +nelm +netblock +netdb +NetInfo +Netstring +NETSTRING +netstrings +newcontext +newd +newpath +newqeueid +newqueueid +newtls +nexhop +NeXT +NEXTHOP +nexthops +nf +Nfinoprsuvw +NFS +ni +nid +NID +nids +nint +NINT +nlink +nlinks +nnn +NOCLOSE +NODELAY +nodename +noexcept +NOEXT +noforward +NOKEY +NOLOCK +NOMEMINIT +NONAME +NONDEF +nonl +noop +Noop +nop +NOP +NORETURN +normalizer +NOSUB +notfound +NOTFOUND +NOTHROTTLE +NOTREACHED +nowait +NOWAIT +np +nparts +nr +Nr +nscd +ntls +ntohs +ntop +NUL +nulll +nullmx +nullMX +NULLMX +num +NUMERICHOST +nvtable +NVTABLE +nxxx +oact +Oaktree +oconv +offsetof +OID +oldd +oldlog +oldstyle +oname +OpenLDAP's +openlog +operability +OPs +OPTNEG +orcpt +ORCPT +ord +ot +ourself +overallocate +ownreq +ozz +padchar +padlen +pagein +pageout +PARAM +parametername +params +PARAMS +paren +parens +parm +parsable +parseline +parsers +Pashkov +passivate +Passivate +passivated +passivation +pathame +Pathname +pathp +patrik +pcf +PCF +pclose +pcs +PDDMDS +pdelay +PDMS +pedantism +peekfd +peercert +permited +pfxs +PGRES +PGresult +pgsqlsource +Pieter +Pipelining +PKCS +PKEY +PKIX +PLAINTEXT +Plauger +plist +plmysql +PLMYSQL +plpgsql +PLPGSQL +PMilter +Pn +pname +POB +popen +POPEN +portnum +PORTP +pos +posix +Posix +postcondition +Postcondition +postexpire +POSTFIX +postgresql +Postgresql +Postlog +postlogd +Postprocessing +postremove +postrename +postrmdir +posttls +PPTR +PQescapeString +PQescapeStringConn +prabhat +PRE +precedences +pred +predefines +prefetch +prefi +pregreet +PREGREET +pregreeting +preimage +Preload +prepended +prepending +Prepending +prepends +preprocessed +Preprocessing +PREREQ +prescan +printfck +PRINTFLIKE +PRINTFPTRLIKE +PRNGD +PROC +procname +procnet +PROCNET +progname +programmatically +prolog +proto +Proto +protomask +prototyped +PROX +proxied +Proxied +PROXYING +Proxymappers +psc +PSC +pseudofield +pseudothread +pseudothreads +PSS +psSv +PTHREAD +pton +PTRs +pushback +PUTC +PUTCHAR +putenv +pv +qfile +qflags +qI +qIqueueid +qname +qnameval +qsort +QSTRING +ratbox +raxoft +rcode +RCODE +rcpb +RCPTs +rdb +rdev +rdonly +RDONLY +rdwr +RDWR +readdir +readline +readlline +readllines +readwrite +realloc +recdump +recip +RECIP +reclen +reconnection +recurse +Recurse +RECURSE +Recurses +recursing +recv +RECV +Redhat +Redistributions +reentrancy +REENTRANCY +reentrant +refcounts +refesh +regerror +reget +REGSUB +relop +RELOP +relops +rendez +repl +replayer +replycode +representable +requestor +requestors +requeuing +resflags +responder +restartable +resync +resynchronize +ret +RET +retransmission +retransmit +retryable +retval +revalidate +revalidated +rewriter +rfind +rflag +rflags +rh +RHS +RHSBL +rhswl +RHSWL +Ribbens +rl +RLIM +RMTA +rname +RO +Roel +roques +roundtrips +rp +RPCs +RQST +rr +RRDATA +rrlist +RRSIG +rtnetlink +ruleset +RWR +sa +salen +SAML +sanitization +Santize +sb +SCACHE +SCANFLIKE +SCCS +Schoenmakers +Schupke +scott +screener +sdelay +SDK's +seach +seekable +selectable +sendfd +sendmsg +sep +serv +SERV +serverid +serverout +servers's +servicename +servname +SERVNAME +SERVPORT +sess +SESS +setegid +Setenv +seteuid +setgroups +Sethi +setrlimit +setsid +setsockopt +setuid +sgid +sig +SIG +sigaction +sigaddset +SIGALRM +sigchld +SIGCHLD +sigdeath +sigdelay +sigemptyset +sighup +SIGILL +siginit +SIGINT +SIGKILL +signum +SIGPIPE +sigprocmask +SIGQUIT +sigresume +SIGSEGV +sigset +sigsetup +sigval +silenty +siocgif +SIOCGIFCONF +SIOCGIFNETMASK +siocglif +SIOCGLIFCONF +SIOCGLIFNETMASK +SIOCLIF +sizeof +skipblanks +sl +SLMDB +SLMs +smap +SMFIF +SMFIM +sni +SOA +sockaddr +SOCKADDR +Socketmap +socketmapname +socketmaps +socketpair +socklen +sockmap +socktype +SOCKTYPE +sofar +softerror +softlinks +SOML +soname +sp +SPARC +spawner +Spead +SPID +splitq +splitter +sqlitecon +sqrt +SRC +srv +srvr +sscanf +SSF +ssize +ssscanf +stackable +starttime +STATCUR +STATFAIL +statp +STATUNTRIED +StatusOr +statusp +stdarg +stderr +STDERR +STDIN +stdout +STDOUT +steenkeeng +stmt +str +STR +strcasecmp +strcat +strcpy +streamlf +STREAMLF +STREQ +strerror +STRERROR +strflags +strftime +stringops +strlen +STRLEN +strncasecmp +strncat +strncpy +strrecord +STRREF +strspn +strtol +strtoul +strtype +struct +structs +strval +STS +stuffozz +stye +subclasses +subcommand +subdirectories +Subdirectory +subjectAltName +subjectAltNames +sublist +sublists +Subnet +subnets +subopen +subpatterns +Substring +substrings +subtype +subtypes +succ +sudo +sunislelodge +superblocks +superset +supprt +Sutou +SVID +swb +Symas +symlinked +symlink's +symlinks +syscall +SYSCALL +sysconf +Syslog +syslogged +syslogging +sysv +TAAAA +tailp +tas +teardown +Tempfail +tempfailed +testcase +testname +th +tha +thash +THASH +theadsafe +threadsafe +thusly +timecmp +timeval +timval +tindx +tItp +tkt +TLScontext +tlsext +tlsfinger +tlsmgrmem +tlsmgr's +tlsp +TLSP +TLSPKTS +TLSPROXY +TLVs +tm +tmpbuf +ToASCII +TOCTOU +Todo +TODO +TOFILE +tok +TOK +tokenize +Tokenize +tokenizer +tokenizes +tokenizing +tokval +toUTF +tp +translit +transp +TRANSP +treibsand +tresspassers +trimblanks +trivally +TRNC +TRUNC +TRUSTAD +trustfile +TTL +TTLs +tty +tunable +Tunable +Tunables +tv +txn +TXT +Typechecking +TYPECONNSTRING +typedef +typedefs +TYPEINET +TYPEUNIX +ucasemap +uchar +UDP +ug +ugid +uic +uidna +UIDNA +UIDs +uint +ULIMIT +Ullman +ulong +ULONG +ultostr +Ultrix +ulval +un +unalias +uname +UNAUTH +unbuffered +uncache +Uncomment +undef +UNDEF +Undefine +Undeliverable +unescape +UNFAIL +unformatted +unget +ungetc +Unhandled +unicode +unimpl +uniq +unistd +unitialized +Universitaetsplatz +UnixWare +unk +unlink +Unlink +unlinked +unlinking +unlockfile +unmark +Unmark +unmarks +Unoptimized +Unparsable +unparse +unparsed +unparser +unparsing +UNPROTO +unprototyped +unregister +unregistering +unregisters +unselect +unselected +unsetenv +unsets +UNSPEC +unterminated +unthrottle +Unthrottle +UNTHROTTLE +UNTRUSTED +upass +upd +updatable +UPDATABLE +Upref +uprefs +URI +URIs +url +useauto +usebits +usec +usleep +USR +utf +utime +UTS +uva +uxtext +va +valgrind +validator +VALIDATOR +variadic +vbuf +VBUF +VBUFs +vdsb +ve +ver +verifier +verpified +VERPify +vfprintf +vfy +vmailer +Vmailer +vmilter +VMS +vmsg +Vn +vopened +vous +vp +vprint +vprintf +vscan +vsmtp +vsmtpd +vsnl +VSNL +vsprintf +vstream +VSTREAM +Vstreams +VSTREAM's +VSTREAMs +VSTREAMS +vstring +VSTRING +VSTRINGs +vtrace +waitpid +WAITPID +Wakeup +WAKEUP +wat +webservers +WeiYu +Wformat +whatsup +Whitespace +WIFSTOPPED +wil +wildcarded +Wimplicit +wireshark +Wmissing +Woops +Wparentheses +wr +Wrappermode +WRITEMAP +WRONLY +wsp +Wstrict +Wswitch +WTF +Wuninitialized +Wunused +XCPT +xdelay +xe +xfers +xmask +xport +xsasl +XSASL +XSH +xt +XTRA +XVxy +xxdbx +xxgdb +xxxx +XXXXX +xxxxxx +XXXXXXX +YASLM +yeardays +yyyy +yyyymmdd +zA +zer +Zmailer +AMD +All's +BIO +BTU +CALLBACK +CHUNKING +CO +CONT +CV +Callback +Cert +Compaq +DBL +DBMS +DICT +DP +Deferrals +ENC +EXCL +EXP +EXT +Ff +Goode +Grandfathered +INST +Inline +Kluge +LANG +LIB +LP +MAI +MGR +MIPS +MISC +MSG +MULTIPART +Majordomo +Misc +Mn +NB +NR +OBS +ORIG +OTOH +PF +PP +PX +Pf +Plugins +REC +RR +Rcpt +Regexp +SB +SC +SEQ +SN +STAT +STATS +STD +Siemens +Simplistically +Stat +UK +UNICODE +USERNAME +UTC +Unicode +Username +VA +ab +alphanumerical +app +av +barf +beholder's +bidirectionally +binding's +bio +builtin +callback +callbacks +ch +chg +comm +comp +crappy +def +deferrals +diff +enc +excl +exp +ext +externalized +gazillions +ht +incl +instance's +key's +kluge +masqueraded +maxed +metadata +mgr +mp +neg +op +ops +perms +pf +piggybacked +pref +proactive +proactively +proxy's +pt +reanimates +rec +refactor +regexps +request's +rollover +schlepping +scratchpad +seq +singlets +stat +stats +trespassing +ts +val +vars +verboten +versioning +wiki +DSTRICT +FNV +NONBLOCK +Vo +chongo +fnv +isthe +ldseed +softwareengineering +stackexchange +stdint +Noll diff --git a/proto/stop.spell-proto-html b/proto/stop.spell-proto-html new file mode 100644 index 0000000..a4ad7c5 --- /dev/null +++ b/proto/stop.spell-proto-html @@ -0,0 +1,350 @@ +ABNF +ADAgECAhQSv +adhoc +ADME +aes +af +ahQkZ +AIX +Allowlist +allowlisting +allowlists +alphanumerics +amavisd +ame +apache +ASE +ATABASE +ated +attractor +authc +Axel +backported +Backscatter +BAQEFAASCBKcwggSjAgEAAoIBAQDc +barelf +bC +BDAT +BgBQGBg +BINARYMIME +bona +BQ +br +CAQAwBQYDK +Carsten +CdUaexKP +ce +certN +cflags +cgi +CHACHA +chainN +ching +ciphe +cldr +cOkjtAH +COMPAT +concurrenc +conn +Crespo +cronjob +csie +cve +cvename +Cy +cyrusimap +DATAB +DATABAS +dbpath +DCCAeCgAwIBAgIUIUkrbk +deduplication +Denylist +denylisting +denylists +der +dereferencing +DESTADDR +destinatio +DESTPORT +dfn +dgram +dH +DISPLA +dll +dom +doma +dont +DONT +dq +ecdsacerts +ecdsakey +EEXIST +eeYOxyThMA +Efbz +egv +else's +ENOENT +exchangers +exploder +fb +fe +fg +fi +fide +fifo +filesystem +fmsiQoRHzAFBgMrZXEwFDESMBAG +fprint +Fq +GAemPCT +ge +gid +GID +github +Gunnar +hardlink +hea +hecks +HGVNTK +HHMMSS +hostn +HOSTNAME +hre +href +HswDQYJKoZIhvcNAQEL +https +HuNn +HUP +iana +IDENT +idna +IDNA +ijs +imit +IU +jane +Jänicke +Jänicke's +jByBifpIe +jnorell +joe +js +jsp +kali +KAME +KazmyRi +keld +keyN +Kilani +krcaJvDSMgvu +KypOZPNPF +lan +latencies +li +libmemcache +libs +lient +limi +LNler +Logfile +logrotate +LOGTAG +lookahead +Lookups +lsqlite +lt +MAILLOG +mbox +MEcCAQAwBQYDK +MessageLabs +MIDDLEBOX +MIIBdjCB +MIIBKzCB +MIIC +MIIEvQIBADANBgkqhkiG +MILTER +mit +mitre +mtaadmin +MTAADMIN +mtadmin +mua +mygroup +myinst +NAbIJaDBqZb +nameservers +namespace +nat +nC +ncache +NCALLS +NCTU +newgroup +NFS +nH +ninit +NNTP +noop +nroffescape +nullmx +nulPzwUo +nzHQJ +OGvpyrMlm +oP +opendmarc +orion +oth +overinflate +oyE +PARAM +parametername +params +parsers +Pathname +pfs +pkgsrc +POSTFIX +postlogd +pQcWsx +precedences +pregreet +Pregreet +PREGREET +prepended +prepending +prepends +proble +proxied +Pseudocode +PSS +punycode +qADAgECAhQaw +qi +qmznjbD +Quanah +QusgkahH +Ralf +relayhos +RESOLV +resolvers +retransmission +retransmits +retransmitted +rf +rflRreYuUZBp +rhswl +Rirz +rL +rMZDAFBgMrZXAwFDESMBAG +RolyeiE +roundtrips +RPCZDrPX +rsacerts +rsachain +rsakey +rsyslog +runnable +SASLAUTHD +scheduler's +schemas +se +selectable +ser +SESS +si +SLcOiXFHXlxp +smarthost +smatch +sni +Softw +sp +spamassassin +spambot +sqrt +stderr +stdout +Stdout +stname +strftime +subdirectories +suboptimal +suid +suiteb +systemd +sz +tDc +tempfailing +th +threadm +threadsafe +tname +TRE +trusteddomain +TTL +tu +tw +TXT +uname +Uncomment +Undeliverable +unexpanded +unextended +unicode +unrefreshed +unrepliable +Unselective +unvalidated +uva +vali +VwBCIEIEJfbbO +VxBDsEOQf +VZuh +Whitespace +wi +wip +wKsTGDH +wzFd +xhtml +YPDWxEHom +YWH +yYhh +zdlPQR +Aren +rejec +debian +prox +vir +AAA +Admin +CHUNKING +DAT +Downsides +Firefox +Inline +Jänicke's +LANG +NZ +Plugin +Plugins +Unicode +WHITELIST +bk +ch +chg +chunking +comm +dbl +downsides +fer +gt +hos +injectors +kinks +pkg +rollover +rs +subj +wiki +Jà +ng +rsyslogd diff --git a/proto/tcp_table b/proto/tcp_table new file mode 100644 index 0000000..d1ddb81 --- /dev/null +++ b/proto/tcp_table @@ -0,0 +1,108 @@ +#++ +# NAME +# tcp_table 5 +# SUMMARY +# Postfix client/server table lookup protocol +# SYNOPSIS +# \fBpostmap -q "\fIstring\fB" tcp:\fIhost:port\fR +# +# \fBpostmap -q - tcp:\fIhost:port\fB <\fIinputfile\fR +# DESCRIPTION +# The Postfix mail system uses optional tables for address +# rewriting or mail routing. These tables are usually in +# \fBdbm\fR or \fBdb\fR format. Alternatively, table lookups +# can be directed to a TCP server. +# +# To find out what types of lookup tables your Postfix system +# supports use the "\fBpostconf -m\fR" command. +# +# To test lookup tables, use the "\fBpostmap -q\fR" command as +# described in the SYNOPSIS above. +# PROTOCOL DESCRIPTION +# .ad +# .fi +# The TCP map class implements a very simple protocol: the client +# sends a request, and the server sends one reply. Requests and +# replies are sent as one line of ASCII text, terminated by the +# ASCII newline character. Request and reply parameters (see below) +# are separated by whitespace. +# +# Send and receive operations must complete in 100 seconds. +# REQUEST FORMAT +# .ad +# .fi +# The tcp_table protocol supports only the lookup request. +# The request has the following form: +# .IP "\fBget\fR SPACE \fIkey\fR NEWLINE" +# Look up data under the specified key. +# .PP +# Postfix will not generate partial search keys such as domain +# names without one or more subdomains, network addresses +# without one or more least-significant octets, or email +# addresses without the localpart, address extension or domain +# portion. This behavior is also found with cidr:, pcre:, and +# regexp: tables. +# REPLY FORMAT +# .ad +# .fi +# Each reply specifies a status code and text. Replies must be no +# longer than 4096 characters including the newline terminator. +# .IP "\fB500\fR SPACE \fItext\fR NEWLINE" +# In case of a lookup request, the requested data does not exist. +# The text describes the nature of the problem. +# .IP "\fB400\fR SPACE \fItext\fR NEWLINE" +# This indicates an error condition. The text describes the nature of +# the problem. The client should retry the request later. +# .IP "\fB200\fR SPACE \fItext\fR NEWLINE" +# The request was successful. In the case of a lookup request, +# the text contains an encoded version of the requested data. +# ENCODING +# .ad +# .fi +# In request and reply parameters, the character %, each non-printing +# character, and each whitespace character must be replaced by %XX, +# where XX is the corresponding ASCII hexadecimal character value. The +# hexadecimal codes can be specified in any case (upper, lower, mixed). +# +# The Postfix client always encodes a request. +# The server may omit the encoding as long as the reply +# is guaranteed to not contain the % or NEWLINE character. +# SECURITY +# .ad +# .fi +# Do not use TCP lookup tables for security critical purposes. +# The client-server connection is not protected and the server +# is not authenticated. +# BUGS +# Only the lookup method is currently implemented. +# +# The client does not hang up when the connection is idle for +# a long time. +# SEE ALSO +# postmap(1), Postfix lookup table manager +# regexp_table(5), format of regular expression tables +# pcre_table(5), format of PCRE tables +# cidr_table(5), format of CIDR tables +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# DATABASE_README, Postfix lookup table overview +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# AUTHOR(S) +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#--*/ diff --git a/proto/transport b/proto/transport new file mode 100644 index 0000000..c5ffff2 --- /dev/null +++ b/proto/transport @@ -0,0 +1,306 @@ +#++ +# NAME +# transport 5 +# SUMMARY +# Postfix transport table format +# SYNOPSIS +# \fBpostmap /etc/postfix/transport\fR +# +# \fBpostmap -q "\fIstring\fB" /etc/postfix/transport\fR +# +# \fBpostmap -q - /etc/postfix/transport <\fIinputfile\fR +# DESCRIPTION +# The optional \fBtransport\fR(5) table specifies a mapping from email +# addresses to message delivery transports and next-hop destinations. +# Message delivery transports such as \fBlocal\fR or \fBsmtp\fR +# are defined in the \fBmaster.cf\fR file, and next-hop +# destinations are typically hosts or domain names. The +# table is searched by the \fBtrivial-rewrite\fR(8) daemon. +# +# This mapping overrides the default \fItransport\fR:\fInexthop\fR +# selection that is built into Postfix: +# .IP "\fBlocal_transport (default: local:$myhostname)\fR" +# This is the default for final delivery to domains listed +# with \fBmydestination\fR, and for [\fIipaddress\fR] +# destinations that match \fB$inet_interfaces\fR or +# \fB$proxy_interfaces\fR. The default \fInexthop\fR destination +# is the MTA hostname. +# .IP "\fBvirtual_transport (default: virtual:)\fR" +# This is the default for final delivery to domains listed +# with \fBvirtual_mailbox_domains\fR. The default \fInexthop\fR +# destination is the recipient domain. +# .IP "\fBrelay_transport (default: relay:)\fR" +# This is the default for remote delivery to domains listed +# with \fBrelay_domains\fR. In order of decreasing precedence, +# the \fInexthop\fR destination is taken from \fBrelay_transport\fR, +# \fBsender_dependent_relayhost_maps\fR, \fBrelayhost\fR, or from the +# recipient domain. +# .IP "\fBdefault_transport (default: smtp:)\fR" +# This is the default for remote delivery to other destinations. +# In order of decreasing precedence, the \fInexthop\fR +# destination is taken from \fBsender_dependent_default_transport_maps, +# \fBdefault_transport\fR, \fBsender_dependent_relayhost_maps\fR, +# \fBrelayhost\fR, or from the recipient domain. +# .PP +# Normally, the \fBtransport\fR(5) table is specified as a text file +# that serves as input to the \fBpostmap\fR(1) command. +# The result, an indexed file in \fBdbm\fR or \fBdb\fR format, is used +# for fast searching by the mail system. Execute the command +# "\fBpostmap /etc/postfix/transport\fR" to rebuild an indexed +# file after changing the corresponding transport table. +# +# When the table is provided via other means such as NIS, LDAP +# or SQL, the same lookups are done as for ordinary indexed files. +# +# Alternatively, the table can be provided as a regular-expression +# map where patterns are given as regular expressions, or lookups +# can be directed to a TCP-based server. In those case, the lookups +# are done in a slightly different way as described below under +# "REGULAR EXPRESSION TABLES" or "TCP-BASED TABLES". +# CASE FOLDING +# .ad +# .fi +# The search string is folded to lowercase before database +# lookup. As of Postfix 2.3, the search string is not case +# folded with database types such as regexp: or pcre: whose +# lookup fields can match both upper and lower case. +# TABLE FORMAT +# .ad +# .fi +# The input format for the \fBpostmap\fR(1) command is as follows: +# .IP "\fIpattern result\fR" +# When \fIpattern\fR matches the recipient address or domain, use the +# corresponding \fIresult\fR. +# .IP "blank lines and comments" +# Empty lines and whitespace-only lines are ignored, as +# are lines whose first non-whitespace character is a `#'. +# .IP "multi-line text" +# A logical line starts with non-whitespace text. A line that +# starts with whitespace continues a logical line. +# .PP +# The \fIpattern\fR specifies an email address, a domain name, or +# a domain name hierarchy, as described in section "TABLE +# SEARCH ORDER". +# +# The \fIresult\fR is of the form \fItransport:nexthop\fR and +# specifies how or where to deliver mail. This is described in +# section "RESULT FORMAT". +# TABLE SEARCH ORDER +# .ad +# .fi +# With lookups from indexed files such as DB or DBM, or from networked +# tables such as NIS, LDAP or SQL, patterns are tried in the order as +# listed below: +# .IP "\fIuser+extension@domain transport\fR:\fInexthop\fR" +# Deliver mail for \fIuser+extension@domain\fR through +# \fItransport\fR to +# \fInexthop\fR. +# .IP "\fIuser@domain transport\fR:\fInexthop\fR" +# Deliver mail for \fIuser@domain\fR through \fItransport\fR to +# \fInexthop\fR. +# .IP "\fIdomain transport\fR:\fInexthop\fR" +# Deliver mail for \fIdomain\fR through \fItransport\fR to +# \fInexthop\fR. +# .IP "\fI.domain transport\fR:\fInexthop\fR" +# Deliver mail for any subdomain of \fIdomain\fR through +# \fItransport\fR to \fInexthop\fR. This applies only when the +# string \fBtransport_maps\fR is not listed in the +# \fBparent_domain_matches_subdomains\fR configuration setting. +# Otherwise, a domain name matches itself and its subdomains. +# .IP "\fB*\fI transport\fR:\fInexthop\fR" +# The special pattern \fB*\fR represents any address (i.e. it +# functions as the wild-card pattern, and is unique to Postfix +# transport tables). +# .PP +# Note 1: the null recipient address is looked up as +# \fB$empty_address_recipient\fR@\fB$myhostname\fR (default: +# mailer-daemon@hostname). +# +# Note 2: \fIuser@domain\fR or \fIuser+extension@domain\fR +# lookup is available in Postfix 2.0 and later. +# RESULT FORMAT +# .ad +# .fi +# The lookup result is of the form \fItransport\fB:\fInexthop\fR. +# The \fItransport\fR field specifies a mail delivery transport +# such as \fBsmtp\fR or \fBlocal\fR. The \fInexthop\fR field +# specifies where and how to deliver mail. +# +# The transport field specifies the name of a mail delivery transport +# (the first name of a mail delivery service entry in the Postfix +# \fBmaster.cf\fR file). +# +# The nexthop field usually specifies one recipient domain +# or hostname. In the case of the Postfix SMTP/LMTP client, +# the nexthop field may contain a list of nexthop destinations +# separated by comma or whitespace (Postfix 3.5 and later). +# +# The syntax of a nexthop destination is transport dependent. +# With SMTP, specify a service on a non-default +# port as \fIhost\fR:\fIservice\fR, and disable MX (mail exchanger) +# DNS lookups with [\fIhost\fR] or [\fIhost\fR]:\fIport\fR. The [] form +# is required when you specify an IP address instead of a hostname. +# +# A null \fItransport\fR and null \fInexthop\fR field means "do +# not change": use the delivery transport and nexthop information +# that would be used when the entire transport table did not exist. +# +# A non-null \fItransport\fR field with a null \fInexthop\fR field +# resets the nexthop information to the recipient domain. +# +# A null \fItransport\fR field with non-null \fInexthop\fR field +# does not modify the transport information. +# EXAMPLES +# .ad +# .fi +# In order to deliver internal mail directly, while using a +# mail relay for all other mail, specify a null entry for +# internal destinations (do not change the delivery transport or +# the nexthop information) and specify a wildcard for all other +# destinations. +# +# .nf +# \fB\&my.domain :\fR +# \fB\&.my.domain :\fR +# \fB* smtp:outbound-relay.my.domain\fR +# .fi +# +# In order to send mail for \fBexample.com\fR and its subdomains +# via the \fBuucp\fR transport to the UUCP host named \fBexample\fR: +# +# .nf +# \fBexample.com uucp:example\fR +# \fB\&.example.com uucp:example\fR +# .fi +# +# When no nexthop host name is specified, the destination domain +# name is used instead. For example, the following directs mail for +# \fIuser\fR@\fBexample.com\fR via the \fBslow\fR transport to a mail +# exchanger for \fBexample.com\fR. The \fBslow\fR transport could be +# configured to run at most one delivery process at a time: +# +# .nf +# \fBexample.com slow:\fR +# .fi +# +# When no transport is specified, Postfix uses the transport that +# matches the address domain class (see DESCRIPTION +# above). The following sends all mail for \fBexample.com\fR and its +# subdomains to host \fBgateway.example.com\fR: +# +# .nf +# \fBexample.com :[gateway.example.com]\fR +# \fB\&.example.com :[gateway.example.com]\fR +# .fi +# +# In the above example, the [] suppress MX lookups. +# This prevents mail routing loops when your machine is primary MX +# host for \fBexample.com\fR. +# +# In the case of delivery via SMTP or LMTP, one may specify +# \fIhost\fR:\fIservice\fR instead of just a host: +# +# .nf +# \fBexample.com smtp:bar.example:2025\fR +# .fi +# +# This directs mail for \fIuser\fR@\fBexample.com\fR to host \fBbar.example\fR +# port \fB2025\fR. Instead of a numerical port a symbolic name may be +# used. Specify [] around the hostname if MX lookups must be disabled. +# +# Deliveries via SMTP or LMTP support multiple destinations +# (Postfix >= 3.5): +# +# .nf +# \fBexample.com smtp:bar.example, foo.example\fR +# .fi +# +# This tries to deliver to \fBbar.example\fR before trying +# to deliver to \fBfoo.example\fR. +# +# The error mailer can be used to bounce mail: +# +# .nf +# \fB\&.example.com error:mail for *.example.com is not deliverable\fR +# .fi +# +# This causes all mail for \fIuser\fR@\fIanything\fB.example.com\fR +# to be bounced. +# REGULAR EXPRESSION TABLES +# .ad +# .fi +# This section describes how the table lookups change when the table +# is given in the form of regular expressions. For a description of +# regular expression lookup table syntax, see \fBregexp_table\fR(5) +# or \fBpcre_table\fR(5). +# +# Each pattern is a regular expression that is applied to the entire +# address being looked up. Thus, \fIsome.domain.hierarchy\fR is not +# looked up via its parent domains, +# nor is \fIuser+foo@domain\fR looked up as \fIuser@domain\fR. +# +# Patterns are applied in the order as specified in the table, until a +# pattern is found that matches the search string. +# +# The \fBtrivial-rewrite\fR(8) server disallows regular +# expression substitution of $1 etc. in regular expression +# lookup tables, because that could open a security hole +# (Postfix version 2.3 and later). +# TCP-BASED TABLES +# .ad +# .fi +# This section describes how the table lookups change when lookups +# are directed to a TCP-based server. For a description of the TCP +# client/server lookup protocol, see \fBtcp_table\fR(5). +# This feature is not available up to and including Postfix version 2.4. +# +# Each lookup operation uses the entire recipient address once. Thus, +# \fIsome.domain.hierarchy\fR is not looked up via its parent domains, +# nor is \fIuser+foo@domain\fR looked up as \fIuser@domain\fR. +# +# Results are the same as with indexed file lookups. +# CONFIGURATION PARAMETERS +# .ad +# .fi +# The following \fBmain.cf\fR parameters are especially relevant. +# The text below provides only a parameter summary. See +# \fBpostconf\fR(5) for more details including examples. +# .IP "\fBempty_address_recipient (MAILER-DAEMON)\fR" +# The recipient of mail addressed to the null address. +# .IP "\fBparent_domain_matches_subdomains (see 'postconf -d' output)\fR" +# A list of Postfix features where the pattern "example.com" also +# matches subdomains of example.com, +# instead of requiring an explicit ".example.com" pattern. +# .IP "\fBtransport_maps (empty)\fR" +# Optional lookup tables with mappings from recipient address to +# (message delivery transport, next-hop destination). +# SEE ALSO +# trivial-rewrite(8), rewrite and resolve addresses +# master(5), master.cf file format +# postconf(5), configuration parameters +# postmap(1), Postfix lookup table manager +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# ADDRESS_REWRITING_README, address rewriting guide +# DATABASE_README, Postfix lookup table overview +# FILTER_README, external content filter +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# AUTHOR(S) +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- diff --git a/proto/virtual b/proto/virtual new file mode 100644 index 0000000..84edde4 --- /dev/null +++ b/proto/virtual @@ -0,0 +1,302 @@ +#++ +# NAME +# virtual 5 +# SUMMARY +# Postfix virtual alias table format +# SYNOPSIS +# \fBpostmap /etc/postfix/virtual\fR +# +# \fBpostmap -q "\fIstring\fB" /etc/postfix/virtual\fR +# +# \fBpostmap -q - /etc/postfix/virtual <\fIinputfile\fR +# DESCRIPTION +# The optional \fBvirtual\fR(5) alias table rewrites recipient +# addresses for all local, all virtual, and all remote mail +# destinations. +# This is unlike the \fBaliases\fR(5) table which is used +# only for \fBlocal\fR(8) delivery. Virtual aliasing is +# recursive, and is implemented by the Postfix \fBcleanup\fR(8) +# daemon before mail is queued. +# +# The main applications of virtual aliasing are: +# .IP \(bu +# To redirect mail for one address to one or more addresses. +# .IP \(bu +# To implement virtual alias domains where all addresses are aliased +# to addresses in other domains. +# .sp +# Virtual alias domains are not to be confused with the virtual mailbox +# domains that are implemented with the Postfix \fBvirtual\fR(8) mail +# delivery agent. With virtual mailbox domains, each recipient address +# can have its own mailbox. +# .PP +# Virtual aliasing is applied only to recipient +# envelope addresses, and does not affect message headers. +# Use \fBcanonical\fR(5) +# mapping to rewrite header and envelope addresses in general. +# +# Normally, the \fBvirtual\fR(5) alias table is specified as a text file +# that serves as input to the \fBpostmap\fR(1) command. +# The result, an indexed file in \fBdbm\fR or \fBdb\fR format, +# is used for fast searching by the mail system. Execute the command +# "\fBpostmap /etc/postfix/virtual\fR" to rebuild an indexed +# file after changing the corresponding text file. +# +# When the table is provided via other means such as NIS, LDAP +# or SQL, the same lookups are done as for ordinary indexed files. +# +# Alternatively, the table can be provided as a regular-expression +# map where patterns are given as regular expressions, or lookups +# can be directed to a TCP-based server. In those case, the lookups +# are done in a slightly different way as described below under +# "REGULAR EXPRESSION TABLES" or "TCP-BASED TABLES". +# CASE FOLDING +# .ad +# .fi +# The search string is folded to lowercase before database +# lookup. As of Postfix 2.3, the search string is not case +# folded with database types such as regexp: or pcre: whose +# lookup fields can match both upper and lower case. +# TABLE FORMAT +# .ad +# .fi +# The input format for the \fBpostmap\fR(1) command is as follows: +# .IP "\fIpattern address, address, ...\fR" +# When \fIpattern\fR matches a mail address, replace it by the +# corresponding \fIaddress\fR. +# .IP "blank lines and comments" +# Empty lines and whitespace-only lines are ignored, as +# are lines whose first non-whitespace character is a `#'. +# .IP "multi-line text" +# A logical line starts with non-whitespace text. A line that +# starts with whitespace continues a logical line. +# TABLE SEARCH ORDER +# .ad +# .fi +# With lookups from indexed files such as DB or DBM, or from networked +# tables such as NIS, LDAP or SQL, each \fIuser\fR@\fIdomain\fR +# query produces a sequence of query patterns as described below. +# +# Each query pattern is sent to each specified lookup table +# before trying the next query pattern, until a match is +# found. +# .IP "\fIuser\fR@\fIdomain address, address, ...\fR" +# Redirect mail for \fIuser\fR@\fIdomain\fR to \fIaddress\fR. +# This form has the highest precedence. +# .IP "\fIuser address, address, ...\fR" +# Redirect mail for \fIuser\fR@\fIsite\fR to \fIaddress\fR when +# \fIsite\fR is equal to $\fBmyorigin\fR, when \fIsite\fR is listed in +# $\fBmydestination\fR, or when it is listed in $\fBinet_interfaces\fR +# or $\fBproxy_interfaces\fR. +# .sp +# This functionality overlaps with the functionality of the local +# \fIaliases\fR(5) database. The difference is that \fBvirtual\fR(5) +# mapping can be applied to non-local addresses. +# .IP "@\fIdomain address, address, ...\fR" +# Redirect mail for other users in \fIdomain\fR to \fIaddress\fR. +# This form has the lowest precedence. +# .sp +# Note: @\fIdomain\fR is a wild-card. With this form, the +# Postfix SMTP server accepts +# mail for any recipient in \fIdomain\fR, regardless of whether +# that recipient exists. This may turn your mail system into +# a backscatter source: Postfix first accepts mail for +# non-existent recipients and then tries to return that mail +# as "undeliverable" to the often forged sender address. +# .sp +# To avoid backscatter with mail for a wild-card domain, +# replace the wild-card mapping with explicit 1:1 mappings, +# or add a reject_unverified_recipient restriction for that +# domain: +# +# .nf +# smtpd_recipient_restrictions = +# ... +# reject_unauth_destination +# check_recipient_access +# inline:{example.com=reject_unverified_recipient} +# unverified_recipient_reject_code = 550 +#.fi +# +# In the above example, Postfix may contact a remote server +# if the recipient is aliased to a remote address. +# RESULT ADDRESS REWRITING +# .ad +# .fi +# The lookup result is subject to address rewriting: +# .IP \(bu +# When the result has the form @\fIotherdomain\fR, the +# result becomes the same \fIuser\fR in \fIotherdomain\fR. +# This works only for the first address in a multi-address +# lookup result. +# .IP \(bu +# When "\fBappend_at_myorigin=yes\fR", append "\fB@$myorigin\fR" +# to addresses without "@domain". +# .IP \(bu +# When "\fBappend_dot_mydomain=yes\fR", append +# "\fB.$mydomain\fR" to addresses without ".domain". +# ADDRESS EXTENSION +# .fi +# .ad +# When a mail address localpart contains the optional recipient delimiter +# (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes: +# \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR, +# \fIuser\fR, and @\fIdomain\fR. +# +# The \fBpropagate_unmatched_extensions\fR parameter controls whether +# an unmatched address extension (\fI+foo\fR) is propagated to the +# result of a table lookup. +# VIRTUAL ALIAS DOMAINS +# .ad +# .fi +# Besides virtual aliases, the virtual alias table can also be used +# to implement virtual alias domains. With a virtual alias domain, all +# recipient addresses are aliased to addresses in other domains. +# +# Virtual alias domains are not to be confused with the virtual mailbox +# domains that are implemented with the Postfix \fBvirtual\fR(8) mail +# delivery agent. With virtual mailbox domains, each recipient address +# can have its own mailbox. +# +# With a virtual alias domain, the virtual domain has its +# own user name space. Local (i.e. non-virtual) usernames are not +# visible in a virtual alias domain. In particular, local +# \fBaliases\fR(5) and local mailing lists are not visible as +# \fIlocalname@virtual-alias.domain\fR. +# +# Support for a virtual alias domain looks like: +# +# .nf +# /etc/postfix/main.cf: +# virtual_alias_maps = hash:/etc/postfix/virtual +# .fi +# +# Note: some systems use \fBdbm\fR databases instead of \fBhash\fR. +# See the output from "\fBpostconf -m\fR" for available database types. +# +# .nf +# /etc/postfix/virtual: +# \fIvirtual-alias.domain anything\fR (right-hand content does not matter) +# \fIpostmaster@virtual-alias.domain postmaster\fR +# \fIuser1@virtual-alias.domain address1\fR +# \fIuser2@virtual-alias.domain address2, address3\fR +# .fi +# .sp +# The \fIvirtual-alias.domain anything\fR entry is required for a +# virtual alias domain. \fBWithout this entry, mail is rejected +# with "relay access denied", or bounces with +# "mail loops back to myself".\fR +# +# Do not specify virtual alias domain names in the \fBmain.cf +# mydestination\fR or \fBrelay_domains\fR configuration parameters. +# +# With a virtual alias domain, the Postfix SMTP server +# accepts mail for \fIknown-user@virtual-alias.domain\fR, and rejects +# mail for \fIunknown-user\fR@\fIvirtual-alias.domain\fR as undeliverable. +# +# Instead of specifying the virtual alias domain name via +# the \fBvirtual_alias_maps\fR table, you may also specify it via +# the \fBmain.cf virtual_alias_domains\fR configuration parameter. +# This latter parameter uses the same syntax as the \fBmain.cf +# mydestination\fR configuration parameter. +# REGULAR EXPRESSION TABLES +# .ad +# .fi +# This section describes how the table lookups change when the table +# is given in the form of regular expressions. For a description of +# regular expression lookup table syntax, see \fBregexp_table\fR(5) +# or \fBpcre_table\fR(5). +# +# Each pattern is a regular expression that is applied to the entire +# address being looked up. Thus, \fIuser@domain\fR mail addresses are not +# broken up into their \fIuser\fR and \fI@domain\fR constituent parts, +# nor is \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR. +# +# Patterns are applied in the order as specified in the table, until a +# pattern is found that matches the search string. +# +# Results are the same as with indexed file lookups, with +# the additional feature that parenthesized substrings from the +# pattern can be interpolated as \fB$1\fR, \fB$2\fR and so on. +# TCP-BASED TABLES +# .ad +# .fi +# This section describes how the table lookups change when lookups +# are directed to a TCP-based server. For a description of the TCP +# client/server lookup protocol, see \fBtcp_table\fR(5). +# This feature is available in Postfix 2.5 and later. +# +# Each lookup operation uses the entire address once. Thus, +# \fIuser@domain\fR mail addresses are not broken up into their +# \fIuser\fR and \fI@domain\fR constituent parts, nor is +# \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR. +# +# Results are the same as with indexed file lookups. +# BUGS +# The table format does not understand quoting conventions. +# CONFIGURATION PARAMETERS +# .ad +# .fi +# The following \fBmain.cf\fR parameters are especially relevant to +# this topic. See the Postfix \fBmain.cf\fR file for syntax details +# and for default values. Use the "\fBpostfix reload\fR" command after +# a configuration change. +# .IP "\fBvirtual_alias_maps ($virtual_maps)\fR" +# Optional lookup tables that alias specific mail addresses or domains +# to other local or remote addresses. +# .IP "\fBvirtual_alias_domains ($virtual_alias_maps)\fR" +# Postfix is the final destination for the specified list of virtual +# alias domains, that is, domains for which all addresses are aliased +# to addresses in other local or remote domains. +# .IP "\fBpropagate_unmatched_extensions (canonical, virtual)\fR" +# What address lookup tables copy an address extension from the lookup +# key to the lookup result. +# .PP +# Other parameters of interest: +# .IP "\fBinet_interfaces (all)\fR" +# The network interface addresses that this mail system receives +# mail on. +# .IP "\fBmydestination ($myhostname, localhost.$mydomain, localhost)\fR" +# The list of domains that are delivered via the $local_transport +# mail delivery transport. +# .IP "\fBmyorigin ($myhostname)\fR" +# The domain name that locally-posted mail appears to come +# from, and that locally posted mail is delivered to. +# .IP "\fBowner_request_special (yes)\fR" +# Enable special treatment for owner-\fIlistname\fR entries in the +# \fBaliases\fR(5) file, and don't split owner-\fIlistname\fR and +# \fIlistname\fR-request address localparts when the recipient_delimiter +# is set to "-". +# .IP "\fBproxy_interfaces (empty)\fR" +# The network interface addresses that this mail system receives mail +# on by way of a proxy or network address translation unit. +# SEE ALSO +# cleanup(8), canonicalize and enqueue mail +# postmap(1), Postfix lookup table manager +# postconf(5), configuration parameters +# canonical(5), canonical address mapping +# README FILES +# .ad +# .fi +# Use "\fBpostconf readme_directory\fR" or +# "\fBpostconf html_directory\fR" to locate this information. +# .na +# .nf +# ADDRESS_REWRITING_README, address rewriting guide +# DATABASE_README, Postfix lookup table overview +# VIRTUAL_README, domain hosting guide +# LICENSE +# .ad +# .fi +# The Secure Mailer license must be distributed with this software. +# AUTHOR(S) +# Wietse Venema +# IBM T.J. Watson Research +# P.O. Box 704 +# Yorktown Heights, NY 10598, USA +# +# Wietse Venema +# Google, Inc. +# 111 8th Avenue +# New York, NY 10011, USA +#-- |