Friday, December 9th, 2005

postfix+clamscan is eating my mail

When I went to check my mail this morning, there was a lot less than I thought there should be. That is, there was no new email, not even spam. This never happens, because I get so much spam and list mail that there's always something there.

I did some investigation and found that postfix was running everything through clamav as configured, but clamav was rejecting everything as having a virus. Even text messages with no attachment!

When I integrated clamscan into postfix, I used a postfix after-queue content filter script. That example shows filter processing as:

filter <in.$$

That redirects the temporary file in.$$ to the filter's stdin for processing. So my script reads:

/usr/local/bin/clamscan -d /var/lib/clamav <in.$$

Looks ok, right? Well, clamscan doesn't support redirecting content into its stdin. Instead, when run without arguments it ignores stdin and processes everything in the current directory. Since the current directory is the temporary filter queue directory, no problem. (Well almost; there is also a race condition if two scans are running simultaneously and one is a virus - the other will be thought to be a virus too.)

Upon further investigation, I found that sometime last evening clamscan had crashed and left a clamscan.core file in the filter working directory. The problem here is that the clamscan core file is itself identified as a virus! While clamscan is running, it contains virus signatures in memory which are then written to disk if it dumps core.

I fixed this problem by changing my clamscan line to:

/usr/local/bin/clamscan -d /var/lib/clamav in.$$

A subtle change but it makes all the difference.

(I don't know why clamscan dumped core. At least if it happens again, it won't cause me to lose 11 hours of email.)
(4 comments | Leave a comment)

Thursday, October 21st, 2004

adventures in unix

This post describes a little fun I had today with repairing a broken Linux system. One of my computers at home stopped working properly: Almost anything I tried to run gave a "fork: Resource temporarily unavailable" error. Read on for a tale of what you might call a shell game...

--More-- 5% )

The lesson learned from all this is that the shell built-in commands are just barely flexible enough to get you out of a pinch if you really need to. It certainly helped having a couple of other creative minds helping me with the problem too. Thanks guys!

(5 comments | Leave a comment)

Wednesday, June 2nd, 2004

poor man's srs

I've been getting an incredible amount of junk bounce messages from email worms. These usually come from the worm sending a message with my email in the From field and a bogus address in the To field. The receiving mail server dutifully returns the message to me, as if I had sent it. I quickly got tired of manually inspecting and deleting these, so I set up a procmail rule to route them to a 'bounce' folder:

* ^Return-Path: (<>|MAILER-DAEMON@)

After setting this up I never really looked in that folder, so I would miss the possibility of receiving a legitimate bounce message (for example, if a message I actually sent was undeliverable for some reason). After reading about Sender Rewriting Scheme, I figured I could rig up something similar that would help (in a simple way, without implementing full SRS).

I changed my .muttrc such that the Envelope-From on outgoing mail is now greg-foo@hewgill.com:

set sendmail="/usr/lib/sendmail -fgreg-foo@hewgill.com"

I actually used a different word than foo above but I'm not going to mention it here. If an email worm were to pick up that address off this page, this whole scheme would be defeated. When setting this up you can use any word you want.

Then I changed my procmail rule to also check bounce messages addressed to my normal address:

* ^Return-Path: (<>|MAILER-DAEMON@)
* ^TO_greg@hewgill.com

In this way, only fake bounce messages that are addressed to my normal address (and are thus worm-generated) get shuffled off to the 'bounce' folder. Any bounce message that I legitimately receive as a result of a message I actually sent, will be addressed to greg-foo@hewgill.com instead, and will not be matched by the above rule. So, they will end up in my normal inbox as they should.

Initial tests show that this is working great. If for some reason a worm discovers the SRS-style Envelope-From address I am using and starts sending me fake bounce messages to that address, I can easily change it to something else.

Fighting spam and worm mail is taking up a nontrivial amount of my time these days, hopefully this will help reduce that time.

(7 comments | Leave a comment)

Monday, December 1st, 2003

qmail may be eating your email

The other day I placed an order online, and entered my email address to get a confirmation message. It was supposed to be sent right away after placing the order, but it didn't arrive. However, since I have been watching my mail server logs more closely recently (due to greylisting), I noticed that the company's mail server had attempted to deliver my confirmation message several times unsuccessfully. I found that this had nothing to do with greylisting rejecting the message, it was being passed straight through to qmail.

The qmail logs were showing an incoming connection but no message was logged as being delivered. Some sleuthing around with the help of davehart, including writing a SMTP shim that logged the precise contents of the mail delivery transaction, revealed the problem. Qmail was rejecting the message with an error message: "451 See http://pobox.com/~djb/docs/smtplf.html."

It turns out that the sending software was trying to send a message that was composed with only LF characters at the end of each line (normally email is sent with both CR and LF line ending characters). Qmail considers this illegal, and when it detects such characters it responds with the above error message and immediately drops the connection. This causes the sending server to save the undelivered message and try again later.

The qmail document refers to a document it calls "822bis", which apparently was an older name for RFC 2822. Section 2.3 of this document does indeed prohibit the use of bare LF characters within the message body. However, this document is not considered a standard; to find a standard relating to email transfer we must look at RFC 822, also known as STD 11. RFC 822 does not specifically prohibit the use of bare LF characters in message bodies.

RFC 821 also requires, in section 4.1.1, that "The receiver should not close the transmission channel until it receives and replies to a QUIT command (even if there was an error)." Based on this, I have concluded that the qmail behaviour is in error and should not be used as is.

The culprit in qmail is the function blast() in the qmail-smtpd.c file. This function scans the message body and if it detects a bare LF character, calls the straynewline() function. This function prints the above 451 message, and abruptly exits:
void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _exit(1); }

There is no evidence that anything bad will happen if the bare LF characters are permitted in the message body. So, in order to fix this problem in qmail, I modified qmail-smtpd.c so that the straynewline() function takes no action:
void straynewline() { }

This modification finally let the order confirmation I was expecting arrive successfully.

I recommend that everybody who runs qmail apply this modification. You may be missing mail and not know it.
(11 comments | Leave a comment)