393aa6140a
Parse From header for delayed failure detection. Don't check reputation of trusted host. Track IP reputation only when missing PTR.
294 lines
12 KiB
Plaintext
294 lines
12 KiB
Plaintext
Title: Python Milter FAQ
|
|
|
|
<h1> Python Milter <a name=faq>FAQ</a> </h1>
|
|
|
|
<menu>
|
|
<li> <a href="#compiling">Compiling Python Milter</a>
|
|
<li> <a href="#running">Running Python Milter</a>
|
|
<li> <a href="#spf">Using SPF</a>
|
|
<li> <a href="#srs">Using SRS</a>
|
|
</menu>
|
|
|
|
<ol>
|
|
|
|
<h3> <a name="compiling">Compiling Python Milter </a> </h3>
|
|
|
|
<li> Q. I have tried to download the current milter code and my virus scan
|
|
traps several viruses in the download.
|
|
<p> A. The milter source includes a number of deactivated viruses in
|
|
the test directory. All but the first and last lines of the base64
|
|
encoded virus data has been removed. I suppose I should randomize
|
|
the first and last lines as well, since pymilter just deletes executables,
|
|
and doesn't look for signatures.
|
|
<li> Q. I have installed sendmail from source, but Python milter won't
|
|
compile.
|
|
<p> A. Even though libmilter is officially supported in sendmail-8.12,
|
|
you need to build and install it in separate steps. Take a look
|
|
at the <a href="/aix/sendmail12.spec">RPM spec file</a> for sendmail-8.12.
|
|
The %prep section shows you how to create
|
|
a site.config.m4 that enables MILTER. The %build section shows you how
|
|
to build libmilter in a separate invocation of make. The %install section
|
|
shows you how to install libmilter with a separate invocation of make.
|
|
<p>
|
|
|
|
<li> Q. Why is mfapi.h not found when I try to compile Python milter on
|
|
RedHat 7.2?
|
|
<p> A. RedHat forgot to include the header in the RPM. See the
|
|
<a href="requirements.html#rh72">RedHat 7.2 requirements</a>.
|
|
<p>
|
|
<li> Q. Python milter compiles ok, but I get an error like this when
|
|
I try to import the milter module:
|
|
<pre>
|
|
ImportError: /usr/lib/python2.4/site-packages/milter.so: undefined symbol: smfi_setmlreply
|
|
</pre>
|
|
<p> A. Your libmilter.a is from sendmail-8.12 or earlier. You need
|
|
sendmail-8.13 or later to support setmlreply. You can disable
|
|
setmlreply by changing setup.py. Change:
|
|
<pre>
|
|
define_macros = [ ('MAX_ML_REPLY',32) ]
|
|
</pre>
|
|
in setup.py to
|
|
<pre>
|
|
define_macros = [ ('MAX_ML_REPLY',1) ]
|
|
</pre>
|
|
|
|
<h3> <a name="running">Running Python Milter </a></h3>
|
|
|
|
<li> Q. The sample.py milter prints a message, then just sits there.
|
|
<pre>
|
|
To use this with sendmail, add the following to sendmail.cf:
|
|
|
|
O InputMailFilters=pythonfilter
|
|
Xpythonfilter, S=local:inet:1030@localhost
|
|
|
|
See the sendmail README for libmilter.
|
|
sample milter startup
|
|
</pre>
|
|
<p> A. You need to tell sendmail to connect to your milter. The
|
|
sample milter tells you what to add to your sendmail.cf to tell
|
|
sendmail to use the milter. You can also add an INPUT_MAIL_FILTER
|
|
macro to your sendmail.mc file and rebuild sendmail.cf - see the sendmail
|
|
README for milters.
|
|
<p>
|
|
|
|
<li> Q. I've configured sendmail properly, but still nothing happens
|
|
when I send myself mail!
|
|
<p> A. Sendmail only milters SMTP mail. Local mail is not miltered.
|
|
You can pipe a raw message through sendmail to test your milter:
|
|
<pre>
|
|
$ cat rawtextmsg | sendmail myname@my.full.domain
|
|
</pre>
|
|
Now check your milter log.
|
|
<p>
|
|
|
|
<li> Q. Why do I get this ImportError exception?
|
|
<pre>
|
|
File "mime.py", line 370, in ?
|
|
from sgmllib import declstringlit, declname
|
|
ImportError: cannot import name declstringlit
|
|
</pre>
|
|
<p> A. <code>declstringlit</code> is not provided by sgmllib in all versions
|
|
of python. For instance, python-2.2 does not have it. Upgrade to
|
|
milter-0.4.5 or later to remove this dependency.
|
|
<p>
|
|
|
|
<li> Q. Why do I get <code>milter.error: cannot add recipient</code>?
|
|
<pre>
|
|
</pre>
|
|
<p> A. You must tell libmilter how you might mutate the message with
|
|
<code>set_flags()</code> before calling <code>runmilter()</code>. For
|
|
instance, <code>Milter.set_flags(Milter.ADDRCPT)</code>. You must add together
|
|
all of <code>ADDHDRS, CHGBODY, ADDRCPT, DELRCPT, CHGHDRS</code> that apply.
|
|
<p> NOTE - recent versions default flags to enabling all features. You
|
|
must now call <code>set_flags()</code> if you wish to disable features for
|
|
efficiency.
|
|
<p>
|
|
|
|
<li> Q. Why does sendmail sometimes print something like:
|
|
"...write(D) returned -1, expected 5: Broken pipe"
|
|
in the sendmail log?
|
|
<p> A. Libmilter expects "rcpt to" shortly after getting "mail from".
|
|
"Shortly" is defined by the timeout parameter you passed to
|
|
<code>Milter.runmilter()
|
|
</code> or <code>milter.settimeout()</code>. If the timeout is 10 seconds,
|
|
and looking up the first recipient in DNS takes more than
|
|
10 seconds, libmilter will give up and break the connection.
|
|
<code>Milter.runmilter()</code> defaulted to 10 seconds in 0.3.4. In 0.3.5
|
|
it will keep the libmilter default of 2 hours.
|
|
<p>
|
|
|
|
<li> Q. Why does milter block messages with big5 encoding? What if I
|
|
want to receive them?
|
|
<p> A. sample.py is a sample. It is supposed to be easily modified
|
|
for your specific needs. We will of course continue to move generic
|
|
code out of the sample as the project evolves. Think of sample.py as
|
|
an active config file.
|
|
<p>
|
|
If you are running bms.py, then the block_chinese option in
|
|
<code>/etc/mail/pymilter.cfg</code> controls this feature.
|
|
<p>
|
|
|
|
<li> Q. Why does sendmail coredump with milters on OpenBSD?
|
|
<p> A. Sendmail has a problem with unix sockets on old versions of OpenBSD.
|
|
OpenBSD users report that this problem has been fixed, so upgrading
|
|
OpenBSD will fix this. Otherwise, you can
|
|
use an internet domain socket instead. For example, in
|
|
<code>sendmail.cf</code> use
|
|
<pre>
|
|
Xpythonfilter, S=inet:1234@localhost
|
|
</pre>
|
|
and change sample.py accordingly.
|
|
<p>
|
|
|
|
<li> Q. How can I change the bounce message for an invalid recipient?
|
|
I can only change the recipient in the eom callback, but the eom callback
|
|
is never called when the recipient is invalid!
|
|
<p> A. Configure sendmail to use virtusertable, and send all unknown
|
|
addresses to /dev/null. For example,
|
|
<h4>/etc/mail/virtusertable</h4>
|
|
<pre>
|
|
@mycorp.com dev-null
|
|
dan@mycorp.com dan
|
|
sally@mycorp.com sally
|
|
</pre>
|
|
<h4>/etc/aliases</h4>
|
|
<pre>
|
|
dev-null: /dev/null
|
|
</pre>
|
|
Now your milter will get to the eom callback, and can change the
|
|
envelope recipient at will. Thanks to Dredd at
|
|
<a href=http://www.milter.org/>milter.org</a> for this solution.
|
|
<p>
|
|
|
|
<li> Q. I am having trouble with the setreply method. It always outputs
|
|
"milter.error: cannot set reply".
|
|
<p> A. Check the sendmail log for errors. If sendmail is getting
|
|
milter timeouts, then your milter is taking too long and sendmail gave
|
|
up waiting. You can adjust the timeouts in your sendmail config. Here
|
|
is a milter declaration for sendmail.cf with all timeouts specified:
|
|
<pre>
|
|
Xpythonfilter, S=local:/var/log/milter/pythonsock, F=T, T=C:5m;S:20s;R:60s;E:5m
|
|
</pre>
|
|
<li> Q. There is a Python traceback in the log file! What happened to
|
|
my email?
|
|
<p> A. By default, when the milter fails with an untrapped exception, a
|
|
TEMPFAIL result (451) is returned to the sender. The sender will then retry
|
|
every hour or so for several days. Hopefully, someone will notice the
|
|
traceback, and workaround or fix the problem. Beginning with milter-0.8.2,
|
|
you can call <code>milter.set_exception_policy(milter.CONTINUE)</code>
|
|
to cause an untrapped exception to continue processing with the
|
|
next callback or milter instead. For
|
|
completeness, you can also set the exception policy to
|
|
<code>milter.REJECT</code>.
|
|
|
|
<li> Q. I read some notes such as "Check valid domains allowed by internal
|
|
senders to detect PCs infected with spam trojans." but could not
|
|
understand the idea. Could you clarify the content ?
|
|
|
|
<p> A. The <code>internal_domains</code> configuration specifies which
|
|
MAIL FROM domains are used by internal connections. If an internal
|
|
PC tries to use some other domain, it is assumed to be a "Zombie".
|
|
<p>
|
|
Here is a sample log line:
|
|
<pre>
|
|
2005Jun22 12:01:04 [12430] REJECT: zombie PC at 192.168.100.171 sending MAIL FROM debby@fedex.com
|
|
</pre>
|
|
No, fedex.com does not use pymilter, and there is no one named debby at my
|
|
client. But the idiot using the PC at 192.168.100.171 has downloaded and
|
|
installed some stupid weatherbar/hotbar/aquariumscreensaver that is actually a
|
|
spam bot.
|
|
<p>
|
|
The <code>internal_domains</code> option is simplistic, it assumes all
|
|
valid senders of the domains are internal. SPF provides a much more general
|
|
check of IP and MAIL FROM for external email. Pymilter should soon
|
|
have a local policy feature for more general checking of internal mail.
|
|
<li> Q. <code>mail_archive</code> isn't working. Or I don't understand how
|
|
it's suppose to work. I have
|
|
<code>mail_archive = /var/mail/mail_archive</code>
|
|
in <code>pymilter.cfg</code> but nothing ever gets dumped into
|
|
<code>/var/mail/mail_archive</code>.
|
|
<p> A. The 'mail' user needs to have write access. Permission failures
|
|
should be logged as a traceback in milter.log if it doesn't.
|
|
|
|
<h3> <a name="spf">Using SPF </a></h3>
|
|
|
|
<li> Q. So how do I use the SPF support? The sample.py milter doesn't seem
|
|
to use it.
|
|
<p> A. The bms.py milter supports spf. The RedHat RPMs will set almost
|
|
everything up for you. For other systems:
|
|
<ol type=i>
|
|
<li> Arrange to run bms.py in the background (as a service perhaps) and
|
|
redirect output and errors to a logfile. For instance, on AIX you'll want
|
|
to use SRC (System Resource Controller).
|
|
<li> Copy pymilter.cfg to the /etc/mail or the directory you run bms.py in,
|
|
and edit it. The comments should explain the options.
|
|
<li> Start bms.py in the background as arranged.
|
|
<li> Add Xpythonfilter to sendmail.cf or add an INPUT_MAIL_FILTER to
|
|
sendmail.mc. Regen sendmail.cf if you use sendmail.mc and restart
|
|
sendmail.
|
|
<li> Arrange to rotate log files and remove old defang files in
|
|
<code>tempdir</code>. The RedHat RPM uses <code>logrotate</code> for
|
|
logfiles and a simple cron script using <code>find</code> to clean
|
|
<code>tempdir</code>.
|
|
</ol>
|
|
In CVS, there is <code>spfmilter.py</code>. Run that as a service,
|
|
and it does just SPF. It uses the sendmail <code>access</code>
|
|
file to configure SPF responses just like <code>bms.py</code>, but
|
|
supports only REJECT and OK.
|
|
<li> Q. The SPF DSN is sent at least once for domains that don't publish a SPF.
|
|
How do I stop this behavior?
|
|
<p> A. The SPF response is controlled by <code>/etc/mail/access</code>
|
|
(actually the file you specify with <code>access_file</code> in
|
|
the <code>[spf]</code> section of <code>pymilter.cfg</code>. Responses
|
|
are OK, CBV, and REJECT. CBV sends the DSN.
|
|
<p>
|
|
You can change the defaults. For instance, I have:
|
|
<pre>
|
|
SPF-None: REJECT
|
|
SPF-Neutral: CBV
|
|
SPF-Softfail: CBV
|
|
SPF-Permerror: CBV
|
|
</pre>
|
|
I have best_guess = 1, so SPF none is converted to PASS/NEUTRAL for policy
|
|
lookup, and 3 strikes (no PTR, no HELO, no SPF) becomes "SPF NONE" for local
|
|
policy purposes (the Received-SPF header always shows the official SPF
|
|
result.)
|
|
<p>
|
|
You can change the default for specific domains:
|
|
<pre>
|
|
# these guys aren't going to pay attention to CBVs anyway...
|
|
SPF-None:cia.gov REJECT
|
|
SPF-None:fbi.gov REJECT
|
|
SPF-Neutral:aol.com REJECT
|
|
SPF-Softfail:ebay.com REJECT
|
|
</pre>
|
|
|
|
<h3> <a name="srs">Using SRS </a></h3>
|
|
|
|
<li> Q. The SRS part doesn't seem to work as whenever I try to start
|
|
<code>/etc/init.d/pysrs</code>, I get this in
|
|
<code>/var/log/milter/pysrs.log</code>:
|
|
<pre>
|
|
ConfigParser.NoOptionError: No option 'fwdomain' in section: 'srs'
|
|
</pre>
|
|
<p> A. You need to specify the forward domain - i.e. the domain you want
|
|
SRS to rewrite stuff too.
|
|
<p>
|
|
For instance, I have:
|
|
<pre>
|
|
# sample SRS configuration
|
|
[srs]
|
|
secret = don't you wish
|
|
maxage = 8
|
|
hashlength = 5
|
|
;database=/var/log/milter/srs.db
|
|
fwdomain = bmsi.com
|
|
sign=bmsi.com,mail.bmsi.com,gathman.org
|
|
srs=bmsaix.bmsi.com,bmsred.bmsi.com,stl.gathman.org,bampa.gathman.org
|
|
</pre>
|
|
The <code>sign</code> is for local domains which are signed.
|
|
The <code>srs</code> list is for other domains which you are relaying,
|
|
and which need to have SRS checked/undone for bounces.
|
|
|
|
</ol>
|