<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://commons.oreilly.com/wiki/skins/common/feed.css?97"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>SpamAssassin/Integrating SpamAssassinwith Postfix - Revision history</title>
		<link>http://commons.oreilly.com/wiki/index.php?title=SpamAssassin/Integrating_SpamAssassinwith_Postfix&amp;action=history</link>
		<description>Revision history for this page on the wiki</description>
		<language>en</language>
		<generator>MediaWiki 1.11.0</generator>
		<lastBuildDate>Fri, 24 May 2013 19:12:44 GMT</lastBuildDate>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SpamAssassin/Integrating_SpamAssassinwith_Postfix&amp;diff=5285&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 10:56, 7 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 648:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 648:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;This variable can be defined on a per-recipient basis much like &amp;lt;tt&amp;gt;$per_recip_blacklist_sender_lookup_tables&amp;lt;/tt&amp;gt;. Set &amp;lt;tt&amp;gt;$sa_tag_level_deflt&amp;lt;/tt&amp;gt; to a reference to a hash keyed on recipient addresses, with the tag level as the hash value.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;This variable can be defined on a per-recipient basis much like &amp;lt;tt&amp;gt;$per_recip_blacklist_sender_lookup_tables&amp;lt;/tt&amp;gt;. Set &amp;lt;tt&amp;gt;$sa_tag_level_deflt&amp;lt;/tt&amp;gt; to a reference to a hash keyed on recipient addresses, with the tag level as the hash value.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/dl&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/dl&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;dl&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;dl&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;dt&amp;gt;&amp;lt;tt&amp;gt;$sa_tag2_level_deflt&amp;lt;/tt&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;dt&amp;gt;&amp;lt;tt&amp;gt;$sa_tag2_level_deflt&amp;lt;/tt&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 654:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 655:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;This variable can be defined on a per-recipient basis much like &amp;lt;tt&amp;gt;$per_recip_blacklist_sender_lookup_tables&amp;lt;/tt&amp;gt;. Set &amp;lt;tt&amp;gt;$sa_tag2_level_deflt&amp;lt;/tt&amp;gt; to a reference to a hash keyed on recipient addresses, with the tag2 level as the hash value.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;This variable can be defined on a per-recipient basis much like &amp;lt;tt&amp;gt;$per_recip_blacklist_sender_lookup_tables&amp;lt;/tt&amp;gt;. Set &amp;lt;tt&amp;gt;$sa_tag2_level_deflt&amp;lt;/tt&amp;gt; to a reference to a hash keyed on recipient addresses, with the tag2 level as the hash value.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/dl&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/dl&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;dl&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;dl&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;dt&amp;gt;&amp;lt;tt&amp;gt;$sa_kill_level_deflt&amp;lt;/tt&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;dt&amp;gt;&amp;lt;tt&amp;gt;$sa_kill_level_deflt&amp;lt;/tt&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 659:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 661:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The variable can be defined on a per-recipient basis much like &amp;lt;tt&amp;gt;$per_recip_blacklist_sender_lookup_tables&amp;lt;/tt&amp;gt;. Set &amp;lt;tt&amp;gt;$sa_kill_level_deflt&amp;lt;/tt&amp;gt; to a reference to a hash keyed on recipient addresses, with the kill level as the hash value.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;The variable can be defined on a per-recipient basis much like &amp;lt;tt&amp;gt;$per_recip_blacklist_sender_lookup_tables&amp;lt;/tt&amp;gt;. Set &amp;lt;tt&amp;gt;$sa_kill_level_deflt&amp;lt;/tt&amp;gt; to a reference to a hash keyed on recipient addresses, with the kill level as the hash value.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/dl&amp;gt;;&amp;lt;tt&amp;gt;$sa_spam_modifies_subj&amp;lt;/tt&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/dl&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;;&amp;lt;tt&amp;gt;$sa_spam_modifies_subj&amp;lt;/tt&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;: If this variable is set to 1, &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; may modify the ''Subject'' header of messages with spam scores above the &amp;lt;tt&amp;gt;$sa_tag2_level_dflt&amp;lt;/tt&amp;gt; setting. You can also set this variable to a reference to a list of recipients who should have their ''Subject'' headers modified, a reference to a hash table keyed on recipients who should have their headers modified (with hash values of 1), or the return value of a &amp;lt;tt&amp;gt;new_RE( )&amp;lt;/tt&amp;gt; call on a list of regular expressions to match against recipients who should have their headers modified. This variable is not defined by default.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;: If this variable is set to 1, &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; may modify the ''Subject'' header of messages with spam scores above the &amp;lt;tt&amp;gt;$sa_tag2_level_dflt&amp;lt;/tt&amp;gt; setting. You can also set this variable to a reference to a list of recipients who should have their ''Subject'' headers modified, a reference to a hash table keyed on recipients who should have their headers modified (with hash values of 1), or the return value of a &amp;lt;tt&amp;gt;new_RE( )&amp;lt;/tt&amp;gt; call on a list of regular expressions to match against recipients who should have their headers modified. This variable is not defined by default.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;;&amp;lt;tt&amp;gt;$sa_spam_subject_tag&amp;lt;/tt&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;;&amp;lt;tt&amp;gt;$sa_spam_subject_tag&amp;lt;/tt&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key wikicontent:diff:version:1.11a:oldid:5231:newid:5285 --&gt;
&lt;/table&gt;</description>
			<pubDate>Fri, 07 Mar 2008 10:56:42 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SpamAssassin/Integrating_SpamAssassinwith_Postfix</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SpamAssassin/Integrating_SpamAssassinwith_Postfix&amp;diff=5231&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{SpamAssassin/TOC}}&lt;br /&gt;
Postfix is a mail transport agent written by security researcher Wietse Venema. Not surprisingly, Postfix is designed from the ground up to be a highly secure system. It consists of several components, each of which runs with least privilege and none of which trust data from the other without validating it themselves. Despite the extensive security emphasis in the system's architecture, Postfix is capable of very good performance in normal conditions; because of architectural decisions, it is also fault tolerant and capable of good performance under adverse conditions such as resource starvation. It has become a popular replacement for sendmail because it provides a compatible command-line interface.&lt;br /&gt;
&lt;br /&gt;
This chapter explains how to integrate SpamAssassin into a Postfix-based mail server to perform spam-checking for local recipients or to create a spam-checking mail gateway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Warning'''&lt;br /&gt;
&lt;br /&gt;
Postfix is a complex piece of software, and, like most MTAs, offers scores of configuration options. This chapter assumes that you are running Postfix 1.1 or 2.x (recommended) and does not cover how to securely install, configure, or operate Postfix itself. For that information, see the Postfix documentation and the book ''Postfix: The Definitive Guide'' by Kyle D. Dent (O'Reilly).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Postfix Architecture ==&lt;br /&gt;
&lt;br /&gt;
Several different Postfix components play roles in receiving messages from the Internet. The &amp;lt;tt&amp;gt;master&amp;lt;/tt&amp;gt; daemon is responsible for the coordination of the components. Messages from the Internet typically enter the mail server via the &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; daemon, which listens on port 25 and conducts the SMTP transaction with the remote sender. &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; passes each message to the &amp;lt;tt&amp;gt;cleanup&amp;lt;/tt&amp;gt; daemon, which performs sanity checks, fixes missing headers, and (with the help of the trivial-rewrite program) rewrites addresses. &amp;lt;tt&amp;gt;cleanup&amp;lt;/tt&amp;gt; then deposits each message in the incoming mail queue and alerts the &amp;lt;tt&amp;gt;qmgr&amp;lt;/tt&amp;gt; daemon. &amp;lt;tt&amp;gt;qmgr&amp;lt;/tt&amp;gt; moves messages from the incoming queue to the active queue, and then calls &amp;lt;tt&amp;gt;local&amp;lt;/tt&amp;gt; for delivery to local recipients (or &amp;lt;tt&amp;gt;smtp&amp;lt;/tt&amp;gt; for relaying to remote recipients by SMTP). [[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-FIG-1|Figure 6-1]] illustrates the flow of email through Postfix components.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;spamassassin-CHP-6-FIG-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 6-1. The Postfix architecture during message receipt'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SpamAssassin_I_6_tt91.png|The Postfix architecture during message receipt]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Most systems keep Postfix's configuration files in ''/etc/postfix''. The most important files are ''main.cf'', which contains nearly all of the configuration directives for Postfix, and ''master.cf'', which configures the &amp;lt;tt&amp;gt;master&amp;lt;/tt&amp;gt; daemon and determines how the various Postfix components will be run. After you make changes to either of these files, you should issue the &amp;lt;tt&amp;gt;postfix reload&amp;lt;/tt&amp;gt; command to cause Postfix to re-read the files.&lt;br /&gt;
&lt;br /&gt;
== Spam-Checking During Local Delivery ==&lt;br /&gt;
&lt;br /&gt;
The easiest way to add SpamAssassin to a Postfix system is to configure Postfix to use procmail as its local delivery agent, rather than the Postfix &amp;lt;tt&amp;gt;local&amp;lt;/tt&amp;gt; program. Then add a procmail recipe for spam-tagging to ''/etc/procmailrc''.&lt;br /&gt;
&lt;br /&gt;
The advantages of this approach are:&lt;br /&gt;
&lt;br /&gt;
* It's very easy to set up.&lt;br /&gt;
* You can run &amp;lt;tt&amp;gt;spamd&amp;lt;/tt&amp;gt;, and the procmail recipe can use &amp;lt;tt&amp;gt;spamc&amp;lt;/tt&amp;gt; for faster spam-checking.&lt;br /&gt;
* User preference files, autowhitelists, and Bayesian databases can be used.&lt;br /&gt;
&lt;br /&gt;
However, Postfix runs a local delivery agent only for email destined for a local recipient. You cannot create a spam-checking gateway with this approach.&lt;br /&gt;
&lt;br /&gt;
Instructions for configuring procmail for spam-checking can be found in [[SpamAssassin/SpamAssassin Basics#spamassassin-CHP-2-EX-6|Example 2-6]] in [[SpamAssassin/SpamAssassin Basics|Chapter 2]]. To configure Postfix to use procmail as the local delivery agent, use the &amp;lt;tt&amp;gt;mailbox_command&amp;lt;/tt&amp;gt; directive in ''main.cf'':&lt;br /&gt;
&lt;br /&gt;
 mailbox_command = procmail -a &amp;quot;$EXTENSION&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Warning'''&lt;br /&gt;
&lt;br /&gt;
If you configure Postfix to use procmail as the local delivery agent, you must be sure that you have an alias for ''root'' in your ''aliases'' file (typically in ''/etc'' or ''/etx/postfix''). The alias should point to another local user. Without such an alias, Postfix may be unable to deliver mail to ''root'' using procmail.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Spam-Checking All Incoming Mail ==&lt;br /&gt;
&lt;br /&gt;
If you want to set up a spam-checking gateway for all recipients, local or not, you need a way to perform spam-checking as mail is received, before final delivery. Postfix provides a general-purpose filtering directive called &amp;lt;tt&amp;gt;content_filter&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;content_filter&amp;lt;/tt&amp;gt; directive specifies a mail transport that Postfix will invoke after receiving a message. The mail transport hands the message to a filtering program. The filter checks the message and then either refuses it (which will cause Postfix to generate a bounce message), discards it, or reinjects the (possibly modified) message into Postfix for further delivery. Messages that pass the filter are reinjected so that Postfix can operate on them almost as if they were new messages; this allows Postfix to behave properly if the content filter rewrites message headers. You can use the &amp;lt;tt&amp;gt;content_filter&amp;lt;/tt&amp;gt; directive in ''main.cf'', in which case the directive will be used by both &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; (for email received via SMTP) and &amp;lt;tt&amp;gt;pickup&amp;lt;/tt&amp;gt; (for email received locally). You can also specify &amp;lt;tt&amp;gt;content_filter&amp;lt;/tt&amp;gt; as an invocation option to &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;pickup&amp;lt;/tt&amp;gt;, which is useful when you only want to filter email received from outside (or inside) the system.&lt;br /&gt;
&lt;br /&gt;
Content filters can be programs that are invoked for each message. They read a message on standard input and reinject filtered messages via the &amp;lt;tt&amp;gt;sendmail&amp;lt;/tt&amp;gt; program. They can also be daemons that listen on a local TCP port, receiving messages via SMTP or LMTP (Local Mail Transfer Protocol), and reinjecting filtered messages via SMTP by communicating with a second instance of &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; listening on a local port.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
Don't confuse Postfix's &amp;lt;tt&amp;gt;sendmail&amp;lt;/tt&amp;gt; program with sendmail. sendmail is an entirely different MTA that also uses an executable named &amp;lt;tt&amp;gt;sendmail&amp;lt;/tt&amp;gt; to perform nearly all of its functions. Postfix's &amp;lt;tt&amp;gt;sendmail&amp;lt;/tt&amp;gt; program is much more limited but is designed to serve as a replacement for sendmail's to facilitate converting systems from sendmail to Postfix.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SpamAssassin itself is not suitable for use as a content filter, because it doesn't know how to reinject a tagged message. However, SpamAssassin can be invoked by a content filter in several ways.&lt;br /&gt;
&lt;br /&gt;
=== Using a Program as a Content Filter ===&lt;br /&gt;
&lt;br /&gt;
The simplest content filters are programs that accept messages on standard input, perform spam-checking, and either exit with an error status code or reinject the message to Postfix. When you use a program as a content filter, you do not need to run any additional daemons—Postfix invokes the program for each message. If your system receives a lot of mail, you are likely to get better performance by using a daemonized content filter, which is discussed in the next section.&lt;br /&gt;
&lt;br /&gt;
To use a program as a content filter requires a series of steps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;Create a new system user that Postfix will use to run the filter program or shell script. SpamAssassin will use this user's SpamAssassin preferences (in the ''.spamassassin/user_prefs'' file in their home directory) when checking messages that have multiple recipients. In the following steps, assume the user is named ''spamfilt''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;Create a program (or shell script) that can accept an email message on standard input, perform filtering, and pass the modified message to &amp;lt;tt&amp;gt;sendmail&amp;lt;/tt&amp;gt;'s standard input. The filter should also return an appropriate status code, usually the exit code from &amp;lt;tt&amp;gt;sendmail&amp;lt;/tt&amp;gt;, which Postfix will understand. Your program (or shell script) should expect to receive command-line arguments consisting of the sender's email address and a space-separated list of recipient email addresses.&lt;br /&gt;
&lt;br /&gt;
Here's an example of a filter script called &amp;lt;tt&amp;gt;pf-spamfilt&amp;lt;/tt&amp;gt; that calls SpamAssassin using &amp;lt;tt&amp;gt;spamc&amp;lt;/tt&amp;gt;. If the message being checked has only a single recipient, &amp;lt;tt&amp;gt;spamc&amp;lt;/tt&amp;gt;'s &amp;lt;tt&amp;gt;-u&amp;lt;/tt&amp;gt; option is used to load the per-user preferences. When the message has multiple recipients, the script runs &amp;lt;tt&amp;gt;spamc&amp;lt;/tt&amp;gt; without &amp;lt;tt&amp;gt;-u&amp;lt;/tt&amp;gt;, and, because the script will be running as the ''spamfilt'' user, &amp;lt;tt&amp;gt;spamc&amp;lt;/tt&amp;gt; will use ''spamfilt'''s preferences file.&lt;br /&gt;
&lt;br /&gt;
 #!/bin/sh&lt;br /&gt;
 #&lt;br /&gt;
 # pf-spamfilt: An example spam filtering script for postfix&lt;br /&gt;
 #&lt;br /&gt;
 sender=$1&lt;br /&gt;
 shift&lt;br /&gt;
 recip=&amp;quot;$@&amp;quot;&lt;br /&gt;
 if [ &amp;quot;$#&amp;quot; -eq 1 ]; then&lt;br /&gt;
   /usr/bin/spamc -u $recip&lt;br /&gt;
 else&lt;br /&gt;
   /usr/bin/spamc&lt;br /&gt;
 fi | /usr/sbin/sendmail -i -f $sender -- $recip&lt;br /&gt;
 exit $?&lt;br /&gt;
&lt;br /&gt;
Because this filter uses the &amp;lt;tt&amp;gt;spamc&amp;lt;/tt&amp;gt; client, you must be running a &amp;lt;tt&amp;gt;spamd&amp;lt;/tt&amp;gt; server. Save the filter somewhere publicly accessible (e.g., ''/usr/local/bin/pf-spamfilt'') and set its permissions to allow anyone to read and execute it.&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;Define a new mail transport in ''master.cf'' that invokes the filter you created in step 2. The following example shows how you add a transport called &amp;lt;tt&amp;gt;spamcheck&amp;lt;/tt&amp;gt;, defined as a Unix service. By defining the transport as shown, you specify that the mail transport will use Postfix's &amp;lt;tt&amp;gt;pipe&amp;lt;/tt&amp;gt; command to run ''/usr/local/bin/pf-spamfilt'' as user ''spamfilt'', and will pass the email address of the sender and the email addresses of recipients as command-line arguments to ''pf-spamfilt''. The flag argument includes the &amp;lt;tt&amp;gt;R&amp;lt;/tt&amp;gt; flag (add a ''Return-Path'' header) and the &amp;lt;tt&amp;gt;q&amp;lt;/tt&amp;gt; flag (quote the sender and recipient addresses for use in the command line).&lt;br /&gt;
&lt;br /&gt;
 # =========================================================================&lt;br /&gt;
 # service type  private unpriv  chroot  wakeup  maxproc command + args&lt;br /&gt;
 #               (yes)   (yes)   (yes)   (never) (50)&lt;br /&gt;
 # =========================================================================&lt;br /&gt;
 spamcheck  unix   -       n       n       -      -       pipe&lt;br /&gt;
   flags=Rq user=spamfilt argv=/usr/local/bin/pf-spamfilt ${sender} ${recipient}&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;Direct Postfix to use the new mail transport as a content filter for the &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; daemon. Replace this line in ''master.cf'':&lt;br /&gt;
&lt;br /&gt;
 smtp      inet  n       -       -       -       -       smtpd&lt;br /&gt;
&lt;br /&gt;
with these two lines:&lt;br /&gt;
&lt;br /&gt;
 smtp      inet  n       -       -       -       -       smtpd&lt;br /&gt;
   -o content_filter=spamcheck:&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;If you always want to use per-user preferences, instruct Postfix to call the &amp;lt;tt&amp;gt;spamcheck&amp;lt;/tt&amp;gt; transport with only a single recipient per message by adding this line to ''main.cf'':&lt;br /&gt;
&lt;br /&gt;
 spamcheck_destination_recipient_limit = 1&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;Run &amp;lt;tt&amp;gt;postfix reload&amp;lt;/tt&amp;gt; to re-read the configuration files. Test the system by sending an email from the Internet and see whether SpamAssassin is called to check the message.&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using a Daemon as a Content Filter ===&lt;br /&gt;
&lt;br /&gt;
Although it's more complicated to run a daemonized content filter, most larger sites will want to do so in order to avoid the overhead associated with starting the content filter for each email and running &amp;lt;tt&amp;gt;sendmail&amp;lt;/tt&amp;gt; for reinjection. In the daemonized approach, the filter listens on a TCP port bound to the loopback address (127.0.0.1). On receiving a message from the Internet, Postfix connects to the filter daemon and relays the message using the SMTP or LMTP protocol.&lt;br /&gt;
&lt;br /&gt;
The daemon can reject the message during the SMTP/LMTP transaction, which will cause Postfix to bounce the message, or the daemon can accept the message, modify it, and reinject it by SMTP. To prevent mail loops, Postfix must run a second &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; daemon, bound to another TCP port on the loopback address. The second &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; is configured to accept messages without rerunning the filter (or performing the checks that would normally be performed on a message received from the Internet).&lt;br /&gt;
&lt;br /&gt;
To use a daemon as a content filter requires five steps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;Install a daemon that performs content-filtering in the fashion that Postfix expects. [[SpamAssassin/Integrating SpamAssassinwith Postfix#Building a Spam-Checking Gateway|Section 6.4]] provides an example. Typically, you will need to know or configure:&lt;br /&gt;
&lt;br /&gt;
* The port on which the daemon accepts incoming messages to check (e.g., 10024).&lt;br /&gt;
* The protocol (SMTP or LMTP) by which the daemon expects to receive an incoming message.&lt;br /&gt;
* The port to which the daemon will connect to reinject a message to Postfix (e.g., 10025).&lt;br /&gt;
* The user that will run the daemon. Ideally, you should run daemons under a single-purpose, non-''root'' user.&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;Define a new mail transport in ''master.cf'' that sends mail to the daemon. In the following example, the transport is called &amp;lt;tt&amp;gt;spamcheck&amp;lt;/tt&amp;gt; and is defined as a Unix service that will use Postfix's &amp;lt;tt&amp;gt;smtp&amp;lt;/tt&amp;gt; command. You can use the &amp;lt;tt&amp;gt;disable_dns_lookups&amp;lt;/tt&amp;gt; option to save overhead, as you know that the transport will be configured to relay mail to your loopback IP address, so the daemon will never need to perform a DNS MX lookup. The example uses the maxproc feature in ''master.cf'' to limit the number of messages that can use this mail transport at one time to two.&lt;br /&gt;
&lt;br /&gt;
 # =========================================================================&lt;br /&gt;
 # service type  private unpriv  chroot  wakeup  maxproc command + args&lt;br /&gt;
 #               (yes)   (yes)   (yes)   (never) (50)&lt;br /&gt;
 # =========================================================================&lt;br /&gt;
 spamcheck  unix   -       -       n       -      2       smtp&lt;br /&gt;
   -o disable_dns_lookups=yes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
If you are using Postfix 2.0 or later, you can define the &amp;lt;tt&amp;gt;spamcheck&amp;lt;/tt&amp;gt; transport to use Postfix's &amp;lt;tt&amp;gt;lmtp&amp;lt;/tt&amp;gt; command instead of &amp;lt;tt&amp;gt;smtp&amp;lt;/tt&amp;gt;. The LMTP protocol has some advantages over SMTP—notably, LMTP servers (including &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt;) can return individual accept/refuse codes for each message recipient during an LMTP transaction. Postfix's &amp;lt;tt&amp;gt;lmtp&amp;lt;/tt&amp;gt; client can also cache connections to an LMTP server for greater performance. Bugs in the &amp;lt;tt&amp;gt;lmtp&amp;lt;/tt&amp;gt; client existed in Postfix versions earlier than 2.0 so using &amp;lt;tt&amp;gt;smtp&amp;lt;/tt&amp;gt; is recommended with these versions.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;Define a new mail transport that receives mail from the daemon in ''master.cf.'' This transport will use Postfix's &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; daemon and is defined by the IP address and port number on which it will listen (127.0.0.1 and 10025, respectively). &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; is an &amp;lt;tt&amp;gt;inet&amp;lt;/tt&amp;gt; service, and many option parameters are provided to prevent further filtering and to restrict access to this mail transport to the local host only. Here is an example of such a definition in ''master.cf'':&lt;br /&gt;
&lt;br /&gt;
 # =========================================================================&lt;br /&gt;
 # service type  private unpriv  chroot  wakeup  maxproc command + args&lt;br /&gt;
 #               (yes)   (yes)   (yes)   (never) (50)&lt;br /&gt;
 # =========================================================================&lt;br /&gt;
 127.0.0.1:10025  inet   n      -      n      -     -       smtpd&lt;br /&gt;
     -o content_filter=&lt;br /&gt;
     -o myhostname=localhost.''yourdomain''&lt;br /&gt;
     -o local_recipient_maps=&lt;br /&gt;
     -o relay_recipient_maps=&lt;br /&gt;
     -o smtpd_restriction_classes=&lt;br /&gt;
     -o smtpd_client_restrictions=&lt;br /&gt;
     -o smtpd_helo_restrictions=&lt;br /&gt;
     -o smtpd_sender_restrictions=&lt;br /&gt;
     -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
     -o mynetworks=127.0.0.0/8&lt;br /&gt;
     -o strict_rfc821_envelopes=yes&lt;br /&gt;
     -o smtpd_error_sleep_time=0&lt;br /&gt;
     -o smtpd_soft_error_limit=1001&lt;br /&gt;
     -o smtpd_hard_error_limit=1000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Warning'''&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;-o myhostname=localhost&amp;lt;/tt&amp;gt;.&amp;lt;tt&amp;gt;''yourdomain''&amp;lt;/tt&amp;gt; option is important if the content filter issues the SMTP HELO command with the same hostname that it originally received from Postfix. If Postfix sees a HELO from itself, it rejects the connection to avoid a mail loop. By telling the new &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; that its hostname is something else, you prevent this problem.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;Direct Postfix to the use the daemon's mail transport as a content filter for mail received by the primary &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; daemon. Replace this line in ''master.cf'':&lt;br /&gt;
&lt;br /&gt;
 smtp      inet  n       -       -       -       -       smtpd&lt;br /&gt;
&lt;br /&gt;
with these two lines:&lt;br /&gt;
&lt;br /&gt;
 smtp      inet  n       -       -       -       2       smtpd&lt;br /&gt;
   -o content_filter=spamcheck:[127.0.0.1]:10024&lt;br /&gt;
&lt;br /&gt;
The primary &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; daemon will filter incoming messages by passing them to the &amp;lt;tt&amp;gt;spamcheck&amp;lt;/tt&amp;gt; mail transport that is listening on port 10024 of the loopback address 127.0.0.1.&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;Run &amp;lt;tt&amp;gt;postfix reload&amp;lt;/tt&amp;gt; to re-read the configuration files. Test the system by sending email from the Internet.&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-FIG-2|Figure 6-2]] illustrates this configuration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;spamassassin-CHP-6-FIG-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 6-2. Postfix with a daemonized content filter'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SpamAssassin_I_6_tt102.png|Postfix with a daemonized content filter]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Filtering Before Address-Rewriting ===&lt;br /&gt;
&lt;br /&gt;
The Postfix queue manager invokes content filters once it has queued a message. A potential problem with the simple content-filtering approaches outlined earlier is that the messages to be filtered have passed through the &amp;lt;tt&amp;gt;cleanup&amp;lt;/tt&amp;gt; service on their way to the queue, and &amp;lt;tt&amp;gt;cleanup&amp;lt;/tt&amp;gt; performs virtual address lookups and address canonicalization—that is, &amp;lt;tt&amp;gt;cleanup&amp;lt;/tt&amp;gt; may rewrite addresses in message headers. Accordingly, the message that Postfix sends to the content filter (and thus to SpamAssassin) to check is not exactly the same as the message that Postfix received. The changes to addresses may rob SpamAssassin's rules (or the Bayesian classifier) of useful determinants of spam.&lt;br /&gt;
&lt;br /&gt;
If you are running Postfix 2.0 or later, you can fix this problem by setting up a separate, &amp;lt;tt&amp;gt;pre-cleanup&amp;lt;/tt&amp;gt; service that does not perform address canonicalization. Messages received by Postfix's &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pickup&amp;lt;/tt&amp;gt; can be routed through the &amp;lt;tt&amp;gt;pre-cleanup&amp;lt;/tt&amp;gt; and then to the queue. Filter-checked messages received by the second &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; instance can then be routed through the standard &amp;lt;tt&amp;gt;cleanup&amp;lt;/tt&amp;gt; service for address-rewriting before returning to the queue for further delivery processing.&lt;br /&gt;
&lt;br /&gt;
To use a two-cleanup design, set up a daemonized filter configuration as described in the previous section and then make the following configuration changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;Add a new &amp;lt;tt&amp;gt;pre-cleanup&amp;lt;/tt&amp;gt; service to ''/etc/postfix/master.cf'' that calls the &amp;lt;tt&amp;gt;cleanup&amp;lt;/tt&amp;gt; daemon but turns off address canonicalization:&lt;br /&gt;
&lt;br /&gt;
 pre-cleanup         unix  n      -      n      -       0      cleanup&lt;br /&gt;
         -o canonical_maps=&lt;br /&gt;
         -o sender_canonical_maps=&lt;br /&gt;
         -o recipient_canonical_maps=&lt;br /&gt;
         -o masquerade_domains=&lt;br /&gt;
         -o virtual_alias_maps=&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;Configure &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pickup&amp;lt;/tt&amp;gt; to use the &amp;lt;tt&amp;gt;pre-cleanup&amp;lt;/tt&amp;gt; service in ''/etc/postfix/master.cf'' by changing their entries from&lt;br /&gt;
&lt;br /&gt;
 smtp      inet  n       -       -       -       -       smtpd&lt;br /&gt;
 pickup    fifo  n       -       -       60      1       pickup&lt;br /&gt;
&lt;br /&gt;
to&lt;br /&gt;
&lt;br /&gt;
 smtp      inet  n       -       -       -       -       smtpd&lt;br /&gt;
   -o cleanup_service_name=pre-cleanup&lt;br /&gt;
 pickup    fifo  n       -       -       60      1       pickup&lt;br /&gt;
   -o cleanup_service_name=pre-cleanup&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;div&amp;gt;To improve performance, modify the entry for &amp;lt;tt&amp;gt;cleanup&amp;lt;/tt&amp;gt; so that it does not perform some of the message checks that will have already been handled by &amp;lt;tt&amp;gt;pre-cleanup&amp;lt;/tt&amp;gt;. You can turn off any checks that would have already been performed on message headers (via the Postfix &amp;lt;tt&amp;gt;header_checks&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;mime_header_checks&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;nested_header_checks&amp;lt;/tt&amp;gt; options) or bodies (via the Postfix &amp;lt;tt&amp;gt;body_checks&amp;lt;/tt&amp;gt; options) by defining each option to be empty:&lt;br /&gt;
&lt;br /&gt;
 cleanup            unix  n      -      n      -       0      cleanup&lt;br /&gt;
     -o header_checks=&lt;br /&gt;
     -o mime_header_checks=&lt;br /&gt;
     -o nested_header_checks=&lt;br /&gt;
     -o body_checks=&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-FIG-3|Figure 6-3]] illustrates this configuration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;spamassassin-CHP-6-FIG-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 6-3. Postfix with a daemonized content filter and two cleanup services'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SpamAssassin_I_6_tt107.png|Postfix with a daemonized content filter and two cleanup services]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Building a Spam-Checking Gateway ==&lt;br /&gt;
&lt;br /&gt;
Several content-filtering daemons that call SpamAssassin are available for Postfix. This section provides a complete sample installation of amavisd-new, a particularly efficient filter that supports both spam-checking and virus-checking. amavisd-new is written in Perl and available at ''http://www.ijs.si/software/amavisd/''. The version used in this chapter's example is 20030616-p9, which supports both SpamAssassin 2.63 and SpamAssassin 3.0.&lt;br /&gt;
&lt;br /&gt;
amavisd-new is based on amavis, another virus-scanning package that is also actively developed and widely used. Although amavisd-new's most important program is also named &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt;, amavisd-new has developed separately and is a significantly different package. Some of amavisd-new's features include:&lt;br /&gt;
&lt;br /&gt;
* avisd-new was specifically developed and tested for Postfix as a daemonized content filter.&lt;br /&gt;
* Messages can be rejected based on MIME type or extensions of attached filenames.&lt;br /&gt;
* Messages can be checked with multiple virus scanners, and messages carrying viruses can be refused, discarded, or quarantined.&lt;br /&gt;
* SpamAssassin can be invoked on a message, and spam can be refused, discarded, quarantined, or tagged.&lt;br /&gt;
* Per-user configuration of amavisd-new is possible through an SQL or LDAP database.&lt;br /&gt;
&lt;br /&gt;
The rest of this chapter details the installation, configuration, and operation of amavisd-new as an example of a full-scale, daemonized, content filter approach to using SpamAssassin with Postfix. amavisd-new's other functions, such as virus-checking, are mentioned but not covered in detail; read the documentation to learn more about these other amavisd-new features.&lt;br /&gt;
&lt;br /&gt;
=== Installing amavisd-new ===&lt;br /&gt;
&lt;br /&gt;
amavisd-new is written in Perl, and invokes SpamAssassin through the ''Mail::SpamAssassin'' Perl modules. Because amavisd-new itself is a daemon, you do not need to run &amp;lt;tt&amp;gt;spamd&amp;lt;/tt&amp;gt;. It's easiest to install SpamAssassin (and your antivirus software) first, and then install amavisd-new. amavisd-new also requires several other Perl modules, including: ''Archive::Tar'', ''Archive::Zip'', ''Compress::Zlib'', ''Convert::TNEF'', ''Convert::UUlib'', ''MIME::Base64'', ''MIME::Tools'', ''Mail::Internet'', ''Net::Server'', ''Net::SMTP'', ''Digest::MD5'', ''IO::Stringy'', ''Time::Hires'', and ''Unix::Syslog''. If you plan to do per-user configuration of amavisd-new through SQL or LDAP, you'll need appropriate Perl modules for database access (''DBI'' and a ''DBD::'' module for SQL, or ''Net::LDAP'' for LDAP). You can install most of these Perl modules using CPAN as described in [[SpamAssassin/SpamAssassin Basics|Chapter 2]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Warning'''&lt;br /&gt;
&lt;br /&gt;
The standard version of ''MIME::Tools'' 5.411a has bugs. Install ''MIME::Tools'' 6 or later from ''http://search.cpan.org/dist/MIME-tools''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Begin the install process by creating a new user account and group for running amavisd-new; the usual name for both the user and group is ''amavis''. This user will own amavisd-new's files, and the user (or group) must have access to SpamAssassin's configuration and database files as well. The user's home directory is traditionally ''/var/amavis'', but you can create it anywhere that fits your system's needs.&lt;br /&gt;
&lt;br /&gt;
amavisd-new uses several important directories. It keeps two files in its home directory, one containing its current process ID, and the other used for locking. It uses a working directory for unpacking email messages and scanning them; by default, this is the home directory or the ''tmp'' subdirectory of the home directory. For optimal performance, this directory should be on a fast disk—even a RAM disk if your operating system supports it and you have enough memory to spare. amavisd-new stores quarantined email messages in ''/var/virusmails'' by default, but you can select any directory for this purpose. Speed is not so critical with this directory, and it should never be located on a RAM disk because you will often want to be sure that you can access quarantined files. If you plan to physically locate these directories somewhere unusual (e.g., to mount new disk partitions or a RAM disk as ''/var/amavis/tmp''), you should do so before you install amavisd-new. The directories should be owned by user and group ''amavis'' and should not be world-readable or world-searchable.&lt;br /&gt;
&lt;br /&gt;
Next, download the amavisd-new source code from ''http://www.ijs.si/software/amavisd/'' and unpack it. As ''root'', copy the &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; script to a suitable directory for executable daemons (e.g., ''/usr/bin'', ''/usr/local/sbin'', etc.), &amp;lt;tt&amp;gt;chown&amp;lt;/tt&amp;gt; it to ''root'', and use &amp;lt;tt&amp;gt;chmod&amp;lt;/tt&amp;gt; to set its permissions to 0755 (readable and executable by all users, writable only by ''root'').&lt;br /&gt;
&lt;br /&gt;
Copy the ''amavisd.conf'' file to a suitable directory for configuration files (e.g., ''/etc'', ''/etc/amavis'', ''/usr/local/etc'', etc.). By default, &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; expects to find this file in ''/etc'', and if you locate it anywhere else, you will have to add an extra command-line option (&amp;lt;tt&amp;gt;-c&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;''filename''&amp;lt;/tt&amp;gt;) when invoking &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; to tell it the new location. The ''amavisd.conf'' file should also be owned by ''root'' and should have permissions 0644 (readable by all, writable only by ''root'').&lt;br /&gt;
&lt;br /&gt;
=== Configuring amavisd-new ===&lt;br /&gt;
&lt;br /&gt;
amavisd-new is configured through the ''amavisd.conf'' file. ''amavisd.conf'' is parsed as a Perl script and can contain any legal Perl code. Because it is parsed as Perl, you must escape any at sign (@), question mark ($), or backslash (\) characters that appear in double-quoted strings by prepending a backslash. For example:&lt;br /&gt;
&lt;br /&gt;
 $some_email = &amp;quot;sample\@example.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
Email addresses must be specified without surrounding brackets and without RFC 2821 quoting.&lt;br /&gt;
&lt;br /&gt;
Edit ''amavisd.conf'' to set the (many) available configuration options to control &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt;. The file is organized in logical sections; the most important options are in Section I, but you'll need to read through the entire file to customize the system completely. The following sections explain commonly modified portions of the configuration file in the order that you'll encounter them.&lt;br /&gt;
&lt;br /&gt;
==== Essential options ====&lt;br /&gt;
&lt;br /&gt;
[[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-EX-1|Example 6-1]] shows the first portion of the configuration file and the settings of the essential options. Set &amp;lt;tt&amp;gt;$MYHOME&amp;lt;/tt&amp;gt; to the ''amavis'' user's home directory. Set &amp;lt;tt&amp;gt;$mydomain&amp;lt;/tt&amp;gt; to your domain name. Set &amp;lt;tt&amp;gt;$daemon_user&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;$daemon_group&amp;lt;/tt&amp;gt; to name of the ''amavis'' user and group. Set &amp;lt;tt&amp;gt;$TEMPBASE&amp;lt;/tt&amp;gt; to the directory to use for unpacking messages; for improved performance, this directory should be a mounted RAM disk.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;spamassassin-CHP-6-EX-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 6-1. Essential settings in amavisd.conf'''&lt;br /&gt;
&lt;br /&gt;
 # Section I - Essential daemon and MTA settings&lt;br /&gt;
 #&lt;br /&gt;
 &lt;br /&gt;
 # $MYHOME serves as a quick default for some other configuration settings.&lt;br /&gt;
 # More refined control is available with each individual setting further down.&lt;br /&gt;
 # $MYHOME is not used directly by the program. No trailing slash!&lt;br /&gt;
 '''$MYHOME = '/var/amavis';     # (default is '/var/amavis')'''&lt;br /&gt;
 &lt;br /&gt;
 # $mydomain serves as a quick default for some other configuration settings.&lt;br /&gt;
 # More refined control is available with each individual setting further down.&lt;br /&gt;
 # $mydomain is never used directly by the program.&lt;br /&gt;
 '''$mydomain = 'example.com';   # (no useful default)'''&lt;br /&gt;
 &lt;br /&gt;
 # Set the user and group to which the daemon will change if started as root&lt;br /&gt;
 # (otherwise just keeps the UID unchanged, and these settings have no effect):&lt;br /&gt;
 '''$daemon_user  = 'amavis';    # (no default;  customary: vscan or amavis)'''&lt;br /&gt;
 '''$daemon_group = 'amavis';    # (no default;  customary: vscan or amavis)'''&lt;br /&gt;
 &lt;br /&gt;
 # Runtime working directory (cwd), and a place where&lt;br /&gt;
 # temporary directories for unpacking mail are created.&lt;br /&gt;
 # (no trailing slash, may be a scratch file system)&lt;br /&gt;
 #$TEMPBASE = $MYHOME;        # (must be set if other config vars use is)&lt;br /&gt;
 '''$TEMPBASE = &amp;quot;$MYHOME/tmp&amp;quot;;   # prefer to keep home dir /var/amavis clean?'''&lt;br /&gt;
                   &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== MTA options ====&lt;br /&gt;
&lt;br /&gt;
[[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-EX-2|Example 6-2]] shows the settings of the MTA options. Set &amp;lt;tt&amp;gt;$forward_method&amp;lt;/tt&amp;gt; to the method you will use to reinject checked mail to the MTA. For Postfix, this method should be of the form &amp;lt;tt&amp;gt;smtp&amp;lt;/tt&amp;gt;:&amp;lt;tt&amp;gt;''ipaddress''&amp;lt;/tt&amp;gt;:&amp;lt;tt&amp;gt;''portnumber''&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;''ipaddress''&amp;lt;/tt&amp;gt; is the IP address of the Postfix system (usually 127.0.0.1) and &amp;lt;tt&amp;gt;''portnumber''&amp;lt;/tt&amp;gt; is the TCP port number on which the second &amp;lt;tt&amp;gt;smtpd&amp;lt;/tt&amp;gt; instance is running. Because amavisd-new was designed with Postfix in mind, you may not need to change this section at all.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;spamassassin-CHP-6-EX-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 6-2. MTA options in amavisd.conf'''&lt;br /&gt;
&lt;br /&gt;
 # MTA SETTINGS, UNCOMMENT AS APPROPRIATE,&lt;br /&gt;
 # both $forward_method and $notify_method default to 'smtp:127.0.0.1:10025'&lt;br /&gt;
 &lt;br /&gt;
 # POSTFIX, or SENDMAIL in dual-MTA setup, or EXIM V4&lt;br /&gt;
 # (set host and port number as required; host can be specified&lt;br /&gt;
 # as IP address or DNS name (A or CNAME, but MX is ignored)&lt;br /&gt;
 '''$forward_method = 'smtp:127.0.0.1:10025';  # where to forward checked mail'''&lt;br /&gt;
 $notify_method = $forward_method;          # where to submit notifications&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Daemon process options ====&lt;br /&gt;
&lt;br /&gt;
[[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-EX-3|Example 6-3]] shows the daemon process settings. The most important setting is &amp;lt;tt&amp;gt;$max_servers&amp;lt;/tt&amp;gt;, which you should set to the same number of &amp;lt;tt&amp;gt;smtp&amp;lt;/tt&amp;gt; processes you have configured Postfix to use concurrently to send messages to amavisd-new.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;spamassassin-CHP-6-EX-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 6-3. Daemon process settings in amavisd.conf'''&lt;br /&gt;
&lt;br /&gt;
 # Net::Server pre-forking settings&lt;br /&gt;
 # You may want $max_servers to match the width of your MTA pipe&lt;br /&gt;
 # feeding amavisd, e.g. with Postfix the 'Max procs' field in the&lt;br /&gt;
 # master.cf file, like the '2' in the:  smtp-amavis unix - - n - 2 smtp&lt;br /&gt;
 #&lt;br /&gt;
 '''$max_servers  =  2;   # number of pre-forked children          (default 2)'''&lt;br /&gt;
                   &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Distinguishing local domains ====&lt;br /&gt;
&lt;br /&gt;
amavisd-new distinguishes local domains from remote domains. Recipients at local domains can take advantage of several per-user features that are not directly available to remote recipients, including local customization of SpamAssassin settings. [[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-EX-4|Example 6-4]] shows that part of ''amavisd.conf''that bears on per-user customization.&lt;br /&gt;
&lt;br /&gt;
You can provide your local domain information in several ways. You can set the &amp;lt;tt&amp;gt;@local_domains_acl&amp;lt;/tt&amp;gt; array to a list of domain names that should be considered local. You can set the &amp;lt;tt&amp;gt;%local_domains&amp;lt;/tt&amp;gt; hash instead, providing local domain names as keys and 1 as their values, or use the &amp;lt;tt&amp;gt;read_hash&amp;lt;/tt&amp;gt; function to read in a list of local domain names from an external file. Finally, you can define local domain names by invoking the &amp;lt;tt&amp;gt;new_RE&amp;lt;/tt&amp;gt; function with a regular expression that matches the local domain names and assigning the result to &amp;lt;tt&amp;gt;$local_domains_re&amp;lt;/tt&amp;gt;. No matter which method you use, adding a period (.) to the beginning of a domain name means that the domain and any subdomains should all be considered local.&lt;br /&gt;
&lt;br /&gt;
[[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-EX-4|Example 6-4]] shows this section of the configuration file, using the &amp;lt;tt&amp;gt;@local_domains_acl&amp;lt;/tt&amp;gt; variable to define local domains.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;spamassassin-CHP-6-EX-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 6-4. Setting local domains in amavisd.conf'''&lt;br /&gt;
&lt;br /&gt;
 # Lookup list of local domains (see README.lookups for syntax details)&lt;br /&gt;
 #&lt;br /&gt;
 # NOTE:&lt;br /&gt;
 #   For backwards compatibility the variable names @local_domains (old) and&lt;br /&gt;
 #   @local_domains_acl (new) are synonyms. For consistency with other lookups&lt;br /&gt;
 #   the name @local_domains_acl is now preferred. It also makes it more&lt;br /&gt;
 #   obviously distinct from the new %local_domains hash lookup table.&lt;br /&gt;
 #&lt;br /&gt;
 # local_domains* lookup tables are used in deciding whether a recipient&lt;br /&gt;
 # is local or not, or in other words, if the message is outgoing or not.&lt;br /&gt;
 # This affects inserting spam-related headers for local recipients,&lt;br /&gt;
 # limiting recipient virus notifications (if enabled) to local recipients,&lt;br /&gt;
 # in deciding if address extension may be appended, and in SQL lookups&lt;br /&gt;
 # for non-fqdn addresses. Set it up correctly if you need features&lt;br /&gt;
 # that rely on this setting (or just leave empty otherwise).&lt;br /&gt;
 #&lt;br /&gt;
 # With Postfix (2.0) a quick reminder on what local domains normally are:&lt;br /&gt;
 # a union of domains specified in: $mydestination, $virtual_alias_domains,&lt;br /&gt;
 # $virtual_mailbox_domains, and $relay_domains.&lt;br /&gt;
 #&lt;br /&gt;
 #@local_domains_acl = ( &amp;quot;.$mydomain&amp;quot; );  # $mydomain and its subdomains&lt;br /&gt;
 # @local_domains_acl = qw( );  # default is empty, no recipient treated as local&lt;br /&gt;
 # @local_domains_acl = qw( .example.com );&lt;br /&gt;
 # @local_domains_acl = qw( .example.com !host.sub.example.net .sub.example.net );&lt;br /&gt;
 # @local_domains_acl = ( &amp;quot;.$mydomain&amp;quot;, '.example.com', 'sub.example.net' );&lt;br /&gt;
 '''@local_domains_acl = qw/'''&lt;br /&gt;
 '''example.com'''&lt;br /&gt;
 '''example.net'''&lt;br /&gt;
 '''example.org'''&lt;br /&gt;
 '''/;'''&lt;br /&gt;
 &lt;br /&gt;
 # or alternatively(A), using a Perl hash lookup table, which may be assigned&lt;br /&gt;
 # directly, or read from a file, one domain per line; comments and empty lines&lt;br /&gt;
 # are ignored, a dot before a domain name implies its subdomains:&lt;br /&gt;
 #&lt;br /&gt;
 #read_hash(\%local_domains, '/var/amavis/local_domains');&lt;br /&gt;
 &lt;br /&gt;
 #or alternatively(B), using a list of regular expressions:&lt;br /&gt;
 # $local_domains_re = new_RE( qr'[@.]example\.com$'i );&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Postfix-specific options ====&lt;br /&gt;
&lt;br /&gt;
Section II of ''amavsid.conf'' specifies options that differ by MTA and is shown in [[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-EX-5|Example 6-5]]. Because amavisd-new was designed with Postfix in mind, you need to modify relatively few options. Set the &amp;lt;tt&amp;gt;$inet_socket_port&amp;lt;/tt&amp;gt; variable to the TCP port number on which &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; should listen for SMTP connections from Postfix. To prevent this port from being accessed by remote hosts, set &amp;lt;tt&amp;gt;$inet_socket_bind&amp;lt;/tt&amp;gt; to '&amp;lt;tt&amp;gt;127.0.0.1&amp;lt;/tt&amp;gt;', which will cause &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; to listen only on the loopback interface and not on other network interfaces. If you want to allow access by a set of remote hosts (if, for example, you want to run &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; on a different host than your Postfix MTA), don't set &amp;lt;tt&amp;gt;$inet_socket_bind&amp;lt;/tt&amp;gt; but do set &amp;lt;tt&amp;gt;@inet_acl&amp;lt;/tt&amp;gt; to a list of IP addresses for hosts that should be permitted to connect. This list is checked in order; the first match wins. You may specify these IP addresses as single addresses or as CIDR-style &amp;lt;tt&amp;gt;''address''&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;/&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;''netmask''&amp;lt;/tt&amp;gt; (e.g., &amp;lt;tt&amp;gt;192.168.1/255.255.255.0&amp;lt;/tt&amp;gt;) or &amp;lt;tt&amp;gt;''address''&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;/&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;''bits''&amp;lt;/tt&amp;gt; (e.g., &amp;lt;tt&amp;gt;192.168.1/24&amp;lt;/tt&amp;gt;) ranges.&amp;lt;ref&amp;gt;&amp;quot;CIDR&amp;quot; stands for Classless Interdomain Routing.&amp;lt;/ref&amp;gt; You may prepend an IP address with an exclamation point (&amp;lt;tt&amp;gt;!)&amp;lt;/tt&amp;gt; to disallow connections from that address, even if a larger range that contains the address is permitted (e.g., &amp;lt;tt&amp;gt;!192.168.0/24 192.168/16&amp;lt;/tt&amp;gt; to allow all 192.168.*.* addresses except 192.168.0.* addresses).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;spamassassin-CHP-6-EX-5&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 6-5. Postfix-specific options in amavisd.conf'''&lt;br /&gt;
&lt;br /&gt;
 # SMTP SERVER (INPUT) PROTOCOL SETTINGS (e.g. with Postfix, Exim v4, ...)&lt;br /&gt;
 #   (used when MTA is configured to pass mail to amavisd via SMTP or LMTP)&lt;br /&gt;
 '''$inet_socket_port = 10024;'''        # accept SMTP on this local TCP port&lt;br /&gt;
                                   # (default is undef, i.e. disabled)&lt;br /&gt;
 # multiple ports may be provided: $inet_socket_port = [10024, 10026, 10028];&lt;br /&gt;
 &lt;br /&gt;
 # SMTP SERVER (INPUT) access control&lt;br /&gt;
 # - do not allow free access to the amavisd SMTP port !!!&lt;br /&gt;
 #&lt;br /&gt;
 # when MTA is at the same host, use the following (one or the other or both):&lt;br /&gt;
 '''$inet_socket_bind = '127.0.0.1';'''  # limit socket bind to loopback interface&lt;br /&gt;
                                   # (default is '127.0.0.1')&lt;br /&gt;
 '''@inet_acl = qw( 127.0.0.1 );'''      # allow SMTP access only from localhost IP&lt;br /&gt;
                                   # (default is qw( 127.0.0.1 ) )&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Logging options ====&lt;br /&gt;
&lt;br /&gt;
Section III of ''amavisd.conf'' deals with logging and is shown in [[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-EX-6|Example 6-6]]. &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; can log using ''syslog'', or it can log to a file. Set &amp;lt;tt&amp;gt;$DO_SYSLOG&amp;lt;/tt&amp;gt; to 1 to instruct &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; to use ''syslog'' for logging; you can change the ''syslog'' facility and priority using the &amp;lt;tt&amp;gt;$SYSLOG_LEVEL&amp;lt;/tt&amp;gt; variable. Set &amp;lt;tt&amp;gt;$DO_SYSLOG&amp;lt;/tt&amp;gt; to 0 to instruct &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; to log to a file; set &amp;lt;tt&amp;gt;$LOGFILE&amp;lt;/tt&amp;gt; to specify the filename. The log file must be in a directory the ''amavis'' user can write to.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;$log_level&amp;lt;/tt&amp;gt; variable controls the amount of detail that &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; logs. A log level of 0 results in minimal logging; a log level of 5 produces highly verbose logging.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;spamassassin-CHP-6-EX-6&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 6-6. Logging options'''&lt;br /&gt;
&lt;br /&gt;
 # Section III - Logging&lt;br /&gt;
 #&lt;br /&gt;
 &lt;br /&gt;
 # true (e.g. 1) =&amp;gt; syslog;  false (e.g. 0) =&amp;gt; logging to file&lt;br /&gt;
 '''$DO_SYSLOG = 1;'''                   # (defaults to false)&lt;br /&gt;
 '''#$SYSLOG_LEVEL = 'user.info';'''     # (defaults to 'mail.info')&lt;br /&gt;
 &lt;br /&gt;
 # Log file (if not using syslog)&lt;br /&gt;
 $LOGFILE = &amp;quot;$MYHOME/amavis.log&amp;quot;;  # (defaults to empty, no log)&lt;br /&gt;
 &lt;br /&gt;
 #NOTE: levels are not strictly observed and are somewhat arbitrary&lt;br /&gt;
 # 0: startup/exit/failure messages, viruses detected&lt;br /&gt;
 # 1: args passed from client, some more interesting messages&lt;br /&gt;
 # 2: virus scanner output, timing&lt;br /&gt;
 # 3: server, client&lt;br /&gt;
 # 4: decompose parts&lt;br /&gt;
 # 5: more debug details&lt;br /&gt;
 '''$log_level = 1;'''                  # (defaults to 0)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Spam-handling options ====&lt;br /&gt;
&lt;br /&gt;
Most of Section IV of ''amavisd.conf'' focuses on detailed configuration of how &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; will handle detected viruses and spam. Only those options related to spam handling are discussed in detail here.&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; detects a spam email, it logs a message to its log file by default. It can also quarantine the email and/or notify an administrator. It can then generate a bounce message to the sender. Finally, it can either accept and deliver the message, or discard the message. Many different configuration variables are involved in these decisions. Unfortunately, the order of the variables in the file is largely the reverse of the order in which they are checked during the spam-handling process.&lt;br /&gt;
&lt;br /&gt;
Enable a spam quarantine by setting the following two variables:&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;$QUARANTINEDIR&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Set this variable to the directory or mailbox file in which to store the quarantined messages.&lt;br /&gt;
;&amp;lt;tt&amp;gt;$spam_quarantine_method&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Set this variable to &amp;quot;&amp;lt;tt&amp;gt;local:spam-%b-%i-%n&amp;lt;/tt&amp;gt;&amp;quot;, to specify the filename format for quarantined spam messages. In that format, &amp;lt;tt&amp;gt;%b&amp;lt;/tt&amp;gt; expands to a digest of the message body, &amp;lt;tt&amp;gt;%i&amp;lt;/tt&amp;gt; expands to the date and time, and &amp;lt;tt&amp;gt;%n&amp;lt;/tt&amp;gt; expands to the &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; message identifier.&lt;br /&gt;
&lt;br /&gt;
To control the spam quarantine on a per-recipient basis, set the &amp;lt;tt&amp;gt;$spam_quarantine_to&amp;lt;/tt&amp;gt; variable to a reference to a hash, keyed by the recipient's address, like this:&lt;br /&gt;
&lt;br /&gt;
 $local_delivery_aliases{'sam-spam'} = '/home/sam/mail/spam';&lt;br /&gt;
 &lt;br /&gt;
 $spam_quarantine_to =&lt;br /&gt;
   { 'example.net' =&amp;gt; undef&lt;br /&gt;
     'jane@example.com' =&amp;gt; 'spam@jane.example.com',&lt;br /&gt;
     'sam@example.com' =&amp;gt; 'sam-spam',&lt;br /&gt;
     'example.com' =&amp;gt; 'spam-quarantine',&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
If the hash value is undefined or empty, spam is not quarantined. In this example, spam sent to ''example.net'' will not be quarantined at all. If the hash value contains an asterisk (&amp;lt;tt&amp;gt;@)&amp;lt;/tt&amp;gt;, spam will be forwarded. Spam sent to ''jane@example.com'' will be forwarded to ''spam@jane.example.com''. Otherwise, the hash value is looked up in the &amp;lt;tt&amp;gt;%local_delivery_aliases&amp;lt;/tt&amp;gt; hash, and the spam is quarantined in the file or directory returned from that lookup. If the lookup fails, &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; logs a warning and doesn't quarantine the message. Several default local delivery aliases are defined in &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt;, including &amp;lt;tt&amp;gt;spam-quarantine&amp;lt;/tt&amp;gt;, which quarantines a message in &amp;lt;tt&amp;gt;$QUARANTINEDIR&amp;lt;/tt&amp;gt;. In the preceding example, spam to ''sam@example.com'' will be quarantined in the ''/home/sam/mail/spam'' mailbox (or mail directory), and other spam to ''example.com'' will be quarantined in the default directory.&lt;br /&gt;
&lt;br /&gt;
You can also write your &amp;lt;tt&amp;gt;$spam_quarantine_to&amp;lt;/tt&amp;gt; policies with regular expressions:&lt;br /&gt;
&lt;br /&gt;
 $spam_quarantine_to = new_RE(&lt;br /&gt;
   [qr/^sam@example\.com$/i =&amp;gt; 'sam-spam'],&lt;br /&gt;
   [qr/^jane@example\.com$/i =&amp;gt; 'spam@jane.example.com'],&lt;br /&gt;
   [qr/@example\.com$/i =&amp;gt; 'spam-quarantine'],&lt;br /&gt;
   [qr/@example\.net$/i =&amp;gt; undef]&lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Because regular expressions are matched in the order that you list them, you must put the most specific matches first (&amp;lt;tt&amp;gt;/^sam@example\.com/&amp;lt;/tt&amp;gt; before &amp;lt;tt&amp;gt;/@example\.com/&amp;lt;/tt&amp;gt;). Because regular expression matches are case sensitive, you should generally include the &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; (case-insensitive) modifier to the &amp;lt;tt&amp;gt;qr//&amp;lt;/tt&amp;gt; operator.&lt;br /&gt;
&lt;br /&gt;
Spam to recipients that don't match any entry in &amp;lt;tt&amp;gt;$spam_quarantine_to&amp;lt;/tt&amp;gt; will not be quarantined, so if you want to quarantine all spam by default, you should either provide a rule for each domain you receive mail for, or use the regular expression approach and include a rule for the regular expression &amp;lt;tt&amp;gt;qr/.*/&amp;lt;/tt&amp;gt; at the end.&lt;br /&gt;
&lt;br /&gt;
amavisd-new is smart about per-recipient policies like &amp;lt;tt&amp;gt;$spam_quarantine_to&amp;lt;/tt&amp;gt;. If some message recipients choose to quarantine spam and some do not, amavisd-new will honor those preferences. If multiple recipients choose the same quarantine destination, a message sent to two or more of those recipients is written only once to the quarantine destination .&lt;br /&gt;
&lt;br /&gt;
You can also make quarantine decisions based on a spam's sender in an analogous way using &amp;lt;tt&amp;gt;$spam_quarantine_bysender_to&amp;lt;/tt&amp;gt;, but this alternative is rarely useful, as spammers often falsify their sending addresses or use throwaway accounts.&lt;br /&gt;
&lt;br /&gt;
To notify an administrator when spam is received, set &amp;lt;tt&amp;gt;$spam_admin&amp;lt;/tt&amp;gt; to the address of the administrator. These notifications are disabled by default. Consider carefully before setting &amp;lt;tt&amp;gt;$spam_admin&amp;lt;/tt&amp;gt; to the email address of a real person; given the amount of spam on the Internet today, it's easy to get hundreds of notifications or more, and difficult to know what to do about them. An alternative that might be useful for service providers is to set &amp;lt;tt&amp;gt;$spam_admin&amp;lt;/tt&amp;gt; to a reference to a hash based on the spam sender's address, in order to detect outgoing spam from customers. For example, to notify the security staff about spam being sent from the ''example.com'' domain but nowhere else, use:&lt;br /&gt;
&lt;br /&gt;
 $spam_admin = &lt;br /&gt;
   { '.example.com' =&amp;gt; 'security@example.com',&lt;br /&gt;
     '.' =&amp;gt; undef&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;$final_spam_destiny&amp;lt;/tt&amp;gt; variable controls the final disposition of spam recognized by &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt;. Although this variable appears first in this section of the configuration file, it is consulted last during spam-handling. When using amavisd-new with Postfix, there are three useful settings for &amp;lt;tt&amp;gt;$final_spam_destiny&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
* Set &amp;lt;tt&amp;gt;$final_spam_destiny&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;D_PASS&amp;lt;/tt&amp;gt; to accept and deliver all spam. Use this strategy when your goal is simply to tag spam and let clients do their own filtering. If you set &amp;lt;tt&amp;gt;$warnspamsender&amp;lt;/tt&amp;gt; to 1, you will also generate a bounce message to the sender. I don't recommend this, however, as spammers often falsify return addresses.&lt;br /&gt;
* Set &amp;lt;tt&amp;gt;$final_spam_destiny&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;D_DISCARD&amp;lt;/tt&amp;gt; to discard spam that scores above a &amp;quot;kill level&amp;quot; (specified in Section VII of ''amavisd.conf''); spam below the kill level will be tagged and accepted. Use this strategy when your goal is to reduce bandwidth or storage space by dropping messages that are very likely to be spam and tagging others.&lt;br /&gt;
* Set &amp;lt;tt&amp;gt;$final_spam_destiny&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;D_BOUNCE&amp;lt;/tt&amp;gt; to generate a bounce message to the sender and then discard the message. Because spammers often falsify their return addresses, you will rarely want to use this setting.&lt;br /&gt;
&lt;br /&gt;
==== Recipient whitelists ====&lt;br /&gt;
&lt;br /&gt;
Section V of the ''amavisd.conf'' file focuses on spam policy controls for individual recipients or recipient domains. Its function is analogous to SpamAssassin's &amp;lt;tt&amp;gt;whitelist_to&amp;lt;/tt&amp;gt; feature. You can prevent any spam-checking at all, or you can continue to perform spam-checking but prevent spam-handling actions for detected spam.&lt;br /&gt;
&lt;br /&gt;
To prevent any spam-checking at all for email sent to a recipient, set the &amp;lt;tt&amp;gt;@bypass_spam_checks_acl&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;%bypass_spam_checks&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;$bypass_spam_checks_re&amp;lt;/tt&amp;gt; variables. You may use domain names instead of recipient addresses to whitelist all mail sent to a given domain. Here's how you'd set the &amp;lt;tt&amp;gt;@bypass_spam_checks_acl&amp;lt;/tt&amp;gt; array to a list of recipients that want to opt out of spam-checking:&lt;br /&gt;
&lt;br /&gt;
 @bypass_spam_checks_acl = qw( chris@example.com robin@example.com);&lt;br /&gt;
&lt;br /&gt;
To use the &amp;lt;tt&amp;gt;%bypass_spam_checks&amp;lt;/tt&amp;gt; hash instead, provide recipient addresses as keys and 1 as their values. You might prefer this approach to using &amp;lt;tt&amp;gt;@bypass_spam_checks_acl&amp;lt;/tt&amp;gt; if you have a very long list of recipients, because searching a hash is much faster than searching a long list. You can also use the &amp;lt;tt&amp;gt;read_hash&amp;lt;/tt&amp;gt; function to read in a list of recipients from an external file and assign them to &amp;lt;tt&amp;gt;%bypass_spam_checks&amp;lt;/tt&amp;gt;. This is useful when you want to keep a long list of recipients separate from the ''amavisd.conf'' file. For example:&lt;br /&gt;
&lt;br /&gt;
 read_hash(\%bypass_spam_checks, '/var/amavis/bypass_spam');&lt;br /&gt;
&lt;br /&gt;
Finally, you can define recipients to opt out by providing a list of regular expressions that match recipient addresses to the &amp;lt;tt&amp;gt;new_RE&amp;lt;/tt&amp;gt; function and assigning the result to &amp;lt;tt&amp;gt;$bypass_spam_checks&amp;lt;/tt&amp;gt;. This method is useful when you can parsimoniously specify your whitelisted recipients with a regular expression or two. For example:&lt;br /&gt;
&lt;br /&gt;
 $bypass_spam_checks = new_RE(qr'^(chris|robin)@example\.com'i);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
Spam checks are bypassed only if all of the recipients of a message have been added to one of these variables. If even one recipient is not listed, spam-checking will still be performed. To ensure that spam is still delivered to whitelisted recipients in such cases, use the &amp;quot;spam_lovers&amp;quot; features discussed next.&lt;br /&gt;
&lt;br /&gt;
If spam checks are bypassed, SpamAssassin's Bayesian classifier will not have an opportunity to learn from a message, whether or not it is spam.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To prevent spam-handling (e.g., tagging or quarantine) from being performed for a recipient when a message has been checked and designated as spam, set the &amp;lt;tt&amp;gt;@spam_lovers_acl&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;%spam_lovers&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;$spam_lovers_re&amp;lt;/tt&amp;gt; variables. These variables are set analogously to the &amp;lt;tt&amp;gt;@bypass_spam_checks_acl&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;%bypass_spam_checks&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;$bypass_spam_checks_re&amp;lt;/tt&amp;gt; variables.&lt;br /&gt;
&lt;br /&gt;
In [[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-EX-7|Example 6-7]], ''jane@example.com'' always receives every message, spam or not, and spam-tagging is skipped when messages are addressed to her alone. In addition, if a message is destined for a domain other than ''example.com'' (i.e., it's outgoing mail from our domain), spam-tagging is skipped. ''postmaster@example.com'' also receives every message, but spam-checking is still performed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;spamassassin-CHP-6-EX-7&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 6-7. Whitelisting by recipient'''&lt;br /&gt;
&lt;br /&gt;
 # Avoid running a spam check if jane is the only recipient, or if&lt;br /&gt;
 # all recipients are outside of ''example.com''&lt;br /&gt;
 @bypass_spam_checks_acl = ('jane@example.com', '!.example.com');&lt;br /&gt;
 &lt;br /&gt;
 # Even if we run a check, don't act on the results for jane or postmaster&lt;br /&gt;
 @spam_lovers_acl = ('jane@example.com', 'postmaster@example.com');&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sender whitelists and blacklists ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; can maintain whitelists and blacklists of message senders. It uses a message's envelope address (the one provided in the SMTP MAIL FROM command) as the sender address. Whitelisting ensures that &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; will allow mail from a whitelisted sender to continue to its intended recipients; blacklisting ensures that &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; will treat mail from a blacklisted sender as spam.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt;'s whitelist and blacklist features do not interact in the same manner as SpamAssassin's. For example, if an address is both whitelisted and blacklisted in SpamAssassin, neither takes effect. If an address is both whitelist and blacklisted in &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt;, both take effect—the message is marked as spam and also allowed to pass to the recipient.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As with other &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; address-matching features, you can specify addresses to globally whitelist by an array, keys of a hash, or by a set of regular expressions. Set the &amp;lt;tt&amp;gt;@whitelist_sender_acl&amp;lt;/tt&amp;gt; array to a list of sender addresses to whitelist. To use the &amp;lt;tt&amp;gt;%whitelist_sender&amp;lt;/tt&amp;gt; hash instead, provide sender addresses as keys and 1 as their values, or use the &amp;lt;tt&amp;gt;read_hash&amp;lt;/tt&amp;gt; function to read in a list of senders from an external file. Finally, you can specify senders to whitelist by providing a list of regular expressions that match the sender addresses to the &amp;lt;tt&amp;gt;new_RE&amp;lt;/tt&amp;gt; function and assigning the result to &amp;lt;tt&amp;gt;$whitelist_sender_re&amp;lt;/tt&amp;gt;. You may use domain names instead of sender addresses to whitelist all mail sent from a given domain.&lt;br /&gt;
&lt;br /&gt;
You can use a similar set of variables for globally blacklisting senders. The array is &amp;lt;tt&amp;gt;@blacklist_sender_acl&amp;lt;/tt&amp;gt;, the hash is &amp;lt;tt&amp;gt;%blacklist_sender&amp;lt;/tt&amp;gt;, and the regular expression version is &amp;lt;tt&amp;gt;$blacklist_sender_re&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The default ''amavisd.conf'' defines &amp;lt;tt&amp;gt;$blacklist_sender_re&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;%whitelist_sender&amp;lt;/tt&amp;gt; as shown in [[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-EX-8|Example 6-8]]. Many username patterns typical of spammers are blacklisted, such as ''investments''; many addresses of well-known security and vendor mailing lists are whitelisted. You can modify these definitions or use one of the other variables to add additional sender addresses to the whitelist or blacklist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;spamassassin-CHP-6-EX-8&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 6-8. Default blacklist and whitelist entries in amavisd.conf'''&lt;br /&gt;
&lt;br /&gt;
 $blacklist_sender_re = new_RE(&lt;br /&gt;
     qr'^(bulkmail|offers|cheapbenefits|earnmoney|foryou|greatcasino)@'i,&lt;br /&gt;
     qr'^(investments|lose_weight_today|market.alert|money2you|MyGreenCard)@'i,&lt;br /&gt;
     qr'^(new\.tld\.registry|opt-out|opt-in|optin|saveonlsmoking2002k)@'i,&lt;br /&gt;
     qr'^(specialoffer|specialoffers|stockalert|stopsnoring|wantsome)@'i,&lt;br /&gt;
     qr'^(workathome|yesitsfree|your_friend|greatoffers)@'i,&lt;br /&gt;
     qr'^(inkjetplanet|marketopt|MakeMoney)\d*@'i,&lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 map { $whitelist_sender{lc($_)}=1 } (qw(&lt;br /&gt;
   cert-advisory-owner@cert.org&lt;br /&gt;
   owner-alert@iss.net&lt;br /&gt;
   slashdot@slashdot.org&lt;br /&gt;
   bugtraq@securityfocus.com&lt;br /&gt;
   NTBUGTRAQ@LISTSERV.NTBUGTRAQ.COM&lt;br /&gt;
   security-alerts@linuxsecurity.com&lt;br /&gt;
   amavis-user-admin@lists.sourceforge.net&lt;br /&gt;
   notification-return@lists.sophos.com&lt;br /&gt;
   mailman-announce-admin@python.org&lt;br /&gt;
   owner-postfix-users@postfix.org&lt;br /&gt;
   owner-postfix-announce@postfix.org&lt;br /&gt;
   owner-sendmail-announce@Lists.Sendmail.ORG&lt;br /&gt;
   owner-technews@postel.ACM.ORG&lt;br /&gt;
   lvs-users-admin@LinuxVirtualServer.org&lt;br /&gt;
   ietf-123-owner@loki.ietf.org&lt;br /&gt;
   cvs-commits-list-admin@gnome.org&lt;br /&gt;
   rt-users-admin@lists.fsck.com&lt;br /&gt;
   clp-request@comp.nus.edu.sg&lt;br /&gt;
   surveys-errors@lists.nua.ie&lt;br /&gt;
   emailNews@genomeweb.com&lt;br /&gt;
   owner-textbreakingnews@CNNIMAIL12.CNN.COM&lt;br /&gt;
   spamassassin-talk-admin@lists.sourceforge.net&lt;br /&gt;
   yahoo-dev-null@yahoo-inc.com&lt;br /&gt;
   returns.groups.yahoo.com&lt;br /&gt;
 ));&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
amavisd-new also supports per-recipient blacklists and whitelists of senders. Per-recipient lists override the global lists. Use the &amp;lt;tt&amp;gt;$per_recip_blacklist_sender_lookup_tables&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;$per_recip_whitelist_sender_lookup_tables&amp;lt;/tt&amp;gt; variables to specify these lists. Each variable is a reference to a hash keyed by the recipient's address (or domain). The hash value should be a reference to an array of sender addresses, a reference to a hash keyed on sender addresses (with hash values of 1), a call to the &amp;lt;tt&amp;gt;read_hash&amp;lt;/tt&amp;gt; function to read the addresses from a file, or a call to &amp;lt;tt&amp;gt;new_RE&amp;lt;/tt&amp;gt; with a list of regular expressions to match sender addresses against. For example, you could add the following code to ''amavisd.conf'' to maintain a list of whitelisted senders for ''jane@example.com'' in the file ''/etc/mail/jane-whitelist'':&lt;br /&gt;
&lt;br /&gt;
 $per_recip_whitelist_sender_lookup_tables = &lt;br /&gt;
   { 'jane@example.com' =&amp;gt; read_hash('/etc/mail/jane-whitelist')&lt;br /&gt;
   };&lt;br /&gt;
&lt;br /&gt;
==== SpamAssassin settings ====&lt;br /&gt;
&lt;br /&gt;
Several variables in ''amavisd.conf'' affect the way that &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; invokes SpamAssassin or the actions it takes based on a message's score from SpamAssassin:&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;$sa_local_tests_only&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Set this variable to 1 if you want SpamAssassin to skip network-based tests. It defaults to 0 (perform network-based tests).&lt;br /&gt;
;&amp;lt;tt&amp;gt;$sa_auto_whitelist&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Set &amp;lt;tt&amp;gt;this variable&amp;lt;/tt&amp;gt; to 1 to enable SpamAssassin's autowhitelist feature. It defaults to (no autowhitelist). Specify the location of the autowhitelist database in SpamAssassin's sitewide configuration file, ''local.cf''. Be sure that the ''amavis'' user has permission to read from and write to the database.&lt;br /&gt;
;&amp;lt;tt&amp;gt;$sa_mail_body_size_limit&amp;lt;/tt&amp;gt;&lt;br /&gt;
: If you set this variable to a size (in bytes), messages larger than the given size will not be checked for spam. This conserves system resources, as SpamAssassin can take a long time to check large messages, and large messages are rarely spam. The variable is undefined by default, which implies no limit. A reasonable value might be 65536 (64Kb) or 102400 (100Kb).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
&amp;lt;dt&amp;gt;&amp;lt;tt&amp;gt;$sa_tag_level_deflt&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;dd&amp;gt;This variable determines the spam score at or above which ''X-Spam-Status'' and ''X-Spam-Level'' headers will be added to the message to show the spam status and level of the message. The default is 3, which is suitable for seeing which tests are and are not being triggered for suspicious messages. If you like to see the spam status of all messages, set this value to -10 or so.&lt;br /&gt;
&lt;br /&gt;
This variable can be defined on a per-recipient basis much like &amp;lt;tt&amp;gt;$per_recip_blacklist_sender_lookup_tables&amp;lt;/tt&amp;gt;. Set &amp;lt;tt&amp;gt;$sa_tag_level_deflt&amp;lt;/tt&amp;gt; to a reference to a hash keyed on recipient addresses, with the tag level as the hash value.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
&amp;lt;dt&amp;gt;&amp;lt;tt&amp;gt;$sa_tag2_level_deflt&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;dd&amp;gt;This variable determines the spam score at or above which &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; adds an ''X-Spam-Flag: YES'' header and an ''X-Spam-Report'' header to the message. It may also modify the ''Subject'' header to tag the message as spam. The default is 6.3.&lt;br /&gt;
&lt;br /&gt;
This variable can be defined on a per-recipient basis much like &amp;lt;tt&amp;gt;$per_recip_blacklist_sender_lookup_tables&amp;lt;/tt&amp;gt;. Set &amp;lt;tt&amp;gt;$sa_tag2_level_deflt&amp;lt;/tt&amp;gt; to a reference to a hash keyed on recipient addresses, with the tag2 level as the hash value.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
&amp;lt;dt&amp;gt;&amp;lt;tt&amp;gt;$sa_kill_level_deflt&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;dd&amp;gt;This variable determines the spam score at or above which &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; will perform spam-handling on the message, such as quarantining the message, discarding it, notifying administrators, etc. By default, this variable is set to the value of &amp;lt;tt&amp;gt;$sa_tag2_level_deflt&amp;lt;/tt&amp;gt; so spam-handling is performed on all spam detected. If you want to discard messages that are extremely likely to be spam and tag messages that are less likely to be spam, set this variable to a higher score (e.g., 12), and only messages above that level will be subject to special handling.&lt;br /&gt;
&lt;br /&gt;
The variable can be defined on a per-recipient basis much like &amp;lt;tt&amp;gt;$per_recip_blacklist_sender_lookup_tables&amp;lt;/tt&amp;gt;. Set &amp;lt;tt&amp;gt;$sa_kill_level_deflt&amp;lt;/tt&amp;gt; to a reference to a hash keyed on recipient addresses, with the kill level as the hash value.&lt;br /&gt;
&amp;lt;/dl&amp;gt;;&amp;lt;tt&amp;gt;$sa_spam_modifies_subj&amp;lt;/tt&amp;gt;&lt;br /&gt;
: If this variable is set to 1, &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; may modify the ''Subject'' header of messages with spam scores above the &amp;lt;tt&amp;gt;$sa_tag2_level_dflt&amp;lt;/tt&amp;gt; setting. You can also set this variable to a reference to a list of recipients who should have their ''Subject'' headers modified, a reference to a hash table keyed on recipients who should have their headers modified (with hash values of 1), or the return value of a &amp;lt;tt&amp;gt;new_RE( )&amp;lt;/tt&amp;gt; call on a list of regular expressions to match against recipients who should have their headers modified. This variable is not defined by default.&lt;br /&gt;
;&amp;lt;tt&amp;gt;$sa_spam_subject_tag&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Set this variable to the string to prepend to the ''Subject'' header of spam messages when &amp;lt;tt&amp;gt;$sa_spam_modifies_subj&amp;lt;/tt&amp;gt; is true. If you do not define this, ''Subject'' headers will never be modified. It is not defined by default; a common definition would be '&amp;lt;tt&amp;gt;*****SPAM*****&amp;lt;/tt&amp;gt;'.&lt;br /&gt;
&lt;br /&gt;
==== Storing recipient preferences in external databases ====&lt;br /&gt;
&lt;br /&gt;
It's possible to store amavisd-new recipient preferences in an SQL or LDAP database. This can be useful if you want to permit users to modify their own preferences, particularly if you already use an SQL- or LDAP-based user directory. SQL and LDAP lookups override variables defined in ''amavisd.conf''.&lt;br /&gt;
&lt;br /&gt;
Database entries indicate user preferences, including whether a user has opted out of spam-checking, whether &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; should modify the ''Subject'' of spam messages, and user spam tag levels (tag, tag2, kill). Database entries may also specify sender addresses that the recipient wants to blacklist or whitelist.&lt;br /&gt;
&lt;br /&gt;
To enable SQL lookups, define the variable &amp;lt;tt&amp;gt;@lookup_sql_dsn&amp;lt;/tt&amp;gt; in ''amavisd.conf''. This variable should contain a list of references to three-element arrays that represent database connections. The first element of each array is a Perl ''DBI'' DSN that defines the database driver to use, the database name, and the name of the database server host. The second element is a database username that &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; will provide for identification to the database server, and the third element is the associated password for authentication. The distributed ''amavisd.conf'' file provides the following commented-out example:&lt;br /&gt;
&lt;br /&gt;
 # @lookup_sql_dsn =&lt;br /&gt;
 #   ( ['DBI:mysql:database=mail;host=127.0.0.1;port=3306', 'user1', 'passwd1'],&lt;br /&gt;
 #     ['DBI:mysql:database=mail;host=host2', 'username2', 'password2'] );&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; will first attempt to connect to the MySQL database server on port 3306 of the local host in order to access the ''mail'' database. It will log into the database server as &amp;lt;tt&amp;gt;''user1''&amp;lt;/tt&amp;gt; with password &amp;lt;tt&amp;gt;''passwd1''&amp;lt;/tt&amp;gt;. If this connection fails, &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; will try the next database server, a MySQL server running on &amp;lt;tt&amp;gt;''host2''&amp;lt;/tt&amp;gt;, using user &amp;lt;tt&amp;gt;''username2''&amp;lt;/tt&amp;gt; and password &amp;lt;tt&amp;gt;''password2''&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The file ''README_FILES/README.lookups'' in the amavisd-new source code provides definitions for a set of SQL tables that are suitable for configuring user policies and whitelists and blacklists in &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt;. You can add these tables to your SQL database and follow the instructions in ''README.lookups'' to add appropriate database queries to ''amavisd.conf''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
amavisd-new's SQL support should not be confused with SpamAssassin's SQL support. Each controls different aspects of mail-processing.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The amavisd-new source code includes an LDAP schema for an auxiliary class (amavisAccount) that can be added to user accounts. The class defines attributes that determine whether a user has opted out of spam-checking, whether &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; should modify the ''Subject'' of spam messages, a user's desired spam tag levels (tag, tag2, kill), and sender addresses to blacklist or whitelist for a user.&lt;br /&gt;
&lt;br /&gt;
To enable LDAP lookups, set the &amp;lt;tt&amp;gt;$enable_ldap&amp;lt;/tt&amp;gt; variable in ''amavisd.conf'' to 1, and provide LDAP server information in the &amp;lt;tt&amp;gt;$default_ldap&amp;lt;/tt&amp;gt; variable as a reference to a hash:&lt;br /&gt;
&lt;br /&gt;
 $default_ldap = {&lt;br /&gt;
   hostname =&amp;gt; '''ldap-server-hostname''',&lt;br /&gt;
   tls =&amp;gt; ''1'',&lt;br /&gt;
   base =&amp;gt; '''base DN for ldap searches''',&lt;br /&gt;
   query_filter =&amp;gt; '(&amp;amp;(objectClass=amavisAccount)(mail=%m))'}&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
For each preference for which &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; can perform an LDAP query, you must define additional query parameters to specify (at minimum) the result attribute to be returned from the LDAP database to &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt;. Parameters left undefined will prevent LDAP queries from being performed for that preference. The &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; source code provides the examples in [[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-EX-9|Example 6-9]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;spamassassin-CHP-6-EX-9&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 6-9. Defining LDAP query parameters for user preferences'''&lt;br /&gt;
&lt;br /&gt;
 $bypass_spam_checks_ldap  = {res_attr =&amp;gt; 'amavisBypassSpamChecks'};&lt;br /&gt;
 $spam_tag_level_ldap      = {res_attr =&amp;gt; 'amavisSpamTagLevel'};&lt;br /&gt;
 $spam_kill_level_ldap     = {res_attr =&amp;gt; 'amavisSpamKillLevel'};&lt;br /&gt;
 $spam_whitelist_sender_ldap = {&lt;br /&gt;
   query_filter =&amp;gt; '(&amp;amp;(objectClass=amavisAccount)(mail=%m)&lt;br /&gt;
                      (amavisWhitelistSender=%s))',&lt;br /&gt;
   res_filter =&amp;gt; 'OK'};&lt;br /&gt;
 $spam_blacklist_sender_ldap = {&lt;br /&gt;
   query_filter =&amp;gt; '(&amp;amp;(objectClass=amavisAccount)(mail=%m)&lt;br /&gt;
                      (amavisBlacklistSender=%s))',&lt;br /&gt;
   res_filter =&amp;gt; 'OK'};&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See the file ''README_FILES/README.lookups'' in the source code for more information.&lt;br /&gt;
&lt;br /&gt;
=== Basic Operations ===&lt;br /&gt;
&lt;br /&gt;
Once you've configured the options in ''amavisd.conf'', you're ready to test &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt;. Start &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; either as the ''amavis'' user or as ''root'' (in which case it will change its UID and GID to that of ''amavis'' during startup).&lt;br /&gt;
&lt;br /&gt;
During your first test, start &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; with the &amp;lt;tt&amp;gt;debug&amp;lt;/tt&amp;gt; argument. This causes &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; to run in the foreground and produce debugging information that you can watch to be sure that it's working correctly. [[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-EX-10|Example 6-10]] shows a debug startup for a properly functioning configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;spamassassin-CHP-6-EX-10&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 6-10. Starting amavisd with the debug arguments'''&lt;br /&gt;
&lt;br /&gt;
 # '''amavisd debug'''&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: starting.  amavisd at tala amavisd-new-20030616-p7&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Perl version               5.006001&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Amavis::Conf        1.15&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Archive::Tar        1.08&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Archive::Zip        1.09&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Compress::Zlib      1.32&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Convert::TNEF       0.17&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Convert::UUlib      1.0&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module MIME::Entity        6.109&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module MIME::Parser        6.108&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module MIME::Tools         6.110&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Mail::Header        1.60&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Mail::Internet      1.60&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Mail::SpamAssassin  2.63&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Net::Cmd            2.24&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Net::DNS            0.45&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Net::SMTP           2.26&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Net::Server         0.86&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Time::HiRes         1.54&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Module Unix::Syslog        0.99&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Found myself: /usr/local/sbin/amavisd -c /etc/amavisd.&lt;br /&gt;
 conf&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Lookup::SQL code       NOT loaded&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Lookup::LDAP code      NOT loaded&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: AMCL-in protocol code  NOT loaded&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: SMTP-in protocol code  loaded&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: ANTI-VIRUS code        loaded&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: ANTI-SPAM  code        loaded&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Net::Server: 2004/02/07-16:58:16 Amavis (type Net::&lt;br /&gt;
 Server::PreForkSimple) starting! pid(924)&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Net::Server: Binding to TCP port 10024 on host 127.0.&lt;br /&gt;
 0.1&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Net::Server: Setting gid to &amp;quot;110 110&amp;quot;&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Net::Server: Setting uid to &amp;quot;2013&amp;quot;&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Net::Server: Setting up serialization via flock&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Found $file       at /usr/bin/file&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: No $arc,          not using it&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Found $gzip       at /bin/gzip&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Found $bzip2      at /usr/bin/bzip2&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Found $lzop       at /bin/lzop&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Found $lha        at /usr/bin/lha&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Found $unarj      at /usr/bin/arj&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Found $uncompress at /bin/uncompress&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: No $unfreeze,     not using it&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Found $unrar      at /usr/bin/unrar&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Found $zoo        at /usr/bin/zoo&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Found $cpio       at /bin/cpio&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: Using internal av scanner code for (primary) Clam &lt;br /&gt;
 Antivirus-clamd&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: No primary av scanner: KasperskyLab AVP - aveclient&lt;br /&gt;
 ...many other messages about detecting av scanners...&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: SpamControl: initializing Mail::SpamAssassin&lt;br /&gt;
 Feb  7 16:58:16 tala amavisd[924]: SpamControl: turning on SA auto-whitelisting&lt;br /&gt;
 Feb  7 16:58:23 tala amavisd[924]: SpamControl: done&lt;br /&gt;
 Feb  7 16:58:23 tala amavisd[924]: Net::Server: Beginning prefork (2 processes)&lt;br /&gt;
 Feb  7 16:58:23 tala amavisd[924]: Net::Server: Starting &amp;quot;2&amp;quot; children&lt;br /&gt;
 Feb  7 16:58:23 tala amavisd[924]: Net::Server: Parent ready for children.&lt;br /&gt;
 Feb  7 16:58:23 tala amavisd[929]: Net::Server: Child Preforked (929)&lt;br /&gt;
 Feb  7 16:58:23 tala amavisd[930]: Net::Server: Child Preforked (930)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After the startup messages, you should begin to see &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; processing incoming messages (which will produce a copious amount of debugging information). When you are satisfied that messages are being properly delivered back to Postfix, hit Ctrl-C to stop &amp;lt;tt&amp;gt;amavisd debug&amp;lt;/tt&amp;gt; and run &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; with no arguments to start the daemon in the background.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
If you've chosen to locate your configuration file somewhere other than ''/etc'', you should either make a symbolic link to ''/etc/amavisd.conf'' or use the &amp;lt;tt&amp;gt;-c&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;''/path/to/amavisd.conf''&amp;lt;/tt&amp;gt; command-line option to &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; is running and you confirm that ordinary email is being delivered correctly, test the SpamAssassin functions by sending a copy of the GTUBE string to yourself from a remote system. Because SpamAssassin assigns GTUBE a spam score of 1000, which should be higher than your spam kill level, you should see the message handled by &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt;'s spam-handling options.&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; appears to work, but SpamAssassin does not, you can enable SpamAssassin debugging by editing ''amavisd.conf'' and setting the &amp;lt;tt&amp;gt;$sa_debug&amp;lt;/tt&amp;gt; variable to 1. This variable appears at the end of ''amavisd.conf''. You must stop &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; and restart it with the &amp;lt;tt&amp;gt;debug&amp;lt;/tt&amp;gt; argument for SpamAssassin debugging to be performed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
Anytime you make a change to ''amavisd.conf'', you must inform &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt; by issuing the command &amp;lt;tt&amp;gt;amavisd reload&amp;lt;/tt&amp;gt; (or stopping and restarting the daemon).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The amavisd-new distribution includes a script named &amp;lt;tt&amp;gt;amavisd_init.sh&amp;lt;/tt&amp;gt; that you can use as a boot script for systems based on RedHat Linux. With a little modification, it makes a suitable boot script for other Unix systems to automatically start and stop &amp;lt;tt&amp;gt;amavisd&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Adding Sitewide Bayesian Filtering ===&lt;br /&gt;
&lt;br /&gt;
You can easily add sitewide Bayesian filtering to amavisd-new. Use the usual SpamAssassin &amp;lt;tt&amp;gt;use_bayes&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;bayes_path&amp;lt;/tt&amp;gt; directives in ''local.cf'', and ensure that the ''amavis'' user has permission to create the databases in the directory named in &amp;lt;tt&amp;gt;bayes_path&amp;lt;/tt&amp;gt;. One way to do this is to use a directory for the databases that is owned by ''amavis'', such as ''/var/amavis''. Another option is to locate the databases in a directory owned by another user but to create them ahead of time and &amp;lt;tt&amp;gt;chown&amp;lt;/tt&amp;gt; them to ''amavis.''If local users need to have access to the databases (e.g., they will be running &amp;lt;tt&amp;gt;sa-learn)&amp;lt;/tt&amp;gt;, you might have to make the databases readable or writable by a group other than ''amavis'' and adjust the &amp;lt;tt&amp;gt;bayes_file_mode&amp;lt;/tt&amp;gt;, or make them world readable or writable. Doing so, however, puts the integrity of your spam-checking at the mercy of the good intentions and comprehension of your users.&lt;br /&gt;
&lt;br /&gt;
If users have shell accounts on the system, you can use per-user Bayesian filtering with amavisd-new instead. Configure SpamAssassin for per-user databases as usual, but ensure that each user's databases are group-owned by the ''amavis'' group and have group read/write permissions so that amavisd-new can use them. Doing so allows users to run &amp;lt;tt&amp;gt;sa-learn&amp;lt;/tt&amp;gt; themselves to train their databases, while still permitting amavisd-new to access them. With SpamAssassin 3.0, you could also store per-user Bayesian data in an SQL database.&lt;br /&gt;
&lt;br /&gt;
=== Adding Sitewide Autowhitelisting ===&lt;br /&gt;
&lt;br /&gt;
amavisd knows how to use autowhitelisting (see the discussion of &amp;lt;tt&amp;gt;$sa_auto_whitelist&amp;lt;/tt&amp;gt; earlier in this chapter). Just add the usual SpamAssassin &amp;lt;tt&amp;gt;auto_whitelist_path&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;auto_whitelist_file_mode&amp;lt;/tt&amp;gt; directives to ''local.cf''. As with the Bayesian databases, the ''amavis'' user must have permission to create the autowhitelist database and read and write to it.&lt;br /&gt;
&lt;br /&gt;
=== Routing Email Through the Gateway ===&lt;br /&gt;
&lt;br /&gt;
Once Postfix and amavisd-new are receiving messages for the local host and performing SpamAssassin checks on them, you can start accepting email for your domain and routing it to an internal mail server after spam-checking. [[SpamAssassin/Integrating SpamAssassinwith Postfix#spamassassin-CHP-6-FIG-4|Figure 6-4]] illustrates this topology.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;spamassassin-CHP-6-FIG-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 6-4. Spam-checking gateway topology'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SpamAssassin_I_6_tt118.png|Spam-checking gateway topology]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Postfix changes ====&lt;br /&gt;
&lt;br /&gt;
To configure Postfix to relay incoming mail for ''example.com'' to ''internal.example.com'', add the following line to ''/etc/postfix/main.cf'':&lt;br /&gt;
&lt;br /&gt;
 transport_maps=hash:/etc/postfix/transport&lt;br /&gt;
&lt;br /&gt;
Then, create the ''/etc/postfix/transport'' file, and add either:&lt;br /&gt;
&lt;br /&gt;
 example.com   smtp:internal.example.com&lt;br /&gt;
&lt;br /&gt;
or, if ''mail.example.com'' cannot resolve the name ''internal.example.com'', you could use&lt;br /&gt;
&lt;br /&gt;
 example.com   smtp:[129.168.10.55]&lt;br /&gt;
&lt;br /&gt;
Run the command &amp;lt;tt&amp;gt;postmap /etc/postfix/transport&amp;lt;/tt&amp;gt; to build the transport map from ''/etc/postfix/transport'', and run &amp;lt;tt&amp;gt;postfix reload&amp;lt;/tt&amp;gt; to reload Postfix's configuration.&lt;br /&gt;
&lt;br /&gt;
==== Routing changes ====&lt;br /&gt;
&lt;br /&gt;
Mail from the Internet for ''example.com'' should be sent to the spam-checking gateway ''mail.example.com''. Add a DNS MX record for the ''example.com'' domain that points to ''mail.example.com''.&lt;br /&gt;
&lt;br /&gt;
Once received by ''mail.example.com'', messages will be spam-checked and should then be relayed to ''internal.example.com'' by Postfix. No DNS records for ''internal.example.com'' need be published to the Internet, but it's useful if ''mail.example.com'' can resolve ''internal.example.com''.&lt;br /&gt;
&lt;br /&gt;
==== Internal server configuration ====&lt;br /&gt;
&lt;br /&gt;
Once the external mail gateway is in place, you can configure the internal mail server to accept SMTP connections only from the gateway (for incoming Internet mail). If you don't have a separate server for outgoing mail, the internal mail server should also accept SMTP connections from hosts on the internal network. These restrictions are usually enforced by limiting access to TCP port 25 using a host-based firewall or a packet-filtering router.&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</description>
			<pubDate>Fri, 07 Mar 2008 10:53:32 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SpamAssassin/Integrating_SpamAssassinwith_Postfix</comments>		</item>
	</channel>
</rss>