Monday, August 13, 2012

Obscure Tips for Sendmail Admins

SkyHi @ Monday, August 13, 2012

Intro
Sendmail is an amazing program. The O’Reilly Sendmail book is its equal, coming in well over 1000 pages. I constantly marvel at how it was possible to pack so much knowledge into one book written by one person. Having run sendmail for over 10 years, I’ve built up a few inside tips that can be extremely hard to find out by yourself, even with the book’s help. I just learned one today, in fact, so I thought I’d put it plus some others in one place where their chances of being useful is slightly greater.
Tip 1: Multiple IPs in a Mailertable Entry, No MX Record Required
Today I learned that you can specify multiple domains in a mailertable entry even when you’re using IP addresses, as in this example:
drjohnstechblog.com       smtp:[50.17.188.196]:[10.10.10.11]
I tested it by putting 50.17.188.196 behind a firewall where it was unreachable. Sure enough, the smtp mail delivery agent of sendmail tried 10.10.10.11 next. You can continue to extend this with additional IPs
Why is this important? If someone has provided you a private IP to forward mail to, say because of a company-to-company VPN, you cannot rely on the usual DNS lookups to do the routing. And a big outfit may have two MTAs reachable in this way. Now you’ve got redundancy built-in to your delivery methods. Just as you have for organizations with multiple MX records. I paged through the book this morning and did not find it. Maybe it’s there. But it’s in an obscure spot if it is.
Tip 2: Error message Containing Punctuation
I also don’t think it’s obvious how to include multiple punctuation marks in a custom error message, even after reading the book. Here’s an example for your access table:
To:hotimail.com   ERROR:"550 You sent an email to hotimail.com.  You probably meant hotmail.com?"
So it’s the quotes that allow you to include the several punctuation marks. The 550 at the beginning will be seen as the error number.
Tip 3: Smarttable for Sender-Based Routing Decisions
Have you ever wanted to make routing decisions based on sender address rather than recipient address? Well, you can! The key is to use smarttable. In my MC file I have:
dnl Define an enhancement, smarttable, from Andrzej Filip
dnl now at http://jmaimon.com/sendmail/anfi.homeunix.net/sendmail/smarttab.html
FEATURE(`smarttable',`hash -o /etc/mail/smarttable')dnl
It’s sufficiently well documented at that page. You need his smarttable.m4 file. So this is not for beginners, but it’s not that hard, either. Although it looks like smarttable hasn’t been updated since 2002, I want to mention that it still works with the latest versions of sendmail. You can route based on the sender domain, or an individual sender address. I use it to send some messages to an encryption gateway. My smarttable entries tend to look like this:
drjohn@drjohnstechtalk.com          relay:[192.168.12.34]
What’s First: Routing Based on Sender or Recipient??
What if your recipient’s domain is in the mailertable and your sender’s address is in the smarttable? What takes precedence in that case? The mailertable entry does. I do not know a way to change that. I actually did experience that conflict and found one way around it.
In my case I had some mailertable entries like this one:
drjohnstechblog.com            relay:drjohnstechtalk.com
with my smarttable entry as above. So I get into this conflict when drjohn@drjohnstechtalk.com wants to send email to someone@drjohnstechblog.com. What I did is run a private BIND DNS server and remove the mailertable entry. My private DNS server is mostly a cache-only server with the usual Internet root servers. But since the public Internet value for the MX record for drjohnstechblog.com is not what I wanted for mail delivery purposes, I created a zone for drjohnstechblog.com on my private DNS server and created the MX record
drjohnstechblog.com            IN   MX   0 drjohnstechtalk.com.
thus overwriting the public MX value for drjohnstechblog.com. Then, of course, I have my server where I am running sendmail set to use my private DNS server as nameserver in /etc/resolv.conf, i.e.,
nameserver 127.0.0.1
since I ran my private DNS server on the same box. Without the mailertable entry sendmail uses DNS to determine how to deliver email unless of course the sender matches a smarttable entry! If my server relies on resolving other resource records within drjohnstechblog.com for other purposes then I have to redefine them, too.
This trick works for individual domains. What if you feel the need for an “everythnig else” entry in your mailertable, i.e.,
.                     relay:relayhost.drjohnstechtalk.com
Well, you’re stuck! I don’t have a solution for you. My DNS trick above could be extended to work for mail with some wildcard entries, but it will break so many other things that you don’t want to go there.
Tip 4: How to send the same email to two (or more) different servers
Someone claimed to need this unusual feature. See the discussion in the comment section about how I believe this is possible to do and an outline of how I would do it.
The blog posting I reference about running sendmail in queue-only mode is here.
Conclusion
Hopefully these sendmail tips will make your life as a sendmail admin toiling away in obscurity (not that I know anyone like that : ) ), just a little easier.

Sendmail’s Mailertable and Backup MX
When a backup MX server is setup, it’s needed to configure the destination server for the domain being backed up.
For example:
domain.tld.            172800 IN MX 10 mail.domain.tld.
domain.tld.            172800 IN MX 20 backup.domain.tld.
In our mailertable we have:
domain.tld     esmtp:[mail.domain.tld]
Simple, isn’t it? We’re using the brackets to avoid MX resolution, and hence undesirable loops because we’re in the MX records ourselves (backup.domain.tld).
But, What if the master server has two 10 MX records to load balancing? We can’t remove the brackets because of a possible loop… Sendmail has two solutions (although not very well documented).

Simulate MX Failover

Setup different servers separated with :, for example:
domain.tld     esmtp:[mail1.domain.tld]:[mail2.domain.tld]
When mail1.domain.tld fails, mail2.domain.tld is used.

Simulate DNS Round-Robin

Setup different servers separated with ,, for example:
domain.tld     esmtp:[mail1.domain.tld],[mail2.domain.tld]
The mail submittion will be balanced between the provided servers.
REFERENCES