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>
|