Thursday 2011-04-21

Got a chance to play with sendmail rulesets again today. Prior to moving to SG, the last time I'd worked with sendmail was '97 to '99, because then I gave up and migrated CTI to postfix.

Some spammers like to use the rcpt_to domain as the mail_from domain, and we finally got the vast majority of users to use authenticated TLS when they are not on school grounds. To prevent external unauthenticated users from claiming to be a school user, we'd typically use a check_mail rule. However we use delay_checks, so the order of evaluation of the checks is reversed (check_rcpt, check_mail, check_relay), which means we need to extend mail_check with a Local_mail_check. A verbose ruleset looks like:


SLocal_check_mail
R$* @ example . com >           $: < $( access $&{client_addr} $) >     
R< $- . $- . $- . $- >          $: < $( access $1.$2.$3 $) >
R< $- . $- . $- >               $: < $( access $1.$2 $) >
R< $- . $- >                    $: < $( access $1 $) >
R<REJECT>                       $# error $@ 5 . 7 . 1 $: "550 Access denied..."
R<RELAY>                        $# OK

The repeated $( access $) calls can be condensed into one rewrite that loops on itself as long as access returns something that looks like part of an IP address. sendmail.m4 supports LOCAL_RULESETS, so you can put this in your sendmail.m4 and be done with it.

LOCAL_RULESETS
SLocal_check_mail
R$* @ example . com >           $: < $&{client_addr} >
R< $* . $- >                    < $( access $1 $) >
R<REJECT>                       $# error $@ 5 . 7 . 1 $: "550 Access denied..."
R<RELAY>                        $# OK
And no, I wouldn't have remembered this stuff except for having a copy of the bat book available via safari. ;)