sendmail.org

Virtual Hosting with Sendmail

[Sendmail, 2nd Edition]

Many people and businesses are getting their own domain names these days and wish to receive mail using these domain names. They can pay ISPs for this service, or they can do it themselves. This web page is a guide for the do-it-yourself people, describing how to use sendmail to accomplish virtual e-mail hosting. Some knowledge of sendmail, Un*x administration, and Internet protocols is assumed. The best source of information about sendmail is the book Sendmail, 2nd Edition.

This page has been translated into Slovak as well.
 

DNS Configuration

First, you need to obtain the new domain name and set up name servers for that new domain:

  1. Choose an available domain name. In our example, we will use yourdomain.com.

  2. Establish two machines as primary and secondary name servers for your domain. Knowledge of how to do this is assumed; otherwise, the book DNS and BIND, 3rd Edition is highly recommended.

  3. Configure MX records for your domain (Note: CNAME records can not be used; see § 5.2.2 of RFC 1123 for details.) MX records are explained in the sendmail book, section 15.3, and how to configure them is explained in section 21.3. You have two options for MX records:

  4. After the name servers are setup, register your domain using one of the registries.

Sendmail Configuration

Now that DNS is setup, it's time to set up sendmail.

  1. Download sendmail from FTP.Sendmail.ORG/pub/sendmail/. You will automatically be offered a short initial message which will indicate the current release. The instructions below assume version 8.10.0 or later.

  2. Build and install sendmail for your machine. In most cases, this consists of unpacking the distribution, reading the README and sendmail/README files, and typing Build in the sendmail directory. See the INSTALL file in the distribution's top-level directory for details.

  3. Configure sendmail. This is where we go into detail.

    1. First, read the cf/README file thoroughly. It will give you instructions on creating a .mc file in the cf/cf directory. Your mailserver.mc file will typically look something like:

      divert(-1)dnl
      #
      #  This file contains definitions for mailserver.yourdomain.com
      #
      divert(0)dnl
      VERSIONID(`@(#)mailserver.mc     1.0 (yourdomain.com) 5/1/97')
      OSTYPE(solaris2)dnl
      DOMAIN(yourdomain.com)dnl
      FEATURE(`virtusertable', `dbm /etc/mail/virtusertable')dnl
      MAILER(local)dnl
      MAILER(smtp)dnl
      

      Your actual OS will be substituted for solaris2. A typical cf/domain/yourdomain.com.m4 file that looks something like:

      divert(-1)dnl
      #
      #  This file contains the global definitions for yourdomain.com
      #
      divert(0)dnl
      VERSIONID(`@(#)yourdomain.com.m4   1.0 (yourdomain.com) 5/1/97')
      FEATURE(`use_cw_file')dnl
      

      It may have some other FEATURE()'s and define()'s as well. The virtual user table is the key to all of this. Note: if you built sendmail with NEWDB instead of NDBM, you will have to use hash instead of dbm in the above line.

    2. Generate your /etc/mail/sendmail.cf file from your mailserver.mc file:

      cd sendmail-VERSION/cf/cf
      ./Build mailserver.cf
      cp mailserver.cf /etc/mail/sendmail.cf
      
  4. Create the virtual user table. This is explained in detail in section 19.6.28 of the sendmail book; an overview is given here. The table is a database that maps virtual addresses into real addresses. You create a text file where each line has a key/value pair, separated by a TAB. For example:

    joe@yourdomain.com	jschmoe
    jane@yourdomain.com	jdoe@othercompany.com
    @yourdomain.com		jschmoe
    

    In this first example, the address joe@yourdomain.com will be mapped to the local user jschmoe, jane@yourdomain.com will be mapped to the remote user jdoe@othercompany.com, and anything else coming in to yourdomain.com will also go to jschmoe.

    joe@yourdomain.com	jschmoe
    bogus@yourdomain.com	error:nouser No such user here
    list@yourdomain.com	yourdomain-list
    @yourdomain.com		%1@othercompany.com
    

    In this second example, the address joe@yourdomain.com will be mapped to the local user jschmoe, the address bogus@yourdomain.com will return the indicated error, the address list@yourdomain.com will be mapped to the local user yourdomain-list (which you would use the aliases file to ultimately resolve) and every other user at yourdomain.com will be mapped to a remote user of the same name at othercompany.com.

    Note 1: if you have a local user, say sam, and there is no key for sam@yourdomain.com and no catch-all key for @yourdomain.com, then sendmail will fall back to the local user sam when resolving sam@yourdomain.com. To prevent this, you must use either a catch-all key or an explicit key for sam@yourdomain.com; the error:nouser example above may be useful in this instance.

    Note 2: if you want a virtual address to resolve to more than one real address, you need to do it indirectly. Have the virtual address resolve to a local alias, then have the local alias resolve to the desired set of addresses. For example, in the virtual user table:

    joe@yourdomain.com		localjoe
    
    then in the aliases file:

    localjoe:	joe@othercompany.com, jane@othercompany.com
    

    Note 3: multiple domains are allowed, and virtual addresses in each domain are independent. So for example, you could have:

    joe@yourdomain1.com		localjoe
    joe@yourdomain2.com		joe@othercompany.com
    joe@yourdomain3.com		localjoe
    joe@yourdomain4.com		error:nouser No such user here
    
    For people admininstering multiple domains, it may be easier to keep each domain's list in a separate file, then write a short script to concatenate all such files together into a master virtual user table. But we're getting ahead of ourselves; that's the next step...

  5. Build the virtual user table. If the above virtual user table text file is located at sourcefile, and you are using the dbm database type, then use the command:

    makemap dbm /etc/mail/virtusertable < sourcefile
    

    This actually creates one or more non-text files (typically /etc/mail/virtusertable.dir and /etc/mail/virtusertable.pag, or /etc/mail/virtusertable.db), but does not actually change /etc/mail/virtusertable itself, so this is the recommended location for sourcefile.

  6. If you would like to reverse-map local users for out-bound mail, you will need to add support for the generics table to your .mc file:

    FEATURE(`genericstable', `dbm /etc/mail/genericstable')dnl
    GENERICS_DOMAIN_FILE(`/etc/mail/generics-domains')dnl
    

    And you will need to create /etc/mail/genericstable which is like /etc/mail/virtusertable above except the columns are reversed:

    jschmoe			joe@yourdomain.com
    
    Note: you may also wish to consult our Masquerading and Relaying page.

  7. Add your domain name to sendmail's class w. This is typically done by adding a line to /etc/mail/local-host-names (known as /etc/sendmail.cw prior to 8.10) with the value of your domain name.

    Likewise, if you are using the genericstable, you should add any domains you wish to reverse-map to /etc/mail/generics-domains.

  8. Restart or SIGHUP sendmail. Note that you do not need to restart sendmail when changing the virtual user or generics tables, only when changing /etc/mail/sendmail.cf or class files such as /etc/mail/local-host-names.

An extra step is required for hosts that are not connected full-time. As noted in the MX configuration section, if you use another host to queue your mail until you connect, you will have to force delivery of mail queued on the secondary mail server. To accomplish this, when your primary server connects, you should run the script etrn.pl which comes in the contrib directory of the sendmail distribution:

etrn.pl secondary-mx-host yourdomain.com
It may be advisable to put this at the end of the sendmail start-up script on any primary MX. It would be especially useful as a follow-up to whatever script initiates the connection on primary MXs without full-time connections.

At this point, you should be set, and people should be able to send e-mail to addresses @yourdomain.com. However, you should test your configuration and make sure everything works as expected before announcing the new domain name and mail addresses for that domain. If things don't work as expected, you can test with sendmail's test mode:

sendmail -bt
Here are some examples of things to try in test mode:
# make sure the domain is in class w:
$=w
# is the map working?
/map virtuser joe@yourdomain.com
/map virtuser jane@yourdomain.com
/map virtuser @yourdomain.com
# is the rewriting working?
3,0 joe@yourdomain.com
3,0 some@yourdomain.com

If you get stuck and can't find the answers in the various README files which come with sendmail, the sendmail FAQ, or the Sendmail book, you can send mail to sendmail-questions@sendmail.org asking for assistance.

home