7.2 Accepting and Cleaning Up Local Mail Using the Regular SMTP Daemon

In the FAQ distributed with qmail 1.03, question 5.5 describes the classic technique for cleaning up remotely injected mail. The smtprules.cdb file that tcpserver consults contains lines that set the RELAYCLIENT environment variable for hosts allowed to inject and relay mail. If RELAYCLIENT is set, qmail-smtpd both skips the usual relay validation and appends the contents of RELAYCLIENT to all envelope destination addresses. If RELAYCLIENT has the value @fixme, mail addressed to fred@example.com is sent to fred@example.com@fixme. If you define fixme as a virtual domain, all mail from these hosts is handled as virtual domain mail.

More concretely, start by creating a fixme virtual domain in virtualdomains:

fixme:alias-fixup

Then create ~alias/.qmail-fixup-default:

| bouncesaying 'Permission denied' [ "@$HOST" != "@fixme" ] | qmail-inject -f "$SENDER" -- "$DEFAULT"

The first line checks that the mail is really sent to the fixme virtual domain, so that sneaky bad guys can't relay mail by sending it to alias-fixup-victim@otherdomain@example.com (assuming example.com is your local domain.) The second line feeds the mail through qmail-inject, preserving the original sender and remailing it to $DEFAULT, which was the original destination address before @fixme was added. Finally, add the @fixme strings to the local network entries in smtprules.txt and rebuild smtprules.cdb:

127.:allow,RELAYCLIENT="@fixme" 172.16.42.:allow,RELAYCLIENT="@fixme" 172.16.15.1-127:allow,RELAYCLIENT="@fixme" :allow

Use svc -h /service/qmail-send to make qmail notice the new virtual domain.

Although as we see in the next section, this is no longer the best way to handle mail injection, the basic model for treating mail depending on its source IP address remains useful. For example, I find that I receive certain spam from AOL over and over again with very predictable strings in the message. So I route all mail from AOL to a pseudodomain aoltrap in which commands in the .qmail file grep each message for the known spammy strings, forward the mail to an abuse reporting script if they find any of the strings, and otherwise forward the mail to $DEFAULT to deliver it normally. While I use a more general spam filter for other incoming mail, the stuff from AOL is different enough that it was worth setting up a special filter, particularly because it only took 10 minutes to set the filter up.

7.2.1 Using Separate Relay and Injection Daemons

Since the new-inject package includes ofmipd, which combines an SMTP daemon and the same mail cleanup that new-inject does, the best way to clean up incoming mail is to arrange for mail clients to inject mail through ofmipd rather than qmail-smtpd. ofmipd doesn't do relay checking, so you have to ensure that only authorized clients can use it.

If you assign more than one IP address to your qmail host, run qmail-smtpd on one address and ofmipd on another. It's also a good idea to run a copy of ofmipd on port 587, the SUBMIT port that is defined (and increasingly used) for mail submission (another name for injection) from MUAs on other hosts.[1] And you must run ofmipd on 127.0.0.1 to accept mail from programs that inject mail by setting up a local SMTP session (such as pine and some mailing list packages). You must run separate copies of tcpserver, each bound to a separate IP address and port. First, change /var/qmail/supervise/qmail-smtpd/run to run tcpserver only on a single IP address, which should be the address in the MX record pointing at the server, as in Example 7-1.

[1] If you have roaming users who connect from hotels and the like, SUBMIT is particularly important. Many networks block attempts to connect to port 25, but they permit connections to 587.

Example 7-1. The SMTP listening script for incoming mail
 1. #!/bin/sh  2. limit datasize 2m  3. exec \  4.    tcpserver -u000 -g000 -v -p -R    \  5.     -x/var/qmail/rules/smtprules.cdb 10.1.2.3 25 \  6.    /var/qmail/bin/qmail-smtpd 2>&1

In the log directory, create a subdirectory log/logfiles, chown it to qmaill (the log user), and create log/run, as in Example 7-2.

Example 7-2. Log file script for SMTP and ofmip daemons
 1. #!/bin/sh  2. exec setuidgid qmaill \  3.   multilog t s1000000 ./logfiles

In line 3, s1000000 says to make each log file a megabyte. Depending on how much log traffic the server generates, you may want to adjust this number up or down to adjust how far back the log data goes. The log setup for all of the servers described in this chapter is the same, so I won't repeat it.

Second, create directories /var/qmail/supervise/ofmipd and /var/qmail/supervise/ofmipd/log to run ofmipd. Set up the log directory the same as the one for qmail-send described in Chapter 4. Set the file modes the same as you did for SMTP service and create ofmipd/run, as in Example 7-3.

Example 7-3. The ofmipd script, for SMTP mail injected from other hosts
 1. #!/bin/sh  2. limit datasize 2m  3. exec \  4.  tcpserver -u000 -g000 -v -p -R        \  5.     -x/var/qmail/rules/ofmipdrules.cdb 10.1.2.4 25 \  6.     /usr/local/bin/ofmipd 2>&1

Third, create /var/qmail/rules/ofmipdrules.txt to permit connections only from the local network and deny everyone else, and create /var/qmail/rules/ofmipdrules.cdb from it:

172.16.42.:allow 172.16.15.1-127.:allow :deny

Finally, symlink /var/qmail/supervise/ofmipd to /service and your injection daemon should start up. Telnet to your injection daemon's address, port 25, and use HELO, MAIL FROM, RCPT TO, and DATA commands to send yourself a test message.

Once that works, copy everything in /var/qmail/supervise/ofmipd to /var/qmail/supervise/ofmipdlocal, and /var/qmail/supervise/ofmipd/log to /var/qmail/supervise/ofmipdlocal/log. Then edit the run file to use 127.0.0.1, as shown in Example 7-4.

Example 7-4. The ofmipd script, for SMTP mail injected from this host
 1. #!/bin/sh  2. limit datasize 2m  3. exec \  4.       tcpserver -u000 -g000 -v -p -R \  5.       127.0.0.1 25 \  6.       /var/qmail/bin/ofmipd 2>&1

You can omit the -x flag because only processes on the local computer can connect to 127.0.0.1. Now symlink /var/qmail/supervise/ofmipdlocal to /service, and test your local daemon by telnetting to 127.0.0.1 port 25, and send yourself another test message.

To create an ofmipd running on the SUBMIT port, create /var/qmail/supervise/ofmipdsubmit and /var/qmail/supervise/ofmipdsubmit/log with the same contents as /var/qmail/supervise/ofmipd and /var/qmail/supervise/ofmipd/log, except that the port number on line 5 is 587 rather than 25. It can (and should) share the same ofmipdrules.cdb file because the rules for who you accept mail from are the same, regardless of which port a client uses. Symlink /var/qmail/supervise/ofmipdsubmit to /service, telnet to your injection daemon's address, port 587, and send one more test message, and you're done setting up mail injection.

To someone familiar with sendmail, it may seem awfully complicated and perhaps slow to set up four separate daemons just to receive mail, but the four are all configured slightly differently, and because tcpserver is small and fast, it doesn't place an undue load on the system.

7.2.2 Deciding On the Fly Which Daemon to Use

Although I don't really recommend this approach, it's easy to arrange to run either qmail-smtpd or ofmipd on connections to the same IP address depending on the remote address from which a connection arrives. Do this by adding an environment variable to entries in smtprules that says which daemon to run, and testing that variable in the programs run from tcpserver. Let's put the name of the server to use in the SERVER variable, so smtprules.txt looks like this:

127.:allow,SERVER="ofmipd" 172.16.42.:allow,SERVER="ofmipd" 172.16.15.1-127:allow,SERVER="ofmipd" :allow,SERVER="smtpd"

Now adjust the run file to use SERVER to decide what to run, as shown in Example 7-5.

Example 7-5. The SMTP listening script for incoming mail
 1. #!/bin/sh  2. limit datasize 2m  3. exec \  4.    tcpserver -u000 -g000 -v -p -R    \  5.     -x/var/qmail/rules/smtprules.cdb 10.1.2.3 25 \  6.     sh -c 'case "$SERVER" in  7.      smtpd) exec /var/qmail/bin/smtpd ;;  8.      ofmipd) exec /usr/local/bin/ofmipd ;;  9.                           esac' 2>&1

When tcpserver receives an incoming connection, it runs the shell script[2] on lines 6-9, which in turn exec's whichever program SERVER tells it to. Be sure to use single and double quotes exactly as shown here, so that the value of SERVER is expanded by the shell run from tcpserver, rather than by the shell that interprets the run script.

[2] Because the script is in single quotes, it doesn't need \ at the end of each line.



qmail
qmail
ISBN: 1565926285
EAN: 2147483647
Year: 2006
Pages: 152

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net