Recipe 5.7 Routing Mail for Entire Virtual Domains

Problem

You have been asked to configure sendmail to route mail for entire virtual domains, not just individual hosts .

Solution

The domain administrator must register each virtual mail domain with an official DNS registrar. The DNS administrator must also create a minimal zone file for each virtual mail domain. In addition to the basic records required to create a zone file, the file must contain MX records that point to the mail exchanger that you are configuring. See DNS and BIND , by Paul Albitz and Cricket Liu (O'Reilly), for more information on DNS configuration.

On the mail server, create a /etc/mail/ virtuser -domains file that lists each virtual mail domain for which service will be provided.

Create an /etc/mail/virtusertable text file that defines the routing for each virtual mail domain. Use makemap to build a hash type database from the text file.

Next , create a sendmail configuration that enables the virtusertable feature, loads class $={VirtHost} from the /etc/mail/virtuser-domains file, and enables the virtuser_entire_domain feature. Here are examples of the lines that need to be added to the sendmail configuration:

 dnl Use the virtusertable for mail routing FEATURE(`virtusertable') dnl Load $={VirtHost} from a file VIRTUSER_DOMAIN_FILE(`/etc/mail/virtuser-domains') dnl Interpret the values in $={VirtHost} as domain names FEATURE(`virtuser_entire_domain') 

As shown in Recipe 1.8, rebuild and install the sendmail.cf file, and restart sendmail.

Discussion

Assume that the zone files created for the shop.wrotethebook.org , school.ora.com, and hotel.example.com domains all contain MX records that route email to mail.wrotethebook.com . The mail.wrotethebook.com host will reject that mail unless the destination hostname is listed in class $=w or class $={VirtHost} . The configuration described in the Solution section loads the $={VirtHost} class from the /etc/mail/virtuser-domains file specified by the VIRTUSER_DOMAIN_FILE macro. Here is a sample virtuser-domains file containing the names of three virtual mail domains:

 #  cat /etc/mail/virtuser-domains  shop.wrotethebook.org school.ora.com hotel.example.com 

Values stored in class $={VirtHost} are replicated in class $=R , as this simple test shows:

 #  sendmail -bt  ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> >  $={VirtHost}  shop.wrotethebook.org school.ora.com hotel.example.com >  $=R  shop.wrotethebook.org school.ora.com hotel.example.com >  /quit  

By default, values in class $=w and class $={VirtHost} are interpreted as hostnames. Values in class $=R , on the other hand, are interpreted as domain names. Use the virtuser_entire_domain feature to cause the values in class $={VirtHost} to also be interpreted as domain names. The virtuser_entire_domain feature tells sendmail to evaluate class $=R and class $={VirtHost} in an equivalent manner ”every host in every domain listed in class $=R is accepted for processing by the local host, and every host in every domain in class $={VirtHost} is matched against the virtusertable . Here is a sample virtusertable we'll use to illustrate this:

 #  cat > /etc/mail/virtusertable   @mainst.shop.wrotethebook.org   logan   @mall.shop.wrotethebook.org     pat   @retro.shop.wrotethebook.org    reba   @school.ora.com                 %1@b2341.isp.wrotethebook.net   @sales.school.ora.com           jeff+sales@b2341.isp.wrotethebook.net   @info.school.ora.com            jeff+info@b2341.isp.wrotethebook.net   @motel.hotel.example.com        reservations@b0021.isp.wrotethebook.net   @lodge.hotel.example.com        reservations@b0531.isp.wrotethebook.net   @hotel.hotel.example.com        reservations@b1088.isp.wrotethebook.net   Ctrl-D  #  makemap hash /etc/mail/virtusertable < /etc/mail/virtusertable  

The first three entries route mail addressed to anyone on the three hosts in the shop.wrotethebook.org domain to the local user accounts where the mail addressed to these virtual hosts is read.

school.ora.com and hotel.example.com both run their own servers, but the servers are literally part of the isp.wrotethebook.net domain. school.ora.com has only one server. hotel.example.com has three servers ”one at the motel, one at the lodge, and one at the hotel. Notice that school.ora.com uses + detail syntax to identify the specific mailbox in the jeff account where the mail should be stored. For this to work, the jeff account on b2341.isp.wrotethebook.net must have a mail filter that processes the + detail syntax.

A few tests of this recipe's configuration show the impact of the virtuser_entire_domain feature and the virtusertable entries:

 #  sendmail -bv info@mall.shop.wrotethebook.org  info@mall.shop.wrotethebook.org... deliverable: mailer local, user pat #  sendmail -bv cranks@sales.school.ora.com  cranks@sales.school.ora.com... deliverable: mailer esmtp, host b2341.isp. wrotethebook.net., user jeff+sales@b2341.isp.wrotethebook.net #  sendmail -bv reservations@lodge.hotel.example.com  reservations@lodge.hotel.example.com... deliverable: mailer esmtp, host b0531.isp. wrotethebook.net., user reservations@b0531.isp.wrotethebook.net 

None of the hostnames in the three test addresses shown above are listed in either class $=w or $={VirtHost} . Yet all three addresses are clearly rewritten by the virtusertable . This is the effect of the virtuser_entire_domain feature ”these hostnames are processed through the virtusertable because they belong to domains listed in the $={VirtHost} class.

Potential conflicts and solutions

However, the virtuser_entire_domain feature does not change the way that the keys in the virtusertable are interpreted. There is no domain wildcard for the virtusertable . Each hostname in the test above is rewritten because it exactly matches a key in the database. A common mistake is to think that an entry like @school.ora.com applies to every host in the school.ora.com domain because the virtuser_entire_domain feature is used. A test shows this is not the case:

 #  sendmail -bv dave@school.ora.com  dave@school.ora.com... deliverable: mailer esmtp, host b2341.isp.wrotethebook.net.,  user dave@b2341.isp.wrotethebook.net #  sendmail -bv dave@hs.school.ora.com  dave@hs.school.ora.com... deliverable: mailer esmtp, host hs.school.ora.com., user  dave@hs.school.ora.com 

Both of the recipient addresses shown above are in a domain listed in $={VirtHost} and the virtuser_entire_domain feature is enabled. For these reasons, both of these addresses are matched against the virtusertable . But only the first address matches a key found in the database and is rerouted. The other address goes through the normal delivery process, and therein lies a possible conflict with the domain administrator.

Some domain administrators use wildcard MX records that match any hostname within a given domain. The wildcard MX makes things easy for the domain administrator but has the potential to cause problems for the sendmail administrator. The sendmail -bv test of dave@hs.school.ora.com shows the problem.

Mail addressed to hs.school.ora.com is accepted by the local host for processing because the school.ora.com domain is listed in class $=R , which means that the local host will relay mail for this domain. The hs.school.ora.com address is not modified by the virtusertable process, so the local host attempts to deliver the mail via the esmtp mailer directly to a host named hs.school.ora.com . When the local host does a DNS lookup of hs.school.ora.com , the lookup succeeds because this host is covered by the MX wildcard. The MX record returned by the lookup points the local host right back to the local host. Problem!

This problem can be avoided in a few different ways. All three solutions work, and all have different advantages and disadvantages. While the first solution is preferred, the solution you choose depends on your personal situation. The three solutions are:


Use individual MX records

The MX wildcard is the root of the problem: it routes mail for a host that has no existence ”real or virtual. Create a zone file customized for each virtual mail domain that explicitly defines an MX record for each host covered in the virtusertable . When the domain administrator and the sendmail administrator are the same person, this approach works well and it has the distinct advantage of responding to domain name errors where they should be responded to ”inside the DNS. The disadvantage of this approach is that it increases the work of the domain administrator, and it reduces the ability of the sendmail administrator to solve his own problems.


Use local-host-names and list only individual hostnames

Mail addressed to hs.school.ora.com is accepted for relaying by the local system because the domain of which it is a part is listed in class $=R . Every entry in $={VirtHost} is replicated in class $=R , and every entry in class $=R is interpreted as a domain name. So, even if the virtuser_entire_domain feature is not used, listing school.ora.com in $={VirtHost} triggers the mail delivery problem just described. Avoid this by listing school.ora.com in the local-host-names file and using the use_cw_file feature to load that file into class $=w . Values in class $=w are interpreted as hostnames; thus, mail addressed to hs.school.ora.com is not accepted by the local system and the delivery problem is not triggered. Of course, the mail is returned to the sender as undeliverable mail. This is okay if the sender made a mistake entering the address; however, if the people at school.ora.com advertise this address, returning an error to the sender is a bad idea. Another disadvantage of this solution is that listing hostnames in local-host-names literally makes those hostnames aliases for the local host, which may cause username conflicts.


Create a catchall entry in the mailertable

A catchall entry is an entry in a database that catches all queries for which there is no specific key. Generally, a catchall entry responds to these queries with an error message. Catchall entries in the virtusertable handle usernames that are not specifically covered by table entries. To create a catchall entry for a hostname, use the mailertable . The advantages of catchall entries are that they proactively respond to error situations, and they are under the direct control of the sendmail administrator. The disadvantage of catchall entries is that they catch everything ”even things they shouldn't. They must be fully tested and used with care.

The catchall solution

Below, we define catchall entries in the mailertable to avoid the possible delivery problems that would be caused if the domain administrator used wildcard MX records in our sample virtual mail domains. First, add mailertable support to the basic Recipe 5.7 configuration:

 dnl Use the virtusertable for mail routing FEATURE(`virtusertable') dnl Load $={VirtHost} from a file VIRTUSER_DOMAIN_FILE(`/etc/mail/virtuser-domains') dnl Interpret the values in $={VirtHost} as domain names FEATURE(`virtuser_entire_domain') dnl Use the mailertable to invoke special mailers FEATURE(`mailertable') 

Create the virtusertable database and the virtuser-domains file as described above. Create a mailertable with a catchall entry for each of the virtual mail domains:

 #  cat > /etc/mail/mailertable   .school.ora.com          error:5.3.0:553 Invalid hostname   shop.wrotethebook.org    error:5.3.0:553 Invalid hostname   .shop.wrotethebook.org   error:5.3.0:553 Invalid hostname   hotel.example.com        error:5.3.0:553 Invalid hostname   .hotel.example.com       error:5.3.0:553 Invalid hostname   Ctrl-D  #  makemap hash /etc/mail/mailertable < /etc/mail/mailertable  

The first entry addresses the specific problem described in the example above. The next two entries provide similar error control for the shop.wrotethebook.org virtual mail domain, and the last two entries provide the protection for the hotel.example.com virtual mail domain. The additional entries for the shop.wrotethebook.org and hotel.example.com domains are necessary because, unlike the school.ora.com domain, neither of these other domains has a virtusertable entry that routes mail addressed to user @ domain , as this test of this recipe's basic configuration shows:

 #  sendmail -bv jane@shop.wrotethebook.org  jane@shop.wrotethebook.org... deliverable: mailer esmtp, host shop.wrotethebook.org., user jane@shop.wrotethebook.org #  sendmail -bv kathy@hotel.example.com  kathy@hotel.example.com... deliverable: mailer esmtp, host hotel.example.com.,  user kathy@hotel.example.com #  sendmail -bv sara@school.ora.com  sara@school.ora.com... deliverable: mailer esmtp, host b2341.isp.wrotethebook.net.,  user sara@b2341.isp.wrotethebook.net 

mailertable entries that begin with a dot are partial domain names that match any address that ends with the specified domain name. For example, a mailertable entry beginning with .wrotethebook.com would match addresses of the form user @ host .wrotethebook.com . Full domain names (those that do not start with a dot) match mail addressed in the form of user @ domain . Therefore, a mailertable entry starting with ora.com would match craig @ora.com but not craig@tcp.ora.com .

These catchall mailertable entries are only applicable to virtual mail domains and are only useful if the zone files for those domains use wildcard MX records. If these were real domains, the virtusertable entry might route mail from one host in the domain to another in the same domain. The rewritten address would then be caught by the mailertable catchall entry, and the "invalid hostname" error would be returned. Because these are virtual mail domains with no physical existence, the virtusertable never routes mail to a host in these nonexistent domains. Thus, addresses rewritten by the virtusertable do not match the catchall entries and are allowed to continue on their way as directed by the virtusertable . These catchall entries are useful, but only for the specific problem described here.

Run some tests with the new configuration to see the impact of these mailertable entries:

 #  sendmail -bv -C recipe5-7a.cf dave@hs.school.ora.com  dave@hs.school.ora.com... Invalid hostname #  sendmail -bv -C recipe5-7a.cf dave@school.ora.com  dave@school.ora.com... deliverable: mailer esmtp, host b2341.isp.wrotethebook.net.,  user dave@ b2341.isp.wrotethebook.net #  sendmail -bv -C recipe5-7a.cf jane@mall.shop.wrotethebook.org  jane@mall.shop.wrotethebook.org... deliverable: mailer local, user pat #  sendmail -bv -C recipe5-7a.cf jane@shop.wrotethebook.org  jane@shop.wrotethebook.org... Invalid hostname 

These tests show that addresses that match keys in the virtusertable are still being properly rewritten, while addresses in the virtual mail domain that do not have entries in the virtusertable are now being properly identified as addressing errors. Catchall entries are useful, but they should be used with caution and be thoroughly tested to ensure that they don't catch things that they shouldn't.

All of this work could, of course, be avoided if the domain administrator did not use wildcard MX records. The best solution to this potential problem is to avoid wildcards and use individual MX records.

See Also

Recipe 5.6 defines individual virtual hosts, as opposed to virtual mail domains, and should be evaluated as an alternative before implementing this recipe. Recipe 5.1 through Recipe 5.4 and this chapter's Introduction provide additional information about the mailertable . The sendmail book covers the virtusertable in Section 4.8.51. MX records and DNS are covered in DNS and BIND , by Paul Albitz and Cricket Liu (O'Reilly), and in TCP/IP Network Administration , by Craig Hunt (O'Reilly).



Sendmail Cookbook
sendmail Cookbook
ISBN: 0596004710
EAN: 2147483647
Year: 2005
Pages: 178
Authors: Craig Hunt

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