FreeBSD comes with Sendmail installed and already configured to serve basic email needs right out of the box. All you have to do to enable Sendmail (so that it starts at boot time) is add the following line to /etc/rc.conf: sendmail_enable="YES" You can then reboot to enable the Sendmail server, or start it by typing /etc/rc.d/sendmail start. When the system is up and running, you can send a message to anyone on the Internet, and they can send one to youprovided you have a few things set up properly. For the most part, these aren't configuration items for Sendmail itself, but rather for the system in generalSendmail relies on the system to have a few guarantees in place before it will operate without a hitch. You can decide to replace Sendmail with another MTA, such as Postfix or Qmail; you learn how to do that at the end of this chapter. Meanwhile, because Sendmail's default configuration works well for the vast majority of servers, we'll talk about how to manage Sendmail itself effectively. Sendmail File LayoutThere are four places in the system that concern Sendmail:
Sendmail itself is located at /usr/sbin/sendmail, and its log files are written to /var/log/maillog (which is rotated on a daily basis by the periodic job, which we discussed in Chapter 15, "Performance Monitoring, Process Control, and Job Automation"). Note Some systems historically put the Sendmail binary in /usr/lib/sendmail. Some programs expect to find Sendmail there, including certain old web tools that were developed without FreeBSD or Linux in mind. If you run these programs, you might want to violate the FreeBSD directory structure so far as to create a symbolic link from this historical location to the current one: # ln -s /usr/sbin/sendmail /usr/lib/sendmail Note /usr/sbin/sendmail is not actually Sendmail itselfit's in fact a link to a "wrapper," a small program that takes commands and data input and feeds them to Sendmailor to another MTA. The purpose of the wrapper is to allow you to replace Sendmail with another MTA such as Postfix; because all your programs interact with the wrapper rather than with Sendmail itself, the wrapper ensures that the transition is transparent to all your system functions. The mailbox files (mail spools) in /var/mail are plain-text files, each named for the user who owns it and with permissions set to 600 (readable and writable only by the owner). New messages are appended to the end of the recipient's mail spool file. There are also temporary POP lock files that have zero length and a name of the form .username.pop. They receive the contents of the corresponding mail spool file while a POP3 connection is open, and any untransferred remnants are then copied back into the mailbox. We'll be talking more about how the POP3 server works later in this chapter. Configuration FilesHere are some of the files in /etc/mail that you'll find important when running Sendmail. /etc/mail/sendmail.cfThis is the main Sendmail config file. However, unlike just about every other config file for every other program, you're not intended to edit this file to alter Sendmail's behavior. Rather, you should make changes at a higher "macro" level in the master config (.mc) file, which is discussed next, and then compile a sendmail.cf file from that. The sendmail.cf file contains options, rule sets, and featuresall in a format that can be very daunting and nearly not human readable. It's best to leave sendmail.cf alone. The sendmail.cf file defines Sendmail's behavior for handling incoming mail addressed to local users. A corresponding config file, submit.cf, handles outgoing mail generated by local users and defines how it is transferred to remote SMTP servers. See "The Message Queue" and "Email for Standalone Workstations" later in this chapter for more details on configuring the "submission" side of Sendmail. /etc/mail/freebsd.mcThe /etc/mail/freebsd.mc file is Sendmail's "master config" file. It contains a list of features and options that override the defaults in the standard config file, much in the same fashion as /etc/rc.conf overrides /etc/defaults/rc.conf. With freebsd.mc, though, the format of the settings is much more bizarre. Commands are given in the m4 macro language (which is barely used outside of Sendmail configurations). The .mc file is then compiled together with the default cf.m4 file from the Sendmail source in /usr/share/sendmail or /usr/src/contrib/sendmail to create a .cf output file. You can then install this file as the new sendmail.cf file. Sound confusing and backward? It is, yes. Sendmail's configuration methods have always been notoriously convoluted, and backward-compatibility concerns have prevented it from receiving the overhaul it so desperately needs. However, the configuration process has been made a lot more straightforward through the efforts of the FreeBSD developers, especially in more recent versions. It used to be the case that to regenerate your sendmail.cf file, you had to go into the source directory on your own, figure out which .mc file was the one that most closely matched your system, make changes according to the online documentation as best you could, and then dig out the cryptic m4 compilation command that produced the output filewhich you then had to install by hand. The state of things today is greatly improved over that, although it's still not what anyone would call user-friendly. Each line in the m4 language contains the string dnl at some point; this stands for "delete through newline," and it marks the end of the readable line (each line must have one). To comment out a line, place the dnl at the beginning. Otherwise, put it at the end. There's a makefile in /etc/mail, with targets defined that allow you to create a new .cf file from the freebsd.mc file simply by typing make cf. Then you install this output file (freebsd.cf) into sendmail.cf using make install:
The file /etc/mail/Makefile has a number of other uses, as you'll see in a moment. Note A makefile (conventionally named Makefile) is a special file that sits in the top level of any tree of source code; it contains "build targets," which allow you to compile the code in a certain predefined way. We covered the makefiles used by the ports in Chapter 16, "Installing Additional Software." In that chapter's example, you could compile the programs in a port with the make command, but the target install would specify to the make command that you wanted to run whatever installation procedures were prescribed in that port's makefile. In /etc/mail, the makefile that FreeBSD provides allows you to compile the various databases that comprise a Sendmail configuration, and even control Sendmail itself. It's not a config file itself, per se. Rather, it's a part of the system. Therefore, you should not modify it unless you know what you're doing. Just as the /etc/mail/freebsd.mc file is what generates the default sendmail.cf file for incoming mail, the freebsd.submit.mc file defines options for the submit.cf file, which controls outgoing mail. See "The Message Queue" and "Email for Standalone Workstations" later in this chapter for more details on configuring the "submission" side of Sendmail. /etc/mail/aliasesThere's a mailbox in /var/mail for every user on the system; however, someone having an email address on your machine doesn't require that they have an account. You can always set up aliases to map incoming email addresses to any other address, whether it's an address somewhere else on the Internet, another account on your machine, or even a pipe to a file or program. The default /etc/mail/aliases contains examples of all these. An alias line contains the alias name, a colon, a space or tab (optionally), and the target address or pipe: tiger: bob@stripes.com fsmith: frank pager: "|/usr/local/bin/pageme" dump: ">>/home/frank/dump2me" mylist:include:/home/frank/list.txt This last example is an "include" alias, which reads in a list of addresses from a plain-text file at the specified location. This is an easy way to manage a mailing list. Just make changes to the included file, and the alias will always serve as an up-to-date shortcut to the list of specified recipients. Traditionally, and as a matter of "netiquette," a system has a number of administration aliases for various purposes that are all aliases for root. Some of these "pseudo-accounts" include abuse (the address for reporting junk mail or malicious activity originating at your server), postmaster (the person who runs the mail server), and webmaster (the person in charge of the web server). Some of these are already aliased to root in the default configuration, and others you may have to enable by uncommenting them. After you make any change to /etc/mail/aliases, you have to rebuild the aliases.db file, which is a hash table version of the aliases file that provides fast lookups (as with /etc/master.passwd, which we discussed in Chapter 13, "Users, Groups, and Permissions"). You can use the traditional newaliases command to do this, or for consistency's sake with the rest of the maintenance tasks, go into /etc/mail and use make aliases: # make aliases /usr/sbin/sendmail -bi /etc/mail/aliases: 25 aliases, longest 10 bytes, 254 bytes total chmod 0640 /etc/mail/aliases.db The command shown here will not return any output if the aliases database is up to date. Note Using global aliases isn't the only way to redirect mail from one local address to another, or to an external address. For instance, if a user wants all his incoming mail to be forwarded automatically to some external address, you could use /etc/mail/aliases to do the trick, but this involves root access. There's a better way, if the user has a full account on the system. All a user has to do to forward mail to another address is to create a .forward file in his home directory, containing the forwarding email address. This can be done with any text editor, or even simply with echo: # echo "frank@somewhereelse.com" > .forward Removing this file will cause mail forwarding to stop. /etc/mail/accessThe access database provides a way to apply certain rules to single hosts, subnets, or whole groups of addressesan excellent anti-spam provision. Applicable rules include OK, REJECT, RELAY, DISCARD, and 550 <message>. The contents of the default /etc/mail/access file show examples of how the address/hostname field can be formatted: cyberspammer.com 550 We don't accept mail from spammers FREE.STEALTH.MAILER@ 550 We don't accept mail from spammers another.source.of.spam REJECT okay.cyberspammer.com OK 128.32 RELAY The addresses on the left side can be complete hostnames or IP addresses, or else they might be only partial ones; cyberspammer.com will match any hostname in the cyberspammer.com domain, and 128.32 covers the entire 128.32.xxx.xxx Class B network. The right side contains the rules, which can be any of the following:
After you've made changes to /etc/mail/access, the access.db file must be regenerated. You can do this with the make maps target, which regenerates any of the feature map files that have been changed since the last time make maps has been run. Follow this command with make restart to restart the Sendmail master process with the new access.db file: # make maps # make restart Restarting: sendmail sendmail-clientmqueue. /etc/mail/local-host-namesFormerly sendmail.cw, this file specifies all the hostnames that your server claims to be. This information becomes especially important if you're hosting multiple domains and doing mail service for all of them (virtual hosting). In that situation, if you don't add each relevant domain name to the local-host-names file, an incoming message destined for a domain you host will bounce back to the sender with the dreaded message MX list for <domain> loops back to myself; local configuration error. # cat /etc/local-host-names example.com www.example.com bobsmachine.com The local-host-names file has a simple format: a list of hostnames, one per line. The file doesn't exist in the default installation, but you'll need to create it if you add more domain or hostname aliases to your machine via DNS. After adding names to the list, run make restart to restart the server: # make restart Restarting: sendmail sendmail-clientmqueue. /etc/mail/virtusertableAlso on the subject of virtual hosting, /etc/mail/virtusertable provides a way to map addresses on one domain that you host to local accounts, other addresses, or error messages. This is somewhat like a hybrid of the access database and the aliases file. Let's say you're hosting a secondary domain called mycave.org. You want webmaster@mycave.org to go to the local user "bill," info@mycave.org to go to a remote address anne@elsewhere.com, and all other addresses (@mycave.org) to be rejected. This could be done with the following tab-separated rules: webmaster@mycave.org bill info@mycave.org anne@elsewhere.com @mycave.org error:nouser User unknown Note that the order in which these rules are specified doesn't matter; when you build the virtusertable.db hash table, each rule has its own lookup value, and the ordering in the virtusertable file is irrelevant. As with the access database, you need to rebuild virtusertable.db and then restart the server. This is easiest to do with make maps, though bear in mind that this rebuilds all the map databases in /etc/mail that have been modified: # make maps /usr/sbin/makemap hash virtusertable.db < virtusertable chmod 0640 virtusertable.db /usr/sbin/makemap hash access.db < access chmod 0640 access.db # make restart Restarting: sendmail sendmail-clientmqueue. An excellent and complete discussion of virtual hosting and the use of the virtusertable file can be found at the Sendmail Consortium information site (http://www.sendmail.org/virtual-hosting.html). Note By the way, /etc/mail/Makefile and all these convenient targets for rebuilding the various configuration databases are additions made by the FreeBSD team and are not part of Sendmail as released by its developers. Some other operating systems don't provide these conveniences. If you're going to be maintaining a Sendmail installation on a Solaris system or some other platform, you'll want to know the underlying commands beneath each of the build targets in the makefile so that you can accomplish the same tasks. The documentation at http://www.sendmail.org is very helpful in this regard. DNS Resolution IssuesRunning a successful Sendmail server really requires that you have accurate DNS information set up for your machine. If you simply install FreeBSD, assign an available IP address to it, and attempt to send mail, it might bounce back to you complaining that the remote server "could not resolve your hostname." Many SMTP servers, including Sendmail in its default configuration, do not accept mail from senders without fully qualified domains in their addresses or resolvable DNS names. Before you try to put Sendmail to full use on your machine, you'll need to make sure you have reverse DNS lookups correctly set up. You can check this with the nslookup command, giving it your machine's IP address as an argument: # nslookup stripes.example.com Server: lion.example.com Address: 64.41.131.132 Name: stripes.example.com Address: 64.41.131.102 This output shows a correctly resolving reverse DNS setup, one in which Sendmail will work just fine. However, you may get something like the following: # nslookup stripes.example.com Server: lion.example.com Address: 64.41.131.132 *** lion.example.com can't find stripes.example.com: Non-existent host/domain This means you'll have problems sending and receiving mail until DNS is set up properly. You learn more about DNS in Chapter 32, "The Domain Name Server." Note You should check against a remote and independent DNS, not just one on your local network, to be absolutely sure of the DNS configuration for your machine; sometimes, a local name server plays tricks on you by reporting information only it knows aboutinformation that hasn't propagated to the rest of the Internet. Controlling SendmailSendmail operates by keeping a single "master" process running and listening on port 25 for incoming connections, with additional processes for handling queue runs on both incoming and outgoing messages, sending messages to remote recipients, and other tasks. The master process is started at boot time from /etc/rc. Starting and stopping the Sendmail master process is made easy by the makefile and the integrated nature of the resource configuration files in /etc. To start the process, simply go into /etc/mail and enter make start: # make start Starting: sendmail sendmail-clientmqueue. This command pulls in relevant configuration details from the systemwide resource configuration files, in which flags such as -q30m (do a queue run every 30 minutes) and -bd (run as a background daemon) are centrally specified. It will even refuse to start the process if the sendmail_enable variable in the rc.conf files is set to NO. Restarting or stopping the master process is equally simple: # make restart Restarting: sendmail sendmail-clientmqueue. # make stop Stopping: sendmail sendmail-clientmqueue. You can see what state each Sendmail process is in by using ps in wide mode in conjunction with grep; each process reports its position in the queue as an argument against its name in the process table. The following example shows the master process (419), the "queue runner" for outgoing mail submissions (51251), and a process in the middle of a queue run (17353):
The Message QueueSendmail's operation is split into two parts: incoming messages and outgoing messages. Incoming messages waiting to be delivered to local users by Sendmail sit in /var/spool/mqueue. A similar directory, /var/spool/clientmqueue, holds messages that local command-line MUA users have submitted for Sendmail to deliver. In Sendmail's default configuration, a new sendmail -q process is started every 30 minutes, stepping through each queued message in both queue directories and attempting to deliver it to its destination. This continues for five days, at the end of which an "undeliverable" message is returned to the sender with the relevant error headers attached. Note The /var/spool/clientmqueue directory is actually fed by a single standalone Sendmail process that is bound only to the localhost interface; this is a security measure that eliminates the need for Sendmail to be setuid root in order for outgoing mail users to write their messages to the queue directory. Messages in the incoming queue, /var/spool/mqueue, should never build up, technically, because once a message has reached the server there should be no reason why delivery to a local user would fail temporarily. The outgoing "submit" Sendmail daemon is enabled by default, but you can disable it (returning to the model where a single Sendmail master process controls both incoming and outgoing mail in the same location, /var/spool/mqueue) by setting the following option in /etc/rc.conf: sendmail_submit_enable=NO Refer to /etc/mail/README for further details on other advanced configuration options concerning the split Sendmail model. If you have some messages in your queues (which you almost certainly will if you've been using the system for any length of time), you can browse through them at will. Unlike opaque systems such as Microsoft Exchange, in which queue files are kept in a database without an easy way to tweak or even see the files waiting to be sent, Sendmail provides full access to queued messages. Caution Queued messages are just plain-text files, able to be read and edited by regular text editors. This gives the administrator great control over how the mail system operates; however, it also provides an opportunity for the administrator to abuse his or her power by looking through the content of pending messages, which isn't just unethical but is illegal as well. If you run a system in which you trust your users, be sure they can trust you too! The first tool that comes with Sendmail is called mailq. It provides a way to list the current state of all messages waiting in the queue. Note that when called with no arguments, mailq reports on the contents of the incoming queue, /var/spool/mqueue. The Ac option instead tells it to look at the outgoing queue, which is likely to be much more interesting: # mailq -Ac /var/spool/clientmqueue (2 requests) ----Q-ID---- --Size-- -----Q-Time----- ------------Sender/Recipient------------ f4H1Ahu36976 6246 Wed May 16 18:10 MAILER-DAEMON (Deferred: Operation timed out with mlists.acmecity.com.) <fred@acmecity.com> f4GKwVW16827 706 Wed May 16 13:58 www (host map: lookup (hotamil.com): deferred) bob@hotamil.com Using mailq in this way, you can keep an eye on what kind of mail transfer errors frequently occur on your system. If people often forget to specify complete email addresses or misspell common mail server hostnames, you can address that problem through education and tutorials. If you're getting a lot of hostname lookup errors, this might point to a configuration problem on your end. mailq is an excellent diagnostic tool. The queue also gives you the ability to fix mistakes in messages on the way out. Let's say, for instance, you have an entry like the second one in the mailq output shown earlier. The erroneous recipient domain is the result of a simple typo; you can either wait five days for Sendmail to give up trying to find hotamil.com and send the message back to you as an error, or you can fix this problem right in the queue. To do this, go into /var/spool/clientmqueue and look for the files matching the ID of the entry in the mailq output. These would be the files dff4GKwVW16827 and qff4GKwVW16827. The first contains the message body, and the second contains the message headers in an interim format. Simply open up the file with the headers (qff4GKwVW16827) in a text editor, replace all occurrences of hotamil.com with hotmail.com, save the file, and wait for the next queue run. The message will go through cleanly this time. If you can't wait that long, force a queue run by running sendmail -q v -Ac. (The q switch tells Sendmail to do a queue run, -v tells it to echo the results of the entire session verbosely, and Ac tells it to use the outgoing queue, /var/spool/clientmqueue.) This gives you the added bonus of a look into exactly how Sendmail does its SMTP transactions with all the remote systems. With each message Sendmail processes, it will echo to your terminal all the output from the transaction, just as in the example at the beginning of the chapter. You'll get to see all the interesting greeting messages that various administrators program into their MTAs, visible only to other MTAs, and therefore often quite creative (one memorable one said, mail.wherever.com ready to rock!). You can use Ctrl+C to exit at any timemessages are removed from the queue only after they've been successfully transferred. Note If no messages are waiting in the queue, there will be no output to the sendmail q v Ac command. |